Meta  0.1
A tiny metaprogramming library
meta.hpp
Go to the documentation of this file.
1 //
3 // Meta library
4 //
5 // Copyright Eric Niebler 2014-2015
6 //
7 // Use, modification and distribution is subject to the
8 // Boost Software License, Version 1.0. (See accompanying
9 // file LICENSE_1_0.txt or copy at
10 // http://www.boost.org/LICENSE_1_0.txt)
11 //
12 // Project home: https://github.com/ericniebler/meta
13 //
14 
15 #ifndef META_HPP
16 #define META_HPP
17 
18 #include <cstddef>
19 #include <initializer_list>
20 #include <type_traits>
21 #include <utility>
22 #include <meta/meta_fwd.hpp>
23 
24 #if defined(__clang__)
25 #pragma GCC diagnostic push
26 #pragma GCC diagnostic ignored "-Wunknown-pragmas"
27 #pragma GCC diagnostic ignored "-Wpragmas"
28 #pragma GCC diagnostic ignored "-Wdocumentation-deprecated-sync"
29 #endif
30 
34 
38 
42 
46 
50 
54 
58 
62 
66 
70 
73 
77 
81 
85 
88 
91 
94 
97 
100 
103 
106 
109 
112 
114 namespace meta
115 {
117  inline namespace v1
118  {
120 
121  namespace detail
122  {
124  template <typename T>
125  constexpr T *_nullptr_v()
126  {
127  return nullptr;
128  }
129  } // namespace detail
130 
133  struct nil_
134  {
135  };
136 
139  template <typename T>
140  using _t = typename T::type;
141 
142 #if defined(__cpp_variable_templates) || defined(META_DOXYGEN_INVOKED)
143  template <typename T>
147  constexpr typename T::type::value_type _v = T::type::value;
148 #endif
149 
151  namespace lazy
152  {
155  template <typename T>
156  using _t = defer<_t, T>;
157  }
158 
161  template <std::size_t N>
162  using size_t = std::integral_constant<std::size_t, N>;
163 
166  template <bool B>
167  using bool_ = std::integral_constant<bool, B>;
168 
171  template <int I>
172  using int_ = std::integral_constant<int, I>;
173 
176  template <char Ch>
177  using char_ = std::integral_constant<char, Ch>;
178 
180  // Math operations
183  template <typename T>
184  using inc = std::integral_constant<decltype(T::type::value + 1), T::type::value + 1>;
185 
188  template <typename T>
189  using dec = std::integral_constant<decltype(T::type::value - 1), T::type::value - 1>;
190 
194  template <typename T, typename U>
195  using plus = std::integral_constant<decltype(T::type::value + U::type::value),
196  T::type::value + U::type::value>;
197 
201  template <typename T, typename U>
202  using minus = std::integral_constant<decltype(T::type::value - U::type::value),
203  T::type::value - U::type::value>;
204 
208  template <typename T, typename U>
209  using multiplies = std::integral_constant<decltype(T::type::value * U::type::value),
210  T::type::value * U::type::value>;
211 
215  template <typename T, typename U>
216  using divides = std::integral_constant<decltype(T::type::value / U::type::value),
217  T::type::value / U::type::value>;
218 
222  template <typename T>
223  using negate = std::integral_constant<decltype(-T::type::value), -T::type::value>;
224 
228  template <typename T, typename U>
229  using modulus = std::integral_constant<decltype(T::type::value % U::type::value),
230  T::type::value % U::type::value>;
231 
235  template <typename T, typename U>
237 
241  template <typename T, typename U>
243 
247  template <typename T, typename U>
248  using greater = bool_<(T::type::value > U::type::value)>;
249 
253  template <typename T, typename U>
255 
259  template <typename T, typename U>
260  using greater_equal = bool_<(T::type::value >= U::type::value)>;
261 
265  template <typename T, typename U>
267 
271  template <typename T, typename U>
272  using bit_and = std::integral_constant<decltype(T::type::value & U::type::value),
273  T::type::value & U::type::value>;
274 
278  template <typename T, typename U>
279  using bit_or = std::integral_constant<decltype(T::type::value | U::type::value),
280  T::type::value | U::type::value>;
281 
285  template <typename T, typename U>
286  using bit_xor = std::integral_constant<decltype(T::type::value ^ U::type::value),
287  T::type::value ^ U::type::value>;
288 
292  template <typename T>
293  using bit_not = std::integral_constant<decltype(~T::type::value), ~T::type::value>;
294 
295  namespace lazy
296  {
299  template <typename T>
301 
304  template <typename T>
306 
309  template <typename T, typename U>
311 
314  template <typename T, typename U>
316 
319  template <typename T, typename U>
321 
324  template <typename T, typename U>
326 
329  template <typename T>
331 
334  template <typename T, typename U>
336 
339  template <typename T, typename U>
341 
344  template <typename T, typename U>
346 
349  template <typename T, typename U>
351 
354  template <typename T, typename U>
356 
359  template <typename T, typename U>
361 
364  template <typename T, typename U>
366 
369  template <typename T, typename U>
371 
374  template <typename T, typename U>
376 
379  template <typename T, typename U>
381 
384  template <typename T>
386  }
387 
390  template <typename F, typename... Args>
391  using invoke = typename F::template invoke<Args...>;
392 
394  namespace lazy
395  {
398  template <typename F, typename... Args>
399  using invoke = defer<invoke, F, Args...>;
400  }
401 
406  template <typename T>
407  struct id
408  {
409  private:
410  // Redirect through a class template for compilers that have not
411  // yet implemented CWG 1558:
412  // <http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1558>
413  template <typename...>
414  struct impl
415  {
416  using type = T;
417  };
418 
419  public:
420  using type = T;
421 
422  template <typename... Ts>
423  using invoke = _t<impl<Ts...>>;
424  };
425 
428  template <typename T>
429  using id_t = _t<id<T>>;
430 
431  namespace lazy
432  {
436  template <typename T>
437  using id = defer<id, T>;
438  }
439 
442  template <typename... Ts>
443  using void_ = invoke<id<void>, Ts...>;
444 
446  namespace detail
447  {
448  template <typename, typename = void>
449  struct is_trait_
450  {
451  using type = std::false_type;
452  };
453 
454  template <typename T>
455  struct is_trait_<T, void_<typename T::type>>
456  {
457  using type = std::true_type;
458  };
459 
460  template <typename, typename = void>
461  struct is_callable_
462  {
463  using type = std::false_type;
464  };
465 
466  template <typename T>
467  struct is_callable_<T, void_<quote<T::template invoke>>>
468  {
469  using type = std::true_type;
470  };
471 
472  template <template <typename...> class, typename, typename = void>
473  struct defer_
474  {
475  };
476 
477  template <template <typename...> class C, typename... Ts>
478  struct defer_<C, list<Ts...>, void_<C<Ts...>>>
479  {
480  using type = C<Ts...>;
481  };
482 
483  template <typename T, template <T...> class, typename, typename = void>
484  struct defer_i_
485  {
486  };
487 
488  template <typename T, template <T...> class C, T... Is>
489  struct defer_i_<T, C, integer_sequence<T, Is...>, void_<C<Is...>>>
490  {
491  using type = C<Is...>;
492  };
493  } // namespace detail
495 
499  template <typename T>
501 
505  template <typename T>
507 
509  // defer
524  template <template <typename...> class C, typename... Ts>
525  struct defer : detail::defer_<C, list<Ts...>>
526  {
527  };
528 
530  // defer_i
535  template <typename T, template <T...> class C, T... Is>
536  struct defer_i : detail::defer_i_<T, C, integer_sequence<T, Is...>>
537  {
538  };
539 
541  // defer_trait
546  template <template <typename...> class C, typename... Ts>
547  using defer_trait = lazy::_t<defer<C, Ts...>>;
548 
550  // defer_trait_i
555  template <typename T, template <T...> class C, T... Is>
556  using defer_trait_i = lazy::_t<defer_i<T, C, Is...>>;
557 
562  template <class T>
564 
569  template <class T>
571 
572  namespace lazy
573  {
576  template <typename T>
578 
581  template <typename T>
583  }
584 
587  namespace detail
588  {
589  template <typename, template <typename...> class>
590  struct is_ : std::false_type
591  {
592  };
593 
594  template <typename... Ts, template <typename...> class C>
595  struct is_<C<Ts...>, C> : std::true_type
596  {
597  };
598  }
600 
604  template <typename T, template <typename...> class C>
606 
609  template <typename... Fs>
610  struct compose
611  {
612  };
613 
614  template <typename F0>
615  struct compose<F0>
616  {
617  template <typename... Ts>
618  using invoke = invoke<F0, Ts...>;
619  };
620 
621  template <typename F0, typename... Fs>
622  struct compose<F0, Fs...>
623  {
624  template <typename... Ts>
625  using invoke = invoke<F0, invoke<compose<Fs...>, Ts...>>;
626  };
627 
628  namespace lazy
629  {
632  template <typename... Fns>
633  using compose = defer<compose, Fns...>;
634  }
635 
638  template <template <typename...> class C>
639  struct quote
640  {
641  // Indirection through defer here needed to avoid Core issue 1430
642  // http://open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1430
643  template <typename... Ts>
644  using invoke = _t<defer<C, Ts...>>;
645  };
646 
650  template <typename T, template <T...> class C>
651  struct quote_i
652  {
653  // Indirection through defer_i here needed to avoid Core issue 1430
654  // http://open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1430
655  template <typename... Ts>
656  using invoke = _t<defer_i<T, C, Ts::type::value...>>;
657  };
658 
659  #if __GNUC__ == 4 && __GNUC_MINOR__ <= 8 && \
660  !defined(__clang__) && !defined(META_DOXYGEN_INVOKED)
661  template <template <typename...> class C>
662  struct quote_trait
663  {
664  template <typename... Ts>
665  using invoke = _t<invoke<quote<C>, Ts...>>;
666  };
667 
668  template <typename T, template <T...> class C>
669  struct quote_trait_i
670  {
671  template <typename... Ts>
672  using invoke = _t<invoke<quote_i<T, C>, Ts...>>;
673  };
674  #else
675  // clang-format off
681  template <template <typename...> class C>
683 
687  template <typename T, template <T...> class C>
689  // clang-format on
690  #endif
691 
695  template <typename F, typename... Ts>
696  struct bind_front
697  {
698  template <typename... Us>
699  using invoke = invoke<F, Ts..., Us...>;
700  };
701 
705  template <typename F, typename... Us>
706  struct bind_back
707  {
708  template <typename... Ts>
709  using invoke = invoke<F, Ts..., Us...>;
710  };
711 
712  namespace lazy
713  {
716  template <typename Fn, typename... Ts>
717  using bind_front = defer<bind_front, Fn, Ts...>;
718 
721  template <typename Fn, typename... Ts>
722  using bind_back = defer<bind_back, Fn, Ts...>;
723  }
724 
726  namespace extension
727  {
731  template <typename F, typename List>
732  struct apply
733  {
734  };
735 
736  template <typename F, typename Ret, typename... Args>
737  struct apply<F, Ret(Args...)> : lazy::invoke<F, Ret, Args...>
738  {
739  };
740 
741  template <typename F, template <typename...> class T, typename... Ts>
742  struct apply<F, T<Ts...>> : lazy::invoke<F, Ts...>
743  {
744  };
745 
746  template <typename F, typename T, T... Is>
747  struct apply<F, integer_sequence<T, Is...>>
748  : lazy::invoke<F, std::integral_constant<T, Is>...>
749  {
750  };
751  }
752 
756  template <typename C, typename List>
758 
759  namespace lazy
760  {
761  template <typename F, typename List>
763  }
764 
768  template <typename F, typename Q = quote<list>>
770 
774  template <typename F>
776 
777  namespace lazy
778  {
781  template <typename F, typename Q = quote<list>>
783 
786  template <typename F>
788  }
789 
792  template <typename F>
793  struct flip
794  {
795  private:
796  template <typename... Ts>
797  struct impl
798  {
799  };
800  template <typename A, typename B, typename... Ts>
801  struct impl<A, B, Ts...> : lazy::invoke<F, B, A, Ts...>
802  {
803  };
804 
805  public:
806  template <typename... Ts>
807  using invoke = _t<impl<Ts...>>;
808  };
809 
810  namespace lazy
811  {
814  template <typename F>
816  }
817 
819  namespace detail
820  {
821  template <typename...>
822  struct on_
823  {
824  };
825  template <typename F, typename... Gs>
826  struct on_<F, Gs...>
827  {
828  template <typename... Ts>
829  using invoke = invoke<F, invoke<compose<Gs...>, Ts>...>;
830  };
831  }
833 
837  template <typename... Fs>
838  using on = detail::on_<Fs...>;
839 
840  namespace lazy
841  {
844  template <typename F, typename G>
846  }
847 
849  // if_
851  namespace detail
852  {
853  template <typename...>
854  struct _if_
855  {
856  };
857 
858  template <typename If>
859  struct _if_<If> : std::enable_if<If::type::value>
860  {
861  };
862 
863  template <typename If, typename Then>
864  struct _if_<If, Then> : std::enable_if<If::type::value, Then>
865  {
866  };
867 
868  template <typename If, typename Then, typename Else>
869  struct _if_<If, Then, Else> : std::conditional<If::type::value, Then, Else>
870  {
871  };
872  } // namespace detail
874 
877  template <typename... Args>
878  using if_ = _t<detail::_if_<Args...>>;
879 
882  template <bool If, typename... Args>
883  using if_c = _t<detail::_if_<bool_<If>, Args...>>;
884 
885  namespace lazy
886  {
889  template <typename... Args>
890  using if_ = defer<if_, Args...>;
891 
894  template <bool If, typename... Args>
895  using if_c = if_<bool_<If>, Args...>;
896  }
897 
899  namespace detail
900  {
901  template <typename... Bools>
902  struct _and_;
903 
904  template <>
905  struct _and_<> : std::true_type
906  {
907  };
908 
909  template <typename Bool, typename... Bools>
910  struct _and_<Bool, Bools...>
911  : if_c<!Bool::type::value, std::false_type, _and_<Bools...>>
912  {
913  };
914 
915  template <typename... Bools>
916  struct _or_;
917 
918  template <>
919  struct _or_<> : std::false_type
920  {
921  };
922 
923  template <typename Bool, typename... Bools>
924  struct _or_<Bool, Bools...> : if_c<Bool::type::value, std::true_type, _or_<Bools...>>
925  {
926  };
927  } // namespace detail
929 
932  template <bool Bool>
934 
937  template <typename Bool>
939 
942 #if (__GNUC__ == 5) && (__GNUC_MINOR__ == 1) && !defined(__clang__)
943  // Alternative formulation of and_c to workaround
944  // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66405
945  template <bool... Bools>
946  using and_c = std::is_same<integer_sequence<bool, true, Bools...>,
947  integer_sequence<bool, Bools..., true>>;
948 #else
949  template <bool... Bools>
950  using and_c = std::is_same<integer_sequence<bool, Bools...>,
951  integer_sequence<bool, (Bools || true)...>>;
952 #endif
953 
957  template <typename... Bools>
958  using strict_and = and_c<Bools::type::value...>;
959 
963  template <typename... Bools>
964  using and_ = _t<detail::_and_<Bools...>>;
965 
968  template <bool... Bools>
969  using or_c = not_<std::is_same<integer_sequence<bool, Bools...>,
970  integer_sequence<bool, (Bools && false)...>>>;
971 
975  template <typename... Bools>
976  using strict_or = or_c<Bools::type::value...>;
977 
981  template <typename... Bools>
982  using or_ = _t<detail::_or_<Bools...>>;
983 
984  namespace lazy
985  {
988  template <typename... Bools>
989  using and_ = defer<and_, Bools...>;
990 
993  template <typename... Bools>
994  using or_ = defer<or_, Bools...>;
995 
998  template <typename Bool>
1000 
1003  template <typename... Bools>
1004  using strict_and = defer<strict_and, Bools...>;
1005 
1008  template <typename... Bools>
1009  using strict_or = defer<strict_or, Bools...>;
1010  }
1011 
1013  // fold
1015  namespace detail
1016  {
1017  template <typename, typename, typename, typename = void>
1018  struct fold_
1019  {
1020  };
1021 
1022  template <typename State, typename Fun>
1023  struct fold_<list<>, State, Fun>
1024  {
1025  using type = State;
1026  };
1027 
1028  template <typename Head, typename... List, typename State, typename Fun>
1029  struct fold_<list<Head, List...>, State, Fun, void_<invoke<Fun, State, Head>>>
1030  : fold_<list<List...>, invoke<Fun, State, Head>, Fun>
1031  {
1032  };
1033  } // namespace detail
1035 
1042  template <typename List, typename State, typename Fun>
1044 
1049  template <typename List, typename State, typename Fun>
1051 
1052  namespace lazy
1053  {
1056  template <typename List, typename State, typename Fun>
1058 
1061  template <typename List, typename State, typename Fun>
1063  }
1064 
1066  // reverse_fold
1068  namespace detail
1069  {
1070  template <typename, typename, typename, typename = void>
1071  struct reverse_fold_
1072  {
1073  };
1074 
1075  template <typename State, typename Fun>
1076  struct reverse_fold_<list<>, State, Fun>
1077  {
1078  using type = State;
1079  };
1080 
1081  template <typename Head, typename... List, typename State, typename Fun>
1082  struct reverse_fold_<list<Head, List...>, State, Fun,
1083  void_<_t<reverse_fold_<list<List...>, State, Fun>>>>
1084  : lazy::invoke<Fun, _t<reverse_fold_<list<List...>, State, Fun>>, Head>
1085  {
1086  };
1087  } // namespace detail
1089 
1096  template <typename List, typename State, typename Fun>
1098 
1099  namespace lazy
1100  {
1103  template <typename List, typename State, typename Fun>
1105  }
1106 
1108  // npos
1113 
1115  // list
1118  template <typename... Ts>
1119  struct list
1120  {
1121  using type = list;
1123  static constexpr std::size_t size() noexcept { return sizeof...(Ts); }
1124  };
1125 
1127  // size
1131  template <typename List>
1133 
1134  namespace lazy
1135  {
1138  template <typename List>
1140  }
1141 
1143  // concat
1145  namespace detail
1146  {
1147  template <typename... Lists>
1148  struct concat_
1149  {
1150  };
1151 
1152  template <>
1153  struct concat_<>
1154  {
1155  using type = list<>;
1156  };
1157 
1158  template <typename... List1>
1159  struct concat_<list<List1...>>
1160  {
1161  using type = list<List1...>;
1162  };
1163 
1164  template <typename... List1, typename... List2>
1165  struct concat_<list<List1...>, list<List2...>>
1166  {
1167  using type = list<List1..., List2...>;
1168  };
1169 
1170  template <typename... List1, typename... List2, typename... List3>
1171  struct concat_<list<List1...>, list<List2...>, list<List3...>>
1172  {
1173  using type = list<List1..., List2..., List3...>;
1174  };
1175 
1176  template <typename... List1, typename... List2, typename... List3, typename... Rest>
1177  struct concat_<list<List1...>, list<List2...>, list<List3...>, Rest...>
1178  : concat_<list<List1..., List2..., List3...>, Rest...>
1179  {
1180  };
1181  } // namespace detail
1183 
1189  template <typename... Lists>
1190  using concat = _t<detail::concat_<Lists...>>;
1191 
1192  namespace lazy
1193  {
1196  template <typename... Lists>
1197  using concat = defer<concat, Lists...>;
1198  }
1199 
1207  template <typename ListOfLists>
1208  using join = apply<quote<concat>, ListOfLists>;
1209 
1210  namespace lazy
1211  {
1214  template <typename ListOfLists>
1216  }
1217 
1219  // repeat_n
1221  namespace detail
1222  {
1223  template <std::size_t N, typename T>
1224  struct repeat_n_c_
1225  {
1226  using type = concat<_t<repeat_n_c_<N / 2, T>>, _t<repeat_n_c_<N / 2, T>>,
1228  };
1229 
1230  template <typename T>
1231  struct repeat_n_c_<0, T>
1232  {
1233  using type = list<>;
1234  };
1235 
1236  template <typename T>
1237  struct repeat_n_c_<1, T>
1238  {
1239  using type = list<T>;
1240  };
1241  } // namespace detail
1243 
1248  template <typename N, typename T = void>
1250 
1255  template <std::size_t N, typename T = void>
1257 
1258  namespace lazy
1259  {
1262  template <typename N, typename T = void>
1264  }
1265 
1267  // at
1269  namespace detail
1270  {
1271  template <typename VoidPtrs>
1272  struct at_impl_;
1273 
1274  template <typename... VoidPtrs>
1275  struct at_impl_<list<VoidPtrs...>>
1276  {
1277  static nil_ eval(...);
1278 
1279  template <typename T, typename... Us>
1280  static T eval(VoidPtrs..., T *, Us *...);
1281  };
1282 
1283  template <typename List, typename N>
1284  struct at_
1285  {
1286  };
1287 
1288  template <typename... Ts, typename N>
1289  struct at_<list<Ts...>, N>
1290  : decltype(at_impl_<repeat_n<N, void *>>::eval(detail::_nullptr_v<id<Ts>>()...))
1291  {
1292  };
1293  } // namespace detail
1295 
1297  // at
1302  template <typename List, typename N>
1304 
1309  template <typename List, std::size_t N>
1311 
1312  namespace lazy
1313  {
1316  template <typename List, typename N>
1318  }
1319 
1321  // drop
1323  namespace detail
1324  {
1327  template <typename VoidPtrs>
1328  struct drop_impl_
1329  {
1330  static nil_ eval(...);
1331  };
1332 
1333  template <typename... VoidPtrs>
1334  struct drop_impl_<list<VoidPtrs...>>
1335  {
1336  static nil_ eval(...);
1337 
1338  template <typename... Ts>
1339  static id<list<Ts...>> eval(VoidPtrs..., id<Ts> *...);
1340  };
1341 
1342  template <>
1343  struct drop_impl_<list<>>
1344  {
1345  template <typename...Ts>
1346  static id<list<Ts...>> eval(id<Ts> *...);
1347  };
1348 
1349  template <typename List, typename N>
1350  struct drop_
1351  {
1352  };
1353 
1354  template <typename... Ts, typename N>
1355  struct drop_<list<Ts...>, N>
1356  : decltype(drop_impl_<repeat_n<N, void *>>::eval(detail::_nullptr_v<id<Ts>>()...))
1357  {
1358  };
1359  } // namespace detail
1361 
1366  template <typename List, typename N>
1368 
1373  template <typename List, std::size_t N>
1375 
1376  namespace lazy
1377  {
1380  template <typename List, typename N>
1382  }
1383 
1385  // front
1387  namespace detail
1388  {
1389  template <typename List>
1390  struct front_
1391  {
1392  };
1393 
1394  template <typename Head, typename... List>
1395  struct front_<list<Head, List...>>
1396  {
1397  using type = Head;
1398  };
1399  } // namespace detail
1401 
1406  template <typename List>
1408 
1409  namespace lazy
1410  {
1413  template <typename List>
1415  }
1416 
1418  // back
1420  namespace detail
1421  {
1422  template <typename List>
1423  struct back_
1424  {
1425  };
1426 
1427  template <typename Head, typename... List>
1428  struct back_<list<Head, List...>>
1429  {
1430  using type = at_c<list<Head, List...>, sizeof...(List)>;
1431  };
1432  } // namespace detail
1434 
1439  template <typename List>
1441 
1442  namespace lazy
1443  {
1446  template <typename List>
1448  }
1449 
1451  // push_front
1453  namespace detail
1454  {
1455  template <typename List, typename T>
1456  struct push_front_
1457  {
1458  };
1459 
1460  template <typename... List, typename T>
1461  struct push_front_<list<List...>, T>
1462  {
1463  using type = list<T, List...>;
1464  };
1465  } // namespace detail
1467 
1472  template <typename List, typename T>
1474 
1475  namespace lazy
1476  {
1479  template <typename List, typename T>
1481  }
1482 
1484  // pop_front
1486  namespace detail
1487  {
1488  template <typename List>
1489  struct pop_front_
1490  {
1491  };
1492 
1493  template <typename Head, typename... List>
1494  struct pop_front_<list<Head, List...>>
1495  {
1496  using type = list<List...>;
1497  };
1498  } // namespace detail
1500 
1505  template <typename List>
1507 
1508  namespace lazy
1509  {
1512  template <typename List>
1514  }
1515 
1517  // push_back
1519  namespace detail
1520  {
1521  template <typename List, typename T>
1522  struct push_back_
1523  {
1524  };
1525 
1526  template <typename... List, typename T>
1527  struct push_back_<list<List...>, T>
1528  {
1529  using type = list<List..., T>;
1530  };
1531  } // namespace detail
1533 
1540  template <typename List, typename T>
1542 
1543  namespace lazy
1544  {
1547  template <typename List, typename T>
1549  }
1551  namespace detail
1552  {
1553  template <typename T, typename U>
1554  using min_ = if_<less<U, T>, U, T>;
1555 
1556  template <typename T, typename U>
1557  using max_ = if_<less<U, T>, T, U>;
1558  }
1560 
1563  template <typename... Ts>
1564  using min = fold<pop_front<list<Ts...>>, front<list<Ts...>>, quote<detail::min_>>;
1565 
1568  template <typename... Ts>
1569  using max = fold<pop_front<list<Ts...>>, front<list<Ts...>>, quote<detail::max_>>;
1570 
1571  namespace lazy
1572  {
1575  template <typename... Ts>
1576  using min = defer<min, Ts...>;
1577 
1580  template <typename... Ts>
1581  using max = defer<max, Ts...>;
1582  }
1583 
1585  // empty
1591  template <typename List>
1593 
1594  namespace lazy
1595  {
1598  template <typename List>
1600  }
1601 
1603  // pair
1606  template <typename F, typename S>
1607  using pair = list<F, S>;
1608 
1611  template <typename Pair>
1613 
1616  template <typename Pair>
1618 
1619  namespace lazy
1620  {
1623  template <typename Pair>
1625 
1628  template <typename Pair>
1630  }
1631 
1633  // find_index
1635  namespace detail
1636  {
1637  // With thanks to Peter Dimov:
1638  constexpr std::size_t find_index_i_(bool const *const first, bool const *const last,
1639  std::size_t N = 0)
1640  {
1641  return first == last ? npos::value : *first ? N
1642  : find_index_i_(first + 1, last, N + 1);
1643  }
1644 
1645  template <typename List, typename T>
1646  struct find_index_
1647  {
1648  };
1649 
1650  template <typename V>
1651  struct find_index_<list<>, V>
1652  {
1653  using type = npos;
1654  };
1655 
1656  template <typename... T, typename V>
1657  struct find_index_<list<T...>, V>
1658  {
1659  static constexpr bool s_v[] = {std::is_same<T, V>::value...};
1660  using type = size_t<find_index_i_(s_v, s_v + sizeof...(T))>;
1661  };
1662  } // namespace detail
1664 
1671  template <typename List, typename T>
1673 
1674  namespace lazy
1675  {
1678  template <typename List, typename T>
1680  }
1681 
1683  // reverse_find_index
1685  namespace detail
1686  {
1687  // With thanks to Peter Dimov:
1688  constexpr std::size_t reverse_find_index_i_(bool const *const first,
1689  bool const *const last, std::size_t N)
1690  {
1691  return first == last
1692  ? npos::value
1693  : *(last - 1) ? N - 1 : reverse_find_index_i_(first, last - 1, N - 1);
1694  }
1695 
1696  template <typename List, typename T>
1697  struct reverse_find_index_
1698  {
1699  };
1700 
1701  template <typename V>
1702  struct reverse_find_index_<list<>, V>
1703  {
1704  using type = npos;
1705  };
1706 
1707  template <typename... T, typename V>
1708  struct reverse_find_index_<list<T...>, V>
1709  {
1710  static constexpr bool s_v[] = {std::is_same<T, V>::value...};
1711  using type = size_t<reverse_find_index_i_(s_v, s_v + sizeof...(T), sizeof...(T))>;
1712  };
1713  } // namespace detail
1715 
1722  template <typename List, typename T>
1724 
1725  namespace lazy
1726  {
1729  template <typename List, typename T>
1731  }
1732 
1734  // reverse_find
1736  namespace detail
1737  {
1738  template <typename List, typename T, typename State = list<>>
1739  struct reverse_find_
1740  {
1741  };
1742 
1743  template <typename T, typename State>
1744  struct reverse_find_<list<>, T, State>
1745  {
1746  using type = State;
1747  };
1748 
1749  template <typename Head, typename... List, typename T, typename State>
1750  struct reverse_find_<list<Head, List...>, T, State>
1751  : reverse_find_<list<List...>, T, State>
1752  {
1753  };
1754 
1755  template <typename... List, typename T, typename State>
1756  struct reverse_find_<list<T, List...>, T, State>
1757  : reverse_find_<list<List...>, T, list<T, List...>>
1758  {
1759  };
1760  }
1762 
1768  template <typename List, typename T>
1770 
1771  namespace lazy
1772  {
1775  template <typename List, typename T>
1777  }
1778 
1784  template <typename List, typename T>
1786 
1787  namespace lazy
1788  {
1791  template <typename List, typename T>
1793  }
1794 
1796  // find_if
1798  namespace detail
1799  {
1800  template <typename List, typename Fun>
1801  struct find_if_
1802  {
1803  };
1804 
1805  template <typename Fun>
1806  struct find_if_<list<>, Fun>
1807  {
1808  using type = list<>;
1809  };
1810 
1811  template <typename Head, typename... List, typename Fun>
1812  struct find_if_<list<Head, List...>, Fun>
1813  : if_<invoke<Fun, Head>, id<list<Head, List...>>, find_if_<list<List...>, Fun>>
1814  {
1815  };
1816  } // namespace detail
1818 
1825  template <typename List, typename Fun>
1827 
1828  namespace lazy
1829  {
1832  template <typename List, typename Fun>
1834  }
1835 
1837  // reverse_find_if
1839  namespace detail
1840  {
1841  template <typename List, typename Fun, typename State = list<>>
1842  struct reverse_find_if_
1843  {
1844  };
1845 
1846  template <typename Fun, typename State>
1847  struct reverse_find_if_<list<>, Fun, State>
1848  {
1849  using type = State;
1850  };
1851 
1852  template <typename Head, typename... List, typename Fun, typename State>
1853  struct reverse_find_if_<list<Head, List...>, Fun, State>
1854  : reverse_find_if_<list<List...>, Fun,
1855  if_<invoke<Fun, Head>, list<Head, List...>, State>>
1856  {
1857  };
1858  }
1860 
1867  template <typename List, typename Fun>
1869 
1870  namespace lazy
1871  {
1874  template <typename List, typename Fun>
1876  }
1877 
1879  // replace
1881  namespace detail
1882  {
1883  template <typename List, typename T, typename U>
1884  struct replace_
1885  {
1886  };
1887 
1888  template <typename... List, typename T, typename U>
1889  struct replace_<list<List...>, T, U>
1890  {
1891  using type = list<if_<std::is_same<T, List>, U, List>...>;
1892  };
1893  } // namespace detail
1895 
1901  template <typename List, typename T, typename U>
1903 
1904  namespace lazy
1905  {
1908  template <typename List, typename T, typename U>
1910  }
1911 
1913  // replace_if
1915  namespace detail
1916  {
1917  template <typename List, typename C, typename U>
1918  struct replace_if_
1919  {
1920  };
1921 
1922  template <typename... List, typename C, typename U>
1923  struct replace_if_<list<List...>, C, U>
1924  {
1925  using type = list<if_<invoke<C, List>, U, List>...>;
1926  };
1927  } // namespace detail
1929 
1935  template <typename List, typename C, typename U>
1937 
1938  namespace lazy
1939  {
1942  template <typename List, typename C, typename U>
1944  }
1945 
1947  // count
1948  namespace detail
1949  {
1950  template <typename State, typename Val, typename T>
1951  using count_fn = if_<std::is_same<Val, T>, inc<State>, State>;
1952  }
1953 
1958  template <typename List, typename T>
1960 
1961  namespace lazy
1962  {
1965  template <typename List, typename T>
1967  }
1968 
1970  // count_if
1971  namespace detail
1972  {
1973  template <typename State, typename Val, typename Fn>
1974  using count_if_fn = if_<invoke<Fn, Val>, inc<State>, State>;
1975  }
1976 
1982  template <typename List, typename Fn>
1984 
1985  namespace lazy
1986  {
1989  template <typename List, typename Fn>
1991  }
1992 
1994  // transform
1996  namespace detail
1997  {
1998  template <typename, typename = void>
1999  struct transform_
2000  {
2001  };
2002 
2003  template <typename... Ts, typename Fun>
2004  struct transform_<list<list<Ts...>, Fun>, void_<invoke<Fun, Ts>...>>
2005  {
2006  using type = list<invoke<Fun, Ts>...>;
2007  };
2008 
2009  template <typename... Ts0, typename... Ts1, typename Fun>
2010  struct transform_<list<list<Ts0...>, list<Ts1...>, Fun>,
2011  void_<invoke<Fun, Ts0, Ts1>...>>
2012  {
2013  using type = list<invoke<Fun, Ts0, Ts1>...>;
2014  };
2015  } // namespace detail
2017 
2026  template <typename... Args>
2027  using transform = _t<detail::transform_<list<Args...>>>;
2028 
2029  namespace lazy
2030  {
2033  template <typename... Args>
2034  using transform = defer<transform, Args...>;
2035  }
2036 
2038  // filter
2040  namespace detail
2041  {
2042  template <typename Pred>
2043  struct filter_
2044  {
2045  template <typename State, typename A>
2047  };
2048  } // namespace detail
2050 
2057  template <typename List, typename Pred>
2058  using filter = fold<List, list<>, detail::filter_<Pred>>;
2059 
2060  namespace lazy
2061  {
2064  template <typename List, typename Pred>
2066  }
2067 
2069  // static_const
2071  namespace detail
2072  {
2073  template <typename T>
2074  struct static_const
2075  {
2076  static constexpr T value{};
2077  };
2078 
2079  // Avoid potential ODR violations with global objects:
2080  template <typename T>
2081  constexpr T static_const<T>::value;
2082  } // namespace detail
2083 
2085 
2087  // for_each
2089  namespace detail
2090  {
2091  struct for_each_fn
2092  {
2093  template <class UnaryFunction, class... Args>
2094  constexpr auto operator()(list<Args...>, UnaryFunction f) const -> UnaryFunction
2095  {
2096  return (void)std::initializer_list<int>{((void)f(Args{}), 0)...}, f;
2097  }
2098  };
2099  } // namespace detail
2101 
2103  namespace
2104  {
2106 
2110  constexpr auto &&for_each = detail::static_const<detail::for_each_fn>::value;
2111 
2113  }
2115 
2117  // transpose
2123  template <typename ListOfLists>
2124  using transpose = fold<ListOfLists, repeat_n<size<front<ListOfLists>>, list<>>,
2126 
2127  namespace lazy
2128  {
2131  template <typename ListOfLists>
2133  }
2134 
2136  // zip_with
2143  template <typename Fun, typename ListOfLists>
2145 
2146  namespace lazy
2147  {
2150  template <typename Fun, typename ListOfLists>
2152  }
2153 
2155  // zip
2162  template <typename ListOfLists>
2164 
2165  namespace lazy
2166  {
2169  template <typename ListOfLists>
2171  }
2172 
2174  // as_list
2176  namespace detail
2177  {
2178  template <typename T>
2179  using uncvref_t = _t<std::remove_cv<_t<std::remove_reference<T>>>>;
2180 
2181  // Indirection here needed to avoid Core issue 1430
2182  // http://open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1430
2183  template <typename Sequence>
2184  struct as_list_ : lazy::invoke<uncurry<curry<quote_trait<id>>>, uncvref_t<Sequence>>
2185  {
2186  };
2187  } // namespace detail
2189 
2193  template <typename Sequence>
2195 
2196  namespace lazy
2197  {
2200  template <typename Sequence>
2202  }
2203 
2205  // reverse
2210  template <typename List>
2211  using reverse = reverse_fold<List, list<>, quote<push_back>>;
2212 
2213  namespace lazy
2214  {
2217  template <typename List>
2219  }
2220 
2223  template <typename F>
2225 
2226  namespace lazy
2227  {
2230  template <typename F>
2232  }
2233 
2235  // all_of
2241  template <typename List, typename F>
2243 
2244  namespace lazy
2245  {
2248  template <typename List, typename Fn>
2250  }
2251 
2253  // any_of
2259  template <typename List, typename F>
2261 
2262  namespace lazy
2263  {
2266  template <typename List, typename Fn>
2268  }
2269 
2271  // none_of
2277  template <typename List, typename F>
2279 
2280  namespace lazy
2281  {
2284  template <typename List, typename Fn>
2286  }
2287 
2289  // in
2295  template <typename List, typename T>
2297 
2298  namespace lazy
2299  {
2302  template <typename List, typename T>
2304  }
2305 
2307  // inherit
2309  namespace detail
2310  {
2311  template<typename List>
2312  struct inherit_
2313  {
2314  };
2315 
2316  template<typename ...List>
2317  struct inherit_<list<List...>> : List...
2318  {
2319  using type = inherit_;
2320  };
2321  }
2323 
2328  template <typename List>
2330 
2331  namespace lazy
2332  {
2335  template <typename List>
2337  }
2338 
2340  // set
2341  // Used to improve the performance of \c meta::unique.
2343  namespace detail
2344  {
2345  template <typename Set, typename T>
2346  struct in_
2347  {
2348  };
2349 
2350  template <typename... Set, typename T>
2351  struct in_<list<Set...>, T> : std::is_base_of<id<T>, inherit<list<id<Set>...>>>
2352  {
2353  };
2354 
2355  template <typename Set, typename T>
2356  struct insert_back_
2357  {
2358  };
2359 
2360  template <typename... Set, typename T>
2361  struct insert_back_<list<Set...>, T>
2362  {
2363  using type = if_<in_<list<Set...>, T>, list<Set...>, list<Set..., T>>;
2364  };
2365  } // namespace detail
2367 
2369  // unique
2374  template <typename List>
2376 
2377  namespace lazy
2378  {
2381  template <typename List>
2383  }
2384 
2386  // partition
2388  namespace detail
2389  {
2390  template <typename Pred>
2391  struct partition_
2392  {
2393  template <typename, typename, typename = void>
2394  struct impl
2395  {
2396  };
2397  template <typename... Yes, typename... No, typename A>
2398  struct impl<pair<list<Yes...>, list<No...>>, A,
2399  void_<bool_<invoke<Pred, A>::type::value>>>
2400  {
2401  using type = if_<invoke<Pred, A>, pair<list<Yes..., A>, list<No...>>,
2402  pair<list<Yes...>, list<No..., A>>>;
2403  };
2404  template <typename State, typename A>
2405  using invoke = _t<impl<State, A>>;
2406  };
2407  } // namespace detail
2409 
2416  template <typename List, typename Pred>
2417  using partition = fold<List, pair<list<>, list<>>, detail::partition_<Pred>>;
2418 
2419  namespace lazy
2420  {
2423  template <typename List, typename Pred>
2425  }
2426 
2428  // sort
2430  namespace detail
2431  {
2432  template <typename, typename, typename = void>
2433  struct sort_
2434  {
2435  };
2436 
2437  template <typename Pred>
2438  struct sort_<list<>, Pred>
2439  {
2440  using type = list<>;
2441  };
2442 
2443  template <typename A, typename Pred>
2444  struct sort_<list<A>, Pred>
2445  {
2446  using type = list<A>;
2447  };
2448 
2449  template <typename A, typename B, typename... List, typename Pred>
2450  struct sort_<
2451  list<A, B, List...>, Pred,
2452  void_<_t<sort_<first<partition<list<B, List...>, bind_back<Pred, A>>>, Pred>>>>
2453  {
2454  using P = partition<list<B, List...>, bind_back<Pred, A>>;
2455  using type =
2456  concat<_t<sort_<first<P>, Pred>>, list<A>, _t<sort_<second<P>, Pred>>>;
2457  };
2458  }
2460 
2461  // clang-format off
2472  // clang-format on
2473  template <typename List, typename Pred>
2475 
2476  namespace lazy
2477  {
2480  template <typename List, typename Pred>
2482  }
2483 
2485  // lambda_
2487  namespace detail
2488  {
2489  template <typename T, int = 0>
2490  struct protect_;
2491 
2492  template <typename, int = 0>
2493  struct vararg_;
2494 
2495  template <typename T, int = 0>
2496  struct is_valid_;
2497 
2498  // Returns which branch to evaluate
2499  template <typename If, typename... Ts>
2500  using lazy_if_ = lazy::_t<defer<_if_, If, protect_<Ts>...>>;
2501 
2502  template <typename A, typename T, typename F, typename Ts>
2503  struct subst1_
2504  {
2505  using type = list<list<T>>;
2506  };
2507  template <typename T, typename F, typename Ts>
2508  struct subst1_<F, T, F, Ts>
2509  {
2510  using type = list<>;
2511  };
2512  template <typename A, typename T, typename F, typename Ts>
2513  struct subst1_<vararg_<A>, T, F, Ts>
2514  {
2515  using type = list<Ts>;
2516  };
2517 
2518  template <typename As, typename Ts>
2519  using substitutions_ = push_back<
2520  join<transform<
2521  concat<As, repeat_n_c<size<Ts>{} + 2 - size<As>{}, back<As>>>,
2522  concat<Ts, repeat_n_c<2, back<As>>>,
2523  bind_back<quote_trait<subst1_>, back<As>, drop_c<Ts, size<As>{} - 2>>>>,
2524  list<back<As>>>;
2525 
2526  template <typename As, typename Ts>
2527  using substitutions =
2528  invoke<if_c<(size<Ts>{} + 2 >= size<As>{}), quote<substitutions_>>, As, Ts>;
2529 
2530  template <typename T>
2531  struct is_vararg_ : std::false_type
2532  {
2533  };
2534  template <typename T>
2535  struct is_vararg_<vararg_<T>> : std::true_type
2536  {
2537  };
2538 
2539  template <typename Tags>
2540  using is_variadic_ = is_vararg_<at<push_front<Tags, void>, dec<size<Tags>>>>;
2541 
2542  template <typename Tags, bool IsVariadic = is_variadic_<Tags>::value>
2543  struct lambda_;
2544 
2545  // Non-variadic lambda implementation
2546  template <typename... As>
2547  struct lambda_<list<As...>, false>
2548  {
2549  private:
2550  static constexpr std::size_t arity = sizeof...(As)-1;
2551  using Tags = list<As...>; // Includes the lambda body as the last arg!
2552  using F = back<Tags>;
2553  template <typename T, typename Args>
2554  struct impl;
2555  template <typename T, typename Args>
2556  using lazy_impl_ = lazy::_t<defer<impl, T, protect_<Args>>>;
2557  template <typename, typename, typename = void>
2558  struct subst_
2559  {
2560  };
2561  template <template <typename...> class C, typename... Ts, typename Args>
2562  struct subst_<defer<C, Ts...>, Args, void_<C<_t<impl<Ts, Args>>...>>>
2563  {
2564  using type = C<_t<impl<Ts, Args>>...>;
2565  };
2566  template <typename T, template <T...> class C, T... Is, typename Args>
2567  struct subst_<defer_i<T, C, Is...>, Args, void_<C<Is...>>>
2568  {
2569  using type = C<Is...>;
2570  };
2571  template <typename T, typename Args>
2572  struct impl : if_c<(reverse_find_index<Tags, T>() != npos()),
2573  lazy::at<Args, reverse_find_index<Tags, T>>, id<T>>
2574  {
2575  };
2576  template <typename T, typename Args>
2577  struct impl<protect_<T>, Args>
2578  {
2579  using type = T;
2580  };
2581  template <typename T, typename Args>
2582  struct impl<is_valid_<T>, Args>
2583  {
2584  using type = is_trait<impl<T, Args>>;
2585  };
2586  template <typename If, typename... Ts, typename Args>
2587  struct impl<defer<if_, If, Ts...>, Args> // Short-circuit if_
2588  : impl<lazy_impl_<lazy_if_<If, Ts...>, Args>, Args>
2589  {
2590  };
2591  template <typename Bool, typename... Ts, typename Args>
2592  struct impl<defer<and_, Bool, Ts...>, Args> // Short-circuit and_
2593  : impl<lazy_impl_<lazy_if_<Bool, lazy::and_<Ts...>, protect_<std::false_type>>,
2594  Args>,
2595  Args>
2596  {
2597  };
2598  template <typename Bool, typename... Ts, typename Args>
2599  struct impl<defer<or_, Bool, Ts...>, Args> // Short-circuit or_
2600  : impl<lazy_impl_<lazy_if_<Bool, protect_<std::true_type>, lazy::or_<Ts...>>,
2601  Args>,
2602  Args>
2603  {
2604  };
2605  template <template <typename...> class C, typename... Ts, typename Args>
2606  struct impl<defer<C, Ts...>, Args> : subst_<defer<C, Ts...>, Args>
2607  {
2608  };
2609  template <typename T, template <T...> class C, T... Is, typename Args>
2610  struct impl<defer_i<T, C, Is...>, Args> : subst_<defer_i<T, C, Is...>, Args>
2611  {
2612  };
2613  template <template <typename...> class C, typename... Ts, typename Args>
2614  struct impl<C<Ts...>, Args> : subst_<defer<C, Ts...>, Args>
2615  {
2616  };
2617  template <typename... Ts, typename Args>
2618  struct impl<lambda_<list<Ts...>, false>, Args>
2619  {
2620  using type = compose<uncurry<lambda_<list<As..., Ts...>, false>>,
2621  curry<bind_front<quote<concat>, Args>>>;
2622  };
2623  template <typename... Bs, typename Args>
2624  struct impl<lambda_<list<Bs...>, true>, Args>
2625  {
2626  using type = compose<typename lambda_<list<As..., Bs...>, true>::thunk,
2627  bind_front<quote<concat>, transform<Args, quote<list>>>,
2628  curry<bind_front<quote<substitutions>, list<Bs...>>>>;
2629  };
2630 
2631  public:
2632  template <typename... Ts>
2633  using invoke = _t<if_c<sizeof...(Ts) == arity, impl<F, list<Ts..., F>>>>;
2634  };
2635 
2636  // Lambda with variadic placeholder (broken out due to less efficient compile-time
2637  // resource usage)
2638  template <typename... As>
2639  struct lambda_<list<As...>, true>
2640  {
2641  private:
2642  template <typename T, bool IsVar>
2643  friend struct lambda_;
2644  using Tags = list<As...>; // Includes the lambda body as the last arg!
2645  template <typename T, typename Args>
2646  struct impl;
2647  template <typename Args>
2648  using eval_impl_ = bind_back<quote_trait<impl>, Args>;
2649  template <typename T, typename Args>
2650  using lazy_impl_ = lazy::_t<defer<impl, T, protect_<Args>>>;
2651  template <template <typename...> class C, typename Args, typename Ts>
2652  using try_subst_ = apply<quote<C>, join<transform<Ts, eval_impl_<Args>>>>;
2653  template <typename, typename, typename = void>
2654  struct subst_
2655  {
2656  };
2657  template <template <typename...> class C, typename... Ts, typename Args>
2658  struct subst_<defer<C, Ts...>, Args, void_<try_subst_<C, Args, list<Ts...>>>>
2659  {
2660  using type = list<try_subst_<C, Args, list<Ts...>>>;
2661  };
2662  template <typename T, template <T...> class C, T... Is, typename Args>
2663  struct subst_<defer_i<T, C, Is...>, Args, void_<C<Is...>>>
2664  {
2665  using type = list<C<Is...>>;
2666  };
2667  template <typename T, typename Args>
2668  struct impl : if_c<(reverse_find_index<Tags, T>() != npos()),
2669  lazy::at<Args, reverse_find_index<Tags, T>>, id<list<T>>>
2670  {
2671  };
2672  template <typename T, typename Args>
2673  struct impl<protect_<T>, Args>
2674  {
2675  using type = list<T>;
2676  };
2677  template <typename T, typename Args>
2678  struct impl<is_valid_<T>, Args>
2679  {
2680  using type = list<is_trait<impl<T, Args>>>;
2681  };
2682  template <typename If, typename... Ts, typename Args>
2683  struct impl<defer<if_, If, Ts...>, Args> // Short-circuit if_
2684  : impl<lazy_impl_<lazy_if_<If, Ts...>, Args>, Args>
2685  {
2686  };
2687  template <typename Bool, typename... Ts, typename Args>
2688  struct impl<defer<and_, Bool, Ts...>, Args> // Short-circuit and_
2689  : impl<lazy_impl_<lazy_if_<Bool, lazy::and_<Ts...>, protect_<std::false_type>>,
2690  Args>,
2691  Args>
2692  {
2693  };
2694  template <typename Bool, typename... Ts, typename Args>
2695  struct impl<defer<or_, Bool, Ts...>, Args> // Short-circuit or_
2696  : impl<lazy_impl_<lazy_if_<Bool, protect_<std::true_type>, lazy::or_<Ts...>>,
2697  Args>,
2698  Args>
2699  {
2700  };
2701  template <template <typename...> class C, typename... Ts, typename Args>
2702  struct impl<defer<C, Ts...>, Args> : subst_<defer<C, Ts...>, Args>
2703  {
2704  };
2705  template <typename T, template <T...> class C, T... Is, typename Args>
2706  struct impl<defer_i<T, C, Is...>, Args> : subst_<defer_i<T, C, Is...>, Args>
2707  {
2708  };
2709  template <template <typename...> class C, typename... Ts, typename Args>
2710  struct impl<C<Ts...>, Args> : subst_<defer<C, Ts...>, Args>
2711  {
2712  };
2713  template <typename... Bs, bool IsVar, typename Args>
2714  struct impl<lambda_<list<Bs...>, IsVar>, Args>
2715  {
2716  using type =
2717  list<compose<typename lambda_<list<As..., Bs...>, true>::thunk,
2718  bind_front<quote<concat>, Args>,
2719  curry<bind_front<quote<substitutions>, list<Bs...>>>>>;
2720  };
2721  struct thunk
2722  {
2723  template <typename S, typename R = _t<impl<back<Tags>, S>>>
2724  using invoke = if_c<size<R>{} == 1, front<R>>;
2725  };
2726 
2727  public:
2728  template <typename... Ts>
2729  using invoke = invoke<thunk, substitutions<Tags, list<Ts...>>>;
2730  };
2731  }
2733 
2735  // lambda
2743  template <typename... Ts>
2744  using lambda = if_c<(sizeof...(Ts) > 0), detail::lambda_<list<Ts...>>>;
2745 
2747  // is_valid
2750  template <typename T>
2751  using is_valid = detail::is_valid_<T>;
2752 
2754  // vararg
2756  template <typename T>
2757  using vararg = detail::vararg_<T>;
2758 
2760  // protect
2763  template <typename T>
2764  using protect = detail::protect_<T>;
2765 
2767  // var
2770  template <typename Tag, typename Value>
2771  struct var;
2772 
2774  namespace detail
2775  {
2776  template <typename... As>
2777  struct let_
2778  {
2779  };
2780  template <typename Fn>
2781  struct let_<Fn>
2782  {
2783  using type = lazy::invoke<lambda<Fn>>;
2784  };
2785  template <typename Tag, typename Value, typename... Rest>
2786  struct let_<var<Tag, Value>, Rest...>
2787  {
2788  using type = lazy::invoke<lambda<Tag, _t<let_<Rest...>>>, Value>;
2789  };
2790  }
2792 
2808  template <typename... As>
2809  using let = _t<_t<detail::let_<As...>>>;
2810 
2811  namespace lazy
2812  {
2815  template <typename... As>
2816  using let = defer<let, As...>;
2817  }
2818 
2819  // Some argument placeholders for use in \c lambda expressions.
2821  inline namespace placeholders
2822  {
2823  // regular placeholders:
2824  struct _a;
2825  struct _b;
2826  struct _c;
2827  struct _d;
2828  struct _e;
2829  struct _f;
2830  struct _g;
2831  struct _h;
2832  struct _i;
2833 
2834  // variadic placeholders:
2835  using _args = vararg<void>;
2836  using _args_a = vararg<_a>;
2837  using _args_b = vararg<_b>;
2838  using _args_c = vararg<_c>;
2839  } // namespace placeholders
2840 
2842  // cartesian_product
2844  namespace detail
2845  {
2846  template <typename M2, typename M>
2847  struct cartesian_product_fn
2848  {
2849  template <typename X>
2850  struct lambda0
2851  {
2852  template <typename Xs>
2853  using lambda1 = list<push_front<Xs, X>>;
2854  using type = join<transform<M2, quote<lambda1>>>;
2855  };
2856  using type = join<transform<M, quote_trait<lambda0>>>;
2857  };
2858  } // namespace detail
2860 
2867  template <typename ListOfLists>
2868  using cartesian_product =
2870 
2871  namespace lazy
2872  {
2875  template <typename ListOfLists>
2877  }
2878 
2881  // add_const_if
2882  template <typename If>
2884 
2885  template <bool If>
2886  using add_const_if_c = if_c<If, quote_trait<std::add_const>, quote_trait<id>>;
2888 
2890  // integer_sequence
2891 
2892 #ifndef __cpp_lib_integer_sequence
2893  template <typename T, T... Is>
2897  {
2898  using value_type = T;
2900  static constexpr std::size_t size() noexcept { return sizeof...(Is); }
2901  };
2902 #endif
2903 
2905  namespace detail
2906  {
2907  // Glue two sets of integer_sequence together
2908  template <typename I1, typename I2, typename I3>
2909  struct integer_sequence_cat;
2910 
2911  template <typename T, T... N1, T... N2, T... N3>
2912  struct integer_sequence_cat<integer_sequence<T, N1...>, integer_sequence<T, N2...>,
2913  integer_sequence<T, N3...>>
2914  {
2915  using type = integer_sequence<T, N1..., (sizeof...(N1) + N2)...,
2916  (sizeof...(N1) + sizeof...(N2) + N3)...>;
2917  };
2918 
2919  template <typename T, std::size_t N>
2920  struct make_integer_sequence_
2921  : integer_sequence_cat<_t<make_integer_sequence_<T, N / 2>>,
2922  _t<make_integer_sequence_<T, N / 2>>,
2923  _t<make_integer_sequence_<T, N % 2>>>
2924  {
2925  };
2926 
2927  template <typename T>
2928  struct make_integer_sequence_<T, 0>
2929  {
2930  using type = integer_sequence<T>;
2931  };
2932 
2933  template <typename T>
2934  struct make_integer_sequence_<T, 1>
2935  {
2936  using type = integer_sequence<T, 0>;
2937  };
2938  } // namespace detail
2940 
2945  template <typename T, T N>
2947 
2951  template <std::size_t... Is>
2953 
2958  template <std::size_t N>
2960 
2962  namespace detail
2963  {
2964  template <typename State, typename Ch>
2965  using atoi_ = if_c<(Ch::value >= '0' && Ch::value <= '9'),
2966  std::integral_constant<typename State::value_type,
2967  State::value * 10 + (Ch::value - '0')>>;
2968  }
2970 
2971  inline namespace literals
2972  {
2975  template <char... Chs>
2977  {
2978  return {};
2979  }
2980  }
2981 
2983  // integer_range
2985  namespace detail
2986  {
2987  template <class T, T offset, class U>
2988  struct offset_integer_sequence_
2989  {
2990  };
2991 
2992  template <class T, T offset, T... Ts>
2993  struct offset_integer_sequence_<T, offset, meta::integer_sequence<T, Ts...>>
2994  {
2995  using type = meta::integer_sequence<T, (Ts + offset)...>;
2996  };
2997  } // namespace detail
2999 
3002  template <class T, T from, T to>
3003  using integer_range = meta::_t<
3004  detail::offset_integer_sequence_<T, from, meta::make_integer_sequence<T, to - from>>>;
3006  } // namespace v1
3008 } // namespace meta
3009 
3011 #if defined(__clang__) && defined(_LIBCPP_VERSION) && _LIBCPP_VERSION <= 1101
3012 
3013 _LIBCPP_BEGIN_NAMESPACE_STD
3014 template <class>
3015 class _LIBCPP_TYPE_VIS_ONLY allocator;
3016 template <class, class>
3017 struct _LIBCPP_TYPE_VIS_ONLY pair;
3018 template <class>
3019 struct _LIBCPP_TYPE_VIS_ONLY hash;
3020 template <class>
3021 struct _LIBCPP_TYPE_VIS_ONLY less;
3022 template <class>
3023 struct _LIBCPP_TYPE_VIS_ONLY equal_to;
3024 template <class>
3025 struct _LIBCPP_TYPE_VIS_ONLY char_traits;
3026 template <class, class>
3027 class _LIBCPP_TYPE_VIS_ONLY list;
3028 template <class, class>
3029 class _LIBCPP_TYPE_VIS_ONLY forward_list;
3030 template <class, class>
3031 class _LIBCPP_TYPE_VIS_ONLY vector;
3032 template <class, class>
3033 class _LIBCPP_TYPE_VIS_ONLY deque;
3034 template <class, class, class>
3035 class _LIBCPP_TYPE_VIS_ONLY basic_string;
3036 template <class, class, class, class>
3037 class _LIBCPP_TYPE_VIS_ONLY map;
3038 template <class, class, class, class>
3039 class _LIBCPP_TYPE_VIS_ONLY multimap;
3040 template <class, class, class>
3041 class _LIBCPP_TYPE_VIS_ONLY set;
3042 template <class, class, class>
3043 class _LIBCPP_TYPE_VIS_ONLY multiset;
3044 template <class, class, class, class, class>
3045 class _LIBCPP_TYPE_VIS_ONLY unordered_map;
3046 template <class, class, class, class, class>
3047 class _LIBCPP_TYPE_VIS_ONLY unordered_multimap;
3048 template <class, class, class, class>
3049 class _LIBCPP_TYPE_VIS_ONLY unordered_set;
3050 template <class, class, class, class>
3051 class _LIBCPP_TYPE_VIS_ONLY unordered_multiset;
3052 template <class, class>
3053 class _LIBCPP_TYPE_VIS_ONLY queue;
3054 template <class, class, class>
3055 class _LIBCPP_TYPE_VIS_ONLY priority_queue;
3056 template <class, class>
3057 class _LIBCPP_TYPE_VIS_ONLY stack;
3058 _LIBCPP_END_NAMESPACE_STD
3059 
3060 namespace meta
3061 {
3062  inline namespace v1
3063  {
3064  namespace detail
3065  {
3066  template <typename T, typename A = std::allocator<T>>
3067  using std_list = std::list<T, A>;
3068  template <typename T, typename A = std::allocator<T>>
3069  using std_forward_list = std::forward_list<T, A>;
3070  template <typename T, typename A = std::allocator<T>>
3071  using std_vector = std::vector<T, A>;
3072  template <typename T, typename A = std::allocator<T>>
3073  using std_deque = std::deque<T, A>;
3074  template <typename T, typename C = std::char_traits<T>, typename A = std::allocator<T>>
3075  using std_basic_string = std::basic_string<T, C, A>;
3076  template <typename K, typename V, typename C = std::less<K>,
3077  typename A = std::allocator<std::pair<K const, V>>>
3078  using std_map = std::map<K, V, C, A>;
3079  template <typename K, typename V, typename C = std::less<K>,
3080  typename A = std::allocator<std::pair<K const, V>>>
3081  using std_multimap = std::multimap<K, V, C, A>;
3082  template <typename K, typename C = std::less<K>, typename A = std::allocator<K>>
3083  using std_set = std::set<K, C, A>;
3084  template <typename K, typename C = std::less<K>, typename A = std::allocator<K>>
3085  using std_multiset = std::multiset<K, C, A>;
3086  template <typename K, typename V, typename H = std::hash<K>,
3087  typename C = std::equal_to<K>,
3088  typename A = std::allocator<std::pair<K const, V>>>
3089  using std_unordered_map = std::unordered_map<K, V, H, C, A>;
3090  template <typename K, typename V, typename H = std::hash<K>,
3091  typename C = std::equal_to<K>,
3092  typename A = std::allocator<std::pair<K const, V>>>
3093  using std_unordered_multimap = std::unordered_multimap<K, V, H, C, A>;
3094  template <typename K, typename H = std::hash<K>, typename C = std::equal_to<K>,
3095  typename A = std::allocator<K>>
3096  using std_unordered_set = std::unordered_set<K, H, C, A>;
3097  template <typename K, typename H = std::hash<K>, typename C = std::equal_to<K>,
3098  typename A = std::allocator<K>>
3099  using std_unordered_multiset = std::unordered_multiset<K, H, C, A>;
3100  template <typename T, typename C = std_deque<T>>
3101  using std_queue = std::queue<T, C>;
3102  template <typename T, typename C = std_vector<T>,
3103  class D = std::less<typename C::value_type>>
3104  using std_priority_queue = std::priority_queue<T, C, D>;
3105  template <typename T, typename C = std_deque<T>>
3106  using std_stack = std::stack<T, C>;
3107  }
3108 
3109  template <>
3110  struct quote<::std::list> : quote<detail::std_list>
3111  {
3112  };
3113  template <>
3114  struct quote<::std::deque> : quote<detail::std_deque>
3115  {
3116  };
3117  template <>
3118  struct quote<::std::forward_list> : quote<detail::std_forward_list>
3119  {
3120  };
3121  template <>
3122  struct quote<::std::vector> : quote<detail::std_vector>
3123  {
3124  };
3125  template <>
3126  struct quote<::std::basic_string> : quote<detail::std_basic_string>
3127  {
3128  };
3129  template <>
3130  struct quote<::std::map> : quote<detail::std_map>
3131  {
3132  };
3133  template <>
3134  struct quote<::std::multimap> : quote<detail::std_multimap>
3135  {
3136  };
3137  template <>
3138  struct quote<::std::set> : quote<detail::std_set>
3139  {
3140  };
3141  template <>
3142  struct quote<::std::multiset> : quote<detail::std_multiset>
3143  {
3144  };
3145  template <>
3146  struct quote<::std::unordered_map> : quote<detail::std_unordered_map>
3147  {
3148  };
3149  template <>
3150  struct quote<::std::unordered_multimap> : quote<detail::std_unordered_multimap>
3151  {
3152  };
3153  template <>
3154  struct quote<::std::unordered_set> : quote<detail::std_unordered_set>
3155  {
3156  };
3157  template <>
3158  struct quote<::std::unordered_multiset> : quote<detail::std_unordered_multiset>
3159  {
3160  };
3161  template <>
3162  struct quote<::std::queue> : quote<detail::std_queue>
3163  {
3164  };
3165  template <>
3166  struct quote<::std::priority_queue> : quote<detail::std_priority_queue>
3167  {
3168  };
3169  template <>
3170  struct quote<::std::stack> : quote<detail::std_stack>
3171  {
3172  };
3173  }
3174 }
3175 
3176 #endif
3177 
3179 #if defined(__clang__)
3180 #pragma GCC diagnostic pop
3181 #endif
3182 #endif
bool_< 0==size< List >::type::value > empty
An Boolean integral constant wrapper around true if List is an empty type list; false, otherwise.
Definition: meta.hpp:1592
and_c< Bools::type::value... > strict_and
Logically and together all the integral constant-wrapped Boolean parameters, without doing short-circ...
Definition: meta.hpp:958
_t< id< T >> id_t
An alias for type T. Useful in non-deduced contexts.
Definition: meta.hpp:429
at< List, meta::size_t< N >> at_c
Return the N th element in the meta::list List.
Definition: meta.hpp:1310
std::integral_constant< decltype(T::type::value-U::type::value), T::type::value-U::type::value > minus
An integral constant wrapper around the result of subtracting the two wrapped integers T::type::value...
Definition: meta.hpp:203
_t< detail::_and_< Bools... >> and_
Logically and together all the integral constant-wrapped Boolean parameters, with short-circuiting...
Definition: meta.hpp:964
defer< bind_front, Fn, Ts... > bind_front
Definition: meta.hpp:717
reverse_fold< ListOfLists, list< list<>>, quote_trait< detail::cartesian_product_fn >> cartesian_product
Given a list of lists ListOfLists, return a new list of lists that is the Cartesian Product...
Definition: meta.hpp:2869
fold< pop_front< list< Ts... >>, front< list< Ts... >>, quote< detail::max_ >> max
An integral constant wrapper around the maximum of Ts::type::value...
Definition: meta.hpp:1569
bool_<(T::type::value > U::type::value)> greater
A Boolean integral constant wrapper around true if T::type::value is greater than U::type::value; fal...
Definition: meta.hpp:248
make_integer_sequence< std::size_t, N > make_index_sequence
Generate index_sequence containing integer constants [0,1,2,...,N-1].
Definition: meta.hpp:2959
A trait that unpacks the types in the type list List into the Callable F.
Definition: meta.hpp:732
_t< detail::find_index_< List, T >> find_index
Finds the index of the first occurrence of the type T within the list List. Returns meta::npos if the...
Definition: meta.hpp:1672
if_c<(sizeof...(Ts) > 0), detail::lambda_< list< Ts... >>> lambda
For creating anonymous Callables.
Definition: meta.hpp:2744
defer< less, T, U > less
Definition: meta.hpp:355
bool_< T::type::value==U::type::value > equal_to
A Boolean integral constant wrapper around the result of comparing T::type::value and U::type::value ...
Definition: meta.hpp:236
std::integral_constant< decltype(T::type::value *U::type::value), T::type::value *U::type::value > multiplies
An integral constant wrapper around the result of multiplying the two wrapped integers T::type::value...
Definition: meta.hpp:210
fold< List, State, Fun > accumulate
An alias for meta::fold.
Definition: meta.hpp:1050
fold< List, meta::size_t< 0 >, bind_back< quote< detail::count_fn >, T >> count
Count the number of times a type T appears in the list List.
Definition: meta.hpp:1959
defer< equal_to, T, U > equal_to
Definition: meta.hpp:340
_t< _t< detail::let_< As... >>> let
A lexically scoped expression with local variables.
Definition: meta.hpp:2809
_t< detail::as_list_< Sequence >> as_list
Turn a type into an instance of meta::list in a way determined by meta::invoke.
Definition: meta.hpp:2194
std::integral_constant< decltype(T::type::value^U::type::value), T::type::value^U::type::value > bit_xor
An integral constant wrapper around the result of bitwise-exclusive-or'ing the two wrapped integers T...
Definition: meta.hpp:287
_t< detail::fold_< List, State, Fun >> fold
Return a new meta::list constructed by doing a left fold of the list List using binary Callable Fun a...
Definition: meta.hpp:1043
std::integral_constant< decltype(T::type::value%U::type::value), T::type::value%U::type::value > modulus
An integral constant wrapper around the remainder of dividing the two wrapped integers T::type::value...
Definition: meta.hpp:230
_t< detail::_if_< Args... >> if_
Select one type or another depending on a compile-time Boolean.
Definition: meta.hpp:878
fold< pop_front< list< Ts... >>, front< list< Ts... >>, quote< detail::min_ >> min
An integral constant wrapper around the minimum of Ts::type::value...
Definition: meta.hpp:1564
typename F::template invoke< Args... > invoke
Evaluate the Callable F with the arguments Args.
Definition: meta.hpp:391
constexpr auto && for_each
for_each(List, UnaryFunction) calls the UnaryFunction for each argument in the List.
Definition: meta.hpp:2110
_t< detail::reverse_find_index_< List, T >> reverse_find_index
Finds the index of the last occurrence of the type T within the list List. Returns meta::npos if the ...
Definition: meta.hpp:1723
For use when defining local variables in meta::let expressions.
Definition: meta.hpp:2771
list< F, S > pair
A list with exactly two elements.
Definition: meta.hpp:1607
defer< compose, Fns... > compose
Definition: meta.hpp:633
fold< List, list<>, detail::filter_< Pred >> filter
Returns a new meta::list where only those elements of List that satisfy the Callable Pred such that i...
Definition: meta.hpp:2058
_t< detail::_if_< bool_< If >, Args... >> if_c
Select one type or another depending on a compile-time Boolean.
Definition: meta.hpp:883
detail::protect_< T > protect
For preventing the evaluation of a nested defered computation in a let or lambda expression.
Definition: meta.hpp:2764
static constexpr std::size_t size() noexcept
Definition: meta.hpp:1123
static constexpr std::size_t size() noexcept
Definition: meta.hpp:2900
meta::size_t< alignof(T)> alignof_
An alias that computes the alignment required for any instance of the type T.
Definition: meta.hpp:570
A Callable that reverses the order of the first two arguments.
Definition: meta.hpp:793
_t< detail::front_< List >> front
Return the first element in meta::list List.
Definition: meta.hpp:1407
std::is_same< integer_sequence< bool, Bools... >, integer_sequence< bool,(Bools||true)... >> and_c
Logically and together all the Boolean parameters.
Definition: meta.hpp:951
fold< ListOfLists, repeat_n< size< front< ListOfLists >>, list<>>, bind_back< quote< transform >, quote< push_back >>> transpose
Given a list of lists of types ListOfLists, transpose the elements from the lists.
Definition: meta.hpp:2125
meta::_t< detail::inherit_< List >> inherit
A type that inherits from all the types in the list.
Definition: meta.hpp:2329
front< Pair > first
Retrieve the first element of the pair Pair.
Definition: meta.hpp:1612
not_< empty< find< List, T >>> in
A Boolean integral constant wrapper around true if there is at least one occurrence of T in List...
Definition: meta.hpp:2296
bool_< T::type::value!=U::type::value > not_equal_to
A Boolean integral constant wrapper around the result of comparing T::type::value and U::type::value ...
Definition: meta.hpp:242
meta::_t< detail::offset_integer_sequence_< T, from, meta::make_integer_sequence< T, to-from >>> integer_range
Makes the integer sequence [from, to).
Definition: meta.hpp:3004
defer< bind_back, Fn, Ts... > bind_back
Definition: meta.hpp:722
compose< quote< _t >, quote_i< T, C >> quote_trait_i
Turn a trait C taking literals of type T into a Callable.
Definition: meta.hpp:688
std::integral_constant< decltype(~T::type::value),~T::type::value > bit_not
An integral constant wrapper around the result of bitwise-complementing the wrapped integer T::type::...
Definition: meta.hpp:293
std::integral_constant< bool, B > bool_
An integral constant wrapper for bool.
Definition: meta.hpp:167
_t< detail::drop_< List, N >> drop
Return a new meta::list by removing the first N elements from List.
Definition: meta.hpp:1367
A Callable that partially applies the Callable F by binding the arguments Ts to the front of F...
Definition: meta.hpp:696
_t< detail::at_< List, N >> at
Return the N th element in the meta::list List.
Definition: meta.hpp:1303
_t< detail::concat_< Lists... >> concat
Concatenates several lists into a single list.
Definition: meta.hpp:1190
_t< detail::reverse_fold_< List, State, Fun >> reverse_fold
Return a new meta::list constructed by doing a right fold of the list List using binary Callable Fun ...
Definition: meta.hpp:1097
detail::is_valid_< T > is_valid
For testing whether a deferred computation will succeed in a let or a lambda.
Definition: meta.hpp:2751
_t< detail::drop_< List, meta::size_t< N >>> drop_c
Return a new meta::list by removing the first N elements from List.
Definition: meta.hpp:1374
transpose< ListOfLists > zip
Given a list of lists of types ListOfLists, construct a new list by grouping the elements from the li...
Definition: meta.hpp:2163
empty< find_if< List, F >> none_of
A Boolean integral constant wrapper around true if invoke::value is false for all elements A in...
Definition: meta.hpp:2278
_t< detail::push_front_< List, T >> push_front
Return a new meta::list by adding the element T to the front of List.
Definition: meta.hpp:1473
_t< detail::sort_< List, Pred >> sort
Return a new meta::list that is sorted according to Callable predicate Pred.
Definition: meta.hpp:2474
A trait that always returns its argument T. Also, a Callable that always returns T.
Definition: meta.hpp:407
meta::size_t< List::size()> size
An integral constant wrapper that is the size of the meta::list List.
Definition: meta.hpp:1132
not_c< Bool::type::value > not_
Logically negate the integral constant-wrapped Boolean parameter.
Definition: meta.hpp:938
transform< transpose< ListOfLists >, uncurry< Fun >> zip_with
Given a list of lists of types ListOfLists and a Callable Fun, construct a new list by calling Fun wi...
Definition: meta.hpp:2144
bool_<(T::type::value<=U::type::value)> less_equal
A Boolean integral constant wrapper around true if T::type::value is less than or equal to U::type::v...
Definition: meta.hpp:266
bool_<(T::type::value< U::type::value)> less
A Boolean integral constant wrapper around true if T::type::value is less than U::type::value; false...
Definition: meta.hpp:254
_t< detail::find_if_< List, Fun >> find_if
Return the tail of the list List starting at the first element A such that invoke::value is true, if any such element exists; the empty list, otherwise.
Definition: meta.hpp:1826
Tiny metaprogramming library.
Definition: meta.hpp:114
A list of types.
Definition: meta.hpp:1119
A wrapper that defers the instantiation of a template C with type parameters Ts in a lambda or let ex...
Definition: meta.hpp:525
_t< detail::pop_front_< List >> pop_front
Return a new meta::list by removing the first element from the front of List.
Definition: meta.hpp:1506
bool_<(T::type::value >=U::type::value)> greater_equal
A Boolean integral constant wrapper around true if T::type::value is greater than or equal to U::type...
Definition: meta.hpp:260
std::integral_constant< std::size_t, N > size_t
An integral constant wrapper for std::size_t.
Definition: meta.hpp:162
Compose the Callables Fs in the parameter pack Ts.
Definition: meta.hpp:610
Forward declarations.
fold< List, list<>, quote_trait< detail::insert_back_ >> unique
Return a new meta::list where all duplicate elements have been removed.
Definition: meta.hpp:2375
_t< detail::is_callable_< T >> is_callable
An alias for std::true_type if T::invoke exists and names a class template or alias template; otherwi...
Definition: meta.hpp:506
std::integral_constant< decltype(T::type::value+U::type::value), T::type::value+U::type::value > plus
An integral constant wrapper around the result of adding the two wrapped integers T::type::value and ...
Definition: meta.hpp:196
not_< empty< find_if< List, F >>> any_of
A Boolean integral constant wrapper around true if invoke::value is true for any element A in m...
Definition: meta.hpp:2260
_t< extension::apply< C, List >> apply
Applies the Callable C using the types in the type list List as arguments.
Definition: meta.hpp:757
std::integral_constant< decltype(T::type::value &U::type::value), T::type::value &U::type::value > bit_and
An integral constant wrapper around the result of bitwise-and'ing the two wrapped integers T::type::v...
Definition: meta.hpp:273
std::integral_constant< decltype(-T::type::value),-T::type::value > negate
An integral constant wrapper around the result of negating the wrapped integer T::type::value.
Definition: meta.hpp:223
reverse_fold< List, list<>, quote< push_back >> reverse
Return a new meta::list by reversing the elements in the list List.
Definition: meta.hpp:2211
_t< detail::is_trait_< T >> is_trait
An alias for std::true_type if T::type exists and names a type; otherwise, it's an alias for std::fal...
Definition: meta.hpp:500
meta::size_t< std::size_t(-1)> npos
A special value used to indicate no matches. It equals the maximum value representable by std::size_t...
Definition: meta.hpp:1112
detail::on_< Fs... > on
Use as on. Creates an Callable that applies Callable F to the result of applying Callable c...
Definition: meta.hpp:838
not_< std::is_same< integer_sequence< bool, Bools... >, integer_sequence< bool,(Bools &&false)... >>> or_c
Logically or together all the Boolean parameters.
Definition: meta.hpp:970
bind_front< quote< apply >, F > uncurry
A Callable that takes a type list, unpacks the types, and then calls the Callable F with the types...
Definition: meta.hpp:775
empty< find_if< List, not_fn< F >>> all_of
A Boolean integral constant wrapper around true if invoke::value is true for all elements A in ...
Definition: meta.hpp:2242
meta::size_t< sizeof(T)> sizeof_
An alias that computes the size of the type T.
Definition: meta.hpp:563
front< pop_front< Pair >> second
Retrieve the first element of the pair Pair.
Definition: meta.hpp:1617
constexpr T::type::value_type _v
Variable alias for T::type::value.
Definition: meta.hpp:147
_t< detail::make_integer_sequence_< T,(std::size_t) N >> make_integer_sequence
Generate integer_sequence containing integer constants [0,1,2,...,N-1].
Definition: meta.hpp:2946
_t< detail::replace_if_< List, C, U >> replace_if
Return a new meta::list where all elements A of the list List for which invoke::value is true ha...
Definition: meta.hpp:1936
_t< detail::is_< T, C >> is
is
Definition: meta.hpp:605
Turn a class template or alias template C into a Callable.
Definition: meta.hpp:639
_t< detail::repeat_n_c_< N::type::value, T >> repeat_n
Generate list of size N arguments.
Definition: meta.hpp:1249
defer< invoke, F, Args... > invoke
Definition: meta.hpp:399
_t< detail::reverse_find_if_< List, Fun >> reverse_find_if
Return the tail of the list List starting at the last element A such that invoke::value is true, if any such element exists; the empty list, otherwise.
Definition: meta.hpp:1868
std::integral_constant< decltype(T::type::value|U::type::value), T::type::value|U::type::value > bit_or
An integral constant wrapper around the result of bitwise-or'ing the two wrapped integers T::type::va...
Definition: meta.hpp:280
_t< detail::push_back_< List, T >> push_back
Return a new meta::list by adding the element T to the back of List.
Definition: meta.hpp:1541
fold< List, pair< list<>, list<>>, detail::partition_< Pred >> partition
Returns a pair of lists, where the elements of List that satisfy the Callable Pred such that invoke
Definition: meta.hpp:2417
A Callable that partially applies the Callable F by binding the arguments Us to the back of F...
Definition: meta.hpp:706
_t< detail::_or_< Bools... >> or_
Logically or together all the integral constant-wrapped Boolean parameters, with short-circuiting.
Definition: meta.hpp:982
fold< List, meta::size_t< 0 >, bind_back< quote< detail::count_if_fn >, Fn >> count_if
Count the number of times the predicate Fn evaluates to true for all the elements in the list List...
Definition: meta.hpp:1983
or_c< Bools::type::value... > strict_or
Logically or together all the integral constant-wrapped Boolean parameters, without doing short-circu...
Definition: meta.hpp:976
_t< detail::replace_< List, T, U >> replace
Return a new meta::list where all instances of type T have been replaced with U.
Definition: meta.hpp:1902
std::integral_constant< char, Ch > char_
An integral constant wrapper for char.
Definition: meta.hpp:177
drop< List, min< find_index< List, T >, size< List >>> find
Return the tail of the list List starting at the first occurrence of T, if any such element exists; t...
Definition: meta.hpp:1769
invoke< id< void >, Ts... > void_
An alias for void.
Definition: meta.hpp:443
A wrapper that defers the instantiation of a template C with integral constant parameters Is in a lam...
Definition: meta.hpp:536
_t< detail::back_< List >> back
Return the last element in meta::list List.
Definition: meta.hpp:1440
A container for a sequence of compile-time integer constants.
Definition: meta.hpp:2896
typename T::type _t
Type alias for T::type.
Definition: meta.hpp:140
apply< quote< concat >, ListOfLists > join
Joins a list of lists into a single list.
Definition: meta.hpp:1208
std::integral_constant< int, I > int_
An integral constant wrapper for int.
Definition: meta.hpp:172
std::integral_constant< decltype(T::type::value+1), T::type::value+1 > inc
An integral constant wrapper around the result of incrementing the wrapped integer T::type::value...
Definition: meta.hpp:184
drop< List, min< reverse_find_index< List, T >, size< List >>> reverse_find
Return the tail of the list List starting at the last occurrence of T, if any such element exists; th...
Definition: meta.hpp:1785
An empty type.
Definition: meta.hpp:133
Turn a class template or alias template C taking literals of type T into a Callable.
Definition: meta.hpp:651
std::integral_constant< decltype(T::type::value/U::type::value), T::type::value/U::type::value > divides
An integral constant wrapper around the result of dividing the two wrapped integers T::type::value an...
Definition: meta.hpp:217
_t< detail::transform_< list< Args... >>> transform
Return a new meta::list constructed by transforming all the elements in List with the unary Callable ...
Definition: meta.hpp:2027
detail::vararg_< T > vararg
For defining variadic placeholders.
Definition: meta.hpp:2757
std::integral_constant< decltype(T::type::value-1), T::type::value-1 > dec
An integral constant wrapper around the result of decrementing the wrapped integer T::type::value...
Definition: meta.hpp:189
_t< detail::repeat_n_c_< N, T >> repeat_n_c
Generate list of size N arguments.
Definition: meta.hpp:1256
bool_<!Bool > not_c
Logically negate the Boolean parameter.
Definition: meta.hpp:933