1/*
2 * Packer_util.hpp
3 *
4 * Created on: Jan 25, 2016
5 * Author: Yaroslav Zaluzhnyi
6 */
7
8#ifndef PACKER_UTIL_HPP_
9#define PACKER_UTIL_HPP_
10
11#include "prp_all_zero.hpp"
12#include "Packer_Unpacker/Pack_selector.hpp"
13#include "memory/HeapMemory.hpp"
14#include "Vector/map_vector_grow_p.hpp"
15#include "Vector/vect_isel.hpp"
16#include "memory_ly/memory_conf.hpp"
17#include "util/Pack_stat.hpp"
18
19template<typename T, typename Mem, int pack_type=Pack_selector<T>::value > class Packer;
20template<typename T, typename Mem, int pack_type=Pack_selector<T>::value > class Unpacker;
21
22#include "Vector/vector_def.hpp"
23
24///////////////////////////////////////////////////////////////////////////////////
25//////////////////////////////// FUNCTORS FOR ENCAP ////////////////////////////////
26////////////////////////////////////////////////////////////////////////////////////
27
28
29//A functor for call_aggregatePackRequest
30template<typename encap, typename Mem>
31struct call_packRequest_enc_functor
32{
33 //! encap object to pack (serialize)
34 encap & obj;
35
36 //! byte counter
37 size_t & req;
38
39 /* \brief Constructor
40 *
41 * \param obj object to pack/serialize
42 * \param req byte to pack/serialize
43 *
44 */
45 call_packRequest_enc_functor(encap & obj, size_t & req)
46 :obj(obj),req(req)
47 {}
48
49 //! It calls the pack request for each property
50 template<typename T>
51 inline void operator()(T& t)
52 {
53 typedef typename boost::mpl::at<typename encap::T_type,T>::type obj_type;
54
55 Packer<obj_type,Mem>::packRequest(obj.template get<T::value>(),req);
56 }
57};
58
59
60//Calls a pack request in nested way
61template<typename encap, typename Mem, int ... prp>
62struct call_encapPackRequest
63{
64 /*! \brief pack/serialize
65 *
66 * \param obj object to serialize
67 * \param req byte counter needed to pack/serialize the object
68 *
69 */
70 static inline void call_packRequest(encap & obj, size_t & req)
71 {
72 //Property sequence into boost::mpl::range_c or boost::mpl::vector, depending on sizeof...(prp)
73 typedef typename prp_all_zero<encap,sizeof...(prp) == 0,prp...>::type b_prp;
74
75 call_packRequest_enc_functor<encap,Mem> functor(obj,req);
76
77 //Apply functor for each property
78 boost::mpl::for_each_ref<b_prp>(functor);
79 }
80};
81
82//A functor for call_aggregatePack
83template<typename encap, typename Mem>
84struct call_pack_enc_functor
85{
86 //! Memory that pack/serialize the object
87 ExtPreAlloc<Mem> & mem;
88
89 //! Object to serialize
90 const encap & obj;
91
92 //! serialization status
93 Pack_stat & sts;
94
95 call_pack_enc_functor(ExtPreAlloc<Mem> & mem,const encap & obj, Pack_stat & sts)
96 :mem(mem), obj(obj), sts(sts)
97 {
98 }
99
100 //! It calls the packer for each property
101 template<typename T>
102 inline void operator()(T& t)
103 {
104 typedef typename boost::mpl::at<typename encap::type,T>::type obj_type;
105
106 Packer<obj_type,Mem>::pack(mem,obj.template get<T::value>(),sts);
107 }
108};
109
110//A functor for call_aggregatePack
111template<typename encap, typename Mem>
112struct call_pack_enc_functor_chunking
113{
114 //! Memory that pack/serialize the object
115 ExtPreAlloc<Mem> & mem;
116
117 //! Object to serialize
118 const encap & obj;
119
120 //! Element id
121 size_t sub_id;
122
123 //! serialization status
124 Pack_stat & sts;
125
126 call_pack_enc_functor_chunking(ExtPreAlloc<Mem> & mem,const encap & obj, size_t sub_id, Pack_stat & sts)
127 :mem(mem), obj(obj),sub_id(sub_id),sts(sts)
128 {
129 }
130
131 //! It calls the packer for each property
132 template<typename T>
133 inline void operator()(T& t)
134 {
135 typedef typename boost::mpl::at<typename encap::type,T>::type::value_type obj_type;
136
137 Packer<obj_type,Mem>::pack(mem,obj.template get<T::value>()[sub_id],sts);
138 }
139};
140
141//Calls a packer in nested way
142template<typename encap, typename Mem, int ... prp>
143struct call_encapPack
144{
145 static inline void call_pack(const encap & obj, ExtPreAlloc<Mem> & mem, Pack_stat & sts)
146 {
147 //Property sequence into boost::mpl::range_c or boost::mpl::vector, depending on sizeof...(prp)
148 typedef typename prp_all_zero<typename encap::T_type,sizeof...(prp) == 0,prp...>::type b_prp;
149
150 call_pack_enc_functor<encap,Mem> functor(mem,obj,sts);
151
152 //Apply functor for each property
153 boost::mpl::for_each_ref<b_prp>(functor);
154 }
155};
156
157//Calls a packer in nested way
158template<typename encap, typename Mem, int ... prp>
159struct call_encapPackChunking
160{
161 static inline void call_pack(const encap & obj, size_t sub_id, ExtPreAlloc<Mem> & mem, Pack_stat & sts)
162 {
163 //Property sequence into boost::mpl::range_c or boost::mpl::vector, depending on sizeof...(prp)
164 typedef typename prp_all_zero<typename encap::T_type,sizeof...(prp) == 0,prp...>::type b_prp;
165
166 call_pack_enc_functor_chunking<encap,Mem> functor(mem,obj,sub_id,sts);
167
168 //Apply functor for each property
169 boost::mpl::for_each_ref<b_prp>(functor);
170 }
171};
172
173//A functor for call_aggregateUnpack
174template<typename encap, typename Mem, int ... prp>
175struct call_unpack_encap_functor
176{
177 ExtPreAlloc<Mem> & mem;
178 const encap & obj;
179 Unpack_stat & ps;
180
181 call_unpack_encap_functor(ExtPreAlloc<Mem> & mem, const encap & obj, Unpack_stat & ps)
182 :mem(mem), obj(obj), ps(ps)
183 {
184 }
185
186 //! It calls the unpacker for each property
187 template<typename T>
188 inline void operator()(T& t)
189 {
190 typedef typename boost::mpl::at<typename encap::type,T>::type obj_type;
191
192 Unpacker<obj_type,Mem>::unpack(mem,obj.template get<T::value>(),ps);
193 }
194};
195
196//A functor for call_aggregateUnpack
197template<typename encap, typename Mem, int ... prp>
198struct call_unpack_encap_functor_chunking
199{
200 ExtPreAlloc<Mem> & mem;
201 const encap & obj;
202 Unpack_stat & ps;
203
204 size_t sub_id;
205
206 call_unpack_encap_functor_chunking(ExtPreAlloc<Mem> & mem, const encap & obj, size_t sub_id, Unpack_stat & ps)
207 :mem(mem), obj(obj), ps(ps),sub_id(sub_id)
208 {
209 }
210
211 //! It calls the unpacker for each property
212 template<typename T>
213 inline void operator()(T& t)
214 {
215 typedef typename boost::mpl::at<typename encap::type,T>::type::value_type obj_type;
216
217 Unpacker<obj_type,Mem>::unpack(mem,obj.template get<T::value>()[sub_id],ps);
218 }
219};
220
221//Calls an unpacker in nested way
222template<typename encap, typename Mem, int ... prp>
223struct call_encapUnpack
224{
225 static inline void call_unpack(encap & obj, ExtPreAlloc<Mem> & mem, Unpack_stat & ps)
226 {
227 //Property sequence into boost::mpl::range_c or boost::mpl::vector, depending on sizeof...(prp)
228 typedef typename prp_all_zero<encap,sizeof...(prp) == 0,prp...>::type b_prp;
229
230 call_unpack_encap_functor_chunking<encap,Mem,prp ... > functor(mem,obj,ps);
231
232 //Apply functor for each property
233 boost::mpl::for_each_ref<b_prp>(functor);
234 }
235};
236
237//Calls an unpacker in nested way
238template<typename encap, typename Mem, int ... prp>
239struct call_encapUnpackChunking
240{
241 static inline void call_unpack(encap & obj, size_t sub_id, ExtPreAlloc<Mem> & mem, Unpack_stat & ps)
242 {
243 //Property sequence into boost::mpl::range_c or boost::mpl::vector, depending on sizeof...(prp)
244 typedef typename prp_all_zero<encap,sizeof...(prp) == 0,prp...>::type b_prp;
245
246 call_unpack_encap_functor_chunking<encap,Mem,prp ... > functor(mem,obj,sub_id,ps);
247
248 //Apply functor for each property
249 boost::mpl::for_each_ref<b_prp>(functor);
250 }
251};
252
253
254////////////////////////////////////////////////////////////////////////////////////
255/////////////////////////////// FUNCTORS FOR AGGREGATE ////////////////////////////
256////////////////////////////////////////////////////////////////////////////////////
257
258
259template<bool inte_layout, typename obj_type, typename Mem>
260struct pack_request_op
261{
262 template<unsigned int p> static inline void call_pack_req(const obj_type & obj,size_t & req)
263 {
264 typedef typename boost::mpl::at<typename obj_type::type,boost::mpl::int_<p>>::type obj_t;
265
266 Packer<obj_t,Mem>::packRequest(obj.template get<p>(),req);
267 }
268};
269
270template<typename obj_type, typename Mem>
271struct pack_request_op<true,obj_type,Mem>
272{
273 template<unsigned int p> static inline void call_pack_req(const obj_type & obj,size_t & req)
274 {
275 typedef typename boost::mpl::at<typename obj_type::type,boost::mpl::int_<p>>::type obj_t;
276
277 Packer<obj_t,Mem>::packRequest(obj.template get<p>(),req);
278 }
279};
280
281template<typename> struct Debug;
282
283//A functor for call_aggregatePackRequest
284
285template<typename obj_type, typename Mem>
286struct call_packRequest_agg_functor
287{
288 //! object to pack
289 const obj_type & obj;
290
291 //! offset of the packed memory
292 size_t & req;
293
294 call_packRequest_agg_functor(const obj_type & obj, size_t & req)
295 :obj(obj),req(req)
296 {}
297
298 //! It calls the pack request for each property
299 template<typename T>
300 inline void operator()(T& t)
301 {
302 pack_request_op<openfpm::is_multi_array<decltype(obj.template get<T::value>())>::value,obj_type,Mem>::template call_pack_req<T::value>(obj,req);
303 }
304};
305
306template<typename obj_type, typename Mem>
307struct call_packRequest_agg_functor_cnk
308{
309 //! object to pack
310 const obj_type & obj;
311
312 //! offset of the packed memory
313 size_t & req;
314
315 //! element id
316 size_t sub_id;
317
318 call_packRequest_agg_functor_cnk(const obj_type & obj, size_t sub_id ,size_t & req)
319 :obj(obj),req(req),sub_id(sub_id)
320 {}
321
322 //! It calls the pack request for each property
323 template<typename T>
324 inline void operator()(T& t)
325 {
326 typedef decltype(obj.template get<T::value>()[sub_id]) obj_t;
327
328 //for (size_t i = 0; i < obj_type::max_prop ; i++)
329 Packer<obj_t,Mem>::packRequest(obj.template get<T::value>()[sub_id],req);
330 }
331};
332
333//Calls a pack request in nested way
334template<typename obj_type, typename Mem, int ... prp>
335struct call_aggregatePackRequest
336{
337 /*! \brief Pack the object
338 *
339 * \param obj object to pack
340 * \param req offset of the packed memory
341 *
342 */
343 static inline void call_packRequest(const obj_type & obj, size_t & req)
344 {
345 //Property sequence into boost::mpl::range_c or boost::mpl::vector, depending on sizeof...(prp)
346 typedef typename prp_all_zero<obj_type,sizeof...(prp) == 0,prp...>::type b_prp;
347
348 call_packRequest_agg_functor<obj_type,Mem> functor(obj,req);
349
350 //Apply functor for each property
351 boost::mpl::for_each_ref<b_prp>(functor);
352 }
353};
354
355template<bool inte_layout, typename obj_type, typename Mem>
356struct pack_pack_op
357{
358 template<unsigned int p> static inline void call_pack_pack(ExtPreAlloc<Mem> & mem, const obj_type & obj,Pack_stat & sts)
359 {
360 typedef typename boost::mpl::at<typename obj_type::type,boost::mpl::int_<p>>::type obj_t;
361
362 Packer<obj_t,Mem>::pack(mem,obj.template get<p>(),sts);
363 }
364};
365
366//Calls a pack request in nested way
367template<typename obj_type, typename Mem, int ... prp>
368struct call_aggregatePackRequestChunking
369{
370 /*! \brief Pack the object
371 *
372 * \param obj object to pack
373 * \param req offset of the packed memory
374 *
375 */
376 static inline void call_packRequest(const obj_type & obj, size_t sub_id, size_t & req)
377 {
378 //Property sequence into boost::mpl::range_c or boost::mpl::vector, depending on sizeof...(prp)
379 typedef typename prp_all_zero<obj_type,sizeof...(prp) == 0,prp...>::type b_prp;
380
381 call_packRequest_agg_functor_cnk<obj_type,Mem> functor(obj,sub_id,req);
382
383 //Apply functor for each property
384 boost::mpl::for_each_ref<b_prp>(functor);
385 }
386};
387
388//A functor for call_aggregatePack
389template<typename obj_type, typename Mem>
390struct call_pack_agg_functor
391{
392 ExtPreAlloc<Mem> & mem;
393 const obj_type & obj;
394 Pack_stat & sts;
395
396 call_pack_agg_functor(ExtPreAlloc<Mem> & mem, const obj_type & obj, Pack_stat & sts)
397 :mem(mem), obj(obj), sts(sts)
398 {
399 }
400
401 //! It calls the packer for each property
402 template<typename T>
403 inline void operator()(T& t)
404 {
405// typedef typename boost::mpl::at<typename obj_type::type,T>::type obj_t;
406
407 pack_pack_op<openfpm::is_multi_array<decltype(obj.template get<T::value>())>::value,obj_type,Mem>::template call_pack_pack<T::value>(mem,obj,sts);
408
409// Packer<obj_t,Mem>::pack(mem,obj.template get<T::value>(),sts);
410 }
411};
412
413//! Calls a packer in nested way
414template<typename obj_type, typename Mem, int ... prp>
415struct call_aggregatePack
416{
417 /*! \brief Call the packer
418 *
419 * \param obj object to pack
420 * \param mem memory where to pack
421 * \param sts information about the packing
422 *
423 */
424 static inline void call_pack(const obj_type & obj, ExtPreAlloc<Mem> & mem, Pack_stat & sts)
425 {
426 //Property sequence into boost::mpl::range_c or boost::mpl::vector, depending on sizeof...(prp)
427 typedef typename prp_all_zero<obj_type,sizeof...(prp) == 0,prp...>::type b_prp;
428
429 call_pack_agg_functor<obj_type,Mem> functor(mem,obj,sts);
430
431 //Apply functor for each property
432 boost::mpl::for_each_ref<b_prp>(functor);
433 }
434};
435
436
437//A functor for call_aggregateUnpack
438template<typename obj_type, typename Mem>
439struct call_unpack_agg_functor
440{
441 //! Memory where to pack
442 ExtPreAlloc<Mem> & mem;
443
444 //! object to pack
445 obj_type & obj;
446
447 //! statistic about packing
448 Unpack_stat & ps;
449
450 /*! \brief constructor
451 *
452 * \param mem memory where to pack
453 * \param obj object to pack
454 * \param ps packing statistic
455 *
456 */
457 call_unpack_agg_functor(ExtPreAlloc<Mem> & mem, obj_type & obj, Unpack_stat & ps)
458 :mem(mem), obj(obj), ps(ps)
459 {
460 }
461
462 //! It calls the unpacker for each property
463 template<typename T>
464 inline void operator()(T& t)
465 {
466 typedef typename boost::mpl::at<typename obj_type::type,T>::type obj_t;
467
468 Unpacker<obj_t,Mem>::unpack(mem,obj.template get<T::value>(),ps);
469 }
470};
471
472//! Calls an unpacker in nested way
473template<typename obj_type, typename Mem, int ... prp>
474struct call_aggregateUnpack
475{
476 /*! \brief constructor
477 *
478 * \param mem memory from where to unpack
479 * \param obj object to pack
480 * \param ps packing statistic
481 *
482 */
483 static inline void call_unpack(obj_type && obj, ExtPreAlloc<Mem> & mem, Unpack_stat & ps)
484 {
485 //Property sequence into boost::mpl::range_c or boost::mpl::vector, depending on sizeof...(prp)
486 typedef typename prp_all_zero<obj_type,sizeof...(prp) == 0,prp...>::type b_prp;
487
488 call_unpack_agg_functor<obj_type,Mem> functor(mem,obj,ps);
489
490 //Apply functor for each property
491 boost::mpl::for_each_ref<b_prp>(functor);
492 }
493};
494
495#endif /* PACKER_UTIL_HPP_ */
496