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>));
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<>));
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<>));