1 | /* |
2 | * map_vector_std_util.hpp |
3 | * |
4 | * Created on: May 14, 2016 |
5 | * Author: i-bird |
6 | */ |
7 | |
8 | #ifndef OPENFPM_DATA_SRC_VECTOR_MAP_VECTOR_STD_UTIL_HPP_ |
9 | #define OPENFPM_DATA_SRC_VECTOR_MAP_VECTOR_STD_UTIL_HPP_ |
10 | |
11 | #include "util/common.hpp" |
12 | |
13 | /*! \brief pack/add function selector |
14 | * |
15 | * This in case of error |
16 | * |
17 | */ |
18 | template<bool,typename T, typename S> |
19 | struct push_back_op_neste |
20 | { |
21 | /*! \brief push_back |
22 | * |
23 | * Print an error |
24 | * |
25 | * \param base vector where to push_back |
26 | * \param obj object to push |
27 | * |
28 | */ |
29 | static inline void push_back(std::vector<T> & base, const S & obj) |
30 | { |
31 | #ifndef DISABLE_ALL_RTTI |
32 | std::cerr << __FILE__ << ":" << __LINE__ << " error cannot push " << demangle(typeid(S).name()) << " into a vector of " << demangle(typeid(T).name()) << std::endl; |
33 | #endif |
34 | } |
35 | }; |
36 | |
37 | /*! \brief pack/add function selector |
38 | * |
39 | * This in case normally add an object |
40 | * |
41 | */ |
42 | template<typename T, typename S> |
43 | struct push_back_op_neste<true,T,S> |
44 | { |
45 | |
46 | /*! \brief Push_back on a vector |
47 | * |
48 | * Push on a vector an object |
49 | * |
50 | * \param base vector where to push_back |
51 | * \param obj object to push |
52 | * |
53 | */ |
54 | static inline void push_back(std::vector<T> & base, const S & obj) |
55 | { |
56 | base.push_back(T()); |
57 | base[base.size()-1] = obj; |
58 | } |
59 | }; |
60 | |
61 | /*! \brief pack/add function selector |
62 | * |
63 | * In case of error |
64 | * |
65 | */ |
66 | template<bool,typename T, typename S> |
67 | struct push_back_std_op_neste |
68 | { |
69 | |
70 | /*! \brief push_back |
71 | * |
72 | * Print an error |
73 | * |
74 | * \param base vector where to push_back |
75 | * \param obj object to push |
76 | * |
77 | */ |
78 | static inline void push_back(std::vector<T> & base, const S & obj) |
79 | { |
80 | #ifndef DISABLE_ALL_RTTI |
81 | std::cerr << __FILE__ << ":" << __LINE__ << " error cannot push " << demangle(typeid(S).name()) << " into a vector of " << demangle(typeid(T).name()) << std::endl; |
82 | #endif |
83 | } |
84 | }; |
85 | |
86 | template<typename T, typename S> |
87 | struct push_back_std_op_neste<true,T,S> |
88 | { |
89 | static inline void push_back(std::vector<T> & base, const S & obj) |
90 | { |
91 | base.reserve(base.size() + obj.size()); |
92 | for (size_t i = 0 ; i < obj.size() ; i++) |
93 | { |
94 | base.push_back(obj.get(i)); |
95 | } |
96 | } |
97 | }; |
98 | |
99 | template<bool is_t, bool is_s,typename T, typename S> |
100 | struct push_back_op |
101 | { |
102 | static inline void push_back(std::vector<T> & base, const S & obj) |
103 | { |
104 | #ifndef DISABLE_ALL_RTTI |
105 | std::cerr << __FILE__ << ":" << __LINE__ << " error cannot push " << demangle(typeid(S).name()) << " into a vector of " << demangle(typeid(T).name()) << std::endl; |
106 | #endif |
107 | } |
108 | }; |
109 | |
110 | template<typename T, typename S> |
111 | struct push_back_op<false,false,T,S> |
112 | { |
113 | static inline void push_back(std::vector<T> & base, const S & obj) |
114 | { |
115 | base.push_back(obj); |
116 | } |
117 | }; |
118 | |
119 | template<typename T, typename S> |
120 | struct push_back_op<false,true,T,S> |
121 | { |
122 | static inline void push_back(std::vector<T> & base, const S & obj) |
123 | { |
124 | push_back_std_op_neste<std::is_same<T,typename S::value_type>::value,T,S>::push_back(base,obj); |
125 | } |
126 | }; |
127 | |
128 | |
129 | |
130 | template<typename T, typename S> |
131 | struct push_back_op<true,true,T,S> |
132 | { |
133 | static inline void push_back(std::vector<T> & base, const S & obj) |
134 | {push_back_op_neste<std::is_assignable<typename T::value_type,typename S::value_type>::value || |
135 | std::is_same<typename T::value_type,typename S::value_type>::value,T,S>::push_back(base,obj);} |
136 | }; |
137 | |
138 | |
139 | template<bool has_base, typename base_obj, typename v_obj> |
140 | struct base_copy |
141 | { |
142 | static inline void copy(base_obj & base, const v_obj & obj) |
143 | { |
144 | base.clear(); |
145 | base.resize(obj.size()); |
146 | |
147 | for (size_t i = 0 ; i < obj.size() ; i++) |
148 | { |
149 | base.get(i) = obj.get(i); |
150 | } |
151 | } |
152 | }; |
153 | |
154 | template<typename base_obj, typename v_obj> |
155 | struct base_copy<true,base_obj,v_obj> |
156 | { |
157 | static inline void copy(base_obj & base, const v_obj & obj) |
158 | { |
159 | base = obj.base; |
160 | } |
161 | }; |
162 | |
163 | template<typename T, typename Sfinae = void> |
164 | struct has_base_to_copy: std::false_type {}; |
165 | |
166 | /*! \brief has_data check if a type has defined a member data |
167 | * |
168 | * ### Example |
169 | * |
170 | * \snippet map_vector_std_util_unit_test.hpp Check has_base_to_copy |
171 | * |
172 | * return true if T::type is a valid type |
173 | * |
174 | */ |
175 | template<typename T> |
176 | struct has_base_to_copy<T, typename Void< typename T::base_to_copy >::type > : std::true_type |
177 | {}; |
178 | |
179 | #endif /* OPENFPM_DATA_SRC_VECTOR_MAP_VECTOR_STD_UTIL_HPP_ */ |
180 | |