1 | /* |
2 | * aggregate.hpp |
3 | * |
4 | * Created on: Oct 31, 2015 |
5 | * Author: i-bird |
6 | */ |
7 | |
8 | #ifndef OPENFPM_DATA_SRC_UTIL_AGGREGATE_HPP_ |
9 | #define OPENFPM_DATA_SRC_UTIL_AGGREGATE_HPP_ |
10 | |
11 | #include <boost/fusion/container/vector.hpp> |
12 | #include <Packer_Unpacker/has_pack_agg.hpp> |
13 | #include "util/copy_compare/copy_compare_aggregates.hpp" |
14 | |
15 | /*! \brief this class is a functor for "for_each" algorithm |
16 | * |
17 | * It copy a boost::fusion::vector into another boost::fusion::vector |
18 | * |
19 | */ |
20 | template<typename bfv> |
21 | struct copy_fusion_vector |
22 | { |
23 | //! source fusion vector |
24 | const bfv & src; |
25 | |
26 | //! destination fusion vector |
27 | bfv & dst; |
28 | |
29 | /*! \brief constructor |
30 | * |
31 | * It define the copy parameters. |
32 | * |
33 | * \param src source fusion vector |
34 | * \param dst destination fusion vector |
35 | * |
36 | */ |
37 | __device__ __host__ inline copy_fusion_vector(const bfv & src, bfv & dst) |
38 | :src(src),dst(dst){}; |
39 | |
40 | #ifdef SE_CLASS1 |
41 | /*! \brief Constructor |
42 | * |
43 | * Calling this constructor produce an error. This class store the reference of the object, |
44 | * this mean that the object passed must not be a temporal object |
45 | * |
46 | */ |
47 | inline copy_fusion_vector(const bfv && src, bfv && dst) |
48 | :src(src),dst(dst) |
49 | {std::cerr << "Error: " <<__FILE__ << ":" << __LINE__ << " Passing a temporal object\n" ;}; |
50 | #endif |
51 | |
52 | //! It call the copy function for each property |
53 | template<typename T> |
54 | __device__ __host__ inline void operator()(T& t) |
55 | { |
56 | // This is the type of the object we have to copy |
57 | typedef typename boost::fusion::result_of::at_c<bfv,T::value>::type copy_type; |
58 | |
59 | // Remove the reference from the type to copy |
60 | typedef typename boost::remove_reference<copy_type>::type copy_rtype; |
61 | |
62 | meta_copy<copy_rtype>::meta_copy_(boost::fusion::at_c<T::value>(src),boost::fusion::at_c<T::value>(dst)); |
63 | } |
64 | }; |
65 | |
66 | #ifdef SE_CLASS3 |
67 | |
68 | #define SE3_MAX_PROP(i) i+2 |
69 | #define SE3_ADD_PROP(i) size_t[i+1],size_t |
70 | #define SE3_SUB_MAX_PROP -2 |
71 | |
72 | /*! \brief An aggregate that accept a boost fusion vector as type |
73 | * |
74 | * |
75 | * |
76 | */ |
77 | template<typename T> |
78 | struct aggregate_bfv |
79 | { |
80 | //! type the object store |
81 | typedef T type; |
82 | |
83 | //! real type the object store |
84 | typedef T type_real; |
85 | |
86 | //! data to store |
87 | type data; |
88 | |
89 | aggregate_bfv() {}; |
90 | |
91 | static const unsigned int max_prop = boost::mpl::size<type>::type::value; |
92 | static const unsigned int max_prop_real = boost::mpl::size<type>::type::value + SE3_SUB_MAX_PROP; |
93 | }; |
94 | |
95 | /*! \brief aggregate of properties, from a list of object if create a struct that follow the OPENFPM native structure |
96 | * |
97 | * see the Wiki for more information about the OPENFPM native structure format |
98 | * |
99 | * \tparam list of properties |
100 | * |
101 | */ |
102 | template<typename ... list> |
103 | struct aggregate |
104 | { |
105 | typedef boost::fusion::vector<list... , SE3_ADD_PROP(sizeof...(list))> type; |
106 | typedef boost::fusion::vector<list... > type_real; |
107 | |
108 | typedef int yes_is_aggregate; |
109 | |
110 | type data; |
111 | |
112 | __device__ __host__ inline aggregate() |
113 | {} |
114 | |
115 | __device__ __host__ inline aggregate(const aggregate<list ...> & aggr) |
116 | { |
117 | this->operator=(aggr); |
118 | } |
119 | |
120 | /*! \brief get the properties i |
121 | * |
122 | * \return the property i |
123 | * |
124 | */ |
125 | template<unsigned int i> typename boost::mpl::at<type,boost::mpl::int_<i>>::type & get() |
126 | { |
127 | return boost::fusion::at_c<i>(data); |
128 | } |
129 | |
130 | /*! \brief get the properties i |
131 | * |
132 | * \return the property i |
133 | * |
134 | */ |
135 | template<unsigned int i> const typename boost::mpl::at<type,boost::mpl::int_<i>>::type & get() const |
136 | { |
137 | return boost::fusion::at_c<i>(data); |
138 | } |
139 | |
140 | /*! \brief it return false if this aggregate has no pointers |
141 | * |
142 | * |
143 | */ |
144 | static bool noPointers() |
145 | { |
146 | return !has_pack_gen<aggregate<list ...>>::value; |
147 | } |
148 | |
149 | aggregate<list...> & operator=(const aggregate<list...> & ag) |
150 | { |
151 | copy_fusion_vector<aggregate<list...>::type> ca(ag.data,this->data); |
152 | |
153 | boost::mpl::for_each_ref< boost::mpl::range_c<int,0,sizeof...(list)> >(ca); |
154 | |
155 | return *this; |
156 | } |
157 | |
158 | static const unsigned int max_prop = boost::mpl::size<type>::type::value; |
159 | static const unsigned int max_prop_real = boost::mpl::size<type>::type::value + SE3_SUB_MAX_PROP; |
160 | }; |
161 | |
162 | |
163 | |
164 | #else |
165 | |
166 | /*! \brief An aggregate that accept a boost fusion vector as type |
167 | * |
168 | * |
169 | * |
170 | */ |
171 | template<typename T> |
172 | struct aggregate_bfv |
173 | { |
174 | //! type the object store |
175 | typedef T type; |
176 | |
177 | //! real type the object store |
178 | typedef T type_real; |
179 | |
180 | //! data to store |
181 | type data; |
182 | |
183 | /*! \brief get the properties i |
184 | * |
185 | * \return the property i |
186 | * |
187 | */ |
188 | template<unsigned int i> typename boost::mpl::at<type,boost::mpl::int_<i>>::type & get() |
189 | { |
190 | return boost::fusion::at_c<i>(data); |
191 | } |
192 | |
193 | /*! \brief get the properties i |
194 | * |
195 | * \return the property i |
196 | * |
197 | */ |
198 | template<unsigned int i> const typename boost::mpl::at<type,boost::mpl::int_<i>>::type & get() const |
199 | { |
200 | return boost::fusion::at_c<i>(data); |
201 | } |
202 | |
203 | static const unsigned int max_prop = boost::mpl::size<type>::type::value; |
204 | }; |
205 | |
206 | /*! \brief aggregate of properties, from a list of object if create a struct that follow the OPENFPM native structure |
207 | * |
208 | * see the Wiki for more information about the OPENFPM native structure format |
209 | * |
210 | * \tparam list of properties |
211 | * |
212 | */ |
213 | template<typename ... list> |
214 | struct aggregate |
215 | { |
216 | //! internal type containing the data |
217 | typedef boost::fusion::vector<list...> type; |
218 | |
219 | //! real internal type containing the data |
220 | typedef boost::fusion::vector<list...> type_real; |
221 | |
222 | typedef int yes_is_aggregate; |
223 | |
224 | //! the data |
225 | type data; |
226 | |
227 | __device__ __host__ inline aggregate() |
228 | {} |
229 | |
230 | __device__ __host__ inline aggregate(const aggregate<list ...> & aggr) |
231 | { |
232 | this->operator=(aggr); |
233 | } |
234 | |
235 | /*! \brief get the properties i |
236 | * |
237 | * \return the property i |
238 | * |
239 | */ |
240 | template<unsigned int i> __device__ __host__ typename boost::mpl::at<type,boost::mpl::int_<i>>::type & get() |
241 | { |
242 | return boost::fusion::at_c<i>(data); |
243 | } |
244 | |
245 | /*! \brief it return false if this aggregate has no pointers |
246 | * |
247 | * |
248 | */ |
249 | static bool noPointers() |
250 | { |
251 | return !has_pack_gen<aggregate<list ...>>::value; |
252 | } |
253 | |
254 | /*! \brief get the properties i |
255 | * |
256 | * \return the property i |
257 | * |
258 | */ |
259 | template<unsigned int i> __device__ __host__ const typename boost::mpl::at<type,boost::mpl::int_<i>>::type & get() const |
260 | { |
261 | return boost::fusion::at_c<i>(data); |
262 | } |
263 | |
264 | inline aggregate<list...> & operator=(const aggregate<list...> & ag) |
265 | { |
266 | copy_fusion_vector<aggregate<list...>::type> ca(ag.data,this->data); |
267 | |
268 | boost::mpl::for_each_ref< boost::mpl::range_c<int,0,sizeof...(list)> >(ca); |
269 | |
270 | return *this; |
271 | } |
272 | |
273 | static const unsigned int max_prop = boost::mpl::size<type>::type::value; |
274 | static const unsigned int max_prop_real = boost::mpl::size<type>::type::value; |
275 | }; |
276 | |
277 | #endif |
278 | |
279 | template<typename T, typename Sfinae = void> |
280 | struct is_aggregate: std::false_type {}; |
281 | |
282 | |
283 | /*! \brief Check if a type T is an aggregate |
284 | * |
285 | * return true if T is an aggregate |
286 | * |
287 | */ |
288 | template<typename T> |
289 | struct is_aggregate<T, typename Void< typename T::yes_is_aggregate>::type> : std::true_type |
290 | {}; |
291 | |
292 | namespace openfpm |
293 | { |
294 | template<unsigned int p, typename aggr> |
295 | auto at_c(aggr & agg) -> decltype(boost::fusion::at_c<p>(agg.data)) |
296 | { |
297 | return boost::fusion::at_c<p>(agg.data); |
298 | } |
299 | |
300 | template<unsigned int p, typename aggr> |
301 | auto get(aggr & agg) -> decltype(boost::fusion::at_c<p>(agg.data)) |
302 | { |
303 | return boost::fusion::at_c<p>(agg.data); |
304 | } |
305 | } |
306 | |
307 | #endif /* OPENFPM_DATA_SRC_UTIL_AGGREGATE_HPP_ */ |
308 | |