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