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