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"
45template <
typename TStorage>
46struct ArrayListMaxLengthRetrieveHelper
48 static const std::size_t Value = CommonFuncs::maxSupportedLength();
51template <
typename T, std::
size_t TSize>
52struct ArrayListMaxLengthRetrieveHelper<
comms::util::StaticVector<T, TSize> >
54 static const std::size_t Value = TSize;
57template <std::
size_t TSize>
58struct ArrayListMaxLengthRetrieveHelper<
comms::util::StaticString<TSize> >
60 static const std::size_t Value = TSize - 1;
63template <
typename TElem>
64using ArrayListFieldHasVarLengthBoolType =
65 typename comms::util::LazyDeepConditional<
66 std::is_integral<TElem>::value
68 comms::util::FalseType,
69 comms::util::FieldCheckVarLength,
73template <
typename TElem>
74using HasArrayListElemNonDefaultRefreshBoolType =
75 typename comms::util::LazyDeepConditional<
76 std::is_integral<TElem>::value
78 comms::util::FalseType,
79 comms::util::FieldCheckNonDefaultRefresh,
83template <
typename TElem>
84using IsArrayListElemVersionDependentBoolType =
85 typename comms::util::LazyDeepConditional<
86 std::is_integral<TElem>::value
88 comms::util::FalseType,
89 comms::util::FieldCheckVersionDependent,
93template <
typename TFieldBase,
typename TStorage>
94using ArrayListVersionStorageBase =
95 typename comms::util::LazyShallowConditional<
96 IsArrayListElemVersionDependentBoolType<typename TStorage::value_type>::value
98 comms::field::details::VersionStorage,
99 comms::util::EmptyStruct,
100 typename TFieldBase::VersionType
105template <
typename TFieldBase,
typename TStorage>
108 public details::ArrayListVersionStorageBase<TFieldBase, TStorage>
110 using BaseImpl = TFieldBase;
111 using VersionBaseImpl = details::ArrayListVersionStorageBase<TFieldBase, TStorage>;
114 using Endian =
typename BaseImpl::Endian;
115 using VersionType =
typename BaseImpl::VersionType;
116 using ElementType =
typename TStorage::value_type;
117 using ValueType = TStorage;
120 std::is_integral<ElementType>::value
122 comms::field::tag::RawArrayList,
123 comms::field::tag::ArrayList
126 ArrayList() =
default;
128 explicit ArrayList(
const ValueType& val)
133 explicit ArrayList(ValueType&& val)
134 : m_value(
std::move(val))
138 ArrayList(
const ArrayList&) =
default;
139 ArrayList(ArrayList&&) =
default;
140 ArrayList& operator=(
const ArrayList&) =
default;
141 ArrayList& operator=(ArrayList&&) =
default;
142 ~ArrayList() noexcept = default;
144 const ValueType& value()
const
154 const ValueType& getValue()
const
159 template <
typename T>
160 void setValue(T&& val)
162 value() = std::forward<T>(val);
165 ElementType& createBack()
168 m_value.emplace_back();
169 updateElemVersion(m_value.back(), VersionTag<>());
170 return m_value.back();
175 static_assert(comms::util::detect::hasClearFunc<ValueType>(),
176 "The used storage type for ArrayList must have clear() member function");
181 constexpr std::size_t length()
const
183 return lengthInternal(ElemTag<>());
186 static constexpr std::size_t minLength()
191 static constexpr std::size_t maxLength()
194 details::ArrayListMaxLengthRetrieveHelper<TStorage>::Value *
195 maxLengthInternal(ElemTag<>());
198 constexpr bool valid()
const
200 return validInternal(ElemTag<>());
205 return refreshInternal(ElemTag<>());
208 static constexpr std::size_t minElementLength()
210 return minElemLengthInternal(ElemTag<>());
213 static constexpr std::size_t maxElementLength()
215 return maxElemLengthInternal(ElemTag<>());
218 static constexpr std::size_t elementLength(
const ElementType& elem)
220 return elementLengthInternal(elem, ElemTag<>());
223 template <
typename TIter>
224 static ErrorStatus readElement(ElementType& elem, TIter& iter, std::size_t& len)
226 return readElementInternal(elem, iter, len, ElemTag<>());
229 template <
typename TIter>
230 static void readElementNoStatus(ElementType& elem, TIter& iter)
232 return readElementNoStatusInternal(elem, iter, ElemTag<>());
235 template <
typename TIter>
238 using IterType =
typename std::decay<
decltype(iter)>::type;
240 typename std::iterator_traits<IterType>::iterator_category;
241 static const bool IsRandomAccessIter =
242 std::is_base_of<std::random_access_iterator_tag, IterCategory>::value;
243 static const bool IsRawData =
244 std::is_integral<ElementType>::value && (
sizeof(ElementType) ==
sizeof(std::uint8_t));
247 typename comms::util::LazyShallowConditional<
248 IsRandomAccessIter && IsRawData
253 return readInternal(iter, len, Tag());
256 static constexpr bool hasReadNoStatus()
261 template <
typename TIter>
262 void readNoStatus(TIter& iter) =
delete;
264 template <
typename TIter>
265 ErrorStatus readN(std::size_t count, TIter& iter, std::size_t& len)
267 using IterType =
typename std::decay<
decltype(iter)>::type;
269 typename std::iterator_traits<IterType>::iterator_category;
270 static const bool IsRandomAccessIter =
271 std::is_base_of<std::random_access_iterator_tag, IterCategory>::value;
272 static const bool IsRawData =
273 std::is_integral<ElementType>::value && (
sizeof(ElementType) ==
sizeof(std::uint8_t));
276 typename comms::util::LazyShallowConditional<
277 IsRandomAccessIter && IsRawData
283 return readInternalN(count, iter, len, Tag());
286 template <
typename TIter>
287 void readNoStatusN(std::size_t count, TIter& iter)
289 using IterType =
typename std::decay<
decltype(iter)>::type;
291 typename std::iterator_traits<IterType>::iterator_category;
292 static const bool IsRandomAccessIter =
293 std::is_base_of<std::random_access_iterator_tag, IterCategory>::value;
294 static const bool IsRawData =
295 std::is_integral<ElementType>::value && (
sizeof(ElementType) ==
sizeof(std::uint8_t));
298 typename comms::util::LazyShallowConditional<
299 IsRandomAccessIter && IsRawData
305 return readNoStatusInternalN(count, iter, Tag());
308 static bool canWriteElement(
const ElementType& elem)
310 return canWriteElementInternal(elem, ElemTag<>());
313 template <
typename TIter>
314 static ErrorStatus writeElement(
const ElementType& elem, TIter& iter, std::size_t& len)
316 return writeElementInternal(elem, iter, len, ElemTag<>());
319 template <
typename TIter>
320 static void writeElementNoStatus(
const ElementType& elem, TIter& iter)
322 return writeElementNoStatusInternal(elem, iter, ElemTag<>());
325 bool canWrite()
const
327 return CommonFuncs::canWriteSequence(*
this);
330 template <
typename TIter>
331 ErrorStatus write(TIter& iter, std::size_t len)
const
333 return CommonFuncs::writeSequence(*
this, iter, len);
336 static constexpr bool hasWriteNoStatus()
338 return hasWriteNoStatusInternal(ElemTag<>());
341 template <
typename TIter>
342 void writeNoStatus(TIter& iter)
const
344 CommonFuncs::writeSequenceNoStatus(*
this, iter);
347 template <
typename TIter>
348 ErrorStatus writeN(std::size_t count, TIter& iter, std::size_t& len)
const
350 return CommonFuncs::writeSequenceN(*
this, count, iter, len);
353 template <
typename TIter>
354 void writeNoStatusN(std::size_t count, TIter& iter)
const
356 CommonFuncs::writeSequenceNoStatusN(*
this, count, iter);
359 static constexpr bool isVersionDependent()
361 return details::IsArrayListElemVersionDependentBoolType<ElementType>::value;
364 static constexpr bool hasNonDefaultRefresh()
366 return details::HasArrayListElemNonDefaultRefreshBoolType<ElementType>::value;
369 bool setVersion(VersionType
version)
371 return setVersionInternal(
version, VersionTag<>());
375 template <
typename... TParams>
376 using FieldElemTag = comms::details::tag::Tag1<>;
378 template <
typename... TParams>
379 using IntegralElemTag = comms::details::tag::Tag2<>;
381 template <
typename... TParams>
382 using FixedLengthTag = comms::details::tag::Tag3<>;
384 template <
typename... TParams>
385 using VarLengthTag = comms::details::tag::Tag4<>;
387 template <
typename... TParams>
388 using RawDataTag = comms::details::tag::Tag5<>;
390 template <
typename... TParams>
391 using VersionDependentTag = comms::details::tag::Tag6<>;
393 template <
typename... TParams>
394 using NoVersionDependencyTag = comms::details::tag::Tag7<>;
396 template <
typename... TParams>
399 std::is_integral<ElementType>::value
401 IntegralElemTag<TParams...>,
402 FieldElemTag<TParams...>
405 template <
typename... TParams>
408 details::IsArrayListElemVersionDependentBoolType<ElementType>::value
410 VersionDependentTag<TParams...>,
411 NoVersionDependencyTag<TParams...>
414 template <
typename... TParams>
415 constexpr std::size_t lengthInternal(FieldElemTag<TParams...>)
const
418 typename comms::util::LazyShallowConditional<
419 details::ArrayListFieldHasVarLengthBoolType<ElementType>::value
425 return fieldLength(Tag());
428 template <
typename... TParams>
429 constexpr std::size_t lengthInternal(IntegralElemTag<TParams...>)
const
431 return m_value.size() *
sizeof(ElementType);
434 template <
typename... TParams>
435 constexpr std::size_t fieldLength(FixedLengthTag<TParams...>)
const
437 return ElementType().length() * m_value.size();
440 template <
typename... TParams>
441 std::size_t fieldLength(VarLengthTag<TParams...>)
const
444 std::accumulate(m_value.begin(), m_value.end(), std::size_t(0),
445 [](std::size_t sum,
typename ValueType::const_reference e) -> std::size_t
447 return sum + e.length();
451 template <
typename... TParams>
452 static constexpr std::size_t maxLengthInternal(FieldElemTag<TParams...>)
454 return ElementType::maxLength();
457 template <
typename... TParams>
458 static constexpr std::size_t maxLengthInternal(IntegralElemTag<TParams...>)
460 return sizeof(ElementType);
463 template <
typename TIter>
464 static ErrorStatus readFieldElement(ElementType& elem, TIter& iter, std::size_t& len)
466 auto fromIter = iter;
467 auto es = elem.read(iter, len);
469 auto diff =
static_cast<std::size_t
>(std::distance(fromIter, iter));
476 template <
typename TIter>
477 static ErrorStatus readIntegralElement(ElementType& elem, TIter& iter, std::size_t& len)
479 if (len <
sizeof(ElementType)) {
483 elem = comms::util::readData<ElementType>(iter,
Endian());
484 len -=
sizeof(ElementType);
488 template <
typename TIter,
typename... TParams>
489 static ErrorStatus readElementInternal(ElementType& elem, TIter& iter, std::size_t& len, FieldElemTag<TParams...>)
491 return readFieldElement(elem, iter, len);
494 template <
typename TIter,
typename... TParams>
495 static ErrorStatus readElementInternal(ElementType& elem, TIter& iter, std::size_t& len, IntegralElemTag<TParams...>)
497 return readIntegralElement(elem, iter, len);
500 template <
typename TIter>
501 static void readNoStatusFieldElement(ElementType& elem, TIter& iter)
503 elem.readNoStatus(iter);
506 template <
typename TIter>
507 static void readNoStatusIntegralElement(ElementType& elem, TIter& iter)
509 elem = comms::util::readData<ElementType>(iter,
Endian());
512 template <
typename TIter,
typename... TParams>
513 static void readElementNoStatusInternal(ElementType& elem, TIter& iter, FieldElemTag<TParams...>)
515 readNoStatusFieldElement(elem, iter);
518 template <
typename TIter,
typename... TParams>
519 static void readElementNoStatusInternal(ElementType& elem, TIter& iter, IntegralElemTag<TParams...>)
521 readElementNoStatusInternal(elem, iter);
524 template <
typename TIter>
525 static ErrorStatus writeFieldElement(
const ElementType& elem, TIter& iter, std::size_t& len)
527 auto es = elem.write(iter, len);
529 len -= elem.length();
534 template <
typename TIter>
535 static ErrorStatus writeIntegralElement(
const ElementType& elem, TIter& iter, std::size_t& len)
537 if (len <
sizeof(ElementType)) {
541 BaseImpl::writeData(elem, iter);
542 len -=
sizeof(ElementType);
546 template <
typename TIter,
typename... TParams>
547 static ErrorStatus writeElementInternal(
const ElementType& elem, TIter& iter, std::size_t& len, FieldElemTag<TParams...>)
549 return writeFieldElement(elem, iter, len);
552 template <
typename TIter,
typename... TParams>
553 static ErrorStatus writeElementInternal(
const ElementType& elem, TIter& iter, std::size_t& len, IntegralElemTag<TParams...>)
555 return writeIntegralElement(elem, iter, len);
558 template <
typename TIter>
559 static void writeNoStatusFieldElement(
const ElementType& elem, TIter& iter)
561 elem.writeNoStatus(iter);
564 template <
typename TIter>
565 static void writeNoStatusIntegralElement(
const ElementType& elem, TIter& iter)
567 BaseImpl::writeData(elem, iter);
570 template <
typename TIter,
typename... TParams>
571 static void writeElementNoStatusInternal(
const ElementType& elem, TIter& iter, FieldElemTag<TParams...>)
573 return writeNoStatusFieldElement(elem, iter);
576 template <
typename TIter,
typename... TParams>
577 static void writeElementNoStatusInternal(
const ElementType& elem, TIter& iter, IntegralElemTag<TParams...>)
579 return writeNoStatusIntegralElement(elem, iter);
582 template <
typename... TParams>
583 constexpr bool validInternal(FieldElemTag<TParams...>)
const
586 m_value.begin(), m_value.end(),
587 [](
const ElementType& e) ->
bool
593 template <
typename... TParams>
594 static constexpr bool validInternal(IntegralElemTag<TParams...>)
599 template <
typename... TParams>
600 bool refreshInternal(FieldElemTag<TParams...>)
604 m_value.begin(), m_value.end(),
false,
605 [](
bool prev,
typename ValueType::reference elem) ->
bool
607 return elem.refresh() || prev;
611 template <
typename... TParams>
612 static constexpr bool refreshInternal(IntegralElemTag<TParams...>)
617 template <
typename... TParams>
618 static constexpr std::size_t minElemLengthInternal(IntegralElemTag<TParams...>)
620 return sizeof(ElementType);
623 template <
typename... TParams>
624 static constexpr std::size_t minElemLengthInternal(FieldElemTag<TParams...>)
626 return ElementType::minLength();
629 template <
typename... TParams>
630 static constexpr std::size_t maxElemLengthInternal(IntegralElemTag<TParams...>)
632 return sizeof(ElementType);
635 template <
typename... TParams>
636 static constexpr std::size_t maxElemLengthInternal(FieldElemTag<TParams...>)
638 return ElementType::maxLength();
641 template <
typename... TParams>
642 static constexpr std::size_t elementLengthInternal(
const ElementType&, IntegralElemTag<TParams...>)
644 return sizeof(ElementType);
647 template <
typename... TParams>
648 static constexpr std::size_t elementLengthInternal(
const ElementType& elem, FieldElemTag<TParams...>)
650 return elem.length();
653 template <
typename TIter,
typename... TParams>
654 ErrorStatus readInternal(TIter& iter, std::size_t len, FieldElemTag<TParams...>)
656 static_assert(comms::util::detect::hasClearFunc<ValueType>(),
657 "The used storage type for ArrayList must have clear() member function");
661 auto es = createAndReadNextElementInternal(iter, remLen);
670 template <
typename TIter,
typename... TParams>
671 ErrorStatus readInternal(TIter& iter, std::size_t len, RawDataTag<TParams...>)
674 std::advance(iter, len);
678 template <
typename TIter,
typename... TParams>
679 ErrorStatus readInternalN(std::size_t count, TIter& iter, std::size_t len, FieldElemTag<TParams...>)
683 auto es = createAndReadNextElementInternal(iter, len);
694 template <
typename TIter,
typename... TParams>
695 ErrorStatus readInternalN(std::size_t count, TIter& iter, std::size_t len, RawDataTag<TParams...>)
701 return readInternal(iter, count, RawDataTag<>());
704 template <
typename TIter,
typename... TParams>
705 void readNoStatusInternalN(std::size_t count, TIter& iter, FieldElemTag<TParams...>)
709 if (m_value.size() < m_value.max_size()) {
710 auto& elem = createBack();
711 readElementNoStatus(elem, iter);
715 readElementNoStatus(elem, iter);
721 template <
typename TIter,
typename... TParams>
722 void readNoStatusInternalN(std::size_t count, TIter& iter, RawDataTag<TParams...>)
724 readInternal(iter, count, RawDataTag<>());
727 template <
typename... TParams>
728 bool updateElemVersion(ElementType& elem, VersionDependentTag<TParams...>)
730 return elem.setVersion(VersionBaseImpl::m_version);
733 template <
typename... TParams>
734 static constexpr bool updateElemVersion(ElementType&, NoVersionDependencyTag<TParams...>)
739 template <
typename... TParams>
740 bool setVersionInternal(VersionType
version, VersionDependentTag<TParams...>)
742 VersionBaseImpl::m_version =
version;
743 bool updated =
false;
744 for (
auto& elem : value()) {
745 updated = elem.setVersion(
version) || updated;
751 template <
typename... TParams>
752 static constexpr bool setVersionInternal(VersionType, NoVersionDependencyTag<TParams...>)
757 template <
typename... TParams>
758 static bool canWriteElementInternal(
const ElementType& elem, FieldElemTag<TParams...>)
760 return elem.canWrite();
763 template <
typename... TParams>
764 static bool canWriteElementInternal(
const ElementType& elem, IntegralElemTag<TParams...>)
766 static_cast<void>(elem);
770 template <
typename... TParams>
771 static constexpr bool hasWriteNoStatusInternal(FieldElemTag<TParams...>)
773 return ElementType::hasWriteNoStatus();
776 template <
typename... TParams>
777 static constexpr bool hasWriteNoStatusInternal(IntegralElemTag<TParams...>)
782 template <
typename TIter>
785 if (m_value.size() < m_value.max_size()) {
786 auto& elem = createBack();
787 auto es = readElement(elem, iter, len);
796 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:168
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:1928
comms::option::def::Endian< TEndian > Endian
Same as comms::option::def::Endian.
Definition options.h:1471
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.