1/*
2 * object_si_di.hpp
3 *
4 * Created on: Jun 11, 2015
5 * Author: i-bird
6 */
7
8#ifndef OBJECT_SI_DI_HPP_
9#define OBJECT_SI_DI_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
18
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 applying an operation
25 *
26 * \tparam op operation
27 * \tparam v_src source object
28 * \tparam d_src destination object
29 * \tparam prp properties
30 *
31 */
32
33template<template<typename,typename> class op, typename v_src,typename v_dst, int... prp>
34struct object_si_di_e_op
35{
36 //! Convert the packed properties into an MPL vector
37 typedef typename to_boost_vmpl<prp...>::type v_prp;
38
39 //! Source object
40 const v_src & src;
41
42 //! Destination object
43 v_dst & dst;
44
45 /*! \brief Constructor
46 *
47 * \param src source object
48 * \param dst destination object
49 *
50 */
51 __device__ __host__ object_si_di_e_op(const v_src & src, v_dst & dst)
52 :src(src),dst(dst)
53 {
54 };
55
56#ifdef SE_CLASS1
57 /*! \brief Constructor
58 *
59 * Calling this constructor produce an error. This class store the reference of the object,
60 * this mean that the object passed must not be a temporal object
61 *
62 */
63 object_si_di_e_op(v_src && src, v_dst & dst)
64 :src(src),dst(dst)
65 {std::cerr << "Error: " <<__FILE__ << ":" << __LINE__ << " Passing a temporal object\n";};
66#endif
67
68 //! It call the functor for each member
69 template<typename T>
70 __device__ __host__ void operator()(T& t)
71 {
72 // Remove the reference from the type to copy
73 typedef typename boost::remove_reference<decltype(dst.template get<boost::mpl::at<v_prp,boost::mpl::int_<T::value>>::type::value>())>::type copy_dtype;
74 typedef typename std::remove_reference<decltype(src.template get<boost::mpl::at<v_prp,boost::mpl::int_<T::value>>::type::value>())>::type copy_stype;
75
76 meta_copy_op_d<op,copy_stype,copy_dtype>::meta_copy_op_d_(src.template get<boost::mpl::at<v_prp,boost::mpl::int_<T::value>>::type::value>(),dst.template get<boost::mpl::at<v_prp,boost::mpl::int_<T::value>>::type::value>());
77 }
78};
79
80
81
82
83
84#define OBJ_ENCAP 1
85
86////////////////////////// WITH OPERATION VERSION
87
88/*! \brief It copy the properties from one object to another applying an operation
89 *
90 * Stub object
91 *
92 * \see object_si_di_op<v_src,v_dst,OBJ_ENCAP,prp...> object_copy<v_src,v_dst,OBJ_ENCAP,prp...>
93 *
94 *
95 */
96template<template<typename,typename> class op, typename v_src, typename v_dst,int type_copy, int... prp>
97struct object_si_di_op
98{
99 /*! \brief Stub method
100 *
101 * \param vs source object
102 * \param vd destination object
103 *
104 */
105 inline object_si_di_op(const v_src & vs, v_dst & vd)
106 {
107 std::cerr << "Error object_copy: " << __FILE__ << " " << __LINE__ << "\n";
108 };
109};
110
111
112
113
114/*! \brief It copy the properties from one object to another applying an operation
115 *
116 * Given a set of properties for the destination object (0,1,3) it copy that properties
117 * to the source object properties (0,1,2) applying an operation
118 *
119 * For object we mean an object that follow the OpenFPM data structure format, see openFPM_data wiki
120 * for more information
121 *
122 * ## Create a compile-time object and copy *to* the selected properties applying an operation
123 * \snippet util_test.hpp object write example with op
124 * ## Create a compile-time Encap object and copy *to* the selected properties applying an operation
125 * \snippet util_test.hpp object write encap example with op
126 *
127 */
128template<template<typename,typename> class op, typename v_src, typename v_dst, int... prp>
129struct object_si_di_op<op, v_src,v_dst,OBJ_ENCAP,prp...>
130{
131 /*! \brief Implementation of the copy with operation
132 *
133 * \param vs source object
134 * \param vd destination object
135 *
136 */
137 __device__ __host__ inline object_si_di_op(const v_src & vs, v_dst && vd)
138 {
139 object_si_di_e_op<op,v_src,v_dst,prp...> obj(vs,vd);
140 boost::mpl::for_each_ref< boost::mpl::range_c<int,0,sizeof...(prp)> >(obj);
141 }
142
143 /*! \brief Implementation of the copy with operation
144 *
145 * \param vs source object
146 * \param vd destination object
147 *
148 */
149 __device__ __host__ inline object_si_di_op(const v_src & vs, v_dst & vd)
150 {
151 object_si_di_e_op<op,v_src,v_dst,prp...> obj(vs,vd);
152 boost::mpl::for_each_ref< boost::mpl::range_c<int,0,sizeof...(prp)> >(obj);
153 }
154};
155
156
157
158#endif /* OBJECT_WRITE_HPP_ */
159