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
26template<int ...> struct index_tuple{};
27
28//! the array itself
29template<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
35template<class T,long int N, size_t orig_N, template<size_t,size_t> class F, int... args>
36struct 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
42template<class T, size_t orig_N, template<size_t,size_t> class F, int... args>
43struct 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
49template<class T, size_t orig_N, template<size_t,size_t> class F, int... args>
50struct 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 */
68template<class T, long int N, template<size_t,size_t> class F>
69struct 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
79template<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
86template<class T,size_t N, size_t orig_N, template<size_t,size_t> class F, unsigned... args>
87struct 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
93template<class T, size_t orig_N, template<size_t,size_t> class F, unsigned... args>
94struct 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 */
119template<class T, size_t N, template<size_t,size_t> class F>
120struct 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
130template<class T, unsigned long... args> struct ArrayHolder {
131 static const T data[sizeof...(args)];
132};
133
134//! initialize the array from variadic template
135template<class T, unsigned long... args>
136const T ArrayHolder<T,args...>::data[sizeof...(args)] = { args... };
137
138//! Generate the array specializing ArrayHolder
139template<class T,size_t N, size_t orig_N, template<size_t,size_t> class F, unsigned... args>
140struct 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
146template<class T, size_t orig_N, template<size_t,size_t> class F, unsigned... args>
147struct 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 */
170template<class T, size_t N, template<size_t,size_t> class F>
171struct 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
178template<class T, size_t N ,class F, unsigned... args>
179struct 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
185template<class T, class F, unsigned... args>
186struct 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 */
207template<class T, class F>
208struct 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