COMMS
Template library intended to help with implementation of communication protocols.
Loading...
Searching...
No Matches
DispatchMsgLinearSwitchHelper.h
1//
2// Copyright 2019 - 2024 (C). Alex Robenko. All rights reserved.
3//
4// This Source Code Form is subject to the terms of the Mozilla Public
5// License, v. 2.0. If a copy of the MPL was not distributed with this
6// file, You can obtain one at http://mozilla.org/MPL/2.0/.
7
8#pragma once
9
10#include <type_traits>
11
13#include "comms/Message.h"
14#include "comms/MessageBase.h"
15#include "comms/details/tag.h"
18#include "DispatchMsgHelperType.h"
19
20COMMS_MSVC_WARNING_PUSH
21COMMS_MSVC_WARNING_DISABLE(4702) // Gives warning about unreachable code
22
23namespace comms
24{
25
26namespace details
27{
28
29template <DispatchMsgTypeEnum TType>
30class DispatchMsgStrongLinearSwitchHelper // <DispatchMsgTypeEnum::Multiple>
31{
32 template <typename TAllMessages, std::size_t TCount>
33 using FromElem =
34 typename std::tuple_element<
35 std::tuple_size<TAllMessages>::value - TCount,
36 TAllMessages
37 >::type;
38
39 // static_assert(messageHasStaticNumId<FromElem>(), "Message must define static ID");
40
41public:
42 template <
43 typename TAllMessages,
44 std::size_t TCount,
45 typename TMsg,
46 typename THandler>
47 static auto dispatch(typename TMsg::MsgIdParamType id, TMsg& msg, THandler& handler) ->
48 MessageInterfaceDispatchRetType<
49 typename std::decay<decltype(handler)>::type>
50 {
51 using RetType =
52 MessageInterfaceDispatchRetType<
53 typename std::decay<decltype(handler)>::type>;
54
55 using Elem = FromElem<TAllMessages, TCount>;
56
57 static constexpr typename TMsg::MsgIdParamType fromId = Elem::doGetId();
58 switch(id) {
59 case fromId: {
60 auto& castedMsg = static_cast<Elem&>(msg);
61 return static_cast<RetType>(handler.handle(castedMsg));
62 break;
63 }
64 default:
65 static constexpr std::size_t NextCount = TCount - 1U;
66 static constexpr auto HelperType = DispatchMsgHelperIntType<NextCount>::value;
67 return
68 DispatchMsgStrongLinearSwitchHelper<HelperType>::template
69 dispatch<TAllMessages, NextCount>(id, msg, handler);
70
71 };
72 // dead code (just in case), should not reach here
73 return static_cast<RetType>(handler.handle(msg));
74 }
75
76 template <
77 typename TAllMessages,
78 std::size_t TCount,
79 typename TId,
80 typename THandler>
81 static bool dispatchType(TId&& id, THandler& handler)
82 {
83 using Elem = FromElem<TAllMessages, TCount>;
84 static constexpr typename Elem::MsgIdParamType fromId = Elem::doGetId();
85 switch(id) {
86 case fromId: {
87 handler.template handle<Elem>();
88 return true;
89 break;
90 }
91 default:
92 static constexpr std::size_t NextCount = TCount - 1U;
93 static constexpr auto HelperType = DispatchMsgHelperIntType<NextCount>::value;
94 return
95 DispatchMsgStrongLinearSwitchHelper<HelperType>::template
96 dispatchType<TAllMessages, NextCount>(id, handler);
97
98 };
99 // dead code (just in case), should not reach here
100 return false;
101 }
102
103};
104
105template <>
106class DispatchMsgStrongLinearSwitchHelper<DispatchMsgTypeEnum::Single>
107{
108 // static_assert(1 <= std::tuple_size<TAllMessages>::value,
109 // "Invalid template params");
110
111 template <typename TAllMessages>
112 using FromElem =
113 typename std::tuple_element<
114 std::tuple_size<TAllMessages>::value - 1U,
115 TAllMessages
116 >::type;
117
118 // static_assert(messageHasStaticNumId<Elem>(), "Message must define static ID");
119
120public:
121 template <
122 typename TAllMessages,
123 std::size_t TCount,
124 typename TMsg,
125 typename THandler>
126 static auto dispatch(typename TMsg::MsgIdParamType id, TMsg& msg, THandler& handler) ->
127 MessageInterfaceDispatchRetType<
128 typename std::decay<decltype(handler)>::type>
129 {
130 static_assert(TCount == 1U, "Invalid invocation");
131
132 using RetType =
133 MessageInterfaceDispatchRetType<
134 typename std::decay<decltype(handler)>::type>;
135
136 using Elem = FromElem<TAllMessages>;
137 typename TMsg::MsgIdParamType elemId = Elem::doGetId();
138 if (id != elemId) {
139 return static_cast<RetType>(handler.handle(msg));
140 }
141
142 auto& castedMsg = static_cast<Elem&>(msg);
143 return static_cast<RetType>(handler.handle(castedMsg));
144 }
145
146 template <
147 typename TAllMessages,
148 std::size_t TCount,
149 typename TId,
150 typename THandler>
151 static bool dispatchType(TId&& id, THandler& handler)
152 {
153 static_assert(TCount == 1U, "Invalid invocation");
154 using Elem = FromElem<TAllMessages>;
155 typename Elem::MsgIdParamType elemId = Elem::doGetId();
156 if (id != elemId) {
157 return false;
158 }
159
160 handler.template handle<Elem>();
161 return true;
162 }
163};
164
165template <>
166class DispatchMsgStrongLinearSwitchHelper<DispatchMsgTypeEnum::None>
167{
168public:
169 template <
170 typename TAllMessages,
171 std::size_t TCount,
172 typename TMsg,
173 typename THandler>
174 static auto dispatch(typename TMsg::MsgIdParamType id, TMsg& msg, THandler& handler) ->
175 MessageInterfaceDispatchRetType<
176 typename std::decay<decltype(handler)>::type>
177 {
178 static_cast<void>(id);
179
180 using RetType =
181 MessageInterfaceDispatchRetType<
182 typename std::decay<decltype(handler)>::type>;
183 return static_cast<RetType>(handler.handle(msg));
184 }
185
186 template <typename TId, typename THandler>
187 static bool dispatchType(TId&& id, THandler& handler)
188 {
189 static_cast<void>(id);
190 static_cast<void>(handler);
191 return false;
192 }
193};
194
195template <bool THasElems>
196class DispatchMsgLinearSwitchWeakCountFinder // <true>
197{
198 template <typename TAllMessages, std::size_t TIdx>
199 using OrigMsgType = typename std::tuple_element<TIdx, TAllMessages>::type;
200
201 template <typename TAllMessages, std::size_t TIdx, std::size_t TCount>
202 using CurrMsgType =
203 typename std::tuple_element<
204 std::tuple_size<TAllMessages>::value - TCount,
205 TAllMessages
206 >::type;
207
208public:
209 template <typename TAllMessages, std::size_t TOrigIdx, std::size_t TRem>
210 using Type =
212 OrigMsgType<TAllMessages, TOrigIdx>::doGetId() == CurrMsgType<TAllMessages, TOrigIdx, TRem>::doGetId()
213 >::template Type<
214 std::integral_constant<
215 std::size_t,
216 1U + DispatchMsgLinearSwitchWeakCountFinder<(1U < TRem)>::template Type<TAllMessages, TOrigIdx, TRem - 1>::value
217 >,
218 std::integral_constant<std::size_t, 0U>
219 >;
220};
221
222template <>
223class DispatchMsgLinearSwitchWeakCountFinder<false>
224{
225public:
226 template <typename TAllMessages, std::size_t TOrigIdx, std::size_t TRem>
227 using Type = std::integral_constant<std::size_t, 0U>;
228};
229
230template <DispatchMsgTypeEnum TType>
231class DispatchMsgWeakLinearSwitchHelper // <DispatchMsgTypeEnum::Multiple>
232{
233 // static_assert(TFrom + TCount <= std::tuple_size<TAllMessages>::value,
234 // "Invalid template params");
235 // static_assert(2 <= TCount, "Invalid invocation");
236
237 template <typename TAllMessages, std::size_t TFrom>
238 using FromElem = typename std::tuple_element<TFrom, TAllMessages>::type;
239
240 // static_assert(messageHasStaticNumId<FromElem>(), "Message must define static ID");
241
242 template <typename TAllMessages, std::size_t TFrom, std::size_t TCount>
243 using SameIdsCount =
244 typename DispatchMsgLinearSwitchWeakCountFinder<
245 0 < TCount
246 >::template Type<
247 TAllMessages,
248 TFrom,
249 TCount
250 >;
251
252 // static_assert(SameIdsCount <= TCount, "Invalid template params");
253 // static_assert(0U < SameIdsCount, "Invalid template params");
254
255public:
256 template <
257 typename TAllMessages,
258 std::size_t TFrom,
259 std::size_t TCount,
260 typename TMsg,
261 typename THandler>
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>
265 {
266 using RetType =
267 MessageInterfaceDispatchRetType<
268 typename std::decay<decltype(handler)>::type>;
269
270 using Elem = FromElem<TAllMessages, TFrom>;
271 static constexpr typename TMsg::MsgIdParamType fromId = Elem::doGetId();
272 switch(id) {
273 case fromId:
274 {
275 static constexpr std::size_t NextCount = SameIdsCount<TAllMessages, TFrom, TCount>::value;
276 static constexpr auto HelperType = DispatchMsgHelperIntType<NextCount>::value;
277 return
278 DispatchMsgWeakLinearSwitchHelper<HelperType>::template
279 dispatchOffset<TAllMessages, TFrom, NextCount>(offset, msg, handler);
280 }
281 default:
282 {
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;
287
288 return
289 DispatchMsgWeakLinearSwitchHelper<HelperType>::template
290 dispatch<TAllMessages, NextFrom, NextCount>(id, offset, msg, handler);
291 }
292 };
293 // dead code (just in case), should not reach here
294 return static_cast<RetType>(handler.handle(msg));
295 }
296
297 template <
298 typename TAllMessages,
299 std::size_t TFrom,
300 std::size_t TCount,
301 typename TMsg,
302 typename THandler>
303 static auto dispatchOffset(std::size_t offset, TMsg& msg, THandler& handler) ->
304 MessageInterfaceDispatchRetType<
305 typename std::decay<decltype(handler)>::type>
306 {
307 using RetType =
308 MessageInterfaceDispatchRetType<
309 typename std::decay<decltype(handler)>::type>;
310
311 using Elem = FromElem<TAllMessages, TFrom>;
312 switch(offset) {
313 case 0:
314 {
315 auto& castedMsg = static_cast<Elem&>(msg);
316 return static_cast<RetType>(handler.handle(castedMsg));
317 }
318 default:
319 static constexpr std::size_t NextCount = TCount - 1U;
320 static constexpr auto HelperType = DispatchMsgHelperIntType<NextCount>::value;
321 return
322 DispatchMsgWeakLinearSwitchHelper<HelperType>::template
323 dispatchOffset<TAllMessages, TFrom + 1, NextCount>(offset - 1, msg, handler);
324 };
325
326 // dead code (just in case), should not reach here
327 return static_cast<RetType>(handler.handle(msg));
328 }
329
330 template <
331 typename TAllMessages,
332 std::size_t TFrom,
333 std::size_t TCount,
334 typename TId,
335 typename THandler>
336 static bool dispatchType(TId&& id, std::size_t offset, THandler& handler)
337 {
338 using Elem = FromElem<TAllMessages, TFrom>;
339 static constexpr typename Elem::MsgIdParamType fromId = Elem::doGetId();
340 switch(id) {
341 case fromId:
342 {
343 static constexpr std::size_t NextCount = SameIdsCount<TAllMessages, TFrom, TCount>::value;
344 static constexpr auto HelperType = DispatchMsgHelperIntType<NextCount>::value;
345 return
346 DispatchMsgWeakLinearSwitchHelper<HelperType>::template
347 dispatchTypeOffset<TAllMessages, TFrom, NextCount>(offset, handler);
348 }
349 default:
350 {
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;
355 return
356 DispatchMsgWeakLinearSwitchHelper<HelperType>::template
357 dispatchType<TAllMessages, NextFrom, NextCount>(id, offset, handler);
358 }
359 };
360 // dead code (just in case), should not reach here
361 return false;
362 }
363
364 template <
365 typename TAllMessages,
366 std::size_t TFrom,
367 std::size_t TCount,
368 typename THandler>
369 static bool dispatchTypeOffset(std::size_t offset, THandler& handler)
370 {
371 switch(offset) {
372 case 0:
373 using Elem = FromElem<TAllMessages, TFrom>;
374 handler.template handle<Elem>();
375 return true;
376 default:
377 static constexpr std::size_t NextCount = TCount - 1U;
378 static constexpr auto HelperType = DispatchMsgHelperIntType<NextCount>::value;
379 return
380 DispatchMsgWeakLinearSwitchHelper<HelperType>::template
381 dispatchTypeOffset<TAllMessages, TFrom + 1, NextCount>(offset - 1, handler);
382 };
383
384 // dead code (just in case), should not reach here
385 return false;
386 }
387};
388
389template <>
390class DispatchMsgWeakLinearSwitchHelper<DispatchMsgTypeEnum::Single>
391{
392 // static_assert(TFrom + 1 <= std::tuple_size<TAllMessages>::value,
393 // "Invalid template params");
394
395 template <typename TAllMessages, std::size_t TFrom>
396 using FromElem = typename std::tuple_element<TFrom, TAllMessages>::type;
397 // static_assert(messageHasStaticNumId<Elem>(), "Message must define static ID");
398
399public:
400 template <
401 typename TAllMessages,
402 std::size_t TFrom,
403 std::size_t TCount,
404 typename TMsg,
405 typename THandler>
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>
409 {
410 using RetType =
411 MessageInterfaceDispatchRetType<
412 typename std::decay<decltype(handler)>::type>;
413
414 if (offset != 0U) {
415 return static_cast<RetType>(handler.handle(msg));
416 }
417
418 using Elem = FromElem<TAllMessages, TFrom>;
419 typename TMsg::MsgIdParamType elemId = Elem::doGetId();
420 if (id != elemId) {
421 return static_cast<RetType>(handler.handle(msg));
422 }
423
424 auto& castedMsg = static_cast<Elem&>(msg);
425 return static_cast<RetType>(handler.handle(castedMsg));
426 }
427
428 template <
429 typename TAllMessages,
430 std::size_t TFrom,
431 std::size_t TCount,
432 typename TMsg,
433 typename THandler>
434 static auto dispatchOffset(std::size_t offset, TMsg& msg, THandler& handler) ->
435 MessageInterfaceDispatchRetType<
436 typename std::decay<decltype(handler)>::type>
437 {
438 using RetType =
439 MessageInterfaceDispatchRetType<
440 typename std::decay<decltype(handler)>::type>;
441
442 if (offset != 0U) {
443 return static_cast<RetType>(handler.handle(msg));
444 }
445
446 using Elem = FromElem<TAllMessages, TFrom>;
447 auto& castedMsg = static_cast<Elem&>(msg);
448 return static_cast<RetType>(handler.handle(castedMsg));
449 }
450
451 template <
452 typename TAllMessages,
453 std::size_t TFrom,
454 std::size_t TCount,
455 typename TId,
456 typename THandler>
457 static bool dispatchType(TId&& id, std::size_t offset, THandler& handler)
458 {
459 if (offset != 0U) {
460 return false;
461 }
462
463 using Elem = FromElem<TAllMessages, TFrom>;
464 typename Elem::MsgIdParamType elemId = Elem::doGetId();
465 if (id != elemId) {
466 return false;
467 }
468
469 handler.template handle<Elem>();
470 return true;
471 }
472
473 template <
474 typename TAllMessages,
475 std::size_t TFrom,
476 std::size_t TCount,
477 typename THandler>
478 static bool dispatchTypeOffset(std::size_t offset, THandler& handler)
479 {
480 if (offset != 0U) {
481 return false;
482 }
483
484 using Elem = FromElem<TAllMessages, TFrom>;
485 handler.template handle<Elem>();
486 return true;
487 }
488};
489
490template <>
491class DispatchMsgWeakLinearSwitchHelper<DispatchMsgTypeEnum::None>
492{
493public:
494 template <
495 typename TAllMessages,
496 std::size_t TFrom,
497 std::size_t TCount,
498 typename TMsg,
499 typename THandler>
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>
503 {
504 static_cast<void>(id);
505 static_cast<void>(offset);
506
507 using RetType =
508 MessageInterfaceDispatchRetType<
509 typename std::decay<decltype(handler)>::type>;
510 return static_cast<RetType>(handler.handle(msg));
511 }
512
513 template <
514 typename TAllMessages,
515 std::size_t TFrom,
516 std::size_t TCount,
517 typename TMsg,
518 typename THandler>
519 static auto dispatchOffset(std::size_t offset, TMsg& msg, THandler& handler) ->
520 MessageInterfaceDispatchRetType<
521 typename std::decay<decltype(handler)>::type>
522 {
523 static_cast<void>(offset);
524
525 using RetType =
526 MessageInterfaceDispatchRetType<
527 typename std::decay<decltype(handler)>::type>;
528 return static_cast<RetType>(handler.handle(msg));
529 }
530
531 template <
532 typename TAllMessages,
533 std::size_t TFrom,
534 std::size_t TCount,
535 typename TId,
536 typename THandler>
537 static bool dispatchType(TId&& id, std::size_t offset, THandler& handler)
538 {
539 static_cast<void>(id);
540 static_cast<void>(offset);
541 static_cast<void>(handler);
542 return false;
543 }
544
545 template <
546 typename TAllMessages,
547 std::size_t TFrom,
548 std::size_t TCount,
549 typename THandler>
550 static bool dispatchTypeOffset(std::size_t offset, THandler& handler)
551 {
552 static_cast<void>(offset);
553 static_cast<void>(handler);
554 return false;
555 }
556};
557
558template <typename...>
559class DispatchMsgLinearSwitchHelper
560{
561 template <typename... TParams>
562 using EmptyTag = comms::details::tag::Tag1<>;
563
564 template <typename... TParams>
565 using StrongTag = comms::details::tag::Tag2<>;
566
567 template <typename... TParams>
568 using WeakTag = comms::details::tag::Tag3<>;
569
570 template <typename TAllMessages, typename...>
571 using StrongWeakTag =
572 typename comms::util::LazyShallowConditional<
573 allMessagesAreStrongSorted<TAllMessages>()
574 >::template Type<
575 StrongTag,
576 WeakTag
577 >;
578
579 template <typename TAllMessages, typename...>
580 using BinSearchTag =
581 typename comms::util::LazyShallowConditional<
582 std::tuple_size<TAllMessages>::value == 0U
583 >::template Type<
584 EmptyTag,
585 StrongWeakTag,
586 TAllMessages
587 >;
588
589 template <typename TAllMessages, typename TMsg>
590 using AdjustedTag =
591 typename comms::util::LazyShallowConditional<
592 comms::isMessageBase<TMsg>()
593 >::template Type<
594 EmptyTag,
595 BinSearchTag,
596 TAllMessages
597 >;
598
599public:
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>
604 {
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>());
611 }
612
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>
617 {
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>());
623 }
624
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>
629 {
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>());
635 }
636
637 template <typename TAllMessages, typename TId, typename THandler>
638 static bool dispatchType(TId&& id, THandler& handler)
639 {
640 return dispatchTypeInternal<TAllMessages>(std::forward<TId>(id), handler, BinSearchTag<TAllMessages>());
641 }
642
643 template <typename TAllMessages, typename TId, typename THandler>
644 static bool dispatchType(TId&& id, std::size_t offset, THandler& handler)
645 {
646 return dispatchTypeInternal<TAllMessages>(std::forward<TId>(id), offset, handler, BinSearchTag<TAllMessages>());
647 }
648
649private:
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>
654 {
655 static_cast<void>(id);
656 return handler.handle(msg);
657 }
658
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>
663 {
664 static_cast<void>(id);
665 static_cast<void>(offset);
666 return handler.handle(msg);
667 }
668
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>
673 {
674 static constexpr std::size_t Count = std::tuple_size<TAllMessages>::value;
675 static constexpr auto HelperType = DispatchMsgHelperIntType<Count>::value;
676 return
677 DispatchMsgStrongLinearSwitchHelper<HelperType>::template
678 dispatch<TAllMessages, Count>(id, msg, handler);
679 }
680
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>
685 {
686 if (offset != 0U) {
687 using RetType =
688 MessageInterfaceDispatchRetType<
689 typename std::decay<decltype(handler)>::type>;
690 return static_cast<RetType>(handler.handle(msg));
691
692 }
693
694 static constexpr std::size_t Count = std::tuple_size<TAllMessages>::value;
695 static constexpr auto HelperType = DispatchMsgHelperIntType<Count>::value;
696 return
697 DispatchMsgStrongLinearSwitchHelper<HelperType>::template
698 dispatch<TAllMessages, Count>(id, msg, handler);
699
700 }
701
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>
706 {
707 return dispatchInternal<TAllMessages>(id, 0U, msg, handler, WeakTag<>());
708 }
709
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>
714 {
715 static constexpr std::size_t Count = std::tuple_size<TAllMessages>::value;
716 static constexpr auto HelperType = DispatchMsgHelperIntType<Count>::value;
717 return
718 DispatchMsgWeakLinearSwitchHelper<HelperType>::template
719 dispatch<TAllMessages, 0, Count>(id, offset, msg, handler);
720
721 }
722
723 template <typename TAllMessages, typename TId, typename THandler, typename... TParams>
724 static bool dispatchTypeInternal(TId&& id, THandler& handler, EmptyTag<TParams...>)
725 {
726 static_cast<void>(id);
727 static_cast<void>(handler);
728 return false;
729 }
730
731 template <typename TAllMessages, typename TId, typename THandler, typename... TParams>
732 static bool dispatchTypeInternal(TId&& id, std::size_t offset, THandler& handler, EmptyTag<TParams...>)
733 {
734 static_cast<void>(id);
735 static_cast<void>(offset);
736 static_cast<void>(handler);
737 return false;
738 }
739
740 template <typename TAllMessages, typename TId, typename THandler, typename... TParams>
741 static bool dispatchTypeInternal(TId&& id, THandler& handler, StrongTag<TParams...>)
742 {
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;
748
749 static constexpr std::size_t Count = std::tuple_size<TAllMessages>::value;
750 static constexpr auto HelperType = DispatchMsgHelperIntType<Count>::value;
751 return
752 DispatchMsgStrongLinearSwitchHelper<HelperType>::template
753 dispatchType<TAllMessages, Count>(static_cast<MsgIdParamType>(id), handler);
754 }
755
756 template <typename TAllMessages, typename TId, typename THandler, typename... TParams>
757 static bool dispatchTypeInternal(TId&& id, std::size_t offset, THandler& handler, StrongTag<TParams...>)
758 {
759 if (offset != 0U) {
760 return false;
761 }
762
763 return dispatchTypeInternal<TAllMessages>(std::forward<TId>(id), handler, StrongTag<TParams...>());
764 }
765
766 template <typename TAllMessages, typename TId, typename THandler, typename... TParams>
767 static bool dispatchTypeInternal(TId&& id, THandler& handler, WeakTag<TParams...>)
768 {
769 return dispatchTypeInternal<TAllMessages>(std::forward<TId>(id), 0U, handler, WeakTag<>());
770 }
771
772 template <typename TAllMessages, typename TId, typename THandler, typename... TParams>
773 static bool dispatchTypeInternal(TId&& id, std::size_t offset, THandler& handler, WeakTag<TParams...>)
774 {
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;
780
781 static constexpr std::size_t Count = std::tuple_size<TAllMessages>::value;
782 static constexpr auto HelperType = DispatchMsgHelperIntType<Count>::value;
783 return
784 DispatchMsgWeakLinearSwitchHelper<HelperType>::template
785 dispatchType<TAllMessages, 0, Count>(static_cast<MsgIdParamType>(id), offset, handler);
786 }
787
788};
789
790} // namespace details
791
792} // namespace comms
793
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.