COMMS
Template library intended to help with implementation of communication protocols.
Loading...
Searching...
No Matches
GenericHandler.h
Go to the documentation of this file.
1//
2// Copyright 2014 - 2025 (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
10
11#pragma once
12
13#include "comms/details/tag.h"
14#include "comms/util/Tuple.h"
16
17#include <tuple>
18#include <type_traits>
19
20namespace comms
21{
22
48template <typename TDefault, typename TAll, typename TRetType = void>
50{
51 static_assert(util::IsTuple<TAll>::Value,
52 "TAll must be std::tuple");
53
54#ifdef FOR_DOXYGEN_DOC_ONLY
55public:
57 using RetType = TRetType;
58
61 virtual TRetType handle(TDefault& msg);
62
63protected:
70 ~GenericHandler() noexcept = default;
71#endif
72};
73
75template <
76 typename TDefault,
77 typename T1,
78 typename T2,
79 typename T3,
80 typename T4,
81 typename T5,
82 typename T6,
83 typename T7,
84 typename T8,
85 typename T9,
86 typename T10,
87 typename... TRest,
88 typename TRetType>
89class GenericHandler<TDefault, std::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TRest...>, TRetType>
90 : public GenericHandler<TDefault, std::tuple<TRest...>, TRetType>
91{
92 using BaseImpl = GenericHandler<TDefault, std::tuple<TRest...>, TRetType>;
93public:
94
95 using BaseImpl::handle;
96 virtual TRetType handle(T1& msg)
97 {
98 static_assert(std::is_base_of<TDefault, T1>::value,
99 "TDefault must be base class for every element in TAll");
100
101 return this->handle(static_cast<TDefault&>(msg));
102 }
103
104 virtual TRetType handle(T2& msg)
105 {
106 static_assert(std::is_base_of<TDefault, T2>::value,
107 "TDefault must be base class for every element in TAll");
108
109 return this->handle(static_cast<TDefault&>(msg));
110 }
111
112 virtual TRetType handle(T3& msg)
113 {
114 static_assert(std::is_base_of<TDefault, T3>::value,
115 "TDefault must be base class for every element in TAll");
116
117 return this->handle(static_cast<TDefault&>(msg));
118 }
119
120 virtual TRetType handle(T4& msg)
121 {
122 static_assert(std::is_base_of<TDefault, T4>::value,
123 "TDefault must be base class for every element in TAll");
124
125 return this->handle(static_cast<TDefault&>(msg));
126 }
127
128 virtual TRetType handle(T5& msg)
129 {
130 static_assert(std::is_base_of<TDefault, T5>::value,
131 "TDefault must be base class for every element in TAll");
132
133 return this->handle(static_cast<TDefault&>(msg));
134 }
135
136 virtual TRetType handle(T6& msg)
137 {
138 static_assert(std::is_base_of<TDefault, T6>::value,
139 "TDefault must be base class for every element in TAll");
140
141 return this->handle(static_cast<TDefault&>(msg));
142 }
143
144 virtual TRetType handle(T7& msg)
145 {
146 static_assert(std::is_base_of<TDefault, T7>::value,
147 "TDefault must be base class for every element in TAll");
148
149 return this->handle(static_cast<TDefault&>(msg));
150 }
151
152 virtual TRetType handle(T8& msg)
153 {
154 static_assert(std::is_base_of<TDefault, T8>::value,
155 "TDefault must be base class for every element in TAll");
156
157 return this->handle(static_cast<TDefault&>(msg));
158 }
159
160 virtual TRetType handle(T9& msg)
161 {
162 static_assert(std::is_base_of<TDefault, T9>::value,
163 "TDefault must be base class for every element in TAll");
164
165 return this->handle(static_cast<TDefault&>(msg));
166 }
167
168 virtual TRetType handle(T10& msg)
169 {
170 static_assert(std::is_base_of<TDefault, T10>::value,
171 "TDefault must be base class for every element in TAll");
172
173 return this->handle(static_cast<TDefault&>(msg));
174 }
175
176protected:
177 ~GenericHandler() noexcept = default;
178};
179
180namespace details
181{
182
183template <typename TDefault, typename TRetType>
184class GenericHandlerBase
185{
186public:
187 using RetType = TRetType;
188
189 virtual TRetType handle(TDefault& msg)
190 {
191 // Nothing to do
192 static_cast<void>(msg);
193
194 using Tag =
195 typename comms::util::LazyShallowConditional<
196 std::is_void<TRetType>::value
197 >::template Type<
198 VoidReturnTag,
199 RetValueShallowCondWrap
200 >;
201
202 return defaultHandle(Tag());
203 }
204
205private:
206 template <typename... TParams>
207 using VoidReturnTag = comms::details::tag::Tag1<>;
208
209 template <typename... TParams>
210 using ReferenceReturnTag = comms::details::tag::Tag2<>;
211
212 template <typename... TParams>
213 using ValueReturnTag = comms::details::tag::Tag3<>;
214
215 template <typename... TParams>
216 using RetValueShallowCondWrap =
217 typename comms::util::LazyShallowConditional<
218 std::is_lvalue_reference<TRetType>::value
219 >::template Type<
220 ReferenceReturnTag,
221 ValueReturnTag,
222 TParams...
223 >;
224
225 template <typename... TParams>
226 void defaultHandle(VoidReturnTag<TParams...>)
227 {
228 }
229
230 template <typename... TParams>
231 TRetType defaultHandle(ReferenceReturnTag<TParams...>)
232 {
233 static typename std::decay<TRetType>::type Value;
234 return Value;
235 }
236
237 template <typename... TParams>
238 TRetType defaultHandle(ValueReturnTag<TParams...>)
239 {
240 return typename std::decay<TRetType>::type();
241 }
242
243};
244
245} // namespace details
246
247template <
248 typename TDefault,
249 typename T1,
250 typename T2,
251 typename T3,
252 typename T4,
253 typename T5,
254 typename T6,
255 typename T7,
256 typename T8,
257 typename T9,
258 typename TRetType>
259class GenericHandler<TDefault, std::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9>, TRetType> : public
260 details::GenericHandlerBase<TDefault, TRetType>
261{
262 using BaseImpl = details::GenericHandlerBase<TDefault, TRetType>;
263public:
264
265 using BaseImpl::handle;
266 virtual TRetType handle(T1& msg)
267 {
268 static_assert(std::is_base_of<TDefault, T1>::value,
269 "TDefault must be base class for every element in TAll");
270
271 return this->handle(static_cast<TDefault&>(msg));
272 }
273
274 virtual TRetType handle(T2& msg)
275 {
276 static_assert(std::is_base_of<TDefault, T2>::value,
277 "TDefault must be base class for every element in TAll");
278
279 return this->handle(static_cast<TDefault&>(msg));
280 }
281
282 virtual TRetType handle(T3& msg)
283 {
284 static_assert(std::is_base_of<TDefault, T3>::value,
285 "TDefault must be base class for every element in TAll");
286
287 return this->handle(static_cast<TDefault&>(msg));
288 }
289
290 virtual TRetType handle(T4& msg)
291 {
292 static_assert(std::is_base_of<TDefault, T4>::value,
293 "TDefault must be base class for every element in TAll");
294
295 return this->handle(static_cast<TDefault&>(msg));
296 }
297
298 virtual TRetType handle(T5& msg)
299 {
300 static_assert(std::is_base_of<TDefault, T5>::value,
301 "TDefault must be base class for every element in TAll");
302
303 return this->handle(static_cast<TDefault&>(msg));
304 }
305
306 virtual TRetType handle(T6& msg)
307 {
308 static_assert(std::is_base_of<TDefault, T6>::value,
309 "TDefault must be base class for every element in TAll");
310
311 return this->handle(static_cast<TDefault&>(msg));
312 }
313
314 virtual TRetType handle(T7& msg)
315 {
316 static_assert(std::is_base_of<TDefault, T7>::value,
317 "TDefault must be base class for every element in TAll");
318
319 return this->handle(static_cast<TDefault&>(msg));
320 }
321
322 virtual TRetType handle(T8& msg)
323 {
324 static_assert(std::is_base_of<TDefault, T8>::value,
325 "TDefault must be base class for every element in TAll");
326
327 return this->handle(static_cast<TDefault&>(msg));
328 }
329
330 virtual TRetType handle(T9& msg)
331 {
332 static_assert(std::is_base_of<TDefault, T9>::value,
333 "TDefault must be base class for every element in TAll");
334
335 return this->handle(static_cast<TDefault&>(msg));
336 }
337
338protected:
339 ~GenericHandler() noexcept = default;
340};
341
342template <
343 typename TDefault,
344 typename T1,
345 typename T2,
346 typename T3,
347 typename T4,
348 typename T5,
349 typename T6,
350 typename T7,
351 typename T8,
352 typename TRetType>
353class GenericHandler<TDefault, std::tuple<T1, T2, T3, T4, T5, T6, T7, T8>, TRetType> : public
354 details::GenericHandlerBase<TDefault, TRetType>
355{
356 using BaseImpl = details::GenericHandlerBase<TDefault, TRetType>;
357public:
358
359 using BaseImpl::handle;
360 virtual TRetType handle(T1& msg)
361 {
362 static_assert(std::is_base_of<TDefault, T1>::value,
363 "TDefault must be base class for every element in TAll");
364
365 return this->handle(static_cast<TDefault&>(msg));
366 }
367
368 virtual TRetType handle(T2& msg)
369 {
370 static_assert(std::is_base_of<TDefault, T2>::value,
371 "TDefault must be base class for every element in TAll");
372
373 return this->handle(static_cast<TDefault&>(msg));
374 }
375
376 virtual TRetType handle(T3& msg)
377 {
378 static_assert(std::is_base_of<TDefault, T3>::value,
379 "TDefault must be base class for every element in TAll");
380
381 return this->handle(static_cast<TDefault&>(msg));
382 }
383
384 virtual TRetType handle(T4& msg)
385 {
386 static_assert(std::is_base_of<TDefault, T4>::value,
387 "TDefault must be base class for every element in TAll");
388
389 return this->handle(static_cast<TDefault&>(msg));
390 }
391
392 virtual TRetType handle(T5& msg)
393 {
394 static_assert(std::is_base_of<TDefault, T5>::value,
395 "TDefault must be base class for every element in TAll");
396
397 return this->handle(static_cast<TDefault&>(msg));
398 }
399
400 virtual TRetType handle(T6& msg)
401 {
402 static_assert(std::is_base_of<TDefault, T6>::value,
403 "TDefault must be base class for every element in TAll");
404
405 return this->handle(static_cast<TDefault&>(msg));
406 }
407
408 virtual TRetType handle(T7& msg)
409 {
410 static_assert(std::is_base_of<TDefault, T7>::value,
411 "TDefault must be base class for every element in TAll");
412
413 return this->handle(static_cast<TDefault&>(msg));
414 }
415
416 virtual TRetType handle(T8& msg)
417 {
418 static_assert(std::is_base_of<TDefault, T8>::value,
419 "TDefault must be base class for every element in TAll");
420
421 return this->handle(static_cast<TDefault&>(msg));
422 }
423
424protected:
425 ~GenericHandler() noexcept = default;
426};
427
428template <
429 typename TDefault,
430 typename T1,
431 typename T2,
432 typename T3,
433 typename T4,
434 typename T5,
435 typename T6,
436 typename T7,
437 typename TRetType>
438class GenericHandler<TDefault, std::tuple<T1, T2, T3, T4, T5, T6, T7>, TRetType> : public
439 details::GenericHandlerBase<TDefault, TRetType>
440{
441 using BaseImpl = details::GenericHandlerBase<TDefault, TRetType>;
442public:
443
444 using BaseImpl::handle;
445 virtual TRetType handle(T1& msg)
446 {
447 static_assert(std::is_base_of<TDefault, T1>::value,
448 "TDefault must be base class for every element in TAll");
449
450 return this->handle(static_cast<TDefault&>(msg));
451 }
452
453 virtual TRetType handle(T2& msg)
454 {
455 static_assert(std::is_base_of<TDefault, T2>::value,
456 "TDefault must be base class for every element in TAll");
457
458 return this->handle(static_cast<TDefault&>(msg));
459 }
460
461 virtual TRetType handle(T3& msg)
462 {
463 static_assert(std::is_base_of<TDefault, T3>::value,
464 "TDefault must be base class for every element in TAll");
465
466 return this->handle(static_cast<TDefault&>(msg));
467 }
468
469 virtual TRetType handle(T4& msg)
470 {
471 static_assert(std::is_base_of<TDefault, T4>::value,
472 "TDefault must be base class for every element in TAll");
473
474 return this->handle(static_cast<TDefault&>(msg));
475 }
476
477 virtual TRetType handle(T5& msg)
478 {
479 static_assert(std::is_base_of<TDefault, T5>::value,
480 "TDefault must be base class for every element in TAll");
481
482 return this->handle(static_cast<TDefault&>(msg));
483 }
484
485 virtual TRetType handle(T6& msg)
486 {
487 static_assert(std::is_base_of<TDefault, T6>::value,
488 "TDefault must be base class for every element in TAll");
489
490 return this->handle(static_cast<TDefault&>(msg));
491 }
492
493 virtual TRetType handle(T7& msg)
494 {
495 static_assert(std::is_base_of<TDefault, T7>::value,
496 "TDefault must be base class for every element in TAll");
497
498 return this->handle(static_cast<TDefault&>(msg));
499 }
500
501protected:
502 ~GenericHandler() noexcept = default;
503};
504
505template <
506 typename TDefault,
507 typename T1,
508 typename T2,
509 typename T3,
510 typename T4,
511 typename T5,
512 typename T6,
513 typename TRetType>
514class GenericHandler<TDefault, std::tuple<T1, T2, T3, T4, T5, T6>, TRetType> : public
515 details::GenericHandlerBase<TDefault, TRetType>
516{
517 using BaseImpl = details::GenericHandlerBase<TDefault, TRetType>;
518public:
519
520 using BaseImpl::handle;
521 virtual TRetType handle(T1& msg)
522 {
523 static_assert(std::is_base_of<TDefault, T1>::value,
524 "TDefault must be base class for every element in TAll");
525
526 return this->handle(static_cast<TDefault&>(msg));
527 }
528
529 virtual TRetType handle(T2& msg)
530 {
531 static_assert(std::is_base_of<TDefault, T2>::value,
532 "TDefault must be base class for every element in TAll");
533
534 return this->handle(static_cast<TDefault&>(msg));
535 }
536
537 virtual TRetType handle(T3& msg)
538 {
539 static_assert(std::is_base_of<TDefault, T3>::value,
540 "TDefault must be base class for every element in TAll");
541
542 return this->handle(static_cast<TDefault&>(msg));
543 }
544
545 virtual TRetType handle(T4& msg)
546 {
547 static_assert(std::is_base_of<TDefault, T4>::value,
548 "TDefault must be base class for every element in TAll");
549
550 return this->handle(static_cast<TDefault&>(msg));
551 }
552
553 virtual TRetType handle(T5& msg)
554 {
555 static_assert(std::is_base_of<TDefault, T5>::value,
556 "TDefault must be base class for every element in TAll");
557
558 return this->handle(static_cast<TDefault&>(msg));
559 }
560
561 virtual TRetType handle(T6& msg)
562 {
563 static_assert(std::is_base_of<TDefault, T6>::value,
564 "TDefault must be base class for every element in TAll");
565
566 return this->handle(static_cast<TDefault&>(msg));
567 }
568
569protected:
570 ~GenericHandler() noexcept = default;
571};
572
573template <
574 typename TDefault,
575 typename T1,
576 typename T2,
577 typename T3,
578 typename T4,
579 typename T5,
580 typename TRetType>
581class GenericHandler<TDefault, std::tuple<T1, T2, T3, T4, T5>, TRetType> : public
582 details::GenericHandlerBase<TDefault, TRetType>
583{
584 using BaseImpl = details::GenericHandlerBase<TDefault, TRetType>;
585public:
586
587 using BaseImpl::handle;
588 virtual TRetType handle(T1& msg)
589 {
590 static_assert(std::is_base_of<TDefault, T1>::value,
591 "TDefault must be base class for every element in TAll");
592
593 return this->handle(static_cast<TDefault&>(msg));
594 }
595
596 virtual TRetType handle(T2& msg)
597 {
598 static_assert(std::is_base_of<TDefault, T2>::value,
599 "TDefault must be base class for every element in TAll");
600
601 return this->handle(static_cast<TDefault&>(msg));
602 }
603
604 virtual TRetType handle(T3& msg)
605 {
606 static_assert(std::is_base_of<TDefault, T3>::value,
607 "TDefault must be base class for every element in TAll");
608
609 return this->handle(static_cast<TDefault&>(msg));
610 }
611
612 virtual TRetType handle(T4& msg)
613 {
614 static_assert(std::is_base_of<TDefault, T4>::value,
615 "TDefault must be base class for every element in TAll");
616
617 return this->handle(static_cast<TDefault&>(msg));
618 }
619
620 virtual TRetType handle(T5& msg)
621 {
622 static_assert(std::is_base_of<TDefault, T5>::value,
623 "TDefault must be base class for every element in TAll");
624
625 return this->handle(static_cast<TDefault&>(msg));
626 }
627
628protected:
629 ~GenericHandler() noexcept = default;
630};
631
632template <
633 typename TDefault,
634 typename T1,
635 typename T2,
636 typename T3,
637 typename T4,
638 typename TRetType>
639class GenericHandler<TDefault, std::tuple<T1, T2, T3, T4>, TRetType> : public
640 details::GenericHandlerBase<TDefault, TRetType>
641{
642 using BaseImpl = details::GenericHandlerBase<TDefault, TRetType>;
643public:
644
645 using BaseImpl::handle;
646 virtual TRetType handle(T1& msg)
647 {
648 static_assert(std::is_base_of<TDefault, T1>::value,
649 "TDefault must be base class for every element in TAll");
650
651 return this->handle(static_cast<TDefault&>(msg));
652 }
653
654 virtual TRetType handle(T2& msg)
655 {
656 static_assert(std::is_base_of<TDefault, T2>::value,
657 "TDefault must be base class for every element in TAll");
658
659 return this->handle(static_cast<TDefault&>(msg));
660 }
661
662 virtual TRetType handle(T3& msg)
663 {
664 static_assert(std::is_base_of<TDefault, T3>::value,
665 "TDefault must be base class for every element in TAll");
666
667 return this->handle(static_cast<TDefault&>(msg));
668 }
669
670 virtual TRetType handle(T4& msg)
671 {
672 static_assert(std::is_base_of<TDefault, T4>::value,
673 "TDefault must be base class for every element in TAll");
674
675 return this->handle(static_cast<TDefault&>(msg));
676 }
677
678protected:
679 ~GenericHandler() noexcept = default;
680};
681
682template <typename TDefault, typename T1, typename T2, typename T3, typename TRetType>
683class GenericHandler<TDefault, std::tuple<T1, T2, T3>, TRetType> : public
684 details::GenericHandlerBase<TDefault, TRetType>
685{
686 using BaseImpl = details::GenericHandlerBase<TDefault, TRetType>;
687public:
688
689 using BaseImpl::handle;
690 virtual TRetType handle(T1& msg)
691 {
692 static_assert(std::is_base_of<TDefault, T1>::value,
693 "TDefault must be base class for every element in TAll");
694
695 return this->handle(static_cast<TDefault&>(msg));
696 }
697
698 virtual TRetType handle(T2& msg)
699 {
700 static_assert(std::is_base_of<TDefault, T2>::value,
701 "TDefault must be base class for every element in TAll");
702
703 return this->handle(static_cast<TDefault&>(msg));
704 }
705
706 virtual TRetType handle(T3& msg)
707 {
708 static_assert(std::is_base_of<TDefault, T3>::value,
709 "TDefault must be base class for every element in TAll");
710
711 return this->handle(static_cast<TDefault&>(msg));
712 }
713
714protected:
715 ~GenericHandler() noexcept = default;
716};
717
718template <typename TDefault, typename T1, typename T2, typename TRetType>
719class GenericHandler<TDefault, std::tuple<T1, T2>, TRetType> : public
720 details::GenericHandlerBase<TDefault, TRetType>
721{
722 using BaseImpl = details::GenericHandlerBase<TDefault, TRetType>;
723public:
724
725 using BaseImpl::handle;
726 virtual TRetType handle(T1& msg)
727 {
728 static_assert(std::is_base_of<TDefault, T1>::value,
729 "TDefault must be base class for every element in TAll");
730
731 return this->handle(static_cast<TDefault&>(msg));
732 }
733
734 virtual TRetType handle(T2& msg)
735 {
736 static_assert(std::is_base_of<TDefault, T2>::value,
737 "TDefault must be base class for every element in TAll");
738
739 return this->handle(static_cast<TDefault&>(msg));
740 }
741
742protected:
743 ~GenericHandler() noexcept = default;
744};
745
746template <typename TDefault, typename T1, typename TRetType>
747class GenericHandler<TDefault, std::tuple<T1>, TRetType> : public
748 details::GenericHandlerBase<TDefault, TRetType>
749{
750 using BaseImpl = details::GenericHandlerBase<TDefault, TRetType>;
751public:
752
753 using BaseImpl::handle;
754 virtual TRetType handle(T1& msg)
755 {
756 static_assert(std::is_base_of<TDefault, T1>::value,
757 "TDefault must be base class for every element in TAll");
758
759 return this->handle(static_cast<TDefault&>(msg));
760 }
761
762protected:
763 ~GenericHandler() noexcept = default;
764};
765
766template <typename TDefault, typename TRetType>
767class GenericHandler<TDefault, std::tuple<>, TRetType> : public
768 details::GenericHandlerBase<TDefault, TRetType>
769{
770 using BaseImpl = details::GenericHandlerBase<TDefault, TRetType>;
771public:
772 using BaseImpl::handle;
773protected:
774 ~GenericHandler() noexcept = default;
775};
776
778
779} // namespace comms
780
Contains various tuple type manipulation classes and functions.
Generic common message handler.
Definition GenericHandler.h:50
~GenericHandler() noexcept=default
Destructor.
virtual TRetType handle(TDefault &msg)
Handle message object.
TRetType RetType
Return type of every handle() member function.
Definition GenericHandler.h:57
Main namespace for all classes / functions of COMMS library.
STL namespace.
Check whether provided type is a variant of std::tuple.
Definition Tuple.h:36
Replacement to some types from standard type_traits.