70class MsgIdLayer :
public comms::frame::details::MsgIdLayerBase<TField, TMessage, TAllMessages, TNextLayer, TOptions...>
73 "TAllMessages must be of std::tuple type");
75 static_assert(TMessage::hasMsgIdType(),
76 "Usage of MsgIdLayer requires support for ID type. "
77 "Use comms::option::def::MsgIdType option in message interface type definition.");
79 using BaseImpl = comms::frame::details::MsgIdLayerBase<TField, TMessage, TAllMessages, TNextLayer, TOptions...>;
80 using ParsedOptionsInternal = details::MsgIdLayerOptionsParser<TOptions...>;
108 using Field =
typename BaseImpl::Field;
135 static constexpr
bool hasExtendingClass()
137 return ParsedOptionsInternal::HasExtendingClass;
145 return ParsedOptionsInternal::HasMsgFactory;
186 template <
typename TMsg,
typename TIter,
typename TNextLayerReader,
typename... TExtraValues>
192 TNextLayerReader&& nextLayerReader,
193 TExtraValues... extraValues)
195 auto beforeReadIter = iter;
196 auto& thisObj = BaseImpl::thisLayer();
197 auto* msgPtr = BaseImpl::toMsgPtr(msg);
198 auto es = thisObj.doReadField(msgPtr, field, iter, size);
200 BaseImpl::updateMissingSize(field, size, extraValues...);
203 if (es != ErrorStatus::Success) {
207 auto fieldLen =
static_cast<std::size_t
>(std::distance(beforeReadIter, iter));
210 typename comms::util::LazyShallowConditional<
223 std::forward<TNextLayerReader>(nextLayerReader),
254 template <
typename TMsg,
typename TIter,
typename TNextLayerWriter>
260 TNextLayerWriter&& nextLayerWriter)
const
262 auto& thisObj = BaseImpl::thisLayer();
263 using MsgType =
typename std::decay<
decltype(msg)>::type;
264 static_assert(comms::isMessage<MsgType>(),
"The message type must extend comms::Message");
265 thisObj.prepareFieldForWrite(
266 getMsgId(msg, IdRetrieveTag<MsgType>()),
270 auto es = thisObj.doWriteField(&msg, field, iter, size);
271 if (es != ErrorStatus::Success) {
278 typename comms::util::LazyShallowConditional<
279 comms::isMessageBase<MsgType>() || MsgType::hasWrite()
285 return writeInternal(field, msg, iter, size - field.length(), std::forward<TNextLayerWriter>(nextLayerWriter), Tag());
300 return m_factory.createMsg(
id, idx, reason);
307 return MsgFactory::isDispatchPolymorphic();
314 return MsgFactory::isDispatchStaticBinSearch();
321 return MsgFactory::isDispatchLinearSwitch();
332 return static_cast<MsgIdType>(field.getValue());
345 template <
typename TMsg>
348 static_cast<void>(field);
349 static_cast<void>(msg);
359 template <
typename TMsg>
362 static_cast<void>(msg);
363 static_cast<void>(field);
369 template <
typename... TParams>
370 using PolymorphicOpTag = comms::details::tag::Tag1<>;
372 template <
typename... TParams>
373 using DirectOpTag = comms::details::tag::Tag2<>;
375 template <
typename... TParams>
376 using PointerOpTag = comms::details::tag::Tag3<>;
378 template <
typename... TParams>
379 using StaticBinSearchOpTag = comms::details::tag::Tag4<>;
381 template <
typename TMsg>
382 using IdRetrieveTag =
383 typename comms::util::LazyShallowConditional<
384 comms::isMessageBase<TMsg>()
390 template <
typename... TParams>
391 using IdParamAsIsTag = comms::details::tag::Tag5<>;
393 template <
typename... TParams>
394 using IdParamCastTag = comms::details::tag::Tag6<>;
396 template <
typename TId>
398 typename comms::util::LazyShallowConditional<
399 std::is_base_of<MsgIdType, TId>::value
405 template <
typename... TParams>
406 using HasGenericMsgTag = comms::details::tag::Tag7<>;
408 template <
typename... TParams>
409 using NoGenericMsgTag = comms::details::tag::Tag8<>;
411 template <
typename TIter,
typename TNextLayerReader,
typename... TExtraValues>
412 class ReadRedirectionHandler
417 ReadRedirectionHandler(
420 TNextLayerReader&& nextLayerReader,
421 TExtraValues... extraValues)
424 m_nextLayerReader(
std::forward<TNextLayerReader>(nextLayerReader)),
425 m_extraValues(extraValues...)
429 template <
typename TMsg>
430 RetType handle(TMsg& msg)
432 static_assert(comms::isMessageBase<TMsg>(),
"Expected to be a valid message object");
433 return handleInternal(msg, m_extraValues);
436 RetType handle(TMessage& msg)
438 static_cast<void>(msg);
439 static constexpr bool Should_not_happen =
false;
440 static_cast<void>(Should_not_happen);
446 template <
typename TMsg>
447 RetType handleInternal(TMsg& msg, std::tuple<>&)
449 return m_nextLayerReader.read(msg, m_iter, m_size);
452 template <
typename TMsg,
typename T0>
453 RetType handleInternal(TMsg& msg, std::tuple<T0>& extraValues)
455 return m_nextLayerReader.read(msg, m_iter, m_size, std::get<0>(extraValues));
458 template <
typename TMsg,
typename T0,
typename T1>
459 RetType handleInternal(TMsg& msg, std::tuple<T0, T1>& extraValues)
461 return m_nextLayerReader.read(msg, m_iter, m_size, std::get<0>(extraValues), std::get<1>(extraValues));
464 template <
typename TMsg,
typename T0,
typename T1,
typename T2>
465 RetType handleInternal(TMsg& msg, std::tuple<T0, T1, T2>& extraValues)
468 m_nextLayerReader.read(
472 std::get<0>(extraValues),
473 std::get<1>(extraValues),
474 std::get<2>(extraValues));
477 template <
typename TMsg,
typename T0,
typename T1,
typename T2,
typename T3>
478 RetType handleInternal(TMsg& msg, std::tuple<T0, T1, T2, T3>& extraValues)
481 m_nextLayerReader.read(
485 std::get<0>(extraValues),
486 std::get<1>(extraValues),
487 std::get<2>(extraValues),
488 std::get<3>(extraValues));
491 template <
typename TMsg,
typename T0,
typename T1,
typename T2,
typename T3,
typename T4>
492 RetType handleInternal(TMsg& msg, std::tuple<T0, T1, T2, T3, T4>& extraValues)
495 m_nextLayerReader.read(
499 std::get<0>(extraValues),
500 std::get<1>(extraValues),
501 std::get<2>(extraValues),
502 std::get<3>(extraValues),
503 std::get<4>(extraValues));
506 template <
typename TMsg,
typename T0,
typename T1,
typename T2,
typename T3,
typename T4,
typename T5>
507 RetType handleInternal(TMsg& msg, std::tuple<T0, T1, T2, T3, T4, T5>& extraValues)
510 m_nextLayerReader.read(
514 std::get<0>(extraValues),
515 std::get<1>(extraValues),
516 std::get<2>(extraValues),
517 std::get<3>(extraValues),
518 std::get<4>(extraValues),
519 std::get<5>(extraValues));
523 std::size_t m_size = 0U;
524 TNextLayerReader&& m_nextLayerReader;
525 std::tuple<TExtraValues...> m_extraValues;
528 template <
typename TIter,
typename TNextLayerReader,
typename... TExtraValues>
529 ReadRedirectionHandler<TIter, TNextLayerReader, TExtraValues...> makeReadRedirectionHandler(
532 TNextLayerReader&& nextLayerReader,
533 TExtraValues... extraValues)
535 return ReadRedirectionHandler<TIter, TNextLayerReader, TExtraValues...>(iter, size, std::forward<TNextLayerReader>(nextLayerReader), extraValues...);
538 template <
typename TIter,
typename TNextLayerWriter>
539 class WriteRedirectionHandler
544 WriteRedirectionHandler(
547 TNextLayerWriter&& nextLayerWriter)
550 m_nextLayerWriter(
std::forward<TNextLayerWriter>(nextLayerWriter))
554 template <
typename TMsg>
555 RetType handle(
const TMsg& msg)
557 static_assert(comms::isMessageBase<TMsg>(),
"Expected to be a valid message object");
558 return m_nextLayerWriter.write(msg, m_iter, m_size);
561 RetType handle(
const TMessage& msg)
563 static_cast<void>(msg);
564 static constexpr bool Should_not_happen =
false;
565 static_cast<void>(Should_not_happen);
572 std::size_t m_size = 0U;
573 TNextLayerWriter&& m_nextLayerWriter;
576 template <
typename TIter,
typename TNextLayerWriter>
577 WriteRedirectionHandler<TIter, TNextLayerWriter> makeWriteRedirectionHandler(
580 TNextLayerWriter&& nextLayerWriter)
582 return WriteRedirectionHandler<TIter, TNextLayerWriter>(iter, size, std::forward<TNextLayerWriter>(nextLayerWriter));
585 template <
typename TMsg,
typename... TParams>
586 static MsgIdParamType getMsgId(
const TMsg& msg, PolymorphicOpTag<TParams...>)
588 using MsgType =
typename std::decay<
decltype(msg)>::type;
589 static_assert(comms::isMessage<MsgType>(),
590 "The message class is expected to inherit from comms::Message");
591 static_assert(MsgType::hasGetId(),
592 "The message interface class must expose polymorphic ID retrieval functionality, "
593 "use comms::option::app::IdInfoInterface option to define it.");
598 template <
typename TMsg,
typename... TParams>
599 static constexpr MsgIdParamType getMsgId(
const TMsg& msg, DirectOpTag<TParams...>)
601 using MsgType =
typename std::decay<
decltype(msg)>::type;
602 static_assert(comms::isMessageBase<MsgType>(),
603 "The message class is expected to inherit from comms::MessageBase");
604 static_assert(MsgType::hasStaticMsgId(),
605 "The message class must expose direct ID retrieval functionality, "
606 "use comms::option::app::StaticNumIdImpl option to define it.");
607 return msg.doGetId();
610 template <
typename TMsg,
typename TIter,
typename TNextLayerReader,
typename... TExtraValues>
616 TNextLayerReader&& nextLayerReader,
617 TExtraValues... extraValues)
619 static_assert((!details::hasMsgIndexRetriever<TExtraValues...>()) || (comms::details::allMessagesAreStrongSorted<AllMessages>()),
620 "Message type index cannot be retrieved with direct message object invocation");
621 auto& thisObj = BaseImpl::thisLayer();
622 auto id = thisObj.getMsgIdFromField(field);
623 BaseImpl::setMsgId(
id, extraValues...);
624 BaseImpl::setMsgIndex(0U, extraValues...);
626 using MsgType =
typename std::decay<
decltype(msg)>::type;
627 if (
id != getMsgId(msg, IdRetrieveTag<MsgType>())) {
628 return ErrorStatus::InvalidMsgId;
631 thisObj.beforeRead(field, msg);
632 return nextLayerReader.read(msg, iter, size, extraValues...);
635 template <
typename TMsg,
typename TIter,
typename TNextLayerReader,
typename... TExtraValues>
642 TNextLayerReader&& nextLayerReader,
644 TExtraValues... extraValues)
646 static_cast<void>(id);
647 static_cast<void>(idx);
648 return nextLayerReader.read(msg, iter, size, extraValues...);
651 template <
typename TMsg,
typename TIter,
typename TNextLayerReader,
typename... TExtraValues>
657 TNextLayerReader&& nextLayerReader,
659 TExtraValues... extraValues)
662 doReadInternalDirect(
667 std::forward<TNextLayerReader>(nextLayerReader),
671 template <
typename TMsg,
typename TIter,
typename TNextLayerReader,
typename... TExtraValues>
677 TNextLayerReader&& nextLayerReader,
679 TExtraValues... extraValues)
681 using MsgType =
typename std::decay<
decltype(msg)>::type;
682 static_assert(comms::details::hasElementType<MsgType>(),
683 "Unsupported type of message object, expected to be either message itself or smart pointer");
685 using MsgElementType =
typename MsgType::element_type;
688 typename comms::util::LazyShallowConditional<
689 MsgElementType::hasRead()
695 auto& thisObj = BaseImpl::thisLayer();
696 const auto id = thisObj.getMsgIdFromField(field);
697 BaseImpl::setMsgId(
id, extraValues...);
701 CreateFailureReason failureReason = CreateFailureReason::None;
704 msg = createMsgInternal(
id, idx, &failureReason);
709 using IterType =
typename std::decay<
decltype(iter)>::type;
710 static_assert(std::is_same<typename std::iterator_traits<IterType>::iterator_category, std::random_access_iterator_tag>::value,
711 "Iterator used for reading is expected to be random access one");
712 IterType readStart = iter;
714 thisObj.beforeRead(field, *msg);
715 es = doReadInternal(
id, idx, msg, iter, size, std::forward<TNextLayerReader>(nextLayerReader), Tag(), extraValues...);
717 BaseImpl::setMsgIndex(idx, extraValues...);
726 BaseImpl::setMsgIndex(idx, extraValues...);
728 if (failureReason == CreateFailureReason::AllocFailure) {
732 COMMS_ASSERT(failureReason == CreateFailureReason::InvalidId);
733 using GenericMsgTag =
734 typename comms::util::LazyShallowConditional<
735 MsgFactory::hasGenericMessageSupport()
742 createAndReadGenericMsgInternal(
748 std::forward<TNextLayerReader>(nextLayerReader),
754 template <
typename TMsg,
typename TIter,
typename TNextLayerReader,
typename... TExtraValues>
761 TNextLayerReader&& nextLayerReader,
762 StaticBinSearchOpTag<>,
763 TExtraValues... extraValues)
766 makeReadRedirectionHandler(
769 std::forward<TNextLayerReader>(nextLayerReader),
771 return comms::dispatchMsgStaticBinSearch<AllMessages>(
id, idx, *msg, handler);
774 template <
typename TId,
typename... TParams>
775 MsgPtr createMsgInternalTagged(TId&&
id,
unsigned idx, CreateFailureReason* reason, IdParamAsIsTag<TParams...>)
777 return createMsg(std::forward<TId>(
id), idx, reason);
780 template <
typename TId,
typename... TParams>
781 MsgPtr createMsgInternalTagged(TId&&
id,
unsigned idx, CreateFailureReason* reason, IdParamCastTag<TParams...>)
783 return createMsg(
static_cast<MsgIdType>(
id), idx, reason);
786 template <
typename TId>
787 MsgPtr createMsgInternal(TId&&
id,
unsigned idx, CreateFailureReason* reason)
789 using IdType =
typename std::decay<
decltype(id)>::type;
790 return createMsgInternalTagged(std::forward<TId>(
id), idx, reason, IdParamTag<IdType>());
793 template <
typename TId,
typename... TParams>
794 MsgPtr createGenericMsgInternalTagged(TId&&
id,
unsigned idx, IdParamAsIsTag<TParams...>)
796 return m_factory.createGenericMsg(std::forward<TId>(
id), idx);
799 template <
typename TId,
typename... TParams>
800 MsgPtr createGenericMsgInternalTagged(TId&&
id,
unsigned idx, IdParamCastTag<TParams...>)
802 return m_factory.createGenericMsg(
static_cast<MsgIdType>(
id), idx);
805 template <
typename TId>
806 MsgPtr createGenericMsgInternal(TId&&
id,
unsigned idx)
808 using IdType =
typename std::decay<
decltype(id)>::type;
809 return createGenericMsgInternalTagged(std::forward<TId>(
id), idx, IdParamTag<IdType>());
812 template <
typename TMsg,
typename TIter,
typename TNextLayerReader,
typename... TExtraValues>
819 TNextLayerReader&& nextLayerReader,
824 static_cast<void>(field);
825 static_cast<void>(msgIdx);
826 static_cast<void>(msg);
827 static_cast<void>(iter);
828 static_cast<void>(size);
829 static_cast<void>(nextLayerReader);
833 template <
typename TMsg,
typename TIter,
typename TNextLayerReader,
typename... TExtraValues>
840 TNextLayerReader&& nextLayerReader,
843 TExtraValues... extraValues)
845 using GenericMsgType =
typename MsgFactory::GenericMessage;
847 auto& thisObj = BaseImpl::thisLayer();
848 auto id = thisObj.getMsgIdFromField(field);
849 msg = createGenericMsgInternal(
id, msgIdx);
854 thisObj.beforeRead(field, *msg);
857 typename comms::util::LazyShallowConditional<
858 GenericMsgType::hasRead()
869 std::forward<TNextLayerReader>(nextLayerReader),
874 template <
typename TMsg,
typename TIter,
typename TNextLayerReader,
typename... TExtraValues>
879 TNextLayerReader&& nextLayerReader,
881 TExtraValues... extraValues)
883 return nextLayerReader.read(msg, iter, size, extraValues...);
886 template <
typename TMsg,
typename TIter,
typename TNextLayerReader,
typename... TExtraValues>
891 TNextLayerReader&& nextLayerReader,
893 TExtraValues... extraValues)
895 using GenericMsgType =
typename MsgFactory::GenericMessage;
896 auto& castedMsgRef =
static_cast<GenericMsgType&
>(*msg);
897 return nextLayerReader.read(castedMsgRef, iter, size, extraValues...);
900 template <
typename TId,
typename... TParams>
901 std::size_t msgCountInternalTagged(TId&&
id, IdParamAsIsTag<TParams...>)
903 return m_factory.msgCount(std::forward<TId>(
id));
906 template <
typename TId,
typename... TParams>
907 std::size_t msgCountInternalTagged(TId&&
id, IdParamCastTag<TParams...>)
909 return m_factory.msgCount(
static_cast<MsgIdType>(
id));
913 template <
typename TId>
914 std::size_t msgCountInternal(TId&&
id)
916 using IdType =
typename std::decay<
decltype(id)>::type;
917 return msgCountInternalTagged(std::forward<TId>(
id), IdParamTag<IdType>());
920 template <
typename TMsg,
typename TIter,
typename TNextLayerWriter,
typename... TParams>
926 TNextLayerWriter&& nextLayerWriter,
927 DirectOpTag<TParams...>)
const
929 static_cast<void>(field);
930 return nextLayerWriter.write(msg, iter, size);
934 template <
typename TMsg,
typename TIter,
typename TNextLayerWriter,
typename... TParams>
940 TNextLayerWriter&& nextLayerWriter,
941 StaticBinSearchOpTag<TParams...>)
const
943 auto& thisObj = BaseImpl::thisLayer();
944 auto handler = makeWriteRedirectionHandler(iter, size, std::forward<TNextLayerWriter>(nextLayerWriter));
945 auto id = thisObj.getMsgIdFromField(field);
949 MsgFactory m_factory;