Giter Club home page Giter Club logo

mp's People

Contributors

justend29 avatar kris-jusiak avatar krzysztof-jusiak avatar ldm5180 avatar sehe avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mp's Issues

boost/mp.hpp:208:7: error: expected identifier before ‘typeof’

C++20 was specified and tried with both GCC11.3 and 12.3, but the same error occurs.
Maybe I'm doing something wrong, please let me know.

Actual Behavior

root@monica003:/home/monica/test/build# cmake --build .
[ 50%] Building CXX object CMakeFiles/main.dir/test.cpp.o
In file included from /home/monica/test/test.cpp:3:
/home/monica/mp/installed/x64-linux/include/mp-0.0.1/boost/mp.hpp:208:7: error: expected identifier before ‘typeof’
  208 | using typeof = decltype(expr(std::declval<Ts>()...));
      |       ^~~~~~
/home/monica/mp/installed/x64-linux/include/mp-0.0.1/boost/mp.hpp:208:14: error: expected primary-expression before ‘=’ token
  208 | using typeof = decltype(expr(std::declval<Ts>()...));
      |              ^
/home/monica/mp/installed/x64-linux/include/mp-0.0.1/boost/mp.hpp:208:14: error: expected unqualified-id before ‘=’ token
gmake[2]: *** [CMakeFiles/main.dir/build.make:76: CMakeFiles/main.dir/test.cpp.o] Error 1
gmake[1]: *** [CMakeFiles/Makefile2:83: CMakeFiles/main.dir/all] Error 2
gmake: *** [Makefile:91: all] Error 2

Steps to Reproduce the Problem

microsoft/vcpkg#29975 (comment)

Specifications

  • Version:
    root@monica003:/home/monica/test/build# lsb_release -a
    No LSB modules are available.
    Distributor ID: Ubuntu
    Description:    Ubuntu 22.04.1 LTS
    Release:        22.04
    Codename:       jammy
    
  • Platform: Linux

Statement SFINAE isn't allowed

mp/include/boost/mp.hpp

Lines 603 to 679 in 73cc053

template <class T>
[[nodiscard]] constexpr auto to_tuple(T&& obj) {
// clang-format off
if constexpr (requires { [&obj] { auto&& [p1, p2, p3, p4, p5, p6, p7, p8, p9, p10] = obj; }; }) {
auto&& [p1, p2, p3, p4, p5, p6, p7, p8, p9, p10] = std::forward<T>(obj);
return std::make_tuple(p1, p2, p3, p4, p5, p6, p7, p8, p8, p10);
} else if constexpr (requires { [&obj] { auto&& [p1, p2, p3, p4, p5, p6, p7, p8, p9] = obj; }; }) {
auto&& [p1, p2, p3, p4, p5, p6, p7, p8, p9] = std::forward<T>(obj);
return std::make_tuple(p1, p2, p3, p4, p5, p6, p7, p8, p9);
} else if constexpr (requires { [&obj] { auto&& [p1, p2, p3, p4, p5, p6, p7, p8] = obj; }; }) {
auto&& [p1, p2, p3, p4, p5, p6, p7, p8] = std::forward<T>(obj);
return std::make_tuple(p1, p2, p3, p4, p5, p6, p7, p8);
} else if constexpr (requires { [&obj] { auto&& [p1, p2, p3, p4, p5, p6, p7] = obj; }; }) {
auto&& [p1, p2, p3, p4, p5, p6, p7] = std::forward<T>(obj);
return std::make_tuple(p1, p2, p3, p4, p5, p6, p7);
} else if constexpr (requires { [&obj] { auto&& [p1, p2, p3, p4, p5, p6] = obj; }; }) {
auto&& [p1, p2, p3, p4, p5, p6] = std::forward<T>(obj);
return std::make_tuple(p1, p2, p3, p4, p5, p6);
} else if constexpr (requires { [&obj] { auto&& [p1, p2, p3, p4, p5] = obj; }; }) {
auto&& [p1, p2, p3, p4, p5] = std::forward<T>(obj);
return std::make_tuple(p1, p2, p3, p4, p5);
} else if constexpr (requires { [&obj] { auto&& [p1, p2, p3, p4] = obj; }; }) {
auto&& [p1, p2, p3, p4] = std::forward<T>(obj);
return std::make_tuple(p1, p2, p3, p4);
} else if constexpr (requires { [&obj] { auto&& [p1, p2, p3] = obj; }; }) {
auto&& [p1, p2, p3] = std::forward<T>(obj);
return std::make_tuple(p1, p2, p3);
} else if constexpr (requires { [&obj] { auto&& [p1, p2] = obj; }; }) {
auto&& [p1, p2] = std::forward<T>(obj);
return std::make_tuple(p1, p2);
} else if constexpr (requires { [&obj] { auto&& [p1] = obj; }; }) {
auto&& [p1] = std::forward<T>(obj);
return std::make_tuple(p1);
} else {
return std::make_tuple();
}
// clang-format on
}
template <class T>
constexpr auto to_list = [] /*[[nodiscard]]*/ {
// clang-format off
if constexpr (requires { [] { auto [p1, p2, p3, p4, p5, p6, p7, p8, p9, p10] = T{}; }; }) {
auto [p1, p2, p3, p4, p5, p6, p7, p8, p9, p10] = T{};
return type_list<decltype(p1), decltype(p2), decltype(p3), decltype(p4), decltype(p5), decltype(p6), decltype(p7), decltype(p8), decltype(p9), decltype(p10)>{};
} else if constexpr (requires { [] { auto [p1, p2, p3, p4, p5, p6, p7, p8, p9] = T{}; }; }) {
auto [p1, p2, p3, p4, p5, p6, p7, p8, p9] = T{};
return type_list<decltype(p1), decltype(p2), decltype(p3), decltype(p4), decltype(p5), decltype(p6), decltype(p7), decltype(p8), decltype(p9)>{};
} else if constexpr (requires { [] { auto [p1, p2, p3, p4, p5, p6, p7, p8] = T{}; }; }) {
auto [p1, p2, p3, p4, p5, p6, p7, p8] = T{};
return type_list<decltype(p1), decltype(p2), decltype(p3), decltype(p4), decltype(p5), decltype(p6), decltype(p7), decltype(p8)>{};
} else if constexpr (requires { [] { auto [p1, p2, p3, p4, p5, p6, p7] = T{}; }; }) {
auto [p1, p2, p3, p4, p5, p6, p7] = T{};
return type_list<decltype(p1), decltype(p2), decltype(p3), decltype(p4), decltype(p5), decltype(p6), decltype(p7)>{};
} else if constexpr (requires { [] { auto [p1, p2, p3, p4, p5, p6] = T{}; }; }) {
auto [p1, p2, p3, p4, p5, p6] = T{};
return type_list<decltype(p1), decltype(p2), decltype(p3), decltype(p4), decltype(p5), decltype(p6)>{};
} else if constexpr (requires { [] { auto [p1, p2, p3, p4, p5] = T{}; }; }) {
auto [p1, p2, p3, p4, p5] = T{};
return type_list<decltype(p1), decltype(p2), decltype(p3), decltype(p4), decltype(p5)>{};
} else if constexpr (requires { [] { auto [p1, p2, p3, p4] = T{}; }; }) {
auto [p1, p2, p3, p4] = T{};
return type_list<decltype(p1), decltype(p2), decltype(p3), decltype(p4)>{};
} else if constexpr (requires { [] { auto [p1, p2, p3] = T{}; }; }) {
auto [p1, p2, p3] = T{};
return type_list<decltype(p1), decltype(p2), decltype(p3)>{};
} else if constexpr (requires { [] { auto [p1, p2] = T{}; }; }) {
auto [p1, p2] = T{};
return type_list<decltype(p1), decltype(p2)>{};
} else if constexpr (requires { [] { auto [p1] = T{}; }; }) {
auto [p1] = T{};
return type_list<decltype(p1)>{};
} else {
return type_list{};
}
// clang-format on
}();

Unfortunately, this only works currently with clang because of a bug. It's not supposed to (according to http://eel.is/c++draft/temp#deduct.general-9.sentence-1, particularly the Note below that)

Example in the readme doesn't compile

great library, I found what I think is a little bug in the readme:

Expected Behavior

In the first godbolt link in the readme, this example compiles:

static_assert(mp::list<val const>() ==
  hello_world(mp::list<int, foo, val, bar>(), add_const, has_value)
);

Actual Behavior

However, in the readme itself, the example is written without the mp::list::operator(), which doesn't compile:

static_assert(mp::list<val const> ==
  hello_world(mp::list<int, foo, val, bar>, add_const, has_value)
);

Steps to Reproduce the Problem

  1. Follow the godbolt link in the readme: https://godbolt.org/z/3T86zvcEn
  2. Remove the two () operators after mp::list<...> to match the example as it is written in the readme
  3. observe that it doesn't compile anymore

Specifications

same as in the original godbolt link

I think the solution is to add the () operators in the readme, too.

parameter pack filter and reorder

Is it possible to filter and reorder a parameter pack?

void foo(auto&&... args)
{
    qoo(std::forward_as_tuple(std::forward<decltype(args)>(args)...)
        | std::views::filter(???)
        | std::views::reverse);
}

[feature] Add `begin` and `end` on list same constants

Currently boost::mp::list is not usable in range based for.

So this is not compiles:

    for (char c : mp::list<__PRETTY_FUNCTION__>()) {
        std::cout << c;
    }

This can be enabled on types where the template arguments are the same.

Possible implementation

#include <https://raw.githubusercontent.com/boost-ext/mp/main/include/boost/mp.hpp>
namespace boost::mp {
template<auto...As>
constexpr static inline auto list_array = std::array{As...};

template<class ...>
constexpr bool is_same_all_v = true;
template<class Ref, class...Oth>
constexpr bool is_same_all_v<Ref, Oth...> = (std::is_same_v<Ref, Oth> && ...);

template<template <auto...> class A, auto...As>
    requires is_same_all_v<decltype(As)...>
auto begin(const A<As...>& v) {
    return std::begin(list_array<As...>);
}

template<template <auto...> class A, auto...As>
    requires is_same_all_v<decltype(As)...>
auto end(const A<As...>& v) {
    return std::end(list_array<As...>);
}
} // boost::mp

MSVC doesn't support __PRETTY_FUNCTION__

>------ Build All started: Project: CMakeFindUsage, Configuration: x64-Release ------
  MSBuild version 17.4.1+9a89d02ff for .NET Framework
    Checking Build System
    Building Custom Rule C:/Users/monica/source/repos/CMakeFindUsage/CMakeFindUsage/CMakeLists.txt
    CMakeFindUsage.cpp
E:\boost-ext-mp\installed\x64-windows\include\mp-0.0.1\boost\mp.hpp(171,13): error C3527: 'Cs' is not a valid operand for 'sizeof...'. Did you mean to use 'sizeof'? 
E:\boost-ext-mp\installed\x64-windows\include\mp-0.0.1\boost\mp.hpp(569,24): error C3861: '__PRETTY_FUNCTION__': identifier not found 
E:\boost-ext-mp\installed\x64-windows\include\mp-0.0.1\boost\mp.hpp(569,24): error C2065: '__PRETTY_FUNCTION__': undeclared identifier 
E:\boost-ext-mp\installed\x64-windows\include\mp-0.0.1\boost\mp.hpp(590,8): error C2065: '__PRETTY_FUNCTION__': undeclared identifier 
E:\boost-ext-mp\installed\x64-windows\include\mp-0.0.1\boost\mp.hpp(590,8): error C3861: '__PRETTY_FUNCTION__': identifier not found 
E:\boost-ext-mp\installed\x64-windows\include\mp-0.0.1\boost\mp.hpp(591,14): error C2065: '__PRETTY_FUNCTION__': undeclared identifier 
E:\boost-ext-mp\installed\x64-windows\include\mp-0.0.1\boost\mp.hpp(591,14): error C3861: '__PRETTY_FUNCTION__': identifier not found 
E:\boost-ext-mp\installed\x64-windows\include\mp-0.0.1\boost\mp.hpp(597,8): error C2065: '__PRETTY_FUNCTION__': undeclared identifier 
E:\boost-ext-mp\installed\x64-windows\include\mp-0.0.1\boost\mp.hpp(597,8): error C3861: '__PRETTY_FUNCTION__': identifier not found 
E:\boost-ext-mp\installed\x64-windows\include\mp-0.0.1\boost\mp.hpp(598,14): error C2065: '__PRETTY_FUNCTION__': undeclared identifier 
E:\boost-ext-mp\installed\x64-windows\include\mp-0.0.1\boost\mp.hpp(598,14): error C3861: '__PRETTY_FUNCTION__': identifier not found 

Build All failed.

For details, please se: microsoft/vcpkg#29975 (comment).

Awesome little library! A few quick comments...

This is so cool! A few random comments (or questions on what I'm missing if I'm wrong about these things):


} or ...)) {

I think this should be and here?


std::array<bool, sizeof...(Ts)>{pred.template operator()<Ts>()...};

This (and several places above) can just use CTAD, right? [Answering my own question: you can't do CTAD because of the sizeof...(Ts) == 0 case 🤦🏼‍♀️]


mp/include/boost/mp.hpp

Lines 98 to 106 in 73cc053

struct callable_base {
void operator()();
};
template <class T>
struct callable : T, callable_base {};
} // namespace detail
template <class T>
concept callable = not requires { &detail::callable<T>::operator(); };

Probably not relevant, but this implies that types like int and float* are callable


mp/include/boost/mp.hpp

Lines 124 to 125 in 73cc053

template <class... Ts>
struct type_list {

Unsolicited suggestion: while you're at it, I like using operator+ for concatenation (so that things like join<TLs...> can just be implemented as decltype(TLs{} + ... + type_list<>{})). Maybe not relevant here, but fun thought for later. Here's where I do this in my toy library cutempl: https://github.com/dhollman/cutempl/blob/5bb6cae4423f0456c21e50454bcba210a94226b3/include/cutempl/containers/type_list.hpp#L14-L21


mp/include/boost/mp.hpp

Lines 389 to 393 in 73cc053

if constexpr (constexpr auto expr_fn = expr(fn); requires { expr_fn.vs; }) {
return [expr_fn]<auto... Ids>(std::index_sequence<Ids...>) {
return declval<
T<utility::nth_pack_element<expr_fn.vs[Ids], Ts...>...>>();
}(std::make_index_sequence<expr_fn.size>{});

I believe expr_fn doesn't need to be captured here since it's constexpr? (In fact, I think it's technically incorrect to do so, but the compiler is just okay with it?)

Also, shouldn't declval be a non-ADL call here since it could be ambiguous with std::declval if T is in std?


mp/include/boost/mp.hpp

Lines 443 to 444 in 73cc053

template <template <class, auto...> class T, class R, auto... Vs>
[[nodiscard]] constexpr auto operator|(T<R, Vs...>, auto fn) {

Seems like this one could just delegate to the previous overload? Something like value_list<Vs...> | fn | []<auto... Vvs> { return declval<T<R, Vvs...>>() }; (Obviously omitting some corner cases).


mp/include/boost/mp.hpp

Lines 486 to 488 in 73cc053

template <class T>
[[nodiscard]] constexpr auto operator|(T t, auto fn)
requires requires { t(); }

Seems like requires requires { []<class... Ts>(std::tuple<Ts...>){}(t()); } would be a more descriptive/self-documenting constraint here.


mp/include/boost/mp.hpp

Lines 714 to 715 in 73cc053

template <class... Ts>
overloaded(Ts...) -> overloaded<Ts...>;

This deduction guide should be unnecessary in C++20 and later


(expr(Ts) or ...);

Is there a reason to do this instead of using the comma operator? (Here and elsewhere; Also, if you do use the comma operator, you should do ((void)expr(Ts), ...) to work around overloaded comma operators)


mp/include/boost/mp.hpp

Lines 80 to 83 in 73cc053

std::size_t result{};
for (const auto c : std::array{Cs...}) {
result = result * std::size_t(10) + std::size_t(c - '0');
}

Really nit-picky, but you should ignore digit separators in this loop.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.