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 - 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
10
11#pragma once
12
13#include <tuple>
14#include <type_traits>
15
16#include "comms/util/Tuple.h"
18#include "comms/details/tag.h"
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
501
502protected:
503 ~GenericHandler() noexcept = default;
504};
505
506template <
507 typename TDefault,
508 typename T1,
509 typename T2,
510 typename T3,
511 typename T4,
512 typename T5,
513 typename T6,
514 typename TRetType>
515class GenericHandler<TDefault, std::tuple<T1, T2, T3, T4, T5, T6>, TRetType> : public
516 details::GenericHandlerBase<TDefault, TRetType>
517{
518 using BaseImpl = details::GenericHandlerBase<TDefault, TRetType>;
519public:
520
521 using BaseImpl::handle;
522 virtual TRetType handle(T1& msg)
523 {
524 static_assert(std::is_base_of<TDefault, T1>::value,
525 "TDefault must be base class for every element in TAll");
526
527 return this->handle(static_cast<TDefault&>(msg));
528 }
529
530 virtual TRetType handle(T2& msg)
531 {
532 static_assert(std::is_base_of<TDefault, T2>::value,
533 "TDefault must be base class for every element in TAll");
534
535 return this->handle(static_cast<TDefault&>(msg));
536 }
537
538 virtual TRetType handle(T3& msg)
539 {
540 static_assert(std::is_base_of<TDefault, T3>::value,
541 "TDefault must be base class for every element in TAll");
542
543 return this->handle(static_cast<TDefault&>(msg));
544 }
545
546 virtual TRetType handle(T4& msg)
547 {
548 static_assert(std::is_base_of<TDefault, T4>::value,
549 "TDefault must be base class for every element in TAll");
550
551 return this->handle(static_cast<TDefault&>(msg));
552 }
553
554 virtual TRetType handle(T5& msg)
555 {
556 static_assert(std::is_base_of<TDefault, T5>::value,
557 "TDefault must be base class for every element in TAll");
558
559 return this->handle(static_cast<TDefault&>(msg));
560 }
561
562 virtual TRetType handle(T6& msg)
563 {
564 static_assert(std::is_base_of<TDefault, T6>::value,
565 "TDefault must be base class for every element in TAll");
566
567 return this->handle(static_cast<TDefault&>(msg));
568 }
569
570
571protected:
572 ~GenericHandler() noexcept = default;
573};
574
575template <
576 typename TDefault,
577 typename T1,
578 typename T2,
579 typename T3,
580 typename T4,
581 typename T5,
582 typename TRetType>
583class GenericHandler<TDefault, std::tuple<T1, T2, T3, T4, T5>, TRetType> : public
584 details::GenericHandlerBase<TDefault, TRetType>
585{
586 using BaseImpl = details::GenericHandlerBase<TDefault, TRetType>;
587public:
588
589 using BaseImpl::handle;
590 virtual TRetType handle(T1& msg)
591 {
592 static_assert(std::is_base_of<TDefault, T1>::value,
593 "TDefault must be base class for every element in TAll");
594
595 return this->handle(static_cast<TDefault&>(msg));
596 }
597
598 virtual TRetType handle(T2& msg)
599 {
600 static_assert(std::is_base_of<TDefault, T2>::value,
601 "TDefault must be base class for every element in TAll");
602
603 return this->handle(static_cast<TDefault&>(msg));
604 }
605
606 virtual TRetType handle(T3& msg)
607 {
608 static_assert(std::is_base_of<TDefault, T3>::value,
609 "TDefault must be base class for every element in TAll");
610
611 return this->handle(static_cast<TDefault&>(msg));
612 }
613
614 virtual TRetType handle(T4& msg)
615 {
616 static_assert(std::is_base_of<TDefault, T4>::value,
617 "TDefault must be base class for every element in TAll");
618
619 return this->handle(static_cast<TDefault&>(msg));
620 }
621
622 virtual TRetType handle(T5& msg)
623 {
624 static_assert(std::is_base_of<TDefault, T5>::value,
625 "TDefault must be base class for every element in TAll");
626
627 return this->handle(static_cast<TDefault&>(msg));
628 }
629
630
631protected:
632 ~GenericHandler() noexcept = default;
633};
634
635template <
636 typename TDefault,
637 typename T1,
638 typename T2,
639 typename T3,
640 typename T4,
641 typename TRetType>
642class GenericHandler<TDefault, std::tuple<T1, T2, T3, T4>, TRetType> : public
643 details::GenericHandlerBase<TDefault, TRetType>
644{
645 using BaseImpl = details::GenericHandlerBase<TDefault, TRetType>;
646public:
647
648 using BaseImpl::handle;
649 virtual TRetType handle(T1& msg)
650 {
651 static_assert(std::is_base_of<TDefault, T1>::value,
652 "TDefault must be base class for every element in TAll");
653
654 return this->handle(static_cast<TDefault&>(msg));
655 }
656
657 virtual TRetType handle(T2& msg)
658 {
659 static_assert(std::is_base_of<TDefault, T2>::value,
660 "TDefault must be base class for every element in TAll");
661
662 return this->handle(static_cast<TDefault&>(msg));
663 }
664
665 virtual TRetType handle(T3& msg)
666 {
667 static_assert(std::is_base_of<TDefault, T3>::value,
668 "TDefault must be base class for every element in TAll");
669
670 return this->handle(static_cast<TDefault&>(msg));
671 }
672
673 virtual TRetType handle(T4& msg)
674 {
675 static_assert(std::is_base_of<TDefault, T4>::value,
676 "TDefault must be base class for every element in TAll");
677
678 return this->handle(static_cast<TDefault&>(msg));
679 }
680
681protected:
682 ~GenericHandler() noexcept = default;
683};
684
685template <typename TDefault, typename T1, typename T2, typename T3, typename TRetType>
686class GenericHandler<TDefault, std::tuple<T1, T2, T3>, TRetType> : public
687 details::GenericHandlerBase<TDefault, TRetType>
688{
689 using BaseImpl = details::GenericHandlerBase<TDefault, TRetType>;
690public:
691
692 using BaseImpl::handle;
693 virtual TRetType handle(T1& msg)
694 {
695 static_assert(std::is_base_of<TDefault, T1>::value,
696 "TDefault must be base class for every element in TAll");
697
698 return this->handle(static_cast<TDefault&>(msg));
699 }
700
701 virtual TRetType handle(T2& msg)
702 {
703 static_assert(std::is_base_of<TDefault, T2>::value,
704 "TDefault must be base class for every element in TAll");
705
706 return this->handle(static_cast<TDefault&>(msg));
707 }
708
709 virtual TRetType handle(T3& msg)
710 {
711 static_assert(std::is_base_of<TDefault, T3>::value,
712 "TDefault must be base class for every element in TAll");
713
714 return this->handle(static_cast<TDefault&>(msg));
715 }
716
717protected:
718 ~GenericHandler() noexcept = default;
719};
720
721template <typename TDefault, typename T1, typename T2, typename TRetType>
722class GenericHandler<TDefault, std::tuple<T1, T2>, TRetType> : public
723 details::GenericHandlerBase<TDefault, TRetType>
724{
725 using BaseImpl = details::GenericHandlerBase<TDefault, TRetType>;
726public:
727
728 using BaseImpl::handle;
729 virtual TRetType handle(T1& msg)
730 {
731 static_assert(std::is_base_of<TDefault, T1>::value,
732 "TDefault must be base class for every element in TAll");
733
734 return this->handle(static_cast<TDefault&>(msg));
735 }
736
737 virtual TRetType handle(T2& msg)
738 {
739 static_assert(std::is_base_of<TDefault, T2>::value,
740 "TDefault must be base class for every element in TAll");
741
742 return this->handle(static_cast<TDefault&>(msg));
743 }
744
745protected:
746 ~GenericHandler() noexcept = default;
747};
748
749template <typename TDefault, typename T1, typename TRetType>
750class GenericHandler<TDefault, std::tuple<T1>, TRetType> : public
751 details::GenericHandlerBase<TDefault, TRetType>
752{
753 using BaseImpl = details::GenericHandlerBase<TDefault, TRetType>;
754public:
755
756 using BaseImpl::handle;
757 virtual TRetType handle(T1& msg)
758 {
759 static_assert(std::is_base_of<TDefault, T1>::value,
760 "TDefault must be base class for every element in TAll");
761
762 return this->handle(static_cast<TDefault&>(msg));
763 }
764
765protected:
766 ~GenericHandler() noexcept = default;
767};
768
769template <typename TDefault, typename TRetType>
770class GenericHandler<TDefault, std::tuple<>, TRetType> : public
771 details::GenericHandlerBase<TDefault, TRetType>
772{
773 using BaseImpl = details::GenericHandlerBase<TDefault, TRetType>;
774public:
775 using BaseImpl::handle;
776protected:
777 ~GenericHandler() noexcept = default;
778};
779
781
782} // namespace comms
783
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.