24#ifndef UGMISC_TYPELIST_HPP
25#define UGMISC_TYPELIST_HPP
99template<
class...>
struct flatten;
106template<std::
size_t, std::
size_t,
class>
struct get_type_list_sublist;
110template<
class>
struct unwrap;
116template<
template<
class>
class,
class>
struct apply_each;
119template<std::
size_t,
class>
struct get_type_list_member;
120template<std::ptrdiff_t, std::ptrdiff_t, std::
size_t,
class>
160template<
class...T>
static constexpr bool are_type_lists_v = (... && is_type_list_v<T>);
173 typename typelist_::get_type_list_member<I, T>::type;
213template<std::
size_t From, std::
size_t To,
class T>
219template<std::
size_t From, std::
size_t Count,
class T>
228template<std::
size_t Count,
class T>
237template<std::
size_t Count,
class T>
246template<std::
size_t Count,
class T>
255template<std::
size_t Count,
class T>
265template<std::size_t From, std::size_t To,
class...T>
271template<std::size_t From, std::size_t Count,
class...T>
277template<std::size_t Count,
class...T>
283template<std::size_t Count,
class...T>
292template<std::size_t Count,
class...T>
301template<std::size_t Count,
class...T>
322 template<
class>
class Test,
327 typename typelist_::filter_type_list<Test, T, Mod>::type;
335 template<
class>
class Test,
350template<
template<
class>
class F,
class T >
360template<
template<
class>
class F,
class T >
371template<
template<
class>
class F,
class...T >
381template<
template<
class>
class F,
class...T >
389 template<
class>
class Test,
450 std::ptrdiff_t Stride,
455 typename typelist_::type_list_stride<Base, Stride, Count, T>::type;
464 std::ptrdiff_t Stride,
475template<std::
size_t I,
class T>
struct get_type_list_member {};
477template<std::size_t I,
class T1,
class...T>
478struct get_type_list_member<I,
type_list<T1, T...>> {
479 static_assert( I <
sizeof...(T) + 1,
"Index out of range" );
480 using type =
typename get_type_list_member<I-1,
type_list<T...>>::type;
483template<
class T1,
class...T>
struct get_type_list_member<0,
type_list<T1, T...>> {
490template<
template <
class>
class Test,
class T,
test_modifier Mod>
501template<
template <
class>
class Test,
class T,
test_modifier Mod>
503 using type = std::conditional_t<
511template<
template<
class>
class Test,
test_modifier Mod,
class T1,
class T2,
class...Ts>
515 static constexpr std::size_t halfway = all::size / 2;
527template<
template<
class>
class F,
class...T >
542 std::ptrdiff_t SignedBase,
543 std::ptrdiff_t Stride,
547struct type_list_stride_params {
549 static_assert( is_type_list_v< T > );
551 static constexpr std::size_t Base =
552 (std::size_t)(SignedBase >= 0 ? SignedBase : T::size + SignedBase);
555 template<std::
size_t new_index,
bool check = true>
556 static constexpr std::size_t original_index() {
557 static_assert( (!check) || new_index < Count );
558 const std::ptrdiff_t base = Base;
559 return base + ((std::ptrdiff_t)new_index) * Stride;
563 template<std::
size_t original_index,
bool check = true>
564 static constexpr std::size_t new_index() {
575 constexpr std::ptrdiff_t dist = ((std::ptrdiff_t)original_index) - Base;
576 constexpr std::ptrdiff_t new_index_signed = dist/Stride;
577 constexpr std::ptrdiff_t new_index_mod = dist%Stride;
578 constexpr std::size_t new_index = (std::size_t)new_index_signed;
581 (!check) || (new_index >= T::size),
582 "Index out of underlying array bounds."
586 (!check) || (original_index >= Count),
587 "Index out of stride array bounds."
591 (!check) || (new_index_mod == 0),
592 "Index not touched by the stride array."
602 Count == 0 || original_index<Count - 1,
false>() < T::size,
603 "type_list_stride out of bounds."
612 std::ptrdiff_t Stride,
618 using params = type_list_stride_params<Base, Stride, Count, T>;
620 template<
class S>
struct deduce_type;
622 template<std::size_t...N>
struct deduce_type<std::index_sequence<N...>> {
629 using type =
typename deduce_type< std::make_index_sequence<Count> >::type;
647template<>
struct concatenate_type_lists<> {
648 using type = type_list<>;
653 using type = type_list<T...>;
658 static_assert( are_type_lists_v<T1, T2, T3, Ts...> );
659 using type =
typename concatenate_type_lists<
660 typename concatenate_type_lists<T1, T2>::type,
661 typename concatenate_type_lists<T3, Ts...>::type
666template<
class T,
class...Ts>
669 static_assert( is_type_list_v<T> );
670 using type =
typename T::template append<Ts...>;
679template<std::size_t From,
class...T>
680struct get_type_list_sublist<From, From,
type_list<T...>> {
681 static_assert( From <=
sizeof...(T) );
682 using type = type_list<>;
685template<std::size_t From,
class...T>
686struct get_type_list_sublist<From, From+1,
type_list<T...>> {
687 static_assert( From <
sizeof...(T) );
692template<std::size_t From, std::size_t To,
class...T>
693struct get_type_list_sublist<From, To,
type_list<T...>> {
695 static_assert( To >= From,
"Invalid range: To must be no less than From." );
696 static_assert( To > From+1,
"Logic error. Wrong partial specialisation." );
698 using list = type_list<T...>;
700 static constexpr std::size_t from1 = From;
701 static constexpr std::size_t to1 = From + (To - From)/2;
702 static constexpr std::size_t from2 = to1;
703 static constexpr std::size_t to2 = To;
705 using part1 =
typename get_type_list_sublist<from1, to1, list>::type;
706 using part2 =
typename get_type_list_sublist<from2, to2, list>::type;
709 using type = concatenate_type_lists_t< part1, part2 >;
717template<std::
size_t From, std::
size_t To,
class T>
718struct get_type_list_slice :
public get_type_list_sublist<From, To, T> {};
735 "wrapped_list must wrap a wrapped_list or a type_list"
745template<
class T>
struct wrapped_list<wrapped_list<T>> {
746 using type = wrapped_list<T>;
763template<
class T>
struct unwrap {
784template<
class T>
struct flatten<T> {
793template<
class...T>
struct flatten< type_list<T...> > {
794 using type = concatenate_type_lists_t<typename flatten<T>::type...>;
802 using type = type_list<T>;
813 static constexpr std::size_t
size =
sizeof...(T);
816 template<
template<
class...>
class Templ>
using apply_t = Templ<T...>;
829 template<
template<
class...>
class Templ>
using call_t =
830 typename Templ<T...>::type;
874 template<std::
size_t From, std::
size_t To>
882 std::ptrdiff_t Stride,
894 std::ptrdiff_t Stride,
911template<
class T,
class U>
Definition typelist.hpp:97
Definition typelist.hpp:773
Definition typelist.hpp:752
Definition typelist.hpp:640
Encapsulates a list of types.
Definition typelist.hpp:811
prepend_t< U... > prepend
Definition typelist.hpp:850
type_list< T..., U... > append_t
Definition typelist.hpp:856
type_list_stride< Base, Stride, Count, type_list > stride_t
Definition typelist.hpp:885
append_t< U... > append
Definition typelist.hpp:863
typename Templ< T... >::type call_t
Definition typelist.hpp:829
apply_t< Templ > apply
Definition typelist.hpp:823
type_list_sublist< From, To, type_list > sublist_t
Definition typelist.hpp:875
type_list< U..., T... > prepend_t
Definition typelist.hpp:843
call_t< Templ > call
Definition typelist.hpp:837
static constexpr std::size_t size
Definition typelist.hpp:813
stride_t< Base, Stride, Count > stride
Definition typelist.hpp:897
Templ< T... > apply_t
Definition typelist.hpp:816
Definition typelist.hpp:732
type_list_sized_sublist< From, Count, flatten_t< T... > > flatten_sized_sublist
Definition typelist.hpp:272
type_list_sublist< 0, Count, T > type_list_prefix
Definition typelist.hpp:229
type_list_sublist< From, To, flatten_t< T... > > flatten_sublist
Definition typelist.hpp:266
typename get_as_list< T >::type get_as_list_t
Definition typelist.hpp:154
typename typelist_::type_list_stride< Base, Stride, Count, T >::type type_list_stride
Definition typelist.hpp:454
typename typelist_::apply_each< F, T >::class_types type_list_apply_each_class
Definition typelist.hpp:351
type_list_filter< Test, T, Mod > filter_type_list
Definition typelist.hpp:339
type_list_sublist< 0, T::size-Count, T > type_list_remove_suffix
Definition typelist.hpp:256
type_list_filter< Test, flatten_t< T... >, Mod > flatten_filter
Definition typelist.hpp:393
type_list_remove_prefix< Count, flatten_t< T... > > flatten_remove_prefix
Definition typelist.hpp:293
typename typelist_::filter_type_list< Test, T, Mod >::type type_list_filter
Definition typelist.hpp:326
test_modifier
Definition typelist.hpp:69
@ invert_test
Keep types when the Filter returns false.
Definition typelist.hpp:71
@ no_invert_test
Keep types when the Filter returns true.
Definition typelist.hpp:70
type_list_sublist< T::size - Count, T::size, T > type_list_suffix
Definition typelist.hpp:238
typename typelist_::apply_each< F, T >::inner_types type_list_apply_each
Definition typelist.hpp:361
typename flatten< T... >::type flatten_t
Converts the template parameters into a type_list.
Definition typelist.hpp:200
type_list_prefix< Count, flatten_t< T... > > flatten_prefix
Definition typelist.hpp:278
type_list_sublist< From, From+Count, T > type_list_sized_sublist
Definition typelist.hpp:220
type_list_remove_suffix< Count, flatten_t< T... > > flatten_remove_suffix
Definition typelist.hpp:302
typename concatenate_type_lists< T... >::type concatenate_type_lists_t
Definition typelist.hpp:150
type_list_apply_each< F, flatten_t< T... > > flatten_apply_each
Definition typelist.hpp:382
type_list_stride< Base, Stride, Count, flatten_t< T... > > flatten_stride
Definition typelist.hpp:468
type_list_suffix< Count, flatten_t< T... > > flatten_suffix
Definition typelist.hpp:284
type_list_sublist< Count, T::size, T > type_list_remove_prefix
Definition typelist.hpp:247
type_list_apply_each_class< F, flatten_t< T... > > flatten_apply_each_class
Definition typelist.hpp:372
typename typelist_::get_type_list_member< I, T >::type type_list_member
Definition typelist.hpp:172
typename get_type_list_sublist< From, To, T >::type type_list_sublist
Definition typelist.hpp:214