GCC Code Coverage Report | |||||||||||||||||||||
|
|||||||||||||||||||||
Line | Branch | Exec | Source |
1 |
#ifndef ZSERIO_ALLOCATOR_PROPAGATING_COPY_H_INC |
||
2 |
#define ZSERIO_ALLOCATOR_PROPAGATING_COPY_H_INC |
||
3 |
|||
4 |
#include <algorithm> |
||
5 |
#include <iterator> |
||
6 |
#include <type_traits> |
||
7 |
#include <memory> |
||
8 |
#include <vector> |
||
9 |
|||
10 |
#include "zserio/OptionalHolder.h" |
||
11 |
#include "zserio/AnyHolder.h" |
||
12 |
#include "zserio/NoInit.h" |
||
13 |
|||
14 |
namespace zserio |
||
15 |
{ |
||
16 |
|||
17 |
/** |
||
18 |
* Helper type for specification of allocator propagation. |
||
19 |
*/ |
||
20 |
struct PropagateAllocatorT |
||
21 |
{ |
||
22 |
constexpr explicit PropagateAllocatorT() = default; |
||
23 |
}; |
||
24 |
|||
25 |
/** |
||
26 |
* Constant used to convenient specification of allocator propagation. |
||
27 |
*/ |
||
28 |
constexpr PropagateAllocatorT PropagateAllocator; |
||
29 |
|||
30 |
template <typename T, typename ALLOC> |
||
31 |
T allocatorPropagatingCopy(const T& source, const ALLOC& allocator); |
||
32 |
|||
33 |
template <typename T, typename ALLOC, typename ALLOC2> |
||
34 |
AnyHolder<ALLOC> allocatorPropagatingCopy( |
||
35 |
const AnyHolder<ALLOC>& source, const ALLOC2& allocator); |
||
36 |
|||
37 |
template <typename T, typename ALLOC> |
||
38 |
T allocatorPropagatingCopy(NoInitT, const T& source, const ALLOC& allocator); |
||
39 |
|||
40 |
template <typename T, typename ALLOC, typename ALLOC2> |
||
41 |
AnyHolder<ALLOC> allocatorPropagatingCopy( |
||
42 |
NoInitT, const AnyHolder<ALLOC>& source, const ALLOC2& allocator); |
||
43 |
|||
44 |
namespace detail |
||
45 |
{ |
||
46 |
|||
47 |
// implementation for std::basic_string from old std. libs, that does not fully conform |
||
48 |
// to C++11. [old-compiler-support] |
||
49 |
template <typename CharT, typename Traits, typename ALLOC1, typename ALLOC2> |
||
50 |
97 |
std::basic_string<CharT, Traits, ALLOC1> allocatorPropagatingCopyDefault(std::true_type, |
|
51 |
const std::basic_string<CharT, Traits, ALLOC1>& source, const ALLOC2& allocator) |
||
52 |
{ |
||
53 |
✓✗✗✗ ✗✗ |
97 |
return std::basic_string<CharT, Traits, ALLOC1>(source.c_str(), source.length(), allocator); |
54 |
} |
||
55 |
|||
56 |
// implementation of copy for vectors of bool from old std. libs, that does not fully |
||
57 |
// conform to C++11. [old-compiler-support] |
||
58 |
template <typename ALLOC, typename ALLOC2> |
||
59 |
64 |
std::vector<bool, ALLOC> allocatorPropagatingCopyVec( |
|
60 |
std::false_type, const std::vector<bool, ALLOC>& source, const ALLOC2& allocator) |
||
61 |
{ |
||
62 |
64 |
std::vector<bool, ALLOC> ret(allocator); |
|
63 |
✓✗ | 64 |
ret.reserve(source.size()); |
64 |
✓✗ | 64 |
ret.assign(source.begin(), source.end()); |
65 |
64 |
return ret; |
|
66 |
} |
||
67 |
|||
68 |
// implementation of copy for "regular" classes that supports allocator |
||
69 |
template <typename T, typename ALLOC> |
||
70 |
97 |
T allocatorPropagatingCopyDefault(std::true_type, const T& source, const ALLOC& allocator) |
|
71 |
{ |
||
72 |
✓✗ | 97 |
return T(source, allocator); |
73 |
} |
||
74 |
|||
75 |
// implementation of copy for "regular" classes that does not support allocator |
||
76 |
template <typename T, typename ALLOC> |
||
77 |
577 |
T allocatorPropagatingCopyDefault(std::false_type, const T& source, const ALLOC&) |
|
78 |
{ |
||
79 |
577 |
return source; |
|
80 |
} |
||
81 |
|||
82 |
// implementation of copy for "regular" classes that supports "PropagateAllocator" copy |
||
83 |
template <typename T, typename ALLOC> |
||
84 |
390 |
T allocatorPropagatingCopyPropagating(std::true_type, const T& source, const ALLOC& allocator) |
|
85 |
{ |
||
86 |
✓✗✗✗ ✓✗✗✗ ✗✗✗✗ |
390 |
return T(PropagateAllocator, source, allocator); |
87 |
} |
||
88 |
|||
89 |
// implementation of copy for "regular" classes that supports "PropagateAllocator" copy |
||
90 |
template <typename T, typename ALLOC> |
||
91 |
196 |
T allocatorPropagatingCopyPropagating(std::true_type, NoInitT, const T& source, const ALLOC& allocator) |
|
92 |
{ |
||
93 |
✓✗✗✗ ✗✗ |
196 |
return T(PropagateAllocator, NoInit, source, allocator); |
94 |
} |
||
95 |
|||
96 |
// implementation of copy for "regular" classes that does not support "PropagateAllocator" copy |
||
97 |
template <typename T, typename ALLOC> |
||
98 |
771 |
T allocatorPropagatingCopyPropagating(std::false_type, const T& source, const ALLOC& allocator) |
|
99 |
{ |
||
100 |
✓✗✗✓ ✗✗✗✗ ✗ |
771 |
return allocatorPropagatingCopyDefault(std::uses_allocator<T, ALLOC>(), source, allocator); |
101 |
} |
||
102 |
|||
103 |
// implementation of copy for vectors containing type that supports allocator |
||
104 |
template <typename T, typename ALLOC, typename ALLOC2> |
||
105 |
354 |
std::vector<T, ALLOC> allocatorPropagatingCopyVec( |
|
106 |
std::true_type, const std::vector<T, ALLOC>& source, const ALLOC2& allocator) |
||
107 |
{ |
||
108 |
354 |
std::vector<T, ALLOC> result(allocator); |
|
109 |
✓✗✓✗ ✓✗✗✗ ✗✗ |
354 |
result.reserve(source.size()); |
110 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✗✗✗ ✗✗✗✗ |
354 |
std::transform(source.begin(), source.end(), std::back_inserter(result), |
111 |
642 |
[&](const T& value){ return allocatorPropagatingCopy(value, allocator); }); |
|
112 |
354 |
return result; |
|
113 |
} |
||
114 |
|||
115 |
// implementation of copy for vectors containing type that supports allocator |
||
116 |
template <typename T, typename ALLOC, typename ALLOC2> |
||
117 |
64 |
std::vector<T, ALLOC> allocatorPropagatingCopyVec( |
|
118 |
std::true_type, NoInitT, const std::vector<T, ALLOC>& source, const ALLOC2& allocator) |
||
119 |
{ |
||
120 |
64 |
std::vector<T, ALLOC> result(allocator); |
|
121 |
✓✗ | 64 |
result.reserve(source.size()); |
122 |
✓✗✓✗ |
64 |
std::transform(source.begin(), source.end(), std::back_inserter(result), |
123 |
192 |
[&](const T& value) { return allocatorPropagatingCopy(NoInit, value, allocator); }); |
|
124 |
64 |
return result; |
|
125 |
} |
||
126 |
|||
127 |
// implementation of copy for vectors containing type that does not support allocator |
||
128 |
template <typename T, typename ALLOC, typename ALLOC2> |
||
129 |
2961 |
std::vector<T, ALLOC> allocatorPropagatingCopyVec( |
|
130 |
std::false_type, const std::vector<T, ALLOC>& source, const ALLOC2& allocator) |
||
131 |
{ |
||
132 |
✓✗ | 2961 |
return std::vector<T, ALLOC>(source, allocator); |
133 |
} |
||
134 |
|||
135 |
template <typename T, typename ALLOC> |
||
136 |
1161 |
T allocatorPropagatingCopyImpl(const T& source, const ALLOC& allocator) |
|
137 |
{ |
||
138 |
✓✗ | 1538 |
return allocatorPropagatingCopyPropagating( |
139 |
✓✗✓✗ ✗✓✗✗ ✗✗✗✗ ✗✗✗✗ ✗ |
1930 |
std::is_constructible<T, PropagateAllocatorT, T, ALLOC>(), source, allocator); |
140 |
} |
||
141 |
|||
142 |
template <typename T, typename ALLOC> |
||
143 |
196 |
T allocatorPropagatingCopyImpl(NoInitT, const T& source, const ALLOC& allocator) |
|
144 |
{ |
||
145 |
static_assert(std::is_constructible<T, NoInitT, T>::value, "Can be used only for parameterized compounds!"); |
||
146 |
|||
147 |
return allocatorPropagatingCopyPropagating( |
||
148 |
✓✗✗✗ ✗✗ |
196 |
std::is_constructible<T, PropagateAllocatorT, NoInitT, T, ALLOC>(), NoInit, source, allocator); |
149 |
} |
||
150 |
|||
151 |
template <typename T, typename ALLOC, typename ALLOC2> |
||
152 |
2 |
HeapOptionalHolder<T, ALLOC> allocatorPropagatingCopyImpl( |
|
153 |
const HeapOptionalHolder<T, ALLOC>& source, const ALLOC2& allocator) |
||
154 |
{ |
||
155 |
✓✓ | 2 |
if (source.hasValue()) |
156 |
✓✗ | 1 |
return HeapOptionalHolder<T, ALLOC>(allocatorPropagatingCopy(*source, allocator), allocator); |
157 |
else |
||
158 |
1 |
return HeapOptionalHolder<T, ALLOC>(allocator); |
|
159 |
} |
||
160 |
|||
161 |
template <typename T, typename ALLOC, typename ALLOC2> |
||
162 |
2 |
HeapOptionalHolder<T, ALLOC> allocatorPropagatingCopyImpl( |
|
163 |
NoInitT, const HeapOptionalHolder<T, ALLOC>& source, const ALLOC2& allocator) |
||
164 |
{ |
||
165 |
static_assert(std::is_constructible<T, NoInitT, T>::value, "Can be used only for parameterized compounds!"); |
||
166 |
|||
167 |
✓✓ | 2 |
if (source.hasValue()) |
168 |
{ |
||
169 |
1 |
return HeapOptionalHolder<T, ALLOC>(NoInit, allocatorPropagatingCopy(NoInit, *source, allocator), |
|
170 |
✓✗ | 1 |
allocator); |
171 |
} |
||
172 |
else |
||
173 |
1 |
return HeapOptionalHolder<T, ALLOC>(allocator); |
|
174 |
} |
||
175 |
|||
176 |
template <typename T, typename ALLOC> |
||
177 |
2 |
InplaceOptionalHolder<T> allocatorPropagatingCopyImpl( |
|
178 |
const InplaceOptionalHolder<T>& source, const ALLOC& allocator) |
||
179 |
{ |
||
180 |
✓✓✗✗ ✗✗ |
2 |
if (source.hasValue()) |
181 |
✓✗✗✗ ✗✗✗✗ |
1 |
return InplaceOptionalHolder<T>(allocatorPropagatingCopy(*source, allocator)); |
182 |
else |
||
183 |
✗✗ | 1 |
return InplaceOptionalHolder<T>(); |
184 |
} |
||
185 |
|||
186 |
template <typename T, typename ALLOC> |
||
187 |
2 |
InplaceOptionalHolder<T> allocatorPropagatingCopyImpl( |
|
188 |
NoInitT, const InplaceOptionalHolder<T>& source, const ALLOC& allocator) |
||
189 |
{ |
||
190 |
static_assert(std::is_constructible<T, NoInitT, T>::value, "Can be used only for parameterized compounds!"); |
||
191 |
|||
192 |
✓✓ | 2 |
if (source.hasValue()) |
193 |
✗✗ | 1 |
return InplaceOptionalHolder<T>(NoInit, allocatorPropagatingCopy(NoInit, *source, allocator)); |
194 |
else |
||
195 |
1 |
return InplaceOptionalHolder<T>(); |
|
196 |
} |
||
197 |
|||
198 |
template <typename T, typename ALLOC, typename ALLOC2> |
||
199 |
2 |
AnyHolder<ALLOC> allocatorPropagatingCopyImpl( |
|
200 |
const AnyHolder<ALLOC>& source, const ALLOC2& allocator) |
||
201 |
{ |
||
202 |
✓✓✗✗ ✗✗✗✗ |
2 |
if (source.hasValue()) |
203 |
{ |
||
204 |
1 |
return AnyHolder<ALLOC>(allocatorPropagatingCopy(source.template get<T>(), allocator), |
|
205 |
✗✓✗✗ ✗✗✗✗ ✗✗✗✗ ✗ |
1 |
allocator); |
206 |
} |
||
207 |
else |
||
208 |
{ |
||
209 |
1 |
return AnyHolder<ALLOC>(allocator); |
|
210 |
} |
||
211 |
} |
||
212 |
|||
213 |
template <typename T, typename ALLOC, typename ALLOC2> |
||
214 |
2 |
AnyHolder<ALLOC> allocatorPropagatingCopyImpl( |
|
215 |
NoInitT, const AnyHolder<ALLOC>& source, const ALLOC2& allocator) |
||
216 |
{ |
||
217 |
✓✓ | 2 |
if (source.hasValue()) |
218 |
{ |
||
219 |
1 |
return AnyHolder<ALLOC>(NoInit, allocatorPropagatingCopy(NoInit, source.template get<T>(), allocator), |
|
220 |
✓✗ | 1 |
allocator); |
221 |
} |
||
222 |
else |
||
223 |
{ |
||
224 |
1 |
return AnyHolder<ALLOC>(allocator); |
|
225 |
} |
||
226 |
} |
||
227 |
|||
228 |
template <typename T, typename ALLOC, typename ALLOC2> |
||
229 |
3379 |
std::vector<T, ALLOC> allocatorPropagatingCopyImpl( |
|
230 |
const std::vector<T, ALLOC>& source, const ALLOC2& allocator) |
||
231 |
{ |
||
232 |
✓✗✓✗ ✓✗✓✗ ✓✗✗✗ ✗✗✗✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗ |
3379 |
return allocatorPropagatingCopyVec(std::uses_allocator<T, ALLOC>(), source, allocator); |
233 |
} |
||
234 |
|||
235 |
template <typename T, typename ALLOC, typename ALLOC2> |
||
236 |
64 |
std::vector<T, ALLOC> allocatorPropagatingCopyImpl( |
|
237 |
NoInitT, const std::vector<T, ALLOC>& source, const ALLOC2& allocator) |
||
238 |
{ |
||
239 |
static_assert(std::is_constructible<T, NoInitT, T>::value, "Can be used only for parameterized compounds!"); |
||
240 |
|||
241 |
✓✗ | 64 |
return allocatorPropagatingCopyVec(std::uses_allocator<T, ALLOC>(), NoInit, source, allocator); |
242 |
} |
||
243 |
|||
244 |
} // namespace detail |
||
245 |
|||
246 |
/** |
||
247 |
* Copy the input object, propagating the allocator where needed. |
||
248 |
* |
||
249 |
* \param source Object to copy. |
||
250 |
* \param allocator Allocator to be propagated to the target object type constructor. |
||
251 |
* |
||
252 |
* \return Object copy. |
||
253 |
*/ |
||
254 |
template <typename T, typename ALLOC> |
||
255 |
4544 |
T allocatorPropagatingCopy(const T& source, const ALLOC& allocator) |
|
256 |
{ |
||
257 |
static_assert(!std::is_same<AnyHolder<ALLOC>, T>::value, "Cannot be used for AnyHolder!"); |
||
258 |
|||
259 |
4544 |
return detail::allocatorPropagatingCopyImpl(source, allocator); |
|
260 |
} |
||
261 |
|||
262 |
/** |
||
263 |
* Copy the input object, propagating the allocator where needed and prevents initialization. |
||
264 |
* |
||
265 |
* \param source Object to copy. |
||
266 |
* \param allocator Allocator to be propagated to the target object type constructor. |
||
267 |
* |
||
268 |
* \return Object copy. |
||
269 |
*/ |
||
270 |
template <typename T, typename ALLOC> |
||
271 |
264 |
T allocatorPropagatingCopy(NoInitT, const T& source, const ALLOC& allocator) |
|
272 |
{ |
||
273 |
static_assert(!std::is_same<AnyHolder<ALLOC>, T>::value, "Cannot be used for AnyHolder!"); |
||
274 |
|||
275 |
264 |
return detail::allocatorPropagatingCopyImpl(NoInit, source, allocator); |
|
276 |
} |
||
277 |
|||
278 |
/** |
||
279 |
* Copy the input any holder, propagating the allocator where needed. |
||
280 |
* |
||
281 |
* \param source Any holder to copy. |
||
282 |
* \param allocator Allocator to be propagated to the target object type constructor. |
||
283 |
* |
||
284 |
* \return Copy of any holder. |
||
285 |
*/ |
||
286 |
template <typename T, typename ALLOC, typename ALLOC2> |
||
287 |
2 |
AnyHolder<ALLOC> allocatorPropagatingCopy( |
|
288 |
const AnyHolder<ALLOC>& source, const ALLOC2& allocator) |
||
289 |
{ |
||
290 |
2 |
return detail::allocatorPropagatingCopyImpl<T>(source, allocator); |
|
291 |
} |
||
292 |
|||
293 |
/** |
||
294 |
* Copy the input any holder, propagating the allocator where needed and prevents initialization. |
||
295 |
* |
||
296 |
* \param source Any holder to copy. |
||
297 |
* \param allocator Allocator to be propagated to the target object type constructor. |
||
298 |
* |
||
299 |
* \return Copy of any holder. |
||
300 |
*/ |
||
301 |
template <typename T, typename ALLOC, typename ALLOC2> |
||
302 |
2 |
AnyHolder<ALLOC> allocatorPropagatingCopy( |
|
303 |
NoInitT, const AnyHolder<ALLOC>& source, const ALLOC2& allocator) |
||
304 |
{ |
||
305 |
static_assert(std::is_constructible<T, NoInitT, T>::value, "Can be used only for parameterized compounds!"); |
||
306 |
|||
307 |
2 |
return detail::allocatorPropagatingCopyImpl<T>(NoInit, source, allocator); |
|
308 |
} |
||
309 |
|||
310 |
} // namespace zserio |
||
311 |
|||
312 |
#endif // ZSERIO_ALLOCATOR_PROPAGATING_COPY_H_INC |
Generated by: GCOVR (Version 4.2) |