1/*
2 * copy_aggregates.hpp
3 *
4 * Created on: Oct 31, 2015
5 * Author: i-bird
6 */
7
8#ifndef OPENFPM_DATA_SRC_UTIL_COPY_COMPARE_AGGREGATES_HPP_
9#define OPENFPM_DATA_SRC_UTIL_COPY_COMPARE_AGGREGATES_HPP_
10
11#include <boost/type_traits.hpp>
12#include <boost/mpl/vector_c.hpp>
13#include <iostream>
14
15template<typename T> struct meta_copy;
16template<template<typename,typename> class op, typename T> struct meta_copy_op;
17template<typename T> struct meta_compare;
18
19/*! \brief Structure to copy aggregates
20 *
21 * \tparam aggregate to copy
22 *
23 */
24template<typename S, typename S2>
25struct copy_aggregate_dual
26{
27 //! src
28 const S src;
29
30 //! Destination grid
31 S2 & dst;
32
33 //! copy_aggregate
34 inline copy_aggregate_dual(S src, S2 & dst)
35 :src(src),dst(dst){};
36
37 //! It call the copy function for each member
38 template<typename T>
39 inline void operator()(T& t) const
40 {
41 // This is the type of the object we have to copy
42 typedef typename boost::fusion::result_of::at_c<typename S2::type,T::value>::type copy_type;
43
44 // Remove the reference from the type to copy
45 typedef typename boost::remove_reference<copy_type>::type copy_rtype;
46
47 meta_copy<copy_rtype>::meta_copy_(src.template get<T::value>(),dst.template get<T::value>());
48 }
49};
50
51template<typename T> struct meta_copy;
52template<template<typename,typename> class op, typename T> struct meta_copy_op;
53template<typename T> struct meta_compare;
54
55/*! \brief Structure to copy aggregates
56 *
57 * \tparam aggregate to copy
58 *
59 */
60template<typename S>
61struct copy_aggregate
62{
63 //! src
64 const S & src;
65
66 //! Destination grid
67 S & dst;
68
69 //! copy_aggregate
70 inline copy_aggregate(const S & src, S & dst)
71 :src(src),dst(dst){};
72
73 //! It call the copy function for each member
74 template<typename T>
75 inline void operator()(T& t) const
76 {
77 // This is the type of the object we have to copy
78 typedef typename boost::fusion::result_of::at_c<typename S::type,T::value>::type copy_type;
79
80 // Remove the reference from the type to copy
81 typedef typename boost::remove_reference<copy_type>::type copy_rtype;
82
83 meta_copy<copy_rtype>::meta_copy_(src.template get<T::value>(),dst.template get<T::value>());
84 }
85};
86
87/*! \brief Structure to copy aggregates applying an operation
88 *
89 * \tparam op operation to apply
90 * \tparam aggregate to copy
91 *
92 */
93template<template<typename,typename> class op, typename S>
94struct copy_aggregate_op
95{
96 //! src
97 const S & src;
98
99 //! Destination grid
100 S & dst;
101
102 //! copy_aggregate
103 inline copy_aggregate_op(const S & src, S & dst)
104 :src(src),dst(dst){};
105
106 //! It call the copy function for each member
107 template<typename T>
108 inline void operator()(T& t) const
109 {
110 // This is the type of the object we have to copy
111 typedef typename boost::fusion::result_of::at_c<typename S::type,T::value>::type copy_type;
112
113 // Remove the reference from the type to copy
114 typedef typename boost::remove_reference<copy_type>::type copy_rtype;
115
116 meta_copy_op<op,copy_rtype>::meta_copy_op_(src.template get<T::value>(),dst.template get<T::value>());
117 }
118};
119
120
121/*! \brief Structure to compare aggregates
122 *
123 * \tparam aggregate to compare
124 *
125 */
126template<typename S>
127struct compare_aggregate
128{
129 //! result of the comparation
130 bool eq;
131
132 //! src
133 const S & src;
134
135 //! Destination grid
136 const S & dst;
137
138 //! copy_aggregate
139 inline compare_aggregate(const S & src, const S & dst)
140 :eq(true),src(src),dst(dst){};
141
142 //! It call the copy function for each member
143 template<typename T>
144 inline void operator()(T& t)
145 {
146 // This is the type of the object we have to copy
147 typedef typename boost::fusion::result_of::at_c<typename S::type,T::value>::type compare_type;
148
149 // Remove the reference from the type to copy
150 typedef typename boost::remove_reference<compare_type>::type compare_rtype;
151
152 if (eq == false)
153 return;
154
155 eq = meta_compare<compare_rtype>::meta_compare_f(boost::fusion::at_c<T::value>(src.data),boost::fusion::at_c<T::value>(dst.data));
156 }
157
158 /*! \brief Returh the result of the comparison
159 *
160 * \return true if aggregates match
161 *
162 */
163 inline bool result()
164 {
165 return eq;
166 }
167};
168
169#endif /* OPENFPM_DATA_SRC_UTIL_COPY_COMPARE_AGGREGATES_HPP_ */
170