| 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 | |
| 33 | template<template<typename,typename> class op, typename v_src,typename v_dst, int... prp> |
| 34 | struct 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 | */ |
| 96 | template<template<typename,typename> class op, typename v_src, typename v_dst,int type_copy, int... prp> |
| 97 | struct 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 | */ |
| 128 | template<template<typename,typename> class op, typename v_src, typename v_dst, int... prp> |
| 129 | struct 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 | |