Skip to content

Latest commit

 

History

History
77 lines (54 loc) · 2.11 KB

372.md

File metadata and controls

77 lines (54 loc) · 2.11 KB
Info

Example

template<class...> struct type_list { };

using type = typename [: // splicer - produces an expression
      std::meta::substitute(^type_list, // not instantiated
          std::array{^int, ^float, ^short} // std::array{meta::info}
    | std::views::reverse // stl.ranges
    | std::views::drop(1)
    | std::ranges::to<std::vector>()
    )
:];

static_assert(typeid(type) == typeid(type_list<float, int>));

https://godbolt.org/z/TTGjxn7h8

Puzzle

  • Can you implement meta function which filter types which have value member?
template<class...> struct type_list { };

template<class... Ts>
using filter; // TODO

struct foo { int value; };
struct bar { };

static_assert(typeid(filter<int>) == typeid(type_list<>));
static_assert(typeid(filter<foo>) == typeid(type_list<foo>));
static_assert(typeid(filter<bar, foo>) == typeid(type_list<foo>));
static_assert(typeid(filter<int, double, foo, bar>) == typeid(type_list<foo>));
static_assert(typeid(filter<int, double, bar>) == typeid(type_list<>));

https://godbolt.org/z/er9GjWMMK

Solutions

template<class...> struct type_list { };

template<class T>
concept has_value = requires(T t) { t.value; };

template<class... Ts>
using filter = typename [: std::meta::substitute(^type_list,
    std::array{^Ts...}
  | std::views::filter([](auto m) { return test_type(^has_value, m); })
  | std::ranges::to<std::vector>())
:];

struct foo { int value; };
struct bar { };

static_assert(typeid(filter<int>) == typeid(type_list<>));
static_assert(typeid(filter<foo>) == typeid(type_list<foo>));
static_assert(typeid(filter<bar, foo>) == typeid(type_list<foo>));
static_assert(typeid(filter<int, double, foo, bar>) == typeid(type_list<foo>));
static_assert(typeid(filter<int, double, bar>) == typeid(type_list<>));

https://godbolt.org/z/EMnrjabfK