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#if ETL_HAS_VIRTUAL_MESSAGES
69
70#include "message.h"
71#include "error_handler.h"
72#include "static_assert.h"
73#include "largest.h"
74#include "alignment.h"
75#include "utility.h"
76
77#include <stdint.h>
78
79namespace etl
80{
81#if ETL_USING_CPP17 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION)
82 //***************************************************************************
83 // The definition for all message types.
84 //***************************************************************************
85 template <typename... TMessageTypes>
86 class message_packet
87 {
88
89 private:
90
91 template <typename T>
92 static constexpr bool IsMessagePacket = etl::is_same_v< etl::remove_const_t<etl::remove_reference_t<T>>, etl::message_packet<TMessageTypes...>>;
93
94 template <typename T>
95 static constexpr bool IsInMessageList = etl::is_one_of_v<etl::remove_const_t<etl::remove_reference_t<T>>, TMessageTypes...>;
96
97 template <typename T>
99
100 public:
101
102 //********************************************
104 message_packet()
105 : valid(false)
106 {
107 }
109
110 //********************************************
112 //********************************************
114 template <typename T, typename = typename etl::enable_if<IsIMessage<T> || IsInMessageList<T>, int>::type>
115 explicit message_packet(T&& msg)
116 : valid(true)
117 {
118 if constexpr (IsIMessage<T>)
119 {
120 if (accepts(msg))
121 {
122 add_new_message(etl::forward<T>(msg));
123 valid = true;
124 }
125 else
126 {
127 valid = false;
128 }
129
130 ETL_ASSERT(valid, ETL_ERROR(unhandled_message_exception));
131 }
132 else if constexpr (IsInMessageList<T>)
133 {
134 add_new_message_type<T>(etl::forward<T>(msg));
135 }
136 else
137 {
138 ETL_STATIC_ASSERT(IsInMessageList<T>, "Message not in packet type list");
139 }
140 }
142
143 //**********************************************
144 message_packet(const message_packet& other)
145 {
146 valid = other.is_valid();
147
148 if (valid)
149 {
150 add_new_message(other.get());
151 }
152 }
153
154#if ETL_USING_CPP11
155 //**********************************************
156 message_packet(message_packet&& other)
157 {
158 valid = other.is_valid();
159
160 if (valid)
161 {
162 add_new_message(etl::move(other.get()));
163 }
164 }
165#endif
166
167 //**********************************************
168 void copy(const message_packet& other)
169 {
170 valid = other.is_valid();
171
172 if (valid)
173 {
174 add_new_message(other.get());
175 }
176 }
177
178 //**********************************************
179 void copy(message_packet&& other)
180 {
181 valid = other.is_valid();
182
183 if (valid)
184 {
185 add_new_message(etl::move(other.get()));
186 }
187 }
188
189 //**********************************************
191 message_packet& operator =(const message_packet& rhs)
192 {
193 delete_current_message();
194 valid = rhs.is_valid();
195 if (valid)
196 {
197 add_new_message(rhs.get());
198 }
199
200 return *this;
201 }
203
204 //**********************************************
206 message_packet& operator =(message_packet&& rhs)
207 {
208 delete_current_message();
209 valid = rhs.is_valid();
210 if (valid)
211 {
212 add_new_message(etl::move(rhs.get()));
213 }
214
215 return *this;
216 }
218
219 //********************************************
220 ~message_packet()
221 {
222 delete_current_message();
223 }
224
225 //********************************************
226 etl::imessage& get() ETL_NOEXCEPT
227 {
228 return *static_cast<etl::imessage*>(data);
229 }
230
231 //********************************************
232 const etl::imessage& get() const ETL_NOEXCEPT
233 {
234 return *static_cast<const etl::imessage*>(data);
235 }
236
237 //********************************************
238 bool is_valid() const
239 {
240 return valid;
241 }
242
243 //**********************************************
244 static ETL_CONSTEXPR bool accepts(etl::message_id_t id)
245 {
246 return (accepts_message<TMessageTypes::ID>(id) || ...);
247 }
248
249 //**********************************************
250 static ETL_CONSTEXPR bool accepts(const etl::imessage& msg)
251 {
252 return accepts(msg.get_message_id());
253 }
254
255 //**********************************************
256 template <etl::message_id_t Id>
257 static ETL_CONSTEXPR bool accepts()
258 {
259 return (accepts_message<TMessageTypes::ID, Id>() || ...);
260 }
261
262 //**********************************************
263 template <typename TMessage>
264 static ETL_CONSTEXPR
266 accepts()
267 {
268 return accepts<TMessage::ID>();
269 }
270
271 enum
272 {
273 SIZE = etl::largest<TMessageTypes...>::size,
274 ALIGNMENT = etl::largest<TMessageTypes...>::alignment
275 };
276
277 private:
278
279 //**********************************************
280 template <etl::message_id_t Id1, etl::message_id_t Id2>
281 static bool accepts_message()
282 {
283 return Id1 == Id2;
284 }
285
286 //**********************************************
287 template <etl::message_id_t Id1>
288 static bool accepts_message(etl::message_id_t id2)
289 {
290 return Id1 == id2;
291 }
292
293 //********************************************
295 void delete_current_message()
296 {
297 if (valid)
298 {
299 etl::imessage* pmsg = static_cast<etl::imessage*>(data);
300
301 pmsg->~imessage();
302 }
303 }
305
306 //********************************************
307 void add_new_message(const etl::imessage& msg)
308 {
309 (add_new_message_type<TMessageTypes>(msg) || ...);
310 }
311
312 //********************************************
313 void add_new_message(etl::imessage&& msg)
314 {
315 (add_new_message_type<TMessageTypes>(etl::move(msg)) || ...);
316 }
317
319 //********************************************
321 //********************************************
322 template <typename TMessage>
324 add_new_message_type(TMessage&& msg)
325 {
326 void* p = data;
328 }
330
332 //********************************************
333 template <typename TType>
334 bool add_new_message_type(const etl::imessage& msg)
335 {
336 if (TType::ID == msg.get_message_id())
337 {
338 void* p = data;
339 new (p) TType(static_cast<const TType&>(msg));
340 return true;
341 }
342 else
343 {
344 return false;
345 }
346 }
348
349 //********************************************
350 template <typename TType>
351 bool add_new_message_type(etl::imessage&& msg)
352 {
353 if (TType::ID == msg.get_message_id())
354 {
355 void* p = data;
356 new (p) TType(static_cast<TType&&>(msg));
357 return true;
358 }
359 else
360 {
361 return false;
362 }
363 }
364
366 bool valid;
367 };
368
369#else
370
371 /*[[[cog
372 import cog
373
374 ################################################
375 def generate_accepts_return(n):
376 cog.out(" return")
377 for i in range(1, n + 1):
378 cog.out(" T%d::ID == id" % i)
379 if i < n:
380 cog.out(" ||")
381 if i % 4 == 0:
382 cog.outl("")
383 cog.out(" ")
384 cog.outl(";")
385
386 ################################################
387 def generate_accepts_return_compile_time(n):
388 cog.out(" return")
389 for i in range(1, n + 1):
390 cog.out(" T%d::ID == Id" % i)
391 if i < n:
392 cog.out(" ||")
393 if i % 4 == 0:
394 cog.outl("")
395 cog.out(" ")
396 cog.outl(";")
397
398 ################################################
399 def generate_accepts_return_compile_time_TMessage(n):
400 cog.out(" return")
401 for i in range(1, n + 1):
402 cog.out(" T%d::ID == TMessage::ID" % i)
403 if i < n:
404 cog.out(" ||")
405 if i % 4 == 0:
406 cog.outl("")
407 cog.out(" ")
408 cog.outl(";")
409
410 ################################################
411 def generate_static_assert_cpp03(n):
412 cog.outl(" // Not etl::message_packet, not etl::imessage and in typelist.")
413 cog.out(" static const bool Enabled = (!etl::is_same<typename etl::remove_cvref<TMessage>::type, etl::message_packet<")
414 for i in range(1, n):
415 cog.out("T%d, " % i)
416 cog.outl("T%s> >::value &&" % n)
417 cog.outl(" !etl::is_same<typename etl::remove_cvref<TMessage>::type, etl::imessage>::value &&")
418 cog.out(" etl::is_one_of<typename etl::remove_cvref<TMessage>::type,")
419 for i in range(1, n):
420 cog.out("T%d, " % i)
421 cog.outl("T%s>::value);" % n)
422 cog.outl("")
423 cog.outl(" ETL_STATIC_ASSERT(Enabled, \"Message not in packet type list\");")
424
425 ################################################
426 def generate_static_assert_cpp11(n):
427 cog.outl(" // Not etl::message_packet, not etl::imessage and in typelist.")
428 cog.out(" static constexpr bool Enabled = (!etl::is_same<typename etl::remove_cvref<TMessage>::type, etl::message_packet<")
429 for i in range(1, n):
430 cog.out("T%d, " % i)
431 cog.outl("T%s> >::value &&" % n)
432 cog.outl(" !etl::is_same<typename etl::remove_cvref<TMessage>::type, etl::imessage>::value &&")
433 cog.out(" etl::is_one_of<typename etl::remove_cvref<TMessage>::type,")
434 for i in range(1, n):
435 cog.out("T%d, " % i)
436 cog.outl("T%s>::value);" % n)
437 cog.outl("")
438 cog.outl(" ETL_STATIC_ASSERT(Enabled, \"Message not in packet type list\");")
439
440 ################################################
441 # The first definition for all of the messages.
442 ################################################
443 cog.outl("//***************************************************************************")
444 cog.outl("// The definition for all %s message types." % Handlers)
445 cog.outl("//***************************************************************************")
446 cog.out("template <")
447 cog.out("typename T1, ")
448 for n in range(2, int(Handlers)):
449 cog.out("typename T%s = void, " % n)
450 if n % 4 == 0:
451 cog.outl("")
452 cog.out(" ")
453 cog.outl("typename T%s = void>" % int(Handlers))
454 cog.outl("class message_packet")
455 cog.outl("{")
456 cog.outl("public:")
457 cog.outl("")
458 cog.outl(" //********************************************")
459 cog.outl("#include \"private/diagnostic_uninitialized_push.h\"")
460 cog.outl(" message_packet()")
461 cog.outl(" : valid(false)")
462 cog.outl(" {")
463 cog.outl(" }")
464 cog.outl("#include \"private/diagnostic_pop.h\"")
465 cog.outl("")
466 cog.outl(" //********************************************")
467 cog.outl("#include \"private/diagnostic_uninitialized_push.h\"")
468 cog.outl(" explicit message_packet(const etl::imessage& msg)")
469 cog.outl(" {")
470 cog.outl(" if (accepts(msg))")
471 cog.outl(" {")
472 cog.outl(" add_new_message(msg);")
473 cog.outl(" valid = true;")
474 cog.outl(" }")
475 cog.outl(" else")
476 cog.outl(" {")
477 cog.outl(" valid = false;")
478 cog.outl(" }")
479 cog.outl("")
480 cog.outl(" ETL_ASSERT(valid, ETL_ERROR(unhandled_message_exception));")
481 cog.outl(" }")
482 cog.outl("#include \"private/diagnostic_pop.h\"")
483 cog.outl("")
484 cog.outl("#if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION)")
485 cog.outl(" //********************************************")
486 cog.outl("#include \"private/diagnostic_uninitialized_push.h\"")
487 cog.outl(" explicit message_packet(etl::imessage&& msg)")
488 cog.outl(" {")
489 cog.outl(" if (accepts(msg))")
490 cog.outl(" {")
491 cog.outl(" add_new_message(etl::move(msg));")
492 cog.outl(" valid = true;")
493 cog.outl(" }")
494 cog.outl(" else")
495 cog.outl(" {")
496 cog.outl(" valid = false;")
497 cog.outl(" }")
498 cog.outl("")
499 cog.outl(" ETL_ASSERT(valid, ETL_ERROR(unhandled_message_exception));")
500 cog.outl(" }")
501 cog.outl("#include \"private/diagnostic_pop.h\"")
502 cog.outl("#endif")
503 cog.outl("")
504 cog.outl("#if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION) && !defined(ETL_COMPILER_GREEN_HILLS)")
505 cog.outl(" //********************************************")
506 cog.outl("#include \"private/diagnostic_uninitialized_push.h\"")
507 cog.out(" template <typename TMessage, typename = typename etl::enable_if<!etl::is_same<typename etl::remove_cvref<TMessage>::type, etl::message_packet<")
508 for n in range(1, int(Handlers)):
509 cog.out("T%s, " % n)
510 cog.outl("T%s> >::value &&" % int(Handlers))
511 cog.outl(" !etl::is_same<typename etl::remove_cvref<TMessage>::type, etl::imessage>::value &&")
512 cog.out(" !etl::is_one_of<typename etl::remove_cvref<TMessage>::type, ")
513 for n in range(1, int(Handlers)):
514 cog.out("T%s, " % n)
515 cog.outl("T%s>::value, int>::type>" % int(Handlers))
516 cog.outl(" explicit message_packet(TMessage&& /*msg*/)")
517 cog.outl(" : valid(true)")
518 cog.outl(" {")
519 generate_static_assert_cpp11(int(Handlers))
520 cog.outl(" }")
521 cog.outl("#include \"private/diagnostic_pop.h\"")
522 cog.outl("#else")
523 cog.outl(" //********************************************")
524 cog.outl("#include \"private/diagnostic_uninitialized_push.h\"")
525 cog.outl(" template <typename TMessage>")
526 cog.out(" explicit message_packet(const TMessage& /*msg*/, typename etl::enable_if<!etl::is_same<typename etl::remove_cvref<TMessage>::type, etl::message_packet<")
527 for n in range(1, int(Handlers)):
528 cog.out("T%s, " % n)
529 cog.outl("T%s> >::value &&" % int(Handlers))
530 cog.outl(" !etl::is_same<typename etl::remove_cvref<TMessage>::type, etl::imessage>::value &&")
531 cog.out(" !etl::is_one_of<typename etl::remove_cvref<TMessage>::type, ")
532 for n in range(1, int(Handlers)):
533 cog.out("T%s, " % n)
534 cog.outl("T%s>::value, int>::type = 0)" % int(Handlers))
535 cog.outl(" : valid(true)")
536 cog.outl(" {")
537 generate_static_assert_cpp03(int(Handlers))
538 cog.outl(" }")
539 cog.outl("#include \"private/diagnostic_pop.h\"")
540 cog.outl("#endif")
541 cog.outl("")
542 cog.outl(" //**********************************************")
543 cog.outl("#include \"private/diagnostic_uninitialized_push.h\"")
544 cog.outl(" message_packet(const message_packet& other)")
545 cog.outl(" : valid(other.is_valid())")
546 cog.outl(" {")
547 cog.outl(" if (valid)")
548 cog.outl(" {")
549 cog.outl(" add_new_message(other.get());")
550 cog.outl(" }")
551 cog.outl(" }")
552 cog.outl("#include \"private/diagnostic_pop.h\"")
553 cog.outl("")
554 cog.outl("#if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION)")
555 cog.outl(" //**********************************************")
556 cog.outl("#include \"private/diagnostic_uninitialized_push.h\"")
557 cog.outl(" message_packet(message_packet&& other)")
558 cog.outl(" : valid(other.is_valid())")
559 cog.outl(" {")
560 cog.outl(" if (valid)")
561 cog.outl(" {")
562 cog.outl(" add_new_message(etl::move(other.get()));")
563 cog.outl(" }")
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& operator =(const message_packet& rhs)")
571 cog.outl(" {")
572 cog.outl(" delete_current_message();")
573 cog.outl(" valid = rhs.is_valid();")
574 cog.outl(" if (valid)")
575 cog.outl(" {")
576 cog.outl(" add_new_message(rhs.get());")
577 cog.outl(" }")
578 cog.outl("")
579 cog.outl(" return *this;")
580 cog.outl(" }")
581 cog.outl("#include \"private/diagnostic_pop.h\"")
582 cog.outl("")
583 cog.outl("#if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION)")
584 cog.outl(" //**********************************************")
585 cog.outl("#include \"private/diagnostic_uninitialized_push.h\"")
586 cog.outl(" message_packet& operator =(message_packet&& rhs)")
587 cog.outl(" {")
588 cog.outl(" delete_current_message();")
589 cog.outl(" valid = rhs.is_valid();")
590 cog.outl(" if (valid)")
591 cog.outl(" {")
592 cog.outl(" add_new_message(etl::move(rhs.get()));")
593 cog.outl(" }")
594 cog.outl("")
595 cog.outl(" return *this;")
596 cog.outl(" }")
597 cog.outl("#include \"private/diagnostic_pop.h\"")
598 cog.outl("#endif")
599 cog.outl("")
600 cog.outl(" //********************************************")
601 cog.outl(" ~message_packet()")
602 cog.outl(" {")
603 cog.outl(" delete_current_message();")
604 cog.outl(" }")
605 cog.outl("")
606 cog.outl(" //********************************************")
607 cog.outl(" etl::imessage& get() ETL_NOEXCEPT")
608 cog.outl(" {")
609 cog.outl(" return *static_cast<etl::imessage*>(data);")
610 cog.outl(" }")
611 cog.outl("")
612 cog.outl(" //********************************************")
613 cog.outl(" const etl::imessage& get() const ETL_NOEXCEPT")
614 cog.outl(" {")
615 cog.outl(" return *static_cast<const etl::imessage*>(data);")
616 cog.outl(" }")
617 cog.outl("")
618 cog.outl(" //********************************************")
619 cog.outl(" bool is_valid() const")
620 cog.outl(" {")
621 cog.outl(" return valid;")
622 cog.outl(" }")
623 cog.outl("")
624 cog.outl(" //**********************************************")
625 cog.outl(" static ETL_CONSTEXPR bool accepts(etl::message_id_t id)")
626 cog.outl(" {")
627 generate_accepts_return(int(Handlers))
628 cog.outl(" }")
629 cog.outl("")
630 cog.outl(" //**********************************************")
631 cog.outl(" static ETL_CONSTEXPR bool accepts(const etl::imessage& msg)")
632 cog.outl(" {")
633 cog.outl(" return accepts(msg.get_message_id());")
634 cog.outl(" }")
635 cog.outl("")
636 cog.outl(" //**********************************************")
637 cog.outl(" template <etl::message_id_t Id>")
638 cog.outl(" static ETL_CONSTEXPR bool accepts()")
639 cog.outl(" {")
640 generate_accepts_return_compile_time(int(Handlers))
641 cog.outl(" }")
642 cog.outl("")
643 cog.outl(" //**********************************************")
644 cog.outl(" template <typename TMessage>")
645 cog.outl(" static ETL_CONSTEXPR")
646 cog.outl(" typename etl::enable_if<etl::is_base_of<etl::imessage, TMessage>::value, bool>::type")
647 cog.outl(" accepts()")
648 cog.outl(" {")
649 generate_accepts_return_compile_time_TMessage(int(Handlers))
650 cog.outl(" }")
651 cog.outl("")
652 cog.outl(" enum")
653 cog.outl(" {")
654 cog.out(" SIZE = etl::largest<")
655 for n in range(1, int(Handlers)):
656 cog.out("T%d, " % n)
657 cog.outl("T%s>::size," % int(Handlers))
658 cog.out(" ALIGNMENT = etl::largest<")
659 for n in range(1, int(Handlers)):
660 cog.out("T%d, " % n)
661 cog.outl("T%s>::alignment" % int(Handlers))
662 cog.outl(" };")
663 cog.outl("")
664 cog.outl("private:")
665 cog.outl("")
666 cog.outl(" //********************************************")
667 cog.outl(" #include \"private/diagnostic_uninitialized_push.h\"")
668 cog.outl(" void delete_current_message()")
669 cog.outl(" {")
670 cog.outl(" if (valid)")
671 cog.outl(" {")
672 cog.outl(" etl::imessage* pmsg = static_cast<etl::imessage*>(data);")
673 cog.outl("")
674 cog.outl(" pmsg->~imessage();")
675 cog.outl(" }")
676 cog.outl(" }")
677 cog.outl(" #include \"private/diagnostic_pop.h\"")
678 cog.outl("")
679 cog.outl(" //********************************************")
680 cog.outl(" void add_new_message(const etl::imessage& msg)")
681 cog.outl(" {")
682 cog.outl(" const size_t id = msg.get_message_id();")
683 cog.outl(" void* p = data;")
684 cog.outl("")
685 cog.outl(" switch (id)")
686 cog.outl(" {")
687 for n in range(1, int(Handlers) + 1):
688 cog.outl(" case T%d::ID: ::new (p) T%d(static_cast<const T%d&>(msg)); break;" %(n, n, n))
689 cog.outl(" default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break;")
690 cog.outl(" }")
691 cog.outl(" }")
692 cog.outl("")
693 cog.outl("#if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION)")
694 cog.outl(" //********************************************")
695 cog.outl(" void add_new_message(etl::imessage&& msg)")
696 cog.outl(" {")
697 cog.outl(" const size_t id = msg.get_message_id();")
698 cog.outl(" void* p = data;")
699 cog.outl("")
700 cog.outl(" switch (id)")
701 cog.outl(" {")
702 for n in range(1, int(Handlers) + 1):
703 cog.outl(" case T%d::ID: ::new (p) T%d(static_cast<T%d&&>(msg)); break;" %(n, n, n))
704 cog.outl(" default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break;")
705 cog.outl(" }")
706 cog.outl(" }")
707 cog.outl("#endif")
708 cog.outl("")
709 cog.outl(" typename etl::aligned_storage<SIZE, ALIGNMENT>::type data;")
710 cog.outl(" bool valid;")
711 cog.outl("};")
712
713 ####################################
714 # All of the other specialisations.
715 ####################################
716 for n in range(int(Handlers) - 1, 0, -1):
717 cog.outl("")
718 cog.outl("//***************************************************************************")
719 if n == 1:
720 cog.outl("// Specialisation for %d message type." % n)
721 else:
722 cog.outl("// Specialisation for %d message types." % n)
723 cog.outl("//***************************************************************************")
724 cog.out("template <")
725 for t in range(1, n):
726 cog.out("typename T%s, " % t)
727 if t % 4 == 0:
728 cog.outl("")
729 cog.out(" ")
730 cog.outl("typename T%s>" % n)
731 cog.out("class message_packet<")
732 for t in range(1, n + 1):
733 cog.out("T%d, " % t)
734 if t % 16 == 0:
735 cog.outl("")
736 cog.out(" ")
737 for t in range(n + 1, int(Handlers)):
738 cog.out("void, ")
739 if t % 16 == 0:
740 cog.outl("")
741 cog.out(" ")
742 cog.outl("void>")
743 cog.outl("{")
744 cog.outl("public:")
745 cog.outl("")
746 cog.outl(" //********************************************")
747 cog.outl("#include \"private/diagnostic_uninitialized_push.h\"")
748 cog.outl(" message_packet()")
749 cog.outl(" : valid(false)")
750 cog.outl(" {")
751 cog.outl(" }")
752 cog.outl("#include \"private/diagnostic_pop.h\"")
753 cog.outl("")
754 cog.outl(" //********************************************")
755 cog.outl("#include \"private/diagnostic_uninitialized_push.h\"")
756 cog.outl(" explicit message_packet(const etl::imessage& msg)")
757 cog.outl(" {")
758 cog.outl(" if (accepts(msg))")
759 cog.outl(" {")
760 cog.outl(" add_new_message(msg);")
761 cog.outl(" valid = true;")
762 cog.outl(" }")
763 cog.outl(" else")
764 cog.outl(" {")
765 cog.outl(" valid = false;")
766 cog.outl(" }")
767 cog.outl("")
768 cog.outl(" ETL_ASSERT(valid, ETL_ERROR(unhandled_message_exception));")
769 cog.outl(" }")
770 cog.outl("#include \"private/diagnostic_pop.h\"")
771 cog.outl("")
772 cog.outl("#if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION)")
773 cog.outl(" //********************************************")
774 cog.outl("#include \"private/diagnostic_uninitialized_push.h\"")
775 cog.outl(" explicit message_packet(etl::imessage&& msg)")
776 cog.outl(" {")
777 cog.outl(" if (accepts(msg))")
778 cog.outl(" {")
779 cog.outl(" add_new_message(etl::move(msg));")
780 cog.outl(" valid = true;")
781 cog.outl(" }")
782 cog.outl(" else")
783 cog.outl(" {")
784 cog.outl(" valid = false;")
785 cog.outl(" }")
786 cog.outl("")
787 cog.outl(" ETL_ASSERT(valid, ETL_ERROR(unhandled_message_exception));")
788 cog.outl(" }")
789 cog.outl("#include \"private/diagnostic_pop.h\"")
790 cog.outl("#endif")
791 cog.outl("")
792 cog.outl("#if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION) && !defined(ETL_COMPILER_GREEN_HILLS)")
793 cog.outl(" //********************************************")
794 cog.outl("#include \"private/diagnostic_uninitialized_push.h\"")
795 cog.out(" template <typename TMessage, typename = typename etl::enable_if<!etl::is_same<typename etl::remove_cvref<TMessage>::type, etl::message_packet<")
796 for t in range(1, n):
797 cog.out("T%s, " % t)
798 cog.outl("T%s> >::value &&" % n)
799 cog.outl(" !etl::is_same<typename etl::remove_cvref<TMessage>::type, etl::imessage>::value &&")
800 cog.out(" !etl::is_one_of<typename etl::remove_cvref<TMessage>::type, ")
801 for t in range(1, n):
802 cog.out("T%s, " % t)
803 cog.outl("T%s>::value, int>::type>" % n)
804 cog.outl(" explicit message_packet(TMessage&& /*msg*/)")
805 cog.outl(" : valid(true)")
806 cog.outl(" {")
807 generate_static_assert_cpp11(n)
808 cog.outl(" }")
809 cog.outl("#include \"private/diagnostic_pop.h\"")
810 cog.outl("#else")
811 cog.outl(" //********************************************")
812 cog.outl("#include \"private/diagnostic_uninitialized_push.h\"")
813 cog.outl(" template <typename TMessage>")
814 cog.out(" explicit message_packet(const TMessage& /*msg*/, typename etl::enable_if<!etl::is_same<typename etl::remove_cvref<TMessage>::type, etl::message_packet<")
815 for t in range(1, n):
816 cog.out("T%s, " % t)
817 cog.outl("T%s> >::value &&" % n)
818 cog.outl(" !etl::is_same<typename etl::remove_cvref<TMessage>::type, etl::imessage>::value &&")
819 cog.out(" !etl::is_one_of<typename etl::remove_cvref<TMessage>::type, ")
820 for t in range(1, n):
821 cog.out("T%s, " % t)
822 cog.outl("T%s>::value, int>::type = 0)" % n)
823 cog.outl(" : valid(true)")
824 cog.outl(" {")
825 generate_static_assert_cpp03(n)
826 cog.outl(" }")
827 cog.outl("#include \"private/diagnostic_pop.h\"")
828 cog.outl("#endif")
829 cog.outl("")
830 cog.outl(" //**********************************************")
831 cog.outl("#include \"private/diagnostic_uninitialized_push.h\"")
832 cog.outl(" message_packet(const message_packet& other)")
833 cog.outl(" : valid(other.is_valid())")
834 cog.outl(" {")
835 cog.outl(" if (valid)")
836 cog.outl(" {")
837 cog.outl(" add_new_message(other.get());")
838 cog.outl(" }")
839 cog.outl(" }")
840 cog.outl("#include \"private/diagnostic_pop.h\"")
841 cog.outl("")
842 cog.outl("#if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION)")
843 cog.outl(" //**********************************************")
844 cog.outl("#include \"private/diagnostic_uninitialized_push.h\"")
845 cog.outl(" message_packet(message_packet&& other)")
846 cog.outl(" : valid(other.is_valid())")
847 cog.outl(" {")
848 cog.outl(" if (valid)")
849 cog.outl(" {")
850 cog.outl(" add_new_message(etl::move(other.get()));")
851 cog.outl(" }")
852 cog.outl(" }")
853 cog.outl("#include \"private/diagnostic_pop.h\"")
854 cog.outl("#endif")
855 cog.outl("")
856 cog.outl(" //**********************************************")
857 cog.outl("#include \"private/diagnostic_uninitialized_push.h\"")
858 cog.outl(" message_packet& operator =(const message_packet& rhs)")
859 cog.outl(" {")
860 cog.outl(" delete_current_message();")
861 cog.outl(" valid = rhs.is_valid();")
862 cog.outl(" if (valid)")
863 cog.outl(" {")
864 cog.outl(" add_new_message(rhs.get());")
865 cog.outl(" }")
866 cog.outl("")
867 cog.outl(" return *this;")
868 cog.outl(" }")
869 cog.outl("#include \"private/diagnostic_pop.h\"")
870 cog.outl("")
871 cog.outl("#if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION)")
872 cog.outl(" //**********************************************")
873 cog.outl("#include \"private/diagnostic_uninitialized_push.h\"")
874 cog.outl(" message_packet& operator =(message_packet&& rhs)")
875 cog.outl(" {")
876 cog.outl(" delete_current_message();")
877 cog.outl(" valid = rhs.is_valid();")
878 cog.outl(" if (valid)")
879 cog.outl(" {")
880 cog.outl(" add_new_message(etl::move(rhs.get()));")
881 cog.outl(" }")
882 cog.outl("")
883 cog.outl(" return *this;")
884 cog.outl(" }")
885 cog.outl("#include \"private/diagnostic_pop.h\"")
886 cog.outl("#endif")
887 cog.outl("")
888 cog.outl(" //********************************************")
889 cog.outl(" ~message_packet()")
890 cog.outl(" {")
891 cog.outl(" delete_current_message();")
892 cog.outl(" }")
893 cog.outl("")
894 cog.outl(" //********************************************")
895 cog.outl(" etl::imessage& get() ETL_NOEXCEPT")
896 cog.outl(" {")
897 cog.outl(" return *static_cast<etl::imessage*>(data);")
898 cog.outl(" }")
899 cog.outl("")
900 cog.outl(" //********************************************")
901 cog.outl(" const etl::imessage& get() const ETL_NOEXCEPT")
902 cog.outl(" {")
903 cog.outl(" return *static_cast<const etl::imessage*>(data);")
904 cog.outl(" }")
905 cog.outl("")
906 cog.outl(" //********************************************")
907 cog.outl(" bool is_valid() const")
908 cog.outl(" {")
909 cog.outl(" return valid;")
910 cog.outl(" }")
911 cog.outl("")
912 cog.outl(" //**********************************************")
913 cog.outl(" static ETL_CONSTEXPR bool accepts(etl::message_id_t id)")
914 cog.outl(" {")
915 generate_accepts_return(n)
916 cog.outl(" }")
917 cog.outl("")
918 cog.outl(" //**********************************************")
919 cog.outl(" static ETL_CONSTEXPR bool accepts(const etl::imessage& msg)")
920 cog.outl(" {")
921 cog.outl(" return accepts(msg.get_message_id());")
922 cog.outl(" }")
923 cog.outl("")
924 cog.outl(" //**********************************************")
925 cog.outl(" template <etl::message_id_t Id>")
926 cog.outl(" static ETL_CONSTEXPR bool accepts()")
927 cog.outl(" {")
928 generate_accepts_return_compile_time(n)
929 cog.outl(" }")
930 cog.outl("")
931 cog.outl(" //**********************************************")
932 cog.outl(" template <typename TMessage>")
933 cog.outl(" static ETL_CONSTEXPR")
934 cog.outl(" typename etl::enable_if<etl::is_base_of<etl::imessage, TMessage>::value, bool>::type")
935 cog.outl(" accepts()")
936 cog.outl(" {")
937 generate_accepts_return_compile_time_TMessage(n)
938 cog.outl(" }")
939 cog.outl("")
940 cog.outl(" enum")
941 cog.outl(" {")
942 cog.out(" SIZE = etl::largest<")
943 for t in range(1, n):
944 cog.out("T%d, " % t)
945 cog.outl("T%s>::size," % n)
946 cog.out(" ALIGNMENT = etl::largest<")
947 for t in range(1, n):
948 cog.out("T%d, " % t)
949 cog.outl("T%s>::alignment" % n)
950 cog.outl(" };")
951 cog.outl("")
952 cog.outl("private:")
953 cog.outl("")
954 cog.outl(" //********************************************")
955 cog.outl(" #include \"private/diagnostic_uninitialized_push.h\"")
956 cog.outl(" void delete_current_message()")
957 cog.outl(" {")
958 cog.outl(" if (valid)")
959 cog.outl(" {")
960 cog.outl(" etl::imessage* pmsg = static_cast<etl::imessage*>(data);")
961 cog.outl("")
962 cog.outl(" pmsg->~imessage();")
963 cog.outl(" }")
964 cog.outl(" }")
965 cog.outl(" #include \"private/diagnostic_pop.h\"")
966 cog.outl("")
967 cog.outl(" //********************************************")
968 cog.outl(" void add_new_message(const etl::imessage& msg)")
969 cog.outl(" {")
970 cog.outl(" const size_t id = msg.get_message_id();")
971 cog.outl(" void* p = data;")
972 cog.outl("")
973 cog.outl(" switch (id)")
974 cog.outl(" {")
975 for t in range(1, n + 1):
976 cog.outl(" case T%d::ID: ::new (p) T%d(static_cast<const T%d&>(msg)); break;" %(t, t, t))
977 cog.outl(" default: break;")
978 cog.outl(" }")
979 cog.outl(" }")
980 cog.outl("")
981 cog.outl("#if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION)")
982 cog.outl(" //********************************************")
983 cog.outl(" void add_new_message(etl::imessage&& msg)")
984 cog.outl(" {")
985 cog.outl(" const size_t id = msg.get_message_id();")
986 cog.outl(" void* p = data;")
987 cog.outl("")
988 cog.outl(" switch (id)")
989 cog.outl(" {")
990 for t in range(1, n + 1):
991 cog.outl(" case T%d::ID: ::new (p) T%d(static_cast<T%d&&>(msg)); break;" %(t, t, t))
992 cog.outl(" default: break;")
993 cog.outl(" }")
994 cog.outl(" }")
995 cog.outl("#endif")
996 cog.outl("")
997 cog.outl(" typename etl::aligned_storage<SIZE, ALIGNMENT>::type data;")
998 cog.outl(" bool valid;")
999 cog.outl("};")
1000 ]]]*/
1001 /*[[[end]]]*/
1002#endif
1003}
1004#else
1005 #error "etl::message_packet is not compatible with non-virtual etl::imessage"
1006#endif
1007
1008#endif
Definition message.h:73
Definition message_packet.h:367
#define ETL_ASSERT(b, e)
Definition error_handler.h:316
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