14#include "comms/details/detect.h"
15#include "comms/details/tag.h"
17#include "comms/field/basic/CommonFuncs.h"
18#include "comms/field/details/VersionStorage.h"
23#include "comms/util/MaxSizeOf.h"
48template <
typename TStorage>
49struct ArrayListMaxLengthRetrieveHelper
51 static const std::size_t Value = CommonFuncs::maxSupportedLength();
54template <
typename T, std::
size_t TSize>
55struct ArrayListMaxLengthRetrieveHelper<
comms::util::StaticVector<T, TSize> >
57 static const std::size_t Value = TSize;
60template <std::
size_t TSize>
61struct ArrayListMaxLengthRetrieveHelper<
comms::util::StaticString<TSize> >
63 static const std::size_t Value = TSize - 1;
66template <
typename TElem>
67using ArrayListFieldHasVarLengthBoolType =
68 typename comms::util::LazyDeepConditional<
69 std::is_integral<TElem>::value
71 comms::util::FalseType,
72 comms::util::FieldCheckVarLength,
76template <
typename TElem>
77using HasArrayListElemNonDefaultRefreshBoolType =
78 typename comms::util::LazyDeepConditional<
79 std::is_integral<TElem>::value
81 comms::util::FalseType,
82 comms::util::FieldCheckNonDefaultRefresh,
86template <
typename TElem>
87using IsArrayListElemVersionDependentBoolType =
88 typename comms::util::LazyDeepConditional<
89 std::is_integral<TElem>::value
91 comms::util::FalseType,
92 comms::util::FieldCheckVersionDependent,
96template <
typename TFieldBase,
typename TStorage>
97using ArrayListVersionStorageBase =
98 typename comms::util::LazyShallowConditional<
99 IsArrayListElemVersionDependentBoolType<typename TStorage::value_type>::value
101 comms::field::details::VersionStorage,
102 comms::util::EmptyStruct,
103 typename TFieldBase::VersionType
108template <
typename TFieldBase,
typename TStorage>
111 public details::ArrayListVersionStorageBase<TFieldBase, TStorage>
113 using BaseImpl = TFieldBase;
114 using VersionBaseImpl = details::ArrayListVersionStorageBase<TFieldBase, TStorage>;
117 using Endian =
typename BaseImpl::Endian;
118 using VersionType =
typename BaseImpl::VersionType;
119 using ElementType =
typename TStorage::value_type;
120 using ValueType = TStorage;
123 std::is_integral<ElementType>::value
125 comms::field::tag::RawArrayList,
126 comms::field::tag::ArrayList
129 ArrayList() =
default;
131 explicit ArrayList(
const ValueType& val)
136 explicit ArrayList(ValueType&& val)
137 : m_value(
std::move(val))
141 ArrayList(
const ArrayList&) =
default;
142 ArrayList(ArrayList&&) =
default;
143 ArrayList& operator=(
const ArrayList&) =
default;
144 ArrayList& operator=(ArrayList&&) =
default;
145 ~ArrayList() noexcept = default;
147 const ValueType& value()
const
157 const ValueType& getValue()
const
162 template <
typename T>
163 void setValue(T&& val)
165 value() = std::forward<T>(val);
168 ElementType& createBack()
171 m_value.emplace_back();
172 updateElemVersion(m_value.back(), VersionTag<>());
173 return m_value.back();
178 static_assert(comms::util::detect::hasClearFunc<ValueType>(),
179 "The used storage type for ArrayList must have clear() member function");
184 constexpr std::size_t length()
const
186 return lengthInternal(ElemTag<>());
189 static constexpr std::size_t minLength()
194 static constexpr std::size_t maxLength()
197 details::ArrayListMaxLengthRetrieveHelper<TStorage>::Value *
198 maxLengthInternal(ElemTag<>());
201 constexpr bool valid()
const
203 return validInternal(ElemTag<>());
208 return refreshInternal(ElemTag<>());
211 static constexpr std::size_t minElementLength()
213 return minElemLengthInternal(ElemTag<>());
216 static constexpr std::size_t maxElementLength()
218 return maxElemLengthInternal(ElemTag<>());
221 static constexpr std::size_t elementLength(
const ElementType& elem)
223 return elementLengthInternal(elem, ElemTag<>());
226 template <
typename TIter>
227 static ErrorStatus readElement(ElementType& elem, TIter& iter, std::size_t& len)
229 return readElementInternal(elem, iter, len, ElemTag<>());
232 template <
typename TIter>
233 static void readElementNoStatus(ElementType& elem, TIter& iter)
235 return readElementNoStatusInternal(elem, iter, ElemTag<>());
238 template <
typename TIter>
241 using IterType =
typename std::decay<
decltype(iter)>::type;
243 typename std::iterator_traits<IterType>::iterator_category;
244 static const bool IsRandomAccessIter =
245 std::is_base_of<std::random_access_iterator_tag, IterCategory>::value;
246 static const bool IsRawData =
247 std::is_integral<ElementType>::value && (
sizeof(ElementType) ==
sizeof(std::uint8_t));
250 typename comms::util::LazyShallowConditional<
251 IsRandomAccessIter && IsRawData
256 return readInternal(iter, len, Tag());
259 static constexpr bool hasReadNoStatus()
264 template <
typename TIter>
265 void readNoStatus(TIter& iter) =
delete;
267 template <
typename TIter>
268 ErrorStatus readN(std::size_t count, TIter& iter, std::size_t& len)
270 using IterType =
typename std::decay<
decltype(iter)>::type;
272 typename std::iterator_traits<IterType>::iterator_category;
273 static const bool IsRandomAccessIter =
274 std::is_base_of<std::random_access_iterator_tag, IterCategory>::value;
275 static const bool IsRawData =
276 std::is_integral<ElementType>::value && (
sizeof(ElementType) ==
sizeof(std::uint8_t));
279 typename comms::util::LazyShallowConditional<
280 IsRandomAccessIter && IsRawData
286 return readInternalN(count, iter, len, Tag());
289 template <
typename TIter>
290 void readNoStatusN(std::size_t count, TIter& iter)
292 using IterType =
typename std::decay<
decltype(iter)>::type;
294 typename std::iterator_traits<IterType>::iterator_category;
295 static const bool IsRandomAccessIter =
296 std::is_base_of<std::random_access_iterator_tag, IterCategory>::value;
297 static const bool IsRawData =
298 std::is_integral<ElementType>::value && (
sizeof(ElementType) ==
sizeof(std::uint8_t));
301 typename comms::util::LazyShallowConditional<
302 IsRandomAccessIter && IsRawData
308 return readNoStatusInternalN(count, iter, Tag());
311 static bool canWriteElement(
const ElementType& elem)
313 return canWriteElementInternal(elem, ElemTag<>());
316 template <
typename TIter>
317 static ErrorStatus writeElement(
const ElementType& elem, TIter& iter, std::size_t& len)
319 return writeElementInternal(elem, iter, len, ElemTag<>());
322 template <
typename TIter>
323 static void writeElementNoStatus(
const ElementType& elem, TIter& iter)
325 return writeElementNoStatusInternal(elem, iter, ElemTag<>());
328 bool canWrite()
const
330 return CommonFuncs::canWriteSequence(*
this);
333 template <
typename TIter>
334 ErrorStatus write(TIter& iter, std::size_t len)
const
336 return CommonFuncs::writeSequence(*
this, iter, len);
339 static constexpr bool hasWriteNoStatus()
341 return hasWriteNoStatusInternal(ElemTag<>());
344 template <
typename TIter>
345 void writeNoStatus(TIter& iter)
const
347 CommonFuncs::writeSequenceNoStatus(*
this, iter);
350 template <
typename TIter>
351 ErrorStatus writeN(std::size_t count, TIter& iter, std::size_t& len)
const
353 return CommonFuncs::writeSequenceN(*
this, count, iter, len);
356 template <
typename TIter>
357 void writeNoStatusN(std::size_t count, TIter& iter)
const
359 CommonFuncs::writeSequenceNoStatusN(*
this, count, iter);
362 static constexpr bool isVersionDependent()
364 return details::IsArrayListElemVersionDependentBoolType<ElementType>::value;
367 static constexpr bool hasNonDefaultRefresh()
369 return details::HasArrayListElemNonDefaultRefreshBoolType<ElementType>::value;
372 bool setVersion(VersionType
version)
374 return setVersionInternal(
version, VersionTag<>());
378 template <
typename... TParams>
379 using FieldElemTag = comms::details::tag::Tag1<>;
381 template <
typename... TParams>
382 using IntegralElemTag = comms::details::tag::Tag2<>;
384 template <
typename... TParams>
385 using FixedLengthTag = comms::details::tag::Tag3<>;
387 template <
typename... TParams>
388 using VarLengthTag = comms::details::tag::Tag4<>;
390 template <
typename... TParams>
391 using RawDataTag = comms::details::tag::Tag5<>;
393 template <
typename... TParams>
394 using VersionDependentTag = comms::details::tag::Tag6<>;
396 template <
typename... TParams>
397 using NoVersionDependencyTag = comms::details::tag::Tag7<>;
399 template <
typename... TParams>
402 std::is_integral<ElementType>::value
404 IntegralElemTag<TParams...>,
405 FieldElemTag<TParams...>
408 template <
typename... TParams>
411 details::IsArrayListElemVersionDependentBoolType<ElementType>::value
413 VersionDependentTag<TParams...>,
414 NoVersionDependencyTag<TParams...>
417 template <
typename... TParams>
418 constexpr std::size_t lengthInternal(FieldElemTag<TParams...>)
const
421 typename comms::util::LazyShallowConditional<
422 details::ArrayListFieldHasVarLengthBoolType<ElementType>::value
428 return fieldLength(Tag());
431 template <
typename... TParams>
432 constexpr std::size_t lengthInternal(IntegralElemTag<TParams...>)
const
434 return m_value.size() *
sizeof(ElementType);
437 template <
typename... TParams>
438 constexpr std::size_t fieldLength(FixedLengthTag<TParams...>)
const
440 return ElementType().length() * m_value.size();
443 template <
typename... TParams>
444 std::size_t fieldLength(VarLengthTag<TParams...>)
const
447 std::accumulate(m_value.begin(), m_value.end(), std::size_t(0),
448 [](std::size_t sum,
typename ValueType::const_reference e) -> std::size_t
450 return sum + e.length();
454 template <
typename... TParams>
455 static constexpr std::size_t maxLengthInternal(FieldElemTag<TParams...>)
457 return ElementType::maxLength();
460 template <
typename... TParams>
461 static constexpr std::size_t maxLengthInternal(IntegralElemTag<TParams...>)
463 return sizeof(ElementType);
466 template <
typename TIter>
467 static ErrorStatus readFieldElement(ElementType& elem, TIter& iter, std::size_t& len)
469 auto fromIter = iter;
470 auto es = elem.read(iter, len);
472 auto diff =
static_cast<std::size_t
>(std::distance(fromIter, iter));
479 template <
typename TIter>
480 static ErrorStatus readIntegralElement(ElementType& elem, TIter& iter, std::size_t& len)
482 if (len <
sizeof(ElementType)) {
486 elem = comms::util::readData<ElementType>(iter,
Endian());
487 len -=
sizeof(ElementType);
491 template <
typename TIter,
typename... TParams>
492 static ErrorStatus readElementInternal(ElementType& elem, TIter& iter, std::size_t& len, FieldElemTag<TParams...>)
494 return readFieldElement(elem, iter, len);
497 template <
typename TIter,
typename... TParams>
498 static ErrorStatus readElementInternal(ElementType& elem, TIter& iter, std::size_t& len, IntegralElemTag<TParams...>)
500 return readIntegralElement(elem, iter, len);
503 template <
typename TIter>
504 static void readNoStatusFieldElement(ElementType& elem, TIter& iter)
506 elem.readNoStatus(iter);
509 template <
typename TIter>
510 static void readNoStatusIntegralElement(ElementType& elem, TIter& iter)
512 elem = comms::util::readData<ElementType>(iter,
Endian());
515 template <
typename TIter,
typename... TParams>
516 static void readElementNoStatusInternal(ElementType& elem, TIter& iter, FieldElemTag<TParams...>)
518 readNoStatusFieldElement(elem, iter);
521 template <
typename TIter,
typename... TParams>
522 static void readElementNoStatusInternal(ElementType& elem, TIter& iter, IntegralElemTag<TParams...>)
524 readElementNoStatusInternal(elem, iter);
527 template <
typename TIter>
528 static ErrorStatus writeFieldElement(
const ElementType& elem, TIter& iter, std::size_t& len)
530 auto es = elem.write(iter, len);
532 len -= elem.length();
537 template <
typename TIter>
538 static ErrorStatus writeIntegralElement(
const ElementType& elem, TIter& iter, std::size_t& len)
540 if (len <
sizeof(ElementType)) {
544 BaseImpl::writeData(elem, iter);
545 len -=
sizeof(ElementType);
549 template <
typename TIter,
typename... TParams>
550 static ErrorStatus writeElementInternal(
const ElementType& elem, TIter& iter, std::size_t& len, FieldElemTag<TParams...>)
552 return writeFieldElement(elem, iter, len);
555 template <
typename TIter,
typename... TParams>
556 static ErrorStatus writeElementInternal(
const ElementType& elem, TIter& iter, std::size_t& len, IntegralElemTag<TParams...>)
558 return writeIntegralElement(elem, iter, len);
561 template <
typename TIter>
562 static void writeNoStatusFieldElement(
const ElementType& elem, TIter& iter)
564 elem.writeNoStatus(iter);
567 template <
typename TIter>
568 static void writeNoStatusIntegralElement(
const ElementType& elem, TIter& iter)
570 BaseImpl::writeData(elem, iter);
573 template <
typename TIter,
typename... TParams>
574 static void writeElementNoStatusInternal(
const ElementType& elem, TIter& iter, FieldElemTag<TParams...>)
576 return writeNoStatusFieldElement(elem, iter);
579 template <
typename TIter,
typename... TParams>
580 static void writeElementNoStatusInternal(
const ElementType& elem, TIter& iter, IntegralElemTag<TParams...>)
582 return writeNoStatusIntegralElement(elem, iter);
585 template <
typename... TParams>
586 constexpr bool validInternal(FieldElemTag<TParams...>)
const
589 m_value.begin(), m_value.end(),
590 [](
const ElementType& e) ->
bool
596 template <
typename... TParams>
597 static constexpr bool validInternal(IntegralElemTag<TParams...>)
602 template <
typename... TParams>
603 bool refreshInternal(FieldElemTag<TParams...>)
607 m_value.begin(), m_value.end(),
false,
608 [](
bool prev,
typename ValueType::reference elem) ->
bool
610 return elem.refresh() || prev;
614 template <
typename... TParams>
615 static constexpr bool refreshInternal(IntegralElemTag<TParams...>)
620 template <
typename... TParams>
621 static constexpr std::size_t minElemLengthInternal(IntegralElemTag<TParams...>)
623 return sizeof(ElementType);
626 template <
typename... TParams>
627 static constexpr std::size_t minElemLengthInternal(FieldElemTag<TParams...>)
629 return ElementType::minLength();
632 template <
typename... TParams>
633 static constexpr std::size_t maxElemLengthInternal(IntegralElemTag<TParams...>)
635 return sizeof(ElementType);
638 template <
typename... TParams>
639 static constexpr std::size_t maxElemLengthInternal(FieldElemTag<TParams...>)
641 return ElementType::maxLength();
644 template <
typename... TParams>
645 static constexpr std::size_t elementLengthInternal(
const ElementType&, IntegralElemTag<TParams...>)
647 return sizeof(ElementType);
650 template <
typename... TParams>
651 static constexpr std::size_t elementLengthInternal(
const ElementType& elem, FieldElemTag<TParams...>)
653 return elem.length();
656 template <
typename TIter,
typename... TParams>
657 ErrorStatus readInternal(TIter& iter, std::size_t len, FieldElemTag<TParams...>)
659 static_assert(comms::util::detect::hasClearFunc<ValueType>(),
660 "The used storage type for ArrayList must have clear() member function");
664 auto es = createAndReadNextElementInternal(iter, remLen);
673 template <
typename TIter,
typename... TParams>
674 ErrorStatus readInternal(TIter& iter, std::size_t len, RawDataTag<TParams...>)
677 std::advance(iter, len);
681 template <
typename TIter,
typename... TParams>
682 ErrorStatus readInternalN(std::size_t count, TIter& iter, std::size_t len, FieldElemTag<TParams...>)
686 auto es = createAndReadNextElementInternal(iter, len);
697 template <
typename TIter,
typename... TParams>
698 ErrorStatus readInternalN(std::size_t count, TIter& iter, std::size_t len, RawDataTag<TParams...>)
704 return readInternal(iter, count, RawDataTag<>());
707 template <
typename TIter,
typename... TParams>
708 void readNoStatusInternalN(std::size_t count, TIter& iter, FieldElemTag<TParams...>)
712 if (m_value.size() < m_value.max_size()) {
713 auto& elem = createBack();
714 readElementNoStatus(elem, iter);
718 readElementNoStatus(elem, iter);
724 template <
typename TIter,
typename... TParams>
725 void readNoStatusInternalN(std::size_t count, TIter& iter, RawDataTag<TParams...>)
727 readInternal(iter, count, RawDataTag<>());
730 template <
typename... TParams>
731 bool updateElemVersion(ElementType& elem, VersionDependentTag<TParams...>)
733 return elem.setVersion(VersionBaseImpl::m_version);
736 template <
typename... TParams>
737 static constexpr bool updateElemVersion(ElementType&, NoVersionDependencyTag<TParams...>)
742 template <
typename... TParams>
743 bool setVersionInternal(VersionType
version, VersionDependentTag<TParams...>)
745 VersionBaseImpl::m_version =
version;
746 bool updated =
false;
747 for (
auto& elem : value()) {
748 updated = elem.setVersion(
version) || updated;
754 template <
typename... TParams>
755 static constexpr bool setVersionInternal(VersionType, NoVersionDependencyTag<TParams...>)
760 template <
typename... TParams>
761 static bool canWriteElementInternal(
const ElementType& elem, FieldElemTag<TParams...>)
763 return elem.canWrite();
766 template <
typename... TParams>
767 static bool canWriteElementInternal(
const ElementType& elem, IntegralElemTag<TParams...>)
769 static_cast<void>(elem);
773 template <
typename... TParams>
774 static constexpr bool hasWriteNoStatusInternal(FieldElemTag<TParams...>)
776 return ElementType::hasWriteNoStatus();
779 template <
typename... TParams>
780 static constexpr bool hasWriteNoStatusInternal(IntegralElemTag<TParams...>)
785 template <
typename TIter>
788 if (m_value.size() < m_value.max_size()) {
789 auto& elem = createBack();
790 auto es = readElement(elem, iter, len);
799 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:1930
comms::option::def::Endian< TEndian > Endian
Same as comms::option::def::Endian.
Definition options.h:1473
void assign(T &obj, TIter from, TIter to)
Assigns a new value to provided object.
Definition assign.h:41
Main namespace for all classes / functions of COMMS library.
ErrorStatus
Error statuses reported by the Communication module.
Definition ErrorStatus.h:19
@ Success
Used to indicate successful outcome of the operation.
constexpr unsigned version()
Version of the COMMS library as single numeric value.
Definition version.h:66
Replacement to std::conditional.
Definition type_traits.h:32
Replacement to some types from standard type_traits.
Various compile-time detection functions of whether specific member functions and/or types exist.