siplasplas
meta.hpp
1 #ifndef SIPLASPLAS_UTILITY_META_H
2 #define SIPLASPLAS_UTILITY_META_H
3 
4 #include <type_traits>
5 #include <cstdint>
6 
7 namespace cpp
8 {
9 
10 namespace meta
11 {
12  template<typename T>
13  using decay_t = typename std::decay<T>::type;
14 
15  template<typename... Bs>
16  struct assert;
17 
18  template<typename B, typename... Bs>
19  struct assert<B, Bs...> : assert<Bs...>
20  {
21  static_assert(B::value, "Assertion failed");
22  };
23 
24  template<>
25  struct assert<> {};
26 
27  template<typename T>
28  using void_t = typename std::conditional<sizeof(T) >= 0, void, T>::type;
29 
30  template<typename T>
31  struct identity
32  {
33  using type = T;
34  };
35 
36  template<typename Metafunction>
37  using type_t = typename Metafunction::type;
38 
39  template<typename MetafunctionClass, typename... Args>
40  using apply_t = type_t<typename MetafunctionClass::template apply<Args...>>;
41 
42  template<typename MetafunctionClass, typename Seq>
44 
45  template<typename MetafunctionClass,
46  template<typename...> class Seq, typename... Ts>
47  struct sequence_apply<MetafunctionClass, Seq<Ts...>>
48  {
49  using type = apply_t<MetafunctionClass, Ts...>;
50  };
51 
52  template<typename MetafunctionClass, typename Seq>
53  using sequence_apply_t = type_t<sequence_apply<MetafunctionClass, Seq>>;
54 
55  template<std::uint8_t I>
56  using uint8_t = std::integral_constant<std::uint8_t, I>;
57  template<std::uint16_t I>
58  using uint16_t = std::integral_constant<std::uint16_t, I>;
59  template<std::uint32_t I>
60  using uint32_t = std::integral_constant<std::uint32_t, I>;
61  template<std::uint64_t I>
62  using uint64_t = std::integral_constant<std::uint64_t, I>;
63 
64  template<std::int8_t I>
65  using int8_t = std::integral_constant<std::int8_t, I>;
66  template<std::int16_t I>
67  using int16_t = std::integral_constant<std::int16_t, I>;
68  template<std::int32_t I>
69  using int32_t = std::integral_constant<std::int32_t, I>;
70  template<std::int64_t I>
71  using int64_t = std::integral_constant<std::int64_t, I>;
72 
73  template<std::size_t I>
74  using size_t = std::integral_constant<std::size_t, I>;
75 
76  template<bool B>
77  using bool_ = std::integral_constant<bool, B>;
78  using true_ = bool_<true>;
79  using false_ = bool_<false>;
80 
81  template<char C>
82  using char_ = std::integral_constant<char, C>;
83 
84  template<typename T, typename = void>
85  struct is_integral : false_ {};
86  template<typename T>
87  struct is_integral<T, void_t<decltype(T::value)>> :
88  true_
89  {};
90 
91  template<typename T, typename = assert<is_integral<T>>>
92  constexpr decltype(T::value) value()
93  {
94  return T::value;
95  }
96 
97  template<template<typename...> class Function>
98  struct defer
99  {
100  template<typename... Args>
101  struct apply
102  {
103  template<typename Instance, bool = is_integral<Instance>::value>
104  struct result
105  {
106  using type = Instance;
107  };
108 
109  template<typename Instance>
110  struct result<Instance, false>
111  {
112  using type = type_t<Instance>;
113  };
114 
115  using type = type_t<result<Function<Args...>>>;
116  };
117  };
118 
119  struct and_
120  {
121  template<typename Lhs, typename Rhs>
122  struct apply : assert<
123  is_integral<Lhs>,
124  is_integral<Rhs>
125  >
126  {
127  using type = bool_<Lhs::value && Rhs::value>;
128  };
129  };
130 
131  template<typename Lhs, typename Rhs>
132  using and_t = apply_t<and_, Lhs, Rhs>;
133 
134  struct or_
135  {
136  template<typename Lhs, typename Rhs>
137  struct apply : assert<
138  is_integral<Lhs>,
139  is_integral<Rhs>
140  >
141  {
142  using type = bool_<Lhs::value || Rhs::value>;
143  };
144  };
145 
146  template<typename Lhs, typename Rhs>
147  using or_t = apply_t<or_, Lhs, Rhs>;
148 
149  struct add_
150  {
151  template<typename Lhs, typename Rhs>
152  struct apply : assert<
153  is_integral<Lhs>,
154  is_integral<Rhs>
155  >
156  {
157  using type = std::integral_constant<decltype(Lhs::value + Rhs::value), Lhs::value + Rhs::value>;
158  };
159  };
160 
161  struct div_
162  {
163  template<typename Lhs, typename Rhs>
164  struct apply : assert<
165  is_integral<Lhs>,
166  is_integral<Rhs>
167  >
168  {
169  using type = std::integral_constant<decltype(Lhs::value / Rhs::value), Lhs::value / Rhs::value>;
170  };
171  };
172 
173  template<typename Lhs, typename Rhs>
174  using add_t = apply_t<add_, Lhs, Rhs>;
175 
176  template<typename Lhs, typename Rhs>
177  using div_t = apply_t<div_, Lhs, Rhs>;
178 
179  struct greater
180  {
181  template<typename Lhs, typename Rhs>
182  struct apply : assert<
183  is_integral<Lhs>,
184  is_integral<Rhs>
185  >
186  {
187  using type = bool_<(Lhs::value > Rhs::value)>;
188  };
189  };
191  {
192  template<typename Lhs, typename Rhs>
193  struct apply : assert<
194  is_integral<Lhs>,
195  is_integral<Rhs>
196  >
197  {
198  using type = bool_<(Lhs::value >= Rhs::value)>;
199  };
200  };
201  struct less
202  {
203  template<typename Lhs, typename Rhs>
204  struct apply : assert<
205  is_integral<Lhs>,
206  is_integral<Rhs>
207  >
208  {
209  using type = bool_<(Lhs::value < Rhs::value)>;
210  };
211  };
213  {
214  template<typename Lhs, typename Rhs>
215  struct apply : assert<
216  is_integral<Lhs>,
217  is_integral<Rhs>
218  >
219  {
220  using type = bool_<(Lhs::value <= Rhs::value)>;
221  };
222  };
223 
224  template<typename... Ts>
225  struct list
226  {
227  static constexpr std::size_t size = sizeof...(Ts);
228  };
229 
230  template<typename List>
231  struct list_size;
232 
233  template<template<typename...> class Sequence, typename... Ts>
234  struct list_size<Sequence<Ts...>> : public size_t<sizeof...(Ts)>
235  {};
236 
237  template<char... Chars>
238  using string = list<std::integral_constant<char, Chars>...>;
239 
240 
241  template<typename Seq>
242  struct functor
243  {
244  static_assert(sizeof(Seq) != sizeof(Seq), "Type is not a sequence");
245  };
246 
247  template<template<typename...> class Seq, typename... Ts>
248  struct functor<Seq<Ts...>>
249  {
250  template<typename... Us>
251  struct apply
252  {
253  using type = Seq<Us...>;
254  };
255 
256  template<template<typename...> class Seq2, typename... Us>
257  struct apply<Seq2<Us...>>
258  {
259  using type = Seq<Us...>;
260  };
261  };
262 
263  template<typename Seq, typename... Ts>
264  using apply_functor = apply_t<functor<Seq>, Ts...>;
265 
266  template<typename Seq, typename... Ts>
267  using functor_t = apply_functor<Seq, Ts...>;
268 
269  template<typename Lhs, typename Rhs>
270  struct cat;
271 
272  template<template<typename...> class Seq,
273  typename... Lhs, typename... Rhs>
274  struct cat<Seq<Lhs...>, Seq<Rhs...>>
275  {
276  using type = Seq<Lhs..., Rhs...>;
277  };
278 
279  template<typename Lhs, typename Rhs>
280  using cat_t = type_t<cat<Lhs, Rhs>>;
281 
282  template<std::size_t I>
283  using index_t = std::integral_constant<std::size_t, I>;
284 
285  template<typename T, T... Values>
287 
288  template<std::size_t... Is>
289  using index_sequence = list<index_t<Is>...>;
290 
291  namespace detail
292  {
293  template<typename Left, std::size_t Index, typename Right>
294  struct split;
295 
296  template<template<typename...> class Seq, std::size_t Index,
297  typename... Left, typename Head, typename... Tail>
298  struct split<Seq<Left...>, Index, Seq<Head, Tail...>>
299  {
300  using next = split<Seq<Left..., Head>, Index - 1, Seq<Tail...>>;
301 
302  using before = typename next::before;
303  using left = typename next::left;
304  using head = typename next::head;
305  using right = typename next::right;
306  using after = typename next::after;
307  };
308 
309  template<template<typename...> class Seq,
310  typename... Left, typename Head, typename... Tail>
311  struct split<Seq<Left...>, 0, Seq<Head, Tail...>>
312  {
313  using before = Seq<Left...>;
314  using left = Seq<Left..., Head>;
315  using head = Head;
316  using right = Seq<Head, Tail...>;
317  using after = Seq<Tail...>;
318  };
319 
320  template<template<typename...> class Seq,
321  typename Head>
322  struct split<Seq<Head>, 0, Seq<>>
323  {
324  using before = Seq<>;
325  using left = Seq<Head>;
326  using head = Head;
327  using right = Seq<Head>;
328  using after = Seq<>;
329  };
330  }
331 
332  template<std::size_t Index, typename... Ts>
333  using pack_split = detail::split<list<>, Index, list<Ts...>>;
334  template<std::size_t Index, typename... Ts>
335  using pack_split_left_t = typename pack_split<Index, Ts...>::left;
336  template<std::size_t Index, typename... Ts>
337  using pack_get_t = typename pack_split<Index, Ts...>::head;
338  template<std::size_t Index, typename... Ts>
339  using pack_split_right_t = typename pack_split<Index, Ts...>::right;
340  template<std::size_t Index, typename... Ts>
341  using pack_split_before_t = typename pack_split<Index, Ts...>::before;
342  template<std::size_t Index, typename... Ts>
343  using pack_split_after_t = typename pack_split<Index, Ts...>::after;
344  template<typename... Ts>
345  using pack_head_t = pack_get_t<0, Ts...>;
346  template<typename... Ts>
347  using pack_tail_t = pack_split_after_t<0, Ts...>;
348 
349  template<std::size_t Index, typename Seq>
350  struct split;
351  template<std::size_t Index, template<typename...> class Seq, typename... Ts>
352  struct split<Index, Seq<Ts...>>
353  {
354  using splitter = detail::split<Seq<>, Index, Seq<Ts...>>;
355 
356  using before = typename splitter::before;
357  using left = typename splitter::left;
358  using head = typename splitter::head;
359  using right = typename splitter::right;
360  using after = typename splitter::after;
361  };
362  template<std::size_t Index, typename Seq>
363  using split_left_t = typename split<Index, Seq>::left;
364  template<std::size_t Index, typename Seq>
365  using get_t = typename split<Index, Seq>::head;
366  template<std::size_t Index, typename Seq>
367  using split_right_t = typename split<Index, Seq>::right;
368  template<std::size_t Index, typename Seq>
369  using split_before_t = typename split<Index, Seq>::before;
370  template<std::size_t Index, typename Seq>
371  using split_after_t = typename split<Index, Seq>::after;
372  template<typename Seq>
373  using head_t = get_t<0, Seq>;
374  template<typename Seq>
375  using tail_t = split_after_t<0, Seq>;
376 
377 
378  template<typename T, typename... Ts>
379  using pack_prepend_t = list<T, Ts...>;
380  template<typename T, typename... Ts>
381  using pack_append_t = list<Ts..., T>;
382  template<typename T, std::size_t Index, typename... Ts>
383  using pack_insert_t = cat_t<pack_append_t<pack_split_left_t<Index, Ts...>, T>, pack_split_right_t<Index, Ts...>>;
384  template<typename T, std::size_t Index, typename... Ts>
385  using pack_remove_t = cat_t<pack_split_before_t<Index, Ts...>, pack_split_after_t<Index, Ts...>>;
386 
387  template<typename T, typename Seq>
388  struct prepend;
389  template<typename T, template<typename...> class Seq, typename... Ts>
390  struct prepend<T, Seq<Ts...>>
391  {
392  using type = Seq<T, Ts...>;
393  };
394  template<typename T, typename Seq>
395  struct append;
396  template<typename T, template<typename...> class Seq, typename... Ts>
397  struct append<T, Seq<Ts...>>
398  {
399  using type = Seq<Ts..., T>;
400  };
401 
402  template<typename T, typename Seq>
403  using prepend_t = type_t<prepend<T, Seq>>;
404  template<typename T, typename Seq>
405  using append_t = type_t<append<Seq, T>>;
406  template<typename T, std::size_t Index, typename Seq>
407  using insert_t = cat_t<append_t<split_left_t<Index, Seq>, T>, split_right_t<Index, Seq>>;
408  template<typename T, std::size_t Index, typename Seq>
409  using remove_t = cat_t<split_before_t<Index, Seq>, split_after_t<Index, Seq>>;
410 
411  namespace detail
412  {
413  template<typename Result, typename Lhs, typename Rhs, typename Compare>
414  struct merge;
415 
416  template<template<typename...> class Sequence, typename... Ts, typename LhsHead, typename... LhsTail, typename RhsHead, typename... RhsTail, typename Compare>
417  struct merge<Sequence<Ts...>, Sequence<LhsHead, LhsTail...>, Sequence<RhsHead, RhsTail...>, Compare>
418  {
419  using next_result = std::conditional_t<
420  apply_t<Compare, LhsHead, RhsHead>::value,
421  Sequence<Ts..., LhsHead>,
422  Sequence<Ts..., RhsHead>
423  >;
424  using next_lhs = std::conditional_t<
425  apply_t<Compare, LhsHead, RhsHead>::value,
426  Sequence<LhsTail...>,
427  Sequence<LhsHead, LhsTail...>
428  >;
429  using next_rhs = std::conditional_t<
430  apply_t<Compare, LhsHead, RhsHead>::value,
431  Sequence<RhsHead, RhsTail...>,
432  Sequence<RhsTail...>
433  >;
434 
435  using type = type_t<
436  merge<
437  next_result,
438  next_lhs,
439  next_rhs,
440  Compare
441  >
442  >;
443  };
444 
445  template<template<typename...> class Sequence, typename... Ts, typename LhsHead, typename... LhsTail, typename Compare>
446  struct merge<Sequence<Ts...>, Sequence<LhsHead, LhsTail...>, Sequence<>, Compare>
447  {
448  using type = Sequence<Ts..., LhsHead, LhsTail...>;
449  };
450 
451  template<template<typename...> class Sequence, typename... Ts, typename RhsHead, typename... RhsTail, typename Compare>
452  struct merge<Sequence<Ts...>, Sequence<>, Sequence<RhsHead, RhsTail...>, Compare>
453  {
454  using type = Sequence<Ts..., RhsHead, RhsTail...>;
455  };
456 
457  template<template<typename...> class Sequence, typename... Ts, typename Compare>
458  struct merge<Sequence<Ts...>, Sequence<>, Sequence<>, Compare>
459  {
460  using type = Sequence<Ts...>;
461  };
462  }
463 
464  template<typename Lhs, typename Rhs, typename Compare = less>
465  using merge = detail::merge<functor_t<Lhs>, Lhs, Rhs, Compare>;
466 
467  template<typename Lhs, typename Rhs, typename Compare = less>
468  using merge_t = type_t<merge<Lhs, Rhs, Compare>>;
469 
470  namespace detail
471  {
472  namespace mergesort
473  {
474  template<typename List, typename Compare>
475  struct mergesort
476  {
477  using left = split_left_t< div_t<list_size<List>, int32_t<2>>::value, List>;
478  using right = split_after_t<div_t<list_size<List>, int32_t<2>>::value, List>;
479 
480  using left_sorted = type_t<mergesort<left, Compare>>;
481  using right_sorted = type_t<mergesort<right, Compare>>;
482 
483  using type = merge_t<left_sorted, right_sorted, Compare>;
484  };
485 
486  template<template<typename...> class Sequence, typename Compare>
487  struct mergesort<Sequence<>, Compare>
488  {
489  using type = Sequence<>;
490  };
491 
492  template<template<typename...> class Sequence, typename T, typename Compare>
493  struct mergesort<Sequence<T>, Compare>
494  {
495  using type = Sequence<T>;
496  };
497 
498  template<template<typename...> class Sequence, typename T, typename U, typename Compare>
499  struct mergesort<Sequence<T, U>, Compare>
500  {
501  template<typename First, typename Second, bool FirstWins = apply_t<Compare, First, Second>::value>
502  struct apply
503  {
504  using type = Sequence<First, Second>;
505  };
506 
507  template<typename First, typename Second>
508  struct apply<First, Second, false>
509  {
510  using type = Sequence<Second, First>;
511  };
512 
513  using type = type_t<apply<T, U>>;
514  };
515  }
516  }
517 
518  template<typename List, typename Compare = less>
520 
521  template<typename List, typename Compare = less>
522  using sort_t = type_t<sort<List, Compare>>;
523 
524  template<typename Key, typename Value>
525  struct pair
526  {
527  using key = Key;
528  using value = Value;
529  };
530 
531  template<typename Pair>
532  using key_t = typename Pair::key;
533  template<typename Pair>
534  using value_t = typename Pair::value;
535 
536  template<typename... Ts>
537  struct inherit : Ts... {};
538 
539  template<typename... Ts>
540  struct inherit<list<Ts...>> : Ts... {};
541 
542  namespace detail
543  {
544  template<typename Ts>
545  struct aggregate;
546 
547  template<template<typename...> class Seq, typename T, typename... Ts>
548  struct aggregate<Seq<T, Ts...>> : public
549  aggregate<Seq<Ts...>>
550  {
551  aggregate() = delete;
552  aggregate(const aggregate&) = delete;
553  aggregate(aggregate&&) = delete;
554  aggregate& operator=(const aggregate&) = delete;
555  aggregate& operator=(aggregate&&) = delete;
556 
557  T member;
558  };
559 
560  template<template<typename...> class Seq>
561  struct aggregate<Seq<>>
562  {
563  aggregate() = delete;
564  aggregate(const aggregate&) = delete;
565  aggregate(aggregate&&) = delete;
566  aggregate& operator=(const aggregate&) = delete;
567  aggregate& operator=(aggregate&&) = delete;
568  };
569  }
570 
571  template<typename... Ts>
573 
574  template<typename...>
575  struct map;
576 
577  template<typename... Keys, typename... Values>
578  struct map<pair<Keys, Values>...>
579  {
580  using keys = list<Keys...>;
581  using values = list<Values...>;
582  using pairs = list<pair<Keys, Values>...>;
583 
584  template<typename Key>
585  using at_key = type_t<decltype(lookup((inherit<pairs>*)nullptr))>;
586  private:
587  template<typename Key, typename Value>
589  };
590 
591  template<typename Map>
592  using keys_t = typename Map::keys;
593  template<typename Map>
594  using values_t = typename Map::values;
595  template<typename Map>
596  using pairs_t = typename Map::pairs;
597  template<typename Map, typename Key>
598  using at_key = typename Map::template at_key<Key>;
599 
600  template<typename Function, typename... Ts>
601  struct pack_fmap
602  {
603  using type = list<apply_t<Function, Ts>...>;
604  };
605 
606  template<typename Function, typename List>
607  struct fmap;
608 
609  template<typename Function, template<typename...> class Seq, typename... Ts>
610  struct fmap<Function, Seq<Ts...>>
611  {
612  using type = Seq<apply_t<Function, Ts>...>;
613  };
614 
615  namespace detail
616  {
617  template<typename Predicate, typename FilteredSeq, typename Seq>
618  struct filter;
619 
620  template<typename Predicate,
621  template<typename...> class Seq, typename... Filtered, typename Head, typename... Tail>
622  struct filter<Predicate, Seq<Filtered...>, Seq<Head, Tail...>>
623  {
624  template<typename _Head = Head, bool = value<apply_t<Predicate, _Head>>()>
625  struct next
626  {
627  using type = Seq<Filtered..., Head>;
628  };
629 
630  template<typename _Head>
631  struct next<_Head, false>
632  {
633  using type = Seq<Filtered...>;
634  };
635 
636  using type = type_t<filter<Predicate, type_t<next<>>, Seq<Tail...>>>;
637  };
638 
639  template<typename Predicate,
640  template<typename...> class Seq, typename... Filtered>
641  struct filter<Predicate, Seq<Filtered...>, Seq<>>
642  {
643  using type = Seq<Filtered...>;
644  };
645  }
646 
647  template<typename Function, typename Seed, typename Seq>
648  struct foldl;
649 
650  template<typename Function, typename Seed,
651  template<typename...> class Seq, typename Head, typename... Tail>
652  struct foldl<Function, Seed, Seq<Head, Tail...>>
653  {
654  using type = type_t<
655  foldl<Function,
656  apply_t<Function, Seed, Head>,
657  Seq<Tail...>
658  >
659  >;
660  };
661 
662  template<typename Function, typename Seed,
663  template<typename...> class Seq>
664  struct foldl<Function, Seed, Seq<>>
665  {
666  using type = Seed;
667  };
668 
669  template<typename Function, typename Seed, typename Seq>
670  struct foldr;
671 
672  template<typename Function, typename Seed,
673  template<typename...> class Seq, typename Head, typename... Tail>
674  struct foldr<Function, Seed, Seq<Head, Tail...>>
675  {
676  using type = apply_t<
677  Function, Head,
678  type_t<foldr<Function, Seed, Seq<Tail...>>>
679  >;
680  };
681 
682  template<typename Function, typename Seed,
683  template<typename...> class Seq>
684  struct foldr<Function, Seed, Seq<>>
685  {
686  using type = Seed;
687  };
688 
689  template<typename Function, typename... Ts>
690  using pack_fmap_t = type_t<pack_fmap<Function, Ts...>>;
691  template<typename Function, typename Seq>
692  using fmap_t = type_t<fmap<Function, Seq>>;
693 
694  template<typename Function, typename Seed, typename... Seq>
695  using pack_foldl = foldl<Function, Seed, list<Seq...>>;
696  template<typename Function, typename Seed, typename... Seq>
697  using pack_foldl_t = type_t<pack_foldl<Function, Seed, Seq...>>;
698  template<typename Function, typename Seed, typename Seq>
699  using foldl_t = type_t<foldl<Function, Seed, Seq>>;
700 
701  template<typename Function, typename Seed, typename... Seq>
702  using pack_foldr = foldr<Function, Seed, list<Seq...>>;
703  template<typename Function, typename Seed, typename... Seq>
704  using pack_foldr_t = type_t<pack_foldr<Function, Seed, Seq...>>;
705  template<typename Function, typename Seed, typename Seq>
706  using foldr_t = type_t<foldr<Function, Seed, Seq>>;
707 
708  template<typename Predicate, typename Seq>
710  template<typename Predicate, typename Seq>
711  using filter_t = type_t<filter<Predicate, Seq>>;
712  template<typename Predicate, typename... Seq>
714  template<typename Predicate, typename... Seq>
715  using pack_filter_t = type_t<pack_filter<Predicate, Seq...>>;
716 
717  template<typename Bs>
719  template<typename Bs>
720  using any_of_t = foldl_t<or_, false_, Bs>;
721  template<typename... Bs>
722  using pack_any_of = pack_foldl<or_, false_, Bs...>;
723  template<typename... Bs>
724  using pack_any_of_t = pack_foldl_t<or_, false_, Bs...>;
725 
726  template<typename Bs>
728  template<typename Bs>
729  using any_of_t = foldl_t<or_, false_, Bs>;
730  template<typename... Bs>
731  using pack_any_of = pack_foldl<or_, false_, Bs...>;
732  template<typename... Bs>
733  using pack_any_of_t = pack_foldl_t<or_, false_, Bs...>;
734 
735  template<typename... Seqs>
736  using join = foldl<defer<cat>, apply_functor<pack_get_t<0, Seqs...>>, apply_functor<pack_get_t<0, Seqs...>, Seqs...>>;
737  template<typename... Seqs>
738  using join_t = type_t<join<Seqs...>>;
739 
740  namespace detail
741  {
742  template<template<typename...> class Seq, std::size_t N>
744  {
745  static constexpr std::size_t n = (N % 2) ? ((N - 1) / 2) : (N / 2);
746  static constexpr std::size_t m = N - n;
747 
748  struct adder
749  {
750  template<typename T>
751  struct apply
752  {
753  using type = apply_t<add_, size_t<n>, T>;
754  };
755  };
756 
757  using type = cat_t<
758  type_t<make_index_sequence<Seq, n>>,
759  fmap_t<adder, type_t<make_index_sequence<Seq, m>>>
760  >;
761  };
762 
763  template<template<typename...> class Seq>
764  struct make_index_sequence<Seq, 1>
765  {
766  using type = Seq<size_t<0>>;
767  };
768 
769  template<template<typename...> class Seq>
770  struct make_index_sequence<Seq, 0>
771  {
772  using type = Seq<>;
773  };
774  }
775 
776  template<std::size_t N, template<typename...> class Seq = list>
777  using make_index_sequence = type_t<detail::make_index_sequence<Seq, N>>;
778  template<typename... Ts>
779  using make_index_sequence_for = make_index_sequence<sizeof...(Ts)>;
780  template<typename Seq>
782  template<template<typename...> class Seq, typename... Ts>
783  struct to_index_sequence<Seq<Ts...>>
784  {
785  using type = make_index_sequence<sizeof...(Ts), Seq>;
786  };
787  template<typename Seq>
788  using to_index_sequence_t = type_t<to_index_sequence<Seq>>;
789 }
790 
791 }
792 
793 #endif // SIPLASPLAS_UTILITY_META_H
Definition: meta.hpp:201
Definition: meta.hpp:670
Definition: membermatching.cpp:14
Definition: meta.hpp:31
Definition: meta.hpp:545
Definition: messaging.hpp:8
Definition: meta.hpp:152
Definition: meta.hpp:119
Definition: meta.hpp:225
Definition: meta.hpp:85
Definition: meta.hpp:161
Definition: meta.hpp:122
Definition: meta.hpp:781
Definition: meta.hpp:607
Definition: meta.hpp:350
Definition: meta.hpp:294
Definition: meta.hpp:618
Definition: test_util.hpp:13
Definition: meta.hpp:137
Definition: meta.hpp:525
Definition: meta.hpp:193
Definition: meta.hpp:388
Definition: meta.hpp:10
Definition: meta.hpp:16
Definition: meta.hpp:537
Definition: meta.hpp:101
Definition: meta.hpp:190
Definition: meta.hpp:179
Definition: meta.hpp:98
Definition: function.hpp:14
Definition: meta.hpp:182
Definition: meta.hpp:648
Definition: meta.hpp:270
Definition: meta.hpp:104
Definition: meta.hpp:215
Definition: meta.hpp:204
Definition: meta.hpp:43
Definition: meta.hpp:212
Definition: meta.hpp:242
Definition: meta.hpp:395
Definition: meta.hpp:601
Definition: meta.hpp:164
Definition: meta.hpp:149
Definition: meta.hpp:575
Definition: meta.hpp:414
Definition: meta.hpp:231
Definition: meta.hpp:134