Zserio C++ runtime library  1.4.0
Built for Zserio 2.18.1
Array.h
Go to the documentation of this file.
1 #ifndef ZSERIO_ARRAY_H_INC
2 #define ZSERIO_ARRAY_H_INC
3 
4 #include <cstdlib>
5 #include <type_traits>
6 
8 #include "zserio/ArrayTraits.h"
10 #include "zserio/BitStreamReader.h"
11 #include "zserio/BitStreamWriter.h"
12 #include "zserio/DeltaContext.h"
13 #include "zserio/SizeConvertUtil.h"
14 #include "zserio/Traits.h"
15 #include "zserio/Types.h"
16 #include "zserio/UniquePtr.h"
17 
18 namespace zserio
19 {
20 
21 namespace detail
22 {
23 
24 // array expressions for arrays which do not need expressions
25 struct DummyArrayExpressions
26 {};
27 
28 // array owner for arrays which do not need the owner
29 struct DummyArrayOwner
30 {};
31 
32 // helper trait to choose the owner type for an array from combination of ARRAY_TRAITS and ARRAY_EXPRESSIONS
33 template <typename ARRAY_TRAITS, typename ARRAY_EXPRESSIONS, typename = void>
34 struct array_owner_type
35 {
36  using type = DummyArrayOwner;
37 };
38 
39 template <typename ARRAY_TRAITS, typename ARRAY_EXPRESSIONS>
40 struct array_owner_type<ARRAY_TRAITS, ARRAY_EXPRESSIONS,
41  typename std::enable_if<has_owner_type<ARRAY_TRAITS>::value>::type>
42 {
43  using type = typename ARRAY_TRAITS::OwnerType;
44 };
45 
46 template <typename ARRAY_TRAITS, typename ARRAY_EXPRESSIONS>
47 struct array_owner_type<ARRAY_TRAITS, ARRAY_EXPRESSIONS,
48  typename std::enable_if<!has_owner_type<ARRAY_TRAITS>::value &&
49  has_owner_type<ARRAY_EXPRESSIONS>::value>::type>
50 {
51  using type = typename ARRAY_EXPRESSIONS::OwnerType;
52 };
53 
54 // helper trait to choose packing context type for an array from an element type T
55 template <typename T, typename = void>
56 struct packing_context_type
57 {
58  using type = DeltaContext;
59 };
60 
61 template <typename T>
62 struct packing_context_type<T, typename std::enable_if<has_zserio_packing_context<T>::value>::type>
63 {
64  using type = typename T::ZserioPackingContext;
65 };
66 
67 // calls the initializeOffset static method on ARRAY_EXPRESSIONS if available
68 template <typename ARRAY_EXPRESSIONS, typename OWNER_TYPE,
69  typename std::enable_if<has_initialize_offset<ARRAY_EXPRESSIONS>::value, int>::type = 0>
70 void initializeOffset(OWNER_TYPE& owner, size_t index, size_t bitPosition)
71 {
72  ARRAY_EXPRESSIONS::initializeOffset(owner, index, bitPosition);
73 }
74 
75 template <typename ARRAY_EXPRESSIONS, typename OWNER_TYPE,
76  typename std::enable_if<!has_initialize_offset<ARRAY_EXPRESSIONS>::value, int>::type = 0>
77 void initializeOffset(OWNER_TYPE&, size_t, size_t)
78 {}
79 
80 // calls the checkOffset static method on ARRAY_EXPRESSIONS if available
81 template <typename ARRAY_EXPRESSIONS, typename OWNER_TYPE,
82  typename std::enable_if<has_check_offset<ARRAY_EXPRESSIONS>::value, int>::type = 0>
83 void checkOffset(const OWNER_TYPE& owner, size_t index, size_t bitPosition)
84 {
85  ARRAY_EXPRESSIONS::checkOffset(owner, index, bitPosition);
86 }
87 
88 template <typename ARRAY_EXPRESSIONS, typename OWNER_TYPE,
89  typename std::enable_if<!has_check_offset<ARRAY_EXPRESSIONS>::value, int>::type = 0>
90 void checkOffset(const OWNER_TYPE&, size_t, size_t)
91 {}
92 
93 // call the initContext method properly on packed array traits
94 template <typename PACKED_ARRAY_TRAITS, typename OWNER_TYPE, typename PACKING_CONTEXT,
95  typename std::enable_if<has_owner_type<PACKED_ARRAY_TRAITS>::value &&
96  !std::is_scalar<typename PACKED_ARRAY_TRAITS::ElementType>::value,
97  int>::type = 0>
98 void packedArrayTraitsInitContext(const OWNER_TYPE& owner, PACKING_CONTEXT& context,
99  const typename PACKED_ARRAY_TRAITS::ElementType& element)
100 {
101  PACKED_ARRAY_TRAITS::initContext(owner, context, element);
102 }
103 
104 template <typename PACKED_ARRAY_TRAITS, typename OWNER_TYPE, typename PACKING_CONTEXT,
105  typename std::enable_if<has_owner_type<PACKED_ARRAY_TRAITS>::value &&
106  std::is_scalar<typename PACKED_ARRAY_TRAITS::ElementType>::value,
107  int>::type = 0>
108 void packedArrayTraitsInitContext(
109  const OWNER_TYPE& owner, PACKING_CONTEXT& context, typename PACKED_ARRAY_TRAITS::ElementType element)
110 {
111  PACKED_ARRAY_TRAITS::initContext(owner, context, element);
112 }
113 
114 template <typename PACKED_ARRAY_TRAITS, typename OWNER_TYPE, typename PACKING_CONTEXT,
115  typename std::enable_if<!has_owner_type<PACKED_ARRAY_TRAITS>::value &&
116  !std::is_scalar<typename PACKED_ARRAY_TRAITS::ElementType>::value,
117  int>::type = 0>
118 void packedArrayTraitsInitContext(
119  const OWNER_TYPE&, PACKING_CONTEXT& context, const typename PACKED_ARRAY_TRAITS::ElementType& element)
120 {
121  PACKED_ARRAY_TRAITS::initContext(context, element);
122 }
123 
124 template <typename PACKED_ARRAY_TRAITS, typename OWNER_TYPE, typename PACKING_CONTEXT,
125  typename std::enable_if<!has_owner_type<PACKED_ARRAY_TRAITS>::value &&
126  std::is_scalar<typename PACKED_ARRAY_TRAITS::ElementType>::value,
127  int>::type = 0>
128 void packedArrayTraitsInitContext(
129  const OWNER_TYPE&, PACKING_CONTEXT& context, typename PACKED_ARRAY_TRAITS::ElementType element)
130 {
131  PACKED_ARRAY_TRAITS::initContext(context, element);
132 }
133 
134 // calls the bitSizeOf method properly on array traits which have constant bit size
135 template <typename ARRAY_TRAITS, typename OWNER_TYPE,
136  typename std::enable_if<ARRAY_TRAITS::IS_BITSIZEOF_CONSTANT && has_owner_type<ARRAY_TRAITS>::value,
137  int>::type = 0>
138 size_t arrayTraitsConstBitSizeOf(const OWNER_TYPE& owner)
139 {
140  return ARRAY_TRAITS::bitSizeOf(owner);
141 }
142 
143 template <typename ARRAY_TRAITS, typename OWNER_TYPE,
144  typename std::enable_if<ARRAY_TRAITS::IS_BITSIZEOF_CONSTANT && !has_owner_type<ARRAY_TRAITS>::value,
145  int>::type = 0>
146 size_t arrayTraitsConstBitSizeOf(const OWNER_TYPE&)
147 {
148  return ARRAY_TRAITS::bitSizeOf();
149 }
150 
151 // calls the bitSizeOf method properly on array traits which haven't constant bit size
152 template <typename ARRAY_TRAITS, typename OWNER_TYPE,
153  typename std::enable_if<has_owner_type<ARRAY_TRAITS>::value, int>::type = 0>
154 size_t arrayTraitsBitSizeOf(
155  const OWNER_TYPE& owner, size_t bitPosition, const typename ARRAY_TRAITS::ElementType& element)
156 {
157  return ARRAY_TRAITS::bitSizeOf(owner, bitPosition, element);
158 }
159 
160 template <typename ARRAY_TRAITS, typename OWNER_TYPE,
161  typename std::enable_if<!has_owner_type<ARRAY_TRAITS>::value, int>::type = 0>
162 size_t arrayTraitsBitSizeOf(
163  const OWNER_TYPE&, size_t bitPosition, const typename ARRAY_TRAITS::ElementType& element)
164 {
165  return ARRAY_TRAITS::bitSizeOf(bitPosition, element);
166 }
167 
168 // calls the bitSizeOf method properly on packed array traits which haven't constant bit size
169 template <typename PACKED_ARRAY_TRAITS, typename OWNER_TYPE, typename PACKING_CONTEXT,
170  typename std::enable_if<has_owner_type<PACKED_ARRAY_TRAITS>::value, int>::type = 0>
171 size_t packedArrayTraitsBitSizeOf(const OWNER_TYPE& owner, PACKING_CONTEXT& context, size_t bitPosition,
172  const typename PACKED_ARRAY_TRAITS::ElementType& element)
173 {
174  return PACKED_ARRAY_TRAITS::bitSizeOf(owner, context, bitPosition, element);
175 }
176 
177 template <typename PACKED_ARRAY_TRAITS, typename OWNER_TYPE, typename PACKING_CONTEXT,
178  typename std::enable_if<!has_owner_type<PACKED_ARRAY_TRAITS>::value, int>::type = 0>
179 size_t packedArrayTraitsBitSizeOf(const OWNER_TYPE&, PACKING_CONTEXT& context, size_t bitPosition,
180  const typename PACKED_ARRAY_TRAITS::ElementType& element)
181 {
182  return PACKED_ARRAY_TRAITS::bitSizeOf(context, bitPosition, element);
183 }
184 
185 // calls the initializeOffsets method properly on array traits
186 template <typename ARRAY_TRAITS, typename OWNER_TYPE,
187  typename std::enable_if<has_owner_type<ARRAY_TRAITS>::value, int>::type = 0>
188 size_t arrayTraitsInitializeOffsets(
189  OWNER_TYPE& owner, size_t bitPosition, typename ARRAY_TRAITS::ElementType& element)
190 {
191  return ARRAY_TRAITS::initializeOffsets(owner, bitPosition, element);
192 }
193 
194 template <typename ARRAY_TRAITS, typename OWNER_TYPE,
195  typename std::enable_if<!has_owner_type<ARRAY_TRAITS>::value &&
196  !std::is_scalar<typename ARRAY_TRAITS::ElementType>::value,
197  int>::type = 0>
198 size_t arrayTraitsInitializeOffsets(
199  OWNER_TYPE&, size_t bitPosition, const typename ARRAY_TRAITS::ElementType& element)
200 {
201  return ARRAY_TRAITS::initializeOffsets(bitPosition, element);
202 }
203 
204 template <typename ARRAY_TRAITS, typename OWNER_TYPE,
205  typename std::enable_if<!has_owner_type<ARRAY_TRAITS>::value &&
206  std::is_scalar<typename ARRAY_TRAITS::ElementType>::value,
207  int>::type = 0>
208 size_t arrayTraitsInitializeOffsets(OWNER_TYPE&, size_t bitPosition, typename ARRAY_TRAITS::ElementType element)
209 {
210  return ARRAY_TRAITS::initializeOffsets(bitPosition, element);
211 }
212 
213 // calls the initializeOffsets method properly on packed array traits
214 template <typename PACKED_ARRAY_TRAITS, typename OWNER_TYPE, typename PACKING_CONTEXT,
215  typename std::enable_if<has_owner_type<PACKED_ARRAY_TRAITS>::value, int>::type = 0>
216 size_t packedArrayTraitsInitializeOffsets(OWNER_TYPE& owner, PACKING_CONTEXT& context, size_t bitPosition,
217  typename PACKED_ARRAY_TRAITS::ElementType& element)
218 {
219  return PACKED_ARRAY_TRAITS::initializeOffsets(owner, context, bitPosition, element);
220 }
221 
222 template <typename PACKED_ARRAY_TRAITS, typename OWNER_TYPE, typename PACKING_CONTEXT,
223  typename std::enable_if<!has_owner_type<PACKED_ARRAY_TRAITS>::value &&
224  !std::is_scalar<typename PACKED_ARRAY_TRAITS::ElementType>::value,
225  int>::type = 0>
226 size_t packedArrayTraitsInitializeOffsets(OWNER_TYPE&, PACKING_CONTEXT& context, size_t bitPosition,
227  const typename PACKED_ARRAY_TRAITS::ElementType& element)
228 {
229  return PACKED_ARRAY_TRAITS::initializeOffsets(context, bitPosition, element);
230 }
231 
232 template <typename PACKED_ARRAY_TRAITS, typename OWNER_TYPE, typename PACKING_CONTEXT,
233  typename std::enable_if<!has_owner_type<PACKED_ARRAY_TRAITS>::value &&
234  std::is_scalar<typename PACKED_ARRAY_TRAITS::ElementType>::value,
235  int>::type = 0>
236 size_t packedArrayTraitsInitializeOffsets(OWNER_TYPE&, PACKING_CONTEXT& context, size_t bitPosition,
237  typename PACKED_ARRAY_TRAITS::ElementType element)
238 {
239  return PACKED_ARRAY_TRAITS::initializeOffsets(context, bitPosition, element);
240 }
241 
242 // calls the read method properly on array traits
243 template <typename ARRAY_TRAITS, typename OWNER_TYPE, typename RAW_ARRAY,
244  typename std::enable_if<has_owner_type<ARRAY_TRAITS>::value && !has_allocator<ARRAY_TRAITS>::value,
245  int>::type = 0>
246 void arrayTraitsRead(const OWNER_TYPE& owner, RAW_ARRAY& rawArray, BitStreamReader& in, size_t index)
247 {
248  rawArray.push_back(ARRAY_TRAITS::read(owner, in, index));
249 }
250 
251 template <typename ARRAY_TRAITS, typename OWNER_TYPE, typename RAW_ARRAY,
252  typename std::enable_if<has_owner_type<ARRAY_TRAITS>::value && has_allocator<ARRAY_TRAITS>::value,
253  int>::type = 0>
254 void arrayTraitsRead(OWNER_TYPE& owner, RAW_ARRAY& rawArray, BitStreamReader& in, size_t index)
255 {
256  ARRAY_TRAITS::read(owner, rawArray, in, index);
257 }
258 
259 template <typename ARRAY_TRAITS, typename OWNER_TYPE, typename RAW_ARRAY,
260  typename std::enable_if<!has_owner_type<ARRAY_TRAITS>::value && !has_allocator<ARRAY_TRAITS>::value,
261  int>::type = 0>
262 void arrayTraitsRead(const OWNER_TYPE&, RAW_ARRAY& rawArray, BitStreamReader& in, size_t index)
263 {
264  rawArray.push_back(ARRAY_TRAITS::read(in, index));
265 }
266 
267 template <typename ARRAY_TRAITS, typename OWNER_TYPE, typename RAW_ARRAY,
268  typename std::enable_if<!has_owner_type<ARRAY_TRAITS>::value && has_allocator<ARRAY_TRAITS>::value,
269  int>::type = 0>
270 void arrayTraitsRead(const OWNER_TYPE&, RAW_ARRAY& rawArray, BitStreamReader& in, size_t index)
271 {
272  ARRAY_TRAITS::read(rawArray, in, index);
273 }
274 
275 // calls the read method properly on packed array traits
276 template <typename PACKED_ARRAY_TRAITS, typename OWNER_TYPE, typename RAW_ARRAY, typename PACKING_CONTEXT,
277  typename std::enable_if<has_owner_type<PACKED_ARRAY_TRAITS>::value &&
278  has_allocator<PACKED_ARRAY_TRAITS>::value,
279  int>::type = 0>
280 void packedArrayTraitsRead(
281  OWNER_TYPE& owner, RAW_ARRAY& rawArray, PACKING_CONTEXT& context, BitStreamReader& in, size_t index)
282 {
283  PACKED_ARRAY_TRAITS::read(owner, rawArray, context, in, index);
284 }
285 
286 template <typename PACKED_ARRAY_TRAITS, typename OWNER_TYPE, typename RAW_ARRAY, typename PACKING_CONTEXT,
287  typename std::enable_if<has_owner_type<PACKED_ARRAY_TRAITS>::value &&
288  !has_allocator<PACKED_ARRAY_TRAITS>::value,
289  int>::type = 0>
290 void packedArrayTraitsRead(const OWNER_TYPE& owner, RAW_ARRAY& rawArray, PACKING_CONTEXT& context,
291  BitStreamReader& in, size_t index)
292 {
293  rawArray.push_back(PACKED_ARRAY_TRAITS::read(owner, context, in, index));
294 }
295 
296 // note: types which doesn't have owner and have allocator are never packed (e.g. string, bytes ...)
297 // and thus such specialization is not needed
298 
299 template <typename PACKED_ARRAY_TRAITS, typename OWNER_TYPE, typename RAW_ARRAY, typename PACKING_CONTEXT,
300  typename std::enable_if<!has_owner_type<PACKED_ARRAY_TRAITS>::value &&
301  !has_allocator<PACKED_ARRAY_TRAITS>::value,
302  int>::type = 0>
303 void packedArrayTraitsRead(
304  const OWNER_TYPE&, RAW_ARRAY& rawArray, PACKING_CONTEXT& context, BitStreamReader& in, size_t index)
305 {
306  rawArray.push_back(PACKED_ARRAY_TRAITS::read(context, in, index));
307 }
308 
309 // call the write method properly on array traits
310 template <typename ARRAY_TRAITS, typename OWNER_TYPE,
311  typename std::enable_if<has_owner_type<ARRAY_TRAITS>::value, int>::type = 0>
312 void arrayTraitsWrite(
313  const OWNER_TYPE& owner, BitStreamWriter& out, const typename ARRAY_TRAITS::ElementType& element)
314 {
315  ARRAY_TRAITS::write(owner, out, element);
316 }
317 
318 template <typename ARRAY_TRAITS, typename OWNER_TYPE,
319  typename std::enable_if<!has_owner_type<ARRAY_TRAITS>::value, int>::type = 0>
320 void arrayTraitsWrite(
321  const OWNER_TYPE&, BitStreamWriter& out, const typename ARRAY_TRAITS::ElementType& element)
322 {
323  ARRAY_TRAITS::write(out, element);
324 }
325 
326 // call the write method properly on packed array traits
327 template <typename PACKED_ARRAY_TRAITS, typename OWNER_TYPE, typename PACKING_CONTEXT,
328  typename std::enable_if<has_owner_type<PACKED_ARRAY_TRAITS>::value, int>::type = 0>
329 void packedArrayTraitsWrite(const OWNER_TYPE& owner, PACKING_CONTEXT& context, BitStreamWriter& out,
330  const typename PACKED_ARRAY_TRAITS::ElementType& element)
331 {
332  PACKED_ARRAY_TRAITS::write(owner, context, out, element);
333 }
334 
335 template <typename PACKED_ARRAY_TRAITS, typename OWNER_TYPE, typename PACKING_CONTEXT,
336  typename std::enable_if<!has_owner_type<PACKED_ARRAY_TRAITS>::value, int>::type = 0>
337 void packedArrayTraitsWrite(const OWNER_TYPE&, PACKING_CONTEXT& context, BitStreamWriter& out,
338  const typename PACKED_ARRAY_TRAITS::ElementType& element)
339 {
340  PACKED_ARRAY_TRAITS::write(context, out, element);
341 }
342 
343 } // namespace detail
344 
349 {
354  ALIGNED_AUTO
355 };
356 
364 template <typename RAW_ARRAY, typename ARRAY_TRAITS, ArrayType ARRAY_TYPE,
365  typename ARRAY_EXPRESSIONS = detail::DummyArrayExpressions>
366 class Array
367 {
368 public:
370  using RawArray = RAW_ARRAY;
371 
373  using ArrayTraits = ARRAY_TRAITS;
374 
376  using ArrayExpressions = ARRAY_EXPRESSIONS;
377 
384  using OwnerType = typename detail::array_owner_type<ArrayTraits, ArrayExpressions>::type;
385 
387  using allocator_type = typename RawArray::allocator_type;
388 
394  explicit Array(const allocator_type& allocator = allocator_type()) :
395  m_rawArray(allocator)
396  {}
397 
403  explicit Array(const RawArray& rawArray) :
404  m_rawArray(rawArray)
405  {}
406 
412  explicit Array(RawArray&& rawArray) :
413  m_rawArray(std::move(rawArray))
414  {}
415 
421  ~Array() = default;
422  Array(const Array& other) = default;
423  Array& operator=(const Array& other) = default;
424  Array(Array&& other) = default;
425  Array& operator=(Array&& other) = default;
437  template <typename T = typename RAW_ARRAY::value_type,
438  typename std::enable_if<std::is_constructible<T, NoInitT, T>::value, int>::type = 0>
439  Array(NoInitT, const Array& other) :
440  Array(std::allocator_traits<allocator_type>::select_on_container_copy_construction(
441  other.m_rawArray.get_allocator()))
442  {
443  m_rawArray.reserve(other.m_rawArray.size());
444  for (const auto& value : other.m_rawArray)
445  {
446  m_rawArray.emplace_back(NoInit, value);
447  }
448  }
449 
457  template <typename T = typename RAW_ARRAY::value_type,
458  typename std::enable_if<std::is_constructible<T, NoInitT, T>::value, int>::type = 0>
459  Array& assign(NoInitT, const Array& other)
460  {
461  const RawArray rawArray(other.m_rawArray.get_allocator());
462  m_rawArray = rawArray; // copy assign to get correct allocator propagation behaviour
463  m_rawArray.reserve(other.m_rawArray.size());
464  for (const auto& value : other.m_rawArray)
465  {
466  m_rawArray.emplace_back(NoInit, value);
467  }
468 
469  return *this;
470  }
471 
479  template <typename T = typename RAW_ARRAY::value_type,
480  typename std::enable_if<std::is_constructible<T, NoInitT, T>::value, int>::type = 0>
481  Array(NoInitT, Array&& other) :
482  Array(std::move(other))
483  {}
484 
493  template <typename T = typename RAW_ARRAY::value_type,
494  typename std::enable_if<std::is_constructible<T, NoInitT, T>::value, int>::type = 0>
496  {
497  return operator=(std::move(other));
498  }
499 
506  Array(PropagateAllocatorT, const Array& other, const allocator_type& allocator) :
507  m_rawArray(allocatorPropagatingCopy(other.m_rawArray, allocator))
508  {}
509 
517  template <typename T = typename RAW_ARRAY::value_type,
518  typename std::enable_if<std::is_constructible<T, NoInitT, T>::value, int>::type = 0>
519  Array(PropagateAllocatorT, NoInitT, const Array& other, const allocator_type& allocator) :
520  m_rawArray(allocatorPropagatingCopy(NoInit, other.m_rawArray, allocator))
521  {}
522 
530  bool operator==(const Array& other) const
531  {
532  return m_rawArray == other.m_rawArray;
533  }
534 
542  bool operator<(const Array& other) const
543  {
544  return m_rawArray < other.m_rawArray;
545  }
546 
552  uint32_t hashCode() const
553  {
554  return calcHashCode(HASH_SEED, m_rawArray);
555  }
556 
562  const RawArray& getRawArray() const
563  {
564  return m_rawArray;
565  }
566 
573  {
574  return m_rawArray;
575  }
576 
582  template <typename ARRAY_EXPRESSIONS_ = ArrayExpressions,
583  typename std::enable_if<has_initialize_element<ARRAY_EXPRESSIONS_>::value, int>::type = 0>
585  {
586  size_t index = 0;
587  for (auto&& element : m_rawArray)
588  {
589  ArrayExpressions::initializeElement(owner, element, index);
590  index++;
591  }
592  }
593 
603  template <typename OWNER_TYPE_ = OwnerType,
604  typename std::enable_if<std::is_same<OWNER_TYPE_, detail::DummyArrayOwner>::value, int>::type = 0>
605  size_t bitSizeOf(size_t bitPosition) const
606  {
607  return bitSizeOfImpl(detail::DummyArrayOwner(), bitPosition);
608  }
609 
620  template <typename OWNER_TYPE_ = OwnerType,
621  typename std::enable_if<!std::is_same<OWNER_TYPE_, detail::DummyArrayOwner>::value, int>::type = 0>
622  size_t bitSizeOf(const OwnerType& owner, size_t bitPosition) const
623  {
624  return bitSizeOfImpl(owner, bitPosition);
625  }
626 
636  template <typename OWNER_TYPE_ = OwnerType,
637  typename std::enable_if<std::is_same<OWNER_TYPE_, detail::DummyArrayOwner>::value, int>::type = 0>
638  size_t initializeOffsets(size_t bitPosition)
639  {
640  detail::DummyArrayOwner owner;
641  return initializeOffsetsImpl(owner, bitPosition);
642  }
643 
654  template <typename OWNER_TYPE_ = OwnerType,
655  typename std::enable_if<!std::is_same<OWNER_TYPE_, detail::DummyArrayOwner>::value, int>::type = 0>
656  size_t initializeOffsets(OwnerType& owner, size_t bitPosition)
657  {
658  return initializeOffsetsImpl(owner, bitPosition);
659  }
660 
669  template <typename OWNER_TYPE_ = OwnerType,
670  typename std::enable_if<std::is_same<OWNER_TYPE_, detail::DummyArrayOwner>::value, int>::type = 0>
671  void read(BitStreamReader& in, size_t arrayLength = 0)
672  {
673  detail::DummyArrayOwner owner;
674  readImpl(owner, in, arrayLength);
675  }
676 
686  template <typename OWNER_TYPE_ = OwnerType,
687  typename std::enable_if<!std::is_same<OWNER_TYPE_, detail::DummyArrayOwner>::value, int>::type = 0>
688  void read(OwnerType& owner, BitStreamReader& in, size_t arrayLength = 0)
689  {
690  readImpl(owner, in, arrayLength);
691  }
692 
700  template <typename OWNER_TYPE_ = OwnerType,
701  typename std::enable_if<std::is_same<OWNER_TYPE_, detail::DummyArrayOwner>::value, int>::type = 0>
702  void write(BitStreamWriter& out) const
703  {
704  writeImpl(detail::DummyArrayOwner(), out);
705  }
706 
715  template <typename OWNER_TYPE_ = OwnerType,
716  typename std::enable_if<!std::is_same<OWNER_TYPE_, detail::DummyArrayOwner>::value, int>::type = 0>
717  void write(const OwnerType& owner, BitStreamWriter& out) const
718  {
719  writeImpl(owner, out);
720  }
721 
731  template <typename OWNER_TYPE_ = OwnerType,
732  typename std::enable_if<std::is_same<OWNER_TYPE_, detail::DummyArrayOwner>::value, int>::type = 0>
733  size_t bitSizeOfPacked(size_t bitPosition) const
734  {
735  return bitSizeOfPackedImpl(detail::DummyArrayOwner(), bitPosition);
736  }
737 
748  template <typename OWNER_TYPE_ = OwnerType,
749  typename std::enable_if<!std::is_same<OWNER_TYPE_, detail::DummyArrayOwner>::value, int>::type = 0>
750  size_t bitSizeOfPacked(const OwnerType& ownerType, size_t bitPosition) const
751  {
752  return bitSizeOfPackedImpl(ownerType, bitPosition);
753  }
754 
764  template <typename OWNER_TYPE_ = OwnerType,
765  typename std::enable_if<std::is_same<OWNER_TYPE_, detail::DummyArrayOwner>::value, int>::type = 0>
766  size_t initializeOffsetsPacked(size_t bitPosition)
767  {
768  detail::DummyArrayOwner owner;
769  return initializeOffsetsPackedImpl(owner, bitPosition);
770  }
771 
782  template <typename OWNER_TYPE_ = OwnerType,
783  typename std::enable_if<!std::is_same<OWNER_TYPE_, detail::DummyArrayOwner>::value, int>::type = 0>
784  size_t initializeOffsetsPacked(OwnerType& owner, size_t bitPosition)
785  {
786  return initializeOffsetsPackedImpl(owner, bitPosition);
787  }
788 
797  template <typename OWNER_TYPE_ = OwnerType,
798  typename std::enable_if<std::is_same<OWNER_TYPE_, detail::DummyArrayOwner>::value, int>::type = 0>
799  void readPacked(BitStreamReader& in, size_t arrayLength = 0)
800  {
801  detail::DummyArrayOwner owner;
802  readPackedImpl(owner, in, arrayLength);
803  }
804 
814  template <typename OWNER_TYPE_ = OwnerType,
815  typename std::enable_if<!std::is_same<OWNER_TYPE_, detail::DummyArrayOwner>::value, int>::type = 0>
816  void readPacked(OwnerType& owner, BitStreamReader& in, size_t arrayLength = 0)
817  {
818  readPackedImpl(owner, in, arrayLength);
819  }
820 
828  template <typename OWNER_TYPE_ = OwnerType,
829  typename std::enable_if<std::is_same<OWNER_TYPE_, detail::DummyArrayOwner>::value, int>::type = 0>
830  void writePacked(BitStreamWriter& out) const
831  {
832  writePackedImpl(detail::DummyArrayOwner(), out);
833  }
834 
843  template <typename OWNER_TYPE_ = OwnerType,
844  typename std::enable_if<!std::is_same<OWNER_TYPE_, detail::DummyArrayOwner>::value, int>::type = 0>
845  void writePacked(const OwnerType& owner, BitStreamWriter& out) const
846  {
847  writePackedImpl(owner, out);
848  }
849 
850 private:
851  template <ArrayType ARRAY_TYPE_ = ARRAY_TYPE,
852  typename std::enable_if<ARRAY_TYPE_ != ArrayType::AUTO && ARRAY_TYPE_ != ArrayType::ALIGNED_AUTO,
853  int>::type = 0>
854  static void addBitSizeOfArrayLength(size_t&, size_t)
855  {}
856 
857  template <ArrayType ARRAY_TYPE_ = ARRAY_TYPE,
858  typename std::enable_if<ARRAY_TYPE_ == ArrayType::AUTO || ARRAY_TYPE_ == ArrayType::ALIGNED_AUTO,
859  int>::type = 0>
860  static void addBitSizeOfArrayLength(size_t& bitPosition, size_t arrayLength)
861  {
862  bitPosition += bitSizeOfVarSize(convertSizeToUInt32(arrayLength));
863  }
864 
865  template <ArrayType ARRAY_TYPE_ = ARRAY_TYPE,
866  typename std::enable_if<ARRAY_TYPE_ != ArrayType::ALIGNED && ARRAY_TYPE_ != ArrayType::ALIGNED_AUTO,
867  int>::type = 0>
868  static void alignBitPosition(size_t&)
869  {}
870 
871  template <ArrayType ARRAY_TYPE_ = ARRAY_TYPE,
872  typename std::enable_if<ARRAY_TYPE_ == ArrayType::ALIGNED || ARRAY_TYPE_ == ArrayType::ALIGNED_AUTO,
873  int>::type = 0>
874  static void alignBitPosition(size_t& bitPosition)
875  {
876  bitPosition = alignTo(8, bitPosition);
877  }
878 
879  template <typename IO, typename OWNER_TYPE, ArrayType ARRAY_TYPE_ = ARRAY_TYPE,
880  typename std::enable_if<ARRAY_TYPE_ != ArrayType::ALIGNED && ARRAY_TYPE_ != ArrayType::ALIGNED_AUTO,
881  int>::type = 0>
882  static void alignAndCheckOffset(IO&, OWNER_TYPE&, size_t)
883  {}
884 
885  template <typename IO, typename OWNER_TYPE, ArrayType ARRAY_TYPE_ = ARRAY_TYPE,
886  typename std::enable_if<ARRAY_TYPE_ == ArrayType::ALIGNED || ARRAY_TYPE_ == ArrayType::ALIGNED_AUTO,
887  int>::type = 0>
888  static void alignAndCheckOffset(IO& io, OWNER_TYPE& owner, size_t index)
889  {
890  io.alignTo(8);
891  detail::checkOffset<ArrayExpressions>(owner, index, io.getBitPosition() / 8);
892  }
893 
894  template <ArrayType ARRAY_TYPE_ = ARRAY_TYPE,
895  typename std::enable_if<ARRAY_TYPE_ != ArrayType::ALIGNED && ARRAY_TYPE_ != ArrayType::ALIGNED_AUTO,
896  int>::type = 0>
897  static void initializeOffset(OwnerType&, size_t, size_t&)
898  {}
899 
900  template <ArrayType ARRAY_TYPE_ = ARRAY_TYPE,
901  typename std::enable_if<ARRAY_TYPE_ == ArrayType::ALIGNED || ARRAY_TYPE_ == ArrayType::ALIGNED_AUTO,
902  int>::type = 0>
903  static void initializeOffset(OwnerType& owner, size_t index, size_t& bitPosition)
904  {
905  bitPosition = alignTo(8, bitPosition);
906  detail::initializeOffset<ArrayExpressions>(owner, index, bitPosition / 8);
907  }
908 
909  template <ArrayType ARRAY_TYPE_ = ARRAY_TYPE,
910  typename std::enable_if<ARRAY_TYPE_ != ArrayType::AUTO && ARRAY_TYPE_ != ArrayType::ALIGNED_AUTO &&
911  ARRAY_TYPE_ != ArrayType::IMPLICIT,
912  int>::type = 0>
913  static size_t readArrayLength(OwnerType&, BitStreamReader&, size_t arrayLength)
914  {
915  return arrayLength;
916  }
917 
918  template <ArrayType ARRAY_TYPE_ = ARRAY_TYPE,
919  typename std::enable_if<ARRAY_TYPE_ == ArrayType::AUTO || ARRAY_TYPE_ == ArrayType::ALIGNED_AUTO,
920  int>::type = 0>
921  static size_t readArrayLength(OwnerType&, BitStreamReader& in, size_t)
922  {
923  return in.readVarSize();
924  }
925 
926  template <ArrayType ARRAY_TYPE_ = ARRAY_TYPE,
927  typename std::enable_if<ARRAY_TYPE_ == ArrayType::IMPLICIT, int>::type = 0>
928  static size_t readArrayLength(OwnerType& owner, BitStreamReader& in, size_t)
929  {
930  static_assert(ARRAY_TYPE != ArrayType::IMPLICIT || ArrayTraits::IS_BITSIZEOF_CONSTANT,
931  "Implicit array elements must have constant bit size!");
932 
933  const size_t remainingBits = in.getBufferBitSize() - in.getBitPosition();
934  return remainingBits / detail::arrayTraitsConstBitSizeOf<ArrayTraits>(owner);
935  }
936 
937  template <ArrayType ARRAY_TYPE_ = ARRAY_TYPE,
938  typename std::enable_if<ARRAY_TYPE_ != ArrayType::AUTO && ARRAY_TYPE_ != ArrayType::ALIGNED_AUTO,
939  int>::type = 0>
940  static void writeArrayLength(BitStreamWriter&, size_t)
941  {}
942 
943  template <ArrayType ARRAY_TYPE_ = ARRAY_TYPE,
944  typename std::enable_if<ARRAY_TYPE_ == ArrayType::AUTO || ARRAY_TYPE_ == ArrayType::ALIGNED_AUTO,
945  int>::type = 0>
946  static void writeArrayLength(BitStreamWriter& out, size_t arrayLength)
947  {
948  out.writeVarSize(convertSizeToUInt32(arrayLength));
949  }
950 
951  template <ArrayType ARRAY_TYPE_ = ARRAY_TYPE,
952  typename std::enable_if<ARRAY_TYPE_ != ArrayType::ALIGNED && ARRAY_TYPE_ != ArrayType::ALIGNED_AUTO,
953  int>::type = 0>
954  static size_t constBitSizeOfElements(size_t, size_t arrayLength, size_t elementBitSize)
955  {
956  return arrayLength * elementBitSize;
957  }
958 
959  template <ArrayType ARRAY_TYPE_ = ARRAY_TYPE,
960  typename std::enable_if<ARRAY_TYPE_ == ArrayType::ALIGNED || ARRAY_TYPE_ == ArrayType::ALIGNED_AUTO,
961  int>::type = 0>
962  static size_t constBitSizeOfElements(size_t bitPosition, size_t arrayLength, size_t elementBitSize)
963  {
964  size_t endBitPosition = alignTo(8, bitPosition);
965  endBitPosition += elementBitSize + (arrayLength - 1) * alignTo(8, elementBitSize);
966 
967  return endBitPosition - bitPosition;
968  }
969 
970  template <typename ARRAY_TRAITS_ = ArrayTraits,
971  typename std::enable_if<ARRAY_TRAITS_::IS_BITSIZEOF_CONSTANT, int>::type = 0>
972  size_t bitSizeOfImpl(const OwnerType& owner, size_t bitPosition) const
973  {
974  size_t endBitPosition = bitPosition;
975 
976  const size_t arrayLength = m_rawArray.size();
977  addBitSizeOfArrayLength(endBitPosition, arrayLength);
978 
979  if (arrayLength > 0)
980  {
981  const size_t elementBitSize = detail::arrayTraitsConstBitSizeOf<ArrayTraits>(owner);
982  endBitPosition += constBitSizeOfElements(endBitPosition, arrayLength, elementBitSize);
983  }
984 
985  return endBitPosition - bitPosition;
986  }
987 
988  template <typename ARRAY_TRAITS_ = ArrayTraits,
989  typename std::enable_if<!ARRAY_TRAITS_::IS_BITSIZEOF_CONSTANT, int>::type = 0>
990  size_t bitSizeOfImpl(const OwnerType& owner, size_t bitPosition) const
991  {
992  size_t endBitPosition = bitPosition;
993 
994  const size_t arrayLength = m_rawArray.size();
995  addBitSizeOfArrayLength(endBitPosition, arrayLength);
996 
997  for (size_t index = 0; index < arrayLength; ++index)
998  {
999  alignBitPosition(endBitPosition);
1000  endBitPosition +=
1001  detail::arrayTraitsBitSizeOf<ArrayTraits>(owner, endBitPosition, m_rawArray[index]);
1002  }
1003 
1004  return endBitPosition - bitPosition;
1005  }
1006 
1007  size_t initializeOffsetsImpl(OwnerType& owner, size_t bitPosition)
1008  {
1009  size_t endBitPosition = bitPosition;
1010 
1011  const size_t arrayLength = m_rawArray.size();
1012  addBitSizeOfArrayLength(endBitPosition, arrayLength);
1013 
1014  for (size_t index = 0; index < arrayLength; ++index)
1015  {
1016  initializeOffset(owner, index, endBitPosition);
1017  endBitPosition =
1018  detail::arrayTraitsInitializeOffsets<ArrayTraits>(owner, endBitPosition, m_rawArray[index]);
1019  }
1020 
1021  return endBitPosition;
1022  }
1023 
1024  template <typename ARRAY_TRAITS_ = ArrayTraits,
1025  typename std::enable_if<ARRAY_TRAITS_::IS_BITSIZEOF_CONSTANT, int>::type = 0>
1026  static void checkReadArraySize(OwnerType& owner, BitStreamReader& in, size_t readLength)
1027  {
1028  const size_t elementSize = detail::arrayTraitsConstBitSizeOf<ArrayTraits>(owner);
1029  if (in.getBitPosition() + readLength * static_cast<uint64_t>(elementSize) > in.getBufferBitSize())
1030  {
1031  throw CppRuntimeException("Array: Array size exceeds available buffer!");
1032  }
1033  }
1034 
1035  template <typename ARRAY_TRAITS_ = ArrayTraits,
1036  typename std::enable_if<!ARRAY_TRAITS_::IS_BITSIZEOF_CONSTANT, int>::type = 0>
1037  static void checkReadArraySize(OwnerType&, BitStreamReader&, size_t)
1038  {}
1039 
1040  void readImpl(OwnerType& owner, BitStreamReader& in, size_t arrayLength)
1041  {
1042  const size_t readLength = readArrayLength(owner, in, arrayLength);
1043  checkReadArraySize(owner, in, readLength);
1044 
1045  size_t reserve = readLength;
1046  if (reserve * static_cast<uint64_t>(sizeof(typename RawArray::value_type)) >
1047  in.getMaxArrayPreallocation())
1048  {
1049  reserve = in.getMaxArrayPreallocation() / sizeof(typename RawArray::value_type);
1050  }
1051  m_rawArray.clear();
1052  m_rawArray.reserve(reserve);
1053  for (size_t index = 0; index < readLength; ++index)
1054  {
1055  alignAndCheckOffset(in, owner, index);
1056  detail::arrayTraitsRead<ArrayTraits>(owner, m_rawArray, in, index);
1057  }
1058  }
1059 
1060  void writeImpl(const OwnerType& owner, BitStreamWriter& out) const
1061  {
1062  const size_t arrayLength = m_rawArray.size();
1063  writeArrayLength(out, arrayLength);
1064 
1065  for (size_t index = 0; index < arrayLength; ++index)
1066  {
1067  alignAndCheckOffset(out, owner, index);
1068  detail::arrayTraitsWrite<ArrayTraits>(owner, out, m_rawArray[index]);
1069  }
1070  }
1071 
1072  using PackingContext = typename detail::packing_context_type<typename RawArray::value_type>::type;
1073 
1074  size_t bitSizeOfPackedImpl(const OwnerType& owner, size_t bitPosition) const
1075  {
1076  static_assert(ARRAY_TYPE != ArrayType::IMPLICIT, "Implicit array cannot be packed!");
1077 
1078  size_t endBitPosition = bitPosition;
1079 
1080  const size_t arrayLength = m_rawArray.size();
1081  addBitSizeOfArrayLength(endBitPosition, arrayLength);
1082 
1083  if (arrayLength > 0)
1084  {
1085  PackingContext context;
1086 
1087  for (size_t index = 0; index < arrayLength; ++index)
1088  {
1089  detail::packedArrayTraitsInitContext<PackedArrayTraits<ArrayTraits>>(
1090  owner, context, m_rawArray[index]);
1091  }
1092 
1093  for (size_t index = 0; index < arrayLength; ++index)
1094  {
1095  alignBitPosition(endBitPosition);
1096  endBitPosition += detail::packedArrayTraitsBitSizeOf<PackedArrayTraits<ArrayTraits>>(
1097  owner, context, endBitPosition, m_rawArray[index]);
1098  }
1099  }
1100 
1101  return endBitPosition - bitPosition;
1102  }
1103 
1104  size_t initializeOffsetsPackedImpl(OwnerType& owner, size_t bitPosition)
1105  {
1106  static_assert(ARRAY_TYPE != ArrayType::IMPLICIT, "Implicit array cannot be packed!");
1107 
1108  size_t endBitPosition = bitPosition;
1109 
1110  const size_t arrayLength = m_rawArray.size();
1111  addBitSizeOfArrayLength(endBitPosition, arrayLength);
1112 
1113  if (arrayLength > 0)
1114  {
1115  PackingContext context;
1116 
1117  for (size_t index = 0; index < arrayLength; ++index)
1118  {
1119  detail::packedArrayTraitsInitContext<PackedArrayTraits<ArrayTraits>>(
1120  owner, context, m_rawArray[index]);
1121  }
1122 
1123  for (size_t index = 0; index < arrayLength; ++index)
1124  {
1125  initializeOffset(owner, index, endBitPosition);
1126  endBitPosition = detail::packedArrayTraitsInitializeOffsets<PackedArrayTraits<ArrayTraits>>(
1127  owner, context, endBitPosition, m_rawArray[index]);
1128  }
1129  }
1130 
1131  return endBitPosition;
1132  }
1133 
1134  void readPackedImpl(OwnerType& owner, BitStreamReader& in, size_t arrayLength = 0)
1135  {
1136  static_assert(ARRAY_TYPE != ArrayType::IMPLICIT, "Implicit array cannot be packed!");
1137 
1138  const size_t readLength = readArrayLength(owner, in, arrayLength);
1139  size_t reserve = readLength;
1140  if (reserve * static_cast<uint64_t>(sizeof(typename RawArray::value_type)) >
1141  in.getMaxArrayPreallocation())
1142  {
1143  reserve = in.getMaxArrayPreallocation() / sizeof(typename RawArray::value_type);
1144  }
1145 
1146  m_rawArray.clear();
1147 
1148  if (readLength > 0)
1149  {
1150  m_rawArray.reserve(reserve);
1151 
1152  PackingContext context;
1153 
1154  for (size_t index = 0; index < readLength; ++index)
1155  {
1156  alignAndCheckOffset(in, owner, index);
1157  detail::packedArrayTraitsRead<PackedArrayTraits<ArrayTraits>>(
1158  owner, m_rawArray, context, in, index);
1159  }
1160  }
1161  }
1162 
1163  void writePackedImpl(const OwnerType& owner, BitStreamWriter& out) const
1164  {
1165  static_assert(ARRAY_TYPE != ArrayType::IMPLICIT, "Implicit array cannot be packed!");
1166 
1167  const size_t arrayLength = m_rawArray.size();
1168  writeArrayLength(out, arrayLength);
1169 
1170  if (arrayLength > 0)
1171  {
1172  PackingContext context;
1173 
1174  for (size_t index = 0; index < arrayLength; ++index)
1175  {
1176  detail::packedArrayTraitsInitContext<PackedArrayTraits<ArrayTraits>>(
1177  owner, context, m_rawArray[index]);
1178  }
1179 
1180  for (size_t index = 0; index < arrayLength; ++index)
1181  {
1182  alignAndCheckOffset(out, owner, index);
1183  detail::packedArrayTraitsWrite<PackedArrayTraits<ArrayTraits>>(
1184  owner, context, out, m_rawArray[index]);
1185  }
1186  }
1187  }
1188 
1189  RawArray m_rawArray;
1190 };
1191 
1196 template <typename ARRAY, typename RAW_ARRAY>
1197 ARRAY createOptionalArray(RAW_ARRAY&& rawArray)
1198 {
1199  return ARRAY(std::forward<RAW_ARRAY>(rawArray));
1200 }
1201 
1205 template <typename ARRAY>
1207 {
1208  return NullOpt;
1209 }
1210 
1211 } // namespace zserio
1212 
1213 #endif // ZSERIO_ARRAY_H_INC
size_t bitSizeOf(const OwnerType &owner, size_t bitPosition) const
Definition: Array.h:622
ARRAY_TRAITS ArrayTraits
Definition: Array.h:373
Array(NoInitT, const Array &other)
Definition: Array.h:439
bool operator==(const Array &other) const
Definition: Array.h:530
~Array()=default
void readPacked(BitStreamReader &in, size_t arrayLength=0)
Definition: Array.h:799
Array & operator=(Array &&other)=default
size_t initializeOffsetsPacked(OwnerType &owner, size_t bitPosition)
Definition: Array.h:784
RAW_ARRAY RawArray
Definition: Array.h:370
Array & assign(NoInitT, const Array &other)
Definition: Array.h:459
RawArray & getRawArray()
Definition: Array.h:572
void write(BitStreamWriter &out) const
Definition: Array.h:702
void read(OwnerType &owner, BitStreamReader &in, size_t arrayLength=0)
Definition: Array.h:688
Array & operator=(const Array &other)=default
size_t bitSizeOfPacked(size_t bitPosition) const
Definition: Array.h:733
size_t initializeOffsets(OwnerType &owner, size_t bitPosition)
Definition: Array.h:656
void readPacked(OwnerType &owner, BitStreamReader &in, size_t arrayLength=0)
Definition: Array.h:816
void read(BitStreamReader &in, size_t arrayLength=0)
Definition: Array.h:671
typename detail::array_owner_type< ArrayTraits, ArrayExpressions >::type OwnerType
Definition: Array.h:384
size_t initializeOffsets(size_t bitPosition)
Definition: Array.h:638
void writePacked(BitStreamWriter &out) const
Definition: Array.h:830
uint32_t hashCode() const
Definition: Array.h:552
Array(RawArray &&rawArray)
Definition: Array.h:412
bool operator<(const Array &other) const
Definition: Array.h:542
Array(PropagateAllocatorT, const Array &other, const allocator_type &allocator)
Definition: Array.h:506
ARRAY_EXPRESSIONS ArrayExpressions
Definition: Array.h:376
typename RawArray::allocator_type allocator_type
Definition: Array.h:387
size_t bitSizeOf(size_t bitPosition) const
Definition: Array.h:605
Array(Array &&other)=default
Array(PropagateAllocatorT, NoInitT, const Array &other, const allocator_type &allocator)
Definition: Array.h:519
void initializeElements(OwnerType &owner)
Definition: Array.h:584
const RawArray & getRawArray() const
Definition: Array.h:562
Array & assign(NoInitT, Array &&other)
Definition: Array.h:495
void write(const OwnerType &owner, BitStreamWriter &out) const
Definition: Array.h:717
Array(NoInitT, Array &&other)
Definition: Array.h:481
size_t initializeOffsetsPacked(size_t bitPosition)
Definition: Array.h:766
Array(const RawArray &rawArray)
Definition: Array.h:403
size_t bitSizeOfPacked(const OwnerType &ownerType, size_t bitPosition) const
Definition: Array.h:750
Array(const allocator_type &allocator=allocator_type())
Definition: Array.h:394
Array(const Array &other)=default
void writePacked(const OwnerType &owner, BitStreamWriter &out) const
Definition: Array.h:845
T read(BitStreamReader &in)
constexpr NoInitT NoInit
Definition: NoInit.h:18
void write(BitStreamWriter &out, T value)
ARRAY createOptionalArray(RAW_ARRAY &&rawArray)
Definition: Array.h:1197
T allocatorPropagatingCopy(const T &source, const ALLOC &allocator)
constexpr size_t alignTo(size_t alignmentValue, size_t bitPosition)
constexpr NullOptType NullOpt
size_t initializeOffsets(size_t bitPosition, T value)
size_t bitSizeOfVarSize(uint32_t value)
std::enable_if< std::is_integral< T >::value &&(sizeof(T)<=4), uint32_t >::type calcHashCode(uint32_t seedValue, T value)
Definition: HashCodeUtil.h:43
uint32_t convertSizeToUInt32(size_t value)
ArrayType
Definition: Array.h:349
@ ALIGNED_AUTO
Definition: Array.h:354
@ ALIGNED
Definition: Array.h:352
@ IMPLICIT
Definition: Array.h:351
@ NORMAL
Definition: Array.h:350
@ AUTO
Definition: Array.h:353
size_t bitSizeOf(T value)