1 // The Art of C++ / Sequences
2 // Copyright (c) 2015 Daniel Frey
3 
4 #ifndef TAOCPP_SEQUENCES_INCLUDE_MAKE_INTEGER_SEQUENCE_HPP
5 #define TAOCPP_SEQUENCES_INCLUDE_MAKE_INTEGER_SEQUENCE_HPP
6 
7 #include <cstddef>
8 #include <utility>
9 #include <type_traits>
10 
11 #include "config.hpp"
12 #include "integer_sequence.hpp"
13 
14 namespace tao
15 {
16   namespace seq
17   {
18 
19 #ifdef TAOCPP_USE_STD_MAKE_INTEGER_SEQUENCE
20 
21     using std::make_integer_sequence;
22     using std::make_index_sequence;
23     using std::index_sequence_for;
24 
25 #else
26 
27     // idea from http://stackoverflow.com/a/13073076
28 
29     namespace impl
30     {
31       template< typename, std::size_t, bool >
32       struct double_up;
33 
34       template< typename T, T... Ns, std::size_t N >
35       struct double_up< integer_sequence< T, Ns... >, N, false >
36       {
37         using type = integer_sequence< T, Ns..., ( N + Ns )... >;
38       };
39 
40       template< typename T, T... Ns, std::size_t N >
41       struct double_up< integer_sequence< T, Ns... >, N, true >
42       {
43         using type = integer_sequence< T, Ns..., ( N + Ns )..., 2 * N >;
44       };
45 
46       template< typename T, T N, typename = void >
47       struct generate;
48 
49       template< typename T, T N >
50       using generate_t = typename generate< T, N >::type;
51 
52       template< typename T, T N, typename >
53       struct generate
54         : double_up< generate_t< T, N / 2 >, N / 2, N % 2 == 1 >
55       {};
56 
57       template< typename T, T N >
58       struct generate< T, N, typename std::enable_if< ( N == 0 ) >::type >
59       {
60         using type = integer_sequence< T >;
61       };
62 
63       template< typename T, T N >
64       struct generate< T, N, typename std::enable_if< ( N == 1 ) >::type >
65       {
66         using type = integer_sequence< T, 0 >;
67       };
68     }
69 
70     template< typename T, T N >
71     using make_integer_sequence = impl::generate_t< T, N >;
72 
73     template< std::size_t N >
74     using make_index_sequence = make_integer_sequence< std::size_t, N >;
75 
76     template< typename... Ts >
77     using index_sequence_for = make_index_sequence< sizeof...( Ts ) >;
78 
79 #endif
80 
81   }
82 }
83 
84 #endif // TAOCPP_SEQUENCES_INCLUDE_MAKE_INTEGER_SEQUENCE_HPP
85