GCC Code Coverage Report | |||||||||||||||||||||
|
|||||||||||||||||||||
Line | Branch | Exec | Source |
1 |
#ifndef ZSERIO_ARRAY_H_INC |
||
2 |
#define ZSERIO_ARRAY_H_INC |
||
3 |
|||
4 |
#include <cstdlib> |
||
5 |
#include <type_traits> |
||
6 |
|||
7 |
#include "zserio/AllocatorPropagatingCopy.h" |
||
8 |
#include "zserio/ArrayTraits.h" |
||
9 |
#include "zserio/BitSizeOfCalculator.h" |
||
10 |
#include "zserio/BitStreamReader.h" |
||
11 |
#include "zserio/BitStreamWriter.h" |
||
12 |
#include "zserio/DeltaContext.h" |
||
13 |
#include "zserio/Traits.h" |
||
14 |
#include "zserio/UniquePtr.h" |
||
15 |
#include "zserio/SizeConvertUtil.h" |
||
16 |
|||
17 |
namespace zserio |
||
18 |
{ |
||
19 |
|||
20 |
namespace detail |
||
21 |
{ |
||
22 |
|||
23 |
// array expressions for arrays which do not need expressions |
||
24 |
struct DummyArrayExpressions |
||
25 |
{}; |
||
26 |
|||
27 |
// array owner for arrays which do not need the owner |
||
28 |
struct DummyArrayOwner |
||
29 |
{}; |
||
30 |
|||
31 |
// helper trait to choose the owner type for an array from combination of ARRAY_TRAITS and ARRAY_EXPRESSIONS |
||
32 |
template <typename ARRAY_TRAITS, typename ARRAY_EXPRESSIONS, typename = void> |
||
33 |
struct array_owner_type |
||
34 |
{ |
||
35 |
using type = DummyArrayOwner; |
||
36 |
}; |
||
37 |
|||
38 |
template <typename ARRAY_TRAITS, typename ARRAY_EXPRESSIONS> |
||
39 |
struct array_owner_type<ARRAY_TRAITS, ARRAY_EXPRESSIONS, |
||
40 |
typename std::enable_if<has_owner_type<ARRAY_TRAITS>::value>::type> |
||
41 |
{ |
||
42 |
using type = typename ARRAY_TRAITS::OwnerType; |
||
43 |
}; |
||
44 |
|||
45 |
template <typename ARRAY_TRAITS, typename ARRAY_EXPRESSIONS> |
||
46 |
struct array_owner_type<ARRAY_TRAITS, ARRAY_EXPRESSIONS, |
||
47 |
typename std::enable_if<!has_owner_type<ARRAY_TRAITS>::value && |
||
48 |
has_owner_type<ARRAY_EXPRESSIONS>::value>::type> |
||
49 |
{ |
||
50 |
using type = typename ARRAY_EXPRESSIONS::OwnerType; |
||
51 |
}; |
||
52 |
|||
53 |
// helper trait to choose packing context type for an array from an element type T |
||
54 |
template <typename T, typename = void> |
||
55 |
struct packing_context_type |
||
56 |
{ |
||
57 |
using type = DeltaContext; |
||
58 |
}; |
||
59 |
|||
60 |
template <typename T> |
||
61 |
struct packing_context_type<T, typename std::enable_if<has_zserio_packing_context<T>::value>::type> |
||
62 |
{ |
||
63 |
using type = typename T::ZserioPackingContext; |
||
64 |
}; |
||
65 |
|||
66 |
// calls the initializeOffset static method on ARRAY_EXPRESSIONS if available |
||
67 |
template <typename ARRAY_EXPRESSIONS, typename OWNER_TYPE, |
||
68 |
typename std::enable_if<has_initialize_offset<ARRAY_EXPRESSIONS>::value, int>::type = 0> |
||
69 |
192 |
void initializeOffset(OWNER_TYPE& owner, size_t index, size_t bitPosition) |
|
70 |
{ |
||
71 |
192 |
ARRAY_EXPRESSIONS::initializeOffset(owner, index, bitPosition); |
|
72 |
192 |
} |
|
73 |
|||
74 |
template <typename ARRAY_EXPRESSIONS, typename OWNER_TYPE, |
||
75 |
typename std::enable_if<!has_initialize_offset<ARRAY_EXPRESSIONS>::value, int>::type = 0> |
||
76 |
4512 |
void initializeOffset(OWNER_TYPE&, size_t, size_t) |
|
77 |
4512 |
{} |
|
78 |
|||
79 |
// calls the checkOffset static method on ARRAY_EXPRESSIONS if available |
||
80 |
template <typename ARRAY_EXPRESSIONS, typename OWNER_TYPE, |
||
81 |
typename std::enable_if<has_check_offset<ARRAY_EXPRESSIONS>::value, int>::type = 0> |
||
82 |
384 |
void checkOffset(const OWNER_TYPE& owner, size_t index, size_t bitPosition) |
|
83 |
{ |
||
84 |
384 |
ARRAY_EXPRESSIONS::checkOffset(owner, index, bitPosition); |
|
85 |
384 |
} |
|
86 |
|||
87 |
template <typename ARRAY_EXPRESSIONS, typename OWNER_TYPE, |
||
88 |
typename std::enable_if<!has_check_offset<ARRAY_EXPRESSIONS>::value, int>::type = 0> |
||
89 |
9024 |
void checkOffset(const OWNER_TYPE&, size_t, size_t) |
|
90 |
9024 |
{} |
|
91 |
|||
92 |
// call the initContext method properly on packed array traits |
||
93 |
template <typename PACKED_ARRAY_TRAITS, typename OWNER_TYPE, typename PACKING_CONTEXT, |
||
94 |
typename std::enable_if<has_owner_type<PACKED_ARRAY_TRAITS>::value, int>::type = 0> |
||
95 |
1152 |
void packedArrayTraitsInitContext(const OWNER_TYPE& owner, PACKING_CONTEXT& context, |
|
96 |
typename PACKED_ARRAY_TRAITS::ElementType element) |
||
97 |
{ |
||
98 |
1152 |
PACKED_ARRAY_TRAITS::initContext(owner, context, element); |
|
99 |
1152 |
} |
|
100 |
|||
101 |
template <typename PACKED_ARRAY_TRAITS, typename OWNER_TYPE, typename PACKING_CONTEXT, |
||
102 |
typename std::enable_if<!has_owner_type<PACKED_ARRAY_TRAITS>::value, int>::type = 0> |
||
103 |
10272 |
void packedArrayTraitsInitContext(const OWNER_TYPE&, PACKING_CONTEXT& context, |
|
104 |
typename PACKED_ARRAY_TRAITS::ElementType element) |
||
105 |
{ |
||
106 |
10272 |
PACKED_ARRAY_TRAITS::initContext(context, element); |
|
107 |
10272 |
} |
|
108 |
|||
109 |
// calls the bitSizeOf method properly on array traits which have constant bit size |
||
110 |
template <typename ARRAY_TRAITS, typename OWNER_TYPE, |
||
111 |
typename std::enable_if< |
||
112 |
ARRAY_TRAITS::IS_BITSIZEOF_CONSTANT && has_owner_type<ARRAY_TRAITS>::value, int>::type = 0> |
||
113 |
230 |
size_t arrayTraitsConstBitSizeOf(const OWNER_TYPE& owner) |
|
114 |
{ |
||
115 |
230 |
return ARRAY_TRAITS::bitSizeOf(owner); |
|
116 |
} |
||
117 |
|||
118 |
template <typename ARRAY_TRAITS, typename OWNER_TYPE, |
||
119 |
typename std::enable_if< |
||
120 |
ARRAY_TRAITS::IS_BITSIZEOF_CONSTANT && !has_owner_type<ARRAY_TRAITS>::value, int>::type = 0> |
||
121 |
1018 |
size_t arrayTraitsConstBitSizeOf(const OWNER_TYPE&) |
|
122 |
{ |
||
123 |
1018 |
return ARRAY_TRAITS::bitSizeOf(); |
|
124 |
} |
||
125 |
|||
126 |
// calls the bitSizeOf method properly on array traits which haven't constant bit size |
||
127 |
template <typename ARRAY_TRAITS, typename OWNER_TYPE, |
||
128 |
typename std::enable_if<has_owner_type<ARRAY_TRAITS>::value, int>::type = 0> |
||
129 |
192 |
size_t arrayTraitsBitSizeOf(const OWNER_TYPE& owner, size_t bitPosition, |
|
130 |
const typename ARRAY_TRAITS::ElementType& element) |
||
131 |
{ |
||
132 |
192 |
return ARRAY_TRAITS::bitSizeOf(owner, bitPosition, element); |
|
133 |
} |
||
134 |
|||
135 |
template <typename ARRAY_TRAITS, typename OWNER_TYPE, |
||
136 |
typename std::enable_if<!has_owner_type<ARRAY_TRAITS>::value, int>::type = 0> |
||
137 |
2561 |
size_t arrayTraitsBitSizeOf(const OWNER_TYPE&, size_t bitPosition, |
|
138 |
const typename ARRAY_TRAITS::ElementType& element) |
||
139 |
{ |
||
140 |
2561 |
return ARRAY_TRAITS::bitSizeOf(bitPosition, element); |
|
141 |
} |
||
142 |
|||
143 |
// calls the bitSizeOf method properly on packed array traits which haven't constant bit size |
||
144 |
template <typename PACKED_ARRAY_TRAITS, typename OWNER_TYPE, typename PACKING_CONTEXT, |
||
145 |
typename std::enable_if<has_owner_type<PACKED_ARRAY_TRAITS>::value, int>::type = 0> |
||
146 |
384 |
size_t packedArrayTraitsBitSizeOf(const OWNER_TYPE& owner, PACKING_CONTEXT& context, |
|
147 |
size_t bitPosition, const typename PACKED_ARRAY_TRAITS::ElementType& element) |
||
148 |
{ |
||
149 |
384 |
return PACKED_ARRAY_TRAITS::bitSizeOf(owner, context, bitPosition, element); |
|
150 |
} |
||
151 |
|||
152 |
template <typename PACKED_ARRAY_TRAITS, typename OWNER_TYPE, typename PACKING_CONTEXT, |
||
153 |
typename std::enable_if<!has_owner_type<PACKED_ARRAY_TRAITS>::value, int>::type = 0> |
||
154 |
3424 |
size_t packedArrayTraitsBitSizeOf(const OWNER_TYPE&, PACKING_CONTEXT& context, size_t bitPosition, |
|
155 |
const typename PACKED_ARRAY_TRAITS::ElementType& element) |
||
156 |
{ |
||
157 |
3424 |
return PACKED_ARRAY_TRAITS::bitSizeOf(context, bitPosition, element); |
|
158 |
} |
||
159 |
|||
160 |
// calls the initializeOffsets method properly on array traits |
||
161 |
template <typename ARRAY_TRAITS, typename OWNER_TYPE, |
||
162 |
typename std::enable_if<has_owner_type<ARRAY_TRAITS>::value, int>::type = 0> |
||
163 |
816 |
size_t arrayTraitsInitializeOffsets(OWNER_TYPE& owner, size_t bitPosition, |
|
164 |
typename ARRAY_TRAITS::ElementType& element) |
||
165 |
{ |
||
166 |
816 |
return ARRAY_TRAITS::initializeOffsets(owner, bitPosition, element); |
|
167 |
} |
||
168 |
|||
169 |
template <typename ARRAY_TRAITS, typename OWNER_TYPE, |
||
170 |
typename std::enable_if<!has_owner_type<ARRAY_TRAITS>::value && |
||
171 |
!std::is_scalar<typename ARRAY_TRAITS::ElementType>::value, int>::type = 0> |
||
172 |
352 |
size_t arrayTraitsInitializeOffsets(OWNER_TYPE&, size_t bitPosition, |
|
173 |
const typename ARRAY_TRAITS::ElementType& element) |
||
174 |
{ |
||
175 |
352 |
return ARRAY_TRAITS::initializeOffsets(bitPosition, element); |
|
176 |
} |
||
177 |
|||
178 |
template <typename ARRAY_TRAITS, typename OWNER_TYPE, |
||
179 |
typename std::enable_if<!has_owner_type<ARRAY_TRAITS>::value && |
||
180 |
std::is_scalar<typename ARRAY_TRAITS::ElementType>::value, int>::type = 0> |
||
181 |
4745 |
size_t arrayTraitsInitializeOffsets(OWNER_TYPE&, size_t bitPosition, typename ARRAY_TRAITS::ElementType element) |
|
182 |
{ |
||
183 |
4745 |
return ARRAY_TRAITS::initializeOffsets(bitPosition, element); |
|
184 |
} |
||
185 |
|||
186 |
// calls the initializeOffsets method properly on packed array traits |
||
187 |
template <typename PACKED_ARRAY_TRAITS, typename OWNER_TYPE, typename PACKING_CONTEXT, |
||
188 |
typename std::enable_if<has_owner_type<PACKED_ARRAY_TRAITS>::value, int>::type = 0> |
||
189 |
384 |
size_t packedArrayTraitsInitializeOffsets(OWNER_TYPE& owner, PACKING_CONTEXT& context, |
|
190 |
size_t bitPosition, typename PACKED_ARRAY_TRAITS::ElementType& element) |
||
191 |
{ |
||
192 |
384 |
return PACKED_ARRAY_TRAITS::initializeOffsets(owner, context, bitPosition, element); |
|
193 |
} |
||
194 |
|||
195 |
template <typename PACKED_ARRAY_TRAITS, typename OWNER_TYPE, typename PACKING_CONTEXT, |
||
196 |
typename std::enable_if<!has_owner_type<PACKED_ARRAY_TRAITS>::value && |
||
197 |
!std::is_scalar<typename PACKED_ARRAY_TRAITS::ElementType>::value, int>::type = 0> |
||
198 |
96 |
size_t packedArrayTraitsInitializeOffsets(OWNER_TYPE&, PACKING_CONTEXT& context, |
|
199 |
size_t bitPosition, const typename PACKED_ARRAY_TRAITS::ElementType& element) |
||
200 |
{ |
||
201 |
96 |
return PACKED_ARRAY_TRAITS::initializeOffsets(context, bitPosition, element); |
|
202 |
} |
||
203 |
|||
204 |
template <typename PACKED_ARRAY_TRAITS, typename OWNER_TYPE, typename PACKING_CONTEXT, |
||
205 |
typename std::enable_if<!has_owner_type<PACKED_ARRAY_TRAITS>::value && |
||
206 |
std::is_scalar<typename PACKED_ARRAY_TRAITS::ElementType>::value, int>::type = 0> |
||
207 |
3328 |
size_t packedArrayTraitsInitializeOffsets(OWNER_TYPE&, PACKING_CONTEXT& context, |
|
208 |
size_t bitPosition, typename PACKED_ARRAY_TRAITS::ElementType element) |
||
209 |
{ |
||
210 |
3328 |
return PACKED_ARRAY_TRAITS::initializeOffsets(context, bitPosition, element); |
|
211 |
} |
||
212 |
|||
213 |
// calls the read method properly on array traits |
||
214 |
template <typename ARRAY_TRAITS, typename OWNER_TYPE, typename RAW_ARRAY, |
||
215 |
typename std::enable_if<has_owner_type<ARRAY_TRAITS>::value && |
||
216 |
!has_allocator<ARRAY_TRAITS>::value, int>::type = 0> |
||
217 |
624 |
void arrayTraitsRead(const OWNER_TYPE& owner, RAW_ARRAY& rawArray, BitStreamReader& in, size_t index) |
|
218 |
{ |
||
219 |
✓✗✓✗ ✓✗✓✗ |
624 |
rawArray.push_back(ARRAY_TRAITS::read(owner, in, index)); |
220 |
624 |
} |
|
221 |
|||
222 |
template <typename ARRAY_TRAITS, typename OWNER_TYPE, typename RAW_ARRAY, |
||
223 |
typename std::enable_if<has_owner_type<ARRAY_TRAITS>::value && |
||
224 |
has_allocator<ARRAY_TRAITS>::value, int>::type = 0> |
||
225 |
192 |
void arrayTraitsRead(OWNER_TYPE& owner, RAW_ARRAY& rawArray, BitStreamReader& in, size_t index) |
|
226 |
{ |
||
227 |
192 |
ARRAY_TRAITS::read(owner, rawArray, in, index); |
|
228 |
192 |
} |
|
229 |
|||
230 |
template <typename ARRAY_TRAITS, typename OWNER_TYPE, typename RAW_ARRAY, |
||
231 |
typename std::enable_if<!has_owner_type<ARRAY_TRAITS>::value && |
||
232 |
!has_allocator<ARRAY_TRAITS>::value, int>::type = 0> |
||
233 |
4841 |
void arrayTraitsRead(const OWNER_TYPE&, RAW_ARRAY& rawArray, BitStreamReader& in, size_t index) |
|
234 |
{ |
||
235 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✗✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ |
4841 |
rawArray.push_back(ARRAY_TRAITS::read(in, index)); |
236 |
4840 |
} |
|
237 |
|||
238 |
template <typename ARRAY_TRAITS, typename OWNER_TYPE, typename RAW_ARRAY, |
||
239 |
typename std::enable_if<!has_owner_type<ARRAY_TRAITS>::value && |
||
240 |
has_allocator<ARRAY_TRAITS>::value, int>::type = 0> |
||
241 |
256 |
void arrayTraitsRead(const OWNER_TYPE&, RAW_ARRAY& rawArray, BitStreamReader& in, size_t index) |
|
242 |
{ |
||
243 |
256 |
ARRAY_TRAITS::read(rawArray, in, index); |
|
244 |
256 |
} |
|
245 |
|||
246 |
// calls the read method properly on packed array traits |
||
247 |
template <typename PACKED_ARRAY_TRAITS, typename OWNER_TYPE, typename RAW_ARRAY, typename PACKING_CONTEXT, |
||
248 |
typename std::enable_if<has_owner_type<PACKED_ARRAY_TRAITS>::value && |
||
249 |
has_allocator<PACKED_ARRAY_TRAITS>::value, int>::type = 0> |
||
250 |
192 |
void packedArrayTraitsRead(OWNER_TYPE& owner, RAW_ARRAY& rawArray, PACKING_CONTEXT& context, |
|
251 |
BitStreamReader& in, size_t index) |
||
252 |
{ |
||
253 |
192 |
PACKED_ARRAY_TRAITS::read(owner, rawArray, context, in, index); |
|
254 |
192 |
} |
|
255 |
|||
256 |
template <typename PACKED_ARRAY_TRAITS, typename OWNER_TYPE, typename RAW_ARRAY, typename PACKING_CONTEXT, |
||
257 |
typename std::enable_if<has_owner_type<PACKED_ARRAY_TRAITS>::value && |
||
258 |
!has_allocator<PACKED_ARRAY_TRAITS>::value, int>::type = 0> |
||
259 |
192 |
void packedArrayTraitsRead(const OWNER_TYPE& owner, RAW_ARRAY& rawArray, PACKING_CONTEXT& context, |
|
260 |
BitStreamReader& in, size_t index) |
||
261 |
{ |
||
262 |
✓✗ | 192 |
rawArray.push_back(PACKED_ARRAY_TRAITS::read(owner, context, in, index)); |
263 |
192 |
} |
|
264 |
|||
265 |
// note: types which doesn't have owner and have allocator are never packed (e.g. string, bytes ...) |
||
266 |
// and thus such specialization is not needed |
||
267 |
|||
268 |
template <typename PACKED_ARRAY_TRAITS, typename OWNER_TYPE, typename RAW_ARRAY, typename PACKING_CONTEXT, |
||
269 |
typename std::enable_if<!has_owner_type<PACKED_ARRAY_TRAITS>::value && |
||
270 |
!has_allocator<PACKED_ARRAY_TRAITS>::value, int>::type = 0> |
||
271 |
3424 |
void packedArrayTraitsRead(const OWNER_TYPE&, RAW_ARRAY& rawArray, PACKING_CONTEXT& context, |
|
272 |
BitStreamReader& in, size_t index) |
||
273 |
{ |
||
274 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ |
3424 |
rawArray.push_back(PACKED_ARRAY_TRAITS::read(context, in, index)); |
275 |
3424 |
} |
|
276 |
|||
277 |
// call the write method properly on array traits |
||
278 |
template <typename ARRAY_TRAITS, typename OWNER_TYPE, |
||
279 |
typename std::enable_if<has_owner_type<ARRAY_TRAITS>::value, int>::type = 0> |
||
280 |
816 |
void arrayTraitsWrite(const OWNER_TYPE& owner, |
|
281 |
BitStreamWriter& out, const typename ARRAY_TRAITS::ElementType& element) |
||
282 |
{ |
||
283 |
816 |
ARRAY_TRAITS::write(owner, out, element); |
|
284 |
816 |
} |
|
285 |
|||
286 |
template <typename ARRAY_TRAITS, typename OWNER_TYPE, |
||
287 |
typename std::enable_if<!has_owner_type<ARRAY_TRAITS>::value, int>::type = 0> |
||
288 |
5097 |
void arrayTraitsWrite(const OWNER_TYPE&, |
|
289 |
BitStreamWriter& out, const typename ARRAY_TRAITS::ElementType& element) |
||
290 |
{ |
||
291 |
5097 |
ARRAY_TRAITS::write(out, element); |
|
292 |
5097 |
} |
|
293 |
|||
294 |
// call the write method properly on packed array traits |
||
295 |
template <typename PACKED_ARRAY_TRAITS, typename OWNER_TYPE, typename PACKING_CONTEXT, |
||
296 |
typename std::enable_if<has_owner_type<PACKED_ARRAY_TRAITS>::value, int>::type = 0> |
||
297 |
384 |
void packedArrayTraitsWrite(const OWNER_TYPE& owner, PACKING_CONTEXT& context, |
|
298 |
BitStreamWriter& out, const typename PACKED_ARRAY_TRAITS::ElementType& element) |
||
299 |
{ |
||
300 |
384 |
PACKED_ARRAY_TRAITS::write(owner, context, out, element); |
|
301 |
384 |
} |
|
302 |
|||
303 |
template <typename PACKED_ARRAY_TRAITS, typename OWNER_TYPE, typename PACKING_CONTEXT, |
||
304 |
typename std::enable_if<!has_owner_type<PACKED_ARRAY_TRAITS>::value, int>::type = 0> |
||
305 |
3424 |
void packedArrayTraitsWrite(const OWNER_TYPE&, PACKING_CONTEXT& context, |
|
306 |
BitStreamWriter& out, const typename PACKED_ARRAY_TRAITS::ElementType& element) |
||
307 |
{ |
||
308 |
3424 |
PACKED_ARRAY_TRAITS::write(context, out, element); |
|
309 |
3424 |
} |
|
310 |
|||
311 |
} // namespace detail |
||
312 |
|||
313 |
/** |
||
314 |
* Array type enum which defined type of the underlying array. |
||
315 |
*/ |
||
316 |
enum ArrayType |
||
317 |
{ |
||
318 |
NORMAL, /**< Normal zserio array which has size defined by the Zserio schema. */ |
||
319 |
IMPLICIT, /**< Implicit zserio array which size is defined by number of remaining bits in the bit stream. */ |
||
320 |
ALIGNED, /**< Aligned zserio array which is normal zserio array with indexed offsets. */ |
||
321 |
AUTO, /**< Auto zserio array which has size stored in a hidden field before the array. */ |
||
322 |
ALIGNED_AUTO /**< Aligned auto zserio array which is auto zserio array with indexed offsets. */ |
||
323 |
}; |
||
324 |
|||
325 |
/** |
||
326 |
* Array wrapper for zserio arrays which are not explicitly packed but the element type is packable |
||
327 |
* and thus it can be packed if requested from a parent. |
||
328 |
*/ |
||
329 |
/** |
||
330 |
* Array wrapper for zserio arrays which are never packed. |
||
331 |
*/ |
||
332 |
template <typename RAW_ARRAY, typename ARRAY_TRAITS, ArrayType ARRAY_TYPE, |
||
333 |
typename ARRAY_EXPRESSIONS = detail::DummyArrayExpressions> |
||
334 |
6710 |
class Array |
|
335 |
{ |
||
336 |
public: |
||
337 |
/** Typedef for raw array type. */ |
||
338 |
using RawArray = RAW_ARRAY; |
||
339 |
|||
340 |
/** Typedef for array traits. */ |
||
341 |
using ArrayTraits = ARRAY_TRAITS; |
||
342 |
|||
343 |
/** Typedef for array expressions. */ |
||
344 |
using ArrayExpressions = ARRAY_EXPRESSIONS; |
||
345 |
|||
346 |
/** |
||
347 |
* Typedef for the array's owner type. |
||
348 |
* |
||
349 |
* Owner type is needed for proper expressions evaluation. If neither traits nor array need the owner |
||
350 |
* for expressions evaluation, detail::DummyArrayOwner is used and such array do not need the owner at all. |
||
351 |
*/ |
||
352 |
using OwnerType = typename detail::array_owner_type<ArrayTraits, ArrayExpressions>::type; |
||
353 |
|||
354 |
/** Typedef for allocator type. */ |
||
355 |
using allocator_type = typename RawArray::allocator_type; |
||
356 |
|||
357 |
/** |
||
358 |
* Empty constructor. |
||
359 |
* |
||
360 |
* \param allocator Allocator to use for the raw array. |
||
361 |
*/ |
||
362 |
10240 |
explicit Array(const allocator_type& allocator = allocator_type()) : |
|
363 |
10240 |
m_rawArray(allocator) |
|
364 |
10240 |
{} |
|
365 |
|||
366 |
/** |
||
367 |
* Constructor from l-value raw array. |
||
368 |
* |
||
369 |
* \param rawArray Raw array. |
||
370 |
*/ |
||
371 |
3314 |
explicit Array(const RawArray& rawArray) : |
|
372 |
3314 |
m_rawArray(rawArray) |
|
373 |
3314 |
{} |
|
374 |
|||
375 |
/** |
||
376 |
* Constructor from r-value raw array. |
||
377 |
* |
||
378 |
* \param rawArray Raw array. |
||
379 |
*/ |
||
380 |
44 |
explicit Array(RawArray&& rawArray) : |
|
381 |
44 |
m_rawArray(std::move(rawArray)) |
|
382 |
44 |
{} |
|
383 |
|||
384 |
/** |
||
385 |
* Method generated by default. |
||
386 |
* |
||
387 |
* \{ |
||
388 |
*/ |
||
389 |
23684 |
~Array() = default; |
|
390 |
3312 |
Array(const Array& other) = default; |
|
391 |
Array& operator=(const Array& other) = default; |
||
392 |
3398 |
Array(Array&& other) = default; |
|
393 |
Array& operator=(Array&& other) = default; |
||
394 |
/** |
||
395 |
* \} |
||
396 |
*/ |
||
397 |
|||
398 |
/** |
||
399 |
* Copy constructor which prevents initialization of parameterized elements. |
||
400 |
* |
||
401 |
* Note that elements will be initialized later by a parent compound. |
||
402 |
* |
||
403 |
* \param other Instance to construct from. |
||
404 |
*/ |
||
405 |
template <typename T = typename RAW_ARRAY::value_type, |
||
406 |
typename std::enable_if<std::is_constructible<T, NoInitT, T>::value, int>::type = 0> |
||
407 |
64 |
Array(NoInitT, const Array& other) : |
|
408 |
Array(std::allocator_traits<allocator_type>::select_on_container_copy_construction( |
||
409 |
✗✗ | 64 |
other.m_rawArray.get_allocator())) |
410 |
{ |
||
411 |
✓✗✓✗ ✓✗✓✗ |
64 |
m_rawArray.reserve(other.m_rawArray.size()); |
412 |
✓✓✓✓ ✓✓✓✓ |
256 |
for (const auto& value : other.m_rawArray) |
413 |
✓✗✓✗ ✓✗✓✗ |
192 |
m_rawArray.emplace_back(NoInit, value); |
414 |
64 |
} |
|
415 |
|||
416 |
/** |
||
417 |
* Assignment which prevents initialization of parameterized elements. |
||
418 |
* |
||
419 |
* Note that elements will be initialized later by a parent compound. |
||
420 |
* |
||
421 |
* \param other Instance to move-assign from. |
||
422 |
*/ |
||
423 |
template <typename T = typename RAW_ARRAY::value_type, |
||
424 |
typename std::enable_if<std::is_constructible<T, NoInitT, T>::value, int>::type = 0> |
||
425 |
64 |
Array& assign(NoInitT, const Array& other) |
|
426 |
{ |
||
427 |
128 |
const RawArray rawArray(other.m_rawArray.get_allocator()); |
|
428 |
✓✗✓✗ ✓✗✓✗ |
64 |
m_rawArray = rawArray; // copy assign to get correct allocator propagation behaviour |
429 |
✓✗✓✗ ✓✗✓✗ |
64 |
m_rawArray.reserve(other.m_rawArray.size()); |
430 |
✓✓✓✓ ✓✓✓✓ |
256 |
for (const auto& value : other.m_rawArray) |
431 |
✓✗✓✗ ✓✗✓✗ |
192 |
m_rawArray.emplace_back(NoInit, value); |
432 |
|||
433 |
128 |
return *this; |
|
434 |
} |
||
435 |
|||
436 |
/** |
||
437 |
* Move constructors which prevents initialization of parameterized elements. |
||
438 |
* |
||
439 |
* Provided for convenience since vector move constructor doesn't call move constructors of its elements. |
||
440 |
* |
||
441 |
* \param other Instance to move-construct from. |
||
442 |
*/ |
||
443 |
template <typename T = typename RAW_ARRAY::value_type, |
||
444 |
typename std::enable_if<std::is_constructible<T, NoInitT, T>::value, int>::type = 0> |
||
445 |
64 |
Array(NoInitT, Array&& other) : |
|
446 |
64 |
Array(std::move(other)) |
|
447 |
{ |
||
448 |
64 |
} |
|
449 |
|||
450 |
/** |
||
451 |
* Assignment which prevents initialization of parameterized elements. |
||
452 |
* |
||
453 |
* Provided for convenience since vector move assignment operator doesn't call move assignment operators |
||
454 |
* of its elements. |
||
455 |
* |
||
456 |
* \param other Instance to move-assign from. |
||
457 |
*/ |
||
458 |
template <typename T = typename RAW_ARRAY::value_type, |
||
459 |
typename std::enable_if<std::is_constructible<T, NoInitT, T>::value, int>::type = 0> |
||
460 |
64 |
Array& assign(NoInitT, Array&& other) |
|
461 |
{ |
||
462 |
64 |
return operator=(std::move(other)); |
|
463 |
} |
||
464 |
|||
465 |
/** |
||
466 |
* Copy constructor which forces allocator propagating while copying the raw array. |
||
467 |
* |
||
468 |
* \param other Source array to copy. |
||
469 |
* \param allocator Allocator to propagate during copying. |
||
470 |
*/ |
||
471 |
3312 |
Array(PropagateAllocatorT, const Array& other, const allocator_type& allocator) : |
|
472 |
3312 |
m_rawArray(allocatorPropagatingCopy(other.m_rawArray, allocator)) |
|
473 |
3312 |
{} |
|
474 |
|||
475 |
/** |
||
476 |
* Copy constructor which prevents initialization and forces allocator propagating while copying |
||
477 |
* the raw array. |
||
478 |
* |
||
479 |
* \param other Source array to copy. |
||
480 |
* \param allocator Allocator to propagate during copying. |
||
481 |
*/ |
||
482 |
template <typename T = typename RAW_ARRAY::value_type, |
||
483 |
typename std::enable_if<std::is_constructible<T, NoInitT, T>::value, int>::type = 0> |
||
484 |
64 |
Array(PropagateAllocatorT, NoInitT, const Array& other, const allocator_type& allocator) : |
|
485 |
64 |
m_rawArray(allocatorPropagatingCopy(NoInit, other.m_rawArray, allocator)) |
|
486 |
64 |
{} |
|
487 |
|||
488 |
/** |
||
489 |
* Operator equality. |
||
490 |
* |
||
491 |
* \param other Array to compare. |
||
492 |
* |
||
493 |
* \return True when the underlying raw arrays have same contents, false otherwise. |
||
494 |
*/ |
||
495 |
19872 |
bool operator==(const Array& other) const |
|
496 |
{ |
||
497 |
19872 |
return m_rawArray == other.m_rawArray; |
|
498 |
} |
||
499 |
|||
500 |
/** |
||
501 |
* Operator less than. |
||
502 |
* |
||
503 |
* \param other Array to compare. |
||
504 |
* |
||
505 |
* \return True when the underlying raw array is less than the other underlying raw array. |
||
506 |
*/ |
||
507 |
6624 |
bool operator<(const Array& other) const |
|
508 |
{ |
||
509 |
6624 |
return m_rawArray < other.m_rawArray; |
|
510 |
} |
||
511 |
|||
512 |
/** |
||
513 |
* Hash code. |
||
514 |
* |
||
515 |
* \return Hash code calculated on the underlying raw array. |
||
516 |
*/ |
||
517 |
1 |
uint32_t hashCode() const |
|
518 |
{ |
||
519 |
1 |
return calcHashCode(HASH_SEED, m_rawArray); |
|
520 |
} |
||
521 |
|||
522 |
/** |
||
523 |
* Gets raw array. |
||
524 |
* |
||
525 |
* \return Constant reference to the raw array. |
||
526 |
*/ |
||
527 |
20320 |
const RawArray& getRawArray() const |
|
528 |
{ |
||
529 |
20320 |
return m_rawArray; |
|
530 |
} |
||
531 |
|||
532 |
/** |
||
533 |
* Gets raw array. |
||
534 |
* |
||
535 |
* \return Reference to the raw array. |
||
536 |
*/ |
||
537 |
13908 |
RawArray& getRawArray() |
|
538 |
{ |
||
539 |
13908 |
return m_rawArray; |
|
540 |
} |
||
541 |
|||
542 |
/** |
||
543 |
* Initializes array elements. |
||
544 |
* |
||
545 |
* \param owner Array owner. |
||
546 |
*/ |
||
547 |
template <typename ARRAY_EXPRESSIONS_ = ArrayExpressions, |
||
548 |
typename std::enable_if<has_initialize_element<ARRAY_EXPRESSIONS_>::value, int>::type = 0> |
||
549 |
68 |
void initializeElements(OwnerType& owner) |
|
550 |
{ |
||
551 |
68 |
size_t index = 0; |
|
552 |
✓✓✓✓ ✓✓✓✓ |
263 |
for (auto&& element : m_rawArray) |
553 |
{ |
||
554 |
✓✗✓✗ ✓✗✓✗ |
195 |
ArrayExpressions::initializeElement(owner, element, index); |
555 |
195 |
index++; |
|
556 |
} |
||
557 |
68 |
} |
|
558 |
|||
559 |
/** |
||
560 |
* Calculates bit size of this array. |
||
561 |
* |
||
562 |
* Available for arrays which do not need the owner. |
||
563 |
* |
||
564 |
* \param bitPosition Current bit position. |
||
565 |
* |
||
566 |
* \return Bit size of the array. |
||
567 |
*/ |
||
568 |
template <typename OWNER_TYPE_ = OwnerType, |
||
569 |
typename std::enable_if<std::is_same<OWNER_TYPE_, detail::DummyArrayOwner>::value, int>::type = 0> |
||
570 |
2113 |
size_t bitSizeOf(size_t bitPosition) const |
|
571 |
{ |
||
572 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✗✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✗✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✗✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✗✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✗✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✗✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✗✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✗✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ |
2113 |
return bitSizeOfImpl(detail::DummyArrayOwner(), bitPosition); |
573 |
} |
||
574 |
|||
575 |
/** |
||
576 |
* Calculates bit size of this array. |
||
577 |
* |
||
578 |
* Available for arrays which need the owner. |
||
579 |
* |
||
580 |
* \param owner Array owner. |
||
581 |
* \param bitPosition Current bit position. |
||
582 |
* |
||
583 |
* \return Bit size of the array. |
||
584 |
*/ |
||
585 |
template <typename OWNER_TYPE_ = OwnerType, |
||
586 |
typename std::enable_if<!std::is_same<OWNER_TYPE_, detail::DummyArrayOwner>::value, int>::type = 0> |
||
587 |
304 |
size_t bitSizeOf(const OwnerType& owner, size_t bitPosition) const |
|
588 |
{ |
||
589 |
304 |
return bitSizeOfImpl(owner, bitPosition); |
|
590 |
} |
||
591 |
|||
592 |
/** |
||
593 |
* Initializes indexed offsets. |
||
594 |
* |
||
595 |
* Available for arrays which do not need the owner. |
||
596 |
* |
||
597 |
* \param bitPosition Current bit position. |
||
598 |
* |
||
599 |
* \return Updated bit position which points to the first bit after the array. |
||
600 |
*/ |
||
601 |
template <typename OWNER_TYPE_ = OwnerType, |
||
602 |
typename std::enable_if<std::is_same<OWNER_TYPE_, detail::DummyArrayOwner>::value, int>::type = 0> |
||
603 |
2113 |
size_t initializeOffsets(size_t bitPosition) |
|
604 |
{ |
||
605 |
detail::DummyArrayOwner owner; |
||
606 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✗✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✗✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✗✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✗✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✗✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✗✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✗✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✗✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ |
2113 |
return initializeOffsetsImpl(owner, bitPosition); |
607 |
} |
||
608 |
|||
609 |
/** |
||
610 |
* Initializes indexed offsets. |
||
611 |
* |
||
612 |
* Available for arrays which need the owner. |
||
613 |
* |
||
614 |
* \param owner Array owner. |
||
615 |
* \param bitPosition Current bit position. |
||
616 |
* |
||
617 |
* \return Updated bit position which points to the first bit after the array. |
||
618 |
*/ |
||
619 |
template <typename OWNER_TYPE_ = OwnerType, |
||
620 |
typename std::enable_if<!std::is_same<OWNER_TYPE_, detail::DummyArrayOwner>::value, int>::type = 0> |
||
621 |
304 |
size_t initializeOffsets(OwnerType& owner, size_t bitPosition) |
|
622 |
{ |
||
623 |
304 |
return initializeOffsetsImpl(owner, bitPosition); |
|
624 |
} |
||
625 |
|||
626 |
/** |
||
627 |
* Reads the array from the bit stream. |
||
628 |
* |
||
629 |
* Available for arrays which do not need the owner. |
||
630 |
* |
||
631 |
* \param in Bit stream reader to use for reading. |
||
632 |
* \param arrayLength Array length. Not needed for auto / implicit arrays. |
||
633 |
*/ |
||
634 |
template <typename OWNER_TYPE_ = OwnerType, |
||
635 |
typename std::enable_if<std::is_same<OWNER_TYPE_, detail::DummyArrayOwner>::value, int>::type = 0> |
||
636 |
2113 |
void read(BitStreamReader& in, size_t arrayLength = 0) |
|
637 |
{ |
||
638 |
detail::DummyArrayOwner owner; |
||
639 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✓ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✗✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✗✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✗✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✗✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✗✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✗✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✗✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✗✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ |
2113 |
readImpl(owner, in, arrayLength); |
640 |
2112 |
} |
|
641 |
|||
642 |
/** |
||
643 |
* Reads the array from the bit stream. |
||
644 |
* |
||
645 |
* Available for arrays which need the owner. |
||
646 |
* |
||
647 |
* \param owner Array owner. |
||
648 |
* \param in Bit stream reader to use for reading. |
||
649 |
* \param arrayLength Array length. Not needed for auto / implicit arrays. |
||
650 |
*/ |
||
651 |
template <typename OWNER_TYPE_ = OwnerType, |
||
652 |
typename std::enable_if<!std::is_same<OWNER_TYPE_, detail::DummyArrayOwner>::value, int>::type = 0> |
||
653 |
304 |
void read(OwnerType& owner, BitStreamReader& in, size_t arrayLength = 0) |
|
654 |
{ |
||
655 |
304 |
readImpl(owner, in, arrayLength); |
|
656 |
304 |
} |
|
657 |
|||
658 |
/** |
||
659 |
* Writes the array to the bit stream. |
||
660 |
* |
||
661 |
* Available for arrays which do not need the owner. |
||
662 |
* |
||
663 |
* \param out Bit stream write to use for writing. |
||
664 |
*/ |
||
665 |
template <typename OWNER_TYPE_ = OwnerType, |
||
666 |
typename std::enable_if<std::is_same<OWNER_TYPE_, detail::DummyArrayOwner>::value, int>::type = 0> |
||
667 |
2113 |
void write(BitStreamWriter& out) const |
|
668 |
{ |
||
669 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✗✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✗✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✗✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✗✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✗✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✗✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✗✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✗✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ |
2113 |
writeImpl(detail::DummyArrayOwner(), out); |
670 |
2113 |
} |
|
671 |
|||
672 |
/** |
||
673 |
* Writes the array to the bit stream. |
||
674 |
* |
||
675 |
* Available for arrays which need the owner. |
||
676 |
* |
||
677 |
* \param owner Array owner. |
||
678 |
* \param out Bit stream write to use for writing. |
||
679 |
*/ |
||
680 |
template <typename OWNER_TYPE_ = OwnerType, |
||
681 |
typename std::enable_if<!std::is_same<OWNER_TYPE_, detail::DummyArrayOwner>::value, int>::type = 0> |
||
682 |
304 |
void write(const OwnerType& owner, BitStreamWriter& out) const |
|
683 |
{ |
||
684 |
304 |
writeImpl(owner, out); |
|
685 |
304 |
} |
|
686 |
|||
687 |
/** |
||
688 |
* Returns length of the packed array stored in the bit stream in bits. |
||
689 |
* |
||
690 |
* Available for arrays which do not need the owner. |
||
691 |
* |
||
692 |
* \param bitPosition Current bit stream position. |
||
693 |
* |
||
694 |
* \return Length of the array stored in the bit stream in bits. |
||
695 |
*/ |
||
696 |
template <typename OWNER_TYPE_ = OwnerType, |
||
697 |
typename std::enable_if<std::is_same<OWNER_TYPE_, detail::DummyArrayOwner>::value, int>::type = 0> |
||
698 |
800 |
size_t bitSizeOfPacked(size_t bitPosition) const |
|
699 |
{ |
||
700 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ |
800 |
return bitSizeOfPackedImpl(detail::DummyArrayOwner(), bitPosition); |
701 |
} |
||
702 |
|||
703 |
/** |
||
704 |
* Returns length of the packed array stored in the bit stream in bits. |
||
705 |
* |
||
706 |
* Available for arrays which need the owner. |
||
707 |
* |
||
708 |
* \param owner Array owner. |
||
709 |
* \param bitPosition Current bit stream position. |
||
710 |
* |
||
711 |
* \return Length of the array stored in the bit stream in bits. |
||
712 |
*/ |
||
713 |
template <typename OWNER_TYPE_ = OwnerType, |
||
714 |
typename std::enable_if<!std::is_same<OWNER_TYPE_, detail::DummyArrayOwner>::value, int>::type = 0> |
||
715 |
96 |
size_t bitSizeOfPacked(const OwnerType& ownerType, size_t bitPosition) const |
|
716 |
{ |
||
717 |
96 |
return bitSizeOfPackedImpl(ownerType, bitPosition); |
|
718 |
} |
||
719 |
|||
720 |
/** |
||
721 |
* Initializes indexed offsets for the packed array. |
||
722 |
* |
||
723 |
* Available for arrays which do not need the owner. |
||
724 |
* |
||
725 |
* \param bitPosition Current bit stream position. |
||
726 |
* |
||
727 |
* \return Updated bit stream position which points to the first bit after the array. |
||
728 |
*/ |
||
729 |
template <typename OWNER_TYPE_ = OwnerType, |
||
730 |
typename std::enable_if<std::is_same<OWNER_TYPE_, detail::DummyArrayOwner>::value, int>::type = 0> |
||
731 |
800 |
size_t initializeOffsetsPacked(size_t bitPosition) |
|
732 |
{ |
||
733 |
detail::DummyArrayOwner owner; |
||
734 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ |
800 |
return initializeOffsetsPackedImpl(owner, bitPosition); |
735 |
} |
||
736 |
|||
737 |
/** |
||
738 |
* Initializes indexed offsets for the packed array. |
||
739 |
* |
||
740 |
* Available for arrays which need the owner. |
||
741 |
* |
||
742 |
* \param owner Array owner. |
||
743 |
* \param bitPosition Current bit stream position. |
||
744 |
* |
||
745 |
* \return Updated bit stream position which points to the first bit after the array. |
||
746 |
*/ |
||
747 |
template <typename OWNER_TYPE_ = OwnerType, |
||
748 |
typename std::enable_if<!std::is_same<OWNER_TYPE_, detail::DummyArrayOwner>::value, int>::type = 0> |
||
749 |
96 |
size_t initializeOffsetsPacked(OwnerType& owner, size_t bitPosition) |
|
750 |
{ |
||
751 |
96 |
return initializeOffsetsPackedImpl(owner, bitPosition); |
|
752 |
} |
||
753 |
|||
754 |
/** |
||
755 |
* Reads packed array from the bit stream. |
||
756 |
* |
||
757 |
* Available for arrays which do not need the owner. |
||
758 |
* |
||
759 |
* \param in Bit stream from which to read. |
||
760 |
* \param arrayLength Number of elements to read or 0 in case of auto arrays. |
||
761 |
*/ |
||
762 |
template <typename OWNER_TYPE_ = OwnerType, |
||
763 |
typename std::enable_if<std::is_same<OWNER_TYPE_, detail::DummyArrayOwner>::value, int>::type = 0> |
||
764 |
800 |
void readPacked(BitStreamReader& in, size_t arrayLength = 0) |
|
765 |
{ |
||
766 |
detail::DummyArrayOwner owner; |
||
767 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ |
800 |
readPackedImpl(owner, in, arrayLength); |
768 |
800 |
} |
|
769 |
|||
770 |
/** |
||
771 |
* Reads packed array from the bit stream. |
||
772 |
* |
||
773 |
* Available for arrays which need the owner. |
||
774 |
* |
||
775 |
* \param owner Array owner. |
||
776 |
* \param in Bit stream from which to read. |
||
777 |
* \param arrayLength Number of elements to read or 0 in case of auto arrays. |
||
778 |
*/ |
||
779 |
template <typename OWNER_TYPE_ = OwnerType, |
||
780 |
typename std::enable_if<!std::is_same<OWNER_TYPE_, detail::DummyArrayOwner>::value, int>::type = 0> |
||
781 |
96 |
void readPacked(OwnerType& owner, BitStreamReader& in, size_t arrayLength = 0) |
|
782 |
{ |
||
783 |
96 |
readPackedImpl(owner, in, arrayLength); |
|
784 |
96 |
} |
|
785 |
|||
786 |
/** |
||
787 |
* Writes packed array to the bit stream. |
||
788 |
* |
||
789 |
* Available for arrays which do not need the owner. |
||
790 |
* |
||
791 |
* \param out Bit stream where to write. |
||
792 |
*/ |
||
793 |
template <typename OWNER_TYPE_ = OwnerType, |
||
794 |
typename std::enable_if<std::is_same<OWNER_TYPE_, detail::DummyArrayOwner>::value, int>::type = 0> |
||
795 |
800 |
void writePacked(BitStreamWriter& out) const |
|
796 |
{ |
||
797 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ |
800 |
writePackedImpl(detail::DummyArrayOwner(), out); |
798 |
800 |
} |
|
799 |
|||
800 |
/** |
||
801 |
* Writes packed array to the bit stream. |
||
802 |
* |
||
803 |
* Available for arrays which need the owner. |
||
804 |
* |
||
805 |
* \param owner Array owner. |
||
806 |
* \param out Bit stream where to write. |
||
807 |
*/ |
||
808 |
template <typename OWNER_TYPE_ = OwnerType, |
||
809 |
typename std::enable_if<!std::is_same<OWNER_TYPE_, detail::DummyArrayOwner>::value, int>::type = 0> |
||
810 |
96 |
void writePacked(const OwnerType& owner, BitStreamWriter& out) const |
|
811 |
{ |
||
812 |
96 |
writePackedImpl(owner, out); |
|
813 |
96 |
} |
|
814 |
|||
815 |
private: |
||
816 |
template <ArrayType ARRAY_TYPE_ = ARRAY_TYPE, |
||
817 |
typename std::enable_if< |
||
818 |
ARRAY_TYPE_ != ArrayType::AUTO && ARRAY_TYPE_ != ArrayType::ALIGNED_AUTO, int>::type = 0> |
||
819 |
3458 |
static void addBitSizeOfArrayLength(size_t&, size_t) |
|
820 |
3458 |
{} |
|
821 |
|||
822 |
template <ArrayType ARRAY_TYPE_ = ARRAY_TYPE, |
||
823 |
typename std::enable_if< |
||
824 |
ARRAY_TYPE_ == ArrayType::AUTO || ARRAY_TYPE_ == ArrayType::ALIGNED_AUTO, int>::type = 0> |
||
825 |
3168 |
static void addBitSizeOfArrayLength(size_t& bitPosition, size_t arrayLength) |
|
826 |
{ |
||
827 |
3168 |
bitPosition += bitSizeOfVarSize(convertSizeToUInt32(arrayLength)); |
|
828 |
3168 |
} |
|
829 |
|||
830 |
template <ArrayType ARRAY_TYPE_ = ARRAY_TYPE, |
||
831 |
typename std::enable_if< |
||
832 |
ARRAY_TYPE_ != ArrayType::ALIGNED && ARRAY_TYPE_ != ArrayType::ALIGNED_AUTO, int>::type = 0> |
||
833 |
3281 |
static void alignBitPosition(size_t&) |
|
834 |
3281 |
{} |
|
835 |
|||
836 |
template <ArrayType ARRAY_TYPE_ = ARRAY_TYPE, |
||
837 |
typename std::enable_if< |
||
838 |
ARRAY_TYPE_ == ArrayType::ALIGNED || ARRAY_TYPE_ == ArrayType::ALIGNED_AUTO, int>::type = 0> |
||
839 |
3280 |
static void alignBitPosition(size_t& bitPosition) |
|
840 |
{ |
||
841 |
3280 |
bitPosition = alignTo(8, bitPosition); |
|
842 |
3280 |
} |
|
843 |
|||
844 |
template <typename IO, typename OWNER_TYPE, ArrayType ARRAY_TYPE_ = ARRAY_TYPE, |
||
845 |
typename std::enable_if< |
||
846 |
ARRAY_TYPE_ != ArrayType::ALIGNED && ARRAY_TYPE_ != ArrayType::ALIGNED_AUTO, int>::type = 0> |
||
847 |
10034 |
static void alignAndCheckOffset(IO&, OWNER_TYPE&, size_t) |
|
848 |
10034 |
{} |
|
849 |
|||
850 |
template <typename IO, typename OWNER_TYPE, ArrayType ARRAY_TYPE_ = ARRAY_TYPE, |
||
851 |
typename std::enable_if< |
||
852 |
ARRAY_TYPE_ == ArrayType::ALIGNED || ARRAY_TYPE_ == ArrayType::ALIGNED_AUTO, int>::type = 0> |
||
853 |
9408 |
static void alignAndCheckOffset(IO& io, OWNER_TYPE& owner, size_t index) |
|
854 |
{ |
||
855 |
9408 |
io.alignTo(8); |
|
856 |
9408 |
detail::checkOffset<ArrayExpressions>(owner, index, io.getBitPosition() / 8); |
|
857 |
9408 |
} |
|
858 |
|||
859 |
template <ArrayType ARRAY_TYPE_ = ARRAY_TYPE, |
||
860 |
typename std::enable_if< |
||
861 |
ARRAY_TYPE_ != ArrayType::ALIGNED && ARRAY_TYPE_ != ArrayType::ALIGNED_AUTO, int>::type = 0> |
||
862 |
5017 |
static void initializeOffset(OwnerType&, size_t, size_t&) |
|
863 |
5017 |
{} |
|
864 |
|||
865 |
template <ArrayType ARRAY_TYPE_ = ARRAY_TYPE, |
||
866 |
typename std::enable_if< |
||
867 |
ARRAY_TYPE_ == ArrayType::ALIGNED || ARRAY_TYPE_ == ArrayType::ALIGNED_AUTO, int>::type = 0> |
||
868 |
4704 |
static void initializeOffset(OwnerType& owner, size_t index, size_t& bitPosition) |
|
869 |
{ |
||
870 |
4704 |
bitPosition = alignTo(8, bitPosition); |
|
871 |
4704 |
detail::initializeOffset<ArrayExpressions>(owner, index, bitPosition / 8); |
|
872 |
4704 |
} |
|
873 |
|||
874 |
template <ArrayType ARRAY_TYPE_ = ARRAY_TYPE, |
||
875 |
typename std::enable_if< |
||
876 |
ARRAY_TYPE_ != ArrayType::AUTO && |
||
877 |
ARRAY_TYPE_ != ArrayType::ALIGNED_AUTO && |
||
878 |
ARRAY_TYPE_ != ArrayType::IMPLICIT, int>::type = 0> |
||
879 |
1585 |
static size_t readArrayLength(OwnerType&, BitStreamReader&, size_t arrayLength) |
|
880 |
{ |
||
881 |
1585 |
return arrayLength; |
|
882 |
} |
||
883 |
|||
884 |
template <ArrayType ARRAY_TYPE_ = ARRAY_TYPE, |
||
885 |
typename std::enable_if< |
||
886 |
ARRAY_TYPE_ == ArrayType::AUTO || ARRAY_TYPE_ == ArrayType::ALIGNED_AUTO, int>::type = 0> |
||
887 |
1584 |
static size_t readArrayLength(OwnerType&, BitStreamReader& in, size_t) |
|
888 |
{ |
||
889 |
1584 |
return in.readVarSize(); |
|
890 |
} |
||
891 |
|||
892 |
template <ArrayType ARRAY_TYPE_ = ARRAY_TYPE, |
||
893 |
typename std::enable_if<ARRAY_TYPE_ == ArrayType::IMPLICIT, int>::type = 0> |
||
894 |
144 |
static size_t readArrayLength(OwnerType& owner, BitStreamReader& in, size_t) |
|
895 |
{ |
||
896 |
static_assert(ARRAY_TYPE != ArrayType::IMPLICIT || ArrayTraits::IS_BITSIZEOF_CONSTANT, |
||
897 |
"Implicit array elements must have constant bit size!"); |
||
898 |
|||
899 |
144 |
const size_t remainingBits = in.getBufferBitSize() - in.getBitPosition(); |
|
900 |
144 |
return remainingBits / detail::arrayTraitsConstBitSizeOf<ArrayTraits>(owner); |
|
901 |
} |
||
902 |
|||
903 |
template <ArrayType ARRAY_TYPE_ = ARRAY_TYPE, |
||
904 |
typename std::enable_if< |
||
905 |
ARRAY_TYPE_ != ArrayType::AUTO && ARRAY_TYPE_ != ArrayType::ALIGNED_AUTO, int>::type = 0> |
||
906 |
1729 |
static void writeArrayLength(BitStreamWriter&, size_t) |
|
907 |
1729 |
{} |
|
908 |
|||
909 |
template <ArrayType ARRAY_TYPE_ = ARRAY_TYPE, |
||
910 |
typename std::enable_if< |
||
911 |
ARRAY_TYPE_ == ArrayType::AUTO || ARRAY_TYPE_ == ArrayType::ALIGNED_AUTO, int>::type = 0> |
||
912 |
1584 |
static void writeArrayLength(BitStreamWriter& out, size_t arrayLength) |
|
913 |
{ |
||
914 |
1584 |
out.writeVarSize(convertSizeToUInt32(arrayLength)); |
|
915 |
1584 |
} |
|
916 |
|||
917 |
template <ArrayType ARRAY_TYPE_ = ARRAY_TYPE, |
||
918 |
typename std::enable_if< |
||
919 |
ARRAY_TYPE_ != ArrayType::ALIGNED && ARRAY_TYPE_ != ArrayType::ALIGNED_AUTO, int>::type = 0> |
||
920 |
584 |
static size_t constBitSizeOfElements(size_t, size_t arrayLength, size_t elementBitSize) |
|
921 |
{ |
||
922 |
584 |
return arrayLength * elementBitSize; |
|
923 |
} |
||
924 |
|||
925 |
template <ArrayType ARRAY_TYPE_ = ARRAY_TYPE, |
||
926 |
typename std::enable_if< |
||
927 |
ARRAY_TYPE_ == ArrayType::ALIGNED || ARRAY_TYPE_ == ArrayType::ALIGNED_AUTO, int>::type = 0> |
||
928 |
480 |
static size_t constBitSizeOfElements(size_t bitPosition, size_t arrayLength, size_t elementBitSize) |
|
929 |
{ |
||
930 |
480 |
size_t endBitPosition = alignTo(8, bitPosition); |
|
931 |
480 |
endBitPosition += elementBitSize + (arrayLength - 1) * alignTo(8, elementBitSize); |
|
932 |
|||
933 |
480 |
return endBitPosition - bitPosition; |
|
934 |
} |
||
935 |
|||
936 |
template <typename ARRAY_TRAITS_ = ArrayTraits, |
||
937 |
typename std::enable_if<ARRAY_TRAITS_::IS_BITSIZEOF_CONSTANT, int>::type = 0> |
||
938 |
1424 |
size_t bitSizeOfImpl(const OwnerType& owner, size_t bitPosition) const |
|
939 |
{ |
||
940 |
1424 |
size_t endBitPosition = bitPosition; |
|
941 |
|||
942 |
1424 |
const size_t arrayLength = m_rawArray.size(); |
|
943 |
✓✓✗✓ ✗✓✗✓ ✗✓✗✓ ✗✓✗✓ ✗✓✗✓ ✗✓✗✗ ✗✓✗✓ ✗✓✗✓ ✗✓✗✓ ✗✓✗✓ ✗✓✗✓ ✗✓✗✓ ✗✓✗✓ ✗✓✗✓ ✗✓✗✓ ✗✓✗✓ ✗✓✗✓ ✗✓✗✓ ✗✓✗✓ ✗✓✗✓ ✗✓✗✓ ✗✓✗✓ ✗✓✗✓ ✗✓✗✓ ✗✓✗✓ ✗✓✗✓ ✗✓✗✓ ✗✓✗✓ ✗✓✗✓ ✗✓✗✓ ✗ |
1424 |
addBitSizeOfArrayLength(endBitPosition, arrayLength); |
944 |
|||
945 |
✓✗✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✓ ✓✓✓✓ ✓✓✓✓ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✓ ✓✓✓✓ ✓✓✓✓ ✗✗✓✗ ✓✗✓✗ ✓✗✗✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✗✗ ✗✓✗✓ ✗✓✗✓ ✓✗✓✗ ✓✗✓✗ ✓✗✗✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✗✗ ✓✗✓✗ ✓✗✓✗ ✗✗✗✓ ✗✓✗✓ ✗✓✓✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✗✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✗✗ ✓✓✓✓ ✓✓✓✓ ✗✗✓✗ ✓✗✓✗ ✓✗✗✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✗✗ ✓✓✓✓ ✓✓✓✓ |
1424 |
if (arrayLength > 0) |
946 |
{ |
||
947 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✗✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✗✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✗✗ ✓✗✓✗ ✓✗✓✗ ✗✗✗✗ ✗✗✗✗ ✗✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✗✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✗✗ ✗✗✗✗ ✗✗✗✗ ✓✗✓✗ ✓✗✓✗ ✓✗✗✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✗✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✗✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✗✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗ |
1064 |
const size_t elementBitSize = detail::arrayTraitsConstBitSizeOf<ArrayTraits>(owner); |
948 |
1064 |
endBitPosition += constBitSizeOfElements(endBitPosition, arrayLength, elementBitSize); |
|
949 |
} |
||
950 |
|||
951 |
1424 |
return endBitPosition - bitPosition; |
|
952 |
} |
||
953 |
|||
954 |
template <typename ARRAY_TRAITS_ = ArrayTraits, |
||
955 |
typename std::enable_if<!ARRAY_TRAITS_::IS_BITSIZEOF_CONSTANT, int>::type = 0> |
||
956 |
993 |
size_t bitSizeOfImpl(const OwnerType& owner, size_t bitPosition) const |
|
957 |
{ |
||
958 |
993 |
size_t endBitPosition = bitPosition; |
|
959 |
|||
960 |
993 |
const size_t arrayLength = m_rawArray.size(); |
|
961 |
✓✗✓✓ ✗✓✗✓ ✗✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✗✗ ✓✗✗✗ ✓✗✗✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ |
993 |
addBitSizeOfArrayLength(endBitPosition, arrayLength); |
962 |
|||
963 |
✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✗✗✓✓ ✓✓✓✓ ✗✗✓✓ ✓✓✓✓ ✗✗✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ |
3746 |
for (size_t index = 0; index < arrayLength; ++index) |
964 |
{ |
||
965 |
2753 |
alignBitPosition(endBitPosition); |
|
966 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ |
2753 |
endBitPosition += detail::arrayTraitsBitSizeOf<ArrayTraits>( |
967 |
2753 |
owner, endBitPosition, m_rawArray[index]); |
|
968 |
} |
||
969 |
|||
970 |
993 |
return endBitPosition - bitPosition; |
|
971 |
} |
||
972 |
|||
973 |
2417 |
size_t initializeOffsetsImpl(OwnerType& owner, size_t bitPosition) |
|
974 |
{ |
||
975 |
2417 |
size_t endBitPosition = bitPosition; |
|
976 |
|||
977 |
2417 |
const size_t arrayLength = m_rawArray.size(); |
|
978 |
✓✗✓✓ ✗✓✗✓ ✗✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✗✗ ✓✗✗✗ ✓✗✗✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✗✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ |
2417 |
addBitSizeOfArrayLength(endBitPosition, arrayLength); |
979 |
|||
980 |
✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✗✗✓✓ ✓✓✓✓ ✗✗✓✓ ✓✓✓✓ ✗✗✓✓ ✗✗✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✗✗✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✗✗✓✓ ✓✓✓✓ ✓✓✗✗ ✓✓✓✓ ✓✓✓✓ ✗✗✓✓ ✓✓✓✓ ✓✓✗✗ ✗✓✗✓ ✗✓✗✓ ✓✓✓✓ ✓✓✓✓ ✓✓✗✗ ✓✓✓✓ ✓✓✓✓ ✗✗✓✓ ✓✓✓✓ ✓✓✗✗ ✓✓✓✓ ✓✓✓✓ ✗✗✗✓ ✗✓✗✓ ✗✓✓✓ ✓✓✓✓ ✓✓✓✓ ✗✗✓✓ ✓✓✓✓ ✓✓✗✗ ✓✓✓✓ ✓✓✓✓ ✗✗✓✓ ✓✓✓✓ ✓✓✗✗ ✓✓✓✓ ✓✓✓✓ ✗✗✓✓ ✓✓✓✓ ✓✓✗✗ ✓✓✓✓ ✓✓✓✓ ✗✗✓✓ ✓✓✓✓ ✓✓✗✗ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ |
8330 |
for (size_t index = 0; index < arrayLength; ++index) |
981 |
{ |
||
982 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✗✗✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✗✗✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ |
5913 |
initializeOffset(owner, index, endBitPosition); |
983 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✗✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✗✗ ✗✗✗✗ ✗✗✗✗ ✓✗✓✗ ✓✗✓✗ ✓✗✗✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✗✗ ✓✗✓✗ ✓✗✓✗ ✗✗✗✗ ✗✗✗✗ ✗✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✗✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✗✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✗✗ ✓✗✓✗ ✓✗✓✗ ✗✗✓✗ ✓✗✓✗ ✓✗✗✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ |
5913 |
endBitPosition = detail::arrayTraitsInitializeOffsets<ArrayTraits>( |
984 |
5913 |
owner, endBitPosition, m_rawArray[index]); |
|
985 |
} |
||
986 |
|||
987 |
2417 |
return endBitPosition; |
|
988 |
} |
||
989 |
|||
990 |
2417 |
void readImpl(OwnerType& owner, BitStreamReader& in, size_t arrayLength) |
|
991 |
{ |
||
992 |
2417 |
size_t readLength = readArrayLength(owner, in, arrayLength); |
|
993 |
|||
994 |
2417 |
m_rawArray.clear(); |
|
995 |
2417 |
m_rawArray.reserve(readLength); |
|
996 |
✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✗✗✓✓ ✓✓✓✓ ✗✗✓✓ ✓✓✓✓ ✗✗✓✓ ✗✗✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✗✗✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✗✗✓✓ ✓✓✓✓ ✓✓✗✗ ✓✓✓✓ ✓✓✓✓ ✗✗✓✓ ✓✓✓✓ ✓✓✗✗ ✗✓✗✓ ✗✓✗✓ ✓✓✓✓ ✓✓✓✓ ✓✓✗✗ ✓✓✓✓ ✓✓✓✓ ✗✗✓✓ ✓✓✓✓ ✓✓✗✗ ✓✓✓✓ ✓✓✓✓ ✗✗✗✓ ✗✓✗✓ ✗✓✓✓ ✓✓✓✓ ✓✓✓✓ ✗✗✓✓ ✓✓✓✓ ✓✓✗✗ ✓✓✓✓ ✓✓✓✓ ✗✗✓✓ ✓✓✓✓ ✓✓✗✗ ✓✓✓✓ ✓✓✓✓ ✗✗✓✓ ✓✓✓✓ ✓✓✗✗ ✓✓✓✓ ✓✓✓✓ ✗✗✓✓ ✓✓✓✓ ✓✓✗✗ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ |
8329 |
for (size_t index = 0; index < readLength; ++index) |
997 |
{ |
||
998 |
5913 |
alignAndCheckOffset(in, owner, index); |
|
999 |
5913 |
detail::arrayTraitsRead<ArrayTraits>(owner, m_rawArray, in, index); |
|
1000 |
} |
||
1001 |
2416 |
} |
|
1002 |
|||
1003 |
2417 |
void writeImpl(const OwnerType& owner, BitStreamWriter& out) const |
|
1004 |
{ |
||
1005 |
2417 |
const size_t arrayLength = m_rawArray.size(); |
|
1006 |
2417 |
writeArrayLength(out, arrayLength); |
|
1007 |
|||
1008 |
✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✗✗✓✓ ✓✓✓✓ ✗✗✓✓ ✓✓✓✓ ✗✗✓✓ ✗✗✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✗✗✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✗✗✓✓ ✓✓✓✓ ✓✓✗✗ ✓✓✓✓ ✓✓✓✓ ✗✗✓✓ ✓✓✓✓ ✓✓✗✗ ✗✓✗✓ ✗✓✗✓ ✓✓✓✓ ✓✓✓✓ ✓✓✗✗ ✓✓✓✓ ✓✓✓✓ ✗✗✓✓ ✓✓✓✓ ✓✓✗✗ ✓✓✓✓ ✓✓✓✓ ✗✗✗✓ ✗✓✗✓ ✗✓✓✓ ✓✓✓✓ ✓✓✓✓ ✗✗✓✓ ✓✓✓✓ ✓✓✗✗ ✓✓✓✓ ✓✓✓✓ ✗✗✓✓ ✓✓✓✓ ✓✓✗✗ ✓✓✓✓ ✓✓✓✓ ✗✗✓✓ ✓✓✓✓ ✓✓✗✗ ✓✓✓✓ ✓✓✓✓ ✗✗✓✓ ✓✓✓✓ ✓✓✗✗ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ |
8330 |
for (size_t index = 0; index < arrayLength; ++index) |
1009 |
{ |
||
1010 |
5913 |
alignAndCheckOffset(out, owner, index); |
|
1011 |
✗✗✓✗ ✓✗✓✗ ✓✗ |
5913 |
detail::arrayTraitsWrite<ArrayTraits>(owner, out, m_rawArray[index]); |
1012 |
} |
||
1013 |
2417 |
} |
|
1014 |
|||
1015 |
using PackingContext = typename detail::packing_context_type<typename RawArray::value_type>::type; |
||
1016 |
|||
1017 |
896 |
size_t bitSizeOfPackedImpl(const OwnerType& owner, size_t bitPosition) const |
|
1018 |
{ |
||
1019 |
static_assert(ARRAY_TYPE != ArrayType::IMPLICIT, "Implicit array cannot be packed!"); |
||
1020 |
|||
1021 |
896 |
size_t endBitPosition = bitPosition; |
|
1022 |
|||
1023 |
896 |
const size_t arrayLength = m_rawArray.size(); |
|
1024 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ |
896 |
addBitSizeOfArrayLength(endBitPosition, arrayLength); |
1025 |
|||
1026 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✓✓✓ ✓✓✓✓ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✓✓✓ ✓✓✓✓ |
896 |
if (arrayLength > 0) |
1027 |
{ |
||
1028 |
832 |
PackingContext context; |
|
1029 |
|||
1030 |
✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ |
4640 |
for (size_t index = 0; index < arrayLength; ++index) |
1031 |
{ |
||
1032 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ |
3808 |
detail::packedArrayTraitsInitContext<PackedArrayTraits<ArrayTraits>>( |
1033 |
3808 |
owner, context, m_rawArray[index]); |
|
1034 |
} |
||
1035 |
|||
1036 |
✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ |
4640 |
for (size_t index = 0; index < arrayLength; ++index) |
1037 |
{ |
||
1038 |
3808 |
alignBitPosition(endBitPosition); |
|
1039 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ |
3808 |
endBitPosition += detail::packedArrayTraitsBitSizeOf<PackedArrayTraits<ArrayTraits>>( |
1040 |
3808 |
owner, context, endBitPosition, m_rawArray[index]); |
|
1041 |
} |
||
1042 |
} |
||
1043 |
|||
1044 |
896 |
return endBitPosition - bitPosition; |
|
1045 |
} |
||
1046 |
|||
1047 |
896 |
size_t initializeOffsetsPackedImpl(OwnerType& owner, size_t bitPosition) |
|
1048 |
{ |
||
1049 |
static_assert(ARRAY_TYPE != ArrayType::IMPLICIT, "Implicit array cannot be packed!"); |
||
1050 |
|||
1051 |
896 |
size_t endBitPosition = bitPosition; |
|
1052 |
|||
1053 |
896 |
const size_t arrayLength = m_rawArray.size(); |
|
1054 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ |
896 |
addBitSizeOfArrayLength(endBitPosition, arrayLength); |
1055 |
|||
1056 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✓✓✓ ✓✓✓✓ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✓✓✓ ✓✓✓✓ |
896 |
if (arrayLength > 0) |
1057 |
{ |
||
1058 |
832 |
PackingContext context; |
|
1059 |
|||
1060 |
✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ |
4640 |
for (size_t index = 0; index < arrayLength; ++index) |
1061 |
{ |
||
1062 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ |
3808 |
detail::packedArrayTraitsInitContext<PackedArrayTraits<ArrayTraits>>( |
1063 |
3808 |
owner, context, m_rawArray[index]); |
|
1064 |
} |
||
1065 |
|||
1066 |
✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ |
4640 |
for (size_t index = 0; index < arrayLength; ++index) |
1067 |
{ |
||
1068 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ |
3808 |
initializeOffset(owner, index, endBitPosition); |
1069 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ |
3808 |
endBitPosition = detail::packedArrayTraitsInitializeOffsets<PackedArrayTraits<ArrayTraits>>( |
1070 |
3808 |
owner, context, endBitPosition, m_rawArray[index]); |
|
1071 |
} |
||
1072 |
} |
||
1073 |
|||
1074 |
896 |
return endBitPosition; |
|
1075 |
} |
||
1076 |
|||
1077 |
896 |
void readPackedImpl(OwnerType& owner, BitStreamReader& in, size_t arrayLength = 0) |
|
1078 |
{ |
||
1079 |
static_assert(ARRAY_TYPE != ArrayType::IMPLICIT, "Implicit array cannot be packed!"); |
||
1080 |
|||
1081 |
896 |
size_t readLength = readArrayLength(owner, in, arrayLength); |
|
1082 |
|||
1083 |
896 |
m_rawArray.clear(); |
|
1084 |
|||
1085 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✓✓✓ ✓✓✓✓ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✓✓✓ ✓✓✓✓ |
896 |
if (readLength > 0) |
1086 |
{ |
||
1087 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ |
832 |
m_rawArray.reserve(readLength); |
1088 |
|||
1089 |
832 |
PackingContext context; |
|
1090 |
|||
1091 |
✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ |
4640 |
for (size_t index = 0; index < readLength; ++index) |
1092 |
{ |
||
1093 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ |
3808 |
alignAndCheckOffset(in, owner, index); |
1094 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ |
3808 |
detail::packedArrayTraitsRead<PackedArrayTraits<ArrayTraits>>( |
1095 |
owner, m_rawArray, context, in, index); |
||
1096 |
} |
||
1097 |
} |
||
1098 |
896 |
} |
|
1099 |
|||
1100 |
896 |
void writePackedImpl(const OwnerType& owner, BitStreamWriter& out) const |
|
1101 |
{ |
||
1102 |
static_assert(ARRAY_TYPE != ArrayType::IMPLICIT, "Implicit array cannot be packed!"); |
||
1103 |
|||
1104 |
896 |
const size_t arrayLength = m_rawArray.size(); |
|
1105 |
896 |
writeArrayLength(out, arrayLength); |
|
1106 |
|||
1107 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✓✓✓ ✓✓✓✓ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✓✓✓ ✓✓✓✓ |
896 |
if (arrayLength > 0) |
1108 |
{ |
||
1109 |
832 |
PackingContext context; |
|
1110 |
|||
1111 |
✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ |
4640 |
for (size_t index = 0; index < arrayLength; ++index) |
1112 |
{ |
||
1113 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ |
3808 |
detail::packedArrayTraitsInitContext<PackedArrayTraits<ArrayTraits>>( |
1114 |
3808 |
owner, context, m_rawArray[index]); |
|
1115 |
} |
||
1116 |
|||
1117 |
✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ ✓✓✓✓ |
4640 |
for (size_t index = 0; index < arrayLength; ++index) |
1118 |
{ |
||
1119 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ |
3808 |
alignAndCheckOffset(out, owner, index); |
1120 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ |
3808 |
detail::packedArrayTraitsWrite<PackedArrayTraits<ArrayTraits>>( |
1121 |
3808 |
owner, context, out, m_rawArray[index]); |
|
1122 |
} |
||
1123 |
} |
||
1124 |
896 |
} |
|
1125 |
|||
1126 |
RawArray m_rawArray; |
||
1127 |
}; |
||
1128 |
|||
1129 |
/** |
||
1130 |
* Helper for creating an optional array within templated field constructor, where the raw array can be |
||
1131 |
* actually the NullOpt. |
||
1132 |
*/ |
||
1133 |
template <typename ARRAY, typename RAW_ARRAY> |
||
1134 |
1 |
ARRAY createOptionalArray(RAW_ARRAY&& rawArray) |
|
1135 |
{ |
||
1136 |
1 |
return ARRAY(std::forward<RAW_ARRAY>(rawArray)); |
|
1137 |
} |
||
1138 |
|||
1139 |
/** |
||
1140 |
* Overload for NullOpt. |
||
1141 |
*/ |
||
1142 |
template <typename ARRAY> |
||
1143 |
14 |
NullOptType createOptionalArray(NullOptType) |
|
1144 |
{ |
||
1145 |
14 |
return NullOpt; |
|
1146 |
} |
||
1147 |
|||
1148 |
} // namespace zserio |
||
1149 |
|||
1150 |
#endif // ZSERIO_ARRAY_H_INC |
Generated by: GCOVR (Version 4.2) |