11#include "comms/details/DispatchMsgHelperType.h"
13#include "comms/details/tag.h"
21COMMS_MSVC_WARNING_PUSH
22COMMS_MSVC_WARNING_DISABLE(4702)
30template <DispatchMsgTypeEnum TType>
31class DispatchMsgStrongLinearSwitchHelper
33 template <
typename TAllMessages, std::
size_t TCount>
35 typename std::tuple_element<
36 std::tuple_size<TAllMessages>::value - TCount,
44 typename TAllMessages,
48 static auto dispatch(
typename TMsg::MsgIdParamType
id, TMsg& msg, THandler& handler) ->
49 MessageInterfaceDispatchRetType<
50 typename std::decay<
decltype(handler)>::type>
53 MessageInterfaceDispatchRetType<
54 typename std::decay<
decltype(handler)>::type>;
56 using Elem = FromElem<TAllMessages, TCount>;
58 static constexpr typename TMsg::MsgIdParamType fromId = Elem::doGetId();
61 auto& castedMsg =
static_cast<Elem&
>(msg);
62 return static_cast<RetType
>(handler.handle(castedMsg));
66 static constexpr std::size_t NextCount = TCount - 1U;
67 static constexpr auto HelperType = DispatchMsgHelperIntType<NextCount>::value;
69 DispatchMsgStrongLinearSwitchHelper<HelperType>::template
70 dispatch<TAllMessages, NextCount>(
id, msg, handler);
74 return static_cast<RetType
>(handler.handle(msg));
78 typename TAllMessages,
82 static bool dispatchType(TId&&
id, THandler& handler)
84 using Elem = FromElem<TAllMessages, TCount>;
85 static constexpr typename Elem::MsgIdParamType fromId = Elem::doGetId();
88 handler.template handle<Elem>();
93 static constexpr std::size_t NextCount = TCount - 1U;
94 static constexpr auto HelperType = DispatchMsgHelperIntType<NextCount>::value;
96 DispatchMsgStrongLinearSwitchHelper<HelperType>::template
97 dispatchType<TAllMessages, NextCount>(
id, handler);
107class DispatchMsgStrongLinearSwitchHelper<DispatchMsgTypeEnum::Single>
112 template <
typename TAllMessages>
114 typename std::tuple_element<
115 std::tuple_size<TAllMessages>::value - 1U,
123 typename TAllMessages,
127 static auto dispatch(
typename TMsg::MsgIdParamType
id, TMsg& msg, THandler& handler) ->
128 MessageInterfaceDispatchRetType<
129 typename std::decay<
decltype(handler)>::type>
131 static_assert(TCount == 1U,
"Invalid invocation");
134 MessageInterfaceDispatchRetType<
135 typename std::decay<
decltype(handler)>::type>;
137 using Elem = FromElem<TAllMessages>;
138 typename TMsg::MsgIdParamType elemId = Elem::doGetId();
140 return static_cast<RetType
>(handler.handle(msg));
143 auto& castedMsg =
static_cast<Elem&
>(msg);
144 return static_cast<RetType
>(handler.handle(castedMsg));
148 typename TAllMessages,
152 static bool dispatchType(TId&&
id, THandler& handler)
154 static_assert(TCount == 1U,
"Invalid invocation");
155 using Elem = FromElem<TAllMessages>;
156 typename Elem::MsgIdParamType elemId = Elem::doGetId();
161 handler.template handle<Elem>();
167class DispatchMsgStrongLinearSwitchHelper<DispatchMsgTypeEnum::None>
171 typename TAllMessages,
175 static auto dispatch(
typename TMsg::MsgIdParamType
id, TMsg& msg, THandler& handler) ->
176 MessageInterfaceDispatchRetType<
177 typename std::decay<
decltype(handler)>::type>
179 static_cast<void>(id);
182 MessageInterfaceDispatchRetType<
183 typename std::decay<
decltype(handler)>::type>;
184 return static_cast<RetType
>(handler.handle(msg));
187 template <
typename TId,
typename THandler>
188 static bool dispatchType(TId&&
id, THandler& handler)
190 static_cast<void>(id);
191 static_cast<void>(handler);
196template <
bool THasElems>
197class DispatchMsgLinearSwitchWeakCountFinder
199 template <
typename TAllMessages, std::
size_t TIdx>
200 using OrigMsgType =
typename std::tuple_element<TIdx, TAllMessages>::type;
202 template <
typename TAllMessages, std::
size_t TIdx, std::
size_t TCount>
204 typename std::tuple_element<
205 std::tuple_size<TAllMessages>::value - TCount,
210 template <
typename TAllMessages, std::
size_t TOrigIdx, std::
size_t TRem>
213 OrigMsgType<TAllMessages, TOrigIdx>::doGetId() == CurrMsgType<TAllMessages, TOrigIdx, TRem>::doGetId()
215 std::integral_constant<
217 1U + DispatchMsgLinearSwitchWeakCountFinder<(1U < TRem)>::template Type<TAllMessages, TOrigIdx, TRem - 1>::value
219 std::integral_constant<std::size_t, 0U>
224class DispatchMsgLinearSwitchWeakCountFinder<false>
227 template <
typename TAllMessages, std::
size_t TOrigIdx, std::
size_t TRem>
228 using Type = std::integral_constant<std::size_t, 0U>;
231template <DispatchMsgTypeEnum TType>
232class DispatchMsgWeakLinearSwitchHelper
238 template <
typename TAllMessages, std::
size_t TFrom>
239 using FromElem =
typename std::tuple_element<TFrom, TAllMessages>::type;
243 template <
typename TAllMessages, std::
size_t TFrom, std::
size_t TCount>
245 typename DispatchMsgLinearSwitchWeakCountFinder<
258 typename TAllMessages,
263 static auto dispatch(
typename TMsg::MsgIdParamType
id, std::size_t offset, TMsg& msg, THandler& handler) ->
264 MessageInterfaceDispatchRetType<
265 typename std::decay<
decltype(handler)>::type>
268 MessageInterfaceDispatchRetType<
269 typename std::decay<
decltype(handler)>::type>;
271 using Elem = FromElem<TAllMessages, TFrom>;
272 static constexpr typename TMsg::MsgIdParamType fromId = Elem::doGetId();
276 static constexpr std::size_t NextCount = SameIdsCount<TAllMessages, TFrom, TCount>::value;
277 static constexpr auto HelperType = DispatchMsgHelperIntType<NextCount>::value;
279 DispatchMsgWeakLinearSwitchHelper<HelperType>::template
280 dispatchOffset<TAllMessages, TFrom, NextCount>(offset, msg, handler);
284 static constexpr std::size_t SkipCount = SameIdsCount<TAllMessages, TFrom, TCount>::value;
285 static constexpr std::size_t NextFrom = TFrom + SkipCount;
286 static constexpr std::size_t NextCount = TCount - SkipCount;
287 static constexpr auto HelperType = DispatchMsgHelperIntType<NextCount>::value;
290 DispatchMsgWeakLinearSwitchHelper<HelperType>::template
291 dispatch<TAllMessages, NextFrom, NextCount>(
id, offset, msg, handler);
295 return static_cast<RetType
>(handler.handle(msg));
299 typename TAllMessages,
304 static auto dispatchOffset(std::size_t offset, TMsg& msg, THandler& handler) ->
305 MessageInterfaceDispatchRetType<
306 typename std::decay<
decltype(handler)>::type>
309 MessageInterfaceDispatchRetType<
310 typename std::decay<
decltype(handler)>::type>;
312 using Elem = FromElem<TAllMessages, TFrom>;
316 auto& castedMsg =
static_cast<Elem&
>(msg);
317 return static_cast<RetType
>(handler.handle(castedMsg));
320 static constexpr std::size_t NextCount = TCount - 1U;
321 static constexpr auto HelperType = DispatchMsgHelperIntType<NextCount>::value;
323 DispatchMsgWeakLinearSwitchHelper<HelperType>::template
324 dispatchOffset<TAllMessages, TFrom + 1, NextCount>(offset - 1, msg, handler);
328 return static_cast<RetType
>(handler.handle(msg));
332 typename TAllMessages,
337 static bool dispatchType(TId&&
id, std::size_t offset, THandler& handler)
339 using Elem = FromElem<TAllMessages, TFrom>;
340 static constexpr typename Elem::MsgIdParamType fromId = Elem::doGetId();
344 static constexpr std::size_t NextCount = SameIdsCount<TAllMessages, TFrom, TCount>::value;
345 static constexpr auto HelperType = DispatchMsgHelperIntType<NextCount>::value;
347 DispatchMsgWeakLinearSwitchHelper<HelperType>::template
348 dispatchTypeOffset<TAllMessages, TFrom, NextCount>(offset, handler);
352 static constexpr std::size_t SkipCount = SameIdsCount<TAllMessages, TFrom, TCount>::value;
353 static constexpr std::size_t NextFrom = TFrom + SkipCount;
354 static constexpr std::size_t NextCount = TCount - SkipCount;
355 static constexpr auto HelperType = DispatchMsgHelperIntType<NextCount>::value;
357 DispatchMsgWeakLinearSwitchHelper<HelperType>::template
358 dispatchType<TAllMessages, NextFrom, NextCount>(
id, offset, handler);
366 typename TAllMessages,
370 static bool dispatchTypeOffset(std::size_t offset, THandler& handler)
374 using Elem = FromElem<TAllMessages, TFrom>;
375 handler.template handle<Elem>();
378 static constexpr std::size_t NextCount = TCount - 1U;
379 static constexpr auto HelperType = DispatchMsgHelperIntType<NextCount>::value;
381 DispatchMsgWeakLinearSwitchHelper<HelperType>::template
382 dispatchTypeOffset<TAllMessages, TFrom + 1, NextCount>(offset - 1, handler);
391class DispatchMsgWeakLinearSwitchHelper<DispatchMsgTypeEnum::Single>
396 template <
typename TAllMessages, std::
size_t TFrom>
397 using FromElem =
typename std::tuple_element<TFrom, TAllMessages>::type;
402 typename TAllMessages,
407 static auto dispatch(
typename TMsg::MsgIdParamType
id, std::size_t offset, TMsg& msg, THandler& handler) ->
408 MessageInterfaceDispatchRetType<
409 typename std::decay<
decltype(handler)>::type>
412 MessageInterfaceDispatchRetType<
413 typename std::decay<
decltype(handler)>::type>;
416 return static_cast<RetType
>(handler.handle(msg));
419 using Elem = FromElem<TAllMessages, TFrom>;
420 typename TMsg::MsgIdParamType elemId = Elem::doGetId();
422 return static_cast<RetType
>(handler.handle(msg));
425 auto& castedMsg =
static_cast<Elem&
>(msg);
426 return static_cast<RetType
>(handler.handle(castedMsg));
430 typename TAllMessages,
435 static auto dispatchOffset(std::size_t offset, TMsg& msg, THandler& handler) ->
436 MessageInterfaceDispatchRetType<
437 typename std::decay<
decltype(handler)>::type>
440 MessageInterfaceDispatchRetType<
441 typename std::decay<
decltype(handler)>::type>;
444 return static_cast<RetType
>(handler.handle(msg));
447 using Elem = FromElem<TAllMessages, TFrom>;
448 auto& castedMsg =
static_cast<Elem&
>(msg);
449 return static_cast<RetType
>(handler.handle(castedMsg));
453 typename TAllMessages,
458 static bool dispatchType(TId&&
id, std::size_t offset, THandler& handler)
464 using Elem = FromElem<TAllMessages, TFrom>;
465 typename Elem::MsgIdParamType elemId = Elem::doGetId();
470 handler.template handle<Elem>();
475 typename TAllMessages,
479 static bool dispatchTypeOffset(std::size_t offset, THandler& handler)
485 using Elem = FromElem<TAllMessages, TFrom>;
486 handler.template handle<Elem>();
492class DispatchMsgWeakLinearSwitchHelper<DispatchMsgTypeEnum::None>
496 typename TAllMessages,
501 static auto dispatch(
typename TMsg::MsgIdParamType
id, std::size_t offset, TMsg& msg, THandler& handler) ->
502 MessageInterfaceDispatchRetType<
503 typename std::decay<
decltype(handler)>::type>
505 static_cast<void>(id);
506 static_cast<void>(offset);
509 MessageInterfaceDispatchRetType<
510 typename std::decay<
decltype(handler)>::type>;
511 return static_cast<RetType
>(handler.handle(msg));
515 typename TAllMessages,
520 static auto dispatchOffset(std::size_t offset, TMsg& msg, THandler& handler) ->
521 MessageInterfaceDispatchRetType<
522 typename std::decay<
decltype(handler)>::type>
524 static_cast<void>(offset);
527 MessageInterfaceDispatchRetType<
528 typename std::decay<
decltype(handler)>::type>;
529 return static_cast<RetType
>(handler.handle(msg));
533 typename TAllMessages,
538 static bool dispatchType(TId&&
id, std::size_t offset, THandler& handler)
540 static_cast<void>(id);
541 static_cast<void>(offset);
542 static_cast<void>(handler);
547 typename TAllMessages,
551 static bool dispatchTypeOffset(std::size_t offset, THandler& handler)
553 static_cast<void>(offset);
554 static_cast<void>(handler);
559template <
typename...>
560class DispatchMsgLinearSwitchHelper
562 template <
typename... TParams>
563 using EmptyTag = comms::details::tag::Tag1<>;
565 template <
typename... TParams>
566 using StrongTag = comms::details::tag::Tag2<>;
568 template <
typename... TParams>
569 using WeakTag = comms::details::tag::Tag3<>;
571 template <
typename TAllMessages,
typename...>
572 using StrongWeakTag =
573 typename comms::util::LazyShallowConditional<
574 allMessagesAreStrongSorted<TAllMessages>()
580 template <
typename TAllMessages,
typename...>
582 typename comms::util::LazyShallowConditional<
583 std::tuple_size<TAllMessages>::value == 0U
590 template <
typename TAllMessages,
typename TMsg>
592 typename comms::util::LazyShallowConditional<
593 comms::isMessageBase<TMsg>()
601 template <
typename TAllMessages,
typename TMsg,
typename THandler>
602 static auto dispatch(TMsg& msg, THandler& handler) ->
603 MessageInterfaceDispatchRetType<
604 typename std::decay<
decltype(handler)>::type>
606 using MsgType =
typename std::decay<
decltype(msg)>::type;
607 static_assert(MsgType::hasGetId(),
608 "The used message object must provide polymorphic ID retrieval function");
609 static_assert(MsgType::hasMsgIdType(),
610 "Message interface class must define its id type");
611 return dispatchInternal<TAllMessages>(msg.getId(), msg, handler, AdjustedTag<TAllMessages, MsgType>());
614 template <
typename TAllMessages,
typename TId,
typename TMsg,
typename THandler>
615 static auto dispatch(TId&&
id, TMsg& msg, THandler& handler) ->
616 MessageInterfaceDispatchRetType<
617 typename std::decay<
decltype(handler)>::type>
619 using MsgType =
typename std::decay<
decltype(msg)>::type;
620 static_assert(MsgType::hasMsgIdType(),
621 "Message interface class must define its id type");
622 using MsgIdParamType =
typename MsgType::MsgIdParamType;
623 return dispatchInternal<TAllMessages>(
static_cast<MsgIdParamType
>(
id), msg, handler, AdjustedTag<TAllMessages, MsgType>());
626 template <
typename TAllMessages,
typename TId,
typename TMsg,
typename THandler>
627 static auto dispatch(TId&&
id, std::size_t offset, TMsg& msg, THandler& handler) ->
628 MessageInterfaceDispatchRetType<
629 typename std::decay<
decltype(handler)>::type>
631 using MsgType =
typename std::decay<
decltype(msg)>::type;
632 static_assert(MsgType::hasMsgIdType(),
633 "Message interface class must define its id type");
634 using MsgIdParamType =
typename MsgType::MsgIdParamType;
635 return dispatchInternal<TAllMessages>(
static_cast<MsgIdParamType
>(
id), offset, msg, handler, AdjustedTag<TAllMessages, MsgType>());
638 template <
typename TAllMessages,
typename TId,
typename THandler>
639 static bool dispatchType(TId&&
id, THandler& handler)
641 return dispatchTypeInternal<TAllMessages>(std::forward<TId>(
id), handler, BinSearchTag<TAllMessages>());
644 template <
typename TAllMessages,
typename TId,
typename THandler>
645 static bool dispatchType(TId&&
id, std::size_t offset, THandler& handler)
647 return dispatchTypeInternal<TAllMessages>(std::forward<TId>(
id), offset, handler, BinSearchTag<TAllMessages>());
651 template <
typename TAllMessages,
typename TMsg,
typename THandler,
typename... TParams>
652 static auto dispatchInternal(
typename TMsg::MsgIdParamType
id, TMsg& msg, THandler& handler, EmptyTag<TParams...>) ->
653 MessageInterfaceDispatchRetType<
654 typename std::decay<
decltype(handler)>::type>
656 static_cast<void>(id);
657 return handler.handle(msg);
660 template <
typename TAllMessages,
typename TMsg,
typename THandler,
typename... TParams>
661 static auto dispatchInternal(
typename TMsg::MsgIdParamType
id, std::size_t offset, TMsg& msg, THandler& handler, EmptyTag<TParams...>) ->
662 MessageInterfaceDispatchRetType<
663 typename std::decay<
decltype(handler)>::type>
665 static_cast<void>(id);
666 static_cast<void>(offset);
667 return handler.handle(msg);
670 template <
typename TAllMessages,
typename TMsg,
typename THandler,
typename... TParams>
671 static auto dispatchInternal(
typename TMsg::MsgIdParamType
id, TMsg& msg, THandler& handler, StrongTag<TParams...>) ->
672 MessageInterfaceDispatchRetType<
673 typename std::decay<
decltype(handler)>::type>
675 static constexpr std::size_t Count = std::tuple_size<TAllMessages>::value;
676 static constexpr auto HelperType = DispatchMsgHelperIntType<Count>::value;
678 DispatchMsgStrongLinearSwitchHelper<HelperType>::template
679 dispatch<TAllMessages, Count>(
id, msg, handler);
682 template <
typename TAllMessages,
typename TMsg,
typename THandler,
typename... TParams>
683 static auto dispatchInternal(
typename TMsg::MsgIdParamType
id, std::size_t offset, TMsg& msg, THandler& handler, StrongTag<TParams...>) ->
684 MessageInterfaceDispatchRetType<
685 typename std::decay<
decltype(handler)>::type>
689 MessageInterfaceDispatchRetType<
690 typename std::decay<
decltype(handler)>::type>;
691 return static_cast<RetType
>(handler.handle(msg));
695 static constexpr std::size_t Count = std::tuple_size<TAllMessages>::value;
696 static constexpr auto HelperType = DispatchMsgHelperIntType<Count>::value;
698 DispatchMsgStrongLinearSwitchHelper<HelperType>::template
699 dispatch<TAllMessages, Count>(
id, msg, handler);
703 template <
typename TAllMessages,
typename TMsg,
typename THandler,
typename... TParams>
704 static auto dispatchInternal(
typename TMsg::MsgIdParamType
id, TMsg& msg, THandler& handler, WeakTag<TParams...>) ->
705 MessageInterfaceDispatchRetType<
706 typename std::decay<
decltype(handler)>::type>
708 return dispatchInternal<TAllMessages>(
id, 0U, msg, handler, WeakTag<>());
711 template <
typename TAllMessages,
typename TMsg,
typename THandler,
typename... TParams>
712 static auto dispatchInternal(
typename TMsg::MsgIdParamType
id, std::size_t offset, TMsg& msg, THandler& handler, WeakTag<TParams...>) ->
713 MessageInterfaceDispatchRetType<
714 typename std::decay<
decltype(handler)>::type>
716 static constexpr std::size_t Count = std::tuple_size<TAllMessages>::value;
717 static constexpr auto HelperType = DispatchMsgHelperIntType<Count>::value;
719 DispatchMsgWeakLinearSwitchHelper<HelperType>::template
720 dispatch<TAllMessages, 0, Count>(
id, offset, msg, handler);
724 template <
typename TAllMessages,
typename TId,
typename THandler,
typename... TParams>
725 static bool dispatchTypeInternal(TId&&
id, THandler& handler, EmptyTag<TParams...>)
727 static_cast<void>(id);
728 static_cast<void>(handler);
732 template <
typename TAllMessages,
typename TId,
typename THandler,
typename... TParams>
733 static bool dispatchTypeInternal(TId&&
id, std::size_t offset, THandler& handler, EmptyTag<TParams...>)
735 static_cast<void>(id);
736 static_cast<void>(offset);
737 static_cast<void>(handler);
741 template <
typename TAllMessages,
typename TId,
typename THandler,
typename... TParams>
742 static bool dispatchTypeInternal(TId&&
id, THandler& handler, StrongTag<TParams...>)
744 using FirstMsgType =
typename std::tuple_element<0, TAllMessages>::type;
745 static_assert(comms::isMessageBase<FirstMsgType>(),
746 "The type in the tuple are expected to be proper messages");
747 static_assert(FirstMsgType::hasMsgIdType(),
"The messages must define their ID type");
748 using MsgIdParamType =
typename FirstMsgType::MsgIdParamType;
750 static constexpr std::size_t Count = std::tuple_size<TAllMessages>::value;
751 static constexpr auto HelperType = DispatchMsgHelperIntType<Count>::value;
753 DispatchMsgStrongLinearSwitchHelper<HelperType>::template
754 dispatchType<TAllMessages, Count>(
static_cast<MsgIdParamType
>(
id), handler);
757 template <
typename TAllMessages,
typename TId,
typename THandler,
typename... TParams>
758 static bool dispatchTypeInternal(TId&&
id, std::size_t offset, THandler& handler, StrongTag<TParams...>)
764 return dispatchTypeInternal<TAllMessages>(std::forward<TId>(
id), handler, StrongTag<TParams...>());
767 template <
typename TAllMessages,
typename TId,
typename THandler,
typename... TParams>
768 static bool dispatchTypeInternal(TId&&
id, THandler& handler, WeakTag<TParams...>)
770 return dispatchTypeInternal<TAllMessages>(std::forward<TId>(
id), 0U, handler, WeakTag<>());
773 template <
typename TAllMessages,
typename TId,
typename THandler,
typename... TParams>
774 static bool dispatchTypeInternal(TId&&
id, std::size_t offset, THandler& handler, WeakTag<TParams...>)
776 using FirstMsgType =
typename std::tuple_element<0, TAllMessages>::type;
777 static_assert(comms::isMessageBase<FirstMsgType>(),
778 "The type in the tuple are expected to be proper messages");
779 static_assert(FirstMsgType::hasMsgIdType(),
"The messages must define their ID type");
780 using MsgIdParamType =
typename FirstMsgType::MsgIdParamType;
782 static constexpr std::size_t Count = std::tuple_size<TAllMessages>::value;
783 static constexpr auto HelperType = DispatchMsgHelperIntType<Count>::value;
785 DispatchMsgWeakLinearSwitchHelper<HelperType>::template
786 dispatchType<TAllMessages, 0, Count>(
static_cast<MsgIdParamType
>(
id), offset, handler);
795COMMS_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:1487
Main namespace for all classes / functions of COMMS library.
Replacement to std::conditional.
Definition type_traits.h:29
Replacement to some types from standard type_traits.