75 details::ProtocolLayerExtendingClassT<
76 MsgIdLayer<TField, TMessage, TAllMessages, TNextLayer, TOptions...>,
77 details::MsgIdLayerOptionsParser<TOptions...>
82 "TAllMessages must be of std::tuple type");
88 details::ProtocolLayerExtendingClassT<
89 MsgIdLayer<TField, TMessage, TAllMessages, TNextLayer, TOptions...>,
90 details::MsgIdLayerOptionsParser<TOptions...>
94 static_assert(TMessage::hasMsgIdType(),
95 "Usage of MsgIdLayer requires support for ID type. "
96 "Use comms::option::def::MsgIdType option in message interface type definition.");
98 using ParsedOptionsInternal = details::MsgIdLayerOptionsParser<TOptions...>;
102 using MsgFactory =
typename ParsedOptionsInternal::template MsgFactory<TMessage, TAllMessages>;
153 static constexpr
bool hasExtendingClass()
155 return ParsedOptionsInternal::HasExtendingClass;
163 return ParsedOptionsInternal::HasMsgFactory;
204 template <
typename TMsg,
typename TIter,
typename TNextLayerReader,
typename... TExtraValues>
210 TNextLayerReader&& nextLayerReader,
211 TExtraValues... extraValues)
213 auto beforeReadIter = iter;
214 auto& thisObj = BaseImpl::thisLayer();
215 auto* msgPtr = BaseImpl::toMsgPtr(msg);
216 auto es = thisObj.doReadField(msgPtr, field, iter, size);
218 BaseImpl::updateMissingSize(field, size, extraValues...);
221 if (es != ErrorStatus::Success) {
225 auto fieldLen =
static_cast<std::size_t
>(std::distance(beforeReadIter, iter));
228 typename comms::util::LazyShallowConditional<
241 std::forward<TNextLayerReader>(nextLayerReader),
272 template <
typename TMsg,
typename TIter,
typename TNextLayerWriter>
278 TNextLayerWriter&& nextLayerWriter)
const
280 auto& thisObj = BaseImpl::thisLayer();
281 using MsgType =
typename std::decay<
decltype(msg)>::type;
282 thisObj.prepareFieldForWrite(
283 getMsgId(msg, IdRetrieveTag<MsgType>()),
287 auto es = thisObj.doWriteField(&msg, field, iter, size);
288 if (es != ErrorStatus::Success) {
295 typename comms::util::LazyShallowConditional<
296 comms::isMessageBase<MsgType>() || MsgType::hasWrite()
302 return writeInternal(field, msg, iter, size - field.length(), std::forward<TNextLayerWriter>(nextLayerWriter), Tag());
317 return factory_.createMsg(
id, idx, reason);
324 return MsgFactory::isDispatchPolymorphic();
331 return MsgFactory::isDispatchStaticBinSearch();
338 return MsgFactory::isDispatchLinearSwitch();
349 return static_cast<MsgIdType>(field.getValue());
362 template <
typename TMsg>
365 static_cast<void>(field);
366 static_cast<void>(msg);
376 template <
typename TMsg>
379 static_cast<void>(msg);
380 static_cast<void>(field);
386 template <
typename... TParams>
387 using PolymorphicOpTag = comms::details::tag::Tag1<>;
389 template <
typename... TParams>
390 using DirectOpTag = comms::details::tag::Tag2<>;
392 template <
typename... TParams>
393 using PointerOpTag = comms::details::tag::Tag3<>;
395 template <
typename... TParams>
396 using StaticBinSearchOpTag = comms::details::tag::Tag4<>;
398 template <
typename TMsg>
399 using IdRetrieveTag =
400 typename comms::util::LazyShallowConditional<
401 details::protocolLayerHasDoGetId<TMsg>()
407 template <
typename... TParams>
408 using IdParamAsIsTag = comms::details::tag::Tag5<>;
410 template <
typename... TParams>
411 using IdParamCastTag = comms::details::tag::Tag6<>;
413 template <
typename TId>
415 typename comms::util::LazyShallowConditional<
416 std::is_base_of<MsgIdType, TId>::value
422 template <
typename... TParams>
423 using HasGenericMsgTag = comms::details::tag::Tag7<>;
425 template <
typename... TParams>
426 using NoGenericMsgTag = comms::details::tag::Tag8<>;
428 template <
typename TIter,
typename TNextLayerReader,
typename... TExtraValues>
429 class ReadRedirectionHandler
434 ReadRedirectionHandler(
437 TNextLayerReader&& nextLayerReader,
438 TExtraValues... extraValues)
441 m_nextLayerReader(
std::forward<TNextLayerReader>(nextLayerReader)),
442 m_extraValues(extraValues...)
446 template <
typename TMsg>
447 RetType handle(TMsg& msg)
449 static_assert(comms::isMessageBase<TMsg>(),
"Expected to be a valid message object");
450 return handleInternal(msg, m_extraValues);
453 RetType handle(TMessage& msg)
455 static_cast<void>(msg);
456 static constexpr bool Should_not_happen =
false;
457 static_cast<void>(Should_not_happen);
463 template <
typename TMsg>
464 RetType handleInternal(TMsg& msg, std::tuple<>&)
466 return m_nextLayerReader.read(msg, m_iter, m_size);
469 template <
typename TMsg,
typename T0>
470 RetType handleInternal(TMsg& msg, std::tuple<T0>& extraValues)
472 return m_nextLayerReader.read(msg, m_iter, m_size, std::get<0>(extraValues));
475 template <
typename TMsg,
typename T0,
typename T1>
476 RetType handleInternal(TMsg& msg, std::tuple<T0, T1>& extraValues)
478 return m_nextLayerReader.read(msg, m_iter, m_size, std::get<0>(extraValues), std::get<1>(extraValues));
481 template <
typename TMsg,
typename T0,
typename T1,
typename T2>
482 RetType handleInternal(TMsg& msg, std::tuple<T0, T1, T2>& extraValues)
485 m_nextLayerReader.read(
489 std::get<0>(extraValues),
490 std::get<1>(extraValues),
491 std::get<2>(extraValues));
494 template <
typename TMsg,
typename T0,
typename T1,
typename T2,
typename T3>
495 RetType handleInternal(TMsg& msg, std::tuple<T0, T1, T2, T3>& extraValues)
498 m_nextLayerReader.read(
502 std::get<0>(extraValues),
503 std::get<1>(extraValues),
504 std::get<2>(extraValues),
505 std::get<3>(extraValues));
508 template <
typename TMsg,
typename T0,
typename T1,
typename T2,
typename T3,
typename T4>
509 RetType handleInternal(TMsg& msg, std::tuple<T0, T1, T2, T3, T4>& extraValues)
512 m_nextLayerReader.read(
516 std::get<0>(extraValues),
517 std::get<1>(extraValues),
518 std::get<2>(extraValues),
519 std::get<3>(extraValues),
520 std::get<4>(extraValues));
523 template <
typename TMsg,
typename T0,
typename T1,
typename T2,
typename T3,
typename T4,
typename T5>
524 RetType handleInternal(TMsg& msg, std::tuple<T0, T1, T2, T3, T4, T5>& extraValues)
527 m_nextLayerReader.read(
531 std::get<0>(extraValues),
532 std::get<1>(extraValues),
533 std::get<2>(extraValues),
534 std::get<3>(extraValues),
535 std::get<4>(extraValues),
536 std::get<5>(extraValues));
540 std::size_t m_size = 0U;
541 TNextLayerReader&& m_nextLayerReader;
542 std::tuple<TExtraValues...> m_extraValues;
545 template <
typename TIter,
typename TNextLayerReader,
typename... TExtraValues>
546 ReadRedirectionHandler<TIter, TNextLayerReader, TExtraValues...> makeReadRedirectionHandler(
549 TNextLayerReader&& nextLayerReader,
550 TExtraValues... extraValues)
552 return ReadRedirectionHandler<TIter, TNextLayerReader, TExtraValues...>(iter, size, std::forward<TNextLayerReader>(nextLayerReader), extraValues...);
555 template <
typename TIter,
typename TNextLayerWriter>
556 class WriteRedirectionHandler
561 WriteRedirectionHandler(
564 TNextLayerWriter&& nextLayerWriter)
567 m_nextLayerWriter(
std::forward<TNextLayerWriter>(nextLayerWriter))
571 template <
typename TMsg>
572 RetType handle(
const TMsg& msg)
574 static_assert(comms::isMessageBase<TMsg>(),
"Expected to be a valid message object");
575 return m_nextLayerWriter.write(msg, m_iter, m_size);
578 RetType handle(
const TMessage& msg)
580 static_cast<void>(msg);
581 static constexpr bool Should_not_happen =
false;
582 static_cast<void>(Should_not_happen);
589 std::size_t m_size = 0U;
590 TNextLayerWriter&& m_nextLayerWriter;
593 template <
typename TIter,
typename TNextLayerWriter>
594 WriteRedirectionHandler<TIter, TNextLayerWriter> makeWriteRedirectionHandler(
597 TNextLayerWriter&& nextLayerWriter)
599 return WriteRedirectionHandler<TIter, TNextLayerWriter>(iter, size, std::forward<TNextLayerWriter>(nextLayerWriter));
602 template <
typename TMsg,
typename... TParams>
603 static MsgIdParamType getMsgId(
const TMsg& msg, PolymorphicOpTag<TParams...>)
605 using MsgType =
typename std::decay<
decltype(msg)>::type;
606 static_assert(comms::isMessage<MsgType>(),
607 "The message class is expected to inherit from comms::Message");
608 static_assert(MsgType::hasGetId(),
609 "The message interface class must expose polymorphic ID retrieval functionality, "
610 "use comms::option::app::IdInfoInterface option to define it.");
615 template <
typename TMsg,
typename... TParams>
616 static constexpr MsgIdParamType getMsgId(
const TMsg& msg, DirectOpTag<TParams...>)
618 return msg.doGetId();
621 template <
typename TMsg,
typename TIter,
typename TNextLayerReader,
typename... TExtraValues>
627 TNextLayerReader&& nextLayerReader,
628 TExtraValues... extraValues)
630 using MsgType =
typename std::decay<
decltype(msg)>::type;
631 static_assert(details::protocolLayerHasDoGetId<MsgType>(),
632 "Explicit message type is expected to expose compile type message ID by "
633 "using \"StaticNumIdImpl\" option");
635 auto& thisObj = BaseImpl::thisLayer();
636 auto id = thisObj.getMsgIdFromField(field);
637 BaseImpl::setMsgId(
id, extraValues...);
638 if (
id != MsgType::doGetId()) {
639 return ErrorStatus::InvalidMsgId;
642 thisObj.beforeRead(field, msg);
643 return nextLayerReader.read(msg, iter, size, extraValues...);
646 template <
typename TMsg,
typename TIter,
typename TNextLayerReader,
typename... TExtraValues>
653 TNextLayerReader&& nextLayerReader,
655 TExtraValues... extraValues)
657 static_cast<void>(id);
658 static_cast<void>(idx);
659 return nextLayerReader.read(msg, iter, size, extraValues...);
662 template <
typename TMsg,
typename TIter,
typename TNextLayerReader,
typename... TExtraValues>
668 TNextLayerReader&& nextLayerReader,
670 TExtraValues... extraValues)
673 doReadInternalDirect(
678 std::forward<TNextLayerReader>(nextLayerReader),
682 template <
typename TMsg,
typename TIter,
typename TNextLayerReader,
typename... TExtraValues>
688 TNextLayerReader&& nextLayerReader,
690 TExtraValues... extraValues)
692 using MsgType =
typename std::decay<
decltype(msg)>::type;
693 static_assert(comms::details::hasElementType<MsgType>(),
694 "Unsupported type of message object, expected to be either message itself or smart pointer");
696 using MsgElementType =
typename MsgType::element_type;
703 typename comms::util::LazyShallowConditional<
704 MsgElementType::hasRead()
710 auto& thisObj = BaseImpl::thisLayer();
711 const auto id = thisObj.getMsgIdFromField(field);
712 BaseImpl::setMsgId(
id, extraValues...);
716 CreateFailureReason failureReason = CreateFailureReason::None;
719 msg = createMsgInternal(
id, idx, &failureReason);
724 using IterType =
typename std::decay<
decltype(iter)>::type;
725 static_assert(std::is_same<typename std::iterator_traits<IterType>::iterator_category, std::random_access_iterator_tag>::value,
726 "Iterator used for reading is expected to be random access one");
727 IterType readStart = iter;
729 thisObj.beforeRead(field, *msg);
730 es = doReadInternal(
id, idx, msg, iter, size, std::forward<TNextLayerReader>(nextLayerReader), Tag(), extraValues...);
732 BaseImpl::setMsgIndex(idx, extraValues...);
741 BaseImpl::setMsgIndex(idx, extraValues...);
743 if (failureReason == CreateFailureReason::AllocFailure) {
747 COMMS_ASSERT(failureReason == CreateFailureReason::InvalidId);
748 using GenericMsgTag =
749 typename comms::util::LazyShallowConditional<
750 MsgFactory::hasGenericMessageSupport()
756 return createAndReadGenericMsgInternal(
762 std::forward<TNextLayerReader>(nextLayerReader),
768 template <
typename TMsg,
typename TIter,
typename TNextLayerReader,
typename... TExtraValues>
775 TNextLayerReader&& nextLayerReader,
776 StaticBinSearchOpTag<>,
777 TExtraValues... extraValues)
780 makeReadRedirectionHandler(
783 std::forward<TNextLayerReader>(nextLayerReader),
785 return comms::dispatchMsgStaticBinSearch<AllMessages>(
id, idx, *msg, handler);
788 template <
typename TId,
typename... TParams>
789 MsgPtr createMsgInternalTagged(TId&&
id,
unsigned idx, CreateFailureReason* reason, IdParamAsIsTag<TParams...>)
791 return createMsg(std::forward<TId>(
id), idx, reason);
794 template <
typename TId,
typename... TParams>
795 MsgPtr createMsgInternalTagged(TId&&
id,
unsigned idx, CreateFailureReason* reason, IdParamCastTag<TParams...>)
797 return createMsg(
static_cast<MsgIdType>(
id), idx, reason);
800 template <
typename TId>
801 MsgPtr createMsgInternal(TId&&
id,
unsigned idx, CreateFailureReason* reason)
803 using IdType =
typename std::decay<
decltype(id)>::type;
804 return createMsgInternalTagged(std::forward<TId>(
id), idx, reason, IdParamTag<IdType>());
807 template <
typename TId,
typename... TParams>
808 MsgPtr createGenericMsgInternalTagged(TId&&
id,
unsigned idx, IdParamAsIsTag<TParams...>)
810 return factory_.createGenericMsg(std::forward<TId>(
id), idx);
813 template <
typename TId,
typename... TParams>
814 MsgPtr createGenericMsgInternalTagged(TId&&
id,
unsigned idx, IdParamCastTag<TParams...>)
816 return factory_.createGenericMsg(
static_cast<MsgIdType>(
id), idx);
819 template <
typename TId>
820 MsgPtr createGenericMsgInternal(TId&&
id,
unsigned idx)
822 using IdType =
typename std::decay<
decltype(id)>::type;
823 return createGenericMsgInternalTagged(std::forward<TId>(
id), idx, IdParamTag<IdType>());
826 template <
typename TMsg,
typename TIter,
typename TNextLayerReader,
typename... TExtraValues>
833 TNextLayerReader&& nextLayerReader,
838 static_cast<void>(field);
839 static_cast<void>(msgIdx);
840 static_cast<void>(msg);
841 static_cast<void>(iter);
842 static_cast<void>(size);
843 static_cast<void>(nextLayerReader);
847 template <
typename TMsg,
typename TIter,
typename TNextLayerReader,
typename... TExtraValues>
854 TNextLayerReader&& nextLayerReader,
857 TExtraValues... extraValues)
859 using GenericMsgType =
typename MsgFactory::GenericMessage;
861 auto& thisObj = BaseImpl::thisLayer();
862 auto id = thisObj.getMsgIdFromField(field);
863 msg = createGenericMsgInternal(
id, msgIdx);
868 thisObj.beforeRead(field, *msg);
871 typename comms::util::LazyShallowConditional<
872 GenericMsgType::hasRead()
883 std::forward<TNextLayerReader>(nextLayerReader),
888 template <
typename TMsg,
typename TIter,
typename TNextLayerReader,
typename... TExtraValues>
893 TNextLayerReader&& nextLayerReader,
895 TExtraValues... extraValues)
897 return nextLayerReader.read(msg, iter, size, extraValues...);
900 template <
typename TMsg,
typename TIter,
typename TNextLayerReader,
typename... TExtraValues>
905 TNextLayerReader&& nextLayerReader,
907 TExtraValues... extraValues)
909 using GenericMsgType =
typename MsgFactory::GenericMessage;
910 auto& castedMsgRef =
static_cast<GenericMsgType&
>(*msg);
911 return nextLayerReader.read(castedMsgRef, iter, size, extraValues...);
914 template <
typename TId,
typename... TParams>
915 std::size_t msgCountInternalTagged(TId&&
id, IdParamAsIsTag<TParams...>)
917 return factory_.msgCount(std::forward<TId>(
id));
920 template <
typename TId,
typename... TParams>
921 std::size_t msgCountInternalTagged(TId&&
id, IdParamCastTag<TParams...>)
923 return factory_.msgCount(
static_cast<MsgIdType>(
id));
927 template <
typename TId>
928 std::size_t msgCountInternal(TId&&
id)
930 using IdType =
typename std::decay<
decltype(id)>::type;
931 return msgCountInternalTagged(std::forward<TId>(
id), IdParamTag<IdType>());
934 template <
typename TMsg,
typename TIter,
typename TNextLayerWriter,
typename... TParams>
940 TNextLayerWriter&& nextLayerWriter,
941 DirectOpTag<TParams...>)
const
943 static_cast<void>(field);
944 return nextLayerWriter.write(msg, iter, size);
948 template <
typename TMsg,
typename TIter,
typename TNextLayerWriter,
typename... TParams>
954 TNextLayerWriter&& nextLayerWriter,
955 StaticBinSearchOpTag<TParams...>)
const
957 auto& thisObj = BaseImpl::thisLayer();
958 auto handler = makeWriteRedirectionHandler(iter, size, std::forward<TNextLayerWriter>(nextLayerWriter));
959 auto id = thisObj.getMsgIdFromField(field);