1/*
2 * object_si_d.hpp
3 *
4 * Created on: May 31, 2015
5 * Author: Pietro Incardona
6 */
7
8#ifndef OBJECT_SI_D_HPP_
9#define OBJECT_SI_D_HPP_
10
11#include "for_each_ref.hpp"
12#include <boost/mpl/range_c.hpp>
13#include <boost/fusion/include/size.hpp>
14
15/*! \brief this class is a functor for "for_each" algorithm
16 *
17 * This class is a functor for "for_each" algorithm. For each
18 * element of the boost::vector the operator() is called.
19 * Is mainly used to copy the selected properties
20 *
21 * \tparam v_src source object
22 * \tparam d_src destination object
23 *
24 */
25
26template<typename v_src,typename v_dst, int... prp>
27struct object_si_d_e
28{
29 //! Convert the packed properties into an MPL vector
30 typedef typename to_boost_vmpl<prp...>::type v_prp;
31
32 //! Source object
33 const v_src & src;
34
35 //! Destination object
36 v_dst & dst;
37
38 /*! \brief Constructor
39 *
40 * \param src source object
41 * \param dst destination object
42 *
43 */
44 __device__ __host__ object_si_d_e(const v_src & src, v_dst & dst)
45 :src(src),dst(dst)
46 {
47 };
48
49 //! It call the functor for each member
50 template<typename T>
51 __device__ __host__ void operator()(T& t)
52 {
53 typedef decltype(src.template get<boost::mpl::at<v_prp,boost::mpl::int_<T::value>>::type::value>()) stype;
54
55 // In case of layout switch use this
56 //meta_copy_d<stype,dtype>::meta_copy_d_(src.template get<boost::mpl::at<v_prp,boost::mpl::int_<T::value>>::type::value>(),dst.template get<T::value>());
57
58 meta_copy<typename std::remove_reference<stype>::type>::meta_copy_(src.template get<boost::mpl::at<v_prp,boost::mpl::int_<T::value>>::type::value>(),dst.template get<T::value>());
59 }
60};
61
62/*! \brief this class is a functor for "for_each" algorithm
63 *
64 * This class is a functor for "for_each" algorithm. For each
65 * element of the boost::vector the operator() is called.
66 * Is mainly used to copy the selected properties
67 *
68 * \tparam v_src source object
69 * \tparam d_src destination object
70 *
71 */
72
73template<typename v_src,typename v_dst, int... prp>
74struct object_si_d_e_cnk
75{
76 // Convert the packed properties into an MPL vector
77 typedef typename to_boost_vmpl<prp...>::type v_prp;
78
79 // Source object
80 const v_src & src;
81
82 // Destination object
83 v_dst & dst;
84
85 // Element id
86 size_t sub_id;
87
88 /*! \brief Constructor
89 *
90 * \param src source object
91 * \param dst destination object
92 *
93 */
94 object_si_d_e_cnk(const v_src & src, size_t sub_id, v_dst & dst)
95 :src(src),dst(dst),sub_id(sub_id)
96 {
97 };
98
99 //! It call the functor for each member
100 template<typename T>
101 void operator()(T& t)
102 {
103 typedef typename boost::mpl::at<typename v_dst::type,typename boost::mpl::int_<T::value>>::type ctype;
104
105 meta_copy<ctype>::meta_copy_(src.template get<boost::mpl::at<v_prp,boost::mpl::int_<T::value>>::type::value>()[sub_id],dst.template get<T::value>());
106 }
107};
108
109/*! \brief this class is a functor for "for_each" algorithm
110 *
111 * This class is a functor for "for_each" algorithm. For each
112 * element of the boost::vector the operator() is called.
113 * Is mainly used to copy the selected properties
114 *
115 * \tparam v_src source object
116 * \tparam d_src destination object
117 *
118 */
119
120template<typename v_src,typename v_dst, int... prp>
121struct object_si_d_f
122{
123 // Convert the packed properties into an MPL vector
124 typedef typename to_boost_vmpl<prp...>::type v_prp;
125
126 // Source object
127 const v_src & src;
128
129 // Destination object
130 v_dst & dst;
131
132 /*! \brief Constructor
133 *
134 * \param src source object
135 * \param dst destination object
136 *
137 */
138 object_si_d_f(const v_src & src, v_dst & dst)
139 :src(src),dst(dst)
140 {
141 };
142
143 //! It call the functor for each member
144 template<typename T>
145 void operator()(T& t)
146 {
147 typedef typename boost::mpl::at<typename v_dst::type,typename boost::mpl::int_<T::value>>::type ctype;
148
149 meta_copy<ctype>::meta_copy_(boost::fusion::at_c<boost::mpl::at<v_prp,boost::mpl::int_<T::value>>::type::value>(src.data),boost::fusion::at_c<T::value>(dst.data));
150 }
151};
152
153#define OBJ_ENCAP 1
154#define OBJ_NORMAL 2
155#define OBJ_ENCAP_CHUNKING 3
156
157/*! \brief It copy the properties from one object to another
158 *
159 * Stub object
160 *
161 * \see object_copy<v_src,v_dst,NORMAL,prp...> object_copy<v_src,v_dst,ENCAP,prp...>
162 *
163 *
164 */
165template<typename v_src, typename v_dst,int type_copy, int... prp>
166struct object_si_d
167{
168 inline object_si_d(const v_src & vs, v_dst & vd)
169 {
170 std::cerr << "Error object_copy: " << __FILE__ << " " << __LINE__ << "\n";
171 };
172};
173
174/*! \brief It copy the properties from one object to another
175 *
176 * Given a set of properties for the source (0,1,3) it copy that property to the destination properties
177 * (0,1,2)
178 *
179 * ### Object copy example
180 * \snippet util_test.hpp object copy example
181 *
182 */
183template<typename v_src, typename v_dst, int... prp>
184struct object_si_d<v_src,v_dst,OBJ_NORMAL,prp...>
185{
186 inline object_si_d(const v_src && vs, v_dst && vd)
187 {
188 object_si_d_f<v_src,v_dst,prp...> obj(vs,vd);
189 boost::mpl::for_each_ref< boost::mpl::range_c<int,0,v_dst::max_prop> >(obj);
190 }
191
192 inline object_si_d(const v_src & vs, v_dst & vd)
193 {
194 object_si_d_f<v_src,v_dst,prp...> obj(vs,vd);
195 boost::mpl::for_each_ref< boost::mpl::range_c<int,0,v_dst::max_prop> >(obj);
196 }
197};
198
199/*! \brief It copy the properties from one object to another
200 *
201 * Given a set of properties for the source object (0,1,3) it copy that properties
202 * to the destination object properties (0,1,2)
203 *
204 * For object we mean an object that follow the OpenFPM data structure format, see openFPM_data wiki
205 * for more information
206 *
207 * ## Create a compile-time object and copy *from* the selected properties
208 * \snippet util_test.hpp object copy example
209 * ## Create a compile-time Encap object and copy *from* the selected properties
210 * \snippet util_test.hpp object copy encap example
211 *
212 */
213template<typename v_src, typename v_dst, int... prp>
214struct object_si_d<v_src,v_dst,OBJ_ENCAP,prp...>
215{
216 __device__ __host__ inline object_si_d(const v_src && vs, v_dst && vd)
217 {
218 object_si_d_e<v_src,v_dst,prp...> obj(vs,vd);
219 boost::mpl::for_each_ref< boost::mpl::range_c<int,0,v_dst::max_prop> >(obj);
220 }
221
222 __device__ __host__ inline object_si_d(const v_src & vs, v_dst & vd)
223 {
224 object_si_d_e<v_src,v_dst,prp...> obj(vs,vd);
225 boost::mpl::for_each_ref< boost::mpl::range_c<int,0,v_dst::max_prop> >(obj);
226 }
227};
228
229
230/*! \brief It copy the properties from one object to another
231 *
232 * Given a set of properties for the source object (0,1,3) it copy that properties
233 * to the destination object properties (0,1,2)
234 *
235 * For object we mean an object that follow the OpenFPM data structure format, see openFPM_data wiki
236 * for more information
237 *
238 * ## Create a compile-time object and copy *from* the selected properties
239 * \snippet util_test.hpp object copy example
240 * ## Create a compile-time Encap object and copy *from* the selected properties
241 * \snippet util_test.hpp object copy encap example
242 *
243 */
244template<typename v_src, typename v_dst, int... prp>
245struct object_si_d<v_src,v_dst,OBJ_ENCAP_CHUNKING,prp...>
246{
247 inline object_si_d(const v_src && vs, size_t sub_id, v_dst && vd)
248 {
249 object_si_d_e_cnk<v_src,v_dst,prp...> obj(vs,sub_id,vd);
250 boost::mpl::for_each_ref< boost::mpl::range_c<int,0,v_dst::max_prop> >(obj);
251 }
252
253 inline object_si_d(const v_src & vs, size_t sub_id, v_dst & vd)
254 {
255 object_si_d_e_cnk<v_src,v_dst,prp...> obj(vs,sub_id,vd);
256 boost::mpl::for_each_ref< boost::mpl::range_c<int,0,v_dst::max_prop> >(obj);
257 }
258};
259
260template<typename v_src, typename v_dst>
261struct object_si_d<v_src,v_dst,OBJ_ENCAP>
262{
263 __device__ __host__ inline object_si_d(const v_src && vs, v_dst && vd)
264 {
265 }
266
267 __device__ __host__ inline object_si_d(const v_src & vs, v_dst & vd)
268 {
269 }
270};
271
272#endif /* VECTOR_PROP_COPY_HPP_ */
273