#pragma once #include #include namespace c10 { namespace guts { template struct false_t : std::false_type {}; template class... T> struct false_higher_t : std::false_type {}; namespace typelist { /** * Type holding a list of types for compile time type computations */ template struct typelist final { private: typelist() = delete; // not for instantiation }; /** * Returns the number of types in a typelist * Example: * 3 == size>::value */ template struct size final { static_assert(false_t::value, "In typelist::size, T must be typelist<...>."); }; template struct size> final { static constexpr size_t value = sizeof...(Types); }; /** * Transforms a list of types into a tuple holding these types. * Example: * std::tuple == to_tuple_t> */ template struct to_tuple final { static_assert(false_t::value, "In typelist::to_tuple, T must be typelist<...>."); }; template struct to_tuple> final { using type = std::tuple; }; template using to_tuple_t = typename to_tuple::type; /** * Creates a typelist containing the types of a given tuple. * Example: * typelist == from_tuple_t> */ template struct from_tuple final { static_assert(false_t::value, "In typelist::from_tuple, T must be std::tuple<...>."); }; template struct from_tuple> final { using type = typelist; }; template using from_tuple_t = typename from_tuple::type; /** * Concatenates multiple type lists. * Example: * typelist == concat_t, typelist> */ template struct concat final { static_assert(false_t::value, "In typelist::concat, the T arguments each must be typelist<...>."); }; template struct concat, typelist, TailLists...> final { using type = typename concat, TailLists...>::type; }; template struct concat> final { using type = typelist; }; template<> struct concat<> final { using type = typelist<>; }; template using concat_t = typename concat::type; /** * Filters the types in a type list by a type trait. * Examples: * typelist == filter_t> */ template