13#include "comms/details/DispatchMsgHelperType.h"
15#include "comms/details/tag.h"
24COMMS_MSVC_WARNING_PUSH
25COMMS_MSVC_WARNING_DISABLE(4702)
33template <DispatchMsgTypeEnum TType>
34class DispatchMsgStrongLinearSwitchHelper
36 template <
typename TAllMessages, std::
size_t TCount>
38 typename std::tuple_element<
39 std::tuple_size<TAllMessages>::value - TCount,
47 typename TAllMessages,
51 static auto dispatch(
typename TMsg::MsgIdParamType
id, TMsg& msg, THandler& handler) ->
52 MessageInterfaceDispatchRetType<
53 typename std::decay<
decltype(handler)>::type>
56 MessageInterfaceDispatchRetType<
57 typename std::decay<
decltype(handler)>::type>;
59 using Elem = FromElem<TAllMessages, TCount>;
61 static constexpr typename TMsg::MsgIdParamType fromId = Elem::doGetId();
64 auto& castedMsg =
static_cast<Elem&
>(msg);
65 return static_cast<RetType
>(handler.handle(castedMsg));
69 static constexpr std::size_t NextCount = TCount - 1U;
70 static constexpr auto HelperType = DispatchMsgHelperIntType<NextCount>::value;
72 DispatchMsgStrongLinearSwitchHelper<HelperType>::template
73 dispatch<TAllMessages, NextCount>(
id, msg, handler);
77 return static_cast<RetType
>(handler.handle(msg));
81 typename TAllMessages,
85 static bool dispatchType(TId&&
id, THandler& handler)
87 using Elem = FromElem<TAllMessages, TCount>;
88 static constexpr typename Elem::MsgIdParamType fromId = Elem::doGetId();
91 handler.template handle<Elem>();
96 static constexpr std::size_t NextCount = TCount - 1U;
97 static constexpr auto HelperType = DispatchMsgHelperIntType<NextCount>::value;
99 DispatchMsgStrongLinearSwitchHelper<HelperType>::template
100 dispatchType<TAllMessages, NextCount>(
id, handler);
110class DispatchMsgStrongLinearSwitchHelper<DispatchMsgTypeEnum::Single>
115 template <
typename TAllMessages>
117 typename std::tuple_element<
118 std::tuple_size<TAllMessages>::value - 1U,
126 typename TAllMessages,
130 static auto dispatch(
typename TMsg::MsgIdParamType
id, TMsg& msg, THandler& handler) ->
131 MessageInterfaceDispatchRetType<
132 typename std::decay<
decltype(handler)>::type>
134 static_assert(TCount == 1U,
"Invalid invocation");
137 MessageInterfaceDispatchRetType<
138 typename std::decay<
decltype(handler)>::type>;
140 using Elem = FromElem<TAllMessages>;
141 typename TMsg::MsgIdParamType elemId = Elem::doGetId();
143 return static_cast<RetType
>(handler.handle(msg));
146 auto& castedMsg =
static_cast<Elem&
>(msg);
147 return static_cast<RetType
>(handler.handle(castedMsg));
151 typename TAllMessages,
155 static bool dispatchType(TId&&
id, THandler& handler)
157 static_assert(TCount == 1U,
"Invalid invocation");
158 using Elem = FromElem<TAllMessages>;
159 typename Elem::MsgIdParamType elemId = Elem::doGetId();
164 handler.template handle<Elem>();
170class DispatchMsgStrongLinearSwitchHelper<DispatchMsgTypeEnum::None>
174 typename TAllMessages,
178 static auto dispatch(
typename TMsg::MsgIdParamType
id, TMsg& msg, THandler& handler) ->
179 MessageInterfaceDispatchRetType<
180 typename std::decay<
decltype(handler)>::type>
182 static_cast<void>(id);
185 MessageInterfaceDispatchRetType<
186 typename std::decay<
decltype(handler)>::type>;
187 return static_cast<RetType
>(handler.handle(msg));
190 template <
typename TId,
typename THandler>
191 static bool dispatchType(TId&&
id, THandler& handler)
193 static_cast<void>(id);
194 static_cast<void>(handler);
199template <
bool THasElems>
200class DispatchMsgLinearSwitchWeakCountFinder
202 template <
typename TAllMessages, std::
size_t TIdx>
203 using OrigMsgType =
typename std::tuple_element<TIdx, TAllMessages>::type;
205 template <
typename TAllMessages, std::
size_t TIdx, std::
size_t TCount>
207 typename std::tuple_element<
208 std::tuple_size<TAllMessages>::value - TCount,
213 template <
typename TAllMessages, std::
size_t TOrigIdx, std::
size_t TRem>
216 OrigMsgType<TAllMessages, TOrigIdx>::doGetId() == CurrMsgType<TAllMessages, TOrigIdx, TRem>::doGetId()
218 std::integral_constant<
220 1U + DispatchMsgLinearSwitchWeakCountFinder<(1U < TRem)>::template Type<TAllMessages, TOrigIdx, TRem - 1>::value
222 std::integral_constant<std::size_t, 0U>
227class DispatchMsgLinearSwitchWeakCountFinder<false>
230 template <
typename TAllMessages, std::
size_t TOrigIdx, std::
size_t TRem>
231 using Type = std::integral_constant<std::size_t, 0U>;
234template <DispatchMsgTypeEnum TType>
235class DispatchMsgWeakLinearSwitchHelper
241 template <
typename TAllMessages, std::
size_t TFrom>
242 using FromElem =
typename std::tuple_element<TFrom, TAllMessages>::type;
246 template <
typename TAllMessages, std::
size_t TFrom, std::
size_t TCount>
248 typename DispatchMsgLinearSwitchWeakCountFinder<
261 typename TAllMessages,
266 static auto dispatch(
typename TMsg::MsgIdParamType
id, std::size_t offset, TMsg& msg, THandler& handler) ->
267 MessageInterfaceDispatchRetType<
268 typename std::decay<
decltype(handler)>::type>
271 MessageInterfaceDispatchRetType<
272 typename std::decay<
decltype(handler)>::type>;
274 using Elem = FromElem<TAllMessages, TFrom>;
275 static constexpr typename TMsg::MsgIdParamType fromId = Elem::doGetId();
279 static constexpr std::size_t NextCount = SameIdsCount<TAllMessages, TFrom, TCount>::value;
280 static constexpr auto HelperType = DispatchMsgHelperIntType<NextCount>::value;
282 DispatchMsgWeakLinearSwitchHelper<HelperType>::template
283 dispatchOffset<TAllMessages, TFrom, NextCount>(offset, msg, handler);
287 static constexpr std::size_t SkipCount = SameIdsCount<TAllMessages, TFrom, TCount>::value;
288 static constexpr std::size_t NextFrom = TFrom + SkipCount;
289 static constexpr std::size_t NextCount = TCount - SkipCount;
290 static constexpr auto HelperType = DispatchMsgHelperIntType<NextCount>::value;
293 DispatchMsgWeakLinearSwitchHelper<HelperType>::template
294 dispatch<TAllMessages, NextFrom, NextCount>(
id, offset, msg, handler);
298 return static_cast<RetType
>(handler.handle(msg));
302 typename TAllMessages,
307 static auto dispatchOffset(std::size_t offset, TMsg& msg, THandler& handler) ->
308 MessageInterfaceDispatchRetType<
309 typename std::decay<
decltype(handler)>::type>
312 MessageInterfaceDispatchRetType<
313 typename std::decay<
decltype(handler)>::type>;
315 using Elem = FromElem<TAllMessages, TFrom>;
319 auto& castedMsg =
static_cast<Elem&
>(msg);
320 return static_cast<RetType
>(handler.handle(castedMsg));
323 static constexpr std::size_t NextCount = TCount - 1U;
324 static constexpr auto HelperType = DispatchMsgHelperIntType<NextCount>::value;
326 DispatchMsgWeakLinearSwitchHelper<HelperType>::template
327 dispatchOffset<TAllMessages, TFrom + 1, NextCount>(offset - 1, msg, handler);
331 return static_cast<RetType
>(handler.handle(msg));
335 typename TAllMessages,
340 static bool dispatchType(TId&&
id, std::size_t offset, THandler& handler)
342 using Elem = FromElem<TAllMessages, TFrom>;
343 static constexpr typename Elem::MsgIdParamType fromId = Elem::doGetId();
347 static constexpr std::size_t NextCount = SameIdsCount<TAllMessages, TFrom, TCount>::value;
348 static constexpr auto HelperType = DispatchMsgHelperIntType<NextCount>::value;
350 DispatchMsgWeakLinearSwitchHelper<HelperType>::template
351 dispatchTypeOffset<TAllMessages, TFrom, NextCount>(offset, handler);
355 static constexpr std::size_t SkipCount = SameIdsCount<TAllMessages, TFrom, TCount>::value;
356 static constexpr std::size_t NextFrom = TFrom + SkipCount;
357 static constexpr std::size_t NextCount = TCount - SkipCount;
358 static constexpr auto HelperType = DispatchMsgHelperIntType<NextCount>::value;
360 DispatchMsgWeakLinearSwitchHelper<HelperType>::template
361 dispatchType<TAllMessages, NextFrom, NextCount>(
id, offset, handler);
369 typename TAllMessages,
373 static bool dispatchTypeOffset(std::size_t offset, THandler& handler)
377 using Elem = FromElem<TAllMessages, TFrom>;
378 handler.template handle<Elem>();
381 static constexpr std::size_t NextCount = TCount - 1U;
382 static constexpr auto HelperType = DispatchMsgHelperIntType<NextCount>::value;
384 DispatchMsgWeakLinearSwitchHelper<HelperType>::template
385 dispatchTypeOffset<TAllMessages, TFrom + 1, NextCount>(offset - 1, handler);
394class DispatchMsgWeakLinearSwitchHelper<DispatchMsgTypeEnum::Single>
399 template <
typename TAllMessages, std::
size_t TFrom>
400 using FromElem =
typename std::tuple_element<TFrom, TAllMessages>::type;
405 typename TAllMessages,
410 static auto dispatch(
typename TMsg::MsgIdParamType
id, std::size_t offset, TMsg& msg, THandler& handler) ->
411 MessageInterfaceDispatchRetType<
412 typename std::decay<
decltype(handler)>::type>
415 MessageInterfaceDispatchRetType<
416 typename std::decay<
decltype(handler)>::type>;
419 return static_cast<RetType
>(handler.handle(msg));
422 using Elem = FromElem<TAllMessages, TFrom>;
423 typename TMsg::MsgIdParamType elemId = Elem::doGetId();
425 return static_cast<RetType
>(handler.handle(msg));
428 auto& castedMsg =
static_cast<Elem&
>(msg);
429 return static_cast<RetType
>(handler.handle(castedMsg));
433 typename TAllMessages,
438 static auto dispatchOffset(std::size_t offset, TMsg& msg, THandler& handler) ->
439 MessageInterfaceDispatchRetType<
440 typename std::decay<
decltype(handler)>::type>
443 MessageInterfaceDispatchRetType<
444 typename std::decay<
decltype(handler)>::type>;
447 return static_cast<RetType
>(handler.handle(msg));
450 using Elem = FromElem<TAllMessages, TFrom>;
451 auto& castedMsg =
static_cast<Elem&
>(msg);
452 return static_cast<RetType
>(handler.handle(castedMsg));
456 typename TAllMessages,
461 static bool dispatchType(TId&&
id, std::size_t offset, THandler& handler)
467 using Elem = FromElem<TAllMessages, TFrom>;
468 typename Elem::MsgIdParamType elemId = Elem::doGetId();
473 handler.template handle<Elem>();
478 typename TAllMessages,
482 static bool dispatchTypeOffset(std::size_t offset, THandler& handler)
488 using Elem = FromElem<TAllMessages, TFrom>;
489 handler.template handle<Elem>();
495class DispatchMsgWeakLinearSwitchHelper<DispatchMsgTypeEnum::None>
499 typename TAllMessages,
504 static auto dispatch(
typename TMsg::MsgIdParamType
id, std::size_t offset, TMsg& msg, THandler& handler) ->
505 MessageInterfaceDispatchRetType<
506 typename std::decay<
decltype(handler)>::type>
508 static_cast<void>(id);
509 static_cast<void>(offset);
512 MessageInterfaceDispatchRetType<
513 typename std::decay<
decltype(handler)>::type>;
514 return static_cast<RetType
>(handler.handle(msg));
518 typename TAllMessages,
523 static auto dispatchOffset(std::size_t offset, TMsg& msg, THandler& handler) ->
524 MessageInterfaceDispatchRetType<
525 typename std::decay<
decltype(handler)>::type>
527 static_cast<void>(offset);
530 MessageInterfaceDispatchRetType<
531 typename std::decay<
decltype(handler)>::type>;
532 return static_cast<RetType
>(handler.handle(msg));
536 typename TAllMessages,
541 static bool dispatchType(TId&&
id, std::size_t offset, THandler& handler)
543 static_cast<void>(id);
544 static_cast<void>(offset);
545 static_cast<void>(handler);
550 typename TAllMessages,
554 static bool dispatchTypeOffset(std::size_t offset, THandler& handler)
556 static_cast<void>(offset);
557 static_cast<void>(handler);
562template <
typename...>
563class DispatchMsgLinearSwitchHelper
565 template <
typename... TParams>
566 using EmptyTag = comms::details::tag::Tag1<>;
568 template <
typename... TParams>
569 using StrongTag = comms::details::tag::Tag2<>;
571 template <
typename... TParams>
572 using WeakTag = comms::details::tag::Tag3<>;
574 template <
typename TAllMessages,
typename...>
575 using StrongWeakTag =
576 typename comms::util::LazyShallowConditional<
577 allMessagesAreStrongSorted<TAllMessages>()
583 template <
typename TAllMessages,
typename...>
585 typename comms::util::LazyShallowConditional<
586 std::tuple_size<TAllMessages>::value == 0U
593 template <
typename TAllMessages,
typename TMsg>
595 typename comms::util::LazyShallowConditional<
596 comms::isMessageBase<TMsg>()
604 template <
typename TAllMessages,
typename TMsg,
typename THandler>
605 static auto dispatch(TMsg& msg, THandler& handler) ->
606 MessageInterfaceDispatchRetType<
607 typename std::decay<
decltype(handler)>::type>
609 using MsgType =
typename std::decay<
decltype(msg)>::type;
610 static_assert(MsgType::hasGetId(),
611 "The used message object must provide polymorphic ID retrieval function");
612 static_assert(MsgType::hasMsgIdType(),
613 "Message interface class must define its id type");
614 return dispatchInternal<TAllMessages>(msg.getId(), msg, handler, AdjustedTag<TAllMessages, MsgType>());
617 template <
typename TAllMessages,
typename TId,
typename TMsg,
typename THandler>
618 static auto dispatch(TId&&
id, TMsg& msg, THandler& handler) ->
619 MessageInterfaceDispatchRetType<
620 typename std::decay<
decltype(handler)>::type>
622 using MsgType =
typename std::decay<
decltype(msg)>::type;
623 static_assert(MsgType::hasMsgIdType(),
624 "Message interface class must define its id type");
625 using MsgIdParamType =
typename MsgType::MsgIdParamType;
626 return dispatchInternal<TAllMessages>(
static_cast<MsgIdParamType
>(
id), msg, handler, AdjustedTag<TAllMessages, MsgType>());
629 template <
typename TAllMessages,
typename TId,
typename TMsg,
typename THandler>
630 static auto dispatch(TId&&
id, std::size_t offset, TMsg& msg, THandler& handler) ->
631 MessageInterfaceDispatchRetType<
632 typename std::decay<
decltype(handler)>::type>
634 using MsgType =
typename std::decay<
decltype(msg)>::type;
635 static_assert(MsgType::hasMsgIdType(),
636 "Message interface class must define its id type");
637 using MsgIdParamType =
typename MsgType::MsgIdParamType;
638 return dispatchInternal<TAllMessages>(
static_cast<MsgIdParamType
>(
id), offset, msg, handler, AdjustedTag<TAllMessages, MsgType>());
641 template <
typename TAllMessages,
typename TId,
typename THandler>
642 static bool dispatchType(TId&&
id, THandler& handler)
644 return dispatchTypeInternal<TAllMessages>(std::forward<TId>(
id), handler, BinSearchTag<TAllMessages>());
647 template <
typename TAllMessages,
typename TId,
typename THandler>
648 static bool dispatchType(TId&&
id, std::size_t offset, THandler& handler)
650 return dispatchTypeInternal<TAllMessages>(std::forward<TId>(
id), offset, handler, BinSearchTag<TAllMessages>());
654 template <
typename TAllMessages,
typename TMsg,
typename THandler,
typename... TParams>
655 static auto dispatchInternal(
typename TMsg::MsgIdParamType
id, TMsg& msg, THandler& handler, EmptyTag<TParams...>) ->
656 MessageInterfaceDispatchRetType<
657 typename std::decay<
decltype(handler)>::type>
659 static_cast<void>(id);
660 return handler.handle(msg);
663 template <
typename TAllMessages,
typename TMsg,
typename THandler,
typename... TParams>
664 static auto dispatchInternal(
typename TMsg::MsgIdParamType
id, std::size_t offset, TMsg& msg, THandler& handler, EmptyTag<TParams...>) ->
665 MessageInterfaceDispatchRetType<
666 typename std::decay<
decltype(handler)>::type>
668 static_cast<void>(id);
669 static_cast<void>(offset);
670 return handler.handle(msg);
673 template <
typename TAllMessages,
typename TMsg,
typename THandler,
typename... TParams>
674 static auto dispatchInternal(
typename TMsg::MsgIdParamType
id, TMsg& msg, THandler& handler, StrongTag<TParams...>) ->
675 MessageInterfaceDispatchRetType<
676 typename std::decay<
decltype(handler)>::type>
678 static constexpr std::size_t Count = std::tuple_size<TAllMessages>::value;
679 static constexpr auto HelperType = DispatchMsgHelperIntType<Count>::value;
681 DispatchMsgStrongLinearSwitchHelper<HelperType>::template
682 dispatch<TAllMessages, Count>(
id, msg, handler);
685 template <
typename TAllMessages,
typename TMsg,
typename THandler,
typename... TParams>
686 static auto dispatchInternal(
typename TMsg::MsgIdParamType
id, std::size_t offset, TMsg& msg, THandler& handler, StrongTag<TParams...>) ->
687 MessageInterfaceDispatchRetType<
688 typename std::decay<
decltype(handler)>::type>
692 MessageInterfaceDispatchRetType<
693 typename std::decay<
decltype(handler)>::type>;
694 return static_cast<RetType
>(handler.handle(msg));
698 static constexpr std::size_t Count = std::tuple_size<TAllMessages>::value;
699 static constexpr auto HelperType = DispatchMsgHelperIntType<Count>::value;
701 DispatchMsgStrongLinearSwitchHelper<HelperType>::template
702 dispatch<TAllMessages, Count>(
id, msg, handler);
706 template <
typename TAllMessages,
typename TMsg,
typename THandler,
typename... TParams>
707 static auto dispatchInternal(
typename TMsg::MsgIdParamType
id, TMsg& msg, THandler& handler, WeakTag<TParams...>) ->
708 MessageInterfaceDispatchRetType<
709 typename std::decay<
decltype(handler)>::type>
711 return dispatchInternal<TAllMessages>(
id, 0U, msg, handler, WeakTag<>());
714 template <
typename TAllMessages,
typename TMsg,
typename THandler,
typename... TParams>
715 static auto dispatchInternal(
typename TMsg::MsgIdParamType
id, std::size_t offset, TMsg& msg, THandler& handler, WeakTag<TParams...>) ->
716 MessageInterfaceDispatchRetType<
717 typename std::decay<
decltype(handler)>::type>
719 static constexpr std::size_t Count = std::tuple_size<TAllMessages>::value;
720 static constexpr auto HelperType = DispatchMsgHelperIntType<Count>::value;
722 DispatchMsgWeakLinearSwitchHelper<HelperType>::template
723 dispatch<TAllMessages, 0, Count>(
id, offset, msg, handler);
727 template <
typename TAllMessages,
typename TId,
typename THandler,
typename... TParams>
728 static bool dispatchTypeInternal(TId&&
id, THandler& handler, EmptyTag<TParams...>)
730 static_cast<void>(id);
731 static_cast<void>(handler);
735 template <
typename TAllMessages,
typename TId,
typename THandler,
typename... TParams>
736 static bool dispatchTypeInternal(TId&&
id, std::size_t offset, THandler& handler, EmptyTag<TParams...>)
738 static_cast<void>(id);
739 static_cast<void>(offset);
740 static_cast<void>(handler);
744 template <
typename TAllMessages,
typename TId,
typename THandler,
typename... TParams>
745 static bool dispatchTypeInternal(TId&&
id, THandler& handler, StrongTag<TParams...>)
747 using FirstMsgType =
typename std::tuple_element<0, TAllMessages>::type;
748 static_assert(comms::isMessageBase<FirstMsgType>(),
749 "The type in the tuple are expected to be proper messages");
750 static_assert(FirstMsgType::hasMsgIdType(),
"The messages must define their ID type");
751 using MsgIdParamType =
typename FirstMsgType::MsgIdParamType;
753 static constexpr std::size_t Count = std::tuple_size<TAllMessages>::value;
754 static constexpr auto HelperType = DispatchMsgHelperIntType<Count>::value;
756 DispatchMsgStrongLinearSwitchHelper<HelperType>::template
757 dispatchType<TAllMessages, Count>(
static_cast<MsgIdParamType
>(
id), handler);
760 template <
typename TAllMessages,
typename TId,
typename THandler,
typename... TParams>
761 static bool dispatchTypeInternal(TId&&
id, std::size_t offset, THandler& handler, StrongTag<TParams...>)
767 return dispatchTypeInternal<TAllMessages>(std::forward<TId>(
id), handler, StrongTag<TParams...>());
770 template <
typename TAllMessages,
typename TId,
typename THandler,
typename... TParams>
771 static bool dispatchTypeInternal(TId&&
id, THandler& handler, WeakTag<TParams...>)
773 return dispatchTypeInternal<TAllMessages>(std::forward<TId>(
id), 0U, handler, WeakTag<>());
776 template <
typename TAllMessages,
typename TId,
typename THandler,
typename... TParams>
777 static bool dispatchTypeInternal(TId&&
id, std::size_t offset, THandler& handler, WeakTag<TParams...>)
779 using FirstMsgType =
typename std::tuple_element<0, TAllMessages>::type;
780 static_assert(comms::isMessageBase<FirstMsgType>(),
781 "The type in the tuple are expected to be proper messages");
782 static_assert(FirstMsgType::hasMsgIdType(),
"The messages must define their ID type");
783 using MsgIdParamType =
typename FirstMsgType::MsgIdParamType;
785 static constexpr std::size_t Count = std::tuple_size<TAllMessages>::value;
786 static constexpr auto HelperType = DispatchMsgHelperIntType<Count>::value;
788 DispatchMsgWeakLinearSwitchHelper<HelperType>::template
789 dispatchType<TAllMessages, 0, Count>(
static_cast<MsgIdParamType
>(
id), offset, handler);
798COMMS_MSVC_WARNING_POP
Contains various compiler related definitions.
Provides common base class for the custom messages with default implementation.
Contains definition of Message object interface and various base classes for custom messages.
comms::option::def::MsgType< TMsg > MsgType
Same as comms::option::def::MsgType.
Definition options.h:1500
Main namespace for all classes / functions of COMMS library.
Replacement to std::conditional.
Definition type_traits.h:32
Replacement to some types from standard type_traits.