1/*
2 * mpl_sequence.hpp
3 *
4 * Set of classes to create an mpl::vector with a filled sequence
5 *
6 * Created on: Aug 27, 2014
7 * Author: Pietro Incardona
8 */
9
10#ifndef MPL_SEQUENCE_HPP
11#define MPL_SEQUENCE_HPP
12
13#include <boost/mpl/int.hpp>
14#include <boost/mpl/reverse.hpp>
15
16template<int ...> struct index_tuple_sq{};
17
18/*! \brief Exit condition
19 *
20 * Exit condition, when c equal to end return true
21 *
22 * \param c actual position in the counter
23 * \param end end of the counter
24 *
25 */
26
27template<int c,int end>
28struct exit_impl_sq : boost::mpl::equal_to<boost::mpl::int_<c>,boost::mpl::int_<end>>
29{};
30
31/*! \brief Recursive specialization of to_variadic
32 *
33 * \param H suppose to be the vector where we are pushing numbers
34 * \param c suppose to be the counter
35 * \param L suppose to be the end of the cycle
36 * \param exit, when true it say to terminate the sequence
37 *
38 */
39template<int c , int end, bool exit,int ... vars>
40struct to_variadic_impl
41{
42 typedef typename exit_impl_sq<c,end>::type exit_;
43 typedef typename to_variadic_impl<c+1,end,exit_::value,vars ..., c>::type type;
44};
45
46
47//! Terminator of to_variadic
48template<int c, int end, int ... vars>
49struct to_variadic_impl<c,end,true, vars ...>
50{
51 typedef index_tuple_sq<vars ...> type;
52};
53
54/*!
55*
56* It create a mpl::vector sequence of integer from N to M
57*
58* usage:
59*
60* to_int_sequence<3,5>::type
61*
62* is mapped to
63*
64* index_tuple_sq<3,5,6>
65*
66*/
67
68template<unsigned int N, unsigned int M>
69struct to_int_sequence
70{
71 //! end condition
72 typedef typename exit_impl_sq<N,M>::type exit_;
73
74 //! generate the boost::fusion::vector apply H on each term
75 typedef typename to_variadic_impl<N+1,M,exit_::value,N>::type type;
76};
77
78
79//////////////////////////////////////////////////////////////////////////
80
81/*! \brief Recursive specialization of to_variadic
82 *
83 * \param H suppose to be the vector where we are pushing numbers
84 * \param c suppose to be the counter
85 * \param L suppose to be the end of the cycle
86 * \param exit, when true it say to terminate the sequence
87 *
88 */
89template<int c , int end, int ele, bool exit,int ... vars>
90struct to_variadic_const_impl
91{
92 typedef typename exit_impl_sq<c,end-1>::type exit_;
93 typedef typename to_variadic_const_impl<c+1,end,ele,exit_::value,vars ..., ele>::type type;
94};
95
96
97//! Terminator of to_variadic
98template<int c, int end, int ele, int ... vars>
99struct to_variadic_const_impl<c,end,ele,true, vars ...>
100{
101 typedef boost::mpl::vector<boost::mpl::int_<vars> ...> type;
102};
103
104/*!
105*
106* It create a mpl::vector sequence of integer with a constant A
107*
108* usage:
109*
110* vmpl_create_constant<3,5>::type
111*
112* is mapped to
113*
114* boost::mpl::vector<int_<5>,int_<5>,int<5>>
115*
116*/
117template<unsigned int N, unsigned int M>
118struct vmpl_create_constant
119{
120 //! end condition
121 typedef typename exit_impl_sq<N,M>::type exit_;
122
123 //! generate the boost::fusion::vector apply H on each term
124 typedef typename to_variadic_const_impl<1,N,M,exit_::value,M>::type type;
125};
126
127//////////////////
128
129template<typename bint, unsigned int ele>
130struct sum_ele
131{
132};
133
134template<int op1, unsigned int ele>
135struct sum_ele<boost::mpl::int_<op1>,ele>
136{
137 typedef boost::mpl::int_<op1+ele> type;
138};
139
140template<unsigned int ele>
141struct sum_ele<boost::mpl::na,ele>
142{
143 typedef boost::mpl::na type;
144};
145
146
147template <unsigned int ele, typename ... vmpl>
148struct vmpl_sum_constant_impl
149{
150 //! construct an mpl vector from the variadic
151 typedef boost::mpl::vector<typename sum_ele<vmpl,ele>::type ...> type;
152};
153
154template <unsigned int ele, typename vmpl>
155struct vmpl_sum_constant
156{
157 typedef int type;
158};
159/*!
160*
161* Take a boost::mpl::vector of boost::mpl::int_ and sum the element ele
162*
163* vmpl_sum_constant<boost::mpl::vector<boost::mpl::int_<2>,boost::mpl::int_<4>,boost::mpl::int<8>>, 5>::type is converted into
164*
165* boost::mpl::vector<int_<7>,int_<9>,int_<13>>
166*
167* \snippet variadic_to_vmpl_unit_test.hpp vmpl_sum_constant usage
168*
169*/
170template <unsigned int ele, typename ... vars>
171struct vmpl_sum_constant<ele, boost::mpl::vector<vars ... > >
172{
173 //! construct an mpl vector from the variadic
174 typedef boost::mpl::vector<typename sum_ele<vars,ele>::type ...> type;
175};
176
177
178
179////////////////////////////////////////////////////////////////////////
180
181template<int c, int accu, int stop, typename vmpl, bool exit>
182struct vmpl_reduce_prod_impl
183{
184 typedef typename exit_impl_sq<c,stop>::type exit_;
185 typedef typename boost::mpl::at<vmpl,boost::mpl::int_<c>>::type ele;
186 typedef typename vmpl_reduce_prod_impl<c+1,accu*ele::value,stop,vmpl,exit_::value>::type type;
187};
188
189
190//! Terminator of to_variadic
191template<int c, int accu, int stop, typename vmpl>
192struct vmpl_reduce_prod_impl<c,accu,stop,vmpl,true>
193{
194 typedef boost::mpl::int_<accu> type;
195};
196
197
198template<typename vmpl>
199struct vmpl_reduce_prod
200{
201 typedef typename vmpl_reduce_prod_impl<0,1,(int)vmpl::size::value-1,vmpl,false>::type type;
202};
203
204template<typename vmpl, int stop>
205struct vmpl_reduce_prod_stop
206{
207 typedef typename vmpl_reduce_prod_impl<0,1,stop,vmpl,false>::type type;
208};
209
210template<typename vmpl>
211struct vmpl_reduce_prod_stop<vmpl,-1>
212{
213 typedef typename boost::mpl::int_<1> type;
214};
215
216//! Linearize a set of index
217template<typename vmpl, typename a> __device__ __host__ inline unsigned int Lin_vmpl(a v)
218{
219 return v*vmpl_reduce_prod_stop<vmpl,((int)vmpl::size::value) - 2>::type::value;
220}
221
222/*! \brief linearize an arbitrary set of index
223 *
224 * linearize an arbitrary set of index
225 *
226 */
227template<typename vmpl, typename a, typename ...lT>
228__device__ __host__ inline unsigned int Lin_vmpl(a v,lT...t)
229{
230 return v*vmpl_reduce_prod_stop<vmpl,(int)vmpl::size::value - (int)sizeof...(t) - 2>::type::value + Lin_vmpl<vmpl>(t...);
231}
232
233//! Linearize a set of index
234template<typename vmpl, typename vmpl_off, typename a> __device__ __host__ inline unsigned int Lin_vmpl_off(a v)
235{
236 return (v + boost::mpl::at<vmpl_off,boost::mpl::int_< ((int)vmpl::size::value) - 1 > >::type::value )*vmpl_reduce_prod_stop<vmpl,(int)vmpl::size::value - 2>::type::value;
237}
238
239/*! \brief linearize an arbitrary set of index
240 *
241 * linearize an arbitrary set of index
242 *
243 */
244template<typename vmpl, typename vmpl_off, typename a, typename ...lT>
245__device__ __host__ inline unsigned int Lin_vmpl_off(a v,lT...t)
246{
247 return (v + boost::mpl::at<vmpl_off,boost::mpl::int_<((int)vmpl::size::value) - (int)sizeof...(t) - 1> >::type::value)*vmpl_reduce_prod_stop<vmpl,(int)((int)vmpl::size::value - sizeof...(t) - 2)>::type::value + Lin_vmpl_off<vmpl,vmpl_off>(t...);
248}
249
250#endif
251