20#include "comms/util/MaxSizeOf.h"
25#include "comms/details/detect.h"
26#include "comms/details/tag.h"
27#include "comms/field/details/VersionStorage.h"
29#include "CommonFuncs.h"
43template <
typename TStorage>
44struct ArrayListMaxLengthRetrieveHelper
46 static const std::size_t Value = CommonFuncs::maxSupportedLength();
49template <
typename T, std::
size_t TSize>
50struct ArrayListMaxLengthRetrieveHelper<
comms::util::StaticVector<T, TSize> >
52 static const std::size_t Value = TSize;
55template <std::
size_t TSize>
56struct ArrayListMaxLengthRetrieveHelper<
comms::util::StaticString<TSize> >
58 static const std::size_t Value = TSize - 1;
61template <
typename TElem>
62using ArrayListFieldHasVarLengthBoolType =
63 typename comms::util::LazyDeepConditional<
64 std::is_integral<TElem>::value
66 comms::util::FalseType,
67 comms::util::FieldCheckVarLength,
71template <
typename TElem>
72using HasArrayListElemNonDefaultRefreshBoolType =
73 typename comms::util::LazyDeepConditional<
74 std::is_integral<TElem>::value
76 comms::util::FalseType,
77 comms::util::FieldCheckNonDefaultRefresh,
81template <
typename TElem>
82using IsArrayListElemVersionDependentBoolType =
83 typename comms::util::LazyDeepConditional<
84 std::is_integral<TElem>::value
86 comms::util::FalseType,
87 comms::util::FieldCheckVersionDependent,
91template <
typename TFieldBase,
typename TStorage>
92using ArrayListVersionStorageBase =
93 typename comms::util::LazyShallowConditional<
94 IsArrayListElemVersionDependentBoolType<typename TStorage::value_type>::value
96 comms::field::details::VersionStorage,
97 comms::util::EmptyStruct,
98 typename TFieldBase::VersionType
103template <
typename TFieldBase,
typename TStorage>
106 public details::ArrayListVersionStorageBase<TFieldBase, TStorage>
108 using BaseImpl = TFieldBase;
109 using VersionBaseImpl = details::ArrayListVersionStorageBase<TFieldBase, TStorage>;
112 using Endian =
typename BaseImpl::Endian;
113 using VersionType =
typename BaseImpl::VersionType;
114 using ElementType =
typename TStorage::value_type;
115 using ValueType = TStorage;
118 std::is_integral<ElementType>::value
120 comms::field::tag::RawArrayList,
121 comms::field::tag::ArrayList
124 ArrayList() =
default;
126 explicit ArrayList(
const ValueType& val)
131 explicit ArrayList(ValueType&& val)
132 : value_(
std::move(val))
136 ArrayList(
const ArrayList&) =
default;
137 ArrayList(ArrayList&&) =
default;
138 ArrayList& operator=(
const ArrayList&) =
default;
139 ArrayList& operator=(ArrayList&&) =
default;
140 ~ArrayList() noexcept = default;
142 const ValueType& value()
const
152 const ValueType& getValue()
const
157 template <
typename T>
158 void setValue(T&& val)
160 value() = std::forward<T>(val);
163 ElementType& createBack()
166 value_.emplace_back();
167 updateElemVersion(value_.back(), VersionTag<>());
168 return value_.back();
173 static_assert(comms::util::detect::hasClearFunc<ValueType>(),
174 "The used storage type for ArrayList must have clear() member function");
179 constexpr std::size_t length()
const
181 return lengthInternal(ElemTag<>());
184 static constexpr std::size_t minLength()
189 static constexpr std::size_t maxLength()
192 details::ArrayListMaxLengthRetrieveHelper<TStorage>::Value *
193 maxLengthInternal(ElemTag<>());
196 constexpr bool valid()
const
198 return validInternal(ElemTag<>());
203 return refreshInternal(ElemTag<>());
206 static constexpr std::size_t minElementLength()
208 return minElemLengthInternal(ElemTag<>());
211 static constexpr std::size_t maxElementLength()
213 return maxElemLengthInternal(ElemTag<>());
216 static constexpr std::size_t elementLength(
const ElementType& elem)
218 return elementLengthInternal(elem, ElemTag<>());
221 template <
typename TIter>
222 static ErrorStatus readElement(ElementType& elem, TIter& iter, std::size_t& len)
224 return readElementInternal(elem, iter, len, ElemTag<>());
227 template <
typename TIter>
228 static void readElementNoStatus(ElementType& elem, TIter& iter)
230 return readElementNoStatusInternal(elem, iter, ElemTag<>());
233 template <
typename TIter>
236 using IterType =
typename std::decay<
decltype(iter)>::type;
238 typename std::iterator_traits<IterType>::iterator_category;
239 static const bool IsRandomAccessIter =
240 std::is_base_of<std::random_access_iterator_tag, IterCategory>::value;
241 static const bool IsRawData =
242 std::is_integral<ElementType>::value && (
sizeof(ElementType) ==
sizeof(std::uint8_t));
245 typename comms::util::LazyShallowConditional<
246 IsRandomAccessIter && IsRawData
251 return readInternal(iter, len, Tag());
254 static constexpr bool hasReadNoStatus()
259 template <
typename TIter>
260 void readNoStatus(TIter& iter) =
delete;
262 template <
typename TIter>
263 ErrorStatus readN(std::size_t count, TIter& iter, std::size_t& len)
265 using IterType =
typename std::decay<
decltype(iter)>::type;
267 typename std::iterator_traits<IterType>::iterator_category;
268 static const bool IsRandomAccessIter =
269 std::is_base_of<std::random_access_iterator_tag, IterCategory>::value;
270 static const bool IsRawData =
271 std::is_integral<ElementType>::value && (
sizeof(ElementType) ==
sizeof(std::uint8_t));
274 typename comms::util::LazyShallowConditional<
275 IsRandomAccessIter && IsRawData
281 return readInternalN(count, iter, len, Tag());
284 template <
typename TIter>
285 void readNoStatusN(std::size_t count, TIter& iter)
287 using IterType =
typename std::decay<
decltype(iter)>::type;
289 typename std::iterator_traits<IterType>::iterator_category;
290 static const bool IsRandomAccessIter =
291 std::is_base_of<std::random_access_iterator_tag, IterCategory>::value;
292 static const bool IsRawData =
293 std::is_integral<ElementType>::value && (
sizeof(ElementType) ==
sizeof(std::uint8_t));
296 typename comms::util::LazyShallowConditional<
297 IsRandomAccessIter && IsRawData
303 return readNoStatusInternalN(count, iter, Tag());
306 static bool canWriteElement(
const ElementType& elem)
308 return canWriteElementInternal(elem, ElemTag<>());
311 template <
typename TIter>
312 static ErrorStatus writeElement(
const ElementType& elem, TIter& iter, std::size_t& len)
314 return writeElementInternal(elem, iter, len, ElemTag<>());
317 template <
typename TIter>
318 static void writeElementNoStatus(
const ElementType& elem, TIter& iter)
320 return writeElementNoStatusInternal(elem, iter, ElemTag<>());
323 bool canWrite()
const
325 return CommonFuncs::canWriteSequence(*
this);
328 template <
typename TIter>
329 ErrorStatus write(TIter& iter, std::size_t len)
const
331 return CommonFuncs::writeSequence(*
this, iter, len);
334 static constexpr bool hasWriteNoStatus()
336 return hasWriteNoStatusInternal(ElemTag<>());
339 template <
typename TIter>
340 void writeNoStatus(TIter& iter)
const
342 CommonFuncs::writeSequenceNoStatus(*
this, iter);
345 template <
typename TIter>
346 ErrorStatus writeN(std::size_t count, TIter& iter, std::size_t& len)
const
348 return CommonFuncs::writeSequenceN(*
this, count, iter, len);
351 template <
typename TIter>
352 void writeNoStatusN(std::size_t count, TIter& iter)
const
354 CommonFuncs::writeSequenceNoStatusN(*
this, count, iter);
357 static constexpr bool isVersionDependent()
359 return details::IsArrayListElemVersionDependentBoolType<ElementType>::value;
362 static constexpr bool hasNonDefaultRefresh()
364 return details::HasArrayListElemNonDefaultRefreshBoolType<ElementType>::value;
367 bool setVersion(VersionType
version)
369 return setVersionInternal(
version, VersionTag<>());
373 template <
typename... TParams>
374 using FieldElemTag = comms::details::tag::Tag1<>;
376 template <
typename... TParams>
377 using IntegralElemTag = comms::details::tag::Tag2<>;
379 template <
typename... TParams>
380 using FixedLengthTag = comms::details::tag::Tag3<>;
382 template <
typename... TParams>
383 using VarLengthTag = comms::details::tag::Tag4<>;
385 template <
typename... TParams>
386 using RawDataTag = comms::details::tag::Tag5<>;
388 template <
typename... TParams>
389 using VersionDependentTag = comms::details::tag::Tag6<>;
391 template <
typename... TParams>
392 using NoVersionDependencyTag = comms::details::tag::Tag7<>;
394 template <
typename... TParams>
397 std::is_integral<ElementType>::value
399 IntegralElemTag<TParams...>,
400 FieldElemTag<TParams...>
403 template <
typename... TParams>
406 details::IsArrayListElemVersionDependentBoolType<ElementType>::value
408 VersionDependentTag<TParams...>,
409 NoVersionDependencyTag<TParams...>
412 template <
typename... TParams>
413 constexpr std::size_t lengthInternal(FieldElemTag<TParams...>)
const
416 typename comms::util::LazyShallowConditional<
417 details::ArrayListFieldHasVarLengthBoolType<ElementType>::value
423 return fieldLength(Tag());
426 template <
typename... TParams>
427 constexpr std::size_t lengthInternal(IntegralElemTag<TParams...>)
const
429 return value_.size() *
sizeof(ElementType);
432 template <
typename... TParams>
433 constexpr std::size_t fieldLength(FixedLengthTag<TParams...>)
const
435 return ElementType().length() * value_.size();
438 template <
typename... TParams>
439 std::size_t fieldLength(VarLengthTag<TParams...>)
const
442 std::accumulate(value_.begin(), value_.end(), std::size_t(0),
443 [](std::size_t sum,
typename ValueType::const_reference e) -> std::size_t
445 return sum + e.length();
449 template <
typename... TParams>
450 static constexpr std::size_t maxLengthInternal(FieldElemTag<TParams...>)
452 return ElementType::maxLength();
455 template <
typename... TParams>
456 static constexpr std::size_t maxLengthInternal(IntegralElemTag<TParams...>)
458 return sizeof(ElementType);
461 template <
typename TIter>
462 static ErrorStatus readFieldElement(ElementType& elem, TIter& iter, std::size_t& len)
464 auto fromIter = iter;
465 auto es = elem.read(iter, len);
467 auto diff =
static_cast<std::size_t
>(std::distance(fromIter, iter));
474 template <
typename TIter>
475 static ErrorStatus readIntegralElement(ElementType& elem, TIter& iter, std::size_t& len)
477 if (len <
sizeof(ElementType)) {
481 elem = comms::util::readData<ElementType>(iter,
Endian());
482 len -=
sizeof(ElementType);
486 template <
typename TIter,
typename... TParams>
487 static ErrorStatus readElementInternal(ElementType& elem, TIter& iter, std::size_t& len, FieldElemTag<TParams...>)
489 return readFieldElement(elem, iter, len);
492 template <
typename TIter,
typename... TParams>
493 static ErrorStatus readElementInternal(ElementType& elem, TIter& iter, std::size_t& len, IntegralElemTag<TParams...>)
495 return readIntegralElement(elem, iter, len);
498 template <
typename TIter>
499 static void readNoStatusFieldElement(ElementType& elem, TIter& iter)
501 elem.readNoStatus(iter);
504 template <
typename TIter>
505 static void readNoStatusIntegralElement(ElementType& elem, TIter& iter)
507 elem = comms::util::readData<ElementType>(iter,
Endian());
510 template <
typename TIter,
typename... TParams>
511 static void readElementNoStatusInternal(ElementType& elem, TIter& iter, FieldElemTag<TParams...>)
513 readNoStatusFieldElement(elem, iter);
516 template <
typename TIter,
typename... TParams>
517 static void readElementNoStatusInternal(ElementType& elem, TIter& iter, IntegralElemTag<TParams...>)
519 readElementNoStatusInternal(elem, iter);
522 template <
typename TIter>
523 static ErrorStatus writeFieldElement(
const ElementType& elem, TIter& iter, std::size_t& len)
525 auto es = elem.write(iter, len);
527 len -= elem.length();
532 template <
typename TIter>
533 static ErrorStatus writeIntegralElement(
const ElementType& elem, TIter& iter, std::size_t& len)
535 if (len <
sizeof(ElementType)) {
539 BaseImpl::writeData(elem, iter);
540 len -=
sizeof(ElementType);
544 template <
typename TIter,
typename... TParams>
545 static ErrorStatus writeElementInternal(
const ElementType& elem, TIter& iter, std::size_t& len, FieldElemTag<TParams...>)
547 return writeFieldElement(elem, iter, len);
550 template <
typename TIter,
typename... TParams>
551 static ErrorStatus writeElementInternal(
const ElementType& elem, TIter& iter, std::size_t& len, IntegralElemTag<TParams...>)
553 return writeIntegralElement(elem, iter, len);
556 template <
typename TIter>
557 static void writeNoStatusFieldElement(
const ElementType& elem, TIter& iter)
559 elem.writeNoStatus(iter);
562 template <
typename TIter>
563 static void writeNoStatusIntegralElement(
const ElementType& elem, TIter& iter)
565 BaseImpl::writeData(elem, iter);
568 template <
typename TIter,
typename... TParams>
569 static void writeElementNoStatusInternal(
const ElementType& elem, TIter& iter, FieldElemTag<TParams...>)
571 return writeNoStatusFieldElement(elem, iter);
574 template <
typename TIter,
typename... TParams>
575 static void writeElementNoStatusInternal(
const ElementType& elem, TIter& iter, IntegralElemTag<TParams...>)
577 return writeNoStatusIntegralElement(elem, iter);
580 template <
typename... TParams>
581 constexpr bool validInternal(FieldElemTag<TParams...>)
const
584 value_.begin(), value_.end(),
585 [](
const ElementType& e) ->
bool
591 template <
typename... TParams>
592 static constexpr bool validInternal(IntegralElemTag<TParams...>)
597 template <
typename... TParams>
598 bool refreshInternal(FieldElemTag<TParams...>)
602 value_.begin(), value_.end(),
false,
603 [](
bool prev,
typename ValueType::reference elem) ->
bool
605 return elem.refresh() || prev;
609 template <
typename... TParams>
610 static constexpr bool refreshInternal(IntegralElemTag<TParams...>)
615 template <
typename... TParams>
616 static constexpr std::size_t minElemLengthInternal(IntegralElemTag<TParams...>)
618 return sizeof(ElementType);
621 template <
typename... TParams>
622 static constexpr std::size_t minElemLengthInternal(FieldElemTag<TParams...>)
624 return ElementType::minLength();
627 template <
typename... TParams>
628 static constexpr std::size_t maxElemLengthInternal(IntegralElemTag<TParams...>)
630 return sizeof(ElementType);
633 template <
typename... TParams>
634 static constexpr std::size_t maxElemLengthInternal(FieldElemTag<TParams...>)
636 return ElementType::maxLength();
639 template <
typename... TParams>
640 static constexpr std::size_t elementLengthInternal(
const ElementType&, IntegralElemTag<TParams...>)
642 return sizeof(ElementType);
645 template <
typename... TParams>
646 static constexpr std::size_t elementLengthInternal(
const ElementType& elem, FieldElemTag<TParams...>)
648 return elem.length();
651 template <
typename TIter,
typename... TParams>
652 ErrorStatus readInternal(TIter& iter, std::size_t len, FieldElemTag<TParams...>)
654 static_assert(comms::util::detect::hasClearFunc<ValueType>(),
655 "The used storage type for ArrayList must have clear() member function");
659 auto es = createAndReadNextElementInternal(iter, remLen);
668 template <
typename TIter,
typename... TParams>
669 ErrorStatus readInternal(TIter& iter, std::size_t len, RawDataTag<TParams...>)
672 std::advance(iter, len);
676 template <
typename TIter,
typename... TParams>
677 ErrorStatus readInternalN(std::size_t count, TIter& iter, std::size_t len, FieldElemTag<TParams...>)
681 auto es = createAndReadNextElementInternal(iter, len);
692 template <
typename TIter,
typename... TParams>
693 ErrorStatus readInternalN(std::size_t count, TIter& iter, std::size_t len, RawDataTag<TParams...>)
699 return readInternal(iter, count, RawDataTag<>());
702 template <
typename TIter,
typename... TParams>
703 void readNoStatusInternalN(std::size_t count, TIter& iter, FieldElemTag<TParams...>)
707 if (value_.size() < value_.max_size()) {
708 auto& elem = createBack();
709 readElementNoStatus(elem, iter);
713 readElementNoStatus(elem, iter);
719 template <
typename TIter,
typename... TParams>
720 void readNoStatusInternalN(std::size_t count, TIter& iter, RawDataTag<TParams...>)
722 readInternal(iter, count, RawDataTag<>());
725 template <
typename... TParams>
726 bool updateElemVersion(ElementType& elem, VersionDependentTag<TParams...>)
728 return elem.setVersion(VersionBaseImpl::version_);
731 template <
typename... TParams>
732 static constexpr bool updateElemVersion(ElementType&, NoVersionDependencyTag<TParams...>)
737 template <
typename... TParams>
738 bool setVersionInternal(VersionType
version, VersionDependentTag<TParams...>)
740 VersionBaseImpl::version_ =
version;
741 bool updated =
false;
742 for (
auto& elem : value()) {
743 updated = elem.setVersion(
version) || updated;
749 template <
typename... TParams>
750 static constexpr bool setVersionInternal(VersionType, NoVersionDependencyTag<TParams...>)
755 template <
typename... TParams>
756 static bool canWriteElementInternal(
const ElementType& elem, FieldElemTag<TParams...>)
758 return elem.canWrite();
761 template <
typename... TParams>
762 static bool canWriteElementInternal(
const ElementType& elem, IntegralElemTag<TParams...>)
764 static_cast<void>(elem);
768 template <
typename... TParams>
769 static constexpr bool hasWriteNoStatusInternal(FieldElemTag<TParams...>)
771 return ElementType::hasWriteNoStatus();
774 template <
typename... TParams>
775 static constexpr bool hasWriteNoStatusInternal(IntegralElemTag<TParams...>)
780 template <
typename TIter>
783 if (value_.size() < value_.max_size()) {
784 auto& elem = createBack();
785 auto es = readElement(elem, iter, len);
794 return readElement(elem, iter, len);
This file contains classes required for generic custom assertion functionality.
#define COMMS_ASSERT(expr)
Generic assert macro.
Definition Assert.h:170
Contains various compiler related definitions.
This file contain definition of error statuses used by comms module.
Contains comms::util::StaticString class.
Contains comms::util::StaticVector class.
Contains functions for raw data access / (de)serialization.
Provides helper assign() function to allow easy assignment of values to collections or views.
Contains definition of various tag classes.
comms::option::def::VersionType< T > VersionType
Same as comms::option::def::VersionType.
Definition options.h:1797
comms::option::def::Endian< TEndian > Endian
Same as comms::option::def::Endian.
Definition options.h:1438
void assign(T &obj, TIter from, TIter to)
Assigns a new value to provided object.
Definition assign.h:39
Main namespace for all classes / functions of COMMS library.
ErrorStatus
Error statuses reported by the Communication module.
Definition ErrorStatus.h:17
@ Success
Used to indicate successful outcome of the operation.
constexpr unsigned version()
Version of the COMMS library as single numeric value.
Definition version.h:64
Replacement to std::conditional.
Definition type_traits.h:28
Replacement to some types from standard type_traits.
Various compile-time detection functions of whether specific member functions and/or types exist.