1/*
2 * object_write.hpp
3 *
4 * Created on: Jun 11, 2015
5 * Author: i-bird
6 */
7
8#ifndef OBJECT_WRITE_HPP_
9#define OBJECT_WRITE_HPP_
10
11
12#include "for_each_ref.hpp"
13#include "util/variadic_to_vmpl.hpp"
14#include "util/copy_compare/meta_copy.hpp"
15#include <boost/mpl/range_c.hpp>
16#include <boost/fusion/include/size.hpp>
17
18template <typename> struct Debug;
19
20/*! \brief this class is a functor for "for_each" algorithm
21 *
22 * This class is a functor for "for_each" algorithm. For each
23 * element of the boost::vector the operator() is called.
24 * Is mainly used to copy the selected properties
25 *
26 * \tparam v_src source object
27 * \tparam d_src destination object
28 * \tparam prp properties
29 *
30 */
31
32template<typename v_src,typename v_dst, int... prp>
33struct object_s_di_e_cnk
34{
35 //! Convert the packed properties into an MPL vector
36 typedef typename to_boost_vmpl<prp...>::type v_prp;
37
38 //! Source object
39 const v_src & src;
40
41 //! Destination object
42 v_dst & dst;
43
44 //! element id
45 size_t sub_id;
46
47 /*! \brief Constructor
48 *
49 * \param src source object
50 * \param dst destination object
51 *
52 */
53 object_s_di_e_cnk(const v_src & src, v_dst & dst,size_t sub_id)
54 :src(src),dst(dst),sub_id(sub_id)
55 {
56 };
57
58 //! It call the functor for each member
59 template<typename T>
60 void operator()(T& t)
61 {
62 // Remove the reference from the type to copy
63 typedef typename boost::remove_reference<decltype(dst.template get<boost::mpl::at<v_prp,boost::mpl::int_<T::value>>::type::value>())>::type::value_type copy_rtype;
64
65 meta_copy<copy_rtype>::meta_copy_(src.template get<T::value>(),dst.template get<boost::mpl::at<v_prp,boost::mpl::int_<T::value>>::type::value>()[sub_id]);
66 }
67};
68
69
70/*! \brief this class is a functor for "for_each" algorithm
71 *
72 * This class is a functor for "for_each" algorithm. For each
73 * element of the boost::vector the operator() is called.
74 * Is mainly used to copy the selected properties
75 *
76 * \tparam v_src source object
77 * \tparam d_src destination object
78 * \tparam prp properties
79 *
80 */
81
82template<typename v_src,typename v_dst, int... prp>
83struct object_s_di_e
84{
85 //! Convert the packed properties into an MPL vector
86 typedef typename to_boost_vmpl<prp...>::type v_prp;
87
88 //! Source object
89 const v_src & src;
90
91 //! Destination object
92 v_dst & dst;
93
94 /*! \brief Constructor
95 *
96 * \param src source object
97 * \param dst destination object
98 *
99 */
100 __device__ __host__ object_s_di_e(const v_src & src, v_dst & dst)
101 :src(src),dst(dst)
102 {
103 };
104
105#ifdef SE_CLASS1
106 /*! \brief Constructor
107 *
108 * Calling this constructor produce an error. This class store the reference of the object,
109 * this mean that the object passed must not be a temporal object
110 *
111 */
112 object_s_di_e(const v_src && src, v_dst & dst)
113 :src(src),dst(dst)
114 {std::cerr << "Error: " <<__FILE__ << ":" << __LINE__ << " Passing a temporal object\n";};
115#endif
116
117 //! It call the functor for each member
118 template<typename T>
119 __device__ __host__ void operator()(T& t)
120 {
121 // Remove the reference from the type to copy
122 typedef typename boost::remove_reference<decltype(dst.template get<boost::mpl::at<v_prp,boost::mpl::int_<T::value>>::type::value>())>::type copy_dtype;
123 typedef typename std::remove_reference<decltype(src.template get<T::value>())>::type copy_stype;
124
125 meta_copy_d<copy_stype,copy_dtype>::meta_copy_d_(src.template get<T::value>(),dst.template get<boost::mpl::at<v_prp,boost::mpl::int_<T::value>>::type::value>());
126 }
127};
128
129
130/*! \brief this class is a functor for "for_each" algorithm
131 *
132 * This class is a functor for "for_each" algorithm. For each
133 * element of the boost::vector the operator() is called.
134 * Is mainly used to copy the selected properties applying an operation
135 *
136 * \tparam op operation
137 * \tparam v_src source object
138 * \tparam d_src destination object
139 * \tparam prp properties
140 *
141 */
142
143template<template<typename,typename> class op, typename v_src,typename v_dst, int... prp>
144struct object_s_di_e_op
145{
146 //! Convert the packed properties into an MPL vector
147 typedef typename to_boost_vmpl<prp...>::type v_prp;
148
149 //! Source object
150 const v_src & src;
151
152 //! Destination object
153 v_dst & dst;
154
155 /*! \brief Constructor
156 *
157 * \param src source object
158 * \param dst destination object
159 *
160 */
161 __device__ __host__ object_s_di_e_op(const v_src & src, v_dst & dst)
162 :src(src),dst(dst)
163 {
164 };
165
166#ifdef SE_CLASS1
167 /*! \brief Constructor
168 *
169 * Calling this constructor produce an error. This class store the reference of the object,
170 * this mean that the object passed must not be a temporal object
171 *
172 */
173 object_s_di_e_op(v_src && src, v_dst & dst)
174 :src(src),dst(dst)
175 {std::cerr << "Error: " <<__FILE__ << ":" << __LINE__ << " Passing a temporal object\n";};
176#endif
177
178 //! It call the functor for each member
179 template<typename T>
180 __device__ __host__ void operator()(T& t)
181 {
182 // Remove the reference from the type to copy
183 typedef typename boost::remove_reference<decltype(dst.template get<boost::mpl::at<v_prp,boost::mpl::int_<T::value>>::type::value>())>::type copy_dtype;
184 typedef typename std::remove_reference<decltype(src.template get<T::value>())>::type copy_stype;
185
186 meta_copy_op_d<op,copy_stype,copy_dtype>::meta_copy_op_d_(src.template get<T::value>(),dst.template get<boost::mpl::at<v_prp,boost::mpl::int_<T::value>>::type::value>());
187 }
188};
189
190/*! \brief this class is a functor for "for_each" algorithm
191 *
192 * This class is a functor for "for_each" algorithm. For each
193 * element of the boost::vector the operator() is called.
194 * Is mainly used to copy the selected properties applying an operation
195 *
196 * \tparam op operation
197 * \tparam v_src source object
198 * \tparam d_src destination object
199 * \tparam prp properties
200 *
201 */
202
203template<template<typename,typename> class op, typename v_src,typename v_dst, int... prp>
204struct object_s_di_e_op_cnk
205{
206 //! Convert the packed properties into an MPL vector
207 typedef typename to_boost_vmpl<prp...>::type v_prp;
208
209 //! Source object
210 const v_src & src;
211
212 //! Destination object
213 v_dst & dst;
214
215 //! element id
216 size_t sub_id;
217
218 /*! \brief Constructor
219 *
220 * \param src source object
221 * \param dst destination object
222 *
223 */
224 object_s_di_e_op_cnk(const v_src & src, v_dst & dst,size_t sub_id)
225 :src(src),dst(dst),sub_id(sub_id)
226 {
227 };
228
229#ifdef SE_CLASS1
230 /*! \brief Constructor
231 *
232 * Calling this constructor produce an error. This class store the reference of the object,
233 * this mean that the object passed must not be a temporal object
234 *
235 */
236 object_s_di_e_op_cnk(v_src && src, v_dst & dst, size_t sub_id)
237 :src(src),dst(dst),sub_id(sub_id)
238 {std::cerr << "Error: " <<__FILE__ << ":" << __LINE__ << " Passing a temporal object\n";};
239#endif
240
241 //! It call the functor for each member
242 template<typename T>
243 void operator()(T& t)
244 {
245 // Remove the reference from the type to copy
246 typedef typename boost::remove_reference<decltype(dst.template get<boost::mpl::at<v_prp,boost::mpl::int_<T::value>>::type::value>()[sub_id])>::type copy_rtype;
247
248 meta_copy_op<op,copy_rtype>::meta_copy_op_(src.template get<T::value>(),dst.template get<boost::mpl::at<v_prp,boost::mpl::int_<T::value>>::type::value>()[sub_id]);
249 }
250};
251
252/*! \brief this class is a functor for "for_each" algorithm
253 *
254 * This class is a functor for "for_each" algorithm. For each
255 * element of the boost::vector the operator() is called.
256 * Is mainly used to copy the selected properties
257 *
258 * \tparam v_src source object
259 * \tparam d_src destination object
260 *
261 */
262
263template<typename v_src,typename v_dst, int... prp>
264struct object_s_di_f
265{
266 //! Convert the packed properties into an MPL vector
267 typedef typename to_boost_vmpl<prp...>::type v_prp;
268
269 //! Source object
270 const v_src & src;
271
272 //! Destination object
273 v_dst & dst;
274
275 /*! \brief Constructor
276 *
277 * \param src source object
278 * \param dst destination object
279 *
280 */
281 object_s_di_f(const v_src & src, v_dst & dst)
282 :src(src),dst(dst)
283 {
284 };
285
286#ifdef DEBUG
287 /*! \brief Constructor
288 *
289 * Calling this constructor produce an error. This class store the reference of the object,
290 * this mean that the object passed must not be a temporal object
291 *
292 */
293 object_s_di_f(const v_src && src, v_dst & dst)
294 :src(src),dst(dst)
295 {std::cerr << "Error: " <<__FILE__ << ":" << __LINE__ << " Passing a temporal object\n";};
296#endif
297
298 //! It call the functor for each member
299 template<typename T>
300 void operator()(T& t)
301 {
302 typedef typename boost::mpl::at<typename v_dst::type,typename boost::mpl::int_<boost::mpl::at<v_prp,boost::mpl::int_<T::value>>::type::value>>::type ctype;
303
304 meta_copy<ctype>::meta_copy_(boost::fusion::at_c<T::value>(src.data),boost::fusion::at_c<boost::mpl::at<v_prp,boost::mpl::int_<T::value>>::type::value>(dst.data));
305 }
306};
307
308
309/*! \brief this class is a functor for "for_each" algorithm
310 *
311 * This class is a functor for "for_each" algorithm. For each
312 * element of the boost::vector the operator() is called.
313 * Is mainly used to copy the selected properties
314 *
315 * \tparam op operation to apply
316 * \tparam v_src source object
317 * \tparam d_src destination object
318 *
319 */
320
321template<template<typename,typename> class op, typename v_src,typename v_dst, int... prp>
322struct object_s_di_f_op
323{
324 //! Convert the packed properties into an MPL vector
325 typedef typename to_boost_vmpl<prp...>::type v_prp;
326
327 //! Source object
328 const v_src & src;
329
330 //! Destination object
331 v_dst & dst;
332
333 /*! \brief Constructor
334 *
335 * \param src source object
336 * \param dst destination object
337 *
338 */
339 object_s_di_f_op(const v_src & src, v_dst & dst)
340 :src(src),dst(dst)
341 {
342 };
343
344#ifdef DEBUG
345 /*! \brief Constructor
346 *
347 * Calling this constructor produce an error. This class store the reference of the object,
348 * this mean that the object passed must not be a temporal object
349 *
350 */
351 object_s_di_f_op(v_src && src, v_dst & dst)
352 :src(src),dst(dst)
353 {std::cerr << "Error: " <<__FILE__ << ":" << __LINE__ << " Passing a temporal object\n";};
354#endif
355
356 //! It call the functor for each member
357 template<typename T>
358 void operator()(T& t)
359 {
360 typedef typename boost::mpl::at<typename v_dst::type,typename boost::mpl::int_<boost::mpl::at<v_prp,boost::mpl::int_<T::value>>::type::value>>::type ctype;
361
362 meta_copy_op<op,ctype>::meta_copy_op_(boost::fusion::at_c<T::value>(src.data),boost::fusion::at_c<boost::mpl::at<v_prp,boost::mpl::int_<T::value>>::type::value>(dst.data));
363 }
364};
365
366#define OBJ_ENCAP 1
367#define OBJ_NORMAL 2
368#define OBJ_ENCAP_CHUNKING 3
369
370/*! \brief It copy the properties from one object to another
371 *
372 * Stub object
373 *
374 * \see object_s_di<v_src,v_dst,OBJ_ENCAP,prp...> object_copy<v_src,v_dst,OBJ_ENCAP,prp...>
375 *
376 *
377 */
378template<typename v_src, typename v_dst,int type_copy, int... prp>
379struct object_s_di
380{
381 /*! \brief Stub method
382 *
383 * \param vs source object
384 * \param vd destination object
385 *
386 */
387 inline object_s_di(const v_src & vs, v_dst & vd)
388 {
389 std::cerr << "Error object_copy: " << __FILE__ << " " << __LINE__ << "\n";
390 };
391};
392
393/*! \brief Given a set of properties for the destination (0,1,3,5) it copy the source properties (0,1,2,3)
394 *
395 *
396 * ### Object copy example
397 * \snippet util_test.hpp object copy example
398 *
399 */
400template<typename v_src, typename v_dst, int... prp>
401struct object_s_di<v_src,v_dst,OBJ_NORMAL,prp...>
402{
403 /*! \brief Implementation of the copy
404 *
405 * \param vs source object
406 * \param vd destination object
407 *
408 */
409 inline object_s_di(const v_src && vs, v_dst && vd)
410 {
411 object_s_di_f<v_src,v_dst,prp...> obj(vs,vd);
412 boost::mpl::for_each_ref< boost::mpl::range_c<int,0,sizeof...(prp)> >(obj);
413 }
414
415 /*! \brief Implementation of the copy
416 *
417 * \param vs source object
418 * \param vd destination object
419 *
420 */
421 inline object_s_di(const v_src & vs, v_dst & vd)
422 {
423 object_s_di_f<v_src,v_dst,prp...> obj(vs,vd);
424 boost::mpl::for_each_ref< boost::mpl::range_c<int,0,sizeof...(prp)> >(obj);
425 }
426};
427
428/*! \brief It copy the properties from one object to another
429 *
430 * Given a set of properties for the destination object (0,1,3) it copy that properties
431 * to the source object properties (0,1,2)
432 *
433 * For object we mean an object that follow the OpenFPM data structure format, see openFPM_data wiki
434 * for more information
435 *
436 * ## Create a compile-time object and copy *to* the selected properties
437 * \snippet util_test.hpp object write example
438 * ## Create a compile-time Encap object and copy *to* the selected properties
439 * \snippet util_test.hpp object write encap example
440 *
441 */
442template<typename v_src, typename v_dst, int... prp>
443struct object_s_di<v_src,v_dst,OBJ_ENCAP,prp...>
444{
445 /*! \brief Implementation of the copy
446 *
447 * \param vs source object
448 * \param vd destination object
449 *
450 */
451 __host__ __device__ inline object_s_di(const v_src & vs, v_dst && vd)
452 {
453 object_s_di_e<v_src,v_dst,prp...> obj(vs,vd);
454 boost::mpl::for_each_ref< boost::mpl::range_c<int,0,(int)sizeof...(prp)> >(obj);
455 }
456
457 /*! \brief Implementation of the copy
458 *
459 * \param vs source object
460 * \param vd destination object
461 *
462 */
463 __host__ __device__ inline object_s_di(const v_src & vs, v_dst & vd)
464 {
465 object_s_di_e<v_src,v_dst,prp...> obj(vs,vd);
466 boost::mpl::for_each_ref< boost::mpl::range_c<int,0,sizeof...(prp)> >(obj);
467 }
468};
469
470
471
472template<typename v_src, typename v_dst, int... prp>
473struct object_s_di<v_src,v_dst,OBJ_ENCAP_CHUNKING,prp...>
474{
475 /*! \brief Implementation of the copy
476 *
477 * \param vs source object
478 * \param vd destination object
479 *
480 */
481 inline object_s_di(const v_src & vs, v_dst && vd, size_t sub_id)
482 {
483 object_s_di_e_cnk<v_src,v_dst,prp...> obj(vs,vd,sub_id);
484 boost::mpl::for_each_ref< boost::mpl::range_c<int,0,sizeof...(prp)> >(obj);
485 }
486
487 /*! \brief Implementation of the copy
488 *
489 * \param vs source object
490 * \param vd destination object
491 *
492 */
493 inline object_s_di(const v_src & vs, v_dst & vd, size_t sub_id)
494 {
495 object_s_di_e_cnk<v_src,v_dst,prp...> obj(vs,vd,sub_id);
496 boost::mpl::for_each_ref< boost::mpl::range_c<int,0,sizeof...(prp)> >(obj);
497 }
498};
499
500////////////////////////// WITH OPERATION VERSION
501
502/*! \brief It copy the properties from one object to another applying an operation
503 *
504 * Stub object
505 *
506 * \see object_s_di_op<v_src,v_dst,OBJ_ENCAP,prp...> object_copy<v_src,v_dst,OBJ_ENCAP,prp...>
507 *
508 *
509 */
510template<template<typename,typename> class op, typename v_src, typename v_dst,int type_copy, int... prp>
511struct object_s_di_op
512{
513 /*! \brief Stub method
514 *
515 * \param vs source object
516 * \param vd destination object
517 *
518 */
519 inline object_s_di_op(const v_src & vs, v_dst & vd)
520 {
521 std::cerr << "Error object_copy: " << __FILE__ << " " << __LINE__ << "\n";
522 };
523};
524
525/*! \brief Given a set of properties for the destination (0,1,3,5)
526 * it copy the source properties (0,1,2,3) applying an operation
527 *
528 *
529 * ### Object copy example
530 * \snippet util_test.hpp object copy example
531 *
532 */
533template<template<typename,typename> class op, typename v_src, typename v_dst, int... prp>
534struct object_s_di_op<op,v_src,v_dst,OBJ_NORMAL,prp...>
535{
536 /*! \brief Implementation of the copy with operation
537 *
538 * \param vs source object
539 * \param vd destination object
540 *
541 */
542 inline object_s_di_op(const v_src && vs, v_dst && vd)
543 {
544 object_s_di_f_op<op,v_src,v_dst,prp...> obj(vs,vd);
545 boost::mpl::for_each_ref< boost::mpl::range_c<int,0,sizeof...(prp)> >(obj);
546 }
547
548 /*! \brief Implementation of the copy with operation
549 *
550 * \param vs source object
551 * \param vd destination object
552 *
553 */
554 inline object_s_di_op(const v_src & vs, v_dst & vd)
555 {
556 object_s_di_f_op<op,v_src,v_dst,prp...> obj(vs,vd);
557 boost::mpl::for_each_ref< boost::mpl::range_c<int,0,sizeof...(prp)> >(obj);
558 }
559};
560
561
562/*! \brief It copy the properties from one object to another applying an operation
563 *
564 * Given a set of properties for the destination object (0,1,3) it copy that properties
565 * to the source object properties (0,1,2) applying an operation
566 *
567 * For object we mean an object that follow the OpenFPM data structure format, see openFPM_data wiki
568 * for more information
569 *
570 * ## Create a compile-time object and copy *to* the selected properties applying an operation
571 * \snippet util_test.hpp object write example with op
572 * ## Create a compile-time Encap object and copy *to* the selected properties applying an operation
573 * \snippet util_test.hpp object write encap example with op
574 *
575 */
576template<template<typename,typename> class op, typename v_src, typename v_dst, int... prp>
577struct object_s_di_op<op, v_src,v_dst,OBJ_ENCAP,prp...>
578{
579 /*! \brief Implementation of the copy with operation
580 *
581 * \param vs source object
582 * \param vd destination object
583 *
584 */
585 __device__ __host__ inline object_s_di_op(const v_src & vs, v_dst && vd)
586 {
587 object_s_di_e_op<op,v_src,v_dst,prp...> obj(vs,vd);
588 boost::mpl::for_each_ref< boost::mpl::range_c<int,0,sizeof...(prp)> >(obj);
589 }
590
591 /*! \brief Implementation of the copy with operation
592 *
593 * \param vs source object
594 * \param vd destination object
595 *
596 */
597 __device__ __host__ inline object_s_di_op(const v_src & vs, v_dst & vd)
598 {
599 object_s_di_e_op<op,v_src,v_dst,prp...> obj(vs,vd);
600 boost::mpl::for_each_ref< boost::mpl::range_c<int,0,sizeof...(prp)> >(obj);
601 }
602};
603
604/*! \brief It copy the properties from one object to another applying an operation
605 *
606 * Given a set of properties for the destination object (0,1,3) it copy that properties
607 * to the source object properties (0,1,2) applying an operation
608 *
609 * For object we mean an object that follow the OpenFPM data structure format, see openFPM_data wiki
610 * for more information
611 *
612 * ## Create a compile-time object and copy *to* the selected properties applying an operation
613 * \snippet util_test.hpp object write example with op
614 * ## Create a compile-time Encap object and copy *to* the selected properties applying an operation
615 * \snippet util_test.hpp object write encap example with op
616 *
617 */
618template<template<typename,typename> class op, typename v_src, typename v_dst, int... prp>
619struct object_s_di_op<op, v_src,v_dst,OBJ_ENCAP_CHUNKING,prp...>
620{
621 /*! \brief Implementation of the copy with operation
622 *
623 * \param vs source object
624 * \param vd destination object
625 *
626 */
627 inline object_s_di_op(const v_src & vs, v_dst && vd)
628 {
629 object_s_di_e_op_cnk<op,v_src,v_dst,prp...> obj(vs,vd);
630 boost::mpl::for_each_ref< boost::mpl::range_c<int,0,sizeof...(prp)> >(obj);
631 }
632
633 /*! \brief Implementation of the copy with operation
634 *
635 * \param vs source object
636 * \param vd destination object
637 *
638 */
639 inline object_s_di_op(const v_src & vs, v_dst & vd, size_t sub_id)
640 {
641 object_s_di_e_op_cnk<op,v_src,v_dst,prp...> obj(vs,vd,sub_id);
642 boost::mpl::for_each_ref< boost::mpl::range_c<int,0,sizeof...(prp)> >(obj);
643 }
644};
645
646#endif /* OBJECT_WRITE_HPP_ */
647