5#ifndef UGMISC_TYPELIST_HPP
6#define UGMISC_TYPELIST_HPP
121template<
class...>
struct flatten;
128template<std::
size_t, std::
size_t,
class>
struct get_type_list_sublist;
132template<
class>
struct unwrap;
138template<
template<
class>
class,
class>
struct apply_each;
141template<
class T>
struct get_type_list_from_tparams;
142template<std::
size_t,
class>
struct get_type_list_member;
143template<std::ptrdiff_t, std::ptrdiff_t, std::
size_t,
class>
183template<
class...T>
static constexpr bool are_type_lists_v = (... && is_type_list_v<T>);
196 typename typelist_::get_type_list_member<I, T>::type;
212 typename typelist_::get_type_list_from_tparams<T>::type;
252template<std::
size_t From, std::
size_t To,
class T>
258template<std::
size_t From, std::
size_t Count,
class T>
267template<std::
size_t Count,
class T>
276template<std::
size_t Count,
class T>
285template<std::
size_t Count,
class T>
294template<std::
size_t Count,
class T>
304template<std::size_t From, std::size_t To,
class...T>
310template<std::size_t From, std::size_t Count,
class...T>
316template<std::size_t Count,
class...T>
322template<std::size_t Count,
class...T>
331template<std::size_t Count,
class...T>
340template<std::size_t Count,
class...T>
361 template<
class>
class Test,
366 typename typelist_::filter_type_list<Test, T, Mod>::type;
374 template<
class>
class Test,
389template<
template<
class>
class F,
class T >
399template<
template<
class>
class F,
class T >
410template<
template<
class>
class F,
class...T >
420template<
template<
class>
class F,
class...T >
428 template<
class>
class Test,
489 std::ptrdiff_t Stride,
494 typename typelist_::type_list_stride<Base, Stride, Count, T>::type;
503 std::ptrdiff_t Stride,
514template<
template<
class...>
class Tmpl,
class...T>
515struct get_type_list_from_tparams<Tmpl<T...>> {
519template<
template<
class U, U...>
class Tmpl,
class T, T...V>
520struct get_type_list_from_tparams<Tmpl<T, V...>> {
524template<std::
size_t I,
class T>
struct get_type_list_member {};
526template<std::size_t I,
class T1,
class...T>
527struct get_type_list_member<I,
type_list<T1, T...>> {
528 static_assert( I <
sizeof...(T) + 1,
"Index out of range" );
529 using type =
typename get_type_list_member<I-1,
type_list<T...>>::type;
532template<
class T1,
class...T>
struct get_type_list_member<0,
type_list<T1, T...>> {
539template<
template <
class>
class Test,
class T,
test_modifier Mod>
550template<
template <
class>
class Test,
class T,
test_modifier Mod>
552 using type = std::conditional_t<
560template<
template<
class>
class Test,
test_modifier Mod,
class T1,
class T2,
class...Ts>
564 static constexpr std::size_t halfway = all::size / 2;
576template<
template<
class>
class F,
class...T >
591 std::ptrdiff_t SignedBase,
592 std::ptrdiff_t Stride,
596struct type_list_stride_params {
598 static_assert( is_type_list_v< T > );
600 static constexpr std::size_t Base =
601 (std::size_t)(SignedBase >= 0 ? SignedBase : T::size + SignedBase);
604 template<std::
size_t new_index,
bool check = true>
605 static constexpr std::size_t original_index() {
606 static_assert( (!check) || new_index < Count );
607 const std::ptrdiff_t base = Base;
608 return base + ((std::ptrdiff_t)new_index) * Stride;
612 template<std::
size_t original_index,
bool check = true>
613 static constexpr std::size_t new_index() {
624 constexpr std::ptrdiff_t dist = ((std::ptrdiff_t)original_index) - Base;
625 constexpr std::ptrdiff_t new_index_signed = dist/Stride;
626 constexpr std::ptrdiff_t new_index_mod = dist%Stride;
627 constexpr std::size_t new_index = (std::size_t)new_index_signed;
630 (!check) || (new_index >= T::size),
631 "Index out of underlying array bounds."
635 (!check) || (original_index >= Count),
636 "Index out of stride array bounds."
640 (!check) || (new_index_mod == 0),
641 "Index not touched by the stride array."
651 Count == 0 || original_index<Count - 1,
false>() < T::size,
652 "type_list_stride out of bounds."
661 std::ptrdiff_t Stride,
667 using params = type_list_stride_params<Base, Stride, Count, T>;
669 template<
class S>
struct deduce_type;
671 template<std::size_t...N>
struct deduce_type<std::index_sequence<N...>> {
678 using type =
typename deduce_type< std::make_index_sequence<Count> >::type;
696template<>
struct concatenate_type_lists<> {
697 using type = type_list<>;
702 using type = type_list<T...>;
707 static_assert( are_type_lists_v<T1, T2, T3, Ts...> );
708 using type =
typename concatenate_type_lists<
709 typename concatenate_type_lists<T1, T2>::type,
710 typename concatenate_type_lists<T3, Ts...>::type
715template<
class T,
class...Ts>
718 static_assert( is_type_list_v<T> );
719 using type =
typename T::template append_t<Ts...>;
728template<std::size_t From,
class...T>
729struct get_type_list_sublist<From, From,
type_list<T...>> {
730 static_assert( From <=
sizeof...(T) );
731 using type = type_list<>;
734template<std::size_t From,
class...T>
735struct get_type_list_sublist<From, From+1,
type_list<T...>> {
736 static_assert( From <
sizeof...(T) );
741template<std::size_t From, std::size_t To,
class...T>
742struct get_type_list_sublist<From, To,
type_list<T...>> {
744 static_assert( To >= From,
"Invalid range: To must be no less than From." );
745 static_assert( To > From+1,
"Logic error. Wrong partial specialisation." );
747 using list = type_list<T...>;
749 static constexpr std::size_t from1 = From;
750 static constexpr std::size_t to1 = From + (To - From)/2;
751 static constexpr std::size_t from2 = to1;
752 static constexpr std::size_t to2 = To;
754 using part1 =
typename get_type_list_sublist<from1, to1, list>::type;
755 using part2 =
typename get_type_list_sublist<from2, to2, list>::type;
758 using type = concatenate_type_lists_t< part1, part2 >;
766template<std::
size_t From, std::
size_t To,
class T>
767struct get_type_list_slice :
public get_type_list_sublist<From, To, T> {};
784 "wrapped_list must wrap a wrapped_list or a type_list"
794template<
class T>
struct wrapped_list<wrapped_list<T>> {
795 using type = wrapped_list<T>;
812template<
class T>
struct unwrap {
833template<
class T>
struct flatten<T> {
842template<
class...T>
struct flatten< type_list<T...> > {
843 using type = concatenate_type_lists_t<typename flatten<T>::type...>;
851 using type = type_list<T>;
864 template<
class,
class...>
865 struct stride_support;
868 template<
class,
class...>
869 struct sublist_support;
872 using stride_method_return =
typename stride_support<void, U...>::type;
875 using sublist_method_return =
typename sublist_support<void, U...>::type;
880 static constexpr std::size_t
size =
sizeof...(T);
884 template<
template<
class...>
class Templ>
using apply_t = Templ<T...>;
897 template<
template<
class...>
class Templ>
using call_t =
898 typename Templ<T...>::type;
970 template<std::
size_t From, std::
size_t To>
986 template<
class...U >
987 static constexpr sublist_method_return<U...>
sublist(U...) {
return {}; }
994 std::ptrdiff_t Stride,
1012 template<
class...U >
1013 static constexpr stride_method_return<U...>
stride(U...) {
return {}; }
1020 struct IgnoreVal {};
1026 template<
template<
class I, I...>
class Tmpl,
class U, U B, U S, U C >
1027 struct stride_support<
1028 std::enable_if_t< std::numeric_limits<U>::is_integer >,
1032 using type = stride_t<
1043 template<
class B,
class S,
class C >
1044 struct stride_support<
1047 std::numeric_limits<decltype(B::value)>::is_integer
1048 && std::numeric_limits<decltype(S::value)>::is_integer
1049 && std::numeric_limits<decltype(C::value)>::is_integer
1051 IgnoreVal<(std::ptrdiff_t)B::value>,
1052 IgnoreVal<(std::ptrdiff_t)S::value>,
1053 IgnoreVal<(std::size_t)C::value>
1058 using type = stride_t<
1059 (std::ptrdiff_t)B::value,
1060 (std::ptrdiff_t)S::value,
1061 (std::size_t)C::value
1069 template<
template<
class I, I...>
class Tmpl,
class U, U From, U To >
1070 struct sublist_support<
1071 std::enable_if_t< std::numeric_limits<U>::is_integer >,
1075 using type = sublist_t<
1085 template<
class From,
class To >
1086 struct sublist_support<
1089 std::numeric_limits<decltype(From::value)>::is_integer
1090 && std::numeric_limits<decltype(To::value)>::is_integer
1092 IgnoreVal<(std::size_t)From::value>,
1093 IgnoreVal<(std::size_t)To::value>
1098 using type = sublist_t<
1099 (std::size_t)From::value,
1100 (std::size_t)To::value
1118template<
class T,
class U>
1127template<
class T,
class U>
1128constexpr auto operator == (T, U)
1129 -> std::enable_if_t< is_type_list_v<T> && is_type_list_v<U>,
bool >
1131 return std::is_same_v<T, U>;
1134template<
class T,
class U>
1135constexpr auto operator != (T, U)
1136 -> std::enable_if_t< is_type_list_v<T> && is_type_list_v<U>,
bool >
1138 return ! std::is_same_v<T, U>;
Encapsulates a list of types.
static constexpr append_t< U... > append(type_list< U... >)
type_list< T..., U... > append_t
type_list_stride< Base, Stride, Count, type_list > stride_t
typename Templ< T... >::type call_t
static constexpr stride_method_return< U... > stride(U...)
static constexpr sublist_method_return< U... > sublist(U...)
type_list_sublist< From, To, type_list > sublist_t
type_list< U..., T... > prepend_t
static constexpr std::size_t size
static constexpr prepend_t< U... > prepend(type_list< U... >)
type_list_sized_sublist< From, Count, flatten_t< T... > > flatten_sized_sublist
type_list_sublist< 0, Count, T > type_list_prefix
type_list_sublist< From, To, flatten_t< T... > > flatten_sublist
typename get_as_list< T >::type get_as_list_t
typename typelist_::type_list_stride< Base, Stride, Count, T >::type type_list_stride
typename typelist_::apply_each< F, T >::class_types type_list_apply_each_class
type_list_filter< Test, T, Mod > filter_type_list
type_list_sublist< 0, T::size-Count, T > type_list_remove_suffix
type_list_filter< Test, flatten_t< T... >, Mod > flatten_filter
type_list_remove_prefix< Count, flatten_t< T... > > flatten_remove_prefix
typename typelist_::filter_type_list< Test, T, Mod >::type type_list_filter
typename typelist_::get_type_list_from_tparams< T >::type type_list_from_tparams
@ invert_test
Keep types when the Filter returns false.
@ no_invert_test
Keep types when the Filter returns true.
type_list_sublist< T::size - Count, T::size, T > type_list_suffix
typename typelist_::apply_each< F, T >::inner_types type_list_apply_each
typename flatten< T... >::type flatten_t
Converts the template parameters into a type_list.
type_list_prefix< Count, flatten_t< T... > > flatten_prefix
type_list_sublist< From, From+Count, T > type_list_sized_sublist
type_list_remove_suffix< Count, flatten_t< T... > > flatten_remove_suffix
typename concatenate_type_lists< T... >::type concatenate_type_lists_t
type_list_apply_each< F, flatten_t< T... > > flatten_apply_each
type_list_stride< Base, Stride, Count, flatten_t< T... > > flatten_stride
type_list_suffix< Count, flatten_t< T... > > flatten_suffix
type_list_sublist< Count, T::size, T > type_list_remove_prefix
type_list_apply_each_class< F, flatten_t< T... > > flatten_apply_each_class
typename typelist_::get_type_list_member< I, T >::type type_list_member
typename get_type_list_sublist< From, To, T >::type type_list_sublist