15#include "comms/details/tag.h"
16#include "comms/field/basic/CommonFuncs.h"
17#include "comms/field/details/FieldOpHelpers.h"
25template <
typename TAllFields>
26class MessageImplFieldsContainer;
28template <
typename... TAllFields>
29class MessageImplFieldsContainer<
std::tuple<TAllFields...> >
32 using AllFields = std::tuple<TAllFields...>;
39 const AllFields& fields()
const
44 static constexpr bool areFieldsVersionDependent()
46 return comms::field::basic::CommonFuncs::IsAnyFieldVersionDependentBoolType<TAllFields...>::value;
49 static constexpr bool doFieldsHaveNonDefaultRefresh()
51 return comms::field::basic::CommonFuncs::AnyFieldHasNonDefaultRefreshBoolType<TAllFields...>::value;
54 template <
typename TIter>
58 typename comms::util::LazyShallowConditional<
59 comms::field::basic::CommonFuncs::AllFieldsHaveReadNoStatusBoolType<TAllFields...>::value
65 return doReadInternal(iter, size, Tag());
68 template <
typename TIter>
71 std::size_t size)
const
75 typename comms::util::LazyShallowConditional<
76 comms::field::basic::CommonFuncs::AllFieldsHaveWriteNoStatusBoolType<TAllFields...>::value
82 return doWriteInternal(iter, size, Tag());
90 std::size_t doLength()
const
92 return util::tupleAccumulate(fields(),
static_cast<std::size_t
>(0U), comms::field::details::FieldLengthSumCalcHelper<>());
95 template <std::
size_t TFromIdx>
96 std::size_t doLengthFrom()
const
99 util::tupleAccumulateFromUntil<TFromIdx, std::tuple_size<AllFields>::value>(
100 fields(),
static_cast<std::size_t
>(0U), comms::field::details::FieldLengthSumCalcHelper<>());
103 template <std::
size_t TUntilIdx>
104 std::size_t doLengthUntil()
const
107 util::tupleAccumulateFromUntil<0, TUntilIdx>(
108 fields(),
static_cast<std::size_t
>(0U), comms::field::details::FieldLengthSumCalcHelper<>());
111 template <std::
size_t TFromIdx, std::
size_t TUntilIdx>
112 std::size_t doLengthFromUntil()
const
115 util::tupleAccumulateFromUntil<TFromIdx, TUntilIdx>(
116 fields(),
static_cast<std::size_t
>(0U), comms::field::details::FieldLengthSumCalcHelper<>());
119 static constexpr std::size_t doMinLength()
122 comms::util::tupleTypeAccumulate<AllFields>(
123 std::size_t(0), comms::field::details::FieldMinLengthSumCalcHelper<>());
126 template <std::
size_t TFromIdx>
127 static constexpr std::size_t doMinLengthFrom()
130 comms::util::tupleTypeAccumulateFromUntil<TFromIdx, std::tuple_size<AllFields>::value, AllFields>(
131 std::size_t(0), comms::field::details::FieldMinLengthSumCalcHelper<>());
134 template <std::
size_t TUntilIdx>
135 static constexpr std::size_t doMinLengthUntil()
138 comms::util::tupleTypeAccumulateFromUntil<0, TUntilIdx, AllFields>(
139 std::size_t(0), comms::field::details::FieldMinLengthSumCalcHelper<>());
142 template <std::
size_t TFromIdx, std::
size_t TUntilIdx>
143 static constexpr std::size_t doMinLengthFromUntil()
146 comms::util::tupleTypeAccumulateFromUntil<TFromIdx, TUntilIdx, AllFields>(
147 std::size_t(0), comms::field::details::FieldMinLengthSumCalcHelper<>());
150 static constexpr std::size_t doMaxLength()
153 comms::util::tupleTypeAccumulate<AllFields>(
154 std::size_t(0), comms::field::details::FieldMaxLengthSumCalcHelper<>());
157 template <std::
size_t TFromIdx>
158 static constexpr std::size_t doMaxLengthFrom()
161 comms::util::tupleTypeAccumulateFromUntil<TFromIdx, std::tuple_size<AllFields>::value, AllFields>(
162 std::size_t(0), comms::field::details::FieldMaxLengthSumCalcHelper<>());
165 template <std::
size_t TUntilIdx>
166 static constexpr std::size_t doMaxLengthUntil()
169 comms::util::tupleTypeAccumulateFromUntil<0, TUntilIdx, AllFields>(
170 std::size_t(0), comms::field::details::FieldMaxLengthSumCalcHelper<>());
173 template <std::
size_t TFromIdx, std::
size_t TUntilIdx>
174 static constexpr std::size_t doMaxLengthFromUntil()
177 comms::util::tupleTypeAccumulateFromUntil<TFromIdx, TUntilIdx, AllFields>(
178 std::size_t(0), comms::field::details::FieldMaxLengthSumCalcHelper<>());
187 ~MessageImplFieldsContainer() noexcept = default;
189 template <
std::
size_t TIdx, typename TIter>
194 return doReadUntilAndUpdateLen<TIdx>(iter, len);
197 template <std::
size_t TIdx,
typename TIter>
203 util::tupleForEachUntil<TIdx>(fields(), makeFieldReader(iter, status, len));
207 template <std::
size_t TIdx,
typename TIter>
208 void doReadNoStatusUntil(TIter& iter)
210 util::tupleForEachUntil<TIdx>(fields(), makeFieldNoStatusReader(iter));
213 template <std::
size_t TIdx,
typename TIter>
218 return doReadFromAndUpdateLen<TIdx>(iter, len);
221 template <std::
size_t TIdx,
typename TIter>
227 util::tupleForEachFrom<TIdx>(fields(), makeFieldReader(iter, status, len));
231 template <std::
size_t TIdx,
typename TIter>
232 void doReadNoStatusFrom(TIter& iter)
234 util::tupleForEachFrom<TIdx>(fields(), makeFieldNoStatusReader(iter));
237 template <std::
size_t TFromIdx, std::
size_t TUntilIdx,
typename TIter>
242 return doReadFromUntilAndUpdateLen<TFromIdx, TUntilIdx>(iter, len);
245 template <std::
size_t TFromIdx, std::
size_t TUntilIdx,
typename TIter>
251 util::tupleForEachFromUntil<TFromIdx, TUntilIdx>(fields(), makeFieldReader(iter, status, len));
255 template <std::
size_t TFromIdx, std::
size_t TUntilIdx,
typename TIter>
256 void doReadNoStatusFromUntil(TIter& iter)
258 util::tupleForEachFromUntil<TFromIdx, TUntilIdx>(fields(), makeFieldNoStatusReader(iter));
261 template <std::
size_t TIdx,
typename TIter>
264 std::size_t len)
const
266 return doWriteUntilAndUpdateLen<TIdx>(iter, len);
269 template <std::
size_t TIdx,
typename TIter>
272 std::size_t& len)
const
275 util::tupleForEachUntil<TIdx>(fields(), makeFieldWriter(iter, status, len));
279 template <std::
size_t TIdx,
typename TIter>
280 void doWriteNoStatusUntil(TIter& iter)
const
282 util::tupleForEachUntil<TIdx>(fields(), makeFieldNoStatusWriter(iter));
285 template <std::
size_t TIdx,
typename TIter>
288 std::size_t len)
const
290 return doWriteFromAndUpdateLen<TIdx>(iter, len);
293 template <std::
size_t TIdx,
typename TIter>
296 std::size_t& len)
const
299 util::tupleForEachFrom<TIdx>(fields(), makeFieldWriter(iter, status, len));
303 template <std::
size_t TIdx,
typename TIter>
304 void doWriteNoStatusFrom(TIter& iter)
const
306 util::tupleForEachFrom<TIdx>(fields(), makeFieldNoStatusWriter(iter));
309 template <std::
size_t TFromIdx, std::
size_t TUntilIdx,
typename TIter>
312 std::size_t len)
const
314 return doWriteFromUntilAndUpdateLen<TFromIdx, TUntilIdx>(iter, len);
317 template <std::
size_t TFromIdx, std::
size_t TUntilIdx,
typename TIter>
320 std::size_t& len)
const
323 util::tupleForEachFromUntil<TFromIdx, TUntilIdx>(fields(), makeFieldWriter(iter, status, len));
327 template <std::
size_t TFromIdx, std::
size_t TUntilIdx,
typename TIter>
328 void doWriteNoStatusFromUntil(TIter& iter)
const
330 util::tupleForEachFromUntil<TFromIdx, TUntilIdx>(fields(), makeFieldNoStatusWriter(iter));
334 template <
typename... TParams>
335 using NoStatusTag = comms::details::tag::Tag1<>;
337 template <
typename... TParams>
338 using UseStatusTag = comms::details::tag::Tag2<>;
340 template <
typename TIter,
typename... TParams>
344 UseStatusTag<TParams...>)
346 return doReadFromAndUpdateLen<0>(iter, size);
349 template <
typename TIter,
typename... TParams>
353 NoStatusTag<TParams...>)
355 if (size < doLength()) {
359 doReadNoStatusFrom<0>(iter);
363 template <
typename TIter,
typename... TParams>
367 UseStatusTag<TParams...>)
const
369 return doWriteFromAndUpdateLen<0>(iter, size);
372 template <
typename TIter,
typename... TParams>
376 NoStatusTag<TParams...>)
const
378 if (size < doLength()) {
382 doWriteNoStatusFrom<0>(iter);
386 template <
typename TIter>
387 static comms::field::details::FieldReadHelper<TIter> makeFieldReader(
392 return comms::field::details::FieldReadHelper<TIter>(status, iter, size);
395 template <
typename TIter>
396 static comms::field::details::FieldReadNoStatusHelper<TIter> makeFieldNoStatusReader(TIter& iter)
398 return comms::field::details::FieldReadNoStatusHelper<TIter>(iter);
401 template <
typename TIter>
402 static comms::field::details::FieldWriteHelper<TIter> makeFieldWriter(
407 return comms::field::details::FieldWriteHelper<TIter>(status, iter, size);
410 template <
typename TIter>
411 static comms::field::details::FieldWriteNoStatusHelper<TIter> makeFieldNoStatusWriter(TIter& iter)
413 return comms::field::details::FieldWriteNoStatusHelper<TIter>(iter);
421template <
typename TBase,
typename TAllFields>
422class MessageImplFieldsBase :
public TBase,
public MessageImplFieldsContainer<TAllFields>
424 using ContainerBase = MessageImplFieldsContainer<TAllFields>;
426 using ContainerBase::doRead;
427 using ContainerBase::doWrite;
428 using ContainerBase::doLength;
429 using ContainerBase::doValid;
430 using ContainerBase::doRefresh;
431 using ContainerBase::doLengthFrom;
432 using ContainerBase::doLengthUntil;
433 using ContainerBase::doLengthFromUntil;
434 using ContainerBase::doMinLength;
435 using ContainerBase::doMinLengthFrom;
436 using ContainerBase::doMinLengthUntil;
437 using ContainerBase::doMinLengthFromUntil;
438 using ContainerBase::doMaxLength;
439 using ContainerBase::doMaxLengthFrom;
440 using ContainerBase::doMaxLengthUntil;
441 using ContainerBase::doMaxLengthFromUntil;
442 using ContainerBase::areFieldsVersionDependent;
445 ~MessageImplFieldsBase() noexcept = default;
447 using ContainerBase::doReadUntil;
448 using ContainerBase::doReadUntilAndUpdateLen;
449 using ContainerBase::doReadNoStatusUntil;
450 using ContainerBase::doReadFrom;
451 using ContainerBase::doReadFromAndUpdateLen;
452 using ContainerBase::doReadNoStatusFrom;
453 using ContainerBase::doReadFromUntil;
454 using ContainerBase::doReadFromUntilAndUpdateLen;
455 using ContainerBase::doReadNoStatusFromUntil;
456 using ContainerBase::doWriteUntil;
457 using ContainerBase::doWriteUntilAndUpdateLen;
458 using ContainerBase::doWriteNoStatusUntil;
459 using ContainerBase::doWriteFrom;
460 using ContainerBase::doWriteFromAndUpdateLen;
461 using ContainerBase::doWriteNoStatusFrom;
462 using ContainerBase::doWriteFromUntil;
463 using ContainerBase::doWriteFromUntilAndUpdateLen;
464 using ContainerBase::doWriteNoStatusFromUntil;
469template <typename TBase>
470class MessageImplVersionBase : public TBase
475 bool doFieldsVersionUpdate()
477 return comms::field::basic::CommonFuncs::setVersionForMembers(TBase::fields(), TBase::version());
480 template <
typename TIter>
483 doFieldsVersionUpdate();
484 return TBase::doRead(iter, len);
489 bool updated = doFieldsVersionUpdate();
490 return TBase::doRefresh() || updated;
494 MessageImplVersionBase()
496 doFieldsVersionUpdate();
499 MessageImplVersionBase(
const MessageImplVersionBase&) =
default;
500 MessageImplVersionBase(MessageImplVersionBase&&) =
default;
501 ~MessageImplVersionBase() noexcept = default;
503 MessageImplVersionBase& operator=(const MessageImplVersionBase&) = default;
504 MessageImplVersionBase& operator=(MessageImplVersionBase&&) = default;
509template <typename TBase, typename TActual =
void>
510class MessageImplFieldsReadImplBase : public TBase
512 using BaseImpl = TBase;
514 ~MessageImplFieldsReadImplBase() noexcept = default;
516 typename BaseImpl::ReadIterator& iter,
517 std::
size_t size)
override
520 typename comms::util::LazyShallowConditional<
521 std::is_same<TActual, void>::value
526 return readImplInternal(iter, size, Tag());
530 template <
typename... TParams>
531 using HasActual = comms::details::tag::Tag1<>;
533 template <
typename... TParams>
534 using NoActual = comms::details::tag::Tag2<>;
536 template <
typename... TParams>
538 typename BaseImpl::ReadIterator& iter,
540 NoActual<TParams...>)
542 return BaseImpl::doRead(iter, size);
545 template <
typename... TParams>
547 typename BaseImpl::ReadIterator& iter,
549 HasActual<TParams...>)
551 return static_cast<TActual*
>(
this)->doRead(iter, size);
557template <
typename TBase,
typename TActual =
void>
558class MessageImplFieldsWriteImplBase :
public TBase
560 using BaseImpl = TBase;
563 ~MessageImplFieldsWriteImplBase() noexcept = default;
564 virtual
comms::ErrorStatus writeImpl(
565 typename BaseImpl::WriteIterator& iter,
566 std::
size_t size)
const override
569 typename comms::util::LazyShallowConditional<
570 std::is_same<TActual, void>::value
575 return writeImplInternal(iter, size, Tag());
579 template <
typename... TParams>
580 using HasActual = comms::details::tag::Tag1<>;
582 template <
typename... TParams>
583 using NoActual = comms::details::tag::Tag2<>;
585 template <
typename... TParams>
587 typename BaseImpl::WriteIterator& iter,
589 NoActual<TParams...>)
const
591 return BaseImpl::doWrite(iter, size);
594 template <
typename... TParams>
596 typename BaseImpl::WriteIterator& iter,
598 HasActual<TParams...>)
const
600 return static_cast<const TActual*
>(
this)->doWrite(iter, size);
606template <
typename TBase,
typename TActual =
void>
607class MessageImplFieldsValidBase :
public TBase
609 using BaseImpl = TBase;
612 ~MessageImplFieldsValidBase() noexcept = default;
613 virtual
bool validImpl()
const override
616 typename comms::util::LazyShallowConditional<
617 std::is_same<TActual, void>::value
622 return validImplInternal(Tag());
626 template <
typename... TParams>
627 using HasActual = comms::details::tag::Tag1<>;
629 template <
typename... TParams>
630 using NoActual = comms::details::tag::Tag2<>;
632 template <
typename... TParams>
633 bool validImplInternal(NoActual<TParams...>)
const
635 return BaseImpl::doValid();
638 template <
typename... TParams>
639 bool validImplInternal(HasActual<TParams...>)
const
641 return static_cast<const TActual*
>(
this)->doValid();
647template <
typename TBase,
typename TActual =
void>
648class MessageImplFieldsLengthBase :
public TBase
650 using BaseImpl = TBase;
653 ~MessageImplFieldsLengthBase() noexcept = default;
654 virtual
std::
size_t lengthImpl()
const override
657 typename comms::util::LazyShallowConditional<
658 std::is_same<TActual, void>::value
663 return lengthImplInternal(Tag());
667 template <
typename... TParams>
668 using HasActual = comms::details::tag::Tag1<>;
670 template <
typename... TParams>
671 using NoActual = comms::details::tag::Tag2<>;
673 template <
typename... TParams>
674 std::size_t lengthImplInternal(NoActual<TParams...>)
const
676 return BaseImpl::doLength();
679 template <
typename... TParams>
680 std::size_t lengthImplInternal(HasActual<TParams...>)
const
682 return static_cast<const TActual*
>(
this)->doLength();
688template <
typename TBase,
typename TActual,
typename TFailOnInval
idStatusWrapper>
689class MessageImplFailOnInvalidBase :
public TBase
691 using BaseImpl = TBase;
694 template <
typename TIter>
697 auto es = TBase::doRead(iter, len);
702 if (!doValidInternal()) {
703 return TFailOnInvalidStatusWrapper::Value;
710 ~MessageImplFailOnInvalidBase() noexcept = default;
713 template <typename... TParams>
714 using HasActual =
comms::details::tag::Tag1<>;
716 template <typename... TParams>
717 using NoActual =
comms::details::tag::Tag2<>;
719 template <typename... TParams>
720 bool doValidInternal(NoActual<TParams...>)
const
722 return BaseImpl::doValid();
725 template <
typename... TParams>
726 bool doValidInternal(HasActual<TParams...>)
const
728 return static_cast<const TActual*
>(
this)->doValid();
731 bool doValidInternal()
const
734 typename comms::util::LazyShallowConditional<
735 std::is_same<TActual, void>::value
741 return doValidInternal(Tag());
748template <
typename TBase,
typename TActual =
void>
749class MessageImplRefreshBase :
public TBase
752 ~MessageImplRefreshBase() noexcept = default;
753 virtual
bool refreshImpl()
override
756 typename comms::util::LazyShallowConditional<
757 std::is_same<TActual, void>::value
762 return refreshInternal(Tag());
766 template <
typename... TParams>
767 using Downcast = comms::details::tag::Tag1<>;
769 template <
typename... TParams>
770 using NoDowncast = comms::details::tag::Tag2<>;
772 template <
typename... TParams>
773 bool refreshInternal(Downcast<TParams...>)
775 return static_cast<TActual*
>(
this)->doRefresh();
778 template <
typename... TParams>
779 bool refreshInternal(NoDowncast<TParams...>)
781 return TBase::doRefresh();
787template <
typename TBase,
typename TActual>
788class MessageImplDispatchBase :
public TBase
790 using BaseImpl = TBase;
792 ~MessageImplDispatchBase() noexcept = default;
793 virtual typename TBase::DispatchRetType dispatchImpl(typename TBase::Handler& handler)
override
795 static_assert(std::is_base_of<TBase, TActual>::value,
796 "TActual is not derived class");
797 return handler.handle(
static_cast<TActual&
>(*
this));
803template <
typename TBase, std::
intmax_t TId>
804class MessageImplStaticNumIdBase :
public TBase
807 static const typename TBase::MsgIdType MsgId =
808 static_cast<typename TBase::MsgIdType
>(TId);
810 static constexpr typename TBase::MsgIdParamType doGetId()
816 ~MessageImplStaticNumIdBase() noexcept = default;
821template <typename TBase, typename TActual =
void>
822class MessageImplPolymorhpicStaticNumIdBase : public TBase
825 ~MessageImplPolymorhpicStaticNumIdBase() noexcept = default;
826 virtual typename TBase::MsgIdParamType getIdImpl()
const override
829 typename comms::util::LazyShallowConditional<
830 std::is_same<TActual, void>::value
835 return getIdInternal(Tag());
839 template <
typename... TParams>
840 using DowncastTag = comms::details::tag::Tag1<>;
842 template <
typename... TParams>
843 using NoDowncastTag = comms::details::tag::Tag2<>;
845 template <
typename... TParams>
846 typename TBase::MsgIdParamType getIdInternal(NoDowncastTag<TParams...>)
const
848 return TBase::doGetId();
851 template <
typename... TParams>
852 typename TBase::MsgIdParamType getIdInternal(DowncastTag<TParams...>)
const
854 return static_cast<const TActual*
>(
this)->doGetId();
860template <
typename TBase>
861class MessageImplNoIdBase :
public TBase
864 ~MessageImplNoIdBase() noexcept = default;
865 virtual typename TBase::MsgIdParamType getIdImpl()
const override
867 static const typename TBase::MsgIdType MsgId =
typename TBase::MsgIdType();
868 static constexpr bool The_message_id_is_not_supposed_to_be_retrieved =
false;
869 static_cast<void>(The_message_id_is_not_supposed_to_be_retrieved);
870 COMMS_ASSERT(The_message_id_is_not_supposed_to_be_retrieved);
877template <
typename TBase,
typename TActual>
878class MessageImplNameBase :
public TBase
881 ~MessageImplNameBase() noexcept = default;
882 virtual const
char* nameImpl()
const override
884 return static_cast<const TActual*
>(
this)->doName();
#define COMMS_ASSERT(expr)
Generic assert macro.
Definition Assert.h:170
This file contain definition of error statuses used by comms module.
Contains various tuple type manipulation classes and functions.
comms::option::def::VersionType< T > VersionType
Same as comms::option::def::VersionType.
Definition options.h:1797
constexpr TValue tupleAccumulate(TTuple &&tuple, const TValue &value, TFunc &&func)
Performs "accumulate" algorithm on every element of the tuple.
Definition Tuple.h:586
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.