Zserio C++17 runtime library  1.1.0
Built for Zserio 2.18.1
ArrayView.h
Go to the documentation of this file.
1 #ifndef ZSERIO_ARRAY_H_INC
2 #define ZSERIO_ARRAY_H_INC
3 
4 #include <string_view>
5 #include <type_traits>
6 
8 #include "zserio/ArrayTraits.h"
10 #include "zserio/BitStreamReader.h"
11 #include "zserio/BitStreamWriter.h"
12 
13 namespace zserio
14 {
15 
16 namespace detail
17 {
18 
22 enum ArrayType
23 {
24  NORMAL,
25  IMPLICIT,
26  ALIGNED,
27  AUTO,
28  ALIGNED_AUTO
29 };
30 
31 } // namespace detail
32 
33 template <typename T, typename ARRAY_TRAITS = ArrayTraits<std::remove_cv_t<T>>>
34 class ArrayView
35 {
36 public:
38  using ValueType = std::remove_cv_t<T>;
39 
41  using Traits = ARRAY_TRAITS;
42 
44  class ConstIterator;
45 
46  using ConstReverseIterator = std::reverse_iterator<ConstIterator>;
47 
54  using OwnerType = detail::array_owner_type_t<Traits>;
55 
61  template <typename OWNER_TYPE_ = OwnerType,
62  std::enable_if_t<detail::is_dummy_array_owner_v<OWNER_TYPE_>, int> = 0>
63  explicit ArrayView(Span<T> data) :
64  m_data(data)
65  {}
66 
73  template <typename OWNER_TYPE_ = OwnerType,
74  std::enable_if_t<!detail::is_dummy_array_owner_v<OWNER_TYPE_>, int> = 0>
75  explicit ArrayView(Span<T> data, const OwnerType& owner) :
76  m_data(data),
77  m_owner(owner)
78  {}
79 
85  ~ArrayView() = default;
86  ArrayView(const ArrayView& other) = default;
87  ArrayView& operator=(const ArrayView& other) = default;
88  ArrayView(ArrayView&& other) = default;
89  ArrayView& operator=(ArrayView&& other) = default;
101  {
102  return m_data;
103  }
113  bool operator==(const ArrayView& other) const
114  {
115  const size_t thisSize = size();
116  const size_t otherSize = other.size();
117  if (thisSize != otherSize)
118  {
119  return false;
120  }
121 
122  for (size_t i = 0; i < thisSize; ++i)
123  {
124  if ((*this)[i] != other[i])
125  {
126  return false;
127  }
128  }
129 
130  return true;
131  }
132 
140  bool operator<(const ArrayView& other) const
141  {
142  const size_t thisSize = size();
143  const size_t otherSize = other.size();
144  const size_t minSize = std::min(thisSize, otherSize);
145 
146  for (size_t i = 0; i < minSize; ++i)
147  {
148  if ((*this)[i] < other[i])
149  {
150  return true;
151  }
152  if (other[i] < (*this)[i])
153  {
154  return false;
155  }
156  }
157 
158  return thisSize < otherSize;
159  }
160 
168  bool operator!=(const ArrayView& other) const
169  {
170  return !operator==(other);
171  }
172 
180  bool operator>(const ArrayView& other) const
181  {
182  return other.operator<(*this);
183  }
184 
192  bool operator<=(const ArrayView& other) const
193  {
194  return !other.operator<(*this);
195  }
196 
204  bool operator>=(const ArrayView& other) const
205  {
206  return !operator<(other);
207  }
208 
214  size_t size() const
215  {
216  return m_data.size();
217  }
218 
224  bool empty() const
225  {
226  return m_data.empty();
227  }
228 
235  decltype(auto) at(size_t index) const
236  {
237  if (index >= m_data.size())
238  {
239  throw CppRuntimeException("ArrayView: Index ")
240  << index << " is out of bounds (" << m_data.size() << ")!";
241  }
242 
243  return Traits::at(m_owner, m_data[index], index);
244  }
245 
253  decltype(auto) operator[](size_t index) const
254  {
255  return Traits::at(m_owner, m_data[index], index);
256  }
257 
263  decltype(auto) front() const
264  {
265  return at(0);
266  }
267 
273  decltype(auto) back() const
274  {
275  return at(size() - 1);
276  }
277 
284  ConstIterator cbegin() const noexcept
285  {
286  return ConstIterator(this, 0);
287  }
288 
289  ConstIterator begin() const noexcept
290  {
291  return cbegin();
292  }
301  ConstIterator cend() const noexcept
302  {
303  return ConstIterator(this, size());
304  }
305 
306  ConstIterator end() const noexcept
307  {
308  return cend();
309  }
318  ConstReverseIterator crbegin() const noexcept
319  {
320  return ConstReverseIterator(end());
321  }
322 
323  ConstReverseIterator rbegin() const noexcept
324  {
325  return crbegin();
326  }
335  ConstReverseIterator crend() const noexcept
336  {
337  return ConstReverseIterator(begin());
338  }
339 
340  ConstReverseIterator rend() const noexcept
341  {
342  return crend();
343  }
350  {
351  public:
352  using iterator_category = std::random_access_iterator_tag;
353  using value_type = decltype(std::declval<ArrayView>().at(std::declval<size_t>()));
354  using difference_type = std::ptrdiff_t;
355  using pointer = void;
356  using reference = value_type; // we always return by value!
357 
359  struct ArrowHelper
360  {
362  {
363  return std::addressof(value);
364  }
365 
367  };
368 
369  ConstIterator(const ArrayView* array, size_t index) :
370  m_array(array),
371  m_index(index)
372  {}
373 
375  {
376  return m_array->at(m_index);
377  }
378 
380  {
381  return ArrowHelper{m_array->at(m_index)};
382  }
383 
385  {
386  return m_array->at(m_index + static_cast<size_t>(offset));
387  }
388 
390  {
391  ++m_index;
392  return *this;
393  }
394 
396  {
397  ConstIterator tmp = *this;
398  m_index++;
399  return tmp;
400  }
401 
403  {
404  --m_index;
405  return *this;
406  }
407 
409  {
410  ConstIterator tmp = *this;
411  m_index--;
412  return tmp;
413  }
414 
416  {
417  m_index += static_cast<size_t>(offset);
418  return *this;
419  }
420 
422  {
423  return ConstIterator(m_array, m_index + static_cast<size_t>(offset));
424  }
425 
427  {
428  return ConstIterator(other.m_array, other.m_index + static_cast<size_t>(offset));
429  }
430 
432  {
433  m_index -= static_cast<size_t>(offset);
434  return *this;
435  }
436 
438  {
439  return ConstIterator(m_array, m_index - static_cast<size_t>(offset));
440  }
441 
443  {
444  return static_cast<difference_type>(m_index - other.m_index);
445  }
446 
447  bool operator==(const ConstIterator& other) const
448  {
449  return m_index == other.m_index;
450  }
451 
452  bool operator!=(const ConstIterator& other) const
453  {
454  return !(*this == other);
455  }
456 
457  bool operator<(const ConstIterator& other) const
458  {
459  if (m_index != other.m_index)
460  {
461  return m_index < other.m_index;
462  }
463 
464  return false;
465  }
466 
467  bool operator>(const ConstIterator& other) const
468  {
469  return other < *this;
470  }
471 
472  bool operator<=(const ConstIterator& other) const
473  {
474  return !(other < *this);
475  }
476 
477  bool operator>=(const ConstIterator& other) const
478  {
479  return !(*this < other);
480  }
481 
482  private:
483  const ArrayView* m_array;
484  size_t m_index;
485  };
486 
487 private:
488  Span<T> m_data;
489  OwnerType m_owner; // view to owner type, parameters are copied by value and that is ok
490 };
491 
492 namespace detail
493 {
494 
495 template <ArrayType ARRAY_TYPE, typename T, typename ARRAY_TRAITS>
496 void validate(const ArrayView<T, ARRAY_TRAITS>& array, std::string_view fieldName, size_t schemaSize = 0)
497 {
498  if constexpr (ARRAY_TYPE == ArrayType::NORMAL || ARRAY_TYPE == ArrayType::ALIGNED)
499  {
500  if (array.size() != schemaSize)
501  {
502  throw ArrayLengthException("Wrong array length for field '")
503  << fieldName << "' (" << array.size() << " != " << schemaSize << ")!";
504  }
505  }
506 
507  validate(VarSize{convertSizeToUInt32(array.size())}, fieldName);
508 
509  for (size_t i = 0; i < array.size(); ++i)
510  {
511  validate(array[i], fieldName);
512  }
513 }
514 
515 template <ArrayType ARRAY_TYPE, typename T, typename ARRAY_TRAITS>
516 BitSize bitSizeOf(const ArrayView<T, ARRAY_TRAITS>& array, BitSize bitPosition = 0)
517 {
518  BitSize endBitPosition = bitPosition;
519 
520  if constexpr (ARRAY_TYPE == ArrayType::AUTO || ARRAY_TYPE == ArrayType::ALIGNED_AUTO)
521  {
522  endBitPosition += bitSizeOf(fromCheckedValue<VarSize>(convertSizeToUInt32(array.size())));
523  }
524 
525  for (size_t i = 0; i < array.size(); ++i)
526  {
527  if constexpr (ARRAY_TYPE == ArrayType::ALIGNED || ARRAY_TYPE == ArrayType::ALIGNED_AUTO)
528  {
529  endBitPosition = alignTo(8, endBitPosition);
530  }
531 
532  endBitPosition += bitSizeOf(array[i], endBitPosition);
533  }
534 
535  return endBitPosition - bitPosition;
536 }
537 
538 struct DummyOffsetSetter
539 {
540  static void setOffset(size_t /*index*/, BitSize /*byteOffset*/)
541  {}
542 };
543 
544 template <ArrayType ARRAY_TYPE, typename T, typename ARRAY_TRAITS, typename OFFSET_SETTER = DummyOffsetSetter>
545 BitSize initializeOffsets(const ArrayView<T, ARRAY_TRAITS>& array, BitSize bitPosition,
546  const OFFSET_SETTER& offsetSetter = OFFSET_SETTER())
547 {
548  using ValueType = typename ArrayView<T, ARRAY_TRAITS>::ValueType;
549 
550  BitSize endBitPosition = bitPosition;
551 
552  if constexpr (ARRAY_TYPE == ArrayType::AUTO || ARRAY_TYPE == ArrayType::ALIGNED_AUTO)
553  {
554  endBitPosition += bitSizeOf(fromCheckedValue<VarSize>(convertSizeToUInt32(array.size())));
555  }
556 
557  for (size_t i = 0; i < array.size(); ++i)
558  {
559  if constexpr (ARRAY_TYPE == ArrayType::ALIGNED || ARRAY_TYPE == ArrayType::ALIGNED_AUTO)
560  {
561  endBitPosition = alignTo(8, endBitPosition);
562  offsetSetter.setOffset(i, endBitPosition / 8);
563  }
564 
565  using AtResult = decltype(std::declval<const ArrayView<T, ARRAY_TRAITS>&>().at(std::declval<size_t>()));
566  if constexpr (std::is_same_v<View<ValueType>, AtResult>)
567  {
568  endBitPosition += initializeOffsets(array[i], endBitPosition);
569  }
570  else
571  {
572  endBitPosition += bitSizeOf(array[i], endBitPosition);
573  }
574  }
575 
576  return endBitPosition - bitPosition;
577 }
578 
579 template <ArrayType ARRAY_TYPE, typename ARRAY_TRAITS>
580 size_t readArrayLength(BitStreamReader& reader, size_t arrayLength)
581 {
582  if constexpr (ARRAY_TYPE == ArrayType::NORMAL || ARRAY_TYPE == ArrayType::ALIGNED)
583  {
584  return arrayLength;
585  }
586  else if constexpr (ARRAY_TYPE == ArrayType::AUTO || ARRAY_TYPE == ArrayType::ALIGNED_AUTO)
587  {
588  return reader.readVarSize();
589  }
590  else
591  {
592  const size_t remainingBits = reader.getBufferBitSize() - reader.getBitPosition();
593  return remainingBits / ARRAY_TRAITS::bitSizeOf();
594  }
595 }
596 
597 template <ArrayType ARRAY_TYPE, typename T, typename ALLOC, typename ARRAY_TRAITS = ArrayTraits<T>>
598 void read(BitStreamReader& reader, Vector<T, ALLOC>& rawArray, detail::array_owner_type_t<ARRAY_TRAITS>& owner,
599  size_t arrayLength = 0)
600 {
601  const size_t readLength = readArrayLength<ARRAY_TYPE, ARRAY_TRAITS>(reader, arrayLength);
602 
603  if constexpr (std::is_base_of_v<NumericArrayTraits<T>, ARRAY_TRAITS>)
604  {
605  const size_t elementSize = ARRAY_TRAITS::bitSizeOf();
606  if (reader.getBitPosition() + readLength * static_cast<uint64_t>(elementSize) >
607  reader.getBufferBitSize())
608  {
609  throw CppRuntimeException("ArrayView: Array size exceeds available buffer!");
610  }
611  }
612 
613  size_t reserve = readLength;
614  if (reserve * static_cast<uint64_t>(sizeof(T)) > reader.getMaxArrayPreallocation())
615  {
616  reserve = reader.getMaxArrayPreallocation() / sizeof(T);
617  }
618  rawArray.clear();
619  rawArray.reserve(reserve);
620  for (size_t i = 0; i < readLength; ++i)
621  {
622  if constexpr (ARRAY_TYPE == ArrayType::ALIGNED || ARRAY_TYPE == ArrayType::ALIGNED_AUTO)
623  {
624  reader.alignTo(8);
625  }
626  rawArray.emplace_back();
627  ARRAY_TRAITS::read(reader, owner, rawArray.back(), i);
628  }
629 }
630 
631 template <ArrayType ARRAY_TYPE, typename T, typename ALLOC,
632  std::enable_if_t<is_dummy_array_owner_v<detail::array_owner_type_t<ArrayTraits<T>>>, int> = 0>
633 void read(BitStreamReader& reader, Vector<T, ALLOC>& rawArray, size_t arrayLength = 0)
634 {
635  DummyArrayOwner owner;
636  read<ARRAY_TYPE, T, ALLOC>(reader, rawArray, owner, arrayLength);
637 }
638 
639 template <ArrayType ARRAY_TYPE, typename ARRAY_TRAITS, typename T, typename ALLOC>
640 void readWithTraits(BitStreamReader& reader, Vector<T, ALLOC>& rawArray,
641  detail::array_owner_type_t<ARRAY_TRAITS>& owner, size_t arrayLength = 0)
642 {
643  read<ARRAY_TYPE, T, ALLOC, ARRAY_TRAITS>(reader, rawArray, owner, arrayLength);
644 }
645 
646 template <ArrayType ARRAY_TYPE, typename ARRAY_TRAITS, typename T, typename ALLOC,
647  std::enable_if_t<is_dummy_array_owner_v<detail::array_owner_type_t<ARRAY_TRAITS>>, int> = 0>
648 void readWithTraits(BitStreamReader& reader, Vector<T, ALLOC>& rawArray, size_t arrayLength = 0)
649 {
650  DummyArrayOwner owner;
651  readWithTraits<ARRAY_TYPE, ARRAY_TRAITS, T, ALLOC>(reader, rawArray, owner, arrayLength);
652 }
653 
654 template <ArrayType ARRAY_TYPE, typename T, typename ARRAY_TRAITS>
655 void write(BitStreamWriter& writer, const ArrayView<T, ARRAY_TRAITS>& array)
656 {
657  if constexpr (ARRAY_TYPE == ArrayType::AUTO || ARRAY_TYPE == ArrayType::ALIGNED_AUTO)
658  {
659  write(writer, fromCheckedValue<VarSize>(convertSizeToUInt32(array.size())));
660  }
661 
662  for (size_t i = 0; i < array.size(); ++i)
663  {
664  if constexpr (ARRAY_TYPE == ArrayType::ALIGNED || ARRAY_TYPE == ArrayType::ALIGNED_AUTO)
665  {
666  writer.alignTo(8);
667  }
668 
669  write(writer, array[i]);
670  }
671 }
672 
673 template <ArrayType ARRAY_TYPE, typename T, typename ARRAY_TRAITS>
674 BitSize bitSizeOfPacked(const ArrayView<T, ARRAY_TRAITS>& array, BitSize bitPosition = 0)
675 {
676  if constexpr (is_packable_v<T>)
677  {
678  using ValueType = typename ArrayView<T, ARRAY_TRAITS>::ValueType;
679 
680  static_assert(ARRAY_TYPE != ArrayType::IMPLICIT, "Implicit array cannot be packed!");
681 
682  BitSize endBitPosition = bitPosition;
683 
684  const size_t arrayLength = array.size();
685  if constexpr (ARRAY_TYPE == ArrayType::AUTO || ARRAY_TYPE == ArrayType::ALIGNED_AUTO)
686  {
687  endBitPosition += bitSizeOf(fromCheckedValue<VarSize>(convertSizeToUInt32(arrayLength)));
688  }
689 
690  if (arrayLength > 0)
691  {
692  detail::packing_context_type_t<ValueType> context;
693 
694  for (size_t i = 0; i < arrayLength; ++i)
695  {
696  initContext(context, array[i]);
697  }
698 
699  for (size_t i = 0; i < arrayLength; ++i)
700  {
701  if constexpr (ARRAY_TYPE == ArrayType::ALIGNED || ARRAY_TYPE == ArrayType::ALIGNED_AUTO)
702  {
703  endBitPosition = alignTo(8, endBitPosition);
704  }
705 
706  endBitPosition += bitSizeOf(context, array[i], endBitPosition);
707  }
708  }
709 
710  return endBitPosition - bitPosition;
711  }
712  else
713  {
714  return bitSizeOf<ARRAY_TYPE>(array, bitPosition);
715  }
716 }
717 
718 template <ArrayType ARRAY_TYPE, typename T, typename ARRAY_TRAITS, typename OFFSET_SETTER = DummyOffsetSetter>
719 BitSize initializeOffsetsPacked(const ArrayView<T, ARRAY_TRAITS>& array, BitSize bitPosition,
720  const OFFSET_SETTER& offsetSetter = OFFSET_SETTER())
721 {
722  if constexpr (is_packable_v<T>)
723  {
724  using ValueType = typename ArrayView<T, ARRAY_TRAITS>::ValueType;
725 
726  static_assert(ARRAY_TYPE != ArrayType::IMPLICIT, "Implicit array cannot be packed!");
727 
728  BitSize endBitPosition = bitPosition;
729 
730  const size_t arrayLength = array.size();
731  if constexpr (ARRAY_TYPE == ArrayType::AUTO || ARRAY_TYPE == ArrayType::ALIGNED_AUTO)
732  {
733  endBitPosition += bitSizeOf(fromCheckedValue<VarSize>(convertSizeToUInt32(arrayLength)));
734  }
735 
736  if (arrayLength > 0)
737  {
738  detail::packing_context_type_t<ValueType> context;
739 
740  for (size_t i = 0; i < arrayLength; ++i)
741  {
742  initContext(context, array[i]);
743  }
744 
745  for (size_t i = 0; i < arrayLength; ++i)
746  {
747  if constexpr (ARRAY_TYPE == ArrayType::ALIGNED || ARRAY_TYPE == ArrayType::ALIGNED_AUTO)
748  {
749  endBitPosition = alignTo(8, endBitPosition);
750  offsetSetter.setOffset(i, endBitPosition / 8);
751  }
752 
753  using AtResult =
754  decltype(std::declval<const ArrayView<T, ARRAY_TRAITS>&>().at(std::declval<size_t>()));
755  if constexpr (std::is_same_v<View<ValueType>, AtResult>)
756  {
757  endBitPosition += initializeOffsets(context, array[i], endBitPosition);
758  }
759  else
760  {
761  endBitPosition += bitSizeOf(context, array[i], endBitPosition);
762  }
763  }
764  }
765 
766  return endBitPosition - bitPosition;
767  }
768  else
769  {
770  return initializeOffsets<ARRAY_TYPE>(array, bitPosition, offsetSetter);
771  }
772 }
773 
774 template <ArrayType ARRAY_TYPE, typename T, typename ARRAY_TRAITS>
775 void writePacked(BitStreamWriter& writer, const ArrayView<T, ARRAY_TRAITS>& array)
776 {
777  if constexpr (is_packable_v<T>)
778  {
779  using ValueType = typename ArrayView<T, ARRAY_TRAITS>::ValueType;
780 
781  static_assert(ARRAY_TYPE != ArrayType::IMPLICIT, "Implicit array cannot be packed!");
782 
783  const size_t arrayLength = array.size();
784  if constexpr (ARRAY_TYPE == ArrayType::AUTO || ARRAY_TYPE == ArrayType::ALIGNED_AUTO)
785  {
786  write(writer, fromCheckedValue<VarSize>(convertSizeToUInt32(array.size())));
787  }
788 
789  if (arrayLength > 0)
790  {
791  detail::packing_context_type_t<ValueType> context;
792 
793  for (size_t i = 0; i < arrayLength; ++i)
794  {
795  initContext(context, array[i]);
796  }
797 
798  for (size_t i = 0; i < arrayLength; ++i)
799  {
800  if constexpr (ARRAY_TYPE == ArrayType::ALIGNED || ARRAY_TYPE == ArrayType::ALIGNED_AUTO)
801  {
802  writer.alignTo(8);
803  }
804 
805  write(context, writer, array[i]);
806  }
807  }
808  }
809  else
810  {
811  write<ARRAY_TYPE>(writer, array);
812  }
813 }
814 
815 template <ArrayType ARRAY_TYPE, typename T, typename ALLOC, typename ARRAY_TRAITS = ArrayTraits<T>>
816 void readPacked(BitStreamReader& reader, Vector<T, ALLOC>& rawArray,
817  detail::array_owner_type_t<ARRAY_TRAITS>& owner, size_t arrayLength = 0)
818 {
819  if constexpr (is_packable_v<T>)
820  {
821  using ValueType = T;
822 
823  const size_t readLength = readArrayLength<ARRAY_TYPE, ARRAY_TRAITS>(reader, arrayLength);
824  rawArray.clear();
825 
826  size_t reserve = readLength;
827  if (reserve * static_cast<uint64_t>(sizeof(T)) > reader.getMaxArrayPreallocation())
828  {
829  reserve = reader.getMaxArrayPreallocation() / sizeof(T);
830  }
831 
832  if (readLength > 0)
833  {
834  rawArray.reserve(reserve);
835 
836  detail::packing_context_type_t<ValueType> context;
837 
838  for (size_t i = 0; i < readLength; ++i)
839  {
840  if constexpr (ARRAY_TYPE == ArrayType::ALIGNED || ARRAY_TYPE == ArrayType::ALIGNED_AUTO)
841  {
842  reader.alignTo(8);
843  }
844  rawArray.emplace_back();
845  ARRAY_TRAITS::read(context, reader, owner, rawArray.back(), i);
846  }
847  }
848  }
849  else
850  {
851  read<ARRAY_TYPE, T, ALLOC, ARRAY_TRAITS>(reader, rawArray, owner, arrayLength);
852  }
853 }
854 
855 template <ArrayType ARRAY_TYPE, typename T, typename ALLOC,
856  typename ARRAY_TRAITS = ArrayTraits<std::remove_cv_t<T>>,
857  std::enable_if_t<is_dummy_array_owner_v<detail::array_owner_type_t<ARRAY_TRAITS>>, int> = 0>
858 void readPacked(BitStreamReader& reader, Vector<T, ALLOC>& rawArray, size_t arrayLength = 0)
859 {
860  DummyArrayOwner owner;
861  readPacked<ARRAY_TYPE, T, ALLOC, ARRAY_TRAITS>(reader, rawArray, owner, arrayLength);
862 }
863 
864 template <ArrayType ARRAY_TYPE, typename ARRAY_TRAITS, typename T, typename ALLOC>
865 void readPackedWithTraits(BitStreamReader& reader, Vector<T, ALLOC>& rawArray,
866  detail::array_owner_type_t<ARRAY_TRAITS>& owner, size_t arrayLength = 0)
867 {
868  readPacked<ARRAY_TYPE, T, ALLOC, ARRAY_TRAITS>(reader, rawArray, owner, arrayLength);
869 }
870 
871 template <ArrayType ARRAY_TYPE, typename ARRAY_TRAITS, typename T, typename ALLOC,
872  std::enable_if_t<is_dummy_array_owner_v<detail::array_owner_type_t<ARRAY_TRAITS>>, int> = 0>
873 void readPackedWithTraits(BitStreamReader& reader, Vector<T, ALLOC>& rawArray, size_t arrayLength = 0)
874 {
875  DummyArrayOwner owner;
876  readPackedWithTraits<ARRAY_TYPE, ARRAY_TRAITS, T, ALLOC>(reader, rawArray, owner, arrayLength);
877 }
878 
879 } // namespace detail
880 
881 template <typename T, typename ARRAY_TRAITS>
882 uint32_t calcHashCode(uint32_t seedValue, const ArrayView<T, ARRAY_TRAITS>& array)
883 {
884  uint32_t result = seedValue;
885  for (size_t i = 0; i < array.size(); ++i)
886  {
887  result = calcHashCode(result, array[i]);
888  }
889 
890  return result;
891 }
892 
893 } // namespace zserio
894 
895 #endif // ZSERIO_ARRAY_H_INC
bool operator<=(const ConstIterator &other) const
Definition: ArrayView.h:472
bool operator==(const ConstIterator &other) const
Definition: ArrayView.h:447
ConstIterator & operator++()
Definition: ArrayView.h:389
ConstIterator operator++(int)
Definition: ArrayView.h:395
ConstIterator(const ArrayView *array, size_t index)
Definition: ArrayView.h:369
ConstIterator operator-(difference_type offset) const
Definition: ArrayView.h:437
value_type operator[](difference_type offset) const
Definition: ArrayView.h:384
ConstIterator & operator+=(difference_type offset)
Definition: ArrayView.h:415
friend ConstIterator operator+(difference_type offset, const ConstIterator &other)
Definition: ArrayView.h:426
bool operator>(const ConstIterator &other) const
Definition: ArrayView.h:467
ArrowHelper operator->() const
Definition: ArrayView.h:379
bool operator<(const ConstIterator &other) const
Definition: ArrayView.h:457
ConstIterator & operator--()
Definition: ArrayView.h:402
ConstIterator operator--(int)
Definition: ArrayView.h:408
difference_type operator-(const ConstIterator &other) const
Definition: ArrayView.h:442
value_type operator*() const
Definition: ArrayView.h:374
ConstIterator & operator-=(difference_type offset)
Definition: ArrayView.h:431
bool operator>=(const ConstIterator &other) const
Definition: ArrayView.h:477
decltype(std::declval< ArrayView >().at(std::declval< size_t >())) value_type
Definition: ArrayView.h:353
std::random_access_iterator_tag iterator_category
Definition: ArrayView.h:352
bool operator!=(const ConstIterator &other) const
Definition: ArrayView.h:452
ConstIterator operator+(difference_type offset) const
Definition: ArrayView.h:421
std::remove_cv_t< T > ValueType
Definition: ArrayView.h:38
ConstIterator begin() const noexcept
Definition: ArrayView.h:289
ARRAY_TRAITS Traits
Definition: ArrayView.h:41
Span< T > zserioData() const
Definition: ArrayView.h:100
ArrayView(Span< T > data)
Definition: ArrayView.h:63
ConstReverseIterator crend() const noexcept
Definition: ArrayView.h:335
ConstIterator cend() const noexcept
Definition: ArrayView.h:301
bool operator>=(const ArrayView &other) const
Definition: ArrayView.h:204
ConstReverseIterator rend() const noexcept
Definition: ArrayView.h:340
std::reverse_iterator< ConstIterator > ConstReverseIterator
Definition: ArrayView.h:46
ConstIterator cbegin() const noexcept
Definition: ArrayView.h:284
ConstReverseIterator rbegin() const noexcept
Definition: ArrayView.h:323
bool operator==(const ArrayView &other) const
Definition: ArrayView.h:113
decltype(auto) front() const
Definition: ArrayView.h:263
~ArrayView()=default
ArrayView & operator=(ArrayView &&other)=default
bool operator>(const ArrayView &other) const
Definition: ArrayView.h:180
decltype(auto) back() const
Definition: ArrayView.h:273
ArrayView(const ArrayView &other)=default
ConstIterator end() const noexcept
Definition: ArrayView.h:306
bool empty() const
Definition: ArrayView.h:224
ArrayView & operator=(const ArrayView &other)=default
bool operator<(const ArrayView &other) const
Definition: ArrayView.h:140
ArrayView(Span< T > data, const OwnerType &owner)
Definition: ArrayView.h:75
bool operator<=(const ArrayView &other) const
Definition: ArrayView.h:192
decltype(auto) at(size_t index) const
Definition: ArrayView.h:235
bool operator!=(const ArrayView &other) const
Definition: ArrayView.h:168
ConstReverseIterator crbegin() const noexcept
Definition: ArrayView.h:318
size_t size() const
Definition: ArrayView.h:214
ArrayView(ArrayView &&other)=default
detail::array_owner_type_t< Traits > OwnerType
Definition: ArrayView.h:54
unsigned int BitSize
Definition: BitSize.h:8
constexpr BitSize alignTo(BitSize alignmentValue, BitSize bitPosition)
uint32_t calcHashCode(uint32_t seedValue, const ArrayView< T, ARRAY_TRAITS > &array)
Definition: ArrayView.h:882
uint32_t convertSizeToUInt32(size_t value)
detail::VarIntWrapper< uint32_t, detail::VarIntType::VARSIZE > VarSize
Definition: Types.h:890