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 */
18template<bool,typename T, typename S>
19struct 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 */
42template<typename T, typename S>
43struct 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 */
66template<bool,typename T, typename S>
67struct 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
86template<typename T, typename S>
87struct 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
99template<bool is_t, bool is_s,typename T, typename S>
100struct 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
110template<typename T, typename S>
111struct 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
119template<typename T, typename S>
120struct 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
130template<typename T, typename S>
131struct 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
139template<bool has_base, typename base_obj, typename v_obj>
140struct 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
154template<typename base_obj, typename v_obj>
155struct 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
163template<typename T, typename Sfinae = void>
164struct 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 */
175template<typename T>
176struct 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