12#include "comms/details/detect.h"
13#include "comms/details/tag.h"
15#include "comms/field/basic/CommonFuncs.h"
16#include "comms/field/details/VersionStorage.h"
21#include "comms/util/MaxSizeOf.h"
44template <
typename TStorage>
45struct ArrayListMaxLengthRetrieveHelper
47 static const std::size_t Value = CommonFuncs::maxSupportedLength();
50template <
typename T, std::
size_t TSize>
51struct ArrayListMaxLengthRetrieveHelper<
comms::util::StaticVector<T, TSize> >
53 static const std::size_t Value = TSize;
56template <std::
size_t TSize>
57struct ArrayListMaxLengthRetrieveHelper<
comms::util::StaticString<TSize> >
59 static const std::size_t Value = TSize - 1;
62template <
typename TElem>
63using ArrayListFieldHasVarLengthBoolType =
64 typename comms::util::LazyDeepConditional<
65 std::is_integral<TElem>::value
67 comms::util::FalseType,
68 comms::util::FieldCheckVarLength,
72template <
typename TElem>
73using HasArrayListElemNonDefaultRefreshBoolType =
74 typename comms::util::LazyDeepConditional<
75 std::is_integral<TElem>::value
77 comms::util::FalseType,
78 comms::util::FieldCheckNonDefaultRefresh,
82template <
typename TElem>
83using IsArrayListElemVersionDependentBoolType =
84 typename comms::util::LazyDeepConditional<
85 std::is_integral<TElem>::value
87 comms::util::FalseType,
88 comms::util::FieldCheckVersionDependent,
92template <
typename TFieldBase,
typename TStorage>
93using ArrayListVersionStorageBase =
94 typename comms::util::LazyShallowConditional<
95 IsArrayListElemVersionDependentBoolType<typename TStorage::value_type>::value
97 comms::field::details::VersionStorage,
98 comms::util::EmptyStruct,
99 typename TFieldBase::VersionType
104template <
typename TFieldBase,
typename TStorage>
107 public details::ArrayListVersionStorageBase<TFieldBase, TStorage>
109 using BaseImpl = TFieldBase;
110 using VersionBaseImpl = details::ArrayListVersionStorageBase<TFieldBase, TStorage>;
113 using Endian =
typename BaseImpl::Endian;
114 using VersionType =
typename BaseImpl::VersionType;
115 using ElementType =
typename TStorage::value_type;
116 using ValueType = TStorage;
119 std::is_integral<ElementType>::value
121 comms::field::tag::RawArrayList,
122 comms::field::tag::ArrayList
125 ArrayList() =
default;
127 explicit ArrayList(
const ValueType& val)
132 explicit ArrayList(ValueType&& val)
133 : m_value(
std::move(val))
137 ArrayList(
const ArrayList&) =
default;
138 ArrayList(ArrayList&&) =
default;
139 ArrayList& operator=(
const ArrayList&) =
default;
140 ArrayList& operator=(ArrayList&&) =
default;
141 ~ArrayList() noexcept = default;
143 const ValueType& value()
const
153 const ValueType& getValue()
const
158 template <
typename T>
159 void setValue(T&& val)
161 value() = std::forward<T>(val);
164 ElementType& createBack()
167 m_value.emplace_back();
168 updateElemVersion(m_value.back(), VersionTag<>());
169 return m_value.back();
174 static_assert(comms::util::detect::hasClearFunc<ValueType>(),
175 "The used storage type for ArrayList must have clear() member function");
180 constexpr std::size_t length()
const
182 return lengthInternal(ElemTag<>());
185 static constexpr std::size_t minLength()
190 static constexpr std::size_t maxLength()
193 details::ArrayListMaxLengthRetrieveHelper<TStorage>::Value *
194 maxLengthInternal(ElemTag<>());
197 constexpr bool valid()
const
199 return validInternal(ElemTag<>());
204 return refreshInternal(ElemTag<>());
207 static constexpr std::size_t minElementLength()
209 return minElemLengthInternal(ElemTag<>());
212 static constexpr std::size_t maxElementLength()
214 return maxElemLengthInternal(ElemTag<>());
217 static constexpr std::size_t elementLength(
const ElementType& elem)
219 return elementLengthInternal(elem, ElemTag<>());
222 template <
typename TIter>
223 static ErrorStatus readElement(ElementType& elem, TIter& iter, std::size_t& len)
225 return readElementInternal(elem, iter, len, ElemTag<>());
228 template <
typename TIter>
229 static void readElementNoStatus(ElementType& elem, TIter& iter)
231 return readElementNoStatusInternal(elem, iter, ElemTag<>());
234 template <
typename TIter>
237 using IterType =
typename std::decay<
decltype(iter)>::type;
239 typename std::iterator_traits<IterType>::iterator_category;
240 static const bool IsRandomAccessIter =
241 std::is_base_of<std::random_access_iterator_tag, IterCategory>::value;
242 static const bool IsRawData =
243 std::is_integral<ElementType>::value && (
sizeof(ElementType) ==
sizeof(std::uint8_t));
246 typename comms::util::LazyShallowConditional<
247 IsRandomAccessIter && IsRawData
252 return readInternal(iter, len, Tag());
255 static constexpr bool hasReadNoStatus()
260 template <
typename TIter>
261 void readNoStatus(TIter& iter) =
delete;
263 template <
typename TIter>
264 ErrorStatus readN(std::size_t count, TIter& iter, std::size_t& len)
266 using IterType =
typename std::decay<
decltype(iter)>::type;
268 typename std::iterator_traits<IterType>::iterator_category;
269 static const bool IsRandomAccessIter =
270 std::is_base_of<std::random_access_iterator_tag, IterCategory>::value;
271 static const bool IsRawData =
272 std::is_integral<ElementType>::value && (
sizeof(ElementType) ==
sizeof(std::uint8_t));
275 typename comms::util::LazyShallowConditional<
276 IsRandomAccessIter && IsRawData
282 return readInternalN(count, iter, len, Tag());
285 template <
typename TIter>
286 void readNoStatusN(std::size_t count, TIter& iter)
288 using IterType =
typename std::decay<
decltype(iter)>::type;
290 typename std::iterator_traits<IterType>::iterator_category;
291 static const bool IsRandomAccessIter =
292 std::is_base_of<std::random_access_iterator_tag, IterCategory>::value;
293 static const bool IsRawData =
294 std::is_integral<ElementType>::value && (
sizeof(ElementType) ==
sizeof(std::uint8_t));
297 typename comms::util::LazyShallowConditional<
298 IsRandomAccessIter && IsRawData
304 return readNoStatusInternalN(count, iter, Tag());
307 static bool canWriteElement(
const ElementType& elem)
309 return canWriteElementInternal(elem, ElemTag<>());
312 template <
typename TIter>
313 static ErrorStatus writeElement(
const ElementType& elem, TIter& iter, std::size_t& len)
315 return writeElementInternal(elem, iter, len, ElemTag<>());
318 template <
typename TIter>
319 static void writeElementNoStatus(
const ElementType& elem, TIter& iter)
321 return writeElementNoStatusInternal(elem, iter, ElemTag<>());
324 bool canWrite()
const
326 return CommonFuncs::canWriteSequence(*
this);
329 template <
typename TIter>
330 ErrorStatus write(TIter& iter, std::size_t len)
const
332 return CommonFuncs::writeSequence(*
this, iter, len);
335 static constexpr bool hasWriteNoStatus()
337 return hasWriteNoStatusInternal(ElemTag<>());
340 template <
typename TIter>
341 void writeNoStatus(TIter& iter)
const
343 CommonFuncs::writeSequenceNoStatus(*
this, iter);
346 template <
typename TIter>
347 ErrorStatus writeN(std::size_t count, TIter& iter, std::size_t& len)
const
349 return CommonFuncs::writeSequenceN(*
this, count, iter, len);
352 template <
typename TIter>
353 void writeNoStatusN(std::size_t count, TIter& iter)
const
355 CommonFuncs::writeSequenceNoStatusN(*
this, count, iter);
358 static constexpr bool isVersionDependent()
360 return details::IsArrayListElemVersionDependentBoolType<ElementType>::value;
363 static constexpr bool hasNonDefaultRefresh()
365 return details::HasArrayListElemNonDefaultRefreshBoolType<ElementType>::value;
368 bool setVersion(VersionType
version)
370 return setVersionInternal(
version, VersionTag<>());
374 template <
typename... TParams>
375 using FieldElemTag = comms::details::tag::Tag1<>;
377 template <
typename... TParams>
378 using IntegralElemTag = comms::details::tag::Tag2<>;
380 template <
typename... TParams>
381 using FixedLengthTag = comms::details::tag::Tag3<>;
383 template <
typename... TParams>
384 using VarLengthTag = comms::details::tag::Tag4<>;
386 template <
typename... TParams>
387 using RawDataTag = comms::details::tag::Tag5<>;
389 template <
typename... TParams>
390 using VersionDependentTag = comms::details::tag::Tag6<>;
392 template <
typename... TParams>
393 using NoVersionDependencyTag = comms::details::tag::Tag7<>;
395 template <
typename... TParams>
398 std::is_integral<ElementType>::value
400 IntegralElemTag<TParams...>,
401 FieldElemTag<TParams...>
404 template <
typename... TParams>
407 details::IsArrayListElemVersionDependentBoolType<ElementType>::value
409 VersionDependentTag<TParams...>,
410 NoVersionDependencyTag<TParams...>
413 template <
typename... TParams>
414 constexpr std::size_t lengthInternal(FieldElemTag<TParams...>)
const
417 typename comms::util::LazyShallowConditional<
418 details::ArrayListFieldHasVarLengthBoolType<ElementType>::value
424 return fieldLength(Tag());
427 template <
typename... TParams>
428 constexpr std::size_t lengthInternal(IntegralElemTag<TParams...>)
const
430 return m_value.size() *
sizeof(ElementType);
433 template <
typename... TParams>
434 constexpr std::size_t fieldLength(FixedLengthTag<TParams...>)
const
436 return ElementType().length() * m_value.size();
439 template <
typename... TParams>
440 std::size_t fieldLength(VarLengthTag<TParams...>)
const
443 std::accumulate(m_value.begin(), m_value.end(), std::size_t(0),
444 [](std::size_t sum,
typename ValueType::const_reference e) -> std::size_t
446 return sum + e.length();
450 template <
typename... TParams>
451 static constexpr std::size_t maxLengthInternal(FieldElemTag<TParams...>)
453 return ElementType::maxLength();
456 template <
typename... TParams>
457 static constexpr std::size_t maxLengthInternal(IntegralElemTag<TParams...>)
459 return sizeof(ElementType);
462 template <
typename TIter>
463 static ErrorStatus readFieldElement(ElementType& elem, TIter& iter, std::size_t& len)
465 auto fromIter = iter;
466 auto es = elem.read(iter, len);
468 auto diff =
static_cast<std::size_t
>(std::distance(fromIter, iter));
475 template <
typename TIter>
476 static ErrorStatus readIntegralElement(ElementType& elem, TIter& iter, std::size_t& len)
478 if (len <
sizeof(ElementType)) {
482 elem = comms::util::readData<ElementType>(iter,
Endian());
483 len -=
sizeof(ElementType);
487 template <
typename TIter,
typename... TParams>
488 static ErrorStatus readElementInternal(ElementType& elem, TIter& iter, std::size_t& len, FieldElemTag<TParams...>)
490 return readFieldElement(elem, iter, len);
493 template <
typename TIter,
typename... TParams>
494 static ErrorStatus readElementInternal(ElementType& elem, TIter& iter, std::size_t& len, IntegralElemTag<TParams...>)
496 return readIntegralElement(elem, iter, len);
499 template <
typename TIter>
500 static void readNoStatusFieldElement(ElementType& elem, TIter& iter)
502 elem.readNoStatus(iter);
505 template <
typename TIter>
506 static void readNoStatusIntegralElement(ElementType& elem, TIter& iter)
508 elem = comms::util::readData<ElementType>(iter,
Endian());
511 template <
typename TIter,
typename... TParams>
512 static void readElementNoStatusInternal(ElementType& elem, TIter& iter, FieldElemTag<TParams...>)
514 readNoStatusFieldElement(elem, iter);
517 template <
typename TIter,
typename... TParams>
518 static void readElementNoStatusInternal(ElementType& elem, TIter& iter, IntegralElemTag<TParams...>)
520 readElementNoStatusInternal(elem, iter);
523 template <
typename TIter>
524 static ErrorStatus writeFieldElement(
const ElementType& elem, TIter& iter, std::size_t& len)
526 auto es = elem.write(iter, len);
528 len -= elem.length();
533 template <
typename TIter>
534 static ErrorStatus writeIntegralElement(
const ElementType& elem, TIter& iter, std::size_t& len)
536 if (len <
sizeof(ElementType)) {
540 BaseImpl::writeData(elem, iter);
541 len -=
sizeof(ElementType);
545 template <
typename TIter,
typename... TParams>
546 static ErrorStatus writeElementInternal(
const ElementType& elem, TIter& iter, std::size_t& len, FieldElemTag<TParams...>)
548 return writeFieldElement(elem, iter, len);
551 template <
typename TIter,
typename... TParams>
552 static ErrorStatus writeElementInternal(
const ElementType& elem, TIter& iter, std::size_t& len, IntegralElemTag<TParams...>)
554 return writeIntegralElement(elem, iter, len);
557 template <
typename TIter>
558 static void writeNoStatusFieldElement(
const ElementType& elem, TIter& iter)
560 elem.writeNoStatus(iter);
563 template <
typename TIter>
564 static void writeNoStatusIntegralElement(
const ElementType& elem, TIter& iter)
566 BaseImpl::writeData(elem, iter);
569 template <
typename TIter,
typename... TParams>
570 static void writeElementNoStatusInternal(
const ElementType& elem, TIter& iter, FieldElemTag<TParams...>)
572 return writeNoStatusFieldElement(elem, iter);
575 template <
typename TIter,
typename... TParams>
576 static void writeElementNoStatusInternal(
const ElementType& elem, TIter& iter, IntegralElemTag<TParams...>)
578 return writeNoStatusIntegralElement(elem, iter);
581 template <
typename... TParams>
582 constexpr bool validInternal(FieldElemTag<TParams...>)
const
585 m_value.begin(), m_value.end(),
586 [](
const ElementType& e) ->
bool
592 template <
typename... TParams>
593 static constexpr bool validInternal(IntegralElemTag<TParams...>)
598 template <
typename... TParams>
599 bool refreshInternal(FieldElemTag<TParams...>)
603 m_value.begin(), m_value.end(),
false,
604 [](
bool prev,
typename ValueType::reference elem) ->
bool
606 return elem.refresh() || prev;
610 template <
typename... TParams>
611 static constexpr bool refreshInternal(IntegralElemTag<TParams...>)
616 template <
typename... TParams>
617 static constexpr std::size_t minElemLengthInternal(IntegralElemTag<TParams...>)
619 return sizeof(ElementType);
622 template <
typename... TParams>
623 static constexpr std::size_t minElemLengthInternal(FieldElemTag<TParams...>)
625 return ElementType::minLength();
628 template <
typename... TParams>
629 static constexpr std::size_t maxElemLengthInternal(IntegralElemTag<TParams...>)
631 return sizeof(ElementType);
634 template <
typename... TParams>
635 static constexpr std::size_t maxElemLengthInternal(FieldElemTag<TParams...>)
637 return ElementType::maxLength();
640 template <
typename... TParams>
641 static constexpr std::size_t elementLengthInternal(
const ElementType&, IntegralElemTag<TParams...>)
643 return sizeof(ElementType);
646 template <
typename... TParams>
647 static constexpr std::size_t elementLengthInternal(
const ElementType& elem, FieldElemTag<TParams...>)
649 return elem.length();
652 template <
typename TIter,
typename... TParams>
653 ErrorStatus readInternal(TIter& iter, std::size_t len, FieldElemTag<TParams...>)
655 static_assert(comms::util::detect::hasClearFunc<ValueType>(),
656 "The used storage type for ArrayList must have clear() member function");
660 auto es = createAndReadNextElementInternal(iter, remLen);
669 template <
typename TIter,
typename... TParams>
670 ErrorStatus readInternal(TIter& iter, std::size_t len, RawDataTag<TParams...>)
673 std::advance(iter, len);
677 template <
typename TIter,
typename... TParams>
678 ErrorStatus readInternalN(std::size_t count, TIter& iter, std::size_t len, FieldElemTag<TParams...>)
682 auto es = createAndReadNextElementInternal(iter, len);
693 template <
typename TIter,
typename... TParams>
694 ErrorStatus readInternalN(std::size_t count, TIter& iter, std::size_t len, RawDataTag<TParams...>)
700 return readInternal(iter, count, RawDataTag<>());
703 template <
typename TIter,
typename... TParams>
704 void readNoStatusInternalN(std::size_t count, TIter& iter, FieldElemTag<TParams...>)
708 if (m_value.size() < m_value.max_size()) {
709 auto& elem = createBack();
710 readElementNoStatus(elem, iter);
714 readElementNoStatus(elem, iter);
720 template <
typename TIter,
typename... TParams>
721 void readNoStatusInternalN(std::size_t count, TIter& iter, RawDataTag<TParams...>)
723 readInternal(iter, count, RawDataTag<>());
726 template <
typename... TParams>
727 bool updateElemVersion(ElementType& elem, VersionDependentTag<TParams...>)
729 return elem.setVersion(VersionBaseImpl::m_version);
732 template <
typename... TParams>
733 static constexpr bool updateElemVersion(ElementType&, NoVersionDependencyTag<TParams...>)
738 template <
typename... TParams>
739 bool setVersionInternal(VersionType
version, VersionDependentTag<TParams...>)
741 VersionBaseImpl::m_version =
version;
742 bool updated =
false;
743 for (
auto& elem : value()) {
744 updated = elem.setVersion(
version) || updated;
750 template <
typename... TParams>
751 static constexpr bool setVersionInternal(VersionType, NoVersionDependencyTag<TParams...>)
756 template <
typename... TParams>
757 static bool canWriteElementInternal(
const ElementType& elem, FieldElemTag<TParams...>)
759 return elem.canWrite();
762 template <
typename... TParams>
763 static bool canWriteElementInternal(
const ElementType& elem, IntegralElemTag<TParams...>)
765 static_cast<void>(elem);
769 template <
typename... TParams>
770 static constexpr bool hasWriteNoStatusInternal(FieldElemTag<TParams...>)
772 return ElementType::hasWriteNoStatus();
775 template <
typename... TParams>
776 static constexpr bool hasWriteNoStatusInternal(IntegralElemTag<TParams...>)
781 template <
typename TIter>
784 if (m_value.size() < m_value.max_size()) {
785 auto& elem = createBack();
786 auto es = readElement(elem, iter, len);
795 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:1917
comms::option::def::Endian< TEndian > Endian
Same as comms::option::def::Endian.
Definition options.h:1460
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:29
Replacement to some types from standard type_traits.
Various compile-time detection functions of whether specific member functions and/or types exist.