15#include "comms/details/tag.h"
18#include "DispatchMsgHelperType.h"
20COMMS_MSVC_WARNING_PUSH
21COMMS_MSVC_WARNING_DISABLE(4702)
29template <DispatchMsgTypeEnum TType>
30class DispatchMsgStrongLinearSwitchHelper
32 template <
typename TAllMessages, std::
size_t TCount>
34 typename std::tuple_element<
35 std::tuple_size<TAllMessages>::value - TCount,
43 typename TAllMessages,
47 static auto dispatch(
typename TMsg::MsgIdParamType
id, TMsg& msg, THandler& handler) ->
48 MessageInterfaceDispatchRetType<
49 typename std::decay<
decltype(handler)>::type>
52 MessageInterfaceDispatchRetType<
53 typename std::decay<
decltype(handler)>::type>;
55 using Elem = FromElem<TAllMessages, TCount>;
57 static constexpr typename TMsg::MsgIdParamType fromId = Elem::doGetId();
60 auto& castedMsg =
static_cast<Elem&
>(msg);
61 return static_cast<RetType
>(handler.handle(castedMsg));
65 static constexpr std::size_t NextCount = TCount - 1U;
66 static constexpr auto HelperType = DispatchMsgHelperIntType<NextCount>::value;
68 DispatchMsgStrongLinearSwitchHelper<HelperType>::template
69 dispatch<TAllMessages, NextCount>(
id, msg, handler);
73 return static_cast<RetType
>(handler.handle(msg));
77 typename TAllMessages,
81 static bool dispatchType(TId&&
id, THandler& handler)
83 using Elem = FromElem<TAllMessages, TCount>;
84 static constexpr typename Elem::MsgIdParamType fromId = Elem::doGetId();
87 handler.template handle<Elem>();
92 static constexpr std::size_t NextCount = TCount - 1U;
93 static constexpr auto HelperType = DispatchMsgHelperIntType<NextCount>::value;
95 DispatchMsgStrongLinearSwitchHelper<HelperType>::template
96 dispatchType<TAllMessages, NextCount>(
id, handler);
106class DispatchMsgStrongLinearSwitchHelper<DispatchMsgTypeEnum::Single>
111 template <
typename TAllMessages>
113 typename std::tuple_element<
114 std::tuple_size<TAllMessages>::value - 1U,
122 typename TAllMessages,
126 static auto dispatch(
typename TMsg::MsgIdParamType
id, TMsg& msg, THandler& handler) ->
127 MessageInterfaceDispatchRetType<
128 typename std::decay<
decltype(handler)>::type>
130 static_assert(TCount == 1U,
"Invalid invocation");
133 MessageInterfaceDispatchRetType<
134 typename std::decay<
decltype(handler)>::type>;
136 using Elem = FromElem<TAllMessages>;
137 typename TMsg::MsgIdParamType elemId = Elem::doGetId();
139 return static_cast<RetType
>(handler.handle(msg));
142 auto& castedMsg =
static_cast<Elem&
>(msg);
143 return static_cast<RetType
>(handler.handle(castedMsg));
147 typename TAllMessages,
151 static bool dispatchType(TId&&
id, THandler& handler)
153 static_assert(TCount == 1U,
"Invalid invocation");
154 using Elem = FromElem<TAllMessages>;
155 typename Elem::MsgIdParamType elemId = Elem::doGetId();
160 handler.template handle<Elem>();
166class DispatchMsgStrongLinearSwitchHelper<DispatchMsgTypeEnum::None>
170 typename TAllMessages,
174 static auto dispatch(
typename TMsg::MsgIdParamType
id, TMsg& msg, THandler& handler) ->
175 MessageInterfaceDispatchRetType<
176 typename std::decay<
decltype(handler)>::type>
178 static_cast<void>(id);
181 MessageInterfaceDispatchRetType<
182 typename std::decay<
decltype(handler)>::type>;
183 return static_cast<RetType
>(handler.handle(msg));
186 template <
typename TId,
typename THandler>
187 static bool dispatchType(TId&&
id, THandler& handler)
189 static_cast<void>(id);
190 static_cast<void>(handler);
195template <
bool THasElems>
196class DispatchMsgLinearSwitchWeakCountFinder
198 template <
typename TAllMessages, std::
size_t TIdx>
199 using OrigMsgType =
typename std::tuple_element<TIdx, TAllMessages>::type;
201 template <
typename TAllMessages, std::
size_t TIdx, std::
size_t TCount>
203 typename std::tuple_element<
204 std::tuple_size<TAllMessages>::value - TCount,
209 template <
typename TAllMessages, std::
size_t TOrigIdx, std::
size_t TRem>
212 OrigMsgType<TAllMessages, TOrigIdx>::doGetId() == CurrMsgType<TAllMessages, TOrigIdx, TRem>::doGetId()
214 std::integral_constant<
216 1U + DispatchMsgLinearSwitchWeakCountFinder<(1U < TRem)>::template Type<TAllMessages, TOrigIdx, TRem - 1>::value
218 std::integral_constant<std::size_t, 0U>
223class DispatchMsgLinearSwitchWeakCountFinder<false>
226 template <
typename TAllMessages, std::
size_t TOrigIdx, std::
size_t TRem>
227 using Type = std::integral_constant<std::size_t, 0U>;
230template <DispatchMsgTypeEnum TType>
231class DispatchMsgWeakLinearSwitchHelper
237 template <
typename TAllMessages, std::
size_t TFrom>
238 using FromElem =
typename std::tuple_element<TFrom, TAllMessages>::type;
242 template <
typename TAllMessages, std::
size_t TFrom, std::
size_t TCount>
244 typename DispatchMsgLinearSwitchWeakCountFinder<
257 typename TAllMessages,
262 static auto dispatch(
typename TMsg::MsgIdParamType
id, std::size_t offset, TMsg& msg, THandler& handler) ->
263 MessageInterfaceDispatchRetType<
264 typename std::decay<
decltype(handler)>::type>
267 MessageInterfaceDispatchRetType<
268 typename std::decay<
decltype(handler)>::type>;
270 using Elem = FromElem<TAllMessages, TFrom>;
271 static constexpr typename TMsg::MsgIdParamType fromId = Elem::doGetId();
275 static constexpr std::size_t NextCount = SameIdsCount<TAllMessages, TFrom, TCount>::value;
276 static constexpr auto HelperType = DispatchMsgHelperIntType<NextCount>::value;
278 DispatchMsgWeakLinearSwitchHelper<HelperType>::template
279 dispatchOffset<TAllMessages, TFrom, NextCount>(offset, msg, handler);
283 static constexpr std::size_t SkipCount = SameIdsCount<TAllMessages, TFrom, TCount>::value;
284 static constexpr std::size_t NextFrom = TFrom + SkipCount;
285 static constexpr std::size_t NextCount = TCount - SkipCount;
286 static constexpr auto HelperType = DispatchMsgHelperIntType<NextCount>::value;
289 DispatchMsgWeakLinearSwitchHelper<HelperType>::template
290 dispatch<TAllMessages, NextFrom, NextCount>(
id, offset, msg, handler);
294 return static_cast<RetType
>(handler.handle(msg));
298 typename TAllMessages,
303 static auto dispatchOffset(std::size_t offset, TMsg& msg, THandler& handler) ->
304 MessageInterfaceDispatchRetType<
305 typename std::decay<
decltype(handler)>::type>
308 MessageInterfaceDispatchRetType<
309 typename std::decay<
decltype(handler)>::type>;
311 using Elem = FromElem<TAllMessages, TFrom>;
315 auto& castedMsg =
static_cast<Elem&
>(msg);
316 return static_cast<RetType
>(handler.handle(castedMsg));
319 static constexpr std::size_t NextCount = TCount - 1U;
320 static constexpr auto HelperType = DispatchMsgHelperIntType<NextCount>::value;
322 DispatchMsgWeakLinearSwitchHelper<HelperType>::template
323 dispatchOffset<TAllMessages, TFrom + 1, NextCount>(offset - 1, msg, handler);
327 return static_cast<RetType
>(handler.handle(msg));
331 typename TAllMessages,
336 static bool dispatchType(TId&&
id, std::size_t offset, THandler& handler)
338 using Elem = FromElem<TAllMessages, TFrom>;
339 static constexpr typename Elem::MsgIdParamType fromId = Elem::doGetId();
343 static constexpr std::size_t NextCount = SameIdsCount<TAllMessages, TFrom, TCount>::value;
344 static constexpr auto HelperType = DispatchMsgHelperIntType<NextCount>::value;
346 DispatchMsgWeakLinearSwitchHelper<HelperType>::template
347 dispatchTypeOffset<TAllMessages, TFrom, NextCount>(offset, handler);
351 static constexpr std::size_t SkipCount = SameIdsCount<TAllMessages, TFrom, TCount>::value;
352 static constexpr std::size_t NextFrom = TFrom + SkipCount;
353 static constexpr std::size_t NextCount = TCount - SkipCount;
354 static constexpr auto HelperType = DispatchMsgHelperIntType<NextCount>::value;
356 DispatchMsgWeakLinearSwitchHelper<HelperType>::template
357 dispatchType<TAllMessages, NextFrom, NextCount>(
id, offset, handler);
365 typename TAllMessages,
369 static bool dispatchTypeOffset(std::size_t offset, THandler& handler)
373 using Elem = FromElem<TAllMessages, TFrom>;
374 handler.template handle<Elem>();
377 static constexpr std::size_t NextCount = TCount - 1U;
378 static constexpr auto HelperType = DispatchMsgHelperIntType<NextCount>::value;
380 DispatchMsgWeakLinearSwitchHelper<HelperType>::template
381 dispatchTypeOffset<TAllMessages, TFrom + 1, NextCount>(offset - 1, handler);
390class DispatchMsgWeakLinearSwitchHelper<DispatchMsgTypeEnum::Single>
395 template <
typename TAllMessages, std::
size_t TFrom>
396 using FromElem =
typename std::tuple_element<TFrom, TAllMessages>::type;
401 typename TAllMessages,
406 static auto dispatch(
typename TMsg::MsgIdParamType
id, std::size_t offset, TMsg& msg, THandler& handler) ->
407 MessageInterfaceDispatchRetType<
408 typename std::decay<
decltype(handler)>::type>
411 MessageInterfaceDispatchRetType<
412 typename std::decay<
decltype(handler)>::type>;
415 return static_cast<RetType
>(handler.handle(msg));
418 using Elem = FromElem<TAllMessages, TFrom>;
419 typename TMsg::MsgIdParamType elemId = Elem::doGetId();
421 return static_cast<RetType
>(handler.handle(msg));
424 auto& castedMsg =
static_cast<Elem&
>(msg);
425 return static_cast<RetType
>(handler.handle(castedMsg));
429 typename TAllMessages,
434 static auto dispatchOffset(std::size_t offset, TMsg& msg, THandler& handler) ->
435 MessageInterfaceDispatchRetType<
436 typename std::decay<
decltype(handler)>::type>
439 MessageInterfaceDispatchRetType<
440 typename std::decay<
decltype(handler)>::type>;
443 return static_cast<RetType
>(handler.handle(msg));
446 using Elem = FromElem<TAllMessages, TFrom>;
447 auto& castedMsg =
static_cast<Elem&
>(msg);
448 return static_cast<RetType
>(handler.handle(castedMsg));
452 typename TAllMessages,
457 static bool dispatchType(TId&&
id, std::size_t offset, THandler& handler)
463 using Elem = FromElem<TAllMessages, TFrom>;
464 typename Elem::MsgIdParamType elemId = Elem::doGetId();
469 handler.template handle<Elem>();
474 typename TAllMessages,
478 static bool dispatchTypeOffset(std::size_t offset, THandler& handler)
484 using Elem = FromElem<TAllMessages, TFrom>;
485 handler.template handle<Elem>();
491class DispatchMsgWeakLinearSwitchHelper<DispatchMsgTypeEnum::None>
495 typename TAllMessages,
500 static auto dispatch(
typename TMsg::MsgIdParamType
id, std::size_t offset, TMsg& msg, THandler& handler) ->
501 MessageInterfaceDispatchRetType<
502 typename std::decay<
decltype(handler)>::type>
504 static_cast<void>(id);
505 static_cast<void>(offset);
508 MessageInterfaceDispatchRetType<
509 typename std::decay<
decltype(handler)>::type>;
510 return static_cast<RetType
>(handler.handle(msg));
514 typename TAllMessages,
519 static auto dispatchOffset(std::size_t offset, TMsg& msg, THandler& handler) ->
520 MessageInterfaceDispatchRetType<
521 typename std::decay<
decltype(handler)>::type>
523 static_cast<void>(offset);
526 MessageInterfaceDispatchRetType<
527 typename std::decay<
decltype(handler)>::type>;
528 return static_cast<RetType
>(handler.handle(msg));
532 typename TAllMessages,
537 static bool dispatchType(TId&&
id, std::size_t offset, THandler& handler)
539 static_cast<void>(id);
540 static_cast<void>(offset);
541 static_cast<void>(handler);
546 typename TAllMessages,
550 static bool dispatchTypeOffset(std::size_t offset, THandler& handler)
552 static_cast<void>(offset);
553 static_cast<void>(handler);
558template <
typename...>
559class DispatchMsgLinearSwitchHelper
561 template <
typename... TParams>
562 using EmptyTag = comms::details::tag::Tag1<>;
564 template <
typename... TParams>
565 using StrongTag = comms::details::tag::Tag2<>;
567 template <
typename... TParams>
568 using WeakTag = comms::details::tag::Tag3<>;
570 template <
typename TAllMessages,
typename...>
571 using StrongWeakTag =
572 typename comms::util::LazyShallowConditional<
573 allMessagesAreStrongSorted<TAllMessages>()
579 template <
typename TAllMessages,
typename...>
581 typename comms::util::LazyShallowConditional<
582 std::tuple_size<TAllMessages>::value == 0U
589 template <
typename TAllMessages,
typename TMsg>
591 typename comms::util::LazyShallowConditional<
592 comms::isMessageBase<TMsg>()
600 template <
typename TAllMessages,
typename TMsg,
typename THandler>
601 static auto dispatch(TMsg& msg, THandler& handler) ->
602 MessageInterfaceDispatchRetType<
603 typename std::decay<
decltype(handler)>::type>
605 using MsgType =
typename std::decay<
decltype(msg)>::type;
606 static_assert(MsgType::hasGetId(),
607 "The used message object must provide polymorphic ID retrieval function");
608 static_assert(MsgType::hasMsgIdType(),
609 "Message interface class must define its id type");
610 return dispatchInternal<TAllMessages>(msg.getId(), msg, handler, AdjustedTag<TAllMessages, MsgType>());
613 template <
typename TAllMessages,
typename TId,
typename TMsg,
typename THandler>
614 static auto dispatch(TId&&
id, TMsg& msg, THandler& handler) ->
615 MessageInterfaceDispatchRetType<
616 typename std::decay<
decltype(handler)>::type>
618 using MsgType =
typename std::decay<
decltype(msg)>::type;
619 static_assert(MsgType::hasMsgIdType(),
620 "Message interface class must define its id type");
621 using MsgIdParamType =
typename MsgType::MsgIdParamType;
622 return dispatchInternal<TAllMessages>(
static_cast<MsgIdParamType
>(
id), msg, handler, AdjustedTag<TAllMessages, MsgType>());
625 template <
typename TAllMessages,
typename TId,
typename TMsg,
typename THandler>
626 static auto dispatch(TId&&
id, std::size_t offset, TMsg& msg, THandler& handler) ->
627 MessageInterfaceDispatchRetType<
628 typename std::decay<
decltype(handler)>::type>
630 using MsgType =
typename std::decay<
decltype(msg)>::type;
631 static_assert(MsgType::hasMsgIdType(),
632 "Message interface class must define its id type");
633 using MsgIdParamType =
typename MsgType::MsgIdParamType;
634 return dispatchInternal<TAllMessages>(
static_cast<MsgIdParamType
>(
id), offset, msg, handler, AdjustedTag<TAllMessages, MsgType>());
637 template <
typename TAllMessages,
typename TId,
typename THandler>
638 static bool dispatchType(TId&&
id, THandler& handler)
640 return dispatchTypeInternal<TAllMessages>(std::forward<TId>(
id), handler, BinSearchTag<TAllMessages>());
643 template <
typename TAllMessages,
typename TId,
typename THandler>
644 static bool dispatchType(TId&&
id, std::size_t offset, THandler& handler)
646 return dispatchTypeInternal<TAllMessages>(std::forward<TId>(
id), offset, handler, BinSearchTag<TAllMessages>());
650 template <
typename TAllMessages,
typename TMsg,
typename THandler,
typename... TParams>
651 static auto dispatchInternal(
typename TMsg::MsgIdParamType
id, TMsg& msg, THandler& handler, EmptyTag<TParams...>) ->
652 MessageInterfaceDispatchRetType<
653 typename std::decay<
decltype(handler)>::type>
655 static_cast<void>(id);
656 return handler.handle(msg);
659 template <
typename TAllMessages,
typename TMsg,
typename THandler,
typename... TParams>
660 static auto dispatchInternal(
typename TMsg::MsgIdParamType
id, std::size_t offset, TMsg& msg, THandler& handler, EmptyTag<TParams...>) ->
661 MessageInterfaceDispatchRetType<
662 typename std::decay<
decltype(handler)>::type>
664 static_cast<void>(id);
665 static_cast<void>(offset);
666 return handler.handle(msg);
669 template <
typename TAllMessages,
typename TMsg,
typename THandler,
typename... TParams>
670 static auto dispatchInternal(
typename TMsg::MsgIdParamType
id, TMsg& msg, THandler& handler, StrongTag<TParams...>) ->
671 MessageInterfaceDispatchRetType<
672 typename std::decay<
decltype(handler)>::type>
674 static constexpr std::size_t Count = std::tuple_size<TAllMessages>::value;
675 static constexpr auto HelperType = DispatchMsgHelperIntType<Count>::value;
677 DispatchMsgStrongLinearSwitchHelper<HelperType>::template
678 dispatch<TAllMessages, Count>(
id, msg, handler);
681 template <
typename TAllMessages,
typename TMsg,
typename THandler,
typename... TParams>
682 static auto dispatchInternal(
typename TMsg::MsgIdParamType
id, std::size_t offset, TMsg& msg, THandler& handler, StrongTag<TParams...>) ->
683 MessageInterfaceDispatchRetType<
684 typename std::decay<
decltype(handler)>::type>
688 MessageInterfaceDispatchRetType<
689 typename std::decay<
decltype(handler)>::type>;
690 return static_cast<RetType
>(handler.handle(msg));
694 static constexpr std::size_t Count = std::tuple_size<TAllMessages>::value;
695 static constexpr auto HelperType = DispatchMsgHelperIntType<Count>::value;
697 DispatchMsgStrongLinearSwitchHelper<HelperType>::template
698 dispatch<TAllMessages, Count>(
id, msg, handler);
702 template <
typename TAllMessages,
typename TMsg,
typename THandler,
typename... TParams>
703 static auto dispatchInternal(
typename TMsg::MsgIdParamType
id, TMsg& msg, THandler& handler, WeakTag<TParams...>) ->
704 MessageInterfaceDispatchRetType<
705 typename std::decay<
decltype(handler)>::type>
707 return dispatchInternal<TAllMessages>(
id, 0U, msg, handler, WeakTag<>());
710 template <
typename TAllMessages,
typename TMsg,
typename THandler,
typename... TParams>
711 static auto dispatchInternal(
typename TMsg::MsgIdParamType
id, std::size_t offset, TMsg& msg, THandler& handler, WeakTag<TParams...>) ->
712 MessageInterfaceDispatchRetType<
713 typename std::decay<
decltype(handler)>::type>
715 static constexpr std::size_t Count = std::tuple_size<TAllMessages>::value;
716 static constexpr auto HelperType = DispatchMsgHelperIntType<Count>::value;
718 DispatchMsgWeakLinearSwitchHelper<HelperType>::template
719 dispatch<TAllMessages, 0, Count>(
id, offset, msg, handler);
723 template <
typename TAllMessages,
typename TId,
typename THandler,
typename... TParams>
724 static bool dispatchTypeInternal(TId&&
id, THandler& handler, EmptyTag<TParams...>)
726 static_cast<void>(id);
727 static_cast<void>(handler);
731 template <
typename TAllMessages,
typename TId,
typename THandler,
typename... TParams>
732 static bool dispatchTypeInternal(TId&&
id, std::size_t offset, THandler& handler, EmptyTag<TParams...>)
734 static_cast<void>(id);
735 static_cast<void>(offset);
736 static_cast<void>(handler);
740 template <
typename TAllMessages,
typename TId,
typename THandler,
typename... TParams>
741 static bool dispatchTypeInternal(TId&&
id, THandler& handler, StrongTag<TParams...>)
743 using FirstMsgType =
typename std::tuple_element<0, TAllMessages>::type;
744 static_assert(comms::isMessageBase<FirstMsgType>(),
745 "The type in the tuple are expected to be proper messages");
746 static_assert(FirstMsgType::hasMsgIdType(),
"The messages must define their ID type");
747 using MsgIdParamType =
typename FirstMsgType::MsgIdParamType;
749 static constexpr std::size_t Count = std::tuple_size<TAllMessages>::value;
750 static constexpr auto HelperType = DispatchMsgHelperIntType<Count>::value;
752 DispatchMsgStrongLinearSwitchHelper<HelperType>::template
753 dispatchType<TAllMessages, Count>(
static_cast<MsgIdParamType
>(
id), handler);
756 template <
typename TAllMessages,
typename TId,
typename THandler,
typename... TParams>
757 static bool dispatchTypeInternal(TId&&
id, std::size_t offset, THandler& handler, StrongTag<TParams...>)
763 return dispatchTypeInternal<TAllMessages>(std::forward<TId>(
id), handler, StrongTag<TParams...>());
766 template <
typename TAllMessages,
typename TId,
typename THandler,
typename... TParams>
767 static bool dispatchTypeInternal(TId&&
id, THandler& handler, WeakTag<TParams...>)
769 return dispatchTypeInternal<TAllMessages>(std::forward<TId>(
id), 0U, handler, WeakTag<>());
772 template <
typename TAllMessages,
typename TId,
typename THandler,
typename... TParams>
773 static bool dispatchTypeInternal(TId&&
id, std::size_t offset, THandler& handler, WeakTag<TParams...>)
775 using FirstMsgType =
typename std::tuple_element<0, TAllMessages>::type;
776 static_assert(comms::isMessageBase<FirstMsgType>(),
777 "The type in the tuple are expected to be proper messages");
778 static_assert(FirstMsgType::hasMsgIdType(),
"The messages must define their ID type");
779 using MsgIdParamType =
typename FirstMsgType::MsgIdParamType;
781 static constexpr std::size_t Count = std::tuple_size<TAllMessages>::value;
782 static constexpr auto HelperType = DispatchMsgHelperIntType<Count>::value;
784 DispatchMsgWeakLinearSwitchHelper<HelperType>::template
785 dispatchType<TAllMessages, 0, Count>(
static_cast<MsgIdParamType
>(
id), offset, handler);
794COMMS_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:1459
Main namespace for all classes / functions of COMMS library.
Replacement to std::conditional.
Definition type_traits.h:28
Replacement to some types from standard type_traits.