1 | /* |
2 | * ct_array.hpp |
3 | * |
4 | * Created on: Aug 21, 2014 |
5 | * Author: Pietro Incardona |
6 | */ |
7 | |
8 | |
9 | |
10 | /*! \brief These set of classes generate an array definition at compile-time |
11 | * |
12 | * These set of classes generate an array definition at compile-time |
13 | * |
14 | * \see generate_array |
15 | * |
16 | */ |
17 | |
18 | #ifndef CT_ARRAY_HPP_ |
19 | #define CT_ARRAY_HPP_ |
20 | |
21 | |
22 | #include <boost/fusion/mpl.hpp> |
23 | |
24 | /////////////////////////////////////////////////// Make indexes /////////////////////// |
25 | |
26 | template<int ...> struct index_tuple{}; |
27 | |
28 | //! the array itself |
29 | template<class T, int... args> struct ArrayHolder_indexes { |
30 | //! convert variadic into a tuple struct containing the list |
31 | typedef index_tuple<args ... > type; |
32 | }; |
33 | |
34 | //! generate compile time index array |
35 | template<class T,long int N, size_t orig_N, template<size_t,size_t> class F, int... args> |
36 | struct generate_indexes_impl { |
37 | //! Metafunction to generate indexes |
38 | typedef typename generate_indexes_impl<T,N-1,orig_N, F, F<N,orig_N>::value, args...>::result result; |
39 | }; |
40 | |
41 | //! terminator of the variadic template |
42 | template<class T, size_t orig_N, template<size_t,size_t> class F, int... args> |
43 | struct generate_indexes_impl<T,0,orig_N, F, args...> { |
44 | //! generate the compile-time array |
45 | typedef typename ArrayHolder_indexes<T,F<0,orig_N>::value, args...>::type result; |
46 | }; |
47 | |
48 | //! In case of an empty list |
49 | template<class T, size_t orig_N, template<size_t,size_t> class F, int... args> |
50 | struct generate_indexes_impl<T,-1,orig_N, F, args...> { |
51 | //! empty array |
52 | typedef index_tuple<> result; |
53 | }; |
54 | |
55 | /*! \brief Main class to generate indexes data structure |
56 | * |
57 | * |
58 | * ### Meta-function definition |
59 | * \snippet util_test.hpp Metafunction definition |
60 | * ### Usage |
61 | * \snippet util_test.hpp indexes array |
62 | * |
63 | * \param T is the type of the output array |
64 | * \param N size of the sequence |
65 | * \param F Meta function it take two template arguments |
66 | * |
67 | */ |
68 | template<class T, long int N, template<size_t,size_t> class F> |
69 | struct generate_indexes { |
70 | //! generate compile time array |
71 | typedef typename generate_indexes_impl<T,N-1, N, F>::result result; |
72 | }; |
73 | |
74 | /////////////////////////////////////////////////// |
75 | |
76 | #ifndef COVERTY_SCAN |
77 | |
78 | //! the array itself |
79 | template<class T, unsigned long... args> struct ArrayHolder_constexpr { |
80 | //! compile-time array |
81 | constexpr static T data[sizeof...(args)] = { args... }; |
82 | }; |
83 | |
84 | |
85 | //! recursive meta-function to generate compile-time array |
86 | template<class T,size_t N, size_t orig_N, template<size_t,size_t> class F, unsigned... args> |
87 | struct generate_array_constexpr_impl { |
88 | //! recursive meta-function to generate compile-time array |
89 | typedef typename generate_array_constexpr_impl<T,N-1,orig_N, F, F<N,orig_N>::value, args...>::result result; |
90 | }; |
91 | |
92 | //! terminator of the variadic template |
93 | template<class T, size_t orig_N, template<size_t,size_t> class F, unsigned... args> |
94 | struct generate_array_constexpr_impl<T,0,orig_N, F, args...> { |
95 | //! Compile-time array |
96 | typedef ArrayHolder_constexpr<T,F<0,orig_N>::value, args...> result; |
97 | }; |
98 | |
99 | /*! \brief Main class to generate constexpr compile-time array |
100 | * |
101 | * |
102 | * A constexpr compile time array is for example |
103 | * |
104 | * \code{.cpp} |
105 | * constexpr size_t array[5] = {1,2,3,4,5} |
106 | * \endcode |
107 | * |
108 | * |
109 | * ### Metafunction definition |
110 | * \snippet util_test.hpp Metafunction definition |
111 | * ### Usage |
112 | * \snippet util_test.hpp constexpr array |
113 | * |
114 | * \param T is the type ot the output array |
115 | * \param N size of the sequence |
116 | * \param F Meta function it take two template arguments |
117 | * |
118 | */ |
119 | template<class T, size_t N, template<size_t,size_t> class F> |
120 | struct generate_array_constexpr { |
121 | //! meta-function to generate compile time array |
122 | typedef typename generate_array_constexpr_impl<T,N-1, N, F>::result result; |
123 | }; |
124 | |
125 | #endif |
126 | |
127 | ////////////////////////////////////////////////// |
128 | |
129 | //! the array itself |
130 | template<class T, unsigned long... args> struct ArrayHolder { |
131 | static const T data[sizeof...(args)]; |
132 | }; |
133 | |
134 | //! initialize the array from variadic template |
135 | template<class T, unsigned long... args> |
136 | const T ArrayHolder<T,args...>::data[sizeof...(args)] = { args... }; |
137 | |
138 | //! Generate the array specializing ArrayHolder |
139 | template<class T,size_t N, size_t orig_N, template<size_t,size_t> class F, unsigned... args> |
140 | struct generate_array_impl { |
141 | //! recursive meta-function to generate compile-time array |
142 | typedef typename generate_array_impl<T,N-1,orig_N, F, F<N,orig_N>::value, args...>::result result; |
143 | }; |
144 | |
145 | //! terminator of the variadic template |
146 | template<class T, size_t orig_N, template<size_t,size_t> class F, unsigned... args> |
147 | struct generate_array_impl<T,0,orig_N, F, args...> { |
148 | //! compile-time array |
149 | typedef ArrayHolder<T,F<0,orig_N>::value, args...> result; |
150 | }; |
151 | |
152 | /*! \brief Main class to generate compile-time array |
153 | * |
154 | * A compile time array is for example |
155 | * |
156 | * \code{.cpp} |
157 | * const size_t array[5] = {1,2,3,4,5} |
158 | * \endcode |
159 | * |
160 | * ### Metafunction definition |
161 | * \snippet util_test.hpp Metafunction definition |
162 | * ### Usage |
163 | * \snippet util_test.hpp compile time array |
164 | * |
165 | * \param T is the type ot the output array |
166 | * \param N size of the sequence |
167 | * \param F Meta function it take two template arguments |
168 | * |
169 | */ |
170 | template<class T, size_t N, template<size_t,size_t> class F> |
171 | struct generate_array { |
172 | typedef typename generate_array_impl<T,N-1, N, F>::result result; |
173 | }; |
174 | |
175 | /////////////// Classes to generate at compile time arrays from a boost::mpl::vector |
176 | |
177 | //! Generate the array specializing ArrayHolder |
178 | template<class T, size_t N ,class F, unsigned... args> |
179 | struct generate_array_vector_impl { |
180 | //! recursive meta-function to generate compile-time array |
181 | typedef typename generate_array_vector_impl<T,N-1,F, boost::mpl::at<F,boost::mpl::int_<N> >::type::value , args...>::result result; |
182 | }; |
183 | |
184 | //! terminator of the variadic template |
185 | template<class T, class F, unsigned... args> |
186 | struct generate_array_vector_impl<T,0, F, args...> { |
187 | //! compile-time array generation |
188 | typedef ArrayHolder<T,boost::mpl::at<F,boost::mpl::int_<0> >::type::value, args...> result; |
189 | }; |
190 | |
191 | /*! \brief Main class to generate an array from a boost::mpl::vector of numbers |
192 | * |
193 | * Main class to generate an array from a boost::mpl::vector of numbers |
194 | * |
195 | * Usage: |
196 | * |
197 | * boost::mpl::vector<int_<4>,int_<4>,......> v |
198 | * |
199 | * typdef generate_array_vector<size_t,v>::result B; |
200 | * |
201 | * B is an array or size_t of two element {4,4} |
202 | * |
203 | * \param T type of the output buffer |
204 | * \param F boost::mpl::vector |
205 | * |
206 | */ |
207 | template<class T, class F> |
208 | struct generate_array_vector { |
209 | //! generate compile-time array vector |
210 | typedef typename generate_array_vector_impl<T,boost::mpl::size<F>::value-1 , F>::result result; |
211 | }; |
212 | |
213 | #endif |
214 | |