diff --git a/include/etl/message_packet.h b/include/etl/message_packet.h index 26582701..eec72724 100644 --- a/include/etl/message_packet.h +++ b/include/etl/message_packet.h @@ -56,6 +56,7 @@ SOFTWARE. #include "static_assert.h" #include "largest.h" #include "alignment.h" +#include "utility.h" #include @@ -75,11 +76,150 @@ namespace etl { public: + //******************************************** + message_packet() + : valid(false) + { + } + //******************************************** explicit message_packet(const etl::imessage& msg) + : valid(true) + { + add_new_message(msg); + } + + #if ETL_CPP11_SUPPORTED + //******************************************** + explicit message_packet(etl::imessage&& msg) + : valid(true) + { + add_new_message(etl::move(msg)); + } + #endif + + //********************************************** + message_packet(const message_packet& other) + : valid(other.is_valid()) + { + if (valid) + { + add_new_message(other.get()); + } + } + + #if ETL_CPP11_SUPPORTED + //********************************************** + message_packet(message_packet&& other) + : valid(other.is_valid()) + { + if (valid) + { + add_new_message(etl::move(other.get())); + } + } + #endif + + //********************************************** + message_packet& operator =(const message_packet& rhs) + { + delete_current_message(); + valid = rhs.is_valid(); + if (valid) + { + add_new_message(rhs.get()); + } + + return *this; + } + + #if ETL_CPP11_SUPPORTED + //********************************************** + message_packet& operator =(message_packet&& rhs) + { + delete_current_message(); + valid = rhs.is_valid(); + if (valid) + { + add_new_message(etl::move(rhs.get())); + } + + return *this; + } + #endif + + //******************************************** + ~message_packet() + { + delete_current_message(); + } + + //******************************************** + etl::imessage& get() ETL_NOEXCEPT + { + return *static_cast(data); + } + + //******************************************** + const etl::imessage& get() const ETL_NOEXCEPT + { + return *static_cast(data); + } + + //******************************************** + bool is_valid() const + { + return valid; + } + + enum + { + SIZE = etl::largest::size, + ALIGNMENT = etl::largest::alignment + }; + + private: + + //******************************************** + void delete_current_message() + { + if (valid) + { + etl::imessage* pmsg = static_cast(data); + + #if defined(ETL_MESSAGES_ARE_VIRTUAL) || defined(ETL_POLYMORPHIC_MESSAGES) + pmsg->~imessage(); + #else + size_t id = pmsg->message_id; + + switch (id) + { + case T1::ID: static_cast(pmsg)->~T1(); break; + case T2::ID: static_cast(pmsg)->~T2(); break; + case T3::ID: static_cast(pmsg)->~T3(); break; + case T4::ID: static_cast(pmsg)->~T4(); break; + case T5::ID: static_cast(pmsg)->~T5(); break; + case T6::ID: static_cast(pmsg)->~T6(); break; + case T7::ID: static_cast(pmsg)->~T7(); break; + case T8::ID: static_cast(pmsg)->~T8(); break; + case T9::ID: static_cast(pmsg)->~T9(); break; + case T10::ID: static_cast(pmsg)->~T10(); break; + case T11::ID: static_cast(pmsg)->~T11(); break; + case T12::ID: static_cast(pmsg)->~T12(); break; + case T13::ID: static_cast(pmsg)->~T13(); break; + case T14::ID: static_cast(pmsg)->~T14(); break; + case T15::ID: static_cast(pmsg)->~T15(); break; + case T16::ID: static_cast(pmsg)->~T16(); break; + default: assert(false); break; + } + #endif + } + } + + //******************************************** + void add_new_message(const etl::imessage& msg) { const size_t id = msg.message_id; - void* p = data; switch (id) @@ -104,77 +244,38 @@ namespace etl } } - //********************************************** - template - explicit message_packet(const T& msg) - { - ETL_STATIC_ASSERT((etl::is_one_of::value), "Unsupported type for this message packet"); - - void* p = data; - ::new (p) T(static_cast(msg)); - } - + #if ETL_CPP11_SUPPORTED //******************************************** - ~message_packet() + void add_new_message(etl::imessage&& msg) { - etl::imessage* pmsg = static_cast(data); - - #if defined(ETL_MESSAGES_ARE_VIRTUAL) || defined(ETL_POLYMORPHIC_MESSAGES) - pmsg->~imessage(); - #else - size_t id = pmsg->message_id; + const size_t id = msg.message_id; + void* p = data; switch (id) { - case T1::ID: static_cast(pmsg)->~T1(); break; - case T2::ID: static_cast(pmsg)->~T2(); break; - case T3::ID: static_cast(pmsg)->~T3(); break; - case T4::ID: static_cast(pmsg)->~T4(); break; - case T5::ID: static_cast(pmsg)->~T5(); break; - case T6::ID: static_cast(pmsg)->~T6(); break; - case T7::ID: static_cast(pmsg)->~T7(); break; - case T8::ID: static_cast(pmsg)->~T8(); break; - case T9::ID: static_cast(pmsg)->~T9(); break; - case T10::ID: static_cast(pmsg)->~T10(); break; - case T11::ID: static_cast(pmsg)->~T11(); break; - case T12::ID: static_cast(pmsg)->~T12(); break; - case T13::ID: static_cast(pmsg)->~T13(); break; - case T14::ID: static_cast(pmsg)->~T14(); break; - case T15::ID: static_cast(pmsg)->~T15(); break; - case T16::ID: static_cast(pmsg)->~T16(); break; - default: assert(false); break; + case T1::ID: ::new (p) T1(static_cast(msg)); break; + case T2::ID: ::new (p) T2(static_cast(msg)); break; + case T3::ID: ::new (p) T3(static_cast(msg)); break; + case T4::ID: ::new (p) T4(static_cast(msg)); break; + case T5::ID: ::new (p) T5(static_cast(msg)); break; + case T6::ID: ::new (p) T6(static_cast(msg)); break; + case T7::ID: ::new (p) T7(static_cast(msg)); break; + case T8::ID: ::new (p) T8(static_cast(msg)); break; + case T9::ID: ::new (p) T9(static_cast(msg)); break; + case T10::ID: ::new (p) T10(static_cast(msg)); break; + case T11::ID: ::new (p) T11(static_cast(msg)); break; + case T12::ID: ::new (p) T12(static_cast(msg)); break; + case T13::ID: ::new (p) T13(static_cast(msg)); break; + case T14::ID: ::new (p) T14(static_cast(msg)); break; + case T15::ID: ::new (p) T15(static_cast(msg)); break; + case T16::ID: ::new (p) T16(static_cast(msg)); break; + default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break; } + } #endif - } - - //******************************************** - etl::imessage& get() ETL_NOEXCEPT - { - return *static_cast(data); - } - - //******************************************** - const etl::imessage& get() const ETL_NOEXCEPT - { - return *static_cast(data); - } - - enum - { - SIZE = etl::largest::size, - ALIGNMENT = etl::largest::alignment - }; - - private: typename etl::aligned_storage::type data; - - message_packet(const message_packet&) ETL_DELETE; - message_packet& operator =(const message_packet&) ETL_DELETE; - #if ETL_CPP11_SUPPORTED - message_packet(message_packet&&) ETL_DELETE; - message_packet& operator =(message_packet&&) ETL_DELETE; - #endif + bool valid; }; //*************************************************************************** @@ -188,11 +289,149 @@ namespace etl { public: + //******************************************** + message_packet() + : valid(false) + { + } + //******************************************** explicit message_packet(const etl::imessage& msg) + : valid(true) + { + add_new_message(msg); + } + + #if ETL_CPP11_SUPPORTED + //******************************************** + explicit message_packet(etl::imessage&& msg) + : valid(true) + { + add_new_message(etl::move(msg)); + } + #endif + + //********************************************** + message_packet(const message_packet& other) + : valid(other.is_valid()) + { + if (valid) + { + add_new_message(other.get()); + } + } + + #if ETL_CPP11_SUPPORTED + //********************************************** + message_packet(message_packet&& other) + : valid(other.is_valid()) + { + if (valid) + { + add_new_message(etl::move(other.get())); + } + } + #endif + + //********************************************** + message_packet& operator =(const message_packet& rhs) + { + delete_current_message(); + valid = rhs.is_valid(); + if (valid) + { + add_new_message(rhs.get()); + } + + return *this; + } + + #if ETL_CPP11_SUPPORTED + //********************************************** + message_packet& operator =(message_packet&& rhs) + { + delete_current_message(); + valid = rhs.is_valid(); + if (valid) + { + add_new_message(etl::move(rhs.get())); + } + + return *this; + } + #endif + + //******************************************** + ~message_packet() + { + delete_current_message(); + } + + //******************************************** + etl::imessage& get() ETL_NOEXCEPT + { + return *static_cast(data); + } + + //******************************************** + const etl::imessage& get() const ETL_NOEXCEPT + { + return *static_cast(data); + } + + //******************************************** + bool is_valid() const + { + return valid; + } + + enum + { + SIZE = etl::largest::size, + ALIGNMENT = etl::largest::alignment + }; + + private: + + //******************************************** + void delete_current_message() + { + if (valid) + { + etl::imessage* pmsg = static_cast(data); + + #if defined(ETL_MESSAGES_ARE_VIRTUAL) || defined(ETL_POLYMORPHIC_MESSAGES) + pmsg->~imessage(); + #else + size_t id = pmsg->message_id; + + switch (id) + { + case T1::ID: static_cast(pmsg)->~T1(); break; + case T2::ID: static_cast(pmsg)->~T2(); break; + case T3::ID: static_cast(pmsg)->~T3(); break; + case T4::ID: static_cast(pmsg)->~T4(); break; + case T5::ID: static_cast(pmsg)->~T5(); break; + case T6::ID: static_cast(pmsg)->~T6(); break; + case T7::ID: static_cast(pmsg)->~T7(); break; + case T8::ID: static_cast(pmsg)->~T8(); break; + case T9::ID: static_cast(pmsg)->~T9(); break; + case T10::ID: static_cast(pmsg)->~T10(); break; + case T11::ID: static_cast(pmsg)->~T11(); break; + case T12::ID: static_cast(pmsg)->~T12(); break; + case T13::ID: static_cast(pmsg)->~T13(); break; + case T14::ID: static_cast(pmsg)->~T14(); break; + case T15::ID: static_cast(pmsg)->~T15(); break; + default: assert(false); break; + } + #endif + } + } + + //******************************************** + void add_new_message(const etl::imessage& msg) { const size_t id = msg.message_id; - void* p = data; switch (id) @@ -216,76 +455,37 @@ namespace etl } } - //********************************************** - template - explicit message_packet(const T& msg) - { - ETL_STATIC_ASSERT((etl::is_one_of::value), "Unsupported type for this message packet"); - - void* p = data; - ::new (p) T(static_cast(msg)); - } - + #if ETL_CPP11_SUPPORTED //******************************************** - ~message_packet() + void add_new_message(etl::imessage&& msg) { - etl::imessage* pmsg = static_cast(data); - - #if defined(ETL_MESSAGES_ARE_VIRTUAL) || defined(ETL_POLYMORPHIC_MESSAGES) - pmsg->~imessage(); - #else - size_t id = pmsg->message_id; + const size_t id = msg.message_id; + void* p = data; switch (id) { - case T1::ID: static_cast(pmsg)->~T1(); break; - case T2::ID: static_cast(pmsg)->~T2(); break; - case T3::ID: static_cast(pmsg)->~T3(); break; - case T4::ID: static_cast(pmsg)->~T4(); break; - case T5::ID: static_cast(pmsg)->~T5(); break; - case T6::ID: static_cast(pmsg)->~T6(); break; - case T7::ID: static_cast(pmsg)->~T7(); break; - case T8::ID: static_cast(pmsg)->~T8(); break; - case T9::ID: static_cast(pmsg)->~T9(); break; - case T10::ID: static_cast(pmsg)->~T10(); break; - case T11::ID: static_cast(pmsg)->~T11(); break; - case T12::ID: static_cast(pmsg)->~T12(); break; - case T13::ID: static_cast(pmsg)->~T13(); break; - case T14::ID: static_cast(pmsg)->~T14(); break; - case T15::ID: static_cast(pmsg)->~T15(); break; - default: assert(false); break; + case T1::ID: ::new (p) T1(static_cast(msg)); break; + case T2::ID: ::new (p) T2(static_cast(msg)); break; + case T3::ID: ::new (p) T3(static_cast(msg)); break; + case T4::ID: ::new (p) T4(static_cast(msg)); break; + case T5::ID: ::new (p) T5(static_cast(msg)); break; + case T6::ID: ::new (p) T6(static_cast(msg)); break; + case T7::ID: ::new (p) T7(static_cast(msg)); break; + case T8::ID: ::new (p) T8(static_cast(msg)); break; + case T9::ID: ::new (p) T9(static_cast(msg)); break; + case T10::ID: ::new (p) T10(static_cast(msg)); break; + case T11::ID: ::new (p) T11(static_cast(msg)); break; + case T12::ID: ::new (p) T12(static_cast(msg)); break; + case T13::ID: ::new (p) T13(static_cast(msg)); break; + case T14::ID: ::new (p) T14(static_cast(msg)); break; + case T15::ID: ::new (p) T15(static_cast(msg)); break; + default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break; } + } #endif - } - - //******************************************** - etl::imessage& get() ETL_NOEXCEPT - { - return *static_cast(data); - } - - //******************************************** - const etl::imessage& get() const ETL_NOEXCEPT - { - return *static_cast(data); - } - - enum - { - SIZE = etl::largest::size, - ALIGNMENT = etl::largest::alignment - }; - - private: typename etl::aligned_storage::type data; - - message_packet(const message_packet&) ETL_DELETE; - message_packet& operator =(const message_packet&) ETL_DELETE; - #if ETL_CPP11_SUPPORTED - message_packet(message_packet&&) ETL_DELETE; - message_packet& operator =(message_packet&&) ETL_DELETE; - #endif + bool valid; }; //*************************************************************************** @@ -299,11 +499,148 @@ namespace etl { public: + //******************************************** + message_packet() + : valid(false) + { + } + //******************************************** explicit message_packet(const etl::imessage& msg) + : valid(true) + { + add_new_message(msg); + } + + #if ETL_CPP11_SUPPORTED + //******************************************** + explicit message_packet(etl::imessage&& msg) + : valid(true) + { + add_new_message(etl::move(msg)); + } + #endif + + //********************************************** + message_packet(const message_packet& other) + : valid(other.is_valid()) + { + if (valid) + { + add_new_message(other.get()); + } + } + + #if ETL_CPP11_SUPPORTED + //********************************************** + message_packet(message_packet&& other) + : valid(other.is_valid()) + { + if (valid) + { + add_new_message(etl::move(other.get())); + } + } + #endif + + //********************************************** + message_packet& operator =(const message_packet& rhs) + { + delete_current_message(); + valid = rhs.is_valid(); + if (valid) + { + add_new_message(rhs.get()); + } + + return *this; + } + + #if ETL_CPP11_SUPPORTED + //********************************************** + message_packet& operator =(message_packet&& rhs) + { + delete_current_message(); + valid = rhs.is_valid(); + if (valid) + { + add_new_message(etl::move(rhs.get())); + } + + return *this; + } + #endif + + //******************************************** + ~message_packet() + { + delete_current_message(); + } + + //******************************************** + etl::imessage& get() ETL_NOEXCEPT + { + return *static_cast(data); + } + + //******************************************** + const etl::imessage& get() const ETL_NOEXCEPT + { + return *static_cast(data); + } + + //******************************************** + bool is_valid() const + { + return valid; + } + + enum + { + SIZE = etl::largest::size, + ALIGNMENT = etl::largest::alignment + }; + + private: + + //******************************************** + void delete_current_message() + { + if (valid) + { + etl::imessage* pmsg = static_cast(data); + + #if defined(ETL_MESSAGES_ARE_VIRTUAL) || defined(ETL_POLYMORPHIC_MESSAGES) + pmsg->~imessage(); + #else + size_t id = pmsg->message_id; + + switch (id) + { + case T1::ID: static_cast(pmsg)->~T1(); break; + case T2::ID: static_cast(pmsg)->~T2(); break; + case T3::ID: static_cast(pmsg)->~T3(); break; + case T4::ID: static_cast(pmsg)->~T4(); break; + case T5::ID: static_cast(pmsg)->~T5(); break; + case T6::ID: static_cast(pmsg)->~T6(); break; + case T7::ID: static_cast(pmsg)->~T7(); break; + case T8::ID: static_cast(pmsg)->~T8(); break; + case T9::ID: static_cast(pmsg)->~T9(); break; + case T10::ID: static_cast(pmsg)->~T10(); break; + case T11::ID: static_cast(pmsg)->~T11(); break; + case T12::ID: static_cast(pmsg)->~T12(); break; + case T13::ID: static_cast(pmsg)->~T13(); break; + case T14::ID: static_cast(pmsg)->~T14(); break; + default: assert(false); break; + } + #endif + } + } + + //******************************************** + void add_new_message(const etl::imessage& msg) { const size_t id = msg.message_id; - void* p = data; switch (id) @@ -326,75 +663,36 @@ namespace etl } } - //********************************************** - template - explicit message_packet(const T& msg) - { - ETL_STATIC_ASSERT((etl::is_one_of::value), "Unsupported type for this message packet"); - - void* p = data; - ::new (p) T(static_cast(msg)); - } - + #if ETL_CPP11_SUPPORTED //******************************************** - ~message_packet() + void add_new_message(etl::imessage&& msg) { - etl::imessage* pmsg = static_cast(data); - - #if defined(ETL_MESSAGES_ARE_VIRTUAL) || defined(ETL_POLYMORPHIC_MESSAGES) - pmsg->~imessage(); - #else - size_t id = pmsg->message_id; + const size_t id = msg.message_id; + void* p = data; switch (id) { - case T1::ID: static_cast(pmsg)->~T1(); break; - case T2::ID: static_cast(pmsg)->~T2(); break; - case T3::ID: static_cast(pmsg)->~T3(); break; - case T4::ID: static_cast(pmsg)->~T4(); break; - case T5::ID: static_cast(pmsg)->~T5(); break; - case T6::ID: static_cast(pmsg)->~T6(); break; - case T7::ID: static_cast(pmsg)->~T7(); break; - case T8::ID: static_cast(pmsg)->~T8(); break; - case T9::ID: static_cast(pmsg)->~T9(); break; - case T10::ID: static_cast(pmsg)->~T10(); break; - case T11::ID: static_cast(pmsg)->~T11(); break; - case T12::ID: static_cast(pmsg)->~T12(); break; - case T13::ID: static_cast(pmsg)->~T13(); break; - case T14::ID: static_cast(pmsg)->~T14(); break; - default: assert(false); break; + case T1::ID: ::new (p) T1(static_cast(msg)); break; + case T2::ID: ::new (p) T2(static_cast(msg)); break; + case T3::ID: ::new (p) T3(static_cast(msg)); break; + case T4::ID: ::new (p) T4(static_cast(msg)); break; + case T5::ID: ::new (p) T5(static_cast(msg)); break; + case T6::ID: ::new (p) T6(static_cast(msg)); break; + case T7::ID: ::new (p) T7(static_cast(msg)); break; + case T8::ID: ::new (p) T8(static_cast(msg)); break; + case T9::ID: ::new (p) T9(static_cast(msg)); break; + case T10::ID: ::new (p) T10(static_cast(msg)); break; + case T11::ID: ::new (p) T11(static_cast(msg)); break; + case T12::ID: ::new (p) T12(static_cast(msg)); break; + case T13::ID: ::new (p) T13(static_cast(msg)); break; + case T14::ID: ::new (p) T14(static_cast(msg)); break; + default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break; } + } #endif - } - - //******************************************** - etl::imessage& get() ETL_NOEXCEPT - { - return *static_cast(data); - } - - //******************************************** - const etl::imessage& get() const ETL_NOEXCEPT - { - return *static_cast(data); - } - - enum - { - SIZE = etl::largest::size, - ALIGNMENT = etl::largest::alignment - }; - - private: typename etl::aligned_storage::type data; - - message_packet(const message_packet&) ETL_DELETE; - message_packet& operator =(const message_packet&) ETL_DELETE; - #if ETL_CPP11_SUPPORTED - message_packet(message_packet&&) ETL_DELETE; - message_packet& operator =(message_packet&&) ETL_DELETE; - #endif + bool valid; }; //*************************************************************************** @@ -408,11 +706,147 @@ namespace etl { public: + //******************************************** + message_packet() + : valid(false) + { + } + //******************************************** explicit message_packet(const etl::imessage& msg) + : valid(true) + { + add_new_message(msg); + } + + #if ETL_CPP11_SUPPORTED + //******************************************** + explicit message_packet(etl::imessage&& msg) + : valid(true) + { + add_new_message(etl::move(msg)); + } + #endif + + //********************************************** + message_packet(const message_packet& other) + : valid(other.is_valid()) + { + if (valid) + { + add_new_message(other.get()); + } + } + + #if ETL_CPP11_SUPPORTED + //********************************************** + message_packet(message_packet&& other) + : valid(other.is_valid()) + { + if (valid) + { + add_new_message(etl::move(other.get())); + } + } + #endif + + //********************************************** + message_packet& operator =(const message_packet& rhs) + { + delete_current_message(); + valid = rhs.is_valid(); + if (valid) + { + add_new_message(rhs.get()); + } + + return *this; + } + + #if ETL_CPP11_SUPPORTED + //********************************************** + message_packet& operator =(message_packet&& rhs) + { + delete_current_message(); + valid = rhs.is_valid(); + if (valid) + { + add_new_message(etl::move(rhs.get())); + } + + return *this; + } + #endif + + //******************************************** + ~message_packet() + { + delete_current_message(); + } + + //******************************************** + etl::imessage& get() ETL_NOEXCEPT + { + return *static_cast(data); + } + + //******************************************** + const etl::imessage& get() const ETL_NOEXCEPT + { + return *static_cast(data); + } + + //******************************************** + bool is_valid() const + { + return valid; + } + + enum + { + SIZE = etl::largest::size, + ALIGNMENT = etl::largest::alignment + }; + + private: + + //******************************************** + void delete_current_message() + { + if (valid) + { + etl::imessage* pmsg = static_cast(data); + + #if defined(ETL_MESSAGES_ARE_VIRTUAL) || defined(ETL_POLYMORPHIC_MESSAGES) + pmsg->~imessage(); + #else + size_t id = pmsg->message_id; + + switch (id) + { + case T1::ID: static_cast(pmsg)->~T1(); break; + case T2::ID: static_cast(pmsg)->~T2(); break; + case T3::ID: static_cast(pmsg)->~T3(); break; + case T4::ID: static_cast(pmsg)->~T4(); break; + case T5::ID: static_cast(pmsg)->~T5(); break; + case T6::ID: static_cast(pmsg)->~T6(); break; + case T7::ID: static_cast(pmsg)->~T7(); break; + case T8::ID: static_cast(pmsg)->~T8(); break; + case T9::ID: static_cast(pmsg)->~T9(); break; + case T10::ID: static_cast(pmsg)->~T10(); break; + case T11::ID: static_cast(pmsg)->~T11(); break; + case T12::ID: static_cast(pmsg)->~T12(); break; + case T13::ID: static_cast(pmsg)->~T13(); break; + default: assert(false); break; + } + #endif + } + } + + //******************************************** + void add_new_message(const etl::imessage& msg) { const size_t id = msg.message_id; - void* p = data; switch (id) @@ -434,44 +868,123 @@ namespace etl } } - //********************************************** - template - explicit message_packet(const T& msg) + #if ETL_CPP11_SUPPORTED + //******************************************** + void add_new_message(etl::imessage&& msg) { - ETL_STATIC_ASSERT((etl::is_one_of::value), "Unsupported type for this message packet"); - + const size_t id = msg.message_id; void* p = data; - ::new (p) T(static_cast(msg)); + + switch (id) + { + case T1::ID: ::new (p) T1(static_cast(msg)); break; + case T2::ID: ::new (p) T2(static_cast(msg)); break; + case T3::ID: ::new (p) T3(static_cast(msg)); break; + case T4::ID: ::new (p) T4(static_cast(msg)); break; + case T5::ID: ::new (p) T5(static_cast(msg)); break; + case T6::ID: ::new (p) T6(static_cast(msg)); break; + case T7::ID: ::new (p) T7(static_cast(msg)); break; + case T8::ID: ::new (p) T8(static_cast(msg)); break; + case T9::ID: ::new (p) T9(static_cast(msg)); break; + case T10::ID: ::new (p) T10(static_cast(msg)); break; + case T11::ID: ::new (p) T11(static_cast(msg)); break; + case T12::ID: ::new (p) T12(static_cast(msg)); break; + case T13::ID: ::new (p) T13(static_cast(msg)); break; + default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break; + } } + #endif + + typename etl::aligned_storage::type data; + bool valid; + }; + + //*************************************************************************** + // Specialisation for 12 message types. + //*************************************************************************** + template + class message_packet + { + public: + + //******************************************** + message_packet() + : valid(false) + { + } + + //******************************************** + explicit message_packet(const etl::imessage& msg) + : valid(true) + { + add_new_message(msg); + } + + #if ETL_CPP11_SUPPORTED + //******************************************** + explicit message_packet(etl::imessage&& msg) + : valid(true) + { + add_new_message(etl::move(msg)); + } + #endif + + //********************************************** + message_packet(const message_packet& other) + : valid(other.is_valid()) + { + if (valid) + { + add_new_message(other.get()); + } + } + + #if ETL_CPP11_SUPPORTED + //********************************************** + message_packet(message_packet&& other) + : valid(other.is_valid()) + { + if (valid) + { + add_new_message(etl::move(other.get())); + } + } + #endif + + //********************************************** + message_packet& operator =(const message_packet& rhs) + { + delete_current_message(); + valid = rhs.is_valid(); + if (valid) + { + add_new_message(rhs.get()); + } + + return *this; + } + + #if ETL_CPP11_SUPPORTED + //********************************************** + message_packet& operator =(message_packet&& rhs) + { + delete_current_message(); + valid = rhs.is_valid(); + if (valid) + { + add_new_message(etl::move(rhs.get())); + } + + return *this; + } + #endif //******************************************** ~message_packet() { - etl::imessage* pmsg = static_cast(data); - - #if defined(ETL_MESSAGES_ARE_VIRTUAL) || defined(ETL_POLYMORPHIC_MESSAGES) - pmsg->~imessage(); - #else - size_t id = pmsg->message_id; - - switch (id) - { - case T1::ID: static_cast(pmsg)->~T1(); break; - case T2::ID: static_cast(pmsg)->~T2(); break; - case T3::ID: static_cast(pmsg)->~T3(); break; - case T4::ID: static_cast(pmsg)->~T4(); break; - case T5::ID: static_cast(pmsg)->~T5(); break; - case T6::ID: static_cast(pmsg)->~T6(); break; - case T7::ID: static_cast(pmsg)->~T7(); break; - case T8::ID: static_cast(pmsg)->~T8(); break; - case T9::ID: static_cast(pmsg)->~T9(); break; - case T10::ID: static_cast(pmsg)->~T10(); break; - case T11::ID: static_cast(pmsg)->~T11(); break; - case T12::ID: static_cast(pmsg)->~T12(); break; - case T13::ID: static_cast(pmsg)->~T13(); break; - default: assert(false); break; - } - #endif + delete_current_message(); } //******************************************** @@ -486,39 +999,56 @@ namespace etl return *static_cast(data); } + //******************************************** + bool is_valid() const + { + return valid; + } + enum { - SIZE = etl::largest::size, - ALIGNMENT = etl::largest::alignment + SIZE = etl::largest::size, + ALIGNMENT = etl::largest::alignment }; private: - typename etl::aligned_storage::type data; + //******************************************** + void delete_current_message() + { + if (valid) + { + etl::imessage* pmsg = static_cast(data); - message_packet(const message_packet&) ETL_DELETE; - message_packet& operator =(const message_packet&) ETL_DELETE; - #if ETL_CPP11_SUPPORTED - message_packet(message_packet&&) ETL_DELETE; - message_packet& operator =(message_packet&&) ETL_DELETE; - #endif - }; + #if defined(ETL_MESSAGES_ARE_VIRTUAL) || defined(ETL_POLYMORPHIC_MESSAGES) + pmsg->~imessage(); + #else + size_t id = pmsg->message_id; - //*************************************************************************** - // Specialisation for 12 message types. - //*************************************************************************** - template - class message_packet - { - public: + switch (id) + { + case T1::ID: static_cast(pmsg)->~T1(); break; + case T2::ID: static_cast(pmsg)->~T2(); break; + case T3::ID: static_cast(pmsg)->~T3(); break; + case T4::ID: static_cast(pmsg)->~T4(); break; + case T5::ID: static_cast(pmsg)->~T5(); break; + case T6::ID: static_cast(pmsg)->~T6(); break; + case T7::ID: static_cast(pmsg)->~T7(); break; + case T8::ID: static_cast(pmsg)->~T8(); break; + case T9::ID: static_cast(pmsg)->~T9(); break; + case T10::ID: static_cast(pmsg)->~T10(); break; + case T11::ID: static_cast(pmsg)->~T11(); break; + case T12::ID: static_cast(pmsg)->~T12(); break; + default: assert(false); break; + } + #endif + } + } //******************************************** - explicit message_packet(const etl::imessage& msg) + void add_new_message(const etl::imessage& msg) { const size_t id = msg.message_id; - void* p = data; switch (id) @@ -539,43 +1069,122 @@ namespace etl } } - //********************************************** - template - explicit message_packet(const T& msg) + #if ETL_CPP11_SUPPORTED + //******************************************** + void add_new_message(etl::imessage&& msg) { - ETL_STATIC_ASSERT((etl::is_one_of::value), "Unsupported type for this message packet"); - + const size_t id = msg.message_id; void* p = data; - ::new (p) T(static_cast(msg)); + + switch (id) + { + case T1::ID: ::new (p) T1(static_cast(msg)); break; + case T2::ID: ::new (p) T2(static_cast(msg)); break; + case T3::ID: ::new (p) T3(static_cast(msg)); break; + case T4::ID: ::new (p) T4(static_cast(msg)); break; + case T5::ID: ::new (p) T5(static_cast(msg)); break; + case T6::ID: ::new (p) T6(static_cast(msg)); break; + case T7::ID: ::new (p) T7(static_cast(msg)); break; + case T8::ID: ::new (p) T8(static_cast(msg)); break; + case T9::ID: ::new (p) T9(static_cast(msg)); break; + case T10::ID: ::new (p) T10(static_cast(msg)); break; + case T11::ID: ::new (p) T11(static_cast(msg)); break; + case T12::ID: ::new (p) T12(static_cast(msg)); break; + default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break; + } } + #endif + + typename etl::aligned_storage::type data; + bool valid; + }; + + //*************************************************************************** + // Specialisation for 11 message types. + //*************************************************************************** + template + class message_packet + { + public: + + //******************************************** + message_packet() + : valid(false) + { + } + + //******************************************** + explicit message_packet(const etl::imessage& msg) + : valid(true) + { + add_new_message(msg); + } + + #if ETL_CPP11_SUPPORTED + //******************************************** + explicit message_packet(etl::imessage&& msg) + : valid(true) + { + add_new_message(etl::move(msg)); + } + #endif + + //********************************************** + message_packet(const message_packet& other) + : valid(other.is_valid()) + { + if (valid) + { + add_new_message(other.get()); + } + } + + #if ETL_CPP11_SUPPORTED + //********************************************** + message_packet(message_packet&& other) + : valid(other.is_valid()) + { + if (valid) + { + add_new_message(etl::move(other.get())); + } + } + #endif + + //********************************************** + message_packet& operator =(const message_packet& rhs) + { + delete_current_message(); + valid = rhs.is_valid(); + if (valid) + { + add_new_message(rhs.get()); + } + + return *this; + } + + #if ETL_CPP11_SUPPORTED + //********************************************** + message_packet& operator =(message_packet&& rhs) + { + delete_current_message(); + valid = rhs.is_valid(); + if (valid) + { + add_new_message(etl::move(rhs.get())); + } + + return *this; + } + #endif //******************************************** ~message_packet() { - etl::imessage* pmsg = static_cast(data); - - #if defined(ETL_MESSAGES_ARE_VIRTUAL) || defined(ETL_POLYMORPHIC_MESSAGES) - pmsg->~imessage(); - #else - size_t id = pmsg->message_id; - - switch (id) - { - case T1::ID: static_cast(pmsg)->~T1(); break; - case T2::ID: static_cast(pmsg)->~T2(); break; - case T3::ID: static_cast(pmsg)->~T3(); break; - case T4::ID: static_cast(pmsg)->~T4(); break; - case T5::ID: static_cast(pmsg)->~T5(); break; - case T6::ID: static_cast(pmsg)->~T6(); break; - case T7::ID: static_cast(pmsg)->~T7(); break; - case T8::ID: static_cast(pmsg)->~T8(); break; - case T9::ID: static_cast(pmsg)->~T9(); break; - case T10::ID: static_cast(pmsg)->~T10(); break; - case T11::ID: static_cast(pmsg)->~T11(); break; - case T12::ID: static_cast(pmsg)->~T12(); break; - default: assert(false); break; - } - #endif + delete_current_message(); } //******************************************** @@ -590,39 +1199,55 @@ namespace etl return *static_cast(data); } + //******************************************** + bool is_valid() const + { + return valid; + } + enum { - SIZE = etl::largest::size, - ALIGNMENT = etl::largest::alignment + SIZE = etl::largest::size, + ALIGNMENT = etl::largest::alignment }; private: - typename etl::aligned_storage::type data; + //******************************************** + void delete_current_message() + { + if (valid) + { + etl::imessage* pmsg = static_cast(data); - message_packet(const message_packet&) ETL_DELETE; - message_packet& operator =(const message_packet&) ETL_DELETE; - #if ETL_CPP11_SUPPORTED - message_packet(message_packet&&) ETL_DELETE; - message_packet& operator =(message_packet&&) ETL_DELETE; - #endif - }; + #if defined(ETL_MESSAGES_ARE_VIRTUAL) || defined(ETL_POLYMORPHIC_MESSAGES) + pmsg->~imessage(); + #else + size_t id = pmsg->message_id; - //*************************************************************************** - // Specialisation for 11 message types. - //*************************************************************************** - template - class message_packet - { - public: + switch (id) + { + case T1::ID: static_cast(pmsg)->~T1(); break; + case T2::ID: static_cast(pmsg)->~T2(); break; + case T3::ID: static_cast(pmsg)->~T3(); break; + case T4::ID: static_cast(pmsg)->~T4(); break; + case T5::ID: static_cast(pmsg)->~T5(); break; + case T6::ID: static_cast(pmsg)->~T6(); break; + case T7::ID: static_cast(pmsg)->~T7(); break; + case T8::ID: static_cast(pmsg)->~T8(); break; + case T9::ID: static_cast(pmsg)->~T9(); break; + case T10::ID: static_cast(pmsg)->~T10(); break; + case T11::ID: static_cast(pmsg)->~T11(); break; + default: assert(false); break; + } + #endif + } + } //******************************************** - explicit message_packet(const etl::imessage& msg) + void add_new_message(const etl::imessage& msg) { const size_t id = msg.message_id; - void* p = data; switch (id) @@ -642,42 +1267,121 @@ namespace etl } } - //********************************************** - template - explicit message_packet(const T& msg) + #if ETL_CPP11_SUPPORTED + //******************************************** + void add_new_message(etl::imessage&& msg) { - ETL_STATIC_ASSERT((etl::is_one_of::value), "Unsupported type for this message packet"); - + const size_t id = msg.message_id; void* p = data; - ::new (p) T(static_cast(msg)); + + switch (id) + { + case T1::ID: ::new (p) T1(static_cast(msg)); break; + case T2::ID: ::new (p) T2(static_cast(msg)); break; + case T3::ID: ::new (p) T3(static_cast(msg)); break; + case T4::ID: ::new (p) T4(static_cast(msg)); break; + case T5::ID: ::new (p) T5(static_cast(msg)); break; + case T6::ID: ::new (p) T6(static_cast(msg)); break; + case T7::ID: ::new (p) T7(static_cast(msg)); break; + case T8::ID: ::new (p) T8(static_cast(msg)); break; + case T9::ID: ::new (p) T9(static_cast(msg)); break; + case T10::ID: ::new (p) T10(static_cast(msg)); break; + case T11::ID: ::new (p) T11(static_cast(msg)); break; + default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break; + } } + #endif + + typename etl::aligned_storage::type data; + bool valid; + }; + + //*************************************************************************** + // Specialisation for 10 message types. + //*************************************************************************** + template + class message_packet + { + public: + + //******************************************** + message_packet() + : valid(false) + { + } + + //******************************************** + explicit message_packet(const etl::imessage& msg) + : valid(true) + { + add_new_message(msg); + } + + #if ETL_CPP11_SUPPORTED + //******************************************** + explicit message_packet(etl::imessage&& msg) + : valid(true) + { + add_new_message(etl::move(msg)); + } + #endif + + //********************************************** + message_packet(const message_packet& other) + : valid(other.is_valid()) + { + if (valid) + { + add_new_message(other.get()); + } + } + + #if ETL_CPP11_SUPPORTED + //********************************************** + message_packet(message_packet&& other) + : valid(other.is_valid()) + { + if (valid) + { + add_new_message(etl::move(other.get())); + } + } + #endif + + //********************************************** + message_packet& operator =(const message_packet& rhs) + { + delete_current_message(); + valid = rhs.is_valid(); + if (valid) + { + add_new_message(rhs.get()); + } + + return *this; + } + + #if ETL_CPP11_SUPPORTED + //********************************************** + message_packet& operator =(message_packet&& rhs) + { + delete_current_message(); + valid = rhs.is_valid(); + if (valid) + { + add_new_message(etl::move(rhs.get())); + } + + return *this; + } + #endif //******************************************** ~message_packet() { - etl::imessage* pmsg = static_cast(data); - - #if defined(ETL_MESSAGES_ARE_VIRTUAL) || defined(ETL_POLYMORPHIC_MESSAGES) - pmsg->~imessage(); - #else - size_t id = pmsg->message_id; - - switch (id) - { - case T1::ID: static_cast(pmsg)->~T1(); break; - case T2::ID: static_cast(pmsg)->~T2(); break; - case T3::ID: static_cast(pmsg)->~T3(); break; - case T4::ID: static_cast(pmsg)->~T4(); break; - case T5::ID: static_cast(pmsg)->~T5(); break; - case T6::ID: static_cast(pmsg)->~T6(); break; - case T7::ID: static_cast(pmsg)->~T7(); break; - case T8::ID: static_cast(pmsg)->~T8(); break; - case T9::ID: static_cast(pmsg)->~T9(); break; - case T10::ID: static_cast(pmsg)->~T10(); break; - case T11::ID: static_cast(pmsg)->~T11(); break; - default: assert(false); break; - } - #endif + delete_current_message(); } //******************************************** @@ -692,39 +1396,54 @@ namespace etl return *static_cast(data); } + //******************************************** + bool is_valid() const + { + return valid; + } + enum { - SIZE = etl::largest::size, - ALIGNMENT = etl::largest::alignment + SIZE = etl::largest::size, + ALIGNMENT = etl::largest::alignment }; private: - typename etl::aligned_storage::type data; + //******************************************** + void delete_current_message() + { + if (valid) + { + etl::imessage* pmsg = static_cast(data); - message_packet(const message_packet&) ETL_DELETE; - message_packet& operator =(const message_packet&) ETL_DELETE; - #if ETL_CPP11_SUPPORTED - message_packet(message_packet&&) ETL_DELETE; - message_packet& operator =(message_packet&&) ETL_DELETE; - #endif - }; + #if defined(ETL_MESSAGES_ARE_VIRTUAL) || defined(ETL_POLYMORPHIC_MESSAGES) + pmsg->~imessage(); + #else + size_t id = pmsg->message_id; - //*************************************************************************** - // Specialisation for 10 message types. - //*************************************************************************** - template - class message_packet - { - public: + switch (id) + { + case T1::ID: static_cast(pmsg)->~T1(); break; + case T2::ID: static_cast(pmsg)->~T2(); break; + case T3::ID: static_cast(pmsg)->~T3(); break; + case T4::ID: static_cast(pmsg)->~T4(); break; + case T5::ID: static_cast(pmsg)->~T5(); break; + case T6::ID: static_cast(pmsg)->~T6(); break; + case T7::ID: static_cast(pmsg)->~T7(); break; + case T8::ID: static_cast(pmsg)->~T8(); break; + case T9::ID: static_cast(pmsg)->~T9(); break; + case T10::ID: static_cast(pmsg)->~T10(); break; + default: assert(false); break; + } + #endif + } + } //******************************************** - explicit message_packet(const etl::imessage& msg) + void add_new_message(const etl::imessage& msg) { const size_t id = msg.message_id; - void* p = data; switch (id) @@ -743,41 +1462,120 @@ namespace etl } } - //********************************************** - template - explicit message_packet(const T& msg) + #if ETL_CPP11_SUPPORTED + //******************************************** + void add_new_message(etl::imessage&& msg) { - ETL_STATIC_ASSERT((etl::is_one_of::value), "Unsupported type for this message packet"); - + const size_t id = msg.message_id; void* p = data; - ::new (p) T(static_cast(msg)); + + switch (id) + { + case T1::ID: ::new (p) T1(static_cast(msg)); break; + case T2::ID: ::new (p) T2(static_cast(msg)); break; + case T3::ID: ::new (p) T3(static_cast(msg)); break; + case T4::ID: ::new (p) T4(static_cast(msg)); break; + case T5::ID: ::new (p) T5(static_cast(msg)); break; + case T6::ID: ::new (p) T6(static_cast(msg)); break; + case T7::ID: ::new (p) T7(static_cast(msg)); break; + case T8::ID: ::new (p) T8(static_cast(msg)); break; + case T9::ID: ::new (p) T9(static_cast(msg)); break; + case T10::ID: ::new (p) T10(static_cast(msg)); break; + default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break; + } } + #endif + + typename etl::aligned_storage::type data; + bool valid; + }; + + //*************************************************************************** + // Specialisation for 9 message types. + //*************************************************************************** + template + class message_packet + { + public: + + //******************************************** + message_packet() + : valid(false) + { + } + + //******************************************** + explicit message_packet(const etl::imessage& msg) + : valid(true) + { + add_new_message(msg); + } + + #if ETL_CPP11_SUPPORTED + //******************************************** + explicit message_packet(etl::imessage&& msg) + : valid(true) + { + add_new_message(etl::move(msg)); + } + #endif + + //********************************************** + message_packet(const message_packet& other) + : valid(other.is_valid()) + { + if (valid) + { + add_new_message(other.get()); + } + } + + #if ETL_CPP11_SUPPORTED + //********************************************** + message_packet(message_packet&& other) + : valid(other.is_valid()) + { + if (valid) + { + add_new_message(etl::move(other.get())); + } + } + #endif + + //********************************************** + message_packet& operator =(const message_packet& rhs) + { + delete_current_message(); + valid = rhs.is_valid(); + if (valid) + { + add_new_message(rhs.get()); + } + + return *this; + } + + #if ETL_CPP11_SUPPORTED + //********************************************** + message_packet& operator =(message_packet&& rhs) + { + delete_current_message(); + valid = rhs.is_valid(); + if (valid) + { + add_new_message(etl::move(rhs.get())); + } + + return *this; + } + #endif //******************************************** ~message_packet() { - etl::imessage* pmsg = static_cast(data); - - #if defined(ETL_MESSAGES_ARE_VIRTUAL) || defined(ETL_POLYMORPHIC_MESSAGES) - pmsg->~imessage(); - #else - size_t id = pmsg->message_id; - - switch (id) - { - case T1::ID: static_cast(pmsg)->~T1(); break; - case T2::ID: static_cast(pmsg)->~T2(); break; - case T3::ID: static_cast(pmsg)->~T3(); break; - case T4::ID: static_cast(pmsg)->~T4(); break; - case T5::ID: static_cast(pmsg)->~T5(); break; - case T6::ID: static_cast(pmsg)->~T6(); break; - case T7::ID: static_cast(pmsg)->~T7(); break; - case T8::ID: static_cast(pmsg)->~T8(); break; - case T9::ID: static_cast(pmsg)->~T9(); break; - case T10::ID: static_cast(pmsg)->~T10(); break; - default: assert(false); break; - } - #endif + delete_current_message(); } //******************************************** @@ -792,39 +1590,53 @@ namespace etl return *static_cast(data); } + //******************************************** + bool is_valid() const + { + return valid; + } + enum { - SIZE = etl::largest::size, - ALIGNMENT = etl::largest::alignment + SIZE = etl::largest::size, + ALIGNMENT = etl::largest::alignment }; private: - typename etl::aligned_storage::type data; + //******************************************** + void delete_current_message() + { + if (valid) + { + etl::imessage* pmsg = static_cast(data); - message_packet(const message_packet&) ETL_DELETE; - message_packet& operator =(const message_packet&) ETL_DELETE; - #if ETL_CPP11_SUPPORTED - message_packet(message_packet&&) ETL_DELETE; - message_packet& operator =(message_packet&&) ETL_DELETE; - #endif - }; + #if defined(ETL_MESSAGES_ARE_VIRTUAL) || defined(ETL_POLYMORPHIC_MESSAGES) + pmsg->~imessage(); + #else + size_t id = pmsg->message_id; - //*************************************************************************** - // Specialisation for 9 message types. - //*************************************************************************** - template - class message_packet - { - public: + switch (id) + { + case T1::ID: static_cast(pmsg)->~T1(); break; + case T2::ID: static_cast(pmsg)->~T2(); break; + case T3::ID: static_cast(pmsg)->~T3(); break; + case T4::ID: static_cast(pmsg)->~T4(); break; + case T5::ID: static_cast(pmsg)->~T5(); break; + case T6::ID: static_cast(pmsg)->~T6(); break; + case T7::ID: static_cast(pmsg)->~T7(); break; + case T8::ID: static_cast(pmsg)->~T8(); break; + case T9::ID: static_cast(pmsg)->~T9(); break; + default: assert(false); break; + } + #endif + } + } //******************************************** - explicit message_packet(const etl::imessage& msg) + void add_new_message(const etl::imessage& msg) { const size_t id = msg.message_id; - void* p = data; switch (id) @@ -842,40 +1654,118 @@ namespace etl } } - //********************************************** - template - explicit message_packet(const T& msg) + #if ETL_CPP11_SUPPORTED + //******************************************** + void add_new_message(etl::imessage&& msg) { - ETL_STATIC_ASSERT((etl::is_one_of::value), "Unsupported type for this message packet"); - + const size_t id = msg.message_id; void* p = data; - ::new (p) T(static_cast(msg)); + + switch (id) + { + case T1::ID: ::new (p) T1(static_cast(msg)); break; + case T2::ID: ::new (p) T2(static_cast(msg)); break; + case T3::ID: ::new (p) T3(static_cast(msg)); break; + case T4::ID: ::new (p) T4(static_cast(msg)); break; + case T5::ID: ::new (p) T5(static_cast(msg)); break; + case T6::ID: ::new (p) T6(static_cast(msg)); break; + case T7::ID: ::new (p) T7(static_cast(msg)); break; + case T8::ID: ::new (p) T8(static_cast(msg)); break; + case T9::ID: ::new (p) T9(static_cast(msg)); break; + default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break; + } } + #endif + + typename etl::aligned_storage::type data; + bool valid; + }; + + //*************************************************************************** + // Specialisation for 8 message types. + //*************************************************************************** + template + class message_packet + { + public: + + //******************************************** + message_packet() + : valid(false) + { + } + + //******************************************** + explicit message_packet(const etl::imessage& msg) + : valid(true) + { + add_new_message(msg); + } + + #if ETL_CPP11_SUPPORTED + //******************************************** + explicit message_packet(etl::imessage&& msg) + : valid(true) + { + add_new_message(etl::move(msg)); + } + #endif + + //********************************************** + message_packet(const message_packet& other) + : valid(other.is_valid()) + { + if (valid) + { + add_new_message(other.get()); + } + } + + #if ETL_CPP11_SUPPORTED + //********************************************** + message_packet(message_packet&& other) + : valid(other.is_valid()) + { + if (valid) + { + add_new_message(etl::move(other.get())); + } + } + #endif + + //********************************************** + message_packet& operator =(const message_packet& rhs) + { + delete_current_message(); + valid = rhs.is_valid(); + if (valid) + { + add_new_message(rhs.get()); + } + + return *this; + } + + #if ETL_CPP11_SUPPORTED + //********************************************** + message_packet& operator =(message_packet&& rhs) + { + delete_current_message(); + valid = rhs.is_valid(); + if (valid) + { + add_new_message(etl::move(rhs.get())); + } + + return *this; + } + #endif //******************************************** ~message_packet() { - etl::imessage* pmsg = static_cast(data); - - #if defined(ETL_MESSAGES_ARE_VIRTUAL) || defined(ETL_POLYMORPHIC_MESSAGES) - pmsg->~imessage(); - #else - size_t id = pmsg->message_id; - - switch (id) - { - case T1::ID: static_cast(pmsg)->~T1(); break; - case T2::ID: static_cast(pmsg)->~T2(); break; - case T3::ID: static_cast(pmsg)->~T3(); break; - case T4::ID: static_cast(pmsg)->~T4(); break; - case T5::ID: static_cast(pmsg)->~T5(); break; - case T6::ID: static_cast(pmsg)->~T6(); break; - case T7::ID: static_cast(pmsg)->~T7(); break; - case T8::ID: static_cast(pmsg)->~T8(); break; - case T9::ID: static_cast(pmsg)->~T9(); break; - default: assert(false); break; - } - #endif + delete_current_message(); } //******************************************** @@ -890,38 +1780,52 @@ namespace etl return *static_cast(data); } + //******************************************** + bool is_valid() const + { + return valid; + } + enum { - SIZE = etl::largest::size, - ALIGNMENT = etl::largest::alignment + SIZE = etl::largest::size, + ALIGNMENT = etl::largest::alignment }; private: - typename etl::aligned_storage::type data; + //******************************************** + void delete_current_message() + { + if (valid) + { + etl::imessage* pmsg = static_cast(data); - message_packet(const message_packet&) ETL_DELETE; - message_packet& operator =(const message_packet&) ETL_DELETE; - #if ETL_CPP11_SUPPORTED - message_packet(message_packet&&) ETL_DELETE; - message_packet& operator =(message_packet&&) ETL_DELETE; - #endif - }; + #if defined(ETL_MESSAGES_ARE_VIRTUAL) || defined(ETL_POLYMORPHIC_MESSAGES) + pmsg->~imessage(); + #else + size_t id = pmsg->message_id; - //*************************************************************************** - // Specialisation for 8 message types. - //*************************************************************************** - template - class message_packet - { - public: + switch (id) + { + case T1::ID: static_cast(pmsg)->~T1(); break; + case T2::ID: static_cast(pmsg)->~T2(); break; + case T3::ID: static_cast(pmsg)->~T3(); break; + case T4::ID: static_cast(pmsg)->~T4(); break; + case T5::ID: static_cast(pmsg)->~T5(); break; + case T6::ID: static_cast(pmsg)->~T6(); break; + case T7::ID: static_cast(pmsg)->~T7(); break; + case T8::ID: static_cast(pmsg)->~T8(); break; + default: assert(false); break; + } + #endif + } + } //******************************************** - explicit message_packet(const etl::imessage& msg) + void add_new_message(const etl::imessage& msg) { const size_t id = msg.message_id; - void* p = data; switch (id) @@ -938,39 +1842,117 @@ namespace etl } } - //********************************************** - template - explicit message_packet(const T& msg) + #if ETL_CPP11_SUPPORTED + //******************************************** + void add_new_message(etl::imessage&& msg) { - ETL_STATIC_ASSERT((etl::is_one_of::value), "Unsupported type for this message packet"); - + const size_t id = msg.message_id; void* p = data; - ::new (p) T(static_cast(msg)); + + switch (id) + { + case T1::ID: ::new (p) T1(static_cast(msg)); break; + case T2::ID: ::new (p) T2(static_cast(msg)); break; + case T3::ID: ::new (p) T3(static_cast(msg)); break; + case T4::ID: ::new (p) T4(static_cast(msg)); break; + case T5::ID: ::new (p) T5(static_cast(msg)); break; + case T6::ID: ::new (p) T6(static_cast(msg)); break; + case T7::ID: ::new (p) T7(static_cast(msg)); break; + case T8::ID: ::new (p) T8(static_cast(msg)); break; + default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break; + } } + #endif + + typename etl::aligned_storage::type data; + bool valid; + }; + + //*************************************************************************** + // Specialisation for 7 message types. + //*************************************************************************** + template + class message_packet + { + public: + + //******************************************** + message_packet() + : valid(false) + { + } + + //******************************************** + explicit message_packet(const etl::imessage& msg) + : valid(true) + { + add_new_message(msg); + } + + #if ETL_CPP11_SUPPORTED + //******************************************** + explicit message_packet(etl::imessage&& msg) + : valid(true) + { + add_new_message(etl::move(msg)); + } + #endif + + //********************************************** + message_packet(const message_packet& other) + : valid(other.is_valid()) + { + if (valid) + { + add_new_message(other.get()); + } + } + + #if ETL_CPP11_SUPPORTED + //********************************************** + message_packet(message_packet&& other) + : valid(other.is_valid()) + { + if (valid) + { + add_new_message(etl::move(other.get())); + } + } + #endif + + //********************************************** + message_packet& operator =(const message_packet& rhs) + { + delete_current_message(); + valid = rhs.is_valid(); + if (valid) + { + add_new_message(rhs.get()); + } + + return *this; + } + + #if ETL_CPP11_SUPPORTED + //********************************************** + message_packet& operator =(message_packet&& rhs) + { + delete_current_message(); + valid = rhs.is_valid(); + if (valid) + { + add_new_message(etl::move(rhs.get())); + } + + return *this; + } + #endif //******************************************** ~message_packet() { - etl::imessage* pmsg = static_cast(data); - - #if defined(ETL_MESSAGES_ARE_VIRTUAL) || defined(ETL_POLYMORPHIC_MESSAGES) - pmsg->~imessage(); - #else - size_t id = pmsg->message_id; - - switch (id) - { - case T1::ID: static_cast(pmsg)->~T1(); break; - case T2::ID: static_cast(pmsg)->~T2(); break; - case T3::ID: static_cast(pmsg)->~T3(); break; - case T4::ID: static_cast(pmsg)->~T4(); break; - case T5::ID: static_cast(pmsg)->~T5(); break; - case T6::ID: static_cast(pmsg)->~T6(); break; - case T7::ID: static_cast(pmsg)->~T7(); break; - case T8::ID: static_cast(pmsg)->~T8(); break; - default: assert(false); break; - } - #endif + delete_current_message(); } //******************************************** @@ -985,38 +1967,51 @@ namespace etl return *static_cast(data); } + //******************************************** + bool is_valid() const + { + return valid; + } + enum { - SIZE = etl::largest::size, - ALIGNMENT = etl::largest::alignment + SIZE = etl::largest::size, + ALIGNMENT = etl::largest::alignment }; private: - typename etl::aligned_storage::type data; + //******************************************** + void delete_current_message() + { + if (valid) + { + etl::imessage* pmsg = static_cast(data); - message_packet(const message_packet&) ETL_DELETE; - message_packet& operator =(const message_packet&) ETL_DELETE; - #if ETL_CPP11_SUPPORTED - message_packet(message_packet&&) ETL_DELETE; - message_packet& operator =(message_packet&&) ETL_DELETE; - #endif - }; + #if defined(ETL_MESSAGES_ARE_VIRTUAL) || defined(ETL_POLYMORPHIC_MESSAGES) + pmsg->~imessage(); + #else + size_t id = pmsg->message_id; - //*************************************************************************** - // Specialisation for 7 message types. - //*************************************************************************** - template - class message_packet - { - public: + switch (id) + { + case T1::ID: static_cast(pmsg)->~T1(); break; + case T2::ID: static_cast(pmsg)->~T2(); break; + case T3::ID: static_cast(pmsg)->~T3(); break; + case T4::ID: static_cast(pmsg)->~T4(); break; + case T5::ID: static_cast(pmsg)->~T5(); break; + case T6::ID: static_cast(pmsg)->~T6(); break; + case T7::ID: static_cast(pmsg)->~T7(); break; + default: assert(false); break; + } + #endif + } + } //******************************************** - explicit message_packet(const etl::imessage& msg) + void add_new_message(const etl::imessage& msg) { const size_t id = msg.message_id; - void* p = data; switch (id) @@ -1032,38 +2027,116 @@ namespace etl } } - //********************************************** - template - explicit message_packet(const T& msg) + #if ETL_CPP11_SUPPORTED + //******************************************** + void add_new_message(etl::imessage&& msg) { - ETL_STATIC_ASSERT((etl::is_one_of::value), "Unsupported type for this message packet"); - + const size_t id = msg.message_id; void* p = data; - ::new (p) T(static_cast(msg)); + + switch (id) + { + case T1::ID: ::new (p) T1(static_cast(msg)); break; + case T2::ID: ::new (p) T2(static_cast(msg)); break; + case T3::ID: ::new (p) T3(static_cast(msg)); break; + case T4::ID: ::new (p) T4(static_cast(msg)); break; + case T5::ID: ::new (p) T5(static_cast(msg)); break; + case T6::ID: ::new (p) T6(static_cast(msg)); break; + case T7::ID: ::new (p) T7(static_cast(msg)); break; + default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break; + } } + #endif + + typename etl::aligned_storage::type data; + bool valid; + }; + + //*************************************************************************** + // Specialisation for 6 message types. + //*************************************************************************** + template + class message_packet + { + public: + + //******************************************** + message_packet() + : valid(false) + { + } + + //******************************************** + explicit message_packet(const etl::imessage& msg) + : valid(true) + { + add_new_message(msg); + } + + #if ETL_CPP11_SUPPORTED + //******************************************** + explicit message_packet(etl::imessage&& msg) + : valid(true) + { + add_new_message(etl::move(msg)); + } + #endif + + //********************************************** + message_packet(const message_packet& other) + : valid(other.is_valid()) + { + if (valid) + { + add_new_message(other.get()); + } + } + + #if ETL_CPP11_SUPPORTED + //********************************************** + message_packet(message_packet&& other) + : valid(other.is_valid()) + { + if (valid) + { + add_new_message(etl::move(other.get())); + } + } + #endif + + //********************************************** + message_packet& operator =(const message_packet& rhs) + { + delete_current_message(); + valid = rhs.is_valid(); + if (valid) + { + add_new_message(rhs.get()); + } + + return *this; + } + + #if ETL_CPP11_SUPPORTED + //********************************************** + message_packet& operator =(message_packet&& rhs) + { + delete_current_message(); + valid = rhs.is_valid(); + if (valid) + { + add_new_message(etl::move(rhs.get())); + } + + return *this; + } + #endif //******************************************** ~message_packet() { - etl::imessage* pmsg = static_cast(data); - - #if defined(ETL_MESSAGES_ARE_VIRTUAL) || defined(ETL_POLYMORPHIC_MESSAGES) - pmsg->~imessage(); - #else - size_t id = pmsg->message_id; - - switch (id) - { - case T1::ID: static_cast(pmsg)->~T1(); break; - case T2::ID: static_cast(pmsg)->~T2(); break; - case T3::ID: static_cast(pmsg)->~T3(); break; - case T4::ID: static_cast(pmsg)->~T4(); break; - case T5::ID: static_cast(pmsg)->~T5(); break; - case T6::ID: static_cast(pmsg)->~T6(); break; - case T7::ID: static_cast(pmsg)->~T7(); break; - default: assert(false); break; - } - #endif + delete_current_message(); } //******************************************** @@ -1078,38 +2151,50 @@ namespace etl return *static_cast(data); } + //******************************************** + bool is_valid() const + { + return valid; + } + enum { - SIZE = etl::largest::size, - ALIGNMENT = etl::largest::alignment + SIZE = etl::largest::size, + ALIGNMENT = etl::largest::alignment }; private: - typename etl::aligned_storage::type data; + //******************************************** + void delete_current_message() + { + if (valid) + { + etl::imessage* pmsg = static_cast(data); - message_packet(const message_packet&) ETL_DELETE; - message_packet& operator =(const message_packet&) ETL_DELETE; - #if ETL_CPP11_SUPPORTED - message_packet(message_packet&&) ETL_DELETE; - message_packet& operator =(message_packet&&) ETL_DELETE; - #endif - }; + #if defined(ETL_MESSAGES_ARE_VIRTUAL) || defined(ETL_POLYMORPHIC_MESSAGES) + pmsg->~imessage(); + #else + size_t id = pmsg->message_id; - //*************************************************************************** - // Specialisation for 6 message types. - //*************************************************************************** - template - class message_packet - { - public: + switch (id) + { + case T1::ID: static_cast(pmsg)->~T1(); break; + case T2::ID: static_cast(pmsg)->~T2(); break; + case T3::ID: static_cast(pmsg)->~T3(); break; + case T4::ID: static_cast(pmsg)->~T4(); break; + case T5::ID: static_cast(pmsg)->~T5(); break; + case T6::ID: static_cast(pmsg)->~T6(); break; + default: assert(false); break; + } + #endif + } + } //******************************************** - explicit message_packet(const etl::imessage& msg) + void add_new_message(const etl::imessage& msg) { const size_t id = msg.message_id; - void* p = data; switch (id) @@ -1124,37 +2209,115 @@ namespace etl } } - //********************************************** - template - explicit message_packet(const T& msg) + #if ETL_CPP11_SUPPORTED + //******************************************** + void add_new_message(etl::imessage&& msg) { - ETL_STATIC_ASSERT((etl::is_one_of::value), "Unsupported type for this message packet"); - + const size_t id = msg.message_id; void* p = data; - ::new (p) T(static_cast(msg)); + + switch (id) + { + case T1::ID: ::new (p) T1(static_cast(msg)); break; + case T2::ID: ::new (p) T2(static_cast(msg)); break; + case T3::ID: ::new (p) T3(static_cast(msg)); break; + case T4::ID: ::new (p) T4(static_cast(msg)); break; + case T5::ID: ::new (p) T5(static_cast(msg)); break; + case T6::ID: ::new (p) T6(static_cast(msg)); break; + default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break; + } } + #endif + + typename etl::aligned_storage::type data; + bool valid; + }; + + //*************************************************************************** + // Specialisation for 5 message types. + //*************************************************************************** + template + class message_packet + { + public: + + //******************************************** + message_packet() + : valid(false) + { + } + + //******************************************** + explicit message_packet(const etl::imessage& msg) + : valid(true) + { + add_new_message(msg); + } + + #if ETL_CPP11_SUPPORTED + //******************************************** + explicit message_packet(etl::imessage&& msg) + : valid(true) + { + add_new_message(etl::move(msg)); + } + #endif + + //********************************************** + message_packet(const message_packet& other) + : valid(other.is_valid()) + { + if (valid) + { + add_new_message(other.get()); + } + } + + #if ETL_CPP11_SUPPORTED + //********************************************** + message_packet(message_packet&& other) + : valid(other.is_valid()) + { + if (valid) + { + add_new_message(etl::move(other.get())); + } + } + #endif + + //********************************************** + message_packet& operator =(const message_packet& rhs) + { + delete_current_message(); + valid = rhs.is_valid(); + if (valid) + { + add_new_message(rhs.get()); + } + + return *this; + } + + #if ETL_CPP11_SUPPORTED + //********************************************** + message_packet& operator =(message_packet&& rhs) + { + delete_current_message(); + valid = rhs.is_valid(); + if (valid) + { + add_new_message(etl::move(rhs.get())); + } + + return *this; + } + #endif //******************************************** ~message_packet() { - etl::imessage* pmsg = static_cast(data); - - #if defined(ETL_MESSAGES_ARE_VIRTUAL) || defined(ETL_POLYMORPHIC_MESSAGES) - pmsg->~imessage(); - #else - size_t id = pmsg->message_id; - - switch (id) - { - case T1::ID: static_cast(pmsg)->~T1(); break; - case T2::ID: static_cast(pmsg)->~T2(); break; - case T3::ID: static_cast(pmsg)->~T3(); break; - case T4::ID: static_cast(pmsg)->~T4(); break; - case T5::ID: static_cast(pmsg)->~T5(); break; - case T6::ID: static_cast(pmsg)->~T6(); break; - default: assert(false); break; - } - #endif + delete_current_message(); } //******************************************** @@ -1169,38 +2332,49 @@ namespace etl return *static_cast(data); } + //******************************************** + bool is_valid() const + { + return valid; + } + enum { - SIZE = etl::largest::size, - ALIGNMENT = etl::largest::alignment + SIZE = etl::largest::size, + ALIGNMENT = etl::largest::alignment }; private: - typename etl::aligned_storage::type data; + //******************************************** + void delete_current_message() + { + if (valid) + { + etl::imessage* pmsg = static_cast(data); - message_packet(const message_packet&) ETL_DELETE; - message_packet& operator =(const message_packet&) ETL_DELETE; - #if ETL_CPP11_SUPPORTED - message_packet(message_packet&&) ETL_DELETE; - message_packet& operator =(message_packet&&) ETL_DELETE; - #endif - }; + #if defined(ETL_MESSAGES_ARE_VIRTUAL) || defined(ETL_POLYMORPHIC_MESSAGES) + pmsg->~imessage(); + #else + size_t id = pmsg->message_id; - //*************************************************************************** - // Specialisation for 5 message types. - //*************************************************************************** - template - class message_packet - { - public: + switch (id) + { + case T1::ID: static_cast(pmsg)->~T1(); break; + case T2::ID: static_cast(pmsg)->~T2(); break; + case T3::ID: static_cast(pmsg)->~T3(); break; + case T4::ID: static_cast(pmsg)->~T4(); break; + case T5::ID: static_cast(pmsg)->~T5(); break; + default: assert(false); break; + } + #endif + } + } //******************************************** - explicit message_packet(const etl::imessage& msg) + void add_new_message(const etl::imessage& msg) { const size_t id = msg.message_id; - void* p = data; switch (id) @@ -1214,36 +2388,113 @@ namespace etl } } - //********************************************** - template - explicit message_packet(const T& msg) + #if ETL_CPP11_SUPPORTED + //******************************************** + void add_new_message(etl::imessage&& msg) { - ETL_STATIC_ASSERT((etl::is_one_of::value), "Unsupported type for this message packet"); - + const size_t id = msg.message_id; void* p = data; - ::new (p) T(static_cast(msg)); + + switch (id) + { + case T1::ID: ::new (p) T1(static_cast(msg)); break; + case T2::ID: ::new (p) T2(static_cast(msg)); break; + case T3::ID: ::new (p) T3(static_cast(msg)); break; + case T4::ID: ::new (p) T4(static_cast(msg)); break; + case T5::ID: ::new (p) T5(static_cast(msg)); break; + default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break; + } } + #endif + + typename etl::aligned_storage::type data; + bool valid; + }; + + //*************************************************************************** + // Specialisation for 4 message types. + //*************************************************************************** + template + class message_packet + { + public: + + //******************************************** + message_packet() + : valid(false) + { + } + + //******************************************** + explicit message_packet(const etl::imessage& msg) + : valid(true) + { + add_new_message(msg); + } + + #if ETL_CPP11_SUPPORTED + //******************************************** + explicit message_packet(etl::imessage&& msg) + : valid(true) + { + add_new_message(etl::move(msg)); + } + #endif + + //********************************************** + message_packet(const message_packet& other) + : valid(other.is_valid()) + { + if (valid) + { + add_new_message(other.get()); + } + } + + #if ETL_CPP11_SUPPORTED + //********************************************** + message_packet(message_packet&& other) + : valid(other.is_valid()) + { + if (valid) + { + add_new_message(etl::move(other.get())); + } + } + #endif + + //********************************************** + message_packet& operator =(const message_packet& rhs) + { + delete_current_message(); + valid = rhs.is_valid(); + if (valid) + { + add_new_message(rhs.get()); + } + + return *this; + } + + #if ETL_CPP11_SUPPORTED + //********************************************** + message_packet& operator =(message_packet&& rhs) + { + delete_current_message(); + valid = rhs.is_valid(); + if (valid) + { + add_new_message(etl::move(rhs.get())); + } + + return *this; + } + #endif //******************************************** ~message_packet() { - etl::imessage* pmsg = static_cast(data); - - #if defined(ETL_MESSAGES_ARE_VIRTUAL) || defined(ETL_POLYMORPHIC_MESSAGES) - pmsg->~imessage(); - #else - size_t id = pmsg->message_id; - - switch (id) - { - case T1::ID: static_cast(pmsg)->~T1(); break; - case T2::ID: static_cast(pmsg)->~T2(); break; - case T3::ID: static_cast(pmsg)->~T3(); break; - case T4::ID: static_cast(pmsg)->~T4(); break; - case T5::ID: static_cast(pmsg)->~T5(); break; - default: assert(false); break; - } - #endif + delete_current_message(); } //******************************************** @@ -1258,37 +2509,48 @@ namespace etl return *static_cast(data); } + //******************************************** + bool is_valid() const + { + return valid; + } + enum { - SIZE = etl::largest::size, - ALIGNMENT = etl::largest::alignment + SIZE = etl::largest::size, + ALIGNMENT = etl::largest::alignment }; private: - typename etl::aligned_storage::type data; + //******************************************** + void delete_current_message() + { + if (valid) + { + etl::imessage* pmsg = static_cast(data); - message_packet(const message_packet&) ETL_DELETE; - message_packet& operator =(const message_packet&) ETL_DELETE; - #if ETL_CPP11_SUPPORTED - message_packet(message_packet&&) ETL_DELETE; - message_packet& operator =(message_packet&&) ETL_DELETE; - #endif - }; + #if defined(ETL_MESSAGES_ARE_VIRTUAL) || defined(ETL_POLYMORPHIC_MESSAGES) + pmsg->~imessage(); + #else + size_t id = pmsg->message_id; - //*************************************************************************** - // Specialisation for 4 message types. - //*************************************************************************** - template - class message_packet - { - public: + switch (id) + { + case T1::ID: static_cast(pmsg)->~T1(); break; + case T2::ID: static_cast(pmsg)->~T2(); break; + case T3::ID: static_cast(pmsg)->~T3(); break; + case T4::ID: static_cast(pmsg)->~T4(); break; + default: assert(false); break; + } + #endif + } + } //******************************************** - explicit message_packet(const etl::imessage& msg) + void add_new_message(const etl::imessage& msg) { const size_t id = msg.message_id; - void* p = data; switch (id) @@ -1301,65 +2563,26 @@ namespace etl } } - //********************************************** - template - explicit message_packet(const T& msg) - { - ETL_STATIC_ASSERT((etl::is_one_of::value), "Unsupported type for this message packet"); - - void* p = data; - ::new (p) T(static_cast(msg)); - } - + #if ETL_CPP11_SUPPORTED //******************************************** - ~message_packet() + void add_new_message(etl::imessage&& msg) { - etl::imessage* pmsg = static_cast(data); - - #if defined(ETL_MESSAGES_ARE_VIRTUAL) || defined(ETL_POLYMORPHIC_MESSAGES) - pmsg->~imessage(); - #else - size_t id = pmsg->message_id; + const size_t id = msg.message_id; + void* p = data; switch (id) { - case T1::ID: static_cast(pmsg)->~T1(); break; - case T2::ID: static_cast(pmsg)->~T2(); break; - case T3::ID: static_cast(pmsg)->~T3(); break; - case T4::ID: static_cast(pmsg)->~T4(); break; - default: assert(false); break; + case T1::ID: ::new (p) T1(static_cast(msg)); break; + case T2::ID: ::new (p) T2(static_cast(msg)); break; + case T3::ID: ::new (p) T3(static_cast(msg)); break; + case T4::ID: ::new (p) T4(static_cast(msg)); break; + default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break; } + } #endif - } - - //******************************************** - etl::imessage& get() ETL_NOEXCEPT - { - return *static_cast(data); - } - - //******************************************** - const etl::imessage& get() const ETL_NOEXCEPT - { - return *static_cast(data); - } - - enum - { - SIZE = etl::largest::size, - ALIGNMENT = etl::largest::alignment - }; - - private: typename etl::aligned_storage::type data; - - message_packet(const message_packet&) ETL_DELETE; - message_packet& operator =(const message_packet&) ETL_DELETE; - #if ETL_CPP11_SUPPORTED - message_packet(message_packet&&) ETL_DELETE; - message_packet& operator =(message_packet&&) ETL_DELETE; - #endif + bool valid; }; //*************************************************************************** @@ -1370,11 +2593,137 @@ namespace etl { public: + //******************************************** + message_packet() + : valid(false) + { + } + //******************************************** explicit message_packet(const etl::imessage& msg) + : valid(true) + { + add_new_message(msg); + } + + #if ETL_CPP11_SUPPORTED + //******************************************** + explicit message_packet(etl::imessage&& msg) + : valid(true) + { + add_new_message(etl::move(msg)); + } + #endif + + //********************************************** + message_packet(const message_packet& other) + : valid(other.is_valid()) + { + if (valid) + { + add_new_message(other.get()); + } + } + + #if ETL_CPP11_SUPPORTED + //********************************************** + message_packet(message_packet&& other) + : valid(other.is_valid()) + { + if (valid) + { + add_new_message(etl::move(other.get())); + } + } + #endif + + //********************************************** + message_packet& operator =(const message_packet& rhs) + { + delete_current_message(); + valid = rhs.is_valid(); + if (valid) + { + add_new_message(rhs.get()); + } + + return *this; + } + + #if ETL_CPP11_SUPPORTED + //********************************************** + message_packet& operator =(message_packet&& rhs) + { + delete_current_message(); + valid = rhs.is_valid(); + if (valid) + { + add_new_message(etl::move(rhs.get())); + } + + return *this; + } + #endif + + //******************************************** + ~message_packet() + { + delete_current_message(); + } + + //******************************************** + etl::imessage& get() ETL_NOEXCEPT + { + return *static_cast(data); + } + + //******************************************** + const etl::imessage& get() const ETL_NOEXCEPT + { + return *static_cast(data); + } + + //******************************************** + bool is_valid() const + { + return valid; + } + + enum + { + SIZE = etl::largest::size, + ALIGNMENT = etl::largest::alignment + }; + + private: + + //******************************************** + void delete_current_message() + { + if (valid) + { + etl::imessage* pmsg = static_cast(data); + + #if defined(ETL_MESSAGES_ARE_VIRTUAL) || defined(ETL_POLYMORPHIC_MESSAGES) + pmsg->~imessage(); + #else + size_t id = pmsg->message_id; + + switch (id) + { + case T1::ID: static_cast(pmsg)->~T1(); break; + case T2::ID: static_cast(pmsg)->~T2(); break; + case T3::ID: static_cast(pmsg)->~T3(); break; + default: assert(false); break; + } + #endif + } + } + + //******************************************** + void add_new_message(const etl::imessage& msg) { const size_t id = msg.message_id; - void* p = data; switch (id) @@ -1386,64 +2735,25 @@ namespace etl } } - //********************************************** - template - explicit message_packet(const T& msg) - { - ETL_STATIC_ASSERT((etl::is_one_of::value), "Unsupported type for this message packet"); - - void* p = data; - ::new (p) T(static_cast(msg)); - } - + #if ETL_CPP11_SUPPORTED //******************************************** - ~message_packet() + void add_new_message(etl::imessage&& msg) { - etl::imessage* pmsg = static_cast(data); - - #if defined(ETL_MESSAGES_ARE_VIRTUAL) || defined(ETL_POLYMORPHIC_MESSAGES) - pmsg->~imessage(); - #else - size_t id = pmsg->message_id; + const size_t id = msg.message_id; + void* p = data; switch (id) { - case T1::ID: static_cast(pmsg)->~T1(); break; - case T2::ID: static_cast(pmsg)->~T2(); break; - case T3::ID: static_cast(pmsg)->~T3(); break; - default: assert(false); break; + case T1::ID: ::new (p) T1(static_cast(msg)); break; + case T2::ID: ::new (p) T2(static_cast(msg)); break; + case T3::ID: ::new (p) T3(static_cast(msg)); break; + default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break; } + } #endif - } - - //******************************************** - etl::imessage& get() ETL_NOEXCEPT - { - return *static_cast(data); - } - - //******************************************** - const etl::imessage& get() const ETL_NOEXCEPT - { - return *static_cast(data); - } - - enum - { - SIZE = etl::largest::size, - ALIGNMENT = etl::largest::alignment - }; - - private: typename etl::aligned_storage::type data; - - message_packet(const message_packet&) ETL_DELETE; - message_packet& operator =(const message_packet&) ETL_DELETE; - #if ETL_CPP11_SUPPORTED - message_packet(message_packet&&) ETL_DELETE; - message_packet& operator =(message_packet&&) ETL_DELETE; - #endif + bool valid; }; //*************************************************************************** @@ -1455,47 +2765,81 @@ namespace etl public: //******************************************** - explicit message_packet(const etl::imessage& msg) + message_packet() + : valid(false) { - const size_t id = msg.message_id; + } - void* p = data; + //******************************************** + explicit message_packet(const etl::imessage& msg) + : valid(true) + { + add_new_message(msg); + } - switch (id) + #if ETL_CPP11_SUPPORTED + //******************************************** + explicit message_packet(etl::imessage&& msg) + : valid(true) + { + add_new_message(etl::move(msg)); + } + #endif + + //********************************************** + message_packet(const message_packet& other) + : valid(other.is_valid()) + { + if (valid) { - case T1::ID: ::new (p) T1(static_cast(msg)); break; - case T2::ID: ::new (p) T2(static_cast(msg)); break; - default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break; + add_new_message(other.get()); } } + #if ETL_CPP11_SUPPORTED //********************************************** - template - explicit message_packet(const T& msg) + message_packet(message_packet&& other) + : valid(other.is_valid()) { - ETL_STATIC_ASSERT((etl::is_one_of::value), "Unsupported type for this message packet"); - - void* p = data; - ::new (p) T(static_cast(msg)); + if (valid) + { + add_new_message(etl::move(other.get())); + } } + #endif + + //********************************************** + message_packet& operator =(const message_packet& rhs) + { + delete_current_message(); + valid = rhs.is_valid(); + if (valid) + { + add_new_message(rhs.get()); + } + + return *this; + } + + #if ETL_CPP11_SUPPORTED + //********************************************** + message_packet& operator =(message_packet&& rhs) + { + delete_current_message(); + valid = rhs.is_valid(); + if (valid) + { + add_new_message(etl::move(rhs.get())); + } + + return *this; + } + #endif //******************************************** ~message_packet() { - etl::imessage* pmsg = static_cast(data); - - #if defined(ETL_MESSAGES_ARE_VIRTUAL) || defined(ETL_POLYMORPHIC_MESSAGES) - pmsg->~imessage(); - #else - size_t id = pmsg->message_id; - - switch (id) - { - case T1::ID: static_cast(pmsg)->~T1(); break; - case T2::ID: static_cast(pmsg)->~T2(); break; - default: assert(false); break; - } - #endif + delete_current_message(); } //******************************************** @@ -1510,6 +2854,12 @@ namespace etl return *static_cast(data); } + //******************************************** + bool is_valid() const + { + return valid; + } + enum { SIZE = etl::largest::size, @@ -1518,14 +2868,60 @@ namespace etl private: - typename etl::aligned_storage::type data; + //******************************************** + void delete_current_message() + { + if (valid) + { + etl::imessage* pmsg = static_cast(data); + + #if defined(ETL_MESSAGES_ARE_VIRTUAL) || defined(ETL_POLYMORPHIC_MESSAGES) + pmsg->~imessage(); + #else + size_t id = pmsg->message_id; + + switch (id) + { + case T1::ID: static_cast(pmsg)->~T1(); break; + case T2::ID: static_cast(pmsg)->~T2(); break; + default: assert(false); break; + } + #endif + } + } + + //******************************************** + void add_new_message(const etl::imessage& msg) + { + const size_t id = msg.message_id; + void* p = data; + + switch (id) + { + case T1::ID: ::new (p) T1(static_cast(msg)); break; + case T2::ID: ::new (p) T2(static_cast(msg)); break; + default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break; + } + } - message_packet(const message_packet&) ETL_DELETE; - message_packet& operator =(const message_packet&) ETL_DELETE; #if ETL_CPP11_SUPPORTED - message_packet(message_packet&&) ETL_DELETE; - message_packet& operator =(message_packet&&) ETL_DELETE; + //******************************************** + void add_new_message(etl::imessage&& msg) + { + const size_t id = msg.message_id; + void* p = data; + + switch (id) + { + case T1::ID: ::new (p) T1(static_cast(msg)); break; + case T2::ID: ::new (p) T2(static_cast(msg)); break; + default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break; + } + } #endif + + typename etl::aligned_storage::type data; + bool valid; }; //*************************************************************************** @@ -1537,45 +2933,81 @@ namespace etl public: //******************************************** - explicit message_packet(const etl::imessage& msg) + message_packet() + : valid(false) { - const size_t id = msg.message_id; + } - void* p = data; + //******************************************** + explicit message_packet(const etl::imessage& msg) + : valid(true) + { + add_new_message(msg); + } - switch (id) + #if ETL_CPP11_SUPPORTED + //******************************************** + explicit message_packet(etl::imessage&& msg) + : valid(true) + { + add_new_message(etl::move(msg)); + } + #endif + + //********************************************** + message_packet(const message_packet& other) + : valid(other.is_valid()) + { + if (valid) { - case T1::ID: ::new (p) T1(static_cast(msg)); break; - default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break; + add_new_message(other.get()); } } + #if ETL_CPP11_SUPPORTED //********************************************** - template - explicit message_packet(const T& msg) + message_packet(message_packet&& other) + : valid(other.is_valid()) { - ETL_STATIC_ASSERT((etl::is_one_of::value), "Unsupported type for this message packet"); - - void* p = data; - ::new (p) T(static_cast(msg)); + if (valid) + { + add_new_message(etl::move(other.get())); + } } + #endif + + //********************************************** + message_packet& operator =(const message_packet& rhs) + { + delete_current_message(); + valid = rhs.is_valid(); + if (valid) + { + add_new_message(rhs.get()); + } + + return *this; + } + + #if ETL_CPP11_SUPPORTED + //********************************************** + message_packet& operator =(message_packet&& rhs) + { + delete_current_message(); + valid = rhs.is_valid(); + if (valid) + { + add_new_message(etl::move(rhs.get())); + } + + return *this; + } + #endif //******************************************** ~message_packet() { - etl::imessage* pmsg = static_cast(data); - - #if defined(ETL_MESSAGES_ARE_VIRTUAL) || defined(ETL_POLYMORPHIC_MESSAGES) - pmsg->~imessage(); - #else - size_t id = pmsg->message_id; - - switch (id) - { - case T1::ID: static_cast(pmsg)->~T1(); break; - default: assert(false); break; - } - #endif + delete_current_message(); } //******************************************** @@ -1590,6 +3022,12 @@ namespace etl return *static_cast(data); } + //******************************************** + bool is_valid() const + { + return valid; + } + enum { SIZE = etl::largest::size, @@ -1598,14 +3036,57 @@ namespace etl private: - typename etl::aligned_storage::type data; + //******************************************** + void delete_current_message() + { + if (valid) + { + etl::imessage* pmsg = static_cast(data); + + #if defined(ETL_MESSAGES_ARE_VIRTUAL) || defined(ETL_POLYMORPHIC_MESSAGES) + pmsg->~imessage(); + #else + size_t id = pmsg->message_id; + + switch (id) + { + case T1::ID: static_cast(pmsg)->~T1(); break; + default: assert(false); break; + } + #endif + } + } + + //******************************************** + void add_new_message(const etl::imessage& msg) + { + const size_t id = msg.message_id; + void* p = data; + + switch (id) + { + case T1::ID: ::new (p) T1(static_cast(msg)); break; + default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break; + } + } - message_packet(const message_packet&) ETL_DELETE; - message_packet& operator =(const message_packet&) ETL_DELETE; #if ETL_CPP11_SUPPORTED - message_packet(message_packet&&) ETL_DELETE; - message_packet& operator =(message_packet&&) ETL_DELETE; + //******************************************** + void add_new_message(etl::imessage&& msg) + { + const size_t id = msg.message_id; + void* p = data; + + switch (id) + { + case T1::ID: ::new (p) T1(static_cast(msg)); break; + default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break; + } + } #endif + + typename etl::aligned_storage::type data; + bool valid; }; } diff --git a/include/etl/message_packet_generator.h b/include/etl/message_packet_generator.h index 43a292de..9aa923e1 100644 --- a/include/etl/message_packet_generator.h +++ b/include/etl/message_packet_generator.h @@ -68,6 +68,7 @@ cog.outl("//******************************************************************** #include "static_assert.h" #include "largest.h" #include "alignment.h" +#include "utility.h" #include @@ -97,52 +98,81 @@ namespace etl cog.outl("public:") cog.outl("") cog.outl(" //********************************************") - cog.outl(" explicit message_packet(const etl::imessage& msg)") + cog.outl(" message_packet()") + cog.outl(" : valid(false)") cog.outl(" {") - cog.outl(" const size_t id = msg.message_id;") + cog.outl(" }") cog.outl("") - cog.outl(" void* p = data;") + cog.outl(" //********************************************") + cog.outl(" explicit message_packet(const etl::imessage& msg)") + cog.outl(" : valid(true)") + cog.outl(" {") + cog.outl(" add_new_message(msg);") + cog.outl(" }") cog.outl("") - cog.outl(" switch (id)") + cog.outl("#if ETL_CPP11_SUPPORTED") + cog.outl(" //********************************************") + cog.outl(" explicit message_packet(etl::imessage&& msg)") + cog.outl(" : valid(true)") + cog.outl(" {") + cog.outl(" add_new_message(etl::move(msg));") + cog.outl(" }") + cog.outl("#endif") + cog.outl("") + cog.outl(" //**********************************************") + cog.outl(" message_packet(const message_packet& other)") + cog.outl(" : valid(other.is_valid())") + cog.outl(" {") + cog.outl(" if (valid)") cog.outl(" {") - for n in range(1, int(Handlers) + 1): - cog.out(" case T%d::ID:" %n) - cog.out(" ::new (p) T%d(static_cast(msg));" % (n, n)) - cog.outl(" break;") - cog.outl(" default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break;") + cog.outl(" add_new_message(other.get());") cog.outl(" }") cog.outl(" }") cog.outl("") + cog.outl("#if ETL_CPP11_SUPPORTED") cog.outl(" //**********************************************") - cog.outl(" template ") - cog.outl(" explicit message_packet(const T& msg)") + cog.outl(" message_packet(message_packet&& other)") + cog.outl(" : valid(other.is_valid())") cog.outl(" {") - cog.out(" ETL_STATIC_ASSERT((etl::is_one_of::value), \"Unsupported type for this message packet\");" % int(Handlers)) - cog.outl("") - cog.outl(" void* p = data;") - cog.outl(" ::new (p) T(static_cast(msg));") + cog.outl(" if (valid)") + cog.outl(" {") + cog.outl(" add_new_message(etl::move(other.get()));") + cog.outl(" }") cog.outl(" }") + cog.outl("#endif") + cog.outl("") + cog.outl(" //**********************************************") + cog.outl(" message_packet& operator =(const message_packet& rhs)") + cog.outl(" {") + cog.outl(" delete_current_message();") + cog.outl(" valid = rhs.is_valid();") + cog.outl(" if (valid)") + cog.outl(" {") + cog.outl(" add_new_message(rhs.get());") + cog.outl(" }") + cog.outl("") + cog.outl(" return *this;") + cog.outl(" }") + cog.outl("") + cog.outl("#if ETL_CPP11_SUPPORTED") + cog.outl(" //**********************************************") + cog.outl(" message_packet& operator =(message_packet&& rhs)") + cog.outl(" {") + cog.outl(" delete_current_message();") + cog.outl(" valid = rhs.is_valid();") + cog.outl(" if (valid)") + cog.outl(" {") + cog.outl(" add_new_message(etl::move(rhs.get()));") + cog.outl(" }") + cog.outl("") + cog.outl(" return *this;") + cog.outl(" }") + cog.outl("#endif") cog.outl("") cog.outl(" //********************************************") cog.outl(" ~message_packet()") cog.outl(" {") - cog.outl(" etl::imessage* pmsg = static_cast(data);") - cog.outl("") - cog.outl("#if defined(ETL_MESSAGES_ARE_VIRTUAL) || defined(ETL_POLYMORPHIC_MESSAGES)") - cog.outl(" pmsg->~imessage();") - cog.outl("#else") - cog.outl(" size_t id = pmsg->message_id;") - cog.outl("") - cog.outl(" switch (id)") - cog.outl(" {") - for n in range(1, int(Handlers) + 1): - cog.outl(" case T%s::ID: static_cast(pmsg)->~T%s(); break;" % (n, n, n)) - cog.outl(" default: assert(false); break;") - cog.outl(" }") - cog.outl("#endif") + cog.outl(" delete_current_message();") cog.outl(" }") cog.outl("") cog.outl(" //********************************************") @@ -157,6 +187,12 @@ namespace etl cog.outl(" return *static_cast(data);") cog.outl(" }") cog.outl("") + cog.outl(" //********************************************") + cog.outl(" bool is_valid() const") + cog.outl(" {") + cog.outl(" return valid;") + cog.outl(" }") + cog.outl("") cog.outl(" enum") cog.outl(" {") cog.out(" SIZE = etl::largest<") @@ -171,14 +207,60 @@ namespace etl cog.outl("") cog.outl("private:") cog.outl("") - cog.outl(" typename etl::aligned_storage::type data;") + cog.outl(" //********************************************") + cog.outl(" void delete_current_message()") + cog.outl(" {") + cog.outl(" if (valid)") + cog.outl(" {") + cog.outl(" etl::imessage* pmsg = static_cast(data);") + cog.outl("") + cog.outl("#if defined(ETL_MESSAGES_ARE_VIRTUAL) || defined(ETL_POLYMORPHIC_MESSAGES)") + cog.outl(" pmsg->~imessage();") + cog.outl("#else") + cog.outl(" size_t id = pmsg->message_id;") + cog.outl("") + cog.outl(" switch (id)") + cog.outl(" {") + for n in range(1, int(Handlers) + 1): + cog.outl(" case T%s::ID: static_cast(pmsg)->~T%s(); break;" % (n, n, n)) + cog.outl(" default: assert(false); break;") + cog.outl(" }") + cog.outl(" #endif") + cog.outl(" }") + cog.outl(" }") + cog.outl("") + cog.outl(" //********************************************") + cog.outl(" void add_new_message(const etl::imessage& msg)") + cog.outl(" {") + cog.outl(" const size_t id = msg.message_id;") + cog.outl(" void* p = data;") + cog.outl("") + cog.outl(" switch (id)") + cog.outl(" {") + for n in range(1, int(Handlers) + 1): + cog.outl(" case T%d::ID: ::new (p) T%d(static_cast(msg)); break;" %(n, n, n)) + cog.outl(" default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break;") + cog.outl(" }") + cog.outl(" }") cog.outl("") - cog.outl(" message_packet(const message_packet&) ETL_DELETE;") - cog.outl(" message_packet& operator =(const message_packet&) ETL_DELETE;") cog.outl("#if ETL_CPP11_SUPPORTED") - cog.outl(" message_packet(message_packet&&) ETL_DELETE;") - cog.outl(" message_packet& operator =(message_packet&&) ETL_DELETE;") + cog.outl(" //********************************************") + cog.outl(" void add_new_message(etl::imessage&& msg)") + cog.outl(" {") + cog.outl(" const size_t id = msg.message_id;") + cog.outl(" void* p = data;") + cog.outl("") + cog.outl(" switch (id)") + cog.outl(" {") + for n in range(1, int(Handlers) + 1): + cog.outl(" case T%d::ID: ::new (p) T%d(static_cast(msg)); break;" %(n, n, n)) + cog.outl(" default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break;") + cog.outl(" }") + cog.outl(" }") cog.outl("#endif") + cog.outl("") + cog.outl(" typename etl::aligned_storage::type data;") + cog.outl(" bool valid;") cog.outl("};") #################################### @@ -215,54 +297,81 @@ namespace etl cog.outl("public:") cog.outl("") cog.outl(" //********************************************") - cog.outl(" explicit message_packet(const etl::imessage& msg)") + cog.outl(" message_packet()") + cog.outl(" : valid(false)") cog.outl(" {") - cog.outl(" const size_t id = msg.message_id;") + cog.outl(" }") cog.outl("") - cog.outl(" void* p = data;") + cog.outl(" //********************************************") + cog.outl(" explicit message_packet(const etl::imessage& msg)") + cog.outl(" : valid(true)") + cog.outl(" {") + cog.outl(" add_new_message(msg);") + cog.outl(" }") cog.outl("") - cog.outl(" switch (id)") + cog.outl("#if ETL_CPP11_SUPPORTED") + cog.outl(" //********************************************") + cog.outl(" explicit message_packet(etl::imessage&& msg)") + cog.outl(" : valid(true)") + cog.outl(" {") + cog.outl(" add_new_message(etl::move(msg));") + cog.outl(" }") + cog.outl("#endif") + cog.outl("") + cog.outl(" //**********************************************") + cog.outl(" message_packet(const message_packet& other)") + cog.outl(" : valid(other.is_valid())") + cog.outl(" {") + cog.outl(" if (valid)") cog.outl(" {") - for t in range(1, n + 1): - cog.out(" case T%d::ID:" %t) - cog.out(" ::new (p) T%d(static_cast(msg));" % (t, t)) - cog.outl(" break;") - cog.outl(" default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break;") + cog.outl(" add_new_message(other.get());") cog.outl(" }") cog.outl(" }") cog.outl("") - + cog.outl("#if ETL_CPP11_SUPPORTED") cog.outl(" //**********************************************") - cog.outl(" template ") - cog.outl(" explicit message_packet(const T& msg)") + cog.outl(" message_packet(message_packet&& other)") + cog.outl(" : valid(other.is_valid())") cog.outl(" {") - cog.out(" ETL_STATIC_ASSERT((etl::is_one_of::value), \"Unsupported type for this message packet\");" % n) + cog.outl(" if (valid)") + cog.outl(" {") + cog.outl(" add_new_message(etl::move(other.get()));") + cog.outl(" }") + cog.outl(" }") + cog.outl("#endif") cog.outl("") - cog.outl(" void* p = data;") - cog.outl(" ::new (p) T(static_cast(msg));") + cog.outl(" //**********************************************") + cog.outl(" message_packet& operator =(const message_packet& rhs)") + cog.outl(" {") + cog.outl(" delete_current_message();") + cog.outl(" valid = rhs.is_valid();") + cog.outl(" if (valid)") + cog.outl(" {") + cog.outl(" add_new_message(rhs.get());") + cog.outl(" }") + cog.outl("") + cog.outl(" return *this;") cog.outl(" }") cog.outl("") - + cog.outl("#if ETL_CPP11_SUPPORTED") + cog.outl(" //**********************************************") + cog.outl(" message_packet& operator =(message_packet&& rhs)") + cog.outl(" {") + cog.outl(" delete_current_message();") + cog.outl(" valid = rhs.is_valid();") + cog.outl(" if (valid)") + cog.outl(" {") + cog.outl(" add_new_message(etl::move(rhs.get()));") + cog.outl(" }") + cog.outl("") + cog.outl(" return *this;") + cog.outl(" }") + cog.outl("#endif") + cog.outl("") cog.outl(" //********************************************") cog.outl(" ~message_packet()") cog.outl(" {") - cog.outl(" etl::imessage* pmsg = static_cast(data);") - cog.outl("") - cog.outl("#if defined(ETL_MESSAGES_ARE_VIRTUAL) || defined(ETL_POLYMORPHIC_MESSAGES)") - cog.outl(" pmsg->~imessage();") - cog.outl("#else") - cog.outl(" size_t id = pmsg->message_id;") - cog.outl("") - cog.outl(" switch (id)") - cog.outl(" {") - for t in range(1, n + 1): - cog.outl(" case T%s::ID: static_cast(pmsg)->~T%s(); break;" % (t, t, t)) - cog.outl(" default: assert(false); break;") - cog.outl(" }") - cog.outl("#endif") + cog.outl(" delete_current_message();") cog.outl(" }") cog.outl("") cog.outl(" //********************************************") @@ -277,6 +386,12 @@ namespace etl cog.outl(" return *static_cast(data);") cog.outl(" }") cog.outl("") + cog.outl(" //********************************************") + cog.outl(" bool is_valid() const") + cog.outl(" {") + cog.outl(" return valid;") + cog.outl(" }") + cog.outl("") cog.outl(" enum") cog.outl(" {") cog.out(" SIZE = etl::largest<") @@ -291,14 +406,60 @@ namespace etl cog.outl("") cog.outl("private:") cog.outl("") - cog.outl(" typename etl::aligned_storage::type data;") + cog.outl(" //********************************************") + cog.outl(" void delete_current_message()") + cog.outl(" {") + cog.outl(" if (valid)") + cog.outl(" {") + cog.outl(" etl::imessage* pmsg = static_cast(data);") + cog.outl("") + cog.outl("#if defined(ETL_MESSAGES_ARE_VIRTUAL) || defined(ETL_POLYMORPHIC_MESSAGES)") + cog.outl(" pmsg->~imessage();") + cog.outl("#else") + cog.outl(" size_t id = pmsg->message_id;") + cog.outl("") + cog.outl(" switch (id)") + cog.outl(" {") + for t in range(1, n + 1): + cog.outl(" case T%s::ID: static_cast(pmsg)->~T%s(); break;" % (t, t, t)) + cog.outl(" default: assert(false); break;") + cog.outl(" }") + cog.outl(" #endif") + cog.outl(" }") + cog.outl(" }") + cog.outl("") + cog.outl(" //********************************************") + cog.outl(" void add_new_message(const etl::imessage& msg)") + cog.outl(" {") + cog.outl(" const size_t id = msg.message_id;") + cog.outl(" void* p = data;") + cog.outl("") + cog.outl(" switch (id)") + cog.outl(" {") + for t in range(1, n + 1): + cog.outl(" case T%d::ID: ::new (p) T%d(static_cast(msg)); break;" %(t, t, t)) + cog.outl(" default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break;") + cog.outl(" }") + cog.outl(" }") cog.outl("") - cog.outl(" message_packet(const message_packet&) ETL_DELETE;") - cog.outl(" message_packet& operator =(const message_packet&) ETL_DELETE;") cog.outl("#if ETL_CPP11_SUPPORTED") - cog.outl(" message_packet(message_packet&&) ETL_DELETE;") - cog.outl(" message_packet& operator =(message_packet&&) ETL_DELETE;") + cog.outl(" //********************************************") + cog.outl(" void add_new_message(etl::imessage&& msg)") + cog.outl(" {") + cog.outl(" const size_t id = msg.message_id;") + cog.outl(" void* p = data;") + cog.outl("") + cog.outl(" switch (id)") + cog.outl(" {") + for t in range(1, n + 1): + cog.outl(" case T%d::ID: ::new (p) T%d(static_cast(msg)); break;" %(t, t, t)) + cog.outl(" default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break;") + cog.outl(" }") + cog.outl(" }") cog.outl("#endif") + cog.outl("") + cog.outl(" typename etl::aligned_storage::type data;") + cog.outl(" bool valid;") cog.outl("};") ]]]*/ /*[[[end]]]*/ diff --git a/include/etl/version.h b/include/etl/version.h index 1f81bd46..5208254f 100644 --- a/include/etl/version.h +++ b/include/etl/version.h @@ -38,8 +38,8 @@ SOFTWARE. ///\ingroup utilities #define ETL_VERSION_MAJOR 17 -#define ETL_VERSION_MINOR 4 -#define ETL_VERSION_PATCH 3 +#define ETL_VERSION_MINOR 5 +#define ETL_VERSION_PATCH 0 #define ETL_VERSION ETL_STRINGIFY(ETL_VERSION_MAJOR) "." ETL_STRINGIFY(ETL_VERSION_MINOR) "." ETL_STRINGIFY(ETL_VERSION_PATCH) #define ETL_VERSION_W ETL_STRINGIFY(ETL_VERSION_MAJOR) L"." ETL_STRINGIFY(ETL_VERSION_MINOR) L"." ETL_STRINGIFY(ETL_VERSION_PATCH) #define ETL_VERSION_U16 ETL_STRINGIFY(ETL_VERSION_MAJOR) u"." ETL_STRINGIFY(ETL_VERSION_MINOR) u"." ETL_STRINGIFY(ETL_VERSION_PATCH) diff --git a/library.json b/library.json index b254c5d9..afd56863 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "Embedded Template Library", - "version": "17.4.3", + "version": "17.5.0", "authors": { "name": "John Wellbelove", "email": "john.wellbelove@etlcpp.com" diff --git a/library.properties b/library.properties index 913c1fa3..a4a1a566 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=Embedded Template Library -version=17.4.3 +version=17.5.0 author= John Wellbelove maintainer=John Wellbelove license=MIT diff --git a/support/Release notes.txt b/support/Release notes.txt index 0178f01c..b3592907 100644 --- a/support/Release notes.txt +++ b/support/Release notes.txt @@ -1,3 +1,8 @@ +=============================================================================== +17.5.0 +Modified etl::message_packet to allow default construction, copy/move construction +and copy/move assignment. + =============================================================================== 17.4.3 Changed local 'work' variables from uint_least8_t to uint32_t to avoid possible overflow. diff --git a/test/test_message_packet.cpp b/test/test_message_packet.cpp index a107098a..dfe22655 100644 --- a/test/test_message_packet.cpp +++ b/test/test_message_packet.cpp @@ -50,30 +50,126 @@ namespace { Message1(int x_) : x(x_) + , moved(false) + , copied(false) { } + Message1(const Message1& other) + : x(other.x) + , moved(false) + , copied(true) + { + } + + Message1(Message1&& other) + : x(other.x) + , moved(true) + , copied(false) + { + } + + Message1& operator =(const Message1& other) + { + x = other.x; + moved = false; + copied = true; + } + + Message1& operator =(Message1&& other) + { + x = other.x; + moved = true; + copied = false; + } + int x; + bool moved; + bool copied; }; struct Message2 : public etl::message { Message2(double x_) : x(x_) + , moved(false) + , copied(false) { } + Message2(const Message2& other) + : x(other.x) + , moved(false) + , copied(true) + { + } + + Message2(Message2&& other) + : x(other.x) + , moved(true) + , copied(false) + { + } + + Message2& operator =(const Message2& other) + { + x = other.x; + moved = false; + copied = true; + } + + Message2& operator =(Message2&& other) + { + x = other.x; + moved = true; + copied = false; + } + double x; + bool moved; + bool copied; }; struct Message3 : public etl::message { Message3(std::string x_) : x(x_) + , moved(false) + , copied(false) { } + Message3(const Message3& other) + : x(other.x) + , moved(false) + , copied(true) + { + } + + Message3(Message3&& other) + : x(other.x) + , moved(true) + , copied(false) + { + } + + Message3& operator =(const Message3& other) + { + x = other.x; + moved = false; + copied = true; + } + + Message3& operator =(Message3&& other) + { + x = other.x; + moved = true; + copied = false; + } + std::string x; + bool moved; + bool copied; }; struct Message4 : public etl::message @@ -103,11 +199,41 @@ namespace CHECK_EQUAL(MESSAGE2, packet2.get().message_id); CHECK_EQUAL(MESSAGE3, packet3.get().message_id); + CHECK(!static_cast(packet1.get()).moved); + CHECK(!static_cast(packet2.get()).moved); + CHECK(!static_cast(packet3.get()).moved); + + CHECK(static_cast(packet1.get()).copied); + CHECK(static_cast(packet2.get()).copied); + CHECK(static_cast(packet3.get()).copied); + CHECK_EQUAL(1, static_cast(packet1.get()).x); CHECK_EQUAL(2.2, static_cast(packet2.get()).x); CHECK_EQUAL("3", static_cast(packet3.get()).x); } + //************************************************************************* + TEST(message_packet_move_construction) + { + Message1 message1(1); + Message2 message2(2.2); + + Packet packet1(message1); + Packet packet2(std::move(message2)); + + CHECK_EQUAL(MESSAGE1, packet1.get().message_id); + CHECK_EQUAL(MESSAGE2, packet2.get().message_id); + + CHECK(!static_cast(packet1.get()).moved); + CHECK(static_cast(packet2.get()).moved); + + CHECK(static_cast(packet1.get()).copied); + CHECK(!static_cast(packet2.get()).copied); + + CHECK_EQUAL(1, static_cast(packet1.get()).x); + CHECK_EQUAL(2.2, static_cast(packet2.get()).x); + } + //************************************************************************* TEST(message_constant_packet_construction) { @@ -154,5 +280,97 @@ namespace CHECK_EQUAL(2.2, static_cast(packet2.get()).x); CHECK_EQUAL("3", static_cast(packet3.get()).x); } + + //************************************************************************* + TEST(message_packet_copy_consructor) + { + Message1 message1(1); + Message2 message2(2.2); + + Packet packet1(message1); + Packet packet2(packet1); + + CHECK_EQUAL(MESSAGE1, packet1.get().message_id); + CHECK_EQUAL(MESSAGE1, packet2.get().message_id); + + CHECK(!static_cast(packet1.get()).moved); + CHECK(!static_cast(packet2.get()).moved); + + CHECK(static_cast(packet1.get()).copied); + CHECK(static_cast(packet2.get()).copied); + + CHECK_EQUAL(1, static_cast(packet1.get()).x); + CHECK_EQUAL(1, static_cast(packet2.get()).x); + } + + //************************************************************************* + TEST(message_packet_move_consructor) + { + Message1 message1(1); + Message2 message2(2.2); + + Packet packet1(message1); + Packet packet2(std::move(Packet(message1))); + + CHECK_EQUAL(MESSAGE1, packet1.get().message_id); + CHECK_EQUAL(MESSAGE1, packet2.get().message_id); + + CHECK(!static_cast(packet1.get()).moved); + CHECK(static_cast(packet2.get()).moved); + + CHECK(static_cast(packet1.get()).copied); + CHECK(!static_cast(packet2.get()).copied); + + CHECK_EQUAL(1, static_cast(packet1.get()).x); + CHECK_EQUAL(1, static_cast(packet2.get()).x); + } + + //************************************************************************* + TEST(message_packet_assignment) + { + Message1 message1(1); + Message2 message2(2.2); + + Packet packet1(message1); + Packet packet2; + + packet2 = packet1; + + CHECK_EQUAL(MESSAGE1, packet1.get().message_id); + CHECK_EQUAL(MESSAGE1, packet2.get().message_id); + + CHECK(!static_cast(packet1.get()).moved); + CHECK(!static_cast(packet2.get()).moved); + + CHECK(static_cast(packet1.get()).copied); + CHECK(static_cast(packet2.get()).copied); + + CHECK_EQUAL(1, static_cast(packet1.get()).x); + CHECK_EQUAL(1, static_cast(packet2.get()).x); + } + + //************************************************************************* + TEST(message_packet_move_assignment) + { + Message1 message1(1); + Message2 message2(2.2); + + Packet packet1(message1); + Packet packet2; + + packet2 = std::move(packet1); + + CHECK_EQUAL(MESSAGE1, packet1.get().message_id); + CHECK_EQUAL(MESSAGE1, packet2.get().message_id); + + CHECK(!static_cast(packet1.get()).moved); + CHECK(static_cast(packet2.get()).moved); + + CHECK(static_cast(packet1.get()).copied); + CHECK(!static_cast(packet2.get()).copied); + + CHECK_EQUAL(1, static_cast(packet1.get()).x); + CHECK_EQUAL(1, static_cast(packet2.get()).x); + } }; }