Embedded Template Library 1.0
Loading...
Searching...
No Matches
message_packet_generator.h
1/******************************************************************************
2The MIT License(MIT)
3
4Embedded Template Library.
5https://github.com/ETLCPP/etl
6https://www.etlcpp.com
7
8Copyright(c) 2020 John Wellbelove
9
10Permission is hereby granted, free of charge, to any person obtaining a copy
11of this software and associated documentation files(the "Software"), to deal
12in the Software without restriction, including without limitation the rights
13to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
14copies of the Software, and to permit persons to whom the Software is
15furnished to do so, subject to the following conditions :
16
17The above copyright notice and this permission notice shall be included in all
18copies or substantial portions of the Software.
19
20THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
23AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26SOFTWARE.
27******************************************************************************/
28
29/*[[[cog
30import cog
31cog.outl("#if 0")
32]]]*/
33/*[[[end]]]*/
34#error THIS HEADER IS A GENERATOR. DO NOT INCLUDE.
35/*[[[cog
36import cog
37cog.outl("#endif")
38]]]*/
39/*[[[end]]]*/
40
41/*[[[cog
42import cog
43cog.outl("//***************************************************************************")
44cog.outl("// THIS FILE HAS BEEN AUTO GENERATED. DO NOT EDIT THIS FILE.")
45cog.outl("//***************************************************************************")
46]]]*/
47/*[[[end]]]*/
48
49//***************************************************************************
50// To generate to header file, run this at the command line.
51// Note: You will need Python and COG installed.
52//
53// python -m cogapp -d -e -omessage_packet.h -DHandlers=<n> message_packet_generator.h
54// Where <n> is the number of messages to support.
55//
56// e.g.
57// To generate handlers for up to 16 messages...
58// python -m cogapp -d -e -omessage_packet.h -DHandlers=16 message_packet_generator.h
59//
60// See generate.bat
61//***************************************************************************
62
63#ifndef ETL_MESSAGE_PACKET_INCLUDED
64#define ETL_MESSAGE_PACKET_INCLUDED
65
66#include "platform.h"
67
68#include "message.h"
69#include "error_handler.h"
70#include "static_assert.h"
71#include "largest.h"
72#include "alignment.h"
73#include "utility.h"
74
75#include <stdint.h>
76
77namespace etl
78{
79#if ETL_USING_CPP17 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION)
80 //***************************************************************************
81 // The definition for all message types.
82 //***************************************************************************
83 template <typename... TMessageTypes>
84 class message_packet
85 {
86
87 private:
88
89 template <typename T>
90 static constexpr bool IsMessagePacket = etl::is_same_v< etl::remove_const_t<etl::remove_reference_t<T>>, etl::message_packet<TMessageTypes...>>;
91
92 template <typename T>
93 static constexpr bool IsInMessageList = etl::is_one_of_v<etl::remove_const_t<etl::remove_reference_t<T>>, TMessageTypes...>;
94
95 template <typename T>
97
98 public:
99
100 //********************************************
102 message_packet()
103 : valid(false)
104 {
105 }
107
108 //********************************************
110 //********************************************
112 template <typename T, typename = typename etl::enable_if<IsIMessage<T> || IsInMessageList<T>, int>::type>
113 explicit message_packet(T&& msg)
114 : valid(true)
115 {
116 if constexpr (IsIMessage<T>)
117 {
118 if (accepts(msg))
119 {
120 add_new_message(etl::forward<T>(msg));
121 valid = true;
122 }
123 else
124 {
125 valid = false;
126 }
127
128 ETL_ASSERT(valid, ETL_ERROR(unhandled_message_exception));
129 }
130 else if constexpr (IsInMessageList<T>)
131 {
132 add_new_message_type<T>(etl::forward<T>(msg));
133 }
134 else
135 {
136 ETL_STATIC_ASSERT(IsInMessageList<T>, "Message not in packet type list");
137 }
138 }
140
141 //**********************************************
142 message_packet(const message_packet& other)
143 {
144 valid = other.is_valid();
145
146 if (valid)
147 {
148 add_new_message(other.get());
149 }
150 }
151
152#if ETL_USING_CPP11
153 //**********************************************
154 message_packet(message_packet&& other)
155 {
156 valid = other.is_valid();
157
158 if (valid)
159 {
160 add_new_message(etl::move(other.get()));
161 }
162 }
163#endif
164
165 //**********************************************
166 void copy(const message_packet& other)
167 {
168 valid = other.is_valid();
169
170 if (valid)
171 {
172 add_new_message(other.get());
173 }
174 }
175
176 //**********************************************
177 void copy(message_packet&& other)
178 {
179 valid = other.is_valid();
180
181 if (valid)
182 {
183 add_new_message(etl::move(other.get()));
184 }
185 }
186
187 //**********************************************
189 message_packet& operator =(const message_packet& rhs)
190 {
191 delete_current_message();
192 valid = rhs.is_valid();
193 if (valid)
194 {
195 add_new_message(rhs.get());
196 }
197
198 return *this;
199 }
201
202 //**********************************************
204 message_packet& operator =(message_packet&& rhs)
205 {
206 delete_current_message();
207 valid = rhs.is_valid();
208 if (valid)
209 {
210 add_new_message(etl::move(rhs.get()));
211 }
212
213 return *this;
214 }
216
217 //********************************************
218 ~message_packet()
219 {
220 delete_current_message();
221 }
222
223 //********************************************
224 etl::imessage& get() ETL_NOEXCEPT
225 {
226 return *static_cast<etl::imessage*>(data);
227 }
228
229 //********************************************
230 const etl::imessage& get() const ETL_NOEXCEPT
231 {
232 return *static_cast<const etl::imessage*>(data);
233 }
234
235 //********************************************
236 bool is_valid() const
237 {
238 return valid;
239 }
240
241 //**********************************************
242 static ETL_CONSTEXPR bool accepts(etl::message_id_t id)
243 {
244 return (accepts_message<TMessageTypes::ID>(id) || ...);
245 }
246
247 //**********************************************
248 static ETL_CONSTEXPR bool accepts(const etl::imessage& msg)
249 {
250 return accepts(msg.get_message_id());
251 }
252
253 //**********************************************
254 template <etl::message_id_t Id>
255 static ETL_CONSTEXPR bool accepts()
256 {
257 return (accepts_message<TMessageTypes::ID, Id>() || ...);
258 }
259
260 //**********************************************
261 template <typename TMessage>
262 static ETL_CONSTEXPR
264 accepts()
265 {
266 return accepts<TMessage::ID>();
267 }
268
269 enum
270 {
271 SIZE = etl::largest<TMessageTypes...>::size,
272 ALIGNMENT = etl::largest<TMessageTypes...>::alignment
273 };
274
275 private:
276
277 //**********************************************
278 template <etl::message_id_t Id1, etl::message_id_t Id2>
279 static bool accepts_message()
280 {
281 return Id1 == Id2;
282 }
283
284 //**********************************************
285 template <etl::message_id_t Id1>
286 static bool accepts_message(etl::message_id_t id2)
287 {
288 return Id1 == id2;
289 }
290
291 //********************************************
293 void delete_current_message()
294 {
295 if (valid)
296 {
297 etl::imessage* pmsg = static_cast<etl::imessage*>(data);
298
299#if ETL_HAS_VIRTUAL_MESSAGES
300 pmsg->~imessage();
301#else
302 delete_message(pmsg);
303#endif
304 }
305 }
307
308#if !ETL_HAS_VIRTUAL_MESSAGES
309 //********************************************
310 void delete_message(etl::imessage* pmsg)
311 {
312 (delete_message_type<TMessageTypes>(pmsg) || ...);
313 }
314
315 //********************************************
316 template <typename TType>
317 bool delete_message_type(etl::imessage* pmsg)
318 {
319 if (TType::ID == pmsg->get_message_id())
320 {
321 TType* p = static_cast<TType*>(pmsg);
322 p->~TType();
323 return true;
324 }
325 else
326 {
327 return false;
328 }
329 }
330#endif
331
332 //********************************************
333 void add_new_message(const etl::imessage& msg)
334 {
335 (add_new_message_type<TMessageTypes>(msg) || ...);
336 }
337
338 //********************************************
339 void add_new_message(etl::imessage&& msg)
340 {
341 (add_new_message_type<TMessageTypes>(etl::move(msg)) || ...);
342 }
343
345 //********************************************
347 //********************************************
348 template <typename TMessage>
350 add_new_message_type(TMessage&& msg)
351 {
352 void* p = data;
354 }
356
358 //********************************************
359 template <typename TType>
360 bool add_new_message_type(const etl::imessage& msg)
361 {
362 if (TType::ID == msg.get_message_id())
363 {
364 void* p = data;
365 new (p) TType(static_cast<const TType&>(msg));
366 return true;
367 }
368 else
369 {
370 return false;
371 }
372 }
374
375 //********************************************
376 template <typename TType>
377 bool add_new_message_type(etl::imessage&& msg)
378 {
379 if (TType::ID == msg.get_message_id())
380 {
381 void* p = data;
382 new (p) TType(static_cast<TType&&>(msg));
383 return true;
384 }
385 else
386 {
387 return false;
388 }
389 }
390
392 bool valid;
393 };
394
395#else
396
397 /*[[[cog
398 import cog
399
400 ################################################
401 def generate_accepts_return(n):
402 cog.out(" return")
403 for i in range(1, n + 1):
404 cog.out(" T%d::ID == id" % i)
405 if i < n:
406 cog.out(" ||")
407 if i % 4 == 0:
408 cog.outl("")
409 cog.out(" ")
410 cog.outl(";")
411
412 ################################################
413 def generate_accepts_return_compile_time(n):
414 cog.out(" return")
415 for i in range(1, n + 1):
416 cog.out(" T%d::ID == Id" % i)
417 if i < n:
418 cog.out(" ||")
419 if i % 4 == 0:
420 cog.outl("")
421 cog.out(" ")
422 cog.outl(";")
423
424 ################################################
425 def generate_accepts_return_compile_time_TMessage(n):
426 cog.out(" return")
427 for i in range(1, n + 1):
428 cog.out(" T%d::ID == TMessage::ID" % i)
429 if i < n:
430 cog.out(" ||")
431 if i % 4 == 0:
432 cog.outl("")
433 cog.out(" ")
434 cog.outl(";")
435
436 ################################################
437 def generate_static_assert_cpp03(n):
438 cog.outl(" // Not etl::message_packet, not etl::imessage and in typelist.")
439 cog.out(" static const bool Enabled = (!etl::is_same<typename etl::remove_cvref<TMessage>::type, etl::message_packet<")
440 for i in range(1, n):
441 cog.out("T%d, " % i)
442 cog.outl("T%s> >::value &&" % n)
443 cog.outl(" !etl::is_same<typename etl::remove_cvref<TMessage>::type, etl::imessage>::value &&")
444 cog.out(" etl::is_one_of<typename etl::remove_cvref<TMessage>::type,")
445 for i in range(1, n):
446 cog.out("T%d, " % i)
447 cog.outl("T%s>::value);" % n)
448 cog.outl("")
449 cog.outl(" ETL_STATIC_ASSERT(Enabled, \"Message not in packet type list\");")
450
451 ################################################
452 def generate_static_assert_cpp11(n):
453 cog.outl(" // Not etl::message_packet, not etl::imessage and in typelist.")
454 cog.out(" static constexpr bool Enabled = (!etl::is_same<typename etl::remove_cvref<TMessage>::type, etl::message_packet<")
455 for i in range(1, n):
456 cog.out("T%d, " % i)
457 cog.outl("T%s> >::value &&" % n)
458 cog.outl(" !etl::is_same<typename etl::remove_cvref<TMessage>::type, etl::imessage>::value &&")
459 cog.out(" etl::is_one_of<typename etl::remove_cvref<TMessage>::type,")
460 for i in range(1, n):
461 cog.out("T%d, " % i)
462 cog.outl("T%s>::value);" % n)
463 cog.outl("")
464 cog.outl(" ETL_STATIC_ASSERT(Enabled, \"Message not in packet type list\");")
465
466 ################################################
467 # The first definition for all of the messages.
468 ################################################
469 cog.outl("//***************************************************************************")
470 cog.outl("// The definition for all %s message types." % Handlers)
471 cog.outl("//***************************************************************************")
472 cog.out("template <")
473 cog.out("typename T1, ")
474 for n in range(2, int(Handlers)):
475 cog.out("typename T%s = void, " % n)
476 if n % 4 == 0:
477 cog.outl("")
478 cog.out(" ")
479 cog.outl("typename T%s = void>" % int(Handlers))
480 cog.outl("class message_packet")
481 cog.outl("{")
482 cog.outl("public:")
483 cog.outl("")
484 cog.outl(" //********************************************")
485 cog.outl("#include \"private/diagnostic_uninitialized_push.h\"")
486 cog.outl(" message_packet()")
487 cog.outl(" : valid(false)")
488 cog.outl(" {")
489 cog.outl(" }")
490 cog.outl("#include \"private/diagnostic_pop.h\"")
491 cog.outl("")
492 cog.outl(" //********************************************")
493 cog.outl("#include \"private/diagnostic_uninitialized_push.h\"")
494 cog.outl(" explicit message_packet(const etl::imessage& msg)")
495 cog.outl(" {")
496 cog.outl(" if (accepts(msg))")
497 cog.outl(" {")
498 cog.outl(" add_new_message(msg);")
499 cog.outl(" valid = true;")
500 cog.outl(" }")
501 cog.outl(" else")
502 cog.outl(" {")
503 cog.outl(" valid = false;")
504 cog.outl(" }")
505 cog.outl("")
506 cog.outl(" ETL_ASSERT(valid, ETL_ERROR(unhandled_message_exception));")
507 cog.outl(" }")
508 cog.outl("#include \"private/diagnostic_pop.h\"")
509 cog.outl("")
510 cog.outl("#if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION)")
511 cog.outl(" //********************************************")
512 cog.outl("#include \"private/diagnostic_uninitialized_push.h\"")
513 cog.outl(" explicit message_packet(etl::imessage&& msg)")
514 cog.outl(" {")
515 cog.outl(" if (accepts(msg))")
516 cog.outl(" {")
517 cog.outl(" add_new_message(etl::move(msg));")
518 cog.outl(" valid = true;")
519 cog.outl(" }")
520 cog.outl(" else")
521 cog.outl(" {")
522 cog.outl(" valid = false;")
523 cog.outl(" }")
524 cog.outl("")
525 cog.outl(" ETL_ASSERT(valid, ETL_ERROR(unhandled_message_exception));")
526 cog.outl(" }")
527 cog.outl("#include \"private/diagnostic_pop.h\"")
528 cog.outl("#endif")
529 cog.outl("")
530 cog.outl("#if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION) && !defined(ETL_COMPILER_GREEN_HILLS)")
531 cog.outl(" //********************************************")
532 cog.outl("#include \"private/diagnostic_uninitialized_push.h\"")
533 cog.out(" template <typename TMessage, typename = typename etl::enable_if<!etl::is_same<typename etl::remove_cvref<TMessage>::type, etl::message_packet<")
534 for n in range(1, int(Handlers)):
535 cog.out("T%s, " % n)
536 cog.outl("T%s> >::value &&" % int(Handlers))
537 cog.outl(" !etl::is_same<typename etl::remove_cvref<TMessage>::type, etl::imessage>::value &&")
538 cog.out(" !etl::is_one_of<typename etl::remove_cvref<TMessage>::type, ")
539 for n in range(1, int(Handlers)):
540 cog.out("T%s, " % n)
541 cog.outl("T%s>::value, int>::type>" % int(Handlers))
542 cog.outl(" explicit message_packet(TMessage&& /*msg*/)")
543 cog.outl(" : valid(true)")
544 cog.outl(" {")
545 generate_static_assert_cpp11(int(Handlers))
546 cog.outl(" }")
547 cog.outl("#include \"private/diagnostic_pop.h\"")
548 cog.outl("#else")
549 cog.outl(" //********************************************")
550 cog.outl("#include \"private/diagnostic_uninitialized_push.h\"")
551 cog.outl(" template <typename TMessage>")
552 cog.out(" explicit message_packet(const TMessage& /*msg*/, typename etl::enable_if<!etl::is_same<typename etl::remove_cvref<TMessage>::type, etl::message_packet<")
553 for n in range(1, int(Handlers)):
554 cog.out("T%s, " % n)
555 cog.outl("T%s> >::value &&" % int(Handlers))
556 cog.outl(" !etl::is_same<typename etl::remove_cvref<TMessage>::type, etl::imessage>::value &&")
557 cog.out(" !etl::is_one_of<typename etl::remove_cvref<TMessage>::type, ")
558 for n in range(1, int(Handlers)):
559 cog.out("T%s, " % n)
560 cog.outl("T%s>::value, int>::type = 0)" % int(Handlers))
561 cog.outl(" : valid(true)")
562 cog.outl(" {")
563 generate_static_assert_cpp03(int(Handlers))
564 cog.outl(" }")
565 cog.outl("#include \"private/diagnostic_pop.h\"")
566 cog.outl("#endif")
567 cog.outl("")
568 cog.outl(" //**********************************************")
569 cog.outl("#include \"private/diagnostic_uninitialized_push.h\"")
570 cog.outl(" message_packet(const message_packet& other)")
571 cog.outl(" : valid(other.is_valid())")
572 cog.outl(" {")
573 cog.outl(" if (valid)")
574 cog.outl(" {")
575 cog.outl(" add_new_message(other.get());")
576 cog.outl(" }")
577 cog.outl(" }")
578 cog.outl("#include \"private/diagnostic_pop.h\"")
579 cog.outl("")
580 cog.outl("#if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION)")
581 cog.outl(" //**********************************************")
582 cog.outl("#include \"private/diagnostic_uninitialized_push.h\"")
583 cog.outl(" message_packet(message_packet&& other)")
584 cog.outl(" : valid(other.is_valid())")
585 cog.outl(" {")
586 cog.outl(" if (valid)")
587 cog.outl(" {")
588 cog.outl(" add_new_message(etl::move(other.get()));")
589 cog.outl(" }")
590 cog.outl(" }")
591 cog.outl("#include \"private/diagnostic_pop.h\"")
592 cog.outl("#endif")
593 cog.outl("")
594 cog.outl(" //**********************************************")
595 cog.outl("#include \"private/diagnostic_uninitialized_push.h\"")
596 cog.outl(" message_packet& operator =(const message_packet& rhs)")
597 cog.outl(" {")
598 cog.outl(" delete_current_message();")
599 cog.outl(" valid = rhs.is_valid();")
600 cog.outl(" if (valid)")
601 cog.outl(" {")
602 cog.outl(" add_new_message(rhs.get());")
603 cog.outl(" }")
604 cog.outl("")
605 cog.outl(" return *this;")
606 cog.outl(" }")
607 cog.outl("#include \"private/diagnostic_pop.h\"")
608 cog.outl("")
609 cog.outl("#if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION)")
610 cog.outl(" //**********************************************")
611 cog.outl("#include \"private/diagnostic_uninitialized_push.h\"")
612 cog.outl(" message_packet& operator =(message_packet&& rhs)")
613 cog.outl(" {")
614 cog.outl(" delete_current_message();")
615 cog.outl(" valid = rhs.is_valid();")
616 cog.outl(" if (valid)")
617 cog.outl(" {")
618 cog.outl(" add_new_message(etl::move(rhs.get()));")
619 cog.outl(" }")
620 cog.outl("")
621 cog.outl(" return *this;")
622 cog.outl(" }")
623 cog.outl("#include \"private/diagnostic_pop.h\"")
624 cog.outl("#endif")
625 cog.outl("")
626 cog.outl(" //********************************************")
627 cog.outl(" ~message_packet()")
628 cog.outl(" {")
629 cog.outl(" delete_current_message();")
630 cog.outl(" }")
631 cog.outl("")
632 cog.outl(" //********************************************")
633 cog.outl(" etl::imessage& get() ETL_NOEXCEPT")
634 cog.outl(" {")
635 cog.outl(" return *static_cast<etl::imessage*>(data);")
636 cog.outl(" }")
637 cog.outl("")
638 cog.outl(" //********************************************")
639 cog.outl(" const etl::imessage& get() const ETL_NOEXCEPT")
640 cog.outl(" {")
641 cog.outl(" return *static_cast<const etl::imessage*>(data);")
642 cog.outl(" }")
643 cog.outl("")
644 cog.outl(" //********************************************")
645 cog.outl(" bool is_valid() const")
646 cog.outl(" {")
647 cog.outl(" return valid;")
648 cog.outl(" }")
649 cog.outl("")
650 cog.outl(" //**********************************************")
651 cog.outl(" static ETL_CONSTEXPR bool accepts(etl::message_id_t id)")
652 cog.outl(" {")
653 generate_accepts_return(int(Handlers))
654 cog.outl(" }")
655 cog.outl("")
656 cog.outl(" //**********************************************")
657 cog.outl(" static ETL_CONSTEXPR bool accepts(const etl::imessage& msg)")
658 cog.outl(" {")
659 cog.outl(" return accepts(msg.get_message_id());")
660 cog.outl(" }")
661 cog.outl("")
662 cog.outl(" //**********************************************")
663 cog.outl(" template <etl::message_id_t Id>")
664 cog.outl(" static ETL_CONSTEXPR bool accepts()")
665 cog.outl(" {")
666 generate_accepts_return_compile_time(int(Handlers))
667 cog.outl(" }")
668 cog.outl("")
669 cog.outl(" //**********************************************")
670 cog.outl(" template <typename TMessage>")
671 cog.outl(" static ETL_CONSTEXPR")
672 cog.outl(" typename etl::enable_if<etl::is_base_of<etl::imessage, TMessage>::value, bool>::type")
673 cog.outl(" accepts()")
674 cog.outl(" {")
675 generate_accepts_return_compile_time_TMessage(int(Handlers))
676 cog.outl(" }")
677 cog.outl("")
678 cog.outl(" enum")
679 cog.outl(" {")
680 cog.out(" SIZE = etl::largest<")
681 for n in range(1, int(Handlers)):
682 cog.out("T%d, " % n)
683 cog.outl("T%s>::size," % int(Handlers))
684 cog.out(" ALIGNMENT = etl::largest<")
685 for n in range(1, int(Handlers)):
686 cog.out("T%d, " % n)
687 cog.outl("T%s>::alignment" % int(Handlers))
688 cog.outl(" };")
689 cog.outl("")
690 cog.outl("private:")
691 cog.outl("")
692 cog.outl(" //********************************************")
693 cog.outl(" #include \"private/diagnostic_uninitialized_push.h\"")
694 cog.outl(" void delete_current_message()")
695 cog.outl(" {")
696 cog.outl(" if (valid)")
697 cog.outl(" {")
698 cog.outl(" etl::imessage* pmsg = static_cast<etl::imessage*>(data);")
699 cog.outl("")
700 cog.outl("#if ETL_HAS_VIRTUAL_MESSAGES")
701 cog.outl(" pmsg->~imessage();")
702 cog.outl("#else")
703 cog.outl(" delete_message(pmsg);")
704 cog.outl("#endif")
705 cog.outl(" }")
706 cog.outl(" }")
707 cog.outl(" #include \"private/diagnostic_pop.h\"")
708 cog.outl("")
709 cog.outl(" //********************************************")
710 cog.outl(" void delete_message(etl::imessage* pmsg)")
711 cog.outl(" {")
712 cog.outl(" switch (pmsg->get_message_id())")
713 cog.outl(" {")
714 for n in range(1, int(Handlers) + 1):
715 cog.out(" case T%d::ID: static_cast<const T%d" %(n, n))
716 cog.outl("*>(pmsg)->~T%d(); break;" % n)
717 cog.outl(" default: ETL_ASSERT_FAIL(ETL_ERROR(unhandled_message_exception)); break;")
718 cog.outl(" }")
719 cog.outl(" }")
720 cog.outl("")
721 cog.outl(" //********************************************")
722 cog.outl(" void add_new_message(const etl::imessage& msg)")
723 cog.outl(" {")
724 cog.outl(" const size_t id = msg.get_message_id();")
725 cog.outl(" void* p = data;")
726 cog.outl("")
727 cog.outl(" switch (id)")
728 cog.outl(" {")
729 for n in range(1, int(Handlers) + 1):
730 cog.outl(" case T%d::ID: ::new (p) T%d(static_cast<const T%d&>(msg)); break;" %(n, n, n))
731 cog.outl(" default: ETL_ASSERT_FAIL(ETL_ERROR(unhandled_message_exception)); break;")
732 cog.outl(" }")
733 cog.outl(" }")
734 cog.outl("")
735 cog.outl("#if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION)")
736 cog.outl(" //********************************************")
737 cog.outl(" void add_new_message(etl::imessage&& msg)")
738 cog.outl(" {")
739 cog.outl(" const size_t id = msg.get_message_id();")
740 cog.outl(" void* p = data;")
741 cog.outl("")
742 cog.outl(" switch (id)")
743 cog.outl(" {")
744 for n in range(1, int(Handlers) + 1):
745 cog.outl(" case T%d::ID: ::new (p) T%d(static_cast<T%d&&>(msg)); break;" %(n, n, n))
746 cog.outl(" default: ETL_ASSERT_FAIL(ETL_ERROR(unhandled_message_exception)); break;")
747 cog.outl(" }")
748 cog.outl(" }")
749 cog.outl("#endif")
750 cog.outl("")
751 cog.outl(" typename etl::aligned_storage<SIZE, ALIGNMENT>::type data;")
752 cog.outl(" bool valid;")
753 cog.outl("};")
754
755 ####################################
756 # All of the other specialisations.
757 ####################################
758 for n in range(int(Handlers) - 1, 0, -1):
759 cog.outl("")
760 cog.outl("//***************************************************************************")
761 if n == 1:
762 cog.outl("// Specialisation for %d message type." % n)
763 else:
764 cog.outl("// Specialisation for %d message types." % n)
765 cog.outl("//***************************************************************************")
766 cog.out("template <")
767 for t in range(1, n):
768 cog.out("typename T%s, " % t)
769 if t % 4 == 0:
770 cog.outl("")
771 cog.out(" ")
772 cog.outl("typename T%s>" % n)
773 cog.out("class message_packet<")
774 for t in range(1, n + 1):
775 cog.out("T%d, " % t)
776 if t % 16 == 0:
777 cog.outl("")
778 cog.out(" ")
779 for t in range(n + 1, int(Handlers)):
780 cog.out("void, ")
781 if t % 16 == 0:
782 cog.outl("")
783 cog.out(" ")
784 cog.outl("void>")
785 cog.outl("{")
786 cog.outl("public:")
787 cog.outl("")
788 cog.outl(" //********************************************")
789 cog.outl("#include \"private/diagnostic_uninitialized_push.h\"")
790 cog.outl(" message_packet()")
791 cog.outl(" : valid(false)")
792 cog.outl(" {")
793 cog.outl(" }")
794 cog.outl("#include \"private/diagnostic_pop.h\"")
795 cog.outl("")
796 cog.outl(" //********************************************")
797 cog.outl("#include \"private/diagnostic_uninitialized_push.h\"")
798 cog.outl(" explicit message_packet(const etl::imessage& msg)")
799 cog.outl(" {")
800 cog.outl(" if (accepts(msg))")
801 cog.outl(" {")
802 cog.outl(" add_new_message(msg);")
803 cog.outl(" valid = true;")
804 cog.outl(" }")
805 cog.outl(" else")
806 cog.outl(" {")
807 cog.outl(" valid = false;")
808 cog.outl(" }")
809 cog.outl("")
810 cog.outl(" ETL_ASSERT(valid, ETL_ERROR(unhandled_message_exception));")
811 cog.outl(" }")
812 cog.outl("#include \"private/diagnostic_pop.h\"")
813 cog.outl("")
814 cog.outl("#if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION)")
815 cog.outl(" //********************************************")
816 cog.outl("#include \"private/diagnostic_uninitialized_push.h\"")
817 cog.outl(" explicit message_packet(etl::imessage&& msg)")
818 cog.outl(" {")
819 cog.outl(" if (accepts(msg))")
820 cog.outl(" {")
821 cog.outl(" add_new_message(etl::move(msg));")
822 cog.outl(" valid = true;")
823 cog.outl(" }")
824 cog.outl(" else")
825 cog.outl(" {")
826 cog.outl(" valid = false;")
827 cog.outl(" }")
828 cog.outl("")
829 cog.outl(" ETL_ASSERT(valid, ETL_ERROR(unhandled_message_exception));")
830 cog.outl(" }")
831 cog.outl("#include \"private/diagnostic_pop.h\"")
832 cog.outl("#endif")
833 cog.outl("")
834 cog.outl("#if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION) && !defined(ETL_COMPILER_GREEN_HILLS)")
835 cog.outl(" //********************************************")
836 cog.outl("#include \"private/diagnostic_uninitialized_push.h\"")
837 cog.out(" template <typename TMessage, typename = typename etl::enable_if<!etl::is_same<typename etl::remove_cvref<TMessage>::type, etl::message_packet<")
838 for t in range(1, n):
839 cog.out("T%s, " % t)
840 cog.outl("T%s> >::value &&" % n)
841 cog.outl(" !etl::is_same<typename etl::remove_cvref<TMessage>::type, etl::imessage>::value &&")
842 cog.out(" !etl::is_one_of<typename etl::remove_cvref<TMessage>::type, ")
843 for t in range(1, n):
844 cog.out("T%s, " % t)
845 cog.outl("T%s>::value, int>::type>" % n)
846 cog.outl(" explicit message_packet(TMessage&& /*msg*/)")
847 cog.outl(" : valid(true)")
848 cog.outl(" {")
849 generate_static_assert_cpp11(n)
850 cog.outl(" }")
851 cog.outl("#include \"private/diagnostic_pop.h\"")
852 cog.outl("#else")
853 cog.outl(" //********************************************")
854 cog.outl("#include \"private/diagnostic_uninitialized_push.h\"")
855 cog.outl(" template <typename TMessage>")
856 cog.out(" explicit message_packet(const TMessage& /*msg*/, typename etl::enable_if<!etl::is_same<typename etl::remove_cvref<TMessage>::type, etl::message_packet<")
857 for t in range(1, n):
858 cog.out("T%s, " % t)
859 cog.outl("T%s> >::value &&" % n)
860 cog.outl(" !etl::is_same<typename etl::remove_cvref<TMessage>::type, etl::imessage>::value &&")
861 cog.out(" !etl::is_one_of<typename etl::remove_cvref<TMessage>::type, ")
862 for t in range(1, n):
863 cog.out("T%s, " % t)
864 cog.outl("T%s>::value, int>::type = 0)" % n)
865 cog.outl(" : valid(true)")
866 cog.outl(" {")
867 generate_static_assert_cpp03(n)
868 cog.outl(" }")
869 cog.outl("#include \"private/diagnostic_pop.h\"")
870 cog.outl("#endif")
871 cog.outl("")
872 cog.outl(" //**********************************************")
873 cog.outl("#include \"private/diagnostic_uninitialized_push.h\"")
874 cog.outl(" message_packet(const message_packet& other)")
875 cog.outl(" : valid(other.is_valid())")
876 cog.outl(" {")
877 cog.outl(" if (valid)")
878 cog.outl(" {")
879 cog.outl(" add_new_message(other.get());")
880 cog.outl(" }")
881 cog.outl(" }")
882 cog.outl("#include \"private/diagnostic_pop.h\"")
883 cog.outl("")
884 cog.outl("#if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION)")
885 cog.outl(" //**********************************************")
886 cog.outl("#include \"private/diagnostic_uninitialized_push.h\"")
887 cog.outl(" message_packet(message_packet&& other)")
888 cog.outl(" : valid(other.is_valid())")
889 cog.outl(" {")
890 cog.outl(" if (valid)")
891 cog.outl(" {")
892 cog.outl(" add_new_message(etl::move(other.get()));")
893 cog.outl(" }")
894 cog.outl(" }")
895 cog.outl("#include \"private/diagnostic_pop.h\"")
896 cog.outl("#endif")
897 cog.outl("")
898 cog.outl(" //**********************************************")
899 cog.outl("#include \"private/diagnostic_uninitialized_push.h\"")
900 cog.outl(" message_packet& operator =(const message_packet& rhs)")
901 cog.outl(" {")
902 cog.outl(" delete_current_message();")
903 cog.outl(" valid = rhs.is_valid();")
904 cog.outl(" if (valid)")
905 cog.outl(" {")
906 cog.outl(" add_new_message(rhs.get());")
907 cog.outl(" }")
908 cog.outl("")
909 cog.outl(" return *this;")
910 cog.outl(" }")
911 cog.outl("#include \"private/diagnostic_pop.h\"")
912 cog.outl("")
913 cog.outl("#if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION)")
914 cog.outl(" //**********************************************")
915 cog.outl("#include \"private/diagnostic_uninitialized_push.h\"")
916 cog.outl(" message_packet& operator =(message_packet&& rhs)")
917 cog.outl(" {")
918 cog.outl(" delete_current_message();")
919 cog.outl(" valid = rhs.is_valid();")
920 cog.outl(" if (valid)")
921 cog.outl(" {")
922 cog.outl(" add_new_message(etl::move(rhs.get()));")
923 cog.outl(" }")
924 cog.outl("")
925 cog.outl(" return *this;")
926 cog.outl(" }")
927 cog.outl("#include \"private/diagnostic_pop.h\"")
928 cog.outl("#endif")
929 cog.outl("")
930 cog.outl(" //********************************************")
931 cog.outl(" ~message_packet()")
932 cog.outl(" {")
933 cog.outl(" delete_current_message();")
934 cog.outl(" }")
935 cog.outl("")
936 cog.outl(" //********************************************")
937 cog.outl(" etl::imessage& get() ETL_NOEXCEPT")
938 cog.outl(" {")
939 cog.outl(" return *static_cast<etl::imessage*>(data);")
940 cog.outl(" }")
941 cog.outl("")
942 cog.outl(" //********************************************")
943 cog.outl(" const etl::imessage& get() const ETL_NOEXCEPT")
944 cog.outl(" {")
945 cog.outl(" return *static_cast<const etl::imessage*>(data);")
946 cog.outl(" }")
947 cog.outl("")
948 cog.outl(" //********************************************")
949 cog.outl(" bool is_valid() const")
950 cog.outl(" {")
951 cog.outl(" return valid;")
952 cog.outl(" }")
953 cog.outl("")
954 cog.outl(" //**********************************************")
955 cog.outl(" static ETL_CONSTEXPR bool accepts(etl::message_id_t id)")
956 cog.outl(" {")
957 generate_accepts_return(n)
958 cog.outl(" }")
959 cog.outl("")
960 cog.outl(" //**********************************************")
961 cog.outl(" static ETL_CONSTEXPR bool accepts(const etl::imessage& msg)")
962 cog.outl(" {")
963 cog.outl(" return accepts(msg.get_message_id());")
964 cog.outl(" }")
965 cog.outl("")
966 cog.outl(" //**********************************************")
967 cog.outl(" template <etl::message_id_t Id>")
968 cog.outl(" static ETL_CONSTEXPR bool accepts()")
969 cog.outl(" {")
970 generate_accepts_return_compile_time(n)
971 cog.outl(" }")
972 cog.outl("")
973 cog.outl(" //**********************************************")
974 cog.outl(" template <typename TMessage>")
975 cog.outl(" static ETL_CONSTEXPR")
976 cog.outl(" typename etl::enable_if<etl::is_base_of<etl::imessage, TMessage>::value, bool>::type")
977 cog.outl(" accepts()")
978 cog.outl(" {")
979 generate_accepts_return_compile_time_TMessage(n)
980 cog.outl(" }")
981 cog.outl("")
982 cog.outl(" enum")
983 cog.outl(" {")
984 cog.out(" SIZE = etl::largest<")
985 for t in range(1, n):
986 cog.out("T%d, " % t)
987 cog.outl("T%s>::size," % n)
988 cog.out(" ALIGNMENT = etl::largest<")
989 for t in range(1, n):
990 cog.out("T%d, " % t)
991 cog.outl("T%s>::alignment" % n)
992 cog.outl(" };")
993 cog.outl("")
994 cog.outl("private:")
995 cog.outl("")
996 cog.outl(" //********************************************")
997 cog.outl(" #include \"private/diagnostic_uninitialized_push.h\"")
998 cog.outl(" void delete_current_message()")
999 cog.outl(" {")
1000 cog.outl(" if (valid)")
1001 cog.outl(" {")
1002 cog.outl(" etl::imessage* pmsg = static_cast<etl::imessage*>(data);")
1003 cog.outl("")
1004 cog.outl("")
1005 cog.outl("#if ETL_HAS_VIRTUAL_MESSAGES")
1006 cog.outl(" pmsg->~imessage();")
1007 cog.outl("#else")
1008 cog.outl(" delete_message(pmsg);")
1009 cog.outl("#endif")
1010 cog.outl(" }")
1011 cog.outl(" }")
1012 cog.outl(" #include \"private/diagnostic_pop.h\"")
1013 cog.outl("")
1014 cog.outl(" //********************************************")
1015 cog.outl(" void delete_message(etl::imessage* pmsg)")
1016 cog.outl(" {")
1017 cog.outl(" switch (pmsg->get_message_id())")
1018 cog.outl(" {")
1019 for t in range(1, n + 1):
1020 cog.out(" case T%d::ID: static_cast<const T%d" %(t, t))
1021 cog.outl("*>(pmsg)->~T%d(); break;" % t)
1022 cog.outl(" default: ETL_ASSERT_FAIL(ETL_ERROR(unhandled_message_exception)); break;")
1023 cog.outl(" }")
1024 cog.outl(" }")
1025 cog.outl("")
1026 cog.outl(" //********************************************")
1027 cog.outl(" void add_new_message(const etl::imessage& msg)")
1028 cog.outl(" {")
1029 cog.outl(" const size_t id = msg.get_message_id();")
1030 cog.outl(" void* p = data;")
1031 cog.outl("")
1032 cog.outl(" switch (id)")
1033 cog.outl(" {")
1034 for t in range(1, n + 1):
1035 cog.outl(" case T%d::ID: ::new (p) T%d(static_cast<const T%d&>(msg)); break;" %(t, t, t))
1036 cog.outl(" default: ETL_ASSERT_FAIL(ETL_ERROR(unhandled_message_exception)); break;")
1037 cog.outl(" }")
1038 cog.outl(" }")
1039 cog.outl("")
1040 cog.outl("#if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION)")
1041 cog.outl(" //********************************************")
1042 cog.outl(" void add_new_message(etl::imessage&& msg)")
1043 cog.outl(" {")
1044 cog.outl(" const size_t id = msg.get_message_id();")
1045 cog.outl(" void* p = data;")
1046 cog.outl("")
1047 cog.outl(" switch (id)")
1048 cog.outl(" {")
1049 for t in range(1, n + 1):
1050 cog.outl(" case T%d::ID: ::new (p) T%d(static_cast<T%d&&>(msg)); break;" %(t, t, t))
1051 cog.outl(" default: break;")
1052 cog.outl(" }")
1053 cog.outl(" }")
1054 cog.outl("#endif")
1055 cog.outl("")
1056 cog.outl(" typename etl::aligned_storage<SIZE, ALIGNMENT>::type data;")
1057 cog.outl(" bool valid;")
1058 cog.outl("};")
1059 ]]]*/
1060 /*[[[end]]]*/
1061#endif
1062}
1063
1064#endif
Definition message.h:73
Definition message_packet.h:393
#define ETL_ASSERT(b, e)
Definition error_handler.h:356
Definition largest.h:367
bitset_ext
Definition absolute.h:38
ETL_CONSTEXPR TContainer::size_type size(const TContainer &container)
Definition iterator.h:1187
Definition alignment.h:233
pair holds two objects of arbitrary type
Definition utility.h:164