12#include "comms/details/tag.h"
14#include "comms/field/basic/CommonFuncs.h"
15#include "comms/field/details/FieldOpHelpers.h"
28template <
typename TAllFields>
29class MessageImplFieldsContainer;
31template <
typename... TAllFields>
32class MessageImplFieldsContainer<
std::tuple<TAllFields...> >
35 using AllFields = std::tuple<TAllFields...>;
42 const AllFields& fields()
const
47 static constexpr bool areFieldsVersionDependent()
49 return comms::field::basic::CommonFuncs::IsAnyFieldVersionDependentBoolType<TAllFields...>::value;
52 static constexpr bool doFieldsHaveNonDefaultRefresh()
54 return comms::field::basic::CommonFuncs::AnyFieldHasNonDefaultRefreshBoolType<TAllFields...>::value;
57 template <
typename TIter>
61 typename comms::util::LazyShallowConditional<
62 comms::field::basic::CommonFuncs::AllFieldsHaveReadNoStatusBoolType<TAllFields...>::value
68 return doReadInternal(iter, size, Tag());
71 template <
typename TIter>
74 std::size_t size)
const
78 typename comms::util::LazyShallowConditional<
79 comms::field::basic::CommonFuncs::AllFieldsHaveWriteNoStatusBoolType<TAllFields...>::value
85 return doWriteInternal(iter, size, Tag());
93 std::size_t doLength()
const
95 return util::tupleAccumulate(fields(),
static_cast<std::size_t
>(0U), comms::field::details::FieldLengthSumCalcHelper<>());
98 template <std::
size_t TFromIdx>
99 std::size_t doLengthFrom()
const
102 util::tupleAccumulateFromUntil<TFromIdx, std::tuple_size<AllFields>::value>(
103 fields(),
static_cast<std::size_t
>(0U), comms::field::details::FieldLengthSumCalcHelper<>());
106 template <std::
size_t TUntilIdx>
107 std::size_t doLengthUntil()
const
110 util::tupleAccumulateFromUntil<0, TUntilIdx>(
111 fields(),
static_cast<std::size_t
>(0U), comms::field::details::FieldLengthSumCalcHelper<>());
114 template <std::
size_t TFromIdx, std::
size_t TUntilIdx>
115 std::size_t doLengthFromUntil()
const
118 util::tupleAccumulateFromUntil<TFromIdx, TUntilIdx>(
119 fields(),
static_cast<std::size_t
>(0U), comms::field::details::FieldLengthSumCalcHelper<>());
122 static constexpr std::size_t doMinLength()
125 comms::util::tupleTypeAccumulate<AllFields>(
126 std::size_t(0), comms::field::details::FieldMinLengthSumCalcHelper<>());
129 template <std::
size_t TFromIdx>
130 static constexpr std::size_t doMinLengthFrom()
133 comms::util::tupleTypeAccumulateFromUntil<TFromIdx, std::tuple_size<AllFields>::value, AllFields>(
134 std::size_t(0), comms::field::details::FieldMinLengthSumCalcHelper<>());
137 template <std::
size_t TUntilIdx>
138 static constexpr std::size_t doMinLengthUntil()
141 comms::util::tupleTypeAccumulateFromUntil<0, TUntilIdx, AllFields>(
142 std::size_t(0), comms::field::details::FieldMinLengthSumCalcHelper<>());
145 template <std::
size_t TFromIdx, std::
size_t TUntilIdx>
146 static constexpr std::size_t doMinLengthFromUntil()
149 comms::util::tupleTypeAccumulateFromUntil<TFromIdx, TUntilIdx, AllFields>(
150 std::size_t(0), comms::field::details::FieldMinLengthSumCalcHelper<>());
153 static constexpr std::size_t doMaxLength()
156 comms::util::tupleTypeAccumulate<AllFields>(
157 std::size_t(0), comms::field::details::FieldMaxLengthSumCalcHelper<>());
160 template <std::
size_t TFromIdx>
161 static constexpr std::size_t doMaxLengthFrom()
164 comms::util::tupleTypeAccumulateFromUntil<TFromIdx, std::tuple_size<AllFields>::value, AllFields>(
165 std::size_t(0), comms::field::details::FieldMaxLengthSumCalcHelper<>());
168 template <std::
size_t TUntilIdx>
169 static constexpr std::size_t doMaxLengthUntil()
172 comms::util::tupleTypeAccumulateFromUntil<0, TUntilIdx, AllFields>(
173 std::size_t(0), comms::field::details::FieldMaxLengthSumCalcHelper<>());
176 template <std::
size_t TFromIdx, std::
size_t TUntilIdx>
177 static constexpr std::size_t doMaxLengthFromUntil()
180 comms::util::tupleTypeAccumulateFromUntil<TFromIdx, TUntilIdx, AllFields>(
181 std::size_t(0), comms::field::details::FieldMaxLengthSumCalcHelper<>());
190 ~MessageImplFieldsContainer() noexcept = default;
192 template <
std::
size_t TIdx, typename TIter>
197 return doReadUntilAndUpdateLen<TIdx>(iter, len);
200 template <std::
size_t TIdx,
typename TIter>
206 util::tupleForEachUntil<TIdx>(fields(), makeFieldReader(iter, status, len));
210 template <std::
size_t TIdx,
typename TIter>
211 void doReadNoStatusUntil(TIter& iter)
213 util::tupleForEachUntil<TIdx>(fields(), makeFieldNoStatusReader(iter));
216 template <std::
size_t TIdx,
typename TIter>
221 return doReadFromAndUpdateLen<TIdx>(iter, len);
224 template <std::
size_t TIdx,
typename TIter>
230 util::tupleForEachFrom<TIdx>(fields(), makeFieldReader(iter, status, len));
234 template <std::
size_t TIdx,
typename TIter>
235 void doReadNoStatusFrom(TIter& iter)
237 util::tupleForEachFrom<TIdx>(fields(), makeFieldNoStatusReader(iter));
240 template <std::
size_t TFromIdx, std::
size_t TUntilIdx,
typename TIter>
245 return doReadFromUntilAndUpdateLen<TFromIdx, TUntilIdx>(iter, len);
248 template <std::
size_t TFromIdx, std::
size_t TUntilIdx,
typename TIter>
254 util::tupleForEachFromUntil<TFromIdx, TUntilIdx>(fields(), makeFieldReader(iter, status, len));
258 template <std::
size_t TFromIdx, std::
size_t TUntilIdx,
typename TIter>
259 void doReadNoStatusFromUntil(TIter& iter)
261 util::tupleForEachFromUntil<TFromIdx, TUntilIdx>(fields(), makeFieldNoStatusReader(iter));
264 template <std::
size_t TIdx,
typename TIter>
267 std::size_t len)
const
269 return doWriteUntilAndUpdateLen<TIdx>(iter, len);
272 template <std::
size_t TIdx,
typename TIter>
275 std::size_t& len)
const
278 util::tupleForEachUntil<TIdx>(fields(), makeFieldWriter(iter, status, len));
282 template <std::
size_t TIdx,
typename TIter>
283 void doWriteNoStatusUntil(TIter& iter)
const
285 util::tupleForEachUntil<TIdx>(fields(), makeFieldNoStatusWriter(iter));
288 template <std::
size_t TIdx,
typename TIter>
291 std::size_t len)
const
293 return doWriteFromAndUpdateLen<TIdx>(iter, len);
296 template <std::
size_t TIdx,
typename TIter>
299 std::size_t& len)
const
302 util::tupleForEachFrom<TIdx>(fields(), makeFieldWriter(iter, status, len));
306 template <std::
size_t TIdx,
typename TIter>
307 void doWriteNoStatusFrom(TIter& iter)
const
309 util::tupleForEachFrom<TIdx>(fields(), makeFieldNoStatusWriter(iter));
312 template <std::
size_t TFromIdx, std::
size_t TUntilIdx,
typename TIter>
315 std::size_t len)
const
317 return doWriteFromUntilAndUpdateLen<TFromIdx, TUntilIdx>(iter, len);
320 template <std::
size_t TFromIdx, std::
size_t TUntilIdx,
typename TIter>
323 std::size_t& len)
const
326 util::tupleForEachFromUntil<TFromIdx, TUntilIdx>(fields(), makeFieldWriter(iter, status, len));
330 template <std::
size_t TFromIdx, std::
size_t TUntilIdx,
typename TIter>
331 void doWriteNoStatusFromUntil(TIter& iter)
const
333 util::tupleForEachFromUntil<TFromIdx, TUntilIdx>(fields(), makeFieldNoStatusWriter(iter));
337 template <
typename... TParams>
338 using NoStatusTag = comms::details::tag::Tag1<>;
340 template <
typename... TParams>
341 using UseStatusTag = comms::details::tag::Tag2<>;
343 template <
typename TIter,
typename... TParams>
347 UseStatusTag<TParams...>)
349 return doReadFromAndUpdateLen<0>(iter, size);
352 template <
typename TIter,
typename... TParams>
356 NoStatusTag<TParams...>)
358 if (size < doLength()) {
362 doReadNoStatusFrom<0>(iter);
366 template <
typename TIter,
typename... TParams>
370 UseStatusTag<TParams...>)
const
372 return doWriteFromAndUpdateLen<0>(iter, size);
375 template <
typename TIter,
typename... TParams>
379 NoStatusTag<TParams...>)
const
381 if (size < doLength()) {
385 doWriteNoStatusFrom<0>(iter);
389 template <
typename TIter>
390 static comms::field::details::FieldReadHelper<TIter> makeFieldReader(
395 return comms::field::details::FieldReadHelper<TIter>(status, iter, size);
398 template <
typename TIter>
399 static comms::field::details::FieldReadNoStatusHelper<TIter> makeFieldNoStatusReader(TIter& iter)
401 return comms::field::details::FieldReadNoStatusHelper<TIter>(iter);
404 template <
typename TIter>
405 static comms::field::details::FieldWriteHelper<TIter> makeFieldWriter(
410 return comms::field::details::FieldWriteHelper<TIter>(status, iter, size);
413 template <
typename TIter>
414 static comms::field::details::FieldWriteNoStatusHelper<TIter> makeFieldNoStatusWriter(TIter& iter)
416 return comms::field::details::FieldWriteNoStatusHelper<TIter>(iter);
424template <
typename TBase,
typename TAllFields>
425class MessageImplFieldsBase :
public TBase,
public MessageImplFieldsContainer<TAllFields>
427 using ContainerBase = MessageImplFieldsContainer<TAllFields>;
429 using ContainerBase::doRead;
430 using ContainerBase::doWrite;
431 using ContainerBase::doLength;
432 using ContainerBase::doValid;
433 using ContainerBase::doRefresh;
434 using ContainerBase::doLengthFrom;
435 using ContainerBase::doLengthUntil;
436 using ContainerBase::doLengthFromUntil;
437 using ContainerBase::doMinLength;
438 using ContainerBase::doMinLengthFrom;
439 using ContainerBase::doMinLengthUntil;
440 using ContainerBase::doMinLengthFromUntil;
441 using ContainerBase::doMaxLength;
442 using ContainerBase::doMaxLengthFrom;
443 using ContainerBase::doMaxLengthUntil;
444 using ContainerBase::doMaxLengthFromUntil;
445 using ContainerBase::areFieldsVersionDependent;
448 ~MessageImplFieldsBase() noexcept = default;
450 using ContainerBase::doReadUntil;
451 using ContainerBase::doReadUntilAndUpdateLen;
452 using ContainerBase::doReadNoStatusUntil;
453 using ContainerBase::doReadFrom;
454 using ContainerBase::doReadFromAndUpdateLen;
455 using ContainerBase::doReadNoStatusFrom;
456 using ContainerBase::doReadFromUntil;
457 using ContainerBase::doReadFromUntilAndUpdateLen;
458 using ContainerBase::doReadNoStatusFromUntil;
459 using ContainerBase::doWriteUntil;
460 using ContainerBase::doWriteUntilAndUpdateLen;
461 using ContainerBase::doWriteNoStatusUntil;
462 using ContainerBase::doWriteFrom;
463 using ContainerBase::doWriteFromAndUpdateLen;
464 using ContainerBase::doWriteNoStatusFrom;
465 using ContainerBase::doWriteFromUntil;
466 using ContainerBase::doWriteFromUntilAndUpdateLen;
467 using ContainerBase::doWriteNoStatusFromUntil;
472template <typename TBase>
473class MessageImplVersionBase : public TBase
478 bool doFieldsVersionUpdate()
480 return comms::field::basic::CommonFuncs::setVersionForMembers(TBase::fields(), TBase::version());
483 template <
typename TIter>
486 doFieldsVersionUpdate();
487 return TBase::doRead(iter, len);
492 bool updated = doFieldsVersionUpdate();
493 return TBase::doRefresh() || updated;
497 MessageImplVersionBase()
499 doFieldsVersionUpdate();
502 MessageImplVersionBase(
const MessageImplVersionBase&) =
default;
503 MessageImplVersionBase(MessageImplVersionBase&&) =
default;
504 ~MessageImplVersionBase() noexcept = default;
506 MessageImplVersionBase& operator=(const MessageImplVersionBase&) = default;
507 MessageImplVersionBase& operator=(MessageImplVersionBase&&) = default;
512template <typename TBase, typename TActual =
void>
513class MessageImplFieldsReadImplBase : public TBase
515 using BaseImpl = TBase;
517 ~MessageImplFieldsReadImplBase() noexcept = default;
519 typename BaseImpl::ReadIterator& iter,
520 std::
size_t size)
override
523 typename comms::util::LazyShallowConditional<
524 std::is_same<TActual, void>::value
529 return readImplInternal(iter, size, Tag());
533 template <
typename... TParams>
534 using HasActual = comms::details::tag::Tag1<>;
536 template <
typename... TParams>
537 using NoActual = comms::details::tag::Tag2<>;
539 template <
typename... TParams>
541 typename BaseImpl::ReadIterator& iter,
543 NoActual<TParams...>)
545 return BaseImpl::doRead(iter, size);
548 template <
typename... TParams>
550 typename BaseImpl::ReadIterator& iter,
552 HasActual<TParams...>)
554 return static_cast<TActual*
>(
this)->doRead(iter, size);
560template <
typename TBase,
typename TActual =
void>
561class MessageImplFieldsWriteImplBase :
public TBase
563 using BaseImpl = TBase;
566 ~MessageImplFieldsWriteImplBase() noexcept = default;
567 virtual
comms::ErrorStatus writeImpl(
568 typename BaseImpl::WriteIterator& iter,
569 std::
size_t size)
const override
572 typename comms::util::LazyShallowConditional<
573 std::is_same<TActual, void>::value
578 return writeImplInternal(iter, size, Tag());
582 template <
typename... TParams>
583 using HasActual = comms::details::tag::Tag1<>;
585 template <
typename... TParams>
586 using NoActual = comms::details::tag::Tag2<>;
588 template <
typename... TParams>
590 typename BaseImpl::WriteIterator& iter,
592 NoActual<TParams...>)
const
594 return BaseImpl::doWrite(iter, size);
597 template <
typename... TParams>
599 typename BaseImpl::WriteIterator& iter,
601 HasActual<TParams...>)
const
603 return static_cast<const TActual*
>(
this)->doWrite(iter, size);
609template <
typename TBase,
typename TActual =
void>
610class MessageImplFieldsValidBase :
public TBase
612 using BaseImpl = TBase;
615 ~MessageImplFieldsValidBase() noexcept = default;
616 virtual
bool validImpl()
const override
619 typename comms::util::LazyShallowConditional<
620 std::is_same<TActual, void>::value
625 return validImplInternal(Tag());
629 template <
typename... TParams>
630 using HasActual = comms::details::tag::Tag1<>;
632 template <
typename... TParams>
633 using NoActual = comms::details::tag::Tag2<>;
635 template <
typename... TParams>
636 bool validImplInternal(NoActual<TParams...>)
const
638 return BaseImpl::doValid();
641 template <
typename... TParams>
642 bool validImplInternal(HasActual<TParams...>)
const
644 return static_cast<const TActual*
>(
this)->doValid();
650template <
typename TBase,
typename TActual =
void>
651class MessageImplFieldsLengthBase :
public TBase
653 using BaseImpl = TBase;
656 ~MessageImplFieldsLengthBase() noexcept = default;
657 virtual
std::
size_t lengthImpl()
const override
660 typename comms::util::LazyShallowConditional<
661 std::is_same<TActual, void>::value
666 return lengthImplInternal(Tag());
670 template <
typename... TParams>
671 using HasActual = comms::details::tag::Tag1<>;
673 template <
typename... TParams>
674 using NoActual = comms::details::tag::Tag2<>;
676 template <
typename... TParams>
677 std::size_t lengthImplInternal(NoActual<TParams...>)
const
679 return BaseImpl::doLength();
682 template <
typename... TParams>
683 std::size_t lengthImplInternal(HasActual<TParams...>)
const
685 return static_cast<const TActual*
>(
this)->doLength();
691template <
typename TBase,
typename TActual,
typename TFailOnInval
idStatusWrapper>
692class MessageImplFailOnInvalidBase :
public TBase
694 using BaseImpl = TBase;
697 template <
typename TIter>
700 auto es = TBase::doRead(iter, len);
705 if (!doValidInternal()) {
706 return TFailOnInvalidStatusWrapper::Value;
713 ~MessageImplFailOnInvalidBase() noexcept = default;
716 template <typename... TParams>
717 using HasActual =
comms::details::tag::Tag1<>;
719 template <typename... TParams>
720 using NoActual =
comms::details::tag::Tag2<>;
722 template <typename... TParams>
723 bool doValidInternal(NoActual<TParams...>)
const
725 return BaseImpl::doValid();
728 template <
typename... TParams>
729 bool doValidInternal(HasActual<TParams...>)
const
731 return static_cast<const TActual*
>(
this)->doValid();
734 bool doValidInternal()
const
737 typename comms::util::LazyShallowConditional<
738 std::is_same<TActual, void>::value
744 return doValidInternal(Tag());
750template <
typename TBase,
typename TActual =
void>
751class MessageImplRefreshBase :
public TBase
754 ~MessageImplRefreshBase() noexcept = default;
755 virtual
bool refreshImpl()
override
758 typename comms::util::LazyShallowConditional<
759 std::is_same<TActual, void>::value
764 return refreshInternal(Tag());
768 template <
typename... TParams>
769 using Downcast = comms::details::tag::Tag1<>;
771 template <
typename... TParams>
772 using NoDowncast = comms::details::tag::Tag2<>;
774 template <
typename... TParams>
775 bool refreshInternal(Downcast<TParams...>)
777 return static_cast<TActual*
>(
this)->doRefresh();
780 template <
typename... TParams>
781 bool refreshInternal(NoDowncast<TParams...>)
783 return TBase::doRefresh();
789template <
typename TBase,
typename TActual>
790class MessageImplDispatchBase :
public TBase
792 using BaseImpl = TBase;
794 ~MessageImplDispatchBase() noexcept = default;
795 virtual typename TBase::DispatchRetType dispatchImpl(typename TBase::Handler& handler)
override
797 static_assert(std::is_base_of<TBase, TActual>::value,
798 "TActual is not derived class");
799 return handler.handle(
static_cast<TActual&
>(*
this));
805template <
typename TBase, std::
intmax_t TId>
806class MessageImplStaticNumIdBase :
public TBase
809 static const typename TBase::MsgIdType MsgId =
810 static_cast<typename TBase::MsgIdType
>(TId);
812 static constexpr typename TBase::MsgIdParamType doGetId()
818 ~MessageImplStaticNumIdBase() noexcept = default;
823template <typename TBase, typename TActual =
void>
824class MessageImplPolymorhpicStaticNumIdBase : public TBase
827 ~MessageImplPolymorhpicStaticNumIdBase() noexcept = default;
828 virtual typename TBase::MsgIdParamType getIdImpl()
const override
831 typename comms::util::LazyShallowConditional<
832 std::is_same<TActual, void>::value
837 return getIdInternal(Tag());
841 template <
typename... TParams>
842 using DowncastTag = comms::details::tag::Tag1<>;
844 template <
typename... TParams>
845 using NoDowncastTag = comms::details::tag::Tag2<>;
847 template <
typename... TParams>
848 typename TBase::MsgIdParamType getIdInternal(NoDowncastTag<TParams...>)
const
850 return TBase::doGetId();
853 template <
typename... TParams>
854 typename TBase::MsgIdParamType getIdInternal(DowncastTag<TParams...>)
const
856 return static_cast<const TActual*
>(
this)->doGetId();
862template <
typename TBase>
863class MessageImplNoIdBase :
public TBase
866 ~MessageImplNoIdBase() noexcept = default;
867 virtual typename TBase::MsgIdParamType getIdImpl()
const override
869 static const typename TBase::MsgIdType MsgId =
typename TBase::MsgIdType();
870 static constexpr bool The_message_id_is_not_supposed_to_be_retrieved =
false;
871 static_cast<void>(The_message_id_is_not_supposed_to_be_retrieved);
872 COMMS_ASSERT(The_message_id_is_not_supposed_to_be_retrieved);
879template <
typename TBase,
typename TActual>
880class MessageImplNameBase :
public TBase
883 ~MessageImplNameBase() noexcept = default;
884 virtual const
char* nameImpl()
const override
886 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:1930
constexpr TValue tupleAccumulate(TTuple &&tuple, const TValue &value, TFunc &&func)
Performs "accumulate" algorithm on every element of the tuple.
Definition Tuple.h:587
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.