1#ifndef BLUETOE_META_TOOLS_HPP
2#define BLUETOE_META_TOOLS_HPP
15 template <
typename T >
21 template <
bool Select >
22 struct select_type_impl {
23 template <
typename A,
typename B >
28 struct select_type_impl< false > {
29 template <
typename A,
typename B >
37 template <
bool Select,
typename A,
typename B >
38 using select_type = wrap< typename select_type_impl< Select >::template f< A, B > >;
46 template <
bool Select,
template <
typename >
class A,
template <
typename >
class B >
47 struct select_template_t1 {
48 template <
typename T1 >
52 template <
template <
typename >
class A,
template <
typename >
class B >
53 struct select_template_t1< false, A, B > {
54 template <
typename T1 >
59 template <
typename Null,
typename A >
65 template <
typename Null >
66 struct or_type_impl< Null, Null > {
67 template <
typename B >
75 template <
typename Null,
typename A,
typename B >
76 using or_type = wrap< typename or_type_impl< Null, A >::template f< B > >;
81 template <
class A,
class B >
84 typedef std::tuple< A, B > type;
87 template <
class T,
class ... Ts >
88 struct add_type< T, std::tuple< Ts... > >
90 typedef std::tuple< T, Ts... > type;
93 template <
class ...Ts,
class T >
94 struct add_type< std::tuple< Ts... >, T >
96 typedef std::tuple< Ts..., T > type;
99 template <
class ...As,
class ...Bs >
100 struct add_type< std::tuple< As... >, std::tuple< Bs...> >
102 typedef std::tuple< As..., Bs... > type;
113 template <
typename A,
typename Zero >
114 struct remove_if_equal;
116 template <
typename Zero >
117 struct remove_if_equal< std::tuple<>, Zero >
119 typedef std::tuple<> type;
126 struct remove_if_equal< std::tuple< Type >, Zero >
128 typedef std::tuple< Type > type;
135 struct remove_if_equal< std::tuple< Zero >, Zero >
137 typedef std::tuple<> type;
142 template <
typename ... >
class Templ,
145 struct remove_if_equal< std::tuple< Templ< Type > >, Templ< wildcard > >
147 typedef std::tuple<> type;
155 struct remove_if_equal< std::tuple< Type, Types... >, Zero >
157 typedef typename add_type<
158 typename remove_if_equal< std::tuple< Type >, Zero >::type,
159 typename remove_if_equal< std::tuple< Types... >, Zero >::type
166 template <
typename A,
typename B >
168 typedef A first_type;
169 typedef B second_type;
172 template <
typename T >
175 typedef std::integral_constant< bool, !T::value > type;
181 struct no_such_type {};
186 template <
typename T,
typename Default = no_such_type >
189 template <
typename Default >
190 struct last_type< std::tuple<>, Default >
192 using type = Default;
195 template <
typename T,
typename Default >
196 struct last_type< std::tuple< T >, Default >
201 template <
typename ...Ts,
typename T,
typename Default >
202 struct last_type< std::tuple< T, Ts... >, Default >
204 using type =
typename last_type< std::tuple< Ts... >, Default >::type;
207 template <
typename T >
208 struct extract_meta_type
211 static typename U::meta_type check( U&& ) {
return U::meta_type(); }
212 static no_such_type check( ... ) {
return no_such_type(); }
214 typedef decltype( check( std::declval< T >() ) ) meta_type;
215 typedef meta_type type;
216 typedef typename not_type<
217 typename std::is_same<
218 meta_type, no_such_type >::type >::type has_meta_type;
227 struct find_by_meta_type;
231 struct find_by_meta_type< MetaType >
233 typedef no_such_type type;
239 struct find_by_meta_type< MetaType, Type >
241 typedef extract_meta_type< Type > meta_type;
243 std::is_convertible< typename meta_type::type*, MetaType* >::value,
244 Type, no_such_type >::type type;
251 struct find_by_meta_type< MetaType, Type, Types... >
255 typename find_by_meta_type< MetaType, Type >::type,
256 typename find_by_meta_type< MetaType, Types... >::type >::type type;
265 struct find_by_not_meta_type;
269 struct find_by_not_meta_type< MetaType >
271 typedef no_such_type type;
277 struct find_by_not_meta_type< MetaType, Type >
279 typedef extract_meta_type< Type > meta_type;
281 std::is_convertible< typename meta_type::type*, MetaType* >::value,
282 no_such_type, Type >::type type;
289 struct find_by_not_meta_type< MetaType, Type, Types... >
293 typename find_by_not_meta_type< MetaType, Type >::type,
294 typename find_by_not_meta_type< MetaType, Types... >::type >::type type;
303 struct find_all_by_meta_type;
307 struct find_all_by_meta_type< MetaType >
309 typedef std::tuple<> type;
316 struct find_all_by_meta_type< MetaType, Type, Types... >
318 typedef extract_meta_type< Type > meta_type;
320 std::is_convertible< typename meta_type::type*, MetaType* >::value,
321 typename add_type< Type,
typename find_all_by_meta_type< MetaType, Types... >::type >::type,
322 typename find_all_by_meta_type< MetaType, Types... >::type >::type type;
328 struct find_all_by_meta_type< MetaType, std::tuple< Types... > > : find_all_by_meta_type< MetaType, Types... > {};
336 struct find_all_by_not_meta_type;
340 struct find_all_by_not_meta_type< MetaType >
342 typedef std::tuple<> type;
349 struct find_all_by_not_meta_type< MetaType, Type, Types... >
351 typedef extract_meta_type< Type > meta_type;
353 std::is_convertible< typename meta_type::type*, MetaType* >::value,
354 typename find_all_by_not_meta_type< MetaType, Types... >::type,
355 typename add_type< Type,
typename find_all_by_not_meta_type< MetaType, Types... >::type >::type
362 struct find_all_by_not_meta_type< MetaType, std::tuple< Types... > > : find_all_by_not_meta_type< MetaType, Types... > {};
372 typename ... MetaTypes >
373 struct group_by_meta_types;
377 struct group_by_meta_types< std::tuple< Types... > >
379 typedef std::tuple<> type;
385 struct group_by_meta_types< std::tuple< Types... >, MetaType >
390 typename find_all_by_meta_type< MetaType, Types... >::type
398 typename ... MetaTypes >
399 struct group_by_meta_types< std::tuple< Types... >, MetaType, MetaTypes... >
401 typedef typename add_type<
402 typename group_by_meta_types< std::tuple< Types... >, MetaType >::type,
403 typename group_by_meta_types< std::tuple< Types... >, MetaTypes... >::type >::type type;
411 typename ... MetaTypes >
412 struct group_by_meta_types_without_empty_groups;
416 typename ... MetaTypes >
417 struct group_by_meta_types_without_empty_groups< std::tuple< Types... >, MetaTypes...>
419 typedef typename remove_if_equal<
420 typename group_by_meta_types< std::tuple< Types... >, MetaTypes... >::type,
421 std::tuple< wildcard >
432 struct count_by_meta_type;
436 struct count_by_meta_type< MetaType > {
444 struct count_by_meta_type< MetaType, Type, Types... > {
445 typedef extract_meta_type< Type > meta_type;
447 enum { count = std::is_convertible< typename meta_type::type*, MetaType* >::value
448 ? 1 + count_by_meta_type< MetaType, Types... >::count
449 : 0 + count_by_meta_type< MetaType, Types... >::count
458 template <
typename >
class Predicate
463 template <
typename >
class Predicate
465 struct count_if< std::tuple<>, Predicate > : std::integral_constant< int, 0 > {};
469 template <
typename >
class Predicate
471 struct count_if< std::tuple< T >, Predicate > : std::integral_constant< int, Predicate< T >::value ? 1 : 0 > {};
476 template <
typename >
class Predicate
478 struct count_if< std::tuple< T, Ts... >, Predicate > : std::integral_constant< int,
479 count_if< std::tuple< T >, Predicate >::value
480 + count_if< std::tuple< Ts... >, Predicate >::value > {};
487 template <
typename >
class Predicate
492 template <
typename >
class Predicate
494 struct sum_by< std::tuple<>, Predicate > : std::integral_constant< int, 0 > {};
498 template <
typename >
class Predicate
500 struct sum_by< std::tuple< T >, Predicate > : std::integral_constant< int, Predicate< T >::value > {};
505 template <
typename >
class Predicate
507 struct sum_by< std::tuple< T, Ts... >, Predicate > : std::integral_constant< int,
508 sum_by< std::tuple< T >, Predicate >::value
509 + sum_by< std::tuple< Ts... >, Predicate >::value > {};
516 typename ... Options >
521 struct has_option< Option > {
522 static bool constexpr value =
false;
527 typename FirstOption,
528 typename ... Options >
529 struct has_option< Option, FirstOption, Options... > {
530 static bool constexpr value =
531 std::is_same< Option, FirstOption >::value || has_option< Option, Options... >::value;
556 typename ... Options >
562 template <
typename Function >
563 static void each( Function )
569 typename ... Options >
570 struct for_impl< Option, Options... >
572 template <
typename Function >
573 static void each( Function f )
575 f.template each< Option >();
576 for_impl< Options... >::template each< Function >( f );
581 typename ... Options >
582 struct for_ : for_impl< Options... >
587 typename ... Options >
588 struct for_< std::tuple< Options... > > : for_impl< Options... >
597 template <
typename >
class Func
602 template <
typename >
class Func
604 struct find_if< std::tuple<>, Func > {
605 typedef no_such_type type;
611 template <
typename >
class Func
613 struct find_if< std::tuple< T, Ts...>, Func > {
617 typename find_if< std::tuple< Ts... >, Func >::type >::type type;
621 template <
typename ... Ts >
622 struct last_from_pack;
624 template <
typename T >
625 struct last_from_pack< T > {
632 struct last_from_pack< T, Ts... > {
633 typedef typename last_from_pack< Ts... >::type type;
637 template <
typename MetaType >
638 struct empty_meta_type {
639 typedef MetaType meta_type;
642 template <
typename ... Ts >
643 struct derive_from_impl;
646 struct derive_from_impl<> {};
648 template <
typename T,
typename ... Ts >
649 struct derive_from_impl< T, Ts... > : T, derive_from_impl< Ts... > {};
652 template <
typename List >
655 template <
typename ... Ts >
656 struct derive_from< std::tuple< Ts... > > : derive_from_impl< Ts... > {};
661 template <
typename ListP,
typename ElementP >
class Operation,
662 typename Start = std::tuple<> >
666 template <
typename List,
typename Element >
class Operation,
668 struct fold< std::tuple<>, Operation, Start >
676 template <
typename List,
typename Element >
class Operation,
678 struct fold< std::tuple< T, Ts... >, Operation, Start >
680 typedef typename Operation<
typename fold< std::tuple< Ts... >, Operation, Start >::type, T >::type type;
685 template <
typename ListP,
typename ElementP >
class Operation,
686 typename Start = std::tuple<> >
687 struct fold_right : fold< List, Operation, Start > {};
692 template <
typename ListP,
typename ElementP >
class Operation,
693 typename Start = std::tuple<> >
697 struct fold_left_impl;
700 struct fold_left_impl< false > {
702 template <
typename,
typename >
class,
709 struct fold_left_impl< true > {
711 template <
typename,
typename >
class Operation,
715 using f =
typename fold_left_impl<
sizeof...(Ts) != 0 >::template f< Operation,
typename Operation< Start, T >::type, Ts... >;
720 template <
typename ListP,
typename ElementP >
class Operation,
722 struct fold_left< std::tuple< Ts... >, Operation, Start > :
723 wrap< typename fold_left_impl< sizeof...(Ts) != 0 >::template f< Operation, Start, Ts... > >
726 template <
template <
typename >
class Transform >
727 struct apply_transformation
729 template <
typename List,
typename Element >
732 using type =
typename add_type< List, typename Transform< Element >::type >::type;
741 template <
typename >
class Transform
743 struct transform_list : fold_left< List, apply_transformation< Transform >::template apply > {};
747 template <
typename T,
typename ... Ts >
751 template <
typename T,
typename O >
752 struct index_of< T, O > {
753 static constexpr unsigned value = 1;
757 template <
typename T >
758 struct index_of< T > {
759 static constexpr unsigned value = 0;
762 template <
typename T >
763 struct index_of< T, T > {
764 static constexpr unsigned value = 0;
767 template <
typename T,
typename ... Ts >
768 struct index_of< T, T, Ts... > {
769 static constexpr unsigned value = 0;
772 template <
typename T,
typename O,
typename ... Ts >
773 struct index_of< T, O, Ts... > {
774 static constexpr unsigned value = index_of< T, Ts... >::value + 1;
777 template <
typename T,
typename ... Ts >
778 struct index_of< T, std::tuple< Ts... > > : index_of< T, Ts... > {};
783 template <
template <
typename,
typename >
class Order,
typename T,
typename ...Ts >
784 struct stable_insert;
786 template <
template <
typename,
typename >
class Order,
typename T,
typename ...Ts >
787 struct stable_insert< Order, T, std::tuple< Ts... > > : stable_insert< Order, T, Ts... > {};
789 template <
template <
typename,
typename >
class Order,
typename T >
790 struct stable_insert< Order, T >
792 using type = std::tuple< T >;
795 template <
template <
typename,
typename >
class Order,
typename T,
typename First,
typename ...Ts >
796 struct stable_insert< Order, T, First, Ts... >
799 Order< First, T >::type::value,
800 typename add_type< First,
typename stable_insert< Order, T, Ts... >::type >::type,
801 std::tuple< T, First, Ts... >
810 template <
template <
typename,
typename >
class Order,
typename ...Ts >
813 template <
template <
typename,
typename >
class Order,
typename ...Ts >
814 struct stable_sort< Order, std::tuple< Ts... > > : stable_sort< Order, Ts... > {};
816 template <
template <
typename,
typename >
class Order >
817 struct stable_sort< Order, std::tuple<> >
819 using type = std::tuple<>;
822 template <
template <
typename,
typename >
class Order >
823 struct stable_sort< Order >
825 using type = std::tuple<>;
828 template <
template <
typename,
typename >
class Order,
typename T,
typename ...Ts >
829 struct stable_sort< Order, T, Ts... >
831 using rest =
typename stable_sort< Order, Ts... >::type;
832 using type =
typename stable_insert< Order, T, rest >::type;
840 template <
typename Map,
typename Key,
typename Default = no_such_type >
843 template <
typename Key,
typename Default >
844 struct map_find< std::tuple<>, Key, Default >
846 using type = Default;
849 template <
typename Value,
typename Key,
typename ...Ts,
typename Default >
850 struct map_find< std::tuple< pair< Key, Value >, Ts... >, Key, Default >
855 template <
typename Value,
typename NotKey,
typename Key,
typename ...Ts,
typename Default >
856 struct map_find< std::tuple< pair< NotKey, Value >, Ts... >, Key, Default >
858 using type =
typename map_find< std::tuple< Ts... >, Key, Default >::type;
862 template <
typename Map,
typename Key >
865 template <
typename Key >
866 struct map_erase< std::tuple<>, Key >
868 using type = std::tuple<>;
871 template <
typename Key,
typename Value,
typename ...Ts >
872 struct map_erase< std::tuple< pair< Key, Value >, Ts... >, Key >
874 using type = std::tuple< Ts... >;
877 template <
typename Key,
typename NotKey,
typename Value,
typename ...Ts >
878 struct map_erase< std::tuple< pair< NotKey, Value >, Ts... >, Key >
880 using type =
typename add_type<
881 pair< NotKey, Value >,
882 typename map_erase< std::tuple< Ts...>, Key >::type
887 template <
typename Map,
typename Key,
typename Value >
890 using type =
typename add_type<
892 typename map_erase< Map, Key >::type >::type;