diff --git a/include/etl/fsm.h b/include/etl/fsm.h index a00206e7..5d233356 100644 --- a/include/etl/fsm.h +++ b/include/etl/fsm.h @@ -26,28 +26,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ -#if 0 -#error THIS HEADER IS A GENERATOR. DO NOT INCLUDE. -#endif - -//*************************************************************************** -// THIS FILE HAS BEEN AUTO GENERATED. DO NOT EDIT THIS FILE. -//*************************************************************************** - -//*************************************************************************** -// To generate to header file, run this at the command line. -// Note: You will need Python and COG installed. -// -// cog -d -e -ofsm.h -DHandlers= fsm_generator.h -// Where is the number of messages to support. -// -// e.g. -// To generate handlers for up to 16 events... -// cog -d -e -ofsm.h -DHandlers=16 fsm_generator.h -// -// See generate.bat -//*************************************************************************** - #ifndef ETL_FSM_INCLUDED #define ETL_FSM_INCLUDED @@ -88,12 +66,7 @@ namespace etl template class fsm_state; #else - template - class fsm_state; + #include "private/fsm_fwd_decl_cpp03.h" #endif //*************************************************************************** @@ -346,12 +319,7 @@ namespace etl template friend class fsm_state; #else - template - friend class etl::fsm_state; + #include "private/fsm_friend_decl_cpp03.h" #endif //******************************************* @@ -994,896 +962,7 @@ namespace etl }; #else -//************************************************************************************************* -// For C++03 and below. -//************************************************************************************************* - //*************************************************************************** - // The definition for all 16 message types. - //*************************************************************************** - template - class fsm_state : public ifsm_state - { - public: - - static ETL_CONSTANT etl::fsm_state_id_t STATE_ID = STATE_ID_; - - fsm_state() - : ifsm_state(STATE_ID) - { - } - - protected: - - ~fsm_state() - { - } - - TContext& get_fsm_context() const - { - return static_cast(ifsm_state::get_fsm_context()); - } - - private: - - etl::fsm_state_id_t process_event(const etl::imessage& message) - { - etl::fsm_state_id_t new_state_id; - etl::message_id_t event_id = message.get_message_id(); - - switch (event_id) - { - case T1::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T2::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T3::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T4::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T5::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T6::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T7::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T8::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T9::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T10::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T11::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T12::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T13::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T14::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T15::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T16::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - default: new_state_id = p_parent ? p_parent->process_event(message) : static_cast(this)->on_event_unknown(message); break; - } - - return (new_state_id != Pass_To_Parent) ? new_state_id : (p_parent ? p_parent->process_event(message) : No_State_Change); - } - }; - - //*************************************************************************** - // Specialisation for 15 message types. - //*************************************************************************** - template - class fsm_state : public ifsm_state - { - public: - - static ETL_CONSTANT etl::fsm_state_id_t STATE_ID = STATE_ID_; - - fsm_state() - : ifsm_state(STATE_ID) - { - } - - protected: - - ~fsm_state() - { - } - - TContext& get_fsm_context() const - { - return static_cast(ifsm_state::get_fsm_context()); - } - - private: - - etl::fsm_state_id_t process_event(const etl::imessage& message) - { - etl::fsm_state_id_t new_state_id; - etl::message_id_t event_id = message.get_message_id(); - - switch (event_id) - { - case T1::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T2::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T3::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T4::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T5::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T6::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T7::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T8::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T9::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T10::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T11::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T12::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T13::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T14::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T15::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - default: new_state_id = p_parent ? p_parent->process_event(message) : static_cast(this)->on_event_unknown(message); break; - } - - return (new_state_id != Pass_To_Parent) ? new_state_id : (p_parent ? p_parent->process_event(message) : No_State_Change); - } - }; - - //*************************************************************************** - // Specialisation for 14 message types. - //*************************************************************************** - template - class fsm_state : public ifsm_state - { - public: - - static ETL_CONSTANT etl::fsm_state_id_t STATE_ID = STATE_ID_; - - fsm_state() - : ifsm_state(STATE_ID) - { - } - - protected: - - ~fsm_state() - { - } - - TContext& get_fsm_context() const - { - return static_cast(ifsm_state::get_fsm_context()); - } - - private: - - etl::fsm_state_id_t process_event(const etl::imessage& message) - { - etl::fsm_state_id_t new_state_id; - etl::message_id_t event_id = message.get_message_id(); - - switch (event_id) - { - case T1::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T2::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T3::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T4::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T5::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T6::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T7::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T8::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T9::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T10::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T11::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T12::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T13::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T14::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - default: new_state_id = p_parent ? p_parent->process_event(message) : static_cast(this)->on_event_unknown(message); break; - } - - return (new_state_id != Pass_To_Parent) ? new_state_id : (p_parent ? p_parent->process_event(message) : No_State_Change); - } - }; - - //*************************************************************************** - // Specialisation for 13 message types. - //*************************************************************************** - template - class fsm_state : public ifsm_state - { - public: - - static ETL_CONSTANT etl::fsm_state_id_t STATE_ID = STATE_ID_; - - fsm_state() - : ifsm_state(STATE_ID) - { - } - - protected: - - ~fsm_state() - { - } - - TContext& get_fsm_context() const - { - return static_cast(ifsm_state::get_fsm_context()); - } - - private: - - etl::fsm_state_id_t process_event(const etl::imessage& message) - { - etl::fsm_state_id_t new_state_id; - etl::message_id_t event_id = message.get_message_id(); - - switch (event_id) - { - case T1::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T2::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T3::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T4::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T5::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T6::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T7::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T8::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T9::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T10::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T11::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T12::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T13::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - default: new_state_id = p_parent ? p_parent->process_event(message) : static_cast(this)->on_event_unknown(message); break; - } - - return (new_state_id != Pass_To_Parent) ? new_state_id : (p_parent ? p_parent->process_event(message) : No_State_Change); - } - }; - - //*************************************************************************** - // Specialisation for 12 message types. - //*************************************************************************** - template - class fsm_state : public ifsm_state - { - public: - - static ETL_CONSTANT etl::fsm_state_id_t STATE_ID = STATE_ID_; - - fsm_state() - : ifsm_state(STATE_ID) - { - } - - protected: - - ~fsm_state() - { - } - - TContext& get_fsm_context() const - { - return static_cast(ifsm_state::get_fsm_context()); - } - - private: - - etl::fsm_state_id_t process_event(const etl::imessage& message) - { - etl::fsm_state_id_t new_state_id; - etl::message_id_t event_id = message.get_message_id(); - - switch (event_id) - { - case T1::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T2::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T3::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T4::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T5::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T6::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T7::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T8::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T9::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T10::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T11::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T12::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - default: new_state_id = p_parent ? p_parent->process_event(message) : static_cast(this)->on_event_unknown(message); break; - } - - return (new_state_id != Pass_To_Parent) ? new_state_id : (p_parent ? p_parent->process_event(message) : No_State_Change); - } - }; - - //*************************************************************************** - // Specialisation for 11 message types. - //*************************************************************************** - template - class fsm_state : public ifsm_state - { - public: - - static ETL_CONSTANT etl::fsm_state_id_t STATE_ID = STATE_ID_; - - fsm_state() - : ifsm_state(STATE_ID) - { - } - - protected: - - ~fsm_state() - { - } - - TContext& get_fsm_context() const - { - return static_cast(ifsm_state::get_fsm_context()); - } - - private: - - etl::fsm_state_id_t process_event(const etl::imessage& message) - { - etl::fsm_state_id_t new_state_id; - etl::message_id_t event_id = message.get_message_id(); - - switch (event_id) - { - case T1::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T2::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T3::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T4::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T5::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T6::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T7::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T8::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T9::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T10::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T11::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - default: new_state_id = p_parent ? p_parent->process_event(message) : static_cast(this)->on_event_unknown(message); break; - } - - return (new_state_id != Pass_To_Parent) ? new_state_id : (p_parent ? p_parent->process_event(message) : No_State_Change); - } - }; - - //*************************************************************************** - // Specialisation for 10 message types. - //*************************************************************************** - template - class fsm_state : public ifsm_state - { - public: - - static ETL_CONSTANT etl::fsm_state_id_t STATE_ID = STATE_ID_; - - fsm_state() - : ifsm_state(STATE_ID) - { - } - - protected: - - ~fsm_state() - { - } - - TContext& get_fsm_context() const - { - return static_cast(ifsm_state::get_fsm_context()); - } - - private: - - etl::fsm_state_id_t process_event(const etl::imessage& message) - { - etl::fsm_state_id_t new_state_id; - etl::message_id_t event_id = message.get_message_id(); - - switch (event_id) - { - case T1::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T2::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T3::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T4::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T5::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T6::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T7::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T8::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T9::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T10::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - default: new_state_id = p_parent ? p_parent->process_event(message) : static_cast(this)->on_event_unknown(message); break; - } - - return (new_state_id != Pass_To_Parent) ? new_state_id : (p_parent ? p_parent->process_event(message) : No_State_Change); - } - }; - - //*************************************************************************** - // Specialisation for 9 message types. - //*************************************************************************** - template - class fsm_state : public ifsm_state - { - public: - - static ETL_CONSTANT etl::fsm_state_id_t STATE_ID = STATE_ID_; - - fsm_state() - : ifsm_state(STATE_ID) - { - } - - protected: - - ~fsm_state() - { - } - - TContext& get_fsm_context() const - { - return static_cast(ifsm_state::get_fsm_context()); - } - - private: - - etl::fsm_state_id_t process_event(const etl::imessage& message) - { - etl::fsm_state_id_t new_state_id; - etl::message_id_t event_id = message.get_message_id(); - - switch (event_id) - { - case T1::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T2::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T3::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T4::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T5::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T6::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T7::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T8::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T9::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - default: new_state_id = p_parent ? p_parent->process_event(message) : static_cast(this)->on_event_unknown(message); break; - } - - return (new_state_id != Pass_To_Parent) ? new_state_id : (p_parent ? p_parent->process_event(message) : No_State_Change); - } - }; - - //*************************************************************************** - // Specialisation for 8 message types. - //*************************************************************************** - template - class fsm_state : public ifsm_state - { - public: - - static ETL_CONSTANT etl::fsm_state_id_t STATE_ID = STATE_ID_; - - fsm_state() - : ifsm_state(STATE_ID) - { - } - - protected: - - ~fsm_state() - { - } - - TContext& get_fsm_context() const - { - return static_cast(ifsm_state::get_fsm_context()); - } - - private: - - etl::fsm_state_id_t process_event(const etl::imessage& message) - { - etl::fsm_state_id_t new_state_id; - etl::message_id_t event_id = message.get_message_id(); - - switch (event_id) - { - case T1::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T2::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T3::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T4::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T5::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T6::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T7::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T8::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - default: new_state_id = p_parent ? p_parent->process_event(message) : static_cast(this)->on_event_unknown(message); break; - } - - return (new_state_id != Pass_To_Parent) ? new_state_id : (p_parent ? p_parent->process_event(message) : No_State_Change); - } - }; - - //*************************************************************************** - // Specialisation for 7 message types. - //*************************************************************************** - template - class fsm_state : public ifsm_state - { - public: - - static ETL_CONSTANT etl::fsm_state_id_t STATE_ID = STATE_ID_; - - fsm_state() - : ifsm_state(STATE_ID) - { - } - - protected: - - ~fsm_state() - { - } - - TContext& get_fsm_context() const - { - return static_cast(ifsm_state::get_fsm_context()); - } - - private: - - etl::fsm_state_id_t process_event(const etl::imessage& message) - { - etl::fsm_state_id_t new_state_id; - etl::message_id_t event_id = message.get_message_id(); - - switch (event_id) - { - case T1::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T2::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T3::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T4::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T5::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T6::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T7::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - default: new_state_id = p_parent ? p_parent->process_event(message) : static_cast(this)->on_event_unknown(message); break; - } - - return (new_state_id != Pass_To_Parent) ? new_state_id : (p_parent ? p_parent->process_event(message) : No_State_Change); - } - }; - - //*************************************************************************** - // Specialisation for 6 message types. - //*************************************************************************** - template - class fsm_state : public ifsm_state - { - public: - - static ETL_CONSTANT etl::fsm_state_id_t STATE_ID = STATE_ID_; - - fsm_state() - : ifsm_state(STATE_ID) - { - } - - protected: - - ~fsm_state() - { - } - - TContext& get_fsm_context() const - { - return static_cast(ifsm_state::get_fsm_context()); - } - - private: - - etl::fsm_state_id_t process_event(const etl::imessage& message) - { - etl::fsm_state_id_t new_state_id; - etl::message_id_t event_id = message.get_message_id(); - - switch (event_id) - { - case T1::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T2::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T3::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T4::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T5::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T6::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - default: new_state_id = p_parent ? p_parent->process_event(message) : static_cast(this)->on_event_unknown(message); break; - } - - return (new_state_id != Pass_To_Parent) ? new_state_id : (p_parent ? p_parent->process_event(message) : No_State_Change); - } - }; - - //*************************************************************************** - // Specialisation for 5 message types. - //*************************************************************************** - template - class fsm_state : public ifsm_state - { - public: - - static ETL_CONSTANT etl::fsm_state_id_t STATE_ID = STATE_ID_; - - fsm_state() - : ifsm_state(STATE_ID) - { - } - - protected: - - ~fsm_state() - { - } - - TContext& get_fsm_context() const - { - return static_cast(ifsm_state::get_fsm_context()); - } - - private: - - etl::fsm_state_id_t process_event(const etl::imessage& message) - { - etl::fsm_state_id_t new_state_id; - etl::message_id_t event_id = message.get_message_id(); - - switch (event_id) - { - case T1::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T2::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T3::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T4::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T5::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - default: new_state_id = p_parent ? p_parent->process_event(message) : static_cast(this)->on_event_unknown(message); break; - } - - return (new_state_id != Pass_To_Parent) ? new_state_id : (p_parent ? p_parent->process_event(message) : No_State_Change); - } - }; - - //*************************************************************************** - // Specialisation for 4 message types. - //*************************************************************************** - template - class fsm_state : public ifsm_state - { - public: - - static ETL_CONSTANT etl::fsm_state_id_t STATE_ID = STATE_ID_; - - fsm_state() - : ifsm_state(STATE_ID) - { - } - - protected: - - ~fsm_state() - { - } - - TContext& get_fsm_context() const - { - return static_cast(ifsm_state::get_fsm_context()); - } - - private: - - etl::fsm_state_id_t process_event(const etl::imessage& message) - { - etl::fsm_state_id_t new_state_id; - etl::message_id_t event_id = message.get_message_id(); - - switch (event_id) - { - case T1::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T2::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T3::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T4::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - default: new_state_id = p_parent ? p_parent->process_event(message) : static_cast(this)->on_event_unknown(message); break; - } - - return (new_state_id != Pass_To_Parent) ? new_state_id : (p_parent ? p_parent->process_event(message) : No_State_Change); - } - }; - - //*************************************************************************** - // Specialisation for 3 message types. - //*************************************************************************** - template - class fsm_state : public ifsm_state - { - public: - - static ETL_CONSTANT etl::fsm_state_id_t STATE_ID = STATE_ID_; - - fsm_state() - : ifsm_state(STATE_ID) - { - } - - protected: - - ~fsm_state() - { - } - - TContext& get_fsm_context() const - { - return static_cast(ifsm_state::get_fsm_context()); - } - - private: - - etl::fsm_state_id_t process_event(const etl::imessage& message) - { - etl::fsm_state_id_t new_state_id; - etl::message_id_t event_id = message.get_message_id(); - - switch (event_id) - { - case T1::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T2::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T3::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - default: new_state_id = p_parent ? p_parent->process_event(message) : static_cast(this)->on_event_unknown(message); break; - } - - return (new_state_id != Pass_To_Parent) ? new_state_id : (p_parent ? p_parent->process_event(message) : No_State_Change); - } - }; - - //*************************************************************************** - // Specialisation for 2 message types. - //*************************************************************************** - template - class fsm_state : public ifsm_state - { - public: - - static ETL_CONSTANT etl::fsm_state_id_t STATE_ID = STATE_ID_; - - fsm_state() - : ifsm_state(STATE_ID) - { - } - - protected: - - ~fsm_state() - { - } - - TContext& get_fsm_context() const - { - return static_cast(ifsm_state::get_fsm_context()); - } - - private: - - etl::fsm_state_id_t process_event(const etl::imessage& message) - { - etl::fsm_state_id_t new_state_id; - etl::message_id_t event_id = message.get_message_id(); - - switch (event_id) - { - case T1::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - case T2::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - default: new_state_id = p_parent ? p_parent->process_event(message) : static_cast(this)->on_event_unknown(message); break; - } - - return (new_state_id != Pass_To_Parent) ? new_state_id : (p_parent ? p_parent->process_event(message) : No_State_Change); - } - }; - - //*************************************************************************** - // Specialisation for 1 message type. - //*************************************************************************** - template - class fsm_state : public ifsm_state - { - public: - - static ETL_CONSTANT etl::fsm_state_id_t STATE_ID = STATE_ID_; - - fsm_state() - : ifsm_state(STATE_ID) - { - } - - protected: - - ~fsm_state() - { - } - - TContext& get_fsm_context() const - { - return static_cast(ifsm_state::get_fsm_context()); - } - - private: - - etl::fsm_state_id_t process_event(const etl::imessage& message) - { - etl::fsm_state_id_t new_state_id; - etl::message_id_t event_id = message.get_message_id(); - - switch (event_id) - { - case T1::ID: new_state_id = static_cast(this)->on_event(static_cast(message)); break; - default: new_state_id = p_parent ? p_parent->process_event(message) : static_cast(this)->on_event_unknown(message); break; - } - - return (new_state_id != Pass_To_Parent) ? new_state_id : (p_parent ? p_parent->process_event(message) : No_State_Change); - } - }; - - //*************************************************************************** - // Specialisation for 0 message types. - //*************************************************************************** - template - class fsm_state : public ifsm_state - { - public: - - static ETL_CONSTANT etl::fsm_state_id_t STATE_ID = STATE_ID_; - - fsm_state() - : ifsm_state(STATE_ID) - { - } - - protected: - - ~fsm_state() - { - } - - TContext& get_fsm_context() const - { - return static_cast(ifsm_state::get_fsm_context()); - } - private: - - etl::fsm_state_id_t process_event(const etl::imessage& message) - { - return p_parent ? p_parent->process_event(message) : static_cast(this)->on_event_unknown(message); - } - }; - - template - ETL_CONSTANT etl::fsm_state_id_t fsm_state::STATE_ID; + #include "private/fsm_cpp03.h" #endif } diff --git a/include/etl/generators/fsm_cpp03_generator.h b/include/etl/generators/fsm_cpp03_generator.h new file mode 100644 index 00000000..9c0aae28 --- /dev/null +++ b/include/etl/generators/fsm_cpp03_generator.h @@ -0,0 +1,199 @@ +//*************************************************************************** +// THIS FILE HAS BEEN AUTO GENERATED. DO NOT EDIT THIS FILE. +//*************************************************************************** + +//************************************************************************************************* +// For C++03 and below. +//************************************************************************************************* + /*[[[cog + import cog + ################################################ + # The first definition for all of the events. + ################################################ + cog.outl("//***************************************************************************") + cog.outl("// The definition for all %s message types." % Handlers) + cog.outl("//***************************************************************************") + cog.outl("template " % Handlers) + cog.outl("class fsm_state : public ifsm_state") + cog.outl("{") + cog.outl("public:") + cog.outl("") + cog.outl(" static ETL_CONSTANT etl::fsm_state_id_t STATE_ID = STATE_ID_;") + cog.outl("") + cog.outl(" fsm_state()") + cog.outl(" : ifsm_state(STATE_ID)") + cog.outl(" {") + cog.outl(" }") + cog.outl("") + cog.outl("protected:") + cog.outl("") + cog.outl(" ~fsm_state()") + cog.outl(" {") + cog.outl(" }") + cog.outl("") + cog.outl(" TContext& get_fsm_context() const") + cog.outl(" {") + cog.outl(" return static_cast(ifsm_state::get_fsm_context());") + cog.outl(" }") + cog.outl("") + cog.outl("private:") + cog.outl("") + cog.outl(" etl::fsm_state_id_t process_event(const etl::imessage& message)") + cog.outl(" {") + cog.outl(" etl::fsm_state_id_t new_state_id;") + cog.outl(" etl::message_id_t event_id = message.get_message_id();") + cog.outl("") + cog.outl(" switch (event_id)") + cog.outl(" {") + for n in range(1, int(Handlers) + 1): + cog.out(" case T%d::ID:" % n) + cog.out(" new_state_id = static_cast(this)->on_event(static_cast(message));" % n) + cog.outl(" break;") + cog.out(" default:") + cog.out(" new_state_id = p_parent ? p_parent->process_event(message) : static_cast(this)->on_event_unknown(message);") + cog.outl(" break;") + cog.outl(" }") + cog.outl("") + cog.outl(" return (new_state_id != Pass_To_Parent) ? new_state_id : (p_parent ? p_parent->process_event(message) : No_State_Change);") + cog.outl(" }") + cog.outl("};") + + #################################### + # All of the other specialisations. + #################################### + for n in range(int(Handlers) - 1, 0, -1): + cog.outl("") + cog.outl("//***************************************************************************") + if n == 1: + cog.outl("// Specialisation for %d message type." % n) + else: + cog.outl("// Specialisation for %d message types." % n) + cog.outl("//***************************************************************************") + cog.outl("template " % n) + cog.out("class fsm_state : public ifsm_state") + cog.outl("{") + cog.outl("public:") + cog.outl("") + cog.outl(" static ETL_CONSTANT etl::fsm_state_id_t STATE_ID = STATE_ID_;") + cog.outl("") + cog.outl(" fsm_state()") + cog.outl(" : ifsm_state(STATE_ID)") + cog.outl(" {") + cog.outl(" }") + cog.outl("") + cog.outl("protected:") + cog.outl("") + cog.outl(" ~fsm_state()") + cog.outl(" {") + cog.outl(" }") + cog.outl("") + cog.outl(" TContext& get_fsm_context() const") + cog.outl(" {") + cog.outl(" return static_cast(ifsm_state::get_fsm_context());") + cog.outl(" }") + cog.outl("") + cog.outl("private:") + cog.outl("") + cog.outl(" etl::fsm_state_id_t process_event(const etl::imessage& message)") + cog.outl(" {") + cog.outl(" etl::fsm_state_id_t new_state_id;") + cog.outl(" etl::message_id_t event_id = message.get_message_id();") + cog.outl("") + cog.outl(" switch (event_id)") + cog.outl(" {") + for n in range(1, n + 1): + cog.out(" case T%d::ID:" % n) + cog.out(" new_state_id = static_cast(this)->on_event(static_cast(message));" % n) + cog.outl(" break;") + cog.out(" default:") + cog.out(" new_state_id = p_parent ? p_parent->process_event(message) : static_cast(this)->on_event_unknown(message);") + cog.outl(" break;") + cog.outl(" }") + cog.outl("") + cog.outl(" return (new_state_id != Pass_To_Parent) ? new_state_id : (p_parent ? p_parent->process_event(message) : No_State_Change);") + cog.outl(" }") + cog.outl("};") + #################################### + # Specialisation for zero messages. + #################################### + cog.outl("") + cog.outl("//***************************************************************************") + cog.outl("// Specialisation for 0 message types.") + cog.outl("//***************************************************************************") + cog.outl("template ") + cog.out("class fsm_state : public ifsm_state") + cog.outl("{") + cog.outl("public:") + cog.outl("") + cog.outl(" static ETL_CONSTANT etl::fsm_state_id_t STATE_ID = STATE_ID_;") + cog.outl("") + cog.outl(" fsm_state()") + cog.outl(" : ifsm_state(STATE_ID)") + cog.outl(" {") + cog.outl(" }") + cog.outl("") + cog.outl("protected:") + cog.outl("") + cog.outl(" ~fsm_state()") + cog.outl(" {") + cog.outl(" }") + cog.outl("") + cog.outl(" TContext& get_fsm_context() const") + cog.outl(" {") + cog.outl(" return static_cast(ifsm_state::get_fsm_context());") + cog.outl(" }") + cog.outl("private:") + cog.outl("") + cog.outl(" etl::fsm_state_id_t process_event(const etl::imessage& message)") + cog.outl(" {") + cog.outl(" return p_parent ? p_parent->process_event(message) : static_cast(this)->on_event_unknown(message);") + cog.outl(" }") + cog.outl("};") + + cog.outl("") + cog.outl("template " % Handlers) + cog.out("ETL_CONSTANT etl::fsm_state_id_t fsm_state::STATE_ID;" % Handlers) + ]]]*/ + /*[[[end]]]*/ + diff --git a/include/etl/generators/fsm_friend_decl_cpp03_generator.h b/include/etl/generators/fsm_friend_decl_cpp03_generator.h new file mode 100644 index 00000000..bbc07ecc --- /dev/null +++ b/include/etl/generators/fsm_friend_decl_cpp03_generator.h @@ -0,0 +1,18 @@ +//*************************************************************************** +// THIS FILE HAS BEEN AUTO GENERATED. DO NOT EDIT THIS FILE. +//*************************************************************************** + + /*[[[cog + import cog + cog.outl(" template ") + ]]]*/ + /*[[[end]]]*/ + friend class etl::fsm_state; + diff --git a/include/etl/generators/fsm_fwd_decl_cpp03_generator.h b/include/etl/generators/fsm_fwd_decl_cpp03_generator.h new file mode 100644 index 00000000..384843b5 --- /dev/null +++ b/include/etl/generators/fsm_fwd_decl_cpp03_generator.h @@ -0,0 +1,18 @@ +//*************************************************************************** +// THIS FILE HAS BEEN AUTO GENERATED. DO NOT EDIT THIS FILE. +//*************************************************************************** + + /*[[[cog + import cog + cog.outl("template ") + cog.outl("class fsm_state;") + ]]]*/ + /*[[[end]]]*/ + diff --git a/include/etl/generators/fsm_generator.h b/include/etl/generators/fsm_generator.h deleted file mode 100644 index 98d4c6b0..00000000 --- a/include/etl/generators/fsm_generator.h +++ /dev/null @@ -1,1222 +0,0 @@ -/****************************************************************************** -The MIT License(MIT) - -Embedded Template Library. -https://github.com/ETLCPP/etl -https://www.etlcpp.com - -Copyright(c) 2017 John Wellbelove - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files(the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions : - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -******************************************************************************/ - -/*[[[cog -import cog -cog.outl("#if 0") -]]]*/ -/*[[[end]]]*/ -#error THIS HEADER IS A GENERATOR. DO NOT INCLUDE. -/*[[[cog -import cog -cog.outl("#endif") -]]]*/ -/*[[[end]]]*/ - -/*[[[cog -import cog -cog.outl("//***************************************************************************") -cog.outl("// THIS FILE HAS BEEN AUTO GENERATED. DO NOT EDIT THIS FILE.") -cog.outl("//***************************************************************************") -]]]*/ -/*[[[end]]]*/ - -//*************************************************************************** -// To generate to header file, run this at the command line. -// Note: You will need Python and COG installed. -// -// cog -d -e -ofsm.h -DHandlers= fsm_generator.h -// Where is the number of messages to support. -// -// e.g. -// To generate handlers for up to 16 events... -// cog -d -e -ofsm.h -DHandlers=16 fsm_generator.h -// -// See generate.bat -//*************************************************************************** - -#ifndef ETL_FSM_INCLUDED -#define ETL_FSM_INCLUDED - -#include "platform.h" -#include "array.h" -#include "nullptr.h" -#include "error_handler.h" -#include "exception.h" -#include "user_type.h" -#include "message_router.h" -#include "integral_limits.h" -#include "largest.h" -#if ETL_USING_CPP11 - #include "tuple.h" - #include "type_list.h" -#endif - -#include - -#include "private/minmax_push.h" - -namespace etl -{ - class fsm; - class hfsm; - - /// Allow alternative type for state id. -#if !defined(ETL_FSM_STATE_ID_TYPE) - typedef uint_least8_t fsm_state_id_t; -#else - typedef ETL_FSM_STATE_ID_TYPE fsm_state_id_t; -#endif - - // For internal FSM use. - typedef typename etl::larger_type::type fsm_internal_id_t; - -#if ETL_USING_CPP11 && !defined(ETL_FSM_FORCE_CPP03_IMPLEMENTATION) // For C++11 and above - template - class fsm_state; -#else - /*[[[cog - import cog - cog.outl("template ") - cog.outl("class fsm_state;") - ]]]*/ - /*[[[end]]]*/ -#endif - - //*************************************************************************** - /// Base exception class for FSM. - //*************************************************************************** - class fsm_exception : public etl::exception - { - public: - - fsm_exception(string_type reason_, string_type file_name_, numeric_type line_number_) - : etl::exception(reason_, file_name_, line_number_) - { - } - }; - - //*************************************************************************** - /// Exception for null state pointer. - //*************************************************************************** - class fsm_null_state_exception : public etl::fsm_exception - { - public: - - fsm_null_state_exception(string_type file_name_, numeric_type line_number_) - : etl::fsm_exception(ETL_ERROR_TEXT("fsm:null state", ETL_FSM_FILE_ID"A"), file_name_, line_number_) - { - } - }; - - //*************************************************************************** - /// Exception for invalid state id. - //*************************************************************************** - class fsm_state_id_exception : public etl::fsm_exception - { - public: - - fsm_state_id_exception(string_type file_name_, numeric_type line_number_) - : etl::fsm_exception(ETL_ERROR_TEXT("fsm:state id", ETL_FSM_FILE_ID"B"), file_name_, line_number_) - { - } - }; - - //*************************************************************************** - /// Exception for incompatible state list. - //*************************************************************************** - class fsm_state_list_exception : public etl::fsm_exception - { - public: - - fsm_state_list_exception(string_type file_name_, numeric_type line_number_) - : etl::fsm_exception(ETL_ERROR_TEXT("fsm:state list", ETL_FSM_FILE_ID"C"), file_name_, line_number_) - { - } - }; - - //*************************************************************************** - /// Exception for incompatible order state list. - //*************************************************************************** - class fsm_state_list_order_exception : public etl::fsm_exception - { - public: - - fsm_state_list_order_exception(string_type file_name_, numeric_type line_number_) - : etl::fsm_exception(ETL_ERROR_TEXT("fsm:state list order", ETL_FSM_FILE_ID"D"), file_name_, line_number_) - { - } - }; - - //*************************************************************************** - /// Exception for message received but not started. - //*************************************************************************** - class fsm_not_started : public etl::fsm_exception - { - public: - fsm_not_started(string_type file_name_, numeric_type line_number_) - : etl::fsm_exception(ETL_ERROR_TEXT("fsm:not started", ETL_FSM_FILE_ID"F"), file_name_, line_number_) - { - } - }; - - //*************************************************************************** - /// Exception for call to receive/start/etc. while receive/start/etc. is already happening. - /// A call like that could result in an infinite loop or landing in an incorrect state. - //*************************************************************************** - class fsm_reentrant_transition_forbidden : public etl::fsm_exception - { - public: - fsm_reentrant_transition_forbidden(string_type file_name_, numeric_type line_number_) - : etl::fsm_exception(ETL_ERROR_TEXT("fsm:reentrant calls to start/receive/etc. forbidden", ETL_FSM_FILE_ID"G"), file_name_, line_number_) - { - } - }; - - namespace private_fsm - { - template - class ifsm_state_helper - { - public: - - // Pass this whenever no state change is desired. - // The highest unsigned value of fsm_state_id_t. - static ETL_CONSTANT fsm_state_id_t No_State_Change = etl::integral_limits::max; - - // Pass this when this event also needs to be passed to the parent. - static ETL_CONSTANT fsm_state_id_t Pass_To_Parent = No_State_Change - 1U; - - // Pass this when this event should trigger a self transition. - static ETL_CONSTANT fsm_state_id_t Self_Transition = No_State_Change - 2U; - }; - - template - ETL_CONSTANT fsm_state_id_t ifsm_state_helper::No_State_Change; - - template - ETL_CONSTANT fsm_state_id_t ifsm_state_helper::Pass_To_Parent; - - template - ETL_CONSTANT fsm_state_id_t ifsm_state_helper::Self_Transition; - - // Compile-time: TState::ID must equal its index in the type list (0..N-1) - template struct check_ids : etl::true_type - { - }; - - template - struct check_ids - : etl::integral_constant::value> - { - }; - - //*************************************************************************** - /// RAII detection mechanism to catch reentrant calls to methods that might - /// transition the state machine to a different state. - /// This is not a mutex. - //*************************************************************************** - class fsm_reentrancy_guard - { - public: - //******************************************* - /// Constructor. - /// Checks if another method has locked reentrancy. - //******************************************* - fsm_reentrancy_guard(bool& transition_guard_flag) - : is_locked(transition_guard_flag) - { - ETL_ASSERT(!is_locked, ETL_ERROR(etl::fsm_reentrant_transition_forbidden)); - is_locked = true; - } - - //******************************************* - /// Destructor. - /// Releases lock on reentrancy. - //******************************************* - ~fsm_reentrancy_guard() ETL_NOEXCEPT - { - is_locked = false; - } - - private: - // Reference to the flag signifying a lock on the state machine. - bool& is_locked; - - // Copy & move semantics disabled since this is a guard. - fsm_reentrancy_guard(fsm_reentrancy_guard const&) ETL_DELETE; - fsm_reentrancy_guard& operator= (fsm_reentrancy_guard const&) ETL_DELETE; -#if ETL_USING_CPP11 - fsm_reentrancy_guard(fsm_reentrancy_guard&&) ETL_DELETE; - fsm_reentrancy_guard& operator= (fsm_reentrancy_guard&&) ETL_DELETE; -#endif - }; - } - - class ifsm_state; - -#if ETL_USING_CPP11 - //*************************************************************************** - /// A class to store FSM states. - //*************************************************************************** - template - class fsm_state_pack - { - public: - - friend class etl::fsm; - - ETL_STATIC_ASSERT((private_fsm::check_ids<0, TStates...>::value), "State IDs must be 0..N-1 and in order"); - ETL_STATIC_ASSERT(sizeof...(TStates) > 0, "At least one state is required"); - ETL_STATIC_ASSERT(sizeof...(TStates) < private_fsm::ifsm_state_helper<>::No_State_Change, "State IDs mst be less than ifsm_state::No_State_Change"); - - //********************************* - // The number of states. - //********************************* - static ETL_CONSTEXPR size_t size() - { - return sizeof...(TStates); - } - - //********************************* - /// Gets a reference to the state. - //********************************* - template - TState& get() - { - return etl::get(storage); - } - - //********************************* - /// Gets a const reference to the state. - //********************************* - template - const TState& get() const - { - return etl::get(storage); - } - - private: - - //********************************* - /// Gets a pointer to the state list. - //********************************* - etl::ifsm_state** get_state_list() - { - return &states[0]; - } - - /// A tuple to store the states. - etl::tuple storage{}; - - /// Pointers to the states. - etl::ifsm_state* states[sizeof...(TStates)]{ &etl::get(storage)... }; - }; -#endif - - //*************************************************************************** - /// Interface class for FSM states. - //*************************************************************************** - class ifsm_state : public private_fsm::ifsm_state_helper<> - { - public: - - /// Allows ifsm_state functions to be private. - friend class etl::fsm; - friend class etl::hfsm; - - using private_fsm::ifsm_state_helper<>::No_State_Change; - using private_fsm::ifsm_state_helper<>::Pass_To_Parent; - using private_fsm::ifsm_state_helper<>::Self_Transition; - -#if ETL_USING_CPP11 && !defined(ETL_FSM_FORCE_CPP03_IMPLEMENTATION) // For C++11 and above - template - friend class fsm_state; -#else - /*[[[cog - import cog - cog.outl(" template ") - ]]]*/ - /*[[[end]]]*/ - friend class etl::fsm_state; -#endif - - //******************************************* - /// Gets the id for this state. - //******************************************* - etl::fsm_state_id_t get_state_id() const - { - return state_id; - } - - //******************************************* - /// Adds a child to this state. - /// Only of use when part of an HFSM. - //******************************************* - void add_child_state(etl::ifsm_state& state) - { - ETL_ASSERT(state.p_parent == ETL_NULLPTR, ETL_ERROR(etl::fsm_null_state_exception)); - state.p_parent = this; - - if (p_default_child == ETL_NULLPTR) - { - p_default_child = &state; - } - } - - //******************************************* - /// Adds a list of child states. - /// Only of use when part of an HFSM. - //******************************************* - template - void set_child_states(etl::ifsm_state** state_list, TSize size) - { - p_active_child = ETL_NULLPTR; - p_default_child = ETL_NULLPTR; - - for (TSize i = 0; i < size; ++i) - { - ETL_ASSERT(state_list[i] != ETL_NULLPTR, ETL_ERROR(etl::fsm_null_state_exception)); - add_child_state(*state_list[i]); - } - } - - protected: - - //******************************************* - /// Constructor. - //******************************************* - ifsm_state(etl::fsm_state_id_t state_id_) - : state_id(state_id_), - p_context(ETL_NULLPTR), - p_parent(ETL_NULLPTR), - p_active_child(ETL_NULLPTR), - p_default_child(ETL_NULLPTR) - { - } - - //******************************************* - /// Destructor. - //******************************************* - virtual ~ifsm_state() - { - } - - //******************************************* - etl::fsm& get_fsm_context() const - { - return *p_context; - } - - private: - - virtual fsm_state_id_t process_event(const etl::imessage& message) = 0; - - virtual fsm_state_id_t on_enter_state() { return No_State_Change; } // By default, do nothing. - virtual void on_exit_state() {} // By default, do nothing. - - //******************************************* - void set_fsm_context(etl::fsm& context) - { - p_context = &context; - } - - // The state id. - const etl::fsm_state_id_t state_id; - - // A pointer to the FSM context. - etl::fsm* p_context; - - // A pointer to the parent. - ifsm_state* p_parent; - - // A pointer to the active child. - ifsm_state* p_active_child; - - // A pointer to the default active child. - ifsm_state* p_default_child; - - // Disabled. - ifsm_state(const ifsm_state&) ETL_DELETE; - ifsm_state& operator =(const ifsm_state&) ETL_DELETE; - }; - - //*************************************************************************** - /// The FSM class. - //*************************************************************************** - class fsm : public etl::imessage_router - { - public: - - friend class etl::hfsm; - using imessage_router::receive; - - //******************************************* - /// Constructor. - //******************************************* - fsm(etl::message_router_id_t id) - : imessage_router(id) - , p_state(ETL_NULLPTR) - , state_list(ETL_NULLPTR) - , number_of_states(0U) - , is_processing_state_change(false) - { - } - - //******************************************* - /// Set the states for the FSM - /// From a pointer to etl::ifsm_state and size. - //******************************************* - template - void set_states(etl::ifsm_state** p_states, TSize size) - { - state_list = p_states; - number_of_states = etl::fsm_state_id_t(size); - - ETL_ASSERT(number_of_states > 0, ETL_ERROR(etl::fsm_state_list_exception)); - ETL_ASSERT(number_of_states < ifsm_state::No_State_Change, ETL_ERROR(etl::fsm_state_list_exception)); - - for (etl::fsm_state_id_t i = 0; i < size; ++i) - { - ETL_ASSERT(state_list[i] != ETL_NULLPTR, ETL_ERROR(etl::fsm_null_state_exception)); - ETL_ASSERT(state_list[i]->get_state_id() == i, ETL_ERROR(etl::fsm_state_list_order_exception)); - state_list[i]->set_fsm_context(*this); - } - } - -#if ETL_USING_CPP11 - //******************************************* - /// Set the states for the FSM - /// From an etl::fsm_state_pack. - //******************************************* - template - void set_states(etl::fsm_state_pack& state_pack) - { - state_list = state_pack.get_state_list(); - number_of_states = etl::fsm_state_id_t(state_pack.size()); - - for (etl::fsm_state_id_t i = 0; i < number_of_states; ++i) - { - state_list[i]->set_fsm_context(*this); - } - } -#endif - - //******************************************* - /// Starts the FSM. - /// Can only be called once. - /// Subsequent calls will do nothing. - ///\param call_on_enter_state If true will call on_enter_state() for the first state. Default = true. - //******************************************* - virtual void start(bool call_on_enter_state = true) - { - private_fsm::fsm_reentrancy_guard transition_lock(is_processing_state_change); - - // Can only be started once. - if (!is_started()) - { - p_state = state_list[0]; - ETL_ASSERT(p_state != ETL_NULLPTR, ETL_ERROR(etl::fsm_null_state_exception)); - - if (call_on_enter_state) - { - etl::fsm_state_id_t next_state_id; - etl::ifsm_state* p_last_state; - - do - { - p_last_state = p_state; - next_state_id = p_state->on_enter_state(); - if (next_state_id != ifsm_state::No_State_Change) - { - ETL_ASSERT(next_state_id < number_of_states, ETL_ERROR(etl::fsm_state_id_exception)); - p_state = state_list[next_state_id]; - } - } while (p_last_state != p_state); - } - } - } - - //******************************************* - /// Top level message handler for the FSM. - //******************************************* - void receive(const etl::imessage& message) ETL_OVERRIDE - { - private_fsm::fsm_reentrancy_guard transition_lock(is_processing_state_change); - - if (is_started()) - { - etl::fsm_state_id_t next_state_id = p_state->process_event(message); - - process_state_change(next_state_id); - } - else - { - ETL_ASSERT_FAIL(ETL_ERROR(etl::fsm_not_started)); - } - } - - //******************************************* - /// Invoke a state transition. - //******************************************* - etl::fsm_state_id_t transition_to(etl::fsm_state_id_t new_state_id) - { - private_fsm::fsm_reentrancy_guard transition_lock(is_processing_state_change); - - if (is_started()) - { - return process_state_change(new_state_id); - } - else - { - return ifsm_state::No_State_Change; - } - } - - using imessage_router::accepts; - - //******************************************* - /// Does this FSM accept the message id? - /// Yes, it accepts everything! - //******************************************* - bool accepts(etl::message_id_t) const ETL_OVERRIDE - { - return true; - } - - //******************************************* - /// Gets the current state id. - //******************************************* - etl::fsm_state_id_t get_state_id() const - { - ETL_ASSERT(p_state != ETL_NULLPTR, ETL_ERROR(etl::fsm_null_state_exception)); - return p_state->get_state_id(); - } - - //******************************************* - /// Gets a reference to the current state interface. - //******************************************* - ifsm_state& get_state() - { - ETL_ASSERT(p_state != ETL_NULLPTR, ETL_ERROR(etl::fsm_null_state_exception)); - return *p_state; - } - - //******************************************* - /// Gets a const reference to the current state interface. - //******************************************* - const ifsm_state& get_state() const - { - ETL_ASSERT(p_state != ETL_NULLPTR, ETL_ERROR(etl::fsm_null_state_exception)); - return *p_state; - } - - //******************************************* - /// Checks if the FSM has been started. - //******************************************* - bool is_started() const - { - return p_state != ETL_NULLPTR; - } - - //******************************************* - /// Reset the FSM to pre-started state. - ///\param call_on_exit_state If true will call on_exit_state() for the current state. Default = false. - //******************************************* - virtual void reset(bool call_on_exit_state = false) - { - private_fsm::fsm_reentrancy_guard transition_lock(is_processing_state_change); - - if (is_started() && call_on_exit_state) - { - p_state->on_exit_state(); - } - - p_state = ETL_NULLPTR; - } - - //******************************************** - ETL_DEPRECATED bool is_null_router() const ETL_OVERRIDE - { - return false; - } - - //******************************************** - bool is_producer() const ETL_OVERRIDE - { - return true; - } - - //******************************************** - bool is_consumer() const ETL_OVERRIDE - { - return true; - } - - private: - - //******************************************** - bool have_changed_state(etl::fsm_state_id_t next_state_id) const - { - return (next_state_id != p_state->get_state_id()) && - (next_state_id != ifsm_state::No_State_Change) && - (next_state_id != ifsm_state::Self_Transition); - } - - //******************************************** - bool is_self_transition(etl::fsm_state_id_t next_state_id) const - { - return (next_state_id == ifsm_state::Self_Transition); - } - - //******************************************* - /// Core function to process a state change. - //******************************************* - virtual etl::fsm_state_id_t process_state_change(etl::fsm_state_id_t next_state_id) - { - if (is_self_transition(next_state_id)) - { - p_state->on_exit_state(); - next_state_id = p_state->on_enter_state(); - } - - if (have_changed_state(next_state_id)) - { - ETL_ASSERT_OR_RETURN_VALUE(next_state_id < number_of_states, ETL_ERROR(etl::fsm_state_id_exception), p_state->get_state_id()); - etl::ifsm_state* p_next_state = state_list[next_state_id]; - - do - { - p_state->on_exit_state(); - p_state = p_next_state; - - next_state_id = p_state->on_enter_state(); - - if (have_changed_state(next_state_id)) - { - ETL_ASSERT_OR_RETURN_VALUE(next_state_id < number_of_states, ETL_ERROR(etl::fsm_state_id_exception), p_state->get_state_id()); - p_next_state = state_list[next_state_id]; - } - } while (p_next_state != p_state); // Have we changed state again? - } - - return p_state->get_state_id(); - } - - etl::ifsm_state* p_state; ///< A pointer to the current state. - etl::ifsm_state** state_list; ///< The list of added states. - etl::fsm_state_id_t number_of_states; ///< The number of states. - bool is_processing_state_change; ///< Whether a method call that could potentially trigger a state change is active - }; - - //************************************************************************************************* - // For C++11 and above. - //************************************************************************************************* -#if ETL_USING_CPP11 && !defined(ETL_FSM_FORCE_CPP03_IMPLEMENTATION) // For C++11 and above - //*************************************************************************** - // The definition for all types. - //*************************************************************************** - template - class fsm_state : public ifsm_state - { - private: - - using message_id_sequence = etl::index_sequence; - - public: - - using message_types = etl::type_list; - using sorted_message_types = etl::type_list_sort_t; - - static_assert(etl::type_list_is_unique::value, "All TMessageTypes must be unique"); - static_assert(etl::type_list_all_of::value, "All TMessageTypes must satisfy the condition etl::is_message_type"); - static_assert(etl::index_sequence_is_unique::value, "All message IDs must be unique"); - - static ETL_CONSTANT etl::fsm_state_id_t STATE_ID = STATE_ID_; - - fsm_state() - : ifsm_state(STATE_ID) - { - } - - protected: - - ~fsm_state() - { - } - - TContext& get_fsm_context() const - { - return static_cast(ifsm_state::get_fsm_context()); - } - - private: - - static constexpr size_t Number_Of_Messages = sizeof...(TMessageTypes); - static constexpr etl::message_id_t Message_Id_Start = etl::type_list_type_at_index_t::ID; - - static_assert(Number_Of_Messages > 0, "Zero messages"); - - //********************************************** - // Checks that the message ids are contiguous. - //********************************************** - template = Number_Of_Messages)> - struct contiguous_impl; - - template - struct contiguous_impl : etl::true_type - { - }; - - template - struct contiguous_impl - : etl::bool_constant<(etl::type_list_type_at_index_t::ID + 1U == - etl::type_list_type_at_index_t::ID) && - contiguous_impl::value> - { - - - }; - - // The message ids are contiguous if there are 0 or 1 message types, or if each message id is one greater than the previous message id. - static constexpr bool Message_Ids_Are_Contiguous = (Number_Of_Messages <= 1U) ? true : contiguous_impl<0U>::value; - - using handler_ptr = etl::fsm_state_id_t (*)(TDerived&, const etl::imessage&); ///< Pointer to a handler function that takes a reference to the derived class and a reference to the message. - using message_dispatch_table_t = etl::array; ///< The dispatch table type. An array of handler pointers, one for each message type. - using message_id_table_t = etl::array; ///< The message id table type. An array of message ids, one for each message type. - - //******************************************** - etl::fsm_state_id_t process_event(const etl::imessage& message) - { - const etl::message_id_t id = message.get_message_id(); - - // The IDs are sorted, so an ID less than the first is not handled by this router. - if (id >= Message_Id_Start) - { - const size_t index = get_dispatch_index_from_message_id(id); - - // If the index is less than Number_Of_Messages, then we have a handler for this message type, so dispatch it. - if (index < Number_Of_Messages) - { - const etl::fsm_state_id_t new_state_id = dispatch(message, index); - - if (new_state_id != Pass_To_Parent) - { - return new_state_id; - } - } - } - -#include "etl/private/diagnostic_array_bounds_push.h" - // If we get here, then we don't have a handler for this message type, so pass it to the parent if we have one, otherwise call on_event_unknown. - return (p_parent != nullptr) ? p_parent->process_event(message) : static_cast(this)->on_event_unknown(message); -#include "etl/private/diagnostic_pop.h" - } - - //********************************************** - // Call for a single message type - //********************************************** - template - static etl::fsm_state_id_t call_on_event(TDerived& derived, const imessage& msg) - { - return derived.on_event(static_cast(msg)); - } - - //********************************************** - // Get the handler for a single message type at the index in the sorted type_list. - // This will be called for each message type to generate the dispatch table. - //********************************************** - template - static constexpr handler_ptr get_message_handler() - { - return &call_on_event>; - } - - //********************************************** - // Generate the dispatch table at compile time. - // This will create an array of handler pointers, one for each message type. - //********************************************** - template - static constexpr message_dispatch_table_t make_message_dispatch_table(etl::index_sequence) - { - return message_dispatch_table_t{ { get_message_handler()... } }; - } - - //********************************************** - // Get the message id for a single message type at an index in the sorted type_list. - // This will be called for each message type to generate the message id table. - //********************************************** - template - static constexpr etl::message_id_t get_message_id_from_index() - { - return etl::type_list_type_at_index_t::ID; - } - - //********************************************** - // Generate the message id table at compile time. - // This will create an array of message ids, one for each message type. - //********************************************** - template - static constexpr message_id_table_t make_message_id_table(etl::index_sequence) - { - return message_id_table_t{ { get_message_id_from_index()... } }; - } - - //********************************************** - // Get the dispatch index for a message id. - // This will be used at runtime to find the handler for a message id. - // If the message ids are contiguous, we can calculate the index directly. If they are not contiguous, we need to do a binary search. - // This will return Number_Of_Messages if the message id is not found. - //********************************************** - static size_t get_dispatch_index_from_message_id(etl::message_id_t id) - { - if ETL_IF_CONSTEXPR(Message_Ids_Are_Contiguous) - { - // The IDs are contiguous, so we can calculate the index directly. - return static_cast(id - Message_Id_Start); - } - else - { - // The IDs are not contiguous, so we need to do a binary search. - size_t left = 0; - size_t right = Number_Of_Messages; - - while (left < right) - { - size_t mid = (left + right) / 2; - - if (message_id_table[mid] == id) - { - return mid; - } - else if (message_id_table[mid] < id) - { - left = mid + 1; - } - else - { - right = mid; - } - } - } - - return Number_Of_Messages; // Not found - } - - //********************************************** - // Dispatch the message to the appropriate handler based on the index in the dispatch table. - //********************************************** - etl::fsm_state_id_t dispatch(const etl::imessage& msg, size_t index) - { - return message_dispatch_table[index](static_cast(*this), msg); - } - - //********************************************** - // The dispatch table is generated at compile time. The dispatch table contains pointers to the on_receive handlers for each message type. - //********************************************** - static ETL_INLINE_VAR constexpr message_dispatch_table_t message_dispatch_table = - etl::fsm_state::make_message_dispatch_table(etl::make_index_sequence::Number_Of_Messages>{}); - - //********************************************** - // The message id table is generated at compile time. The message id table contains the corresponding message ids for each message type. - //********************************************** - static ETL_INLINE_VAR constexpr message_id_table_t message_id_table = - etl::fsm_state::make_message_id_table(etl::make_index_sequence::Number_Of_Messages>{}); - }; - -#if ETL_USING_CPP11 && !ETL_USING_CPP17 - template - constexpr const typename etl::fsm_state::message_dispatch_table_t - etl::fsm_state::message_dispatch_table; - - template - constexpr const typename etl::fsm_state::message_id_table_t - etl::fsm_state::message_id_table; -#endif - - /// Definition of STATE_ID - template - ETL_CONSTANT etl::fsm_state_id_t fsm_state::STATE_ID; - - //*************************************************************************** - // The definition for no messages. - //*************************************************************************** - template - class fsm_state : public ifsm_state - { - private: - - using message_id_sequence = etl::index_sequence<>; - - public: - - using message_types = etl::type_list<>; - using sorted_message_types = etl::type_list<>; - - static ETL_CONSTANT etl::fsm_state_id_t STATE_ID = STATE_ID_; - - fsm_state() - : ifsm_state(STATE_ID) - { - } - - protected: - - ~fsm_state() - { - } - - TContext& get_fsm_context() const - { - return static_cast(ifsm_state::get_fsm_context()); - } - - private: - - //******************************************** - etl::fsm_state_id_t process_event(const etl::imessage& message) - { - return (p_parent != nullptr) ? p_parent->process_event(message) : static_cast(this)->on_event_unknown(message); - } - }; - -#else -//************************************************************************************************* -// For C++03 and below. -//************************************************************************************************* - /*[[[cog - import cog - ################################################ - # The first definition for all of the events. - ################################################ - cog.outl("//***************************************************************************") - cog.outl("// The definition for all %s message types." % Handlers) - cog.outl("//***************************************************************************") - cog.outl("template " % Handlers) - cog.outl("class fsm_state : public ifsm_state") - cog.outl("{") - cog.outl("public:") - cog.outl("") - cog.outl(" static ETL_CONSTANT etl::fsm_state_id_t STATE_ID = STATE_ID_;") - cog.outl("") - cog.outl(" fsm_state()") - cog.outl(" : ifsm_state(STATE_ID)") - cog.outl(" {") - cog.outl(" }") - cog.outl("") - cog.outl("protected:") - cog.outl("") - cog.outl(" ~fsm_state()") - cog.outl(" {") - cog.outl(" }") - cog.outl("") - cog.outl(" TContext& get_fsm_context() const") - cog.outl(" {") - cog.outl(" return static_cast(ifsm_state::get_fsm_context());") - cog.outl(" }") - cog.outl("") - cog.outl("private:") - cog.outl("") - cog.outl(" etl::fsm_state_id_t process_event(const etl::imessage& message)") - cog.outl(" {") - cog.outl(" etl::fsm_state_id_t new_state_id;") - cog.outl(" etl::message_id_t event_id = message.get_message_id();") - cog.outl("") - cog.outl(" switch (event_id)") - cog.outl(" {") - for n in range(1, int(Handlers) + 1): - cog.out(" case T%d::ID:" % n) - cog.out(" new_state_id = static_cast(this)->on_event(static_cast(message));" % n) - cog.outl(" break;") - cog.out(" default:") - cog.out(" new_state_id = p_parent ? p_parent->process_event(message) : static_cast(this)->on_event_unknown(message);") - cog.outl(" break;") - cog.outl(" }") - cog.outl("") - cog.outl(" return (new_state_id != Pass_To_Parent) ? new_state_id : (p_parent ? p_parent->process_event(message) : No_State_Change);") - cog.outl(" }") - cog.outl("};") - - #################################### - # All of the other specialisations. - #################################### - for n in range(int(Handlers) - 1, 0, -1): - cog.outl("") - cog.outl("//***************************************************************************") - if n == 1: - cog.outl("// Specialisation for %d message type." % n) - else: - cog.outl("// Specialisation for %d message types." % n) - cog.outl("//***************************************************************************") - cog.outl("template " % n) - cog.out("class fsm_state : public ifsm_state") - cog.outl("{") - cog.outl("public:") - cog.outl("") - cog.outl(" static ETL_CONSTANT etl::fsm_state_id_t STATE_ID = STATE_ID_;") - cog.outl("") - cog.outl(" fsm_state()") - cog.outl(" : ifsm_state(STATE_ID)") - cog.outl(" {") - cog.outl(" }") - cog.outl("") - cog.outl("protected:") - cog.outl("") - cog.outl(" ~fsm_state()") - cog.outl(" {") - cog.outl(" }") - cog.outl("") - cog.outl(" TContext& get_fsm_context() const") - cog.outl(" {") - cog.outl(" return static_cast(ifsm_state::get_fsm_context());") - cog.outl(" }") - cog.outl("") - cog.outl("private:") - cog.outl("") - cog.outl(" etl::fsm_state_id_t process_event(const etl::imessage& message)") - cog.outl(" {") - cog.outl(" etl::fsm_state_id_t new_state_id;") - cog.outl(" etl::message_id_t event_id = message.get_message_id();") - cog.outl("") - cog.outl(" switch (event_id)") - cog.outl(" {") - for n in range(1, n + 1): - cog.out(" case T%d::ID:" % n) - cog.out(" new_state_id = static_cast(this)->on_event(static_cast(message));" % n) - cog.outl(" break;") - cog.out(" default:") - cog.out(" new_state_id = p_parent ? p_parent->process_event(message) : static_cast(this)->on_event_unknown(message);") - cog.outl(" break;") - cog.outl(" }") - cog.outl("") - cog.outl(" return (new_state_id != Pass_To_Parent) ? new_state_id : (p_parent ? p_parent->process_event(message) : No_State_Change);") - cog.outl(" }") - cog.outl("};") - #################################### - # Specialisation for zero messages. - #################################### - cog.outl("") - cog.outl("//***************************************************************************") - cog.outl("// Specialisation for 0 message types.") - cog.outl("//***************************************************************************") - cog.outl("template ") - cog.out("class fsm_state : public ifsm_state") - cog.outl("{") - cog.outl("public:") - cog.outl("") - cog.outl(" static ETL_CONSTANT etl::fsm_state_id_t STATE_ID = STATE_ID_;") - cog.outl("") - cog.outl(" fsm_state()") - cog.outl(" : ifsm_state(STATE_ID)") - cog.outl(" {") - cog.outl(" }") - cog.outl("") - cog.outl("protected:") - cog.outl("") - cog.outl(" ~fsm_state()") - cog.outl(" {") - cog.outl(" }") - cog.outl("") - cog.outl(" TContext& get_fsm_context() const") - cog.outl(" {") - cog.outl(" return static_cast(ifsm_state::get_fsm_context());") - cog.outl(" }") - cog.outl("private:") - cog.outl("") - cog.outl(" etl::fsm_state_id_t process_event(const etl::imessage& message)") - cog.outl(" {") - cog.outl(" return p_parent ? p_parent->process_event(message) : static_cast(this)->on_event_unknown(message);") - cog.outl(" }") - cog.outl("};") - - cog.outl("") - cog.outl("template " % Handlers) - cog.out("ETL_CONSTANT etl::fsm_state_id_t fsm_state::STATE_ID;" % Handlers) - ]]]*/ - /*[[[end]]]*/ -#endif -} - -#include "private/minmax_pop.h" - -#endif diff --git a/include/etl/generators/generate.bat b/include/etl/generators/generate.bat index bee06d99..289d17e8 100644 --- a/include/etl/generators/generate.bat +++ b/include/etl/generators/generate.bat @@ -1,9 +1,13 @@ -python3 -m cogapp -d -e -o../fsm.h -DHandlers=16 fsm_generator.h -python3 -m cogapp -d -e -o../message_router.h -DHandlers=16 message_router_generator.h -python3 -m cogapp -d -e -o../largest.h -DNTypes=16 largest_generator.h -python3 -m cogapp -d -e -o../smallest.h -DNTypes=16 smallest_generator.h -python3 -m cogapp -d -e -o../type_traits.h -DIsOneOf=16 type_traits_generator.h -python3 -m cogapp -d -e -o../type_lookup.h -DNTypes=16 type_lookup_generator.h -python3 -m cogapp -d -e -o../type_select.h -DNTypes=16 type_select_generator.h -python3 -m cogapp -d -e -o../message_packet.h -DHandlers=16 message_packet_generator.h -python3 -m cogapp -d -e -o../variant_pool.h -DNTypes=16 variant_pool_generator.h +python3 -m cogapp -d -e -o../private/fsm_fwd_decl_cpp03.h -DHandlers=16 fsm_fwd_decl_cpp03_generator.h +python3 -m cogapp -d -e -o../private/fsm_friend_decl_cpp03.h -DHandlers=16 fsm_friend_decl_cpp03_generator.h +python3 -m cogapp -d -e -o../private/fsm_cpp03.h -DHandlers=16 fsm_cpp03_generator.h +python3 -m cogapp -d -e -o../private/message_router_cpp03.h -DHandlers=16 message_router_cpp03_generator.h +python3 -m cogapp -d -e -o../private/largest_type_cpp03.h -DNTypes=16 largest_type_cpp03_generator.h +python3 -m cogapp -d -e -o../private/largest_alignment_cpp03.h -DNTypes=16 largest_alignment_cpp03_generator.h +python3 -m cogapp -d -e -o../private/largest_cpp03.h -DNTypes=16 largest_cpp03_generator.h +python3 -m cogapp -d -e -o../private/smallest_cpp03.h -DNTypes=16 smallest_cpp03_generator.h +python3 -m cogapp -d -e -o../private/type_traits_cpp03.h -DIsOneOf=16 type_traits_cpp03_generator.h +python3 -m cogapp -d -e -o../private/type_lookup_cpp03.h -DNTypes=16 type_lookup_cpp03_generator.h +python3 -m cogapp -d -e -o../private/type_select_cpp03.h -DNTypes=16 type_select_cpp03_generator.h +python3 -m cogapp -d -e -o../private/message_packet_cpp03.h -DHandlers=16 message_packet_cpp03_generator.h +python3 -m cogapp -d -e -o../private/variant_pool_cpp03.h -DNTypes=16 variant_pool_cpp03_generator.h diff --git a/include/etl/generators/generate_fsm.bat b/include/etl/generators/generate_fsm.bat index 32c8304f..9ddeb11e 100644 --- a/include/etl/generators/generate_fsm.bat +++ b/include/etl/generators/generate_fsm.bat @@ -1 +1,3 @@ -python3 -m cogapp -d -e -o../fsm.h -DHandlers=16 fsm_generator.h +python3 -m cogapp -d -e -o../private/fsm_fwd_decl_cpp03.h -DHandlers=16 fsm_fwd_decl_cpp03_generator.h +python3 -m cogapp -d -e -o../private/fsm_friend_decl_cpp03.h -DHandlers=16 fsm_friend_decl_cpp03_generator.h +python3 -m cogapp -d -e -o../private/fsm_cpp03.h -DHandlers=16 fsm_cpp03_generator.h diff --git a/include/etl/generators/generate_largest.bat b/include/etl/generators/generate_largest.bat index ce76d1c2..704dd535 100644 --- a/include/etl/generators/generate_largest.bat +++ b/include/etl/generators/generate_largest.bat @@ -1 +1,3 @@ -python3 -m cogapp -d -e -o../largest.h -DNTypes=16 largest_generator.h +python3 -m cogapp -d -e -o../private/largest_type_cpp03.h -DNTypes=16 largest_type_cpp03_generator.h +python3 -m cogapp -d -e -o../private/largest_alignment_cpp03.h -DNTypes=16 largest_alignment_cpp03_generator.h +python3 -m cogapp -d -e -o../private/largest_cpp03.h -DNTypes=16 largest_cpp03_generator.h diff --git a/include/etl/generators/generate_message_packet.bat b/include/etl/generators/generate_message_packet.bat index 37a096e5..414a1f18 100644 --- a/include/etl/generators/generate_message_packet.bat +++ b/include/etl/generators/generate_message_packet.bat @@ -1 +1 @@ -python3 -m cogapp -d -e -o../message_packet.h -DHandlers=16 message_packet_generator.h +python3 -m cogapp -d -e -o../private/message_packet_cpp03.h -DHandlers=16 message_packet_cpp03_generator.h diff --git a/include/etl/generators/generate_message_router.bat b/include/etl/generators/generate_message_router.bat index a54586d6..0fd435c1 100644 --- a/include/etl/generators/generate_message_router.bat +++ b/include/etl/generators/generate_message_router.bat @@ -1 +1 @@ -python3 -m cogapp -d -e -o../message_router.h -DHandlers=16 message_router_generator.h +python3 -m cogapp -d -e -o../private/message_router_cpp03.h -DHandlers=16 message_router_cpp03_generator.h diff --git a/include/etl/generators/generate_smallest.bat b/include/etl/generators/generate_smallest.bat index 70b7da9c..5ad79081 100644 --- a/include/etl/generators/generate_smallest.bat +++ b/include/etl/generators/generate_smallest.bat @@ -1 +1 @@ -python3 -m cogapp -d -e -o../smallest.h -DNTypes=16 smallest_generator.h +python3 -m cogapp -d -e -o../private/smallest_cpp03.h -DNTypes=16 smallest_cpp03_generator.h diff --git a/include/etl/generators/generate_type_lookup.bat b/include/etl/generators/generate_type_lookup.bat index 198a50ed..7bed051c 100644 --- a/include/etl/generators/generate_type_lookup.bat +++ b/include/etl/generators/generate_type_lookup.bat @@ -1 +1 @@ -python3 -m cogapp -d -e -o../type_lookup.h -DNTypes=16 type_lookup_generator.h +python3 -m cogapp -d -e -o../private/type_lookup_cpp03.h -DNTypes=16 type_lookup_cpp03_generator.h diff --git a/include/etl/generators/generate_type_select.bat b/include/etl/generators/generate_type_select.bat index 2a68cf63..91613c03 100644 --- a/include/etl/generators/generate_type_select.bat +++ b/include/etl/generators/generate_type_select.bat @@ -1 +1 @@ -python3 -m cogapp -d -e -o../type_select.h -DNTypes=16 type_select_generator.h +python3 -m cogapp -d -e -o../private/type_select_cpp03.h -DNTypes=16 type_select_cpp03_generator.h diff --git a/include/etl/generators/generate_type_traits.bat b/include/etl/generators/generate_type_traits.bat index 27a48516..8acc50ce 100644 --- a/include/etl/generators/generate_type_traits.bat +++ b/include/etl/generators/generate_type_traits.bat @@ -1 +1 @@ -python3 -m cogapp -d -e -o../type_traits.h -DIsOneOf=16 type_traits_generator.h +python3 -m cogapp -d -e -o../private/type_traits_cpp03.h -DIsOneOf=16 type_traits_cpp03_generator.h diff --git a/include/etl/generators/generate_variant_pool.bat b/include/etl/generators/generate_variant_pool.bat index e81e4d84..4fdf27c4 100644 --- a/include/etl/generators/generate_variant_pool.bat +++ b/include/etl/generators/generate_variant_pool.bat @@ -1 +1 @@ -python3 -m cogapp -d -e -o../variant_pool.h -DNTypes=16 variant_pool_generator.h +python3 -m cogapp -d -e -o../private/variant_pool_cpp03.h -DNTypes=16 variant_pool_cpp03_generator.h diff --git a/include/etl/generators/largest_alignment_cpp03_generator.h b/include/etl/generators/largest_alignment_cpp03_generator.h new file mode 100644 index 00000000..7e9a40ad --- /dev/null +++ b/include/etl/generators/largest_alignment_cpp03_generator.h @@ -0,0 +1,66 @@ +//*************************************************************************** +// THIS FILE HAS BEEN AUTO GENERATED. DO NOT EDIT THIS FILE. +//*************************************************************************** + + /*[[[cog + import cog + cog.outl("//***************************************************************************") + cog.outl("/// Template to determine the largest alignment.") + cog.outl("/// Supports up to %s types." % int(NTypes)) + cog.outl("/// Defines value which is the largest alignment of all the parameters.") + cog.outl("///\\ingroup largest") + cog.outl("//***************************************************************************") + cog.out("template " % int(NTypes)) + cog.outl("struct largest_alignment") + cog.outl("{") + cog.outl(" // Define 'largest_other' as 'largest_type' with all but the first parameter. ") + cog.out(" typedef typename largest_alignment<") + for n in range(2, int(NTypes)): + cog.out("T%s, " % n) + if n % 16 == 0: + cog.outl("") + cog.out(" ") + cog.outl("T%s>::type largest_other;" % int(NTypes)) + cog.outl("") + cog.outl(" // Set 'type' to be the largest of the first parameter and any of the others.") + cog.outl(" // This is recursive.") + cog.outl(" typedef typename etl::conditional<(etl::alignment_of::value > etl::alignment_of::value), // Boolean") + cog.outl(" T1, // TrueType") + cog.outl(" largest_other> // FalseType") + cog.outl(" ::type type; // The largest type of the two.") + cog.outl("") + cog.outl(" // The largest alignment.") + cog.outl(" enum") + cog.outl(" {") + cog.outl(" value = etl::alignment_of::value") + cog.outl(" };") + cog.outl("};") + cog.outl("") + cog.outl("//***************************************************************************") + cog.outl("// Specialisation for one template parameter.") + cog.outl("//***************************************************************************") + cog.outl("template ") + cog.out("struct largest_alignment") + cog.outl("{") + cog.outl(" typedef T1 type;") + cog.outl("") + cog.outl(" enum") + cog.outl(" {") + cog.outl(" value = etl::alignment_of::value") + cog.outl(" };") + cog.outl("};") + ]]]*/ + /*[[[end]]]*/ + diff --git a/include/etl/generators/largest_cpp03_generator.h b/include/etl/generators/largest_cpp03_generator.h new file mode 100644 index 00000000..54369dad --- /dev/null +++ b/include/etl/generators/largest_cpp03_generator.h @@ -0,0 +1,50 @@ +//*************************************************************************** +// THIS FILE HAS BEEN AUTO GENERATED. DO NOT EDIT THIS FILE. +//*************************************************************************** + + /*[[[cog + import cog + cog.outl("//***************************************************************************") + cog.outl("/// Template to determine the largest type, size and alignment.") + cog.outl("/// Supports up to %s types." % NTypes) + cog.outl("/// Defines value which is the largest type, size and alignment of all the parameters.") + cog.outl("///\\ingroup largest") + cog.outl("//***************************************************************************") + cog.out("template " % NTypes) + cog.outl("struct largest") + cog.outl("{") + cog.out(" typedef typename etl::largest_type<") + for n in range(1, int(NTypes)): + cog.out("T%s, " % n) + if n % 16 == 0: + cog.outl("") + cog.out(" ") + cog.outl("T%s>::type type;" % NTypes) + cog.outl("") + cog.outl(" enum") + cog.outl(" {") + cog.out(" size = etl::largest_type<") + for n in range(1, int(NTypes)): + cog.out("T%s, " % n) + if n % 16 == 0: + cog.outl("") + cog.out(" ") + cog.outl("T%s>::size," % NTypes) + cog.out(" alignment = etl::largest_alignment<") + for n in range(1, int(NTypes)): + cog.out("T%s, " % n) + if n % 16 == 0: + cog.outl("") + cog.out(" ") + cog.outl("T%s>::value" % NTypes) + cog.outl(" };") + cog.outl("};") + ]]]*/ + /*[[[end]]]*/ + diff --git a/include/etl/generators/largest_generator.h b/include/etl/generators/largest_generator.h deleted file mode 100644 index ff31d050..00000000 --- a/include/etl/generators/largest_generator.h +++ /dev/null @@ -1,452 +0,0 @@ -///\file - -/****************************************************************************** -The MIT License(MIT) - -Embedded Template Library. -https://github.com/ETLCPP/etl -https://www.etlcpp.com - -Copyright(c) 2014 John Wellbelove - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files(the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions : - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -******************************************************************************/ - -/*[[[cog -import cog -cog.outl("#if 0") -]]]*/ -/*[[[end]]]*/ -#error THIS HEADER IS A GENERATOR. DO NOT INCLUDE. -/*[[[cog -import cog -cog.outl("#endif") -]]]*/ -/*[[[end]]]*/ - -/*[[[cog -import cog -cog.outl("//***************************************************************************") -cog.outl("// THIS FILE HAS BEEN AUTO GENERATED. DO NOT EDIT THIS FILE.") -cog.outl("//***************************************************************************") -]]]*/ -/*[[[end]]]*/ - -//*************************************************************************** -// To generate to header file, run this at the command line. -// Note: You will need Python and COG installed. -// -// cog -d -e -olargest.h -DNTypes= largest_generator.h -// Where is the number of types to support. -// -// e.g. -// To generate handlers for up to 16 types... -// cog -d -e -olargest.h -DNTypes=16 largest_generator.h -// -// See generate.bat -//*************************************************************************** - -#ifndef ETL_LARGEST_INCLUDED -#define ETL_LARGEST_INCLUDED - -///\defgroup largest largest -///\ingroup utilities - -#include "platform.h" -#include "type_traits.h" -#include "smallest.h" -#include "static_assert.h" - -namespace etl -{ -#if ETL_USING_CPP11 && !defined(ETL_LARGEST_TYPE_FORCE_CPP03_IMPLEMENTATION) - //*************************************************************************** - /// Template to determine the largest type and size. - /// Defines 'value_type' which is the type of the largest parameter. - /// Defines 'size' which is the size of the largest parameter. - ///\ingroup largest - //*************************************************************************** - template - class largest_type - { - private: - - // Define 'largest_other' as 'largest_type' with all but the first parameter. - using largest_other = typename largest_type::type; - - public: - - // Set 'type' to be the largest of the first parameter and any of the others. - // This is recursive. - using type = typename etl::conditional<(etl::size_of::value > etl::size_of::value), // Boolean - T1, // TrueType - largest_other> // FalseType - ::type; // The largest type of the two. - - // The size of the largest type. - enum - { - size = etl::size_of::value - }; - }; - - //*************************************************************************** - // Specialisation for one template parameter. - //*************************************************************************** - template - class largest_type - { - public: - - using type = T1; - - enum - { - size = etl::size_of::value - }; - }; - -#if ETL_USING_CPP11 - template - using largest_type_t = typename largest_type::type; -#endif - -#if ETL_USING_CPP17 - template - constexpr size_t largest_type_v = largest_type::size; -#endif - -#else - /*[[[cog - import cog - cog.outl("//***************************************************************************") - cog.outl("/// Template to determine the largest type and size.") - cog.outl("/// Supports up to %s types." % NTypes) - cog.outl("/// Defines 'value_type' which is the type of the largest parameter.") - cog.outl("/// Defines 'size' which is the size of the largest parameter.") - cog.outl("///\\ingroup largest") - cog.outl("//***************************************************************************") - cog.out("template " % int(NTypes)) - cog.outl("struct largest_type") - cog.outl("{") - cog.outl(" // Define 'largest_other' as 'largest_type' with all but the first parameter. ") - cog.out(" typedef typename largest_type<") - for n in range(2, int(NTypes)): - cog.out("T%s, " % n) - if n % 16 == 0: - cog.outl("") - cog.out(" ") - cog.outl("T%s>::type largest_other;" % int(NTypes)) - cog.outl("") - cog.outl(" // Set 'type' to be the largest of the first parameter and any of the others.") - cog.outl(" // This is recursive.") - cog.outl(" typedef typename etl::conditional<(sizeof(T1) > sizeof(largest_other)), // Boolean") - cog.outl(" T1, // TrueType") - cog.outl(" largest_other> // FalseType") - cog.outl(" ::type type; // The largest type of the two.") - cog.outl("") - cog.outl(" // The size of the largest type.") - cog.outl(" enum") - cog.outl(" {") - cog.outl(" size = sizeof(type)") - cog.outl(" };") - cog.outl("};") - cog.outl("") - cog.outl("//***************************************************************************") - cog.outl("// Specialisation for one template parameter.") - cog.outl("//***************************************************************************") - cog.outl("template ") - cog.out("struct largest_type") - cog.outl("{") - cog.outl(" typedef T1 type;") - cog.outl("") - cog.outl(" enum") - cog.outl(" {") - cog.outl(" size = sizeof(type)") - cog.outl(" };") - cog.outl("};") - ]]]*/ - /*[[[end]]]*/ -#endif - -#if ETL_USING_CPP11 && !defined(ETL_LARGEST_ALIGNMENT_FORCE_CPP03_IMPLEMENTATION) - //*************************************************************************** - /// Template to determine the largest alignment. - /// Defines value which is the largest alignment of all the parameters. - ///\ingroup largest - //*************************************************************************** - template - struct largest_alignment - { - // Define 'largest_other' as 'largest_type' with all but the first parameter. - using largest_other = typename largest_alignment::type; - - // Set 'type' to be the largest of the first parameter and any of the others. - // This is recursive. - using type = typename etl::conditional<(etl::alignment_of::value > etl::alignment_of::value), // Boolean - T1, // TrueType - largest_other> // FalseType - ::type; // The largest type of the two. - - // The largest alignment. - enum - { - value = etl::alignment_of::value - }; - }; - - //*************************************************************************** - // Specialisation for one template parameter. - //*************************************************************************** - template - struct largest_alignment - { - typedef T1 type; - - enum - { - value = etl::alignment_of::value - }; - }; - -#if ETL_USING_CPP17 - template - inline constexpr size_t largest_alignment_v = largest_alignment::value; -#endif - -#else - /*[[[cog - import cog - cog.outl("//***************************************************************************") - cog.outl("/// Template to determine the largest alignment.") - cog.outl("/// Supports up to %s types." % int(NTypes)) - cog.outl("/// Defines value which is the largest alignment of all the parameters.") - cog.outl("///\\ingroup largest") - cog.outl("//***************************************************************************") - cog.out("template " % int(NTypes)) - cog.outl("struct largest_alignment") - cog.outl("{") - cog.outl(" // Define 'largest_other' as 'largest_type' with all but the first parameter. ") - cog.out(" typedef typename largest_alignment<") - for n in range(2, int(NTypes)): - cog.out("T%s, " % n) - if n % 16 == 0: - cog.outl("") - cog.out(" ") - cog.outl("T%s>::type largest_other;" % int(NTypes)) - cog.outl("") - cog.outl(" // Set 'type' to be the largest of the first parameter and any of the others.") - cog.outl(" // This is recursive.") - cog.outl(" typedef typename etl::conditional<(etl::alignment_of::value > etl::alignment_of::value), // Boolean") - cog.outl(" T1, // TrueType") - cog.outl(" largest_other> // FalseType") - cog.outl(" ::type type; // The largest type of the two.") - cog.outl("") - cog.outl(" // The largest alignment.") - cog.outl(" enum") - cog.outl(" {") - cog.outl(" value = etl::alignment_of::value") - cog.outl(" };") - cog.outl("};") - cog.outl("") - cog.outl("//***************************************************************************") - cog.outl("// Specialisation for one template parameter.") - cog.outl("//***************************************************************************") - cog.outl("template ") - cog.out("struct largest_alignment") - cog.outl("{") - cog.outl(" typedef T1 type;") - cog.outl("") - cog.outl(" enum") - cog.outl(" {") - cog.outl(" value = etl::alignment_of::value") - cog.outl(" };") - cog.outl("};") - ]]]*/ - /*[[[end]]]*/ -#endif - - //*************************************************************************** - /// Defines a type that is as larger or larger than the specified type. - /// Will return the specified type is there is not a larger type. - ///\\ingroup largest - //*************************************************************************** - template - struct larger_int_type - { - ETL_STATIC_ASSERT(etl::is_integral::value, "Must be an integral type"); - - typedef typename etl::smallest_int_for_bits::type>::bits + 1>::type type; - }; - -#if ETL_USING_CPP11 - template - using larger_int_type_t = typename larger_int_type::type; -#endif - - //*************************************************************************** - /// Defines a type that is as larger or larger than the specified type. - /// Will return the specified type is there is not a larger type. - ///\ingroup largest - //*************************************************************************** - template - struct larger_uint_type - { - ETL_STATIC_ASSERT(etl::is_integral::value, "Must be an integral type"); - - typedef typename etl::smallest_uint_for_bits::type>::bits + 1>::type type; - }; - -#if ETL_USING_CPP11 - template - using larger_uint_type_t = typename larger_uint_type::type; -#endif - - //*************************************************************************** - /// Defines a type that is as larger or larger than the specified type. - /// Will return the specified type is there is not a larger type. - /// The returned type will be of the same sign. - ///\ingroup largest - //*************************************************************************** - template ::value> - struct larger_type; - - template - struct larger_type - { - ETL_STATIC_ASSERT(etl::is_integral::value, "Must be an integral type"); - - typedef typename etl::smallest_uint_for_bits::bits + 1>::type type; - }; - - template - struct larger_type - { - ETL_STATIC_ASSERT(etl::is_integral::value, "Must be an integral type"); - - typedef typename etl::smallest_int_for_bits::bits + 1>::type type; - }; - -#if ETL_USING_CPP11 - template - using larger_type_t = typename larger_type::type; -#endif - -#if ETL_USING_CPP11 && !defined(ETL_LARGEST_FORCE_CPP03_IMPLEMENTATION) - //*************************************************************************** - /// Template to determine the largest type, size and alignment. - /// Defines value which is the largest type, size and alignment of all the parameters. - ///\ingroup largest - //*************************************************************************** - template - struct largest - { - using type = typename etl::largest_type::type; - - enum - { - size = etl::largest_type::size, - alignment = etl::largest_alignment::value - }; - }; - -#if ETL_USING_CPP11 - template - using largest_t = typename largest::type; -#endif - -#if ETL_USING_CPP17 - template - inline constexpr size_t largest_size = largest::size; -#endif - -#else - /*[[[cog - import cog - cog.outl("//***************************************************************************") - cog.outl("/// Template to determine the largest type, size and alignment.") - cog.outl("/// Supports up to %s types." % NTypes) - cog.outl("/// Defines value which is the largest type, size and alignment of all the parameters.") - cog.outl("///\\ingroup largest") - cog.outl("//***************************************************************************") - cog.out("template " % NTypes) - cog.outl("struct largest") - cog.outl("{") - cog.out(" typedef typename etl::largest_type<") - for n in range(1, int(NTypes)): - cog.out("T%s, " % n) - if n % 16 == 0: - cog.outl("") - cog.out(" ") - cog.outl("T%s>::type type;" % NTypes) - cog.outl("") - cog.outl(" enum") - cog.outl(" {") - cog.out(" size = etl::largest_type<") - for n in range(1, int(NTypes)): - cog.out("T%s, " % n) - if n % 16 == 0: - cog.outl("") - cog.out(" ") - cog.outl("T%s>::size," % NTypes) - cog.out(" alignment = etl::largest_alignment<") - for n in range(1, int(NTypes)): - cog.out("T%s, " % n) - if n % 16 == 0: - cog.outl("") - cog.out(" ") - cog.outl("T%s>::value" % NTypes) - cog.outl(" };") - cog.outl("};") - ]]]*/ - /*[[[end]]]*/ -#endif -} - -#endif diff --git a/include/etl/generators/largest_type_cpp03_generator.h b/include/etl/generators/largest_type_cpp03_generator.h new file mode 100644 index 00000000..aa603ce1 --- /dev/null +++ b/include/etl/generators/largest_type_cpp03_generator.h @@ -0,0 +1,67 @@ +//*************************************************************************** +// THIS FILE HAS BEEN AUTO GENERATED. DO NOT EDIT THIS FILE. +//*************************************************************************** + + /*[[[cog + import cog + cog.outl("//***************************************************************************") + cog.outl("/// Template to determine the largest type and size.") + cog.outl("/// Supports up to %s types." % NTypes) + cog.outl("/// Defines 'type' which is the type of the largest parameter.") + cog.outl("/// Defines 'size' which is the size of the largest parameter.") + cog.outl("///\\ingroup largest") + cog.outl("//***************************************************************************") + cog.out("template " % int(NTypes)) + cog.outl("struct largest_type") + cog.outl("{") + cog.outl(" // Define 'largest_other' as 'largest_type' with all but the first parameter. ") + cog.out(" typedef typename largest_type<") + for n in range(2, int(NTypes)): + cog.out("T%s, " % n) + if n % 16 == 0: + cog.outl("") + cog.out(" ") + cog.outl("T%s>::type largest_other;" % int(NTypes)) + cog.outl("") + cog.outl(" // Set 'type' to be the largest of the first parameter and any of the others.") + cog.outl(" // This is recursive.") + cog.outl(" typedef typename etl::conditional<(sizeof(T1) > sizeof(largest_other)), // Boolean") + cog.outl(" T1, // TrueType") + cog.outl(" largest_other> // FalseType") + cog.outl(" ::type type; // The largest type of the two.") + cog.outl("") + cog.outl(" // The size of the largest type.") + cog.outl(" enum") + cog.outl(" {") + cog.outl(" size = sizeof(type)") + cog.outl(" };") + cog.outl("};") + cog.outl("") + cog.outl("//***************************************************************************") + cog.outl("// Specialisation for one template parameter.") + cog.outl("//***************************************************************************") + cog.outl("template ") + cog.out("struct largest_type") + cog.outl("{") + cog.outl(" typedef T1 type;") + cog.outl("") + cog.outl(" enum") + cog.outl(" {") + cog.outl(" size = sizeof(type)") + cog.outl(" };") + cog.outl("};") + ]]]*/ + /*[[[end]]]*/ + diff --git a/include/etl/generators/message_packet_generator.h b/include/etl/generators/message_packet_cpp03_generator.h similarity index 62% rename from include/etl/generators/message_packet_generator.h rename to include/etl/generators/message_packet_cpp03_generator.h index 59f3b7e5..4531735b 100644 --- a/include/etl/generators/message_packet_generator.h +++ b/include/etl/generators/message_packet_cpp03_generator.h @@ -1,529 +1,7 @@ -/****************************************************************************** -The MIT License(MIT) - -Embedded Template Library. -https://github.com/ETLCPP/etl -https://www.etlcpp.com - -Copyright(c) 2020 John Wellbelove - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files(the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions : - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -******************************************************************************/ - -/*[[[cog -import cog -cog.outl("#if 0") -]]]*/ -/*[[[end]]]*/ -#error THIS HEADER IS A GENERATOR. DO NOT INCLUDE. -/*[[[cog -import cog -cog.outl("#endif") -]]]*/ -/*[[[end]]]*/ - -/*[[[cog -import cog -cog.outl("//***************************************************************************") -cog.outl("// THIS FILE HAS BEEN AUTO GENERATED. DO NOT EDIT THIS FILE.") -cog.outl("//***************************************************************************") -]]]*/ -/*[[[end]]]*/ - //*************************************************************************** -// To generate to header file, run this at the command line. -// Note: You will need Python and COG installed. -// -// cog -d -e -omessage_packet.h -DHandlers= message_packet_generator.h -// Where is the number of messages to support. -// -// e.g. -// To generate handlers for up to 16 messages... -// cog -d -e -omessage_packet.h -DHandlers=16 message_packet_generator.h -// -// See generate.bat +// THIS FILE HAS BEEN AUTO GENERATED. DO NOT EDIT THIS FILE. //*************************************************************************** -#ifndef ETL_MESSAGE_PACKET_INCLUDED -#define ETL_MESSAGE_PACKET_INCLUDED - -#include "platform.h" - -#include "message.h" -#include "error_handler.h" -#include "static_assert.h" -#include "largest.h" -#include "alignment.h" -#include "utility.h" -#include "type_list.h" - -#include - -namespace etl -{ -#if ETL_USING_CPP17 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION) - //*************************************************************************** - // The definition for all message types. - //*************************************************************************** - template - class message_packet - { - - private: - - template - static constexpr bool IsMessagePacket = etl::is_same_v>, etl::message_packet>; - - template - static constexpr bool IsInMessageList = etl::is_one_of_v>, TMessageTypes...>; - - template - static constexpr bool IsIMessage = etl::is_same_v>, etl::imessage>; - - public: - - using message_types = etl::type_list; - - //******************************************** -#include "private/diagnostic_uninitialized_push.h" - constexpr message_packet() noexcept - : valid(false) - { - } -#include "private/diagnostic_pop.h" - - //******************************************** - /// - //******************************************** -#include "private/diagnostic_uninitialized_push.h" - template || IsInMessageList, int>::type> - explicit message_packet(T&& msg) - : valid(true) - { - if constexpr (IsIMessage) - { - if (accepts(msg)) - { - add_new_message(etl::forward(msg)); - valid = true; - } - else - { - valid = false; - } - - ETL_ASSERT(valid, ETL_ERROR(unhandled_message_exception)); - } - else if constexpr (IsInMessageList) - { - add_new_message_type(etl::forward(msg)); - } - else - { - ETL_STATIC_ASSERT(IsInMessageList, "Message not in packet type list"); - } - } -#include "private/diagnostic_pop.h" - - //********************************************** - message_packet(const message_packet& other) - { - valid = other.is_valid(); - - if (valid) - { - add_new_message(other.get()); - } - } - -#if ETL_USING_CPP11 - //********************************************** - message_packet(message_packet&& other) - { - valid = other.is_valid(); - - if (valid) - { - add_new_message(etl::move(other.get())); - } - } -#endif - - //********************************************** - void copy(const message_packet& other) - { - valid = other.is_valid(); - - if (valid) - { - add_new_message(other.get()); - } - } - - //********************************************** - void copy(message_packet&& other) - { - valid = other.is_valid(); - - if (valid) - { - add_new_message(etl::move(other.get())); - } - } - - //********************************************** -#include "private/diagnostic_uninitialized_push.h" - message_packet& operator =(const message_packet& rhs) - { - delete_current_message(); - valid = rhs.is_valid(); - if (valid) - { - add_new_message(rhs.get()); - } - - return *this; - } -#include "private/diagnostic_pop.h" - - //********************************************** -#include "private/diagnostic_uninitialized_push.h" - message_packet& operator =(message_packet&& rhs) - { - delete_current_message(); - valid = rhs.is_valid(); - if (valid) - { - add_new_message(etl::move(rhs.get())); - } - - return *this; - } -#include "private/diagnostic_pop.h" - - //******************************************** - ~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; - } - - //********************************************** - static ETL_CONSTEXPR bool accepts(etl::message_id_t id) - { - return (accepts_message(id) || ...); - } - - //********************************************** - static ETL_CONSTEXPR bool accepts(const etl::imessage& msg) - { - return accepts(msg.get_message_id()); - } - - //********************************************** - template - static ETL_CONSTEXPR bool accepts() - { - return (accepts_message() || ...); - } - - //********************************************** - template - static ETL_CONSTEXPR - typename etl::enable_if::value, bool>::type - accepts() - { - return accepts(); - } - - enum - { - SIZE = etl::largest::size, - ALIGNMENT = etl::largest::alignment - }; - - private: - - //********************************************** - template - static bool accepts_message() - { - return Id1 == Id2; - } - - //********************************************** - template - static bool accepts_message(etl::message_id_t id2) - { - return Id1 == id2; - } - - //******************************************** -#include "private/diagnostic_uninitialized_push.h" - void delete_current_message() - { - if (valid) - { - etl::imessage* pmsg = static_cast(data); - -#if ETL_HAS_VIRTUAL_MESSAGES - pmsg->~imessage(); -#else - delete_message(pmsg); -#endif - } - } -#include "private/diagnostic_pop.h" - -#if !ETL_HAS_VIRTUAL_MESSAGES - //******************************************** - void delete_message(etl::imessage* pmsg) - { - (delete_message_type(pmsg) || ...); - } - - //******************************************** - template - bool delete_message_type(etl::imessage* pmsg) - { - if (TType::ID == pmsg->get_message_id()) - { - TType* p = static_cast(pmsg); - p->~TType(); - return true; - } - else - { - return false; - } - } -#endif - - //******************************************** - void add_new_message(const etl::imessage& msg) - { - (add_new_message_type(msg) || ...); - } - - //******************************************** - void add_new_message(etl::imessage&& msg) - { - (add_new_message_type(etl::move(msg)) || ...); - } - -#include "private/diagnostic_uninitialized_push.h" - //******************************************** - /// Only enabled for types that are in the typelist. - //******************************************** - template - etl::enable_if_t>, TMessageTypes...>, void> - add_new_message_type(TMessage&& msg) - { - void* p = data; - new (p) etl::remove_reference_t((etl::forward(msg))); - } -#include "private/diagnostic_pop.h" - -#include "private/diagnostic_uninitialized_push.h" - //******************************************** - template - bool add_new_message_type(const etl::imessage& msg) - { - if (TType::ID == msg.get_message_id()) - { - void* p = data; - new (p) TType(static_cast(msg)); - return true; - } - else - { - return false; - } - } -#include "private/diagnostic_pop.h" - -#include "private/diagnostic_uninitialized_push.h" - //******************************************** - template - bool add_new_message_type(etl::imessage&& msg) - { - if (TType::ID == msg.get_message_id()) - { - void* p = data; - new (p) TType(static_cast(msg)); - return true; - } - else - { - return false; - } - } -#include "private/diagnostic_pop.h" - - typename etl::aligned_storage::type data; - bool valid; - }; - - //*************************************************************************** - // The definition for no message types. - //*************************************************************************** - template <> - class message_packet<> - { - private: - - template - static constexpr bool IsMessagePacket = etl::is_same_v>, etl::message_packet<>>; - - template - static constexpr bool IsInMessageList = false; - - template - static constexpr bool IsIMessage = etl::is_same_v>, etl::imessage>; - - public: - - using message_types = etl::type_list<>; - - //******************************************** -#include "private/diagnostic_uninitialized_push.h" - constexpr message_packet() noexcept - { - } -#include "private/diagnostic_pop.h" - - //********************************************** - message_packet(const message_packet& /*other*/) - { - } - -#if ETL_USING_CPP11 - //********************************************** - message_packet(message_packet&& /*other*/) - { - } -#endif - - //********************************************** - void copy(const message_packet& /*other*/) - { - } - - //********************************************** - void copy(message_packet&& /*other*/) - { - } - - //********************************************** -#include "private/diagnostic_uninitialized_push.h" - message_packet& operator =(const message_packet& /*rhs*/) - { - return *this; - } -#include "private/diagnostic_pop.h" - - //********************************************** -#include "private/diagnostic_uninitialized_push.h" - message_packet& operator =(message_packet&& /*rhs*/) - { - return *this; - } -#include "private/diagnostic_pop.h" - - //******************************************** - ~message_packet() - { - } - - //******************************************** - bool is_valid() const - { - return false; - } - - //********************************************** - static ETL_CONSTEXPR bool accepts(etl::message_id_t /*id*/) - { - return false; - } - - //********************************************** - static ETL_CONSTEXPR bool accepts(const etl::imessage& /*msg*/) - { - return false; - } - - //********************************************** - template - static ETL_CONSTEXPR bool accepts() - { - return false; - } - - //********************************************** - template - static ETL_CONSTEXPR - typename etl::enable_if::value, bool>::type - accepts() - { - return false; - } - - enum - { - SIZE = 0, - ALIGNMENT = 1 - }; - }; - - //*************************************************************************** - /// Helper to turn etl::type_list into etl::message_packet - template - struct message_packet_from_type_list; - - template - struct message_packet_from_type_list> - { - using type = etl::message_packet; - }; - - template - using message_packet_from_type_list_t = typename message_packet_from_type_list::type; - -#else /*[[[cog import cog @@ -611,7 +89,7 @@ namespace etl cog.outl("{") cog.outl("public:") cog.outl("") - + cog.outl("#if ETL_USING_CPP11") cog.out(" using message_types = etl::type_list<") for n in range(1, int(Handlers)): @@ -621,15 +99,15 @@ namespace etl cog.outl("") cog.outl(" //********************************************") - cog.outl("#include \"private/diagnostic_uninitialized_push.h\"") + cog.outl("#include \"diagnostic_uninitialized_push.h\"") cog.outl(" ETL_CONSTEXPR message_packet() ETL_NOEXCEPT") cog.outl(" : valid(false)") cog.outl(" {") cog.outl(" }") - cog.outl("#include \"private/diagnostic_pop.h\"") + cog.outl("#include \"diagnostic_pop.h\"") cog.outl("") cog.outl(" //********************************************") - cog.outl("#include \"private/diagnostic_uninitialized_push.h\"") + cog.outl("#include \"diagnostic_uninitialized_push.h\"") cog.outl(" explicit message_packet(const etl::imessage& msg)") cog.outl(" {") cog.outl(" if (accepts(msg))") @@ -644,11 +122,11 @@ namespace etl cog.outl("") cog.outl(" ETL_ASSERT(valid, ETL_ERROR(unhandled_message_exception));") cog.outl(" }") - cog.outl("#include \"private/diagnostic_pop.h\"") + cog.outl("#include \"diagnostic_pop.h\"") cog.outl("") cog.outl("#if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION)") cog.outl(" //********************************************") - cog.outl("#include \"private/diagnostic_uninitialized_push.h\"") + cog.outl("#include \"diagnostic_uninitialized_push.h\"") cog.outl(" explicit message_packet(etl::imessage&& msg)") cog.outl(" {") cog.outl(" if (accepts(msg))") @@ -663,12 +141,12 @@ namespace etl cog.outl("") cog.outl(" ETL_ASSERT(valid, ETL_ERROR(unhandled_message_exception));") cog.outl(" }") - cog.outl("#include \"private/diagnostic_pop.h\"") + cog.outl("#include \"diagnostic_pop.h\"") cog.outl("#endif") cog.outl("") cog.outl("#if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION) && !defined(ETL_COMPILER_GREEN_HILLS)") cog.outl(" //********************************************") - cog.outl("#include \"private/diagnostic_uninitialized_push.h\"") + cog.outl("#include \"diagnostic_uninitialized_push.h\"") cog.out(" template ::type, etl::message_packet<") for n in range(1, int(Handlers)): cog.out("T%s, " % n) @@ -683,10 +161,10 @@ namespace etl cog.outl(" {") generate_static_assert_cpp11(int(Handlers)) cog.outl(" }") - cog.outl("#include \"private/diagnostic_pop.h\"") + cog.outl("#include \"diagnostic_pop.h\"") cog.outl("#else") cog.outl(" //********************************************") - cog.outl("#include \"private/diagnostic_uninitialized_push.h\"") + cog.outl("#include \"diagnostic_uninitialized_push.h\"") cog.outl(" template ") cog.out(" explicit message_packet(const TMessage& /*msg*/, typename etl::enable_if::type, etl::message_packet<") for n in range(1, int(Handlers)): @@ -701,11 +179,11 @@ namespace etl cog.outl(" {") generate_static_assert_cpp03(int(Handlers)) cog.outl(" }") - cog.outl("#include \"private/diagnostic_pop.h\"") + cog.outl("#include \"diagnostic_pop.h\"") cog.outl("#endif") cog.outl("") cog.outl(" //**********************************************") - cog.outl("#include \"private/diagnostic_uninitialized_push.h\"") + cog.outl("#include \"diagnostic_uninitialized_push.h\"") cog.outl(" message_packet(const message_packet& other)") cog.outl(" : valid(other.is_valid())") cog.outl(" {") @@ -714,11 +192,11 @@ namespace etl cog.outl(" add_new_message(other.get());") cog.outl(" }") cog.outl(" }") - cog.outl("#include \"private/diagnostic_pop.h\"") + cog.outl("#include \"diagnostic_pop.h\"") cog.outl("") cog.outl("#if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION)") cog.outl(" //**********************************************") - cog.outl("#include \"private/diagnostic_uninitialized_push.h\"") + cog.outl("#include \"diagnostic_uninitialized_push.h\"") cog.outl(" message_packet(message_packet&& other)") cog.outl(" : valid(other.is_valid())") cog.outl(" {") @@ -727,11 +205,11 @@ namespace etl cog.outl(" add_new_message(etl::move(other.get()));") cog.outl(" }") cog.outl(" }") - cog.outl("#include \"private/diagnostic_pop.h\"") + cog.outl("#include \"diagnostic_pop.h\"") cog.outl("#endif") cog.outl("") cog.outl(" //**********************************************") - cog.outl("#include \"private/diagnostic_uninitialized_push.h\"") + cog.outl("#include \"diagnostic_uninitialized_push.h\"") cog.outl(" message_packet& operator =(const message_packet& rhs)") cog.outl(" {") cog.outl(" delete_current_message();") @@ -743,11 +221,11 @@ namespace etl cog.outl("") cog.outl(" return *this;") cog.outl(" }") - cog.outl("#include \"private/diagnostic_pop.h\"") + cog.outl("#include \"diagnostic_pop.h\"") cog.outl("") cog.outl("#if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION)") cog.outl(" //**********************************************") - cog.outl("#include \"private/diagnostic_uninitialized_push.h\"") + cog.outl("#include \"diagnostic_uninitialized_push.h\"") cog.outl(" message_packet& operator =(message_packet&& rhs)") cog.outl(" {") cog.outl(" delete_current_message();") @@ -759,7 +237,7 @@ namespace etl cog.outl("") cog.outl(" return *this;") cog.outl(" }") - cog.outl("#include \"private/diagnostic_pop.h\"") + cog.outl("#include \"diagnostic_pop.h\"") cog.outl("#endif") cog.outl("") cog.outl(" //********************************************") @@ -829,7 +307,7 @@ namespace etl cog.outl("private:") cog.outl("") cog.outl(" //********************************************") - cog.outl(" #include \"private/diagnostic_uninitialized_push.h\"") + cog.outl(" #include \"diagnostic_uninitialized_push.h\"") cog.outl(" void delete_current_message()") cog.outl(" {") cog.outl(" if (valid)") @@ -843,7 +321,7 @@ namespace etl cog.outl("#endif") cog.outl(" }") cog.outl(" }") - cog.outl(" #include \"private/diagnostic_pop.h\"") + cog.outl(" #include \"diagnostic_pop.h\"") cog.outl("") cog.outl(" //********************************************") cog.outl(" void delete_message(etl::imessage* pmsg)") @@ -856,7 +334,7 @@ namespace etl cog.outl(" default: ETL_ASSERT_FAIL(ETL_ERROR(unhandled_message_exception)); break;") cog.outl(" }") cog.outl(" }") - cog.outl("") + cog.outl("") cog.outl(" //********************************************") cog.outl(" void add_new_message(const etl::imessage& msg)") cog.outl(" {") @@ -935,15 +413,15 @@ namespace etl cog.outl("") cog.outl(" //********************************************") - cog.outl("#include \"private/diagnostic_uninitialized_push.h\"") + cog.outl("#include \"diagnostic_uninitialized_push.h\"") cog.outl(" ETL_CONSTEXPR message_packet() ETL_NOEXCEPT") cog.outl(" : valid(false)") cog.outl(" {") cog.outl(" }") - cog.outl("#include \"private/diagnostic_pop.h\"") + cog.outl("#include \"diagnostic_pop.h\"") cog.outl("") cog.outl(" //********************************************") - cog.outl("#include \"private/diagnostic_uninitialized_push.h\"") + cog.outl("#include \"diagnostic_uninitialized_push.h\"") cog.outl(" explicit message_packet(const etl::imessage& msg)") cog.outl(" {") cog.outl(" if (accepts(msg))") @@ -958,11 +436,11 @@ namespace etl cog.outl("") cog.outl(" ETL_ASSERT(valid, ETL_ERROR(unhandled_message_exception));") cog.outl(" }") - cog.outl("#include \"private/diagnostic_pop.h\"") + cog.outl("#include \"diagnostic_pop.h\"") cog.outl("") cog.outl("#if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION)") cog.outl(" //********************************************") - cog.outl("#include \"private/diagnostic_uninitialized_push.h\"") + cog.outl("#include \"diagnostic_uninitialized_push.h\"") cog.outl(" explicit message_packet(etl::imessage&& msg)") cog.outl(" {") cog.outl(" if (accepts(msg))") @@ -977,12 +455,12 @@ namespace etl cog.outl("") cog.outl(" ETL_ASSERT(valid, ETL_ERROR(unhandled_message_exception));") cog.outl(" }") - cog.outl("#include \"private/diagnostic_pop.h\"") + cog.outl("#include \"diagnostic_pop.h\"") cog.outl("#endif") cog.outl("") cog.outl("#if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION) && !defined(ETL_COMPILER_GREEN_HILLS)") cog.outl(" //********************************************") - cog.outl("#include \"private/diagnostic_uninitialized_push.h\"") + cog.outl("#include \"diagnostic_uninitialized_push.h\"") cog.out(" template ::type, etl::message_packet<") for t in range(1, n): cog.out("T%s, " % t) @@ -997,10 +475,10 @@ namespace etl cog.outl(" {") generate_static_assert_cpp11(n) cog.outl(" }") - cog.outl("#include \"private/diagnostic_pop.h\"") + cog.outl("#include \"diagnostic_pop.h\"") cog.outl("#else") cog.outl(" //********************************************") - cog.outl("#include \"private/diagnostic_uninitialized_push.h\"") + cog.outl("#include \"diagnostic_uninitialized_push.h\"") cog.outl(" template ") cog.out(" explicit message_packet(const TMessage& /*msg*/, typename etl::enable_if::type, etl::message_packet<") for t in range(1, n): @@ -1015,11 +493,11 @@ namespace etl cog.outl(" {") generate_static_assert_cpp03(n) cog.outl(" }") - cog.outl("#include \"private/diagnostic_pop.h\"") + cog.outl("#include \"diagnostic_pop.h\"") cog.outl("#endif") cog.outl("") cog.outl(" //**********************************************") - cog.outl("#include \"private/diagnostic_uninitialized_push.h\"") + cog.outl("#include \"diagnostic_uninitialized_push.h\"") cog.outl(" message_packet(const message_packet& other)") cog.outl(" : valid(other.is_valid())") cog.outl(" {") @@ -1028,11 +506,11 @@ namespace etl cog.outl(" add_new_message(other.get());") cog.outl(" }") cog.outl(" }") - cog.outl("#include \"private/diagnostic_pop.h\"") + cog.outl("#include \"diagnostic_pop.h\"") cog.outl("") cog.outl("#if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION)") cog.outl(" //**********************************************") - cog.outl("#include \"private/diagnostic_uninitialized_push.h\"") + cog.outl("#include \"diagnostic_uninitialized_push.h\"") cog.outl(" message_packet(message_packet&& other)") cog.outl(" : valid(other.is_valid())") cog.outl(" {") @@ -1041,11 +519,11 @@ namespace etl cog.outl(" add_new_message(etl::move(other.get()));") cog.outl(" }") cog.outl(" }") - cog.outl("#include \"private/diagnostic_pop.h\"") + cog.outl("#include \"diagnostic_pop.h\"") cog.outl("#endif") cog.outl("") cog.outl(" //**********************************************") - cog.outl("#include \"private/diagnostic_uninitialized_push.h\"") + cog.outl("#include \"diagnostic_uninitialized_push.h\"") cog.outl(" message_packet& operator =(const message_packet& rhs)") cog.outl(" {") cog.outl(" delete_current_message();") @@ -1057,11 +535,11 @@ namespace etl cog.outl("") cog.outl(" return *this;") cog.outl(" }") - cog.outl("#include \"private/diagnostic_pop.h\"") + cog.outl("#include \"diagnostic_pop.h\"") cog.outl("") cog.outl("#if ETL_USING_CPP11 && !defined(ETL_MESSAGE_PACKET_FORCE_CPP03_IMPLEMENTATION)") cog.outl(" //**********************************************") - cog.outl("#include \"private/diagnostic_uninitialized_push.h\"") + cog.outl("#include \"diagnostic_uninitialized_push.h\"") cog.outl(" message_packet& operator =(message_packet&& rhs)") cog.outl(" {") cog.outl(" delete_current_message();") @@ -1073,7 +551,7 @@ namespace etl cog.outl("") cog.outl(" return *this;") cog.outl(" }") - cog.outl("#include \"private/diagnostic_pop.h\"") + cog.outl("#include \"diagnostic_pop.h\"") cog.outl("#endif") cog.outl("") cog.outl(" //********************************************") @@ -1143,7 +621,7 @@ namespace etl cog.outl("private:") cog.outl("") cog.outl(" //********************************************") - cog.outl(" #include \"private/diagnostic_uninitialized_push.h\"") + cog.outl(" #include \"diagnostic_uninitialized_push.h\"") cog.outl(" void delete_current_message()") cog.outl(" {") cog.outl(" if (valid)") @@ -1158,7 +636,7 @@ namespace etl cog.outl("#endif") cog.outl(" }") cog.outl(" }") - cog.outl(" #include \"private/diagnostic_pop.h\"") + cog.outl(" #include \"diagnostic_pop.h\"") cog.outl("") cog.outl(" //********************************************") cog.outl(" void delete_message(etl::imessage* pmsg)") @@ -1171,7 +649,7 @@ namespace etl cog.outl(" default: ETL_ASSERT_FAIL(ETL_ERROR(unhandled_message_exception)); break;") cog.outl(" }") cog.outl(" }") - cog.outl("") + cog.outl("") cog.outl(" //********************************************") cog.outl(" void add_new_message(const etl::imessage& msg)") cog.outl(" {") @@ -1263,7 +741,4 @@ namespace etl bool valid; }; -#endif -} -#endif diff --git a/include/etl/generators/message_router_cpp03_generator.h b/include/etl/generators/message_router_cpp03_generator.h new file mode 100644 index 00000000..e2f9aba0 --- /dev/null +++ b/include/etl/generators/message_router_cpp03_generator.h @@ -0,0 +1,456 @@ +//*************************************************************************** +// THIS FILE HAS BEEN AUTO GENERATED. DO NOT EDIT THIS FILE. +//*************************************************************************** + + //************************************************************************************************* + // For C++03/98. + //************************************************************************************************* + /*[[[cog + import cog + ################################################ + # The first definition for all of the messages. + ################################################ + cog.outl("//***************************************************************************") + cog.outl("// The definition for all %s message types." % Handlers) + cog.outl("//***************************************************************************") + cog.outl("template " % int(Handlers)) + cog.out("class message_router") + cog.outl(" : public imessage_router") + cog.outl("{") + cog.outl("public:") + cog.outl("") + cog.out(" typedef etl::message_packet<") + for n in range(1, int(Handlers)): + cog.out("T%s, " % n) + cog.outl("T%s> message_packet;" % int(Handlers)) + cog.outl("") + + cog.outl("#if ETL_USING_CPP11") + cog.out(" using message_types = etl::type_list<") + for n in range(1, int(Handlers)): + cog.out("T%s, " % n) + cog.outl("T%s>;" % int(Handlers)) + cog.outl("#endif") + cog.outl("") + + cog.outl(" //**********************************************") + cog.outl(" message_router(etl::message_router_id_t id_)") + cog.outl(" : imessage_router(id_)") + cog.outl(" {") + cog.outl(" ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id));") + cog.outl(" }") + cog.outl("") + cog.outl(" //**********************************************") + cog.outl(" message_router(etl::message_router_id_t id_, etl::imessage_router& successor_)") + cog.outl(" : imessage_router(id_, successor_)") + cog.outl(" {") + cog.outl(" ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id));") + cog.outl(" }") + cog.outl("") + cog.outl(" //**********************************************") + cog.outl(" message_router()") + cog.outl(" : imessage_router(etl::imessage_router::MESSAGE_ROUTER)") + cog.outl(" {") + cog.outl(" }") + cog.outl("") + cog.outl(" //**********************************************") + cog.outl(" message_router(etl::imessage_router& successor_)") + cog.outl(" : imessage_router(etl::imessage_router::MESSAGE_ROUTER, successor_)") + cog.outl(" {") + cog.outl(" }") + cog.outl("") + cog.outl(" //**********************************************") + cog.outl(" using etl::imessage_router::receive;") + cog.outl("") + cog.outl(" void receive(const etl::imessage& msg) ETL_OVERRIDE") + cog.outl(" {") + cog.outl(" const etl::message_id_t id = msg.get_message_id();") + cog.outl("") + cog.outl("#include \"etl/private/diagnostic_array_bounds_push.h\"") + cog.outl(" switch (id)") + cog.outl(" {") + for n in range(1, int(Handlers) + 1): + cog.out(" case T%d::ID:" % n) + cog.out(" static_cast(this)->on_receive(static_cast(msg));" % n) + cog.outl(" break;") + cog.outl(" default:") + cog.outl(" {") + cog.outl(" if (has_successor())") + cog.outl(" {") + cog.outl(" get_successor().receive(msg);") + cog.outl(" }") + cog.outl(" else") + cog.outl(" {") + cog.outl(" static_cast(this)->on_receive_unknown(msg);") + cog.outl(" }") + cog.outl(" break;") + cog.outl(" }") + cog.outl(" }") + cog.outl("#include \"etl/private/diagnostic_pop.h\"") + cog.outl(" }") + cog.outl("") + cog.outl(" template ") + cog.out(" typename etl::enable_if::value && etl::is_one_of::value, void>::type" % int(Handlers)) + cog.outl(" receive(const TMessage& msg)") + cog.outl(" {") + cog.outl("#include \"etl/private/diagnostic_array_bounds_push.h\"") + cog.outl(" static_cast(this)->on_receive(msg);") + cog.outl("#include \"etl/private/diagnostic_pop.h\"") + cog.outl(" }") + cog.outl("") + cog.outl(" template ") + cog.out(" typename etl::enable_if::value && !etl::is_one_of::value, void>::type" % int(Handlers)) + cog.outl(" receive(const TMessage& msg)") + cog.outl(" {") + cog.outl(" if (has_successor())") + cog.outl(" {") + cog.outl(" get_successor().receive(msg);") + cog.outl(" }") + cog.outl(" else") + cog.outl(" {") + cog.outl("#include \"etl/private/diagnostic_array_bounds_push.h\"") + cog.outl(" static_cast(this)->on_receive_unknown(msg);") + cog.outl("#include \"etl/private/diagnostic_pop.h\"") + cog.outl(" }") + cog.outl(" }") + cog.outl("") + cog.outl(" //**********************************************") + cog.outl(" using imessage_router::accepts;") + cog.outl("") + cog.outl(" bool accepts(etl::message_id_t id) const ETL_OVERRIDE") + cog.outl(" {") + cog.outl(" switch (id)") + cog.outl(" {") + cog.out(" ") + for n in range(1, int(Handlers) + 1): + cog.out(" case T%d::ID:" % n) + if n % 8 == 0: + cog.outl("") + cog.out(" ") + cog.outl(" return true;") + cog.outl(" default:") + cog.outl(" {") + cog.outl(" if (has_successor())") + cog.outl(" {") + cog.outl(" return get_successor().accepts(id);") + cog.outl(" }") + cog.outl(" else") + cog.outl(" {") + cog.outl(" return false;") + cog.outl(" }") + cog.outl(" }") + cog.outl(" }") + cog.outl(" }") + cog.outl("") + cog.outl(" //********************************************") + cog.outl(" ETL_DEPRECATED bool is_null_router() const ETL_OVERRIDE") + cog.outl(" {") + cog.outl(" return false;") + cog.outl(" }") + cog.outl("") + cog.outl(" //********************************************") + cog.outl(" bool is_producer() const ETL_OVERRIDE") + cog.outl(" {") + cog.outl(" return true;") + cog.outl(" }") + cog.outl("") + cog.outl(" //********************************************") + cog.outl(" bool is_consumer() const ETL_OVERRIDE") + cog.outl(" {") + cog.outl(" return true;") + cog.outl(" }") + cog.outl("};") + + #################################### + # All of the other specialisations. + #################################### + for n in range(int(Handlers) - 1, 0, -1): + cog.outl("") + cog.outl("//***************************************************************************") + if n == 1: + cog.outl("// Specialisation for %d message type." % n) + else: + cog.outl("// Specialisation for %d message types." % n) + cog.outl("//***************************************************************************") + cog.outl("template " % n) + cog.out("class message_router") + cog.outl(" : public imessage_router") + cog.outl("{") + cog.outl("public:") + cog.outl("") + cog.out(" typedef etl::message_packet<") + for t in range(1, n): + cog.out("T%s, " % t) + cog.outl(" T%s> message_packet;" % n) + cog.outl("") + + cog.outl("#if ETL_USING_CPP11") + cog.out(" using message_types = etl::type_list<") + for t in range(1, n): + cog.out("T%s, " % t) + cog.outl("T%s>;" % n) + cog.outl("#endif") + cog.outl("") + + cog.outl(" //**********************************************") + cog.outl(" message_router(etl::message_router_id_t id_)") + cog.outl(" : imessage_router(id_)") + cog.outl(" {") + cog.outl(" ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id));") + cog.outl(" }") + cog.outl("") + cog.outl(" //**********************************************") + cog.outl(" message_router(etl::message_router_id_t id_, etl::imessage_router& successor_)") + cog.outl(" : imessage_router(id_, successor_)") + cog.outl(" {") + cog.outl(" ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id));") + cog.outl(" }") + cog.outl("") + cog.outl(" //**********************************************") + cog.outl(" message_router()") + cog.outl(" : imessage_router(etl::imessage_router::MESSAGE_ROUTER)") + cog.outl(" {") + cog.outl(" }") + cog.outl("") + cog.outl(" //**********************************************") + cog.outl(" message_router(etl::imessage_router& successor_)") + cog.outl(" : imessage_router(etl::imessage_router::MESSAGE_ROUTER, successor_)") + cog.outl(" {") + cog.outl(" }") + cog.outl("") + cog.outl(" //**********************************************") + cog.outl(" using etl::imessage_router::receive;") + cog.outl("") + cog.outl(" void receive(const etl::imessage& msg) ETL_OVERRIDE") + cog.outl(" {") + cog.outl(" const etl::message_id_t id = msg.get_message_id();") + cog.outl("") + cog.outl("#include \"etl/private/diagnostic_array_bounds_push.h\"") + cog.outl(" switch (id)") + cog.outl(" {") + for t in range(1, n + 1): + cog.out(" case T%d::ID:" % t) + cog.out(" static_cast(this)->on_receive(static_cast(msg));" % t) + cog.outl(" break;") + cog.outl(" default:") + cog.outl(" {") + cog.outl(" if (has_successor())") + cog.outl(" {") + cog.outl(" get_successor().receive(msg);") + cog.outl(" }") + cog.outl(" else") + cog.outl(" {") + cog.outl(" static_cast(this)->on_receive_unknown(msg);") + cog.outl(" }") + cog.outl(" break;") + cog.outl(" }") + cog.outl(" }") + cog.outl("#include \"etl/private/diagnostic_pop.h\"") + cog.outl(" }") + cog.outl("") + cog.outl(" template ") + cog.out(" typename etl::enable_if::value && etl::is_one_of::value, void>::type" % n) + cog.outl(" receive(const TMessage& msg)") + cog.outl(" {") + cog.outl("#include \"etl/private/diagnostic_array_bounds_push.h\"") + cog.outl(" static_cast(this)->on_receive(msg);") + cog.outl("#include \"etl/private/diagnostic_pop.h\"") + cog.outl(" }") + cog.outl("") + cog.outl(" template ") + cog.out(" typename etl::enable_if::value && !etl::is_one_of::value, void>::type" % n) + cog.outl(" receive(const TMessage& msg)") + cog.outl(" {") + cog.outl(" if (has_successor())") + cog.outl(" {") + cog.outl(" get_successor().receive(msg);") + cog.outl(" }") + cog.outl(" else") + cog.outl(" {") + cog.outl("#include \"etl/private/diagnostic_array_bounds_push.h\"") + cog.outl(" static_cast(this)->on_receive_unknown(msg);") + cog.outl("#include \"etl/private/diagnostic_pop.h\"") + cog.outl(" }") + cog.outl(" }") + cog.outl("") + cog.outl("") + cog.outl(" //**********************************************") + cog.outl(" using imessage_router::accepts;") + cog.outl("") + cog.outl(" bool accepts(etl::message_id_t id) const ETL_OVERRIDE") + cog.outl(" {") + cog.outl(" switch (id)") + cog.outl(" {") + cog.out(" ") + for t in range(1, n + 1): + cog.out(" case T%d::ID:" % t) + if t % 8 == 0: + cog.outl("") + if t != n: + cog.out(" ") + cog.outl("") + cog.outl(" return true;") + cog.outl(" default:") + cog.outl(" {") + cog.outl(" if (has_successor())") + cog.outl(" {") + cog.outl(" return get_successor().accepts(id);") + cog.outl(" }") + cog.outl(" else") + cog.outl(" {") + cog.outl(" return false;") + cog.outl(" }") + cog.outl(" }") + cog.outl(" }") + cog.outl(" }") + cog.outl("") + cog.outl(" //********************************************") + cog.outl(" ETL_DEPRECATED bool is_null_router() const ETL_OVERRIDE") + cog.outl(" {") + cog.outl(" return false;") + cog.outl(" }") + cog.outl("") + cog.outl(" //********************************************") + cog.outl(" bool is_producer() const ETL_OVERRIDE") + cog.outl(" {") + cog.outl(" return true;") + cog.outl(" }") + cog.outl("") + cog.outl(" //********************************************") + cog.outl(" bool is_consumer() const ETL_OVERRIDE") + cog.outl(" {") + cog.outl(" return true;") + cog.outl(" }") + cog.outl("};") + ]]]*/ + /*[[[end]]]*/ + + //*************************************************************************** + // Specialisation for 0 message types. + //*************************************************************************** + template + class message_router + : public imessage_router + { + public: + + typedef etl::message_packet<> message_packet; + +#if ETL_USING_CPP11 + using message_types = etl::type_list<>; +#endif + + //********************************************** + message_router(etl::message_router_id_t id_) + : imessage_router(id_) + { + ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); + } + + //********************************************** + message_router(etl::message_router_id_t id_, etl::imessage_router& successor_) + : imessage_router(id_, successor_) + { + ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); + } + + //********************************************** + message_router() + : imessage_router(etl::imessage_router::MESSAGE_ROUTER) + { + } + + //********************************************** + message_router(etl::imessage_router& successor_) + : imessage_router(etl::imessage_router::MESSAGE_ROUTER, successor_) + { + } + + //********************************************** + using etl::imessage_router::receive; + + void receive(const etl::imessage& msg) ETL_OVERRIDE + { +#include "etl/private/diagnostic_array_bounds_push.h" + if (has_successor()) + { + get_successor().receive(msg); + } +#include "etl/private/diagnostic_pop.h" + } + + //********************************************** + using imessage_router::accepts; + + bool accepts(etl::message_id_t id) const ETL_OVERRIDE + { + if (has_successor()) + { + return get_successor().accepts(id); + } + else + { + return false; + } + } + + //******************************************** + ETL_DEPRECATED bool is_null_router() const ETL_OVERRIDE + { + return false; + } + + //******************************************** + bool is_producer() const ETL_OVERRIDE + { + return true; + } + + //******************************************** + bool is_consumer() const ETL_OVERRIDE + { + return true; + } + }; + diff --git a/include/etl/generators/message_router_generator.h b/include/etl/generators/message_router_generator.h deleted file mode 100644 index 312848b6..00000000 --- a/include/etl/generators/message_router_generator.h +++ /dev/null @@ -1,1356 +0,0 @@ -/****************************************************************************** -The MIT License(MIT) - -Embedded Template Library. -https://github.com/ETLCPP/etl -https://www.etlcpp.com - -Copyright(c) 2017 John Wellbelove - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files(the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions : - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -******************************************************************************/ - -/*[[[cog -import cog -cog.outl("#if 0") -]]]*/ -/*[[[end]]]*/ -#error THIS HEADER IS A GENERATOR. DO NOT INCLUDE. -/*[[[cog -import cog -cog.outl("#endif") -]]]*/ -/*[[[end]]]*/ - -/*[[[cog -import cog -cog.outl("//***************************************************************************") -cog.outl("// THIS FILE HAS BEEN AUTO GENERATED. DO NOT EDIT THIS FILE.") -cog.outl("//***************************************************************************") -]]]*/ -/*[[[end]]]*/ - -//*************************************************************************** -// To generate to header file, run this at the command line. -// Note: You will need Python and COG installed. -// -// cog -d -e -omessage_router.h -DHandlers= message_router_generator.h -// Where is the maximum number of messages to support. -// -// e.g. -// To generate handlers for up to 16 messages... -// cog -d -e -omessage_router.h -DHandlers=16 message_router_generator.h -// -// See generate.bat -//*************************************************************************** - -#ifndef ETL_MESSAGE_ROUTER_INCLUDED -#define ETL_MESSAGE_ROUTER_INCLUDED - -#include "platform.h" -#include "message.h" -#include "shared_message.h" -#include "message_packet.h" -#include "message_types.h" -#include "alignment.h" -#include "error_handler.h" -#include "exception.h" -#include "largest.h" -#include "nullptr.h" -#include "placement_new.h" -#include "successor.h" -#include "type_traits.h" -#include "type_list.h" -#include "array.h" - -#include - -namespace etl -{ - //*************************************************************************** - /// Base exception class for message router - //*************************************************************************** - class message_router_exception : public etl::exception - { - public: - - message_router_exception(string_type reason_, string_type file_name_, numeric_type line_number_) - : etl::exception(reason_, file_name_, line_number_) - { - } - }; - - //*************************************************************************** - /// Router id is out of the legal range. - //*************************************************************************** - class message_router_illegal_id : public etl::message_router_exception - { - public: - - message_router_illegal_id(string_type file_name_, numeric_type line_number_) - : message_router_exception(ETL_ERROR_TEXT("message router:illegal id", ETL_MESSAGE_ROUTER_FILE_ID"A"), file_name_, line_number_) - { - } - }; - - namespace private_message_router - { - //*************************************************************************** - // Traits for a message router. - // message packet type - // message type_list - // sorted message type_list. - //*************************************************************************** - template - class traits - { -#if ETL_USING_CPP11 - private: - - using message_id_sequence = etl::index_sequence; - - public: - - using message_packet = etl::message_packet; - using message_types = etl::type_list; - using sorted_message_types = etl::type_list_sort_t; - - static_assert(etl::type_list_is_unique::value, "All TMessageTypes must be unique"); - static_assert(etl::type_list_all_of::value, "All TMessageTypes must satisfy the condition etl::is_message_type"); - static_assert(etl::index_sequence_is_unique::value, "All message IDs must be unique"); -#endif - }; - - //*************************************************************************** - // Specialisation of traits for no message types. - // message packet type - // message type_list - // sorted message type_list. - //*************************************************************************** - template <> - class traits<> - { - public: - -#if ETL_USING_CPP11 - using message_packet = etl::message_packet<>; - using message_types = etl::type_list<>; - using sorted_message_types = etl::type_list<>; -#endif - }; - } - - //*************************************************************************** - /// Forward declare null message router functionality. - //*************************************************************************** - class imessage_router; - - etl::imessage_router& get_null_message_router(); - - //*************************************************************************** - /// This is the base of all message routers. - //*************************************************************************** - class imessage_router : public etl::successor - { - public: - - virtual ~imessage_router() {} - virtual void receive(const etl::imessage&) = 0; - virtual bool accepts(etl::message_id_t) const = 0; - virtual bool is_null_router() const = 0; - virtual bool is_producer() const = 0; - virtual bool is_consumer() const = 0; - - //******************************************** - virtual void receive(etl::message_router_id_t destination_router_id, const etl::imessage& message) - { - if ((destination_router_id == get_message_router_id()) || (destination_router_id == imessage_router::ALL_MESSAGE_ROUTERS)) - { - receive(message); - } - } - - //******************************************** - virtual void receive(etl::shared_message shared_msg) - { - receive(shared_msg.get_message()); - } - - //******************************************** - virtual void receive(etl::message_router_id_t destination_router_id, etl::shared_message shared_msg) - { - if ((destination_router_id == get_message_router_id()) || (destination_router_id == imessage_router::ALL_MESSAGE_ROUTERS)) - { - receive(shared_msg); - } - } - - //******************************************** - bool accepts(const etl::imessage& msg) const - { - return accepts(msg.get_message_id()); - } - - //******************************************** - etl::message_router_id_t get_message_router_id() const - { - return message_router_id; - } - - enum - { - NULL_MESSAGE_ROUTER = 255, - MESSAGE_BUS = 254, - ALL_MESSAGE_ROUTERS = 253, - MESSAGE_BROKER = 252, - MESSAGE_ROUTER = 251, - MAX_MESSAGE_ROUTER = 249 - }; - - protected: - - imessage_router(etl::message_router_id_t id_) - : message_router_id(id_) - { - } - - imessage_router(etl::message_router_id_t id_, imessage_router& successor_) - : successor(successor_) - , message_router_id(id_) - { - } - - private: - - // Disabled. - imessage_router(const imessage_router&); - imessage_router& operator =(const imessage_router&); - - etl::message_router_id_t message_router_id; - }; - - //*************************************************************************** - /// This router can be used as a sink for messages or a 'null source' router. - //*************************************************************************** - class null_message_router : public imessage_router - , public private_message_router::traits<> - { - public: - - //******************************************** - null_message_router() - : imessage_router(imessage_router::NULL_MESSAGE_ROUTER) - { - } - - //******************************************** - null_message_router(etl::imessage_router& successor_) - : imessage_router(imessage_router::NULL_MESSAGE_ROUTER, successor_) - { - } - - //******************************************** - using etl::imessage_router::receive; - - void receive(const etl::imessage& msg) ETL_OVERRIDE - { - if (has_successor()) - { - get_successor().receive(msg); - } - } - - //******************************************** - using etl::imessage_router::accepts; - - bool accepts(etl::message_id_t id) const ETL_OVERRIDE - { - if (has_successor()) - { - return get_successor().accepts(id); - } - else - { - return false; - } - } - - //******************************************** - ETL_DEPRECATED bool is_null_router() const ETL_OVERRIDE - { - return true; - } - - //******************************************** - bool is_producer() const ETL_OVERRIDE - { - return false; - } - - //******************************************** - bool is_consumer() const ETL_OVERRIDE - { - return false; - } - - //******************************************** - static null_message_router& instance() - { - static null_message_router nmr; - return nmr; - } - }; - - //*********************************************** - /// null message router functionality. - inline etl::imessage_router& get_null_message_router() - { - return etl::null_message_router::instance(); - } - - //*************************************************************************** - /// This router can be used as a producer-only of messages, such an interrupt routine. - //*************************************************************************** - class message_producer : public imessage_router - , public private_message_router::traits<> - { - public: - - //******************************************** - message_producer() - : imessage_router(etl::imessage_router::MESSAGE_ROUTER) - { - } - - //******************************************** - message_producer(etl::imessage_router& successor_) - : imessage_router(imessage_router::NULL_MESSAGE_ROUTER, successor_) - { - } - - //******************************************** - message_producer(etl::message_router_id_t id_) - : imessage_router(id_) - { - ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); - } - - //******************************************** - message_producer(etl::message_router_id_t id_, etl::imessage_router& successor_) - : imessage_router(id_, successor_) - { - ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); - } - - //******************************************** - using etl::imessage_router::receive; - - void receive(const etl::imessage& msg) ETL_OVERRIDE - { - if (has_successor()) - { - get_successor().receive(msg); - } - } - - //******************************************** - using etl::imessage_router::accepts; - - bool accepts(etl::message_id_t id) const ETL_OVERRIDE - { - if (has_successor()) - { - return get_successor().accepts(id); - } - else - { - return false; - } - } - - //******************************************** - ETL_DEPRECATED bool is_null_router() const ETL_OVERRIDE - { - return false; - } - - //******************************************** - bool is_producer() const ETL_OVERRIDE - { - return true; - } - - //******************************************** - bool is_consumer() const ETL_OVERRIDE - { - return false; - } - }; - - //*************************************************************************** - /// Is T ultimately derived from etl::imessage_router? - //*************************************************************************** - template - struct is_message_router : public etl::bool_constant::type>::value> - { - }; - - //*************************************************************************** - /// Send a message to a router. - //*************************************************************************** - template - static - typename etl::enable_if::value && etl::is_message::value, void>::type - send_message(TRouter& destination, - const TMessage& message) - { - destination.receive(message); - } - - //*************************************************************************** - /// Send a shared message to a router. - //*************************************************************************** - template - static - typename etl::enable_if::value, void>::type - send_message(TRouter& destination, - etl::shared_message message) - { - destination.receive(message); - } - - //*************************************************************************** - /// Send a message to a router with a particular id. - //*************************************************************************** - template - static - typename etl::enable_if::value && etl::is_message::value, void>::type - send_message(TRouter& destination, - etl::message_router_id_t id, - const TMessage& message) - { - destination.receive(id, message); - } - - //*************************************************************************** - /// Send a shared message to a router with a particular id. - //*************************************************************************** - template - static - typename etl::enable_if::value, void>::type - send_message(TRouter& destination, - etl::message_router_id_t id, - etl::shared_message message) - { - destination.receive(id, message); - } - - //************************************************************************************************* - // For C++11 and above. - //************************************************************************************************* -#if ETL_USING_CPP11 && !defined(ETL_MESSAGE_ROUTER_FORCE_CPP03_IMPLEMENTATION) - //*************************************************************************** - // The definition for all message types. - //*************************************************************************** - template - class message_router : public imessage_router - , public private_message_router::traits - { - public: - - using typename private_message_router::traits::message_packet; - using typename private_message_router::traits::message_types; - using typename private_message_router::traits::sorted_message_types; - - //********************************************** - /// Default constructor. The message router id will be MESSAGE_ROUTER. - //********************************************** - message_router() - : imessage_router(etl::imessage_router::MESSAGE_ROUTER) - { - } - - //********************************************** - /// Constructor with successor. The message router id will be MESSAGE_ROUTER. - //********************************************** - message_router(etl::imessage_router& successor_) - : imessage_router(etl::imessage_router::MESSAGE_ROUTER, successor_) - { - } - - //********************************************** - /// Constructor with message router id. - //********************************************** - message_router(etl::message_router_id_t id_) - : imessage_router(id_) - { - ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); - } - - //********************************************** - /// Constructor with message router id and successor. - //********************************************** - message_router(etl::message_router_id_t id_, etl::imessage_router& successor_) - : imessage_router(id_, successor_) - { - ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); - } - - //********************************************** - /// Allow visibility of base class receive() methods. - //********************************************** - using etl::imessage_router::receive; - - //********************************************** - /// This will be called for all messages passed as an etl::imessage. - /// It will dispatch the message to the correct handler based on the message id, - /// or pass it to a successor if there is no handler for the message id. - /// \param msg The message. - //*********************************************** - void receive(const etl::imessage& msg) ETL_OVERRIDE - { - const etl::message_id_t id = msg.get_message_id(); - - // The IDs are sorted, so an ID less than the first is not handled by this router. - if (id >= Message_Id_Start) - { - const size_t index = get_dispatch_index_from_message_id(id); - - // If the index is less than Number_Of_Messages, then we have a handler for this message type, so dispatch it. - if (index < Number_Of_Messages) - { - dispatch(msg, index); - return; - } - } - - // We don't have a handler for this message type, so pass it to a successor if there is one, or call on_receive_unknown() if there isn't. - if (has_successor()) - { - get_successor().receive(msg); - } - else - { -#include "etl/private/diagnostic_array_bounds_push.h" - static_cast(this)->on_receive_unknown(msg); -#include "etl/private/diagnostic_pop.h" - } - } - - //********************************************** - /// This will be called for messages where TMessage is in the message type list. - /// \tparam TMessage The message type. - /// \param msg The message. - /// Enabled if TMessage is in the message type list. - //********************************************** - template ::value, int>::type = 0> - void receive(const TMessage& msg) - { -#include "etl/private/diagnostic_array_bounds_push.h" - static_cast(this)->on_receive(msg); -#include "etl/private/diagnostic_pop.h" - } - - //********************************************** - /// This will be called for messages where TMessage is a message type, but not in the message type list. - /// \tparam TMessage The message type. - /// \param msg The message. - /// Enabled if TMessage is a message type, but not in the message type list. - //********************************************** - template ::value && - !etl::is_one_of::value, int>::type = 0> - void receive(const TMessage& msg) - { - if (has_successor()) - { - get_successor().receive(msg); - } - else - { -#include "etl/private/diagnostic_array_bounds_push.h" - static_cast(this)->on_receive_unknown(msg); -#include "etl/private/diagnostic_pop.h" - } - } - - //********************************************** - /// Allow visibility of base class accepts() methods. - //********************************************** - using imessage_router::accepts; - - //********************************************** - /// This will return true if the message id is in the message type list, or if a successor accepts the message id. - //*********************************************** - bool accepts(etl::message_id_t id) const ETL_OVERRIDE - { - if (id >= Message_Id_Start) - { - const size_t index = get_dispatch_index_from_message_id(id); - - if (index < Number_Of_Messages) - { - return true; - } - } - - return has_successor() ? get_successor().accepts(id) : false; - } - - //******************************************** - ETL_DEPRECATED bool is_null_router() const ETL_OVERRIDE - { - return false; - } - - //******************************************** - bool is_producer() const ETL_OVERRIDE - { - return true; - } - - //******************************************** - bool is_consumer() const ETL_OVERRIDE - { - return true; - } - - private: - - static constexpr size_t Number_Of_Messages = sizeof...(TMessageTypes); - static constexpr etl::message_id_t Message_Id_Start = etl::type_list_type_at_index_t::ID; - - //********************************************** - // Checks that the message ids are contiguous. - //********************************************** - template = Number_Of_Messages)> - struct contiguous_impl; - - template - struct contiguous_impl : etl::true_type - { - }; - - template - struct contiguous_impl - : etl::bool_constant<(etl::type_list_type_at_index_t::ID + 1U == - etl::type_list_type_at_index_t::ID) && - contiguous_impl::value> - { - }; - - // The message ids are contiguous if there are 0 or 1 message types, or if each message id is one greater than the previous message id. - static constexpr bool Message_Ids_Are_Contiguous = (Number_Of_Messages <= 1U) ? true : contiguous_impl<0U>::value; - - using handler_ptr = void (*)(TDerived&, const etl::imessage&); ///< Pointer to a handler function that takes a reference to the derived class and a reference to the message. - using message_dispatch_table_t = etl::array; ///< The dispatch table type. An array of handler pointers, one for each message type. - using message_id_table_t = etl::array; ///< The message id table type. An array of message ids, one for each message type. - - //********************************************** - // Call for a single message type - //********************************************** - template - static void call_on_receive(TDerived& derived, const imessage& msg) - { - derived.on_receive(static_cast(msg)); - } - - //********************************************** - // Get the handler for a single message type at the index in the sorted type_list. - // This will be called for each message type to generate the dispatch table. - //********************************************** - template - static constexpr handler_ptr get_message_handler() - { - return &call_on_receive>; - } - - //********************************************** - // Generate the dispatch table at compile time. - // This will create an array of handler pointers, one for each message type. - //********************************************** - template - static constexpr message_dispatch_table_t make_message_dispatch_table(etl::index_sequence) - { - return message_dispatch_table_t{ { get_message_handler()... } }; - } - - //********************************************** - // Get the message id for a single message type at an index in the sorted type_list. - // This will be called for each message type to generate the message id table. - //********************************************** - template - static constexpr etl::message_id_t get_message_id_from_index() - { - return etl::type_list_type_at_index_t::ID; - } - - //********************************************** - // Generate the message id table at compile time. - // This will create an array of message ids, one for each message type. - //********************************************** - template - static constexpr message_id_table_t make_message_id_table(etl::index_sequence) - { - return message_id_table_t{ { get_message_id_from_index()... } }; - } - - //********************************************** - // Get the dispatch index for a message id. - // This will be used at runtime to find the handler for a message id. - // If the message ids are contiguous, we can calculate the index directly. If they are not contiguous, we need to do a binary search. - // This will return Number_Of_Messages if the message id is not found, which indicates that the message should be passed to the successor. - //********************************************** - static size_t get_dispatch_index_from_message_id(etl::message_id_t id) - { - if ETL_IF_CONSTEXPR(Message_Ids_Are_Contiguous) - { - // The IDs are contiguous, so we can calculate the index directly. - return static_cast(id - Message_Id_Start); - } - else - { - // The IDs are not contiguous, so we need to do a binary search. - size_t left = 0; - size_t right = Number_Of_Messages; - - while (left < right) - { - size_t mid = (left + right) / 2; - - if (message_id_table[mid] == id) - { - return mid; - } - else if (message_id_table[mid] < id) - { - left = mid + 1; - } - else - { - right = mid; - } - } - } - - return Number_Of_Messages; // Not found - } - - //********************************************** - // Dispatch the message to the appropriate handler based on the index in the dispatch table. - //********************************************** - void dispatch(const etl::imessage& msg, size_t index) - { - message_dispatch_table[index](static_cast(*this), msg); - } - - //********************************************** - // The dispatch table is generated at compile time. The dispatch table contains pointers to the on_receive handlers for each message type. - //********************************************** - static ETL_INLINE_VAR constexpr message_dispatch_table_t message_dispatch_table = - etl::message_router::make_message_dispatch_table(etl::make_index_sequence::Number_Of_Messages>{}); - - //********************************************** - // The message id table is generated at compile time. The message id table contains the corresponding message ids for each message type. - //********************************************** - static ETL_INLINE_VAR constexpr message_id_table_t message_id_table = - etl::message_router::make_message_id_table(etl::make_index_sequence::Number_Of_Messages>{}); - }; - -#if ETL_USING_CPP11 && !ETL_USING_CPP17 - template - constexpr const typename etl::message_router::message_dispatch_table_t - etl::message_router::message_dispatch_table; - - template - constexpr const typename etl::message_router::message_id_table_t - etl::message_router::message_id_table; -#endif - - //*************************************************************************** - // The definition of a message_router for zero message types. - //*************************************************************************** - template - class message_router : public imessage_router - , public private_message_router::traits<> - { - public: - - //********************************************** - /// Default constructor. The message router id will be MESSAGE_ROUTER. - //********************************************** - message_router() - : imessage_router(etl::imessage_router::MESSAGE_ROUTER) - { - } - - //********************************************** - /// Constructor with successor. The message router id will be MESSAGE_ROUTER. - //********************************************** - message_router(etl::imessage_router& successor_) - : imessage_router(etl::imessage_router::MESSAGE_ROUTER, successor_) - { - } - - //********************************************** - /// Constructor with message router id. - //********************************************** - message_router(etl::message_router_id_t id_) - : imessage_router(id_) - { - ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); - } - - //********************************************** - /// Constructor with message router id and successor. - //********************************************** - message_router(etl::message_router_id_t id_, etl::imessage_router& successor_) - : imessage_router(id_, successor_) - { - ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); - } - - //********************************************** - /// Allow visibility of base class receive() methods. - using etl::imessage_router::receive; - - //********************************************** - /// This will be called for all messages passed as an etl::imessage. - /// Since there are no message types, this will just pass the message to a successor if there is one, or call on_receive_unknown() if there isn't. - /// \param msg The message. - //*********************************************** - void receive(const etl::imessage& msg) ETL_OVERRIDE - { -#include "etl/private/diagnostic_array_bounds_push.h" - if (has_successor()) - { - get_successor().receive(msg); - } -#include "etl/private/diagnostic_pop.h" - } - - //********************************************** - /// Allow visibility of base class accepts() methods. - //********************************************** - using imessage_router::accepts; - - //********************************************** - /// This will return true if a successor accepts the message id. - //*********************************************** - bool accepts(etl::message_id_t id) const ETL_OVERRIDE - { - if (has_successor()) - { - return get_successor().accepts(id); - } - else - { - return false; - } - } - - //******************************************** - ETL_DEPRECATED bool is_null_router() const ETL_OVERRIDE - { - return false; - } - - //******************************************** - bool is_producer() const ETL_OVERRIDE - { - return true; - } - - //******************************************** - bool is_consumer() const ETL_OVERRIDE - { - return true; - } - }; - - //*************************************************************************** - /// Helper to turn etl::type_list into etl::message_router - //*************************************************************************** - template - struct message_router_from_type_list; - - template - struct message_router_from_type_list> - { - using type = etl::message_router; - }; - - template - using message_router_from_type_list_t = typename message_router_from_type_list::type; - -#else - //************************************************************************************************* - // For C++03/98. - //************************************************************************************************* - /*[[[cog - import cog - ################################################ - # The first definition for all of the messages. - ################################################ - cog.outl("//***************************************************************************") - cog.outl("// The definition for all %s message types." % Handlers) - cog.outl("//***************************************************************************") - cog.outl("template " % int(Handlers)) - cog.out("class message_router") - cog.outl(" : public imessage_router") - cog.outl("{") - cog.outl("public:") - cog.outl("") - cog.out(" typedef etl::message_packet<") - for n in range(1, int(Handlers)): - cog.out("T%s, " % n) - cog.outl("T%s> message_packet;" % int(Handlers)) - cog.outl("") - - cog.outl("#if ETL_USING_CPP11") - cog.out(" using message_types = etl::type_list<") - for n in range(1, int(Handlers)): - cog.out("T%s, " % n) - cog.outl("T%s>;" % int(Handlers)) - cog.outl("#endif") - cog.outl("") - - cog.outl(" //**********************************************") - cog.outl(" message_router(etl::message_router_id_t id_)") - cog.outl(" : imessage_router(id_)") - cog.outl(" {") - cog.outl(" ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id));") - cog.outl(" }") - cog.outl("") - cog.outl(" //**********************************************") - cog.outl(" message_router(etl::message_router_id_t id_, etl::imessage_router& successor_)") - cog.outl(" : imessage_router(id_, successor_)") - cog.outl(" {") - cog.outl(" ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id));") - cog.outl(" }") - cog.outl("") - cog.outl(" //**********************************************") - cog.outl(" message_router()") - cog.outl(" : imessage_router(etl::imessage_router::MESSAGE_ROUTER)") - cog.outl(" {") - cog.outl(" }") - cog.outl("") - cog.outl(" //**********************************************") - cog.outl(" message_router(etl::imessage_router& successor_)") - cog.outl(" : imessage_router(etl::imessage_router::MESSAGE_ROUTER, successor_)") - cog.outl(" {") - cog.outl(" }") - cog.outl("") - cog.outl(" //**********************************************") - cog.outl(" using etl::imessage_router::receive;") - cog.outl("") - cog.outl(" void receive(const etl::imessage& msg) ETL_OVERRIDE") - cog.outl(" {") - cog.outl(" const etl::message_id_t id = msg.get_message_id();") - cog.outl("") - cog.outl("#include \"etl/private/diagnostic_array_bounds_push.h\"") - cog.outl(" switch (id)") - cog.outl(" {") - for n in range(1, int(Handlers) + 1): - cog.out(" case T%d::ID:" % n) - cog.out(" static_cast(this)->on_receive(static_cast(msg));" % n) - cog.outl(" break;") - cog.outl(" default:") - cog.outl(" {") - cog.outl(" if (has_successor())") - cog.outl(" {") - cog.outl(" get_successor().receive(msg);") - cog.outl(" }") - cog.outl(" else") - cog.outl(" {") - cog.outl(" static_cast(this)->on_receive_unknown(msg);") - cog.outl(" }") - cog.outl(" break;") - cog.outl(" }") - cog.outl(" }") - cog.outl("#include \"etl/private/diagnostic_pop.h\"") - cog.outl(" }") - cog.outl("") - cog.outl(" template ") - cog.out(" typename etl::enable_if::value && etl::is_one_of::value, void>::type" % int(Handlers)) - cog.outl(" receive(const TMessage& msg)") - cog.outl(" {") - cog.outl("#include \"etl/private/diagnostic_array_bounds_push.h\"") - cog.outl(" static_cast(this)->on_receive(msg);") - cog.outl("#include \"etl/private/diagnostic_pop.h\"") - cog.outl(" }") - cog.outl("") - cog.outl(" template ") - cog.out(" typename etl::enable_if::value && !etl::is_one_of::value, void>::type" % int(Handlers)) - cog.outl(" receive(const TMessage& msg)") - cog.outl(" {") - cog.outl(" if (has_successor())") - cog.outl(" {") - cog.outl(" get_successor().receive(msg);") - cog.outl(" }") - cog.outl(" else") - cog.outl(" {") - cog.outl("#include \"etl/private/diagnostic_array_bounds_push.h\"") - cog.outl(" static_cast(this)->on_receive_unknown(msg);") - cog.outl("#include \"etl/private/diagnostic_pop.h\"") - cog.outl(" }") - cog.outl(" }") - cog.outl("") - cog.outl(" //**********************************************") - cog.outl(" using imessage_router::accepts;") - cog.outl("") - cog.outl(" bool accepts(etl::message_id_t id) const ETL_OVERRIDE") - cog.outl(" {") - cog.outl(" switch (id)") - cog.outl(" {") - cog.out(" ") - for n in range(1, int(Handlers) + 1): - cog.out(" case T%d::ID:" % n) - if n % 8 == 0: - cog.outl("") - cog.out(" ") - cog.outl(" return true;") - cog.outl(" default:") - cog.outl(" {") - cog.outl(" if (has_successor())") - cog.outl(" {") - cog.outl(" return get_successor().accepts(id);") - cog.outl(" }") - cog.outl(" else") - cog.outl(" {") - cog.outl(" return false;") - cog.outl(" }") - cog.outl(" }") - cog.outl(" }") - cog.outl(" }") - cog.outl("") - cog.outl(" //********************************************") - cog.outl(" ETL_DEPRECATED bool is_null_router() const ETL_OVERRIDE") - cog.outl(" {") - cog.outl(" return false;") - cog.outl(" }") - cog.outl("") - cog.outl(" //********************************************") - cog.outl(" bool is_producer() const ETL_OVERRIDE") - cog.outl(" {") - cog.outl(" return true;") - cog.outl(" }") - cog.outl("") - cog.outl(" //********************************************") - cog.outl(" bool is_consumer() const ETL_OVERRIDE") - cog.outl(" {") - cog.outl(" return true;") - cog.outl(" }") - cog.outl("};") - - #################################### - # All of the other specialisations. - #################################### - for n in range(int(Handlers) - 1, 0, -1): - cog.outl("") - cog.outl("//***************************************************************************") - if n == 1: - cog.outl("// Specialisation for %d message type." % n) - else: - cog.outl("// Specialisation for %d message types." % n) - cog.outl("//***************************************************************************") - cog.outl("template " % n) - cog.out("class message_router") - cog.outl(" : public imessage_router") - cog.outl("{") - cog.outl("public:") - cog.outl("") - cog.out(" typedef etl::message_packet<") - for t in range(1, n): - cog.out("T%s, " % t) - cog.outl(" T%s> message_packet;" % n) - cog.outl("") - - cog.outl("#if ETL_USING_CPP11") - cog.out(" using message_types = etl::type_list<") - for t in range(1, n): - cog.out("T%s, " % t) - cog.outl("T%s>;" % n) - cog.outl("#endif") - cog.outl("") - - cog.outl(" //**********************************************") - cog.outl(" message_router(etl::message_router_id_t id_)") - cog.outl(" : imessage_router(id_)") - cog.outl(" {") - cog.outl(" ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id));") - cog.outl(" }") - cog.outl("") - cog.outl(" //**********************************************") - cog.outl(" message_router(etl::message_router_id_t id_, etl::imessage_router& successor_)") - cog.outl(" : imessage_router(id_, successor_)") - cog.outl(" {") - cog.outl(" ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id));") - cog.outl(" }") - cog.outl("") - cog.outl(" //**********************************************") - cog.outl(" message_router()") - cog.outl(" : imessage_router(etl::imessage_router::MESSAGE_ROUTER)") - cog.outl(" {") - cog.outl(" }") - cog.outl("") - cog.outl(" //**********************************************") - cog.outl(" message_router(etl::imessage_router& successor_)") - cog.outl(" : imessage_router(etl::imessage_router::MESSAGE_ROUTER, successor_)") - cog.outl(" {") - cog.outl(" }") - cog.outl("") - cog.outl(" //**********************************************") - cog.outl(" using etl::imessage_router::receive;") - cog.outl("") - cog.outl(" void receive(const etl::imessage& msg) ETL_OVERRIDE") - cog.outl(" {") - cog.outl(" const size_t id = msg.get_message_id();") - cog.outl("") - cog.outl("#include \"etl/private/diagnostic_array_bounds_push.h\"") - cog.outl(" switch (id)") - cog.outl(" {") - for t in range(1, n + 1): - cog.out(" case T%d::ID:" % t) - cog.out(" static_cast(this)->on_receive(static_cast(msg));" % t) - cog.outl(" break;") - cog.outl(" default:") - cog.outl(" {") - cog.outl(" if (has_successor())") - cog.outl(" {") - cog.outl(" get_successor().receive(msg);") - cog.outl(" }") - cog.outl(" else") - cog.outl(" {") - cog.outl(" static_cast(this)->on_receive_unknown(msg);") - cog.outl(" }") - cog.outl(" break;") - cog.outl(" }") - cog.outl(" }") - cog.outl("#include \"etl/private/diagnostic_pop.h\"") - cog.outl(" }") - cog.outl("") - cog.outl(" template ") - cog.out(" typename etl::enable_if::value && etl::is_one_of::value, void>::type" % n) - cog.outl(" receive(const TMessage& msg)") - cog.outl(" {") - cog.outl("#include \"etl/private/diagnostic_array_bounds_push.h\"") - cog.outl(" static_cast(this)->on_receive(msg);") - cog.outl("#include \"etl/private/diagnostic_pop.h\"") - cog.outl(" }") - cog.outl("") - cog.outl(" template ") - cog.out(" typename etl::enable_if::value && !etl::is_one_of::value, void>::type" % n) - cog.outl(" receive(const TMessage& msg)") - cog.outl(" {") - cog.outl(" if (has_successor())") - cog.outl(" {") - cog.outl(" get_successor().receive(msg);") - cog.outl(" }") - cog.outl(" else") - cog.outl(" {") - cog.outl("#include \"etl/private/diagnostic_array_bounds_push.h\"") - cog.outl(" static_cast(this)->on_receive_unknown(msg);") - cog.outl("#include \"etl/private/diagnostic_pop.h\"") - cog.outl(" }") - cog.outl(" }") - cog.outl("") - cog.outl("") - cog.outl(" //**********************************************") - cog.outl(" using imessage_router::accepts;") - cog.outl("") - cog.outl(" bool accepts(etl::message_id_t id) const ETL_OVERRIDE") - cog.outl(" {") - cog.outl(" switch (id)") - cog.outl(" {") - cog.out(" ") - for t in range(1, n + 1): - cog.out(" case T%d::ID:" % t) - if t % 8 == 0: - cog.outl("") - if t != n: - cog.out(" ") - cog.outl("") - cog.outl(" return true;") - cog.outl(" default:") - cog.outl(" {") - cog.outl(" if (has_successor())") - cog.outl(" {") - cog.outl(" return get_successor().accepts(id);") - cog.outl(" }") - cog.outl(" else") - cog.outl(" {") - cog.outl(" return false;") - cog.outl(" }") - cog.outl(" }") - cog.outl(" }") - cog.outl(" }") - cog.outl("") - cog.outl(" //********************************************") - cog.outl(" ETL_DEPRECATED bool is_null_router() const ETL_OVERRIDE") - cog.outl(" {") - cog.outl(" return false;") - cog.outl(" }") - cog.outl("") - cog.outl(" //********************************************") - cog.outl(" bool is_producer() const ETL_OVERRIDE") - cog.outl(" {") - cog.outl(" return true;") - cog.outl(" }") - cog.outl("") - cog.outl(" //********************************************") - cog.outl(" bool is_consumer() const ETL_OVERRIDE") - cog.outl(" {") - cog.outl(" return true;") - cog.outl(" }") - cog.outl("};") - ]]]*/ - /*[[[end]]]*/ - - //*************************************************************************** - // Specialisation for 0 message types. - //*************************************************************************** - template - class message_router - : public imessage_router - { - public: - - typedef etl::message_packet<> message_packet; - -#if ETL_USING_CPP11 - using message_types = etl::type_list<>; -#endif - - //********************************************** - message_router(etl::message_router_id_t id_) - : imessage_router(id_) - { - ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); - } - - //********************************************** - message_router(etl::message_router_id_t id_, etl::imessage_router& successor_) - : imessage_router(id_, successor_) - { - ETL_ASSERT(id_ <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id)); - } - - //********************************************** - message_router() - : imessage_router(etl::imessage_router::MESSAGE_ROUTER) - { - } - - //********************************************** - message_router(etl::imessage_router& successor_) - : imessage_router(etl::imessage_router::MESSAGE_ROUTER, successor_) - { - } - - //********************************************** - using etl::imessage_router::receive; - - void receive(const etl::imessage& msg) ETL_OVERRIDE - { -#include "etl/private/diagnostic_array_bounds_push.h" - if (has_successor()) - { - get_successor().receive(msg); - } -#include "etl/private/diagnostic_pop.h" - } - - //********************************************** - using imessage_router::accepts; - - bool accepts(etl::message_id_t id) const ETL_OVERRIDE - { - if (has_successor()) - { - return get_successor().accepts(id); - } - else - { - return false; - } - } - - //******************************************** - ETL_DEPRECATED bool is_null_router() const ETL_OVERRIDE - { - return false; - } - - //******************************************** - bool is_producer() const ETL_OVERRIDE - { - return true; - } - - //******************************************** - bool is_consumer() const ETL_OVERRIDE - { - return true; - } - }; -#endif -} - -#endif diff --git a/include/etl/generators/smallest_cpp03_generator.h b/include/etl/generators/smallest_cpp03_generator.h new file mode 100644 index 00000000..5f957f72 --- /dev/null +++ b/include/etl/generators/smallest_cpp03_generator.h @@ -0,0 +1,91 @@ +//*************************************************************************** +// THIS FILE HAS BEEN AUTO GENERATED. DO NOT EDIT THIS FILE. +//*************************************************************************** + + /*[[[cog + import cog + cog.outl("//***************************************************************************") + cog.outl("/// Template to determine the smallest type and size.") + cog.outl("/// Supports up to %s types." % NTypes) + cog.outl("/// Defines 'value_type' which is the type of the smallest parameter.") + cog.outl("/// Defines 'size' which is the size of the smallest parameter.") + cog.outl("///\\ingroup smallest") + cog.outl("//***************************************************************************") + cog.out("template " % int(NTypes)) + cog.outl("struct smallest_type") + cog.outl("{") + cog.outl("private:") + cog.outl("") + cog.outl(" // Declaration.") + cog.outl(" template ") + cog.outl(" struct choose_type;") + cog.outl("") + cog.outl(" // Specialisation for 'true'.") + cog.outl(" // Defines 'type' as 'TrueType'.") + cog.outl(" template ") + cog.outl(" struct choose_type") + cog.outl(" {") + cog.outl(" typedef TrueType type;") + cog.outl(" };") + cog.outl("") + cog.outl(" // Specialisation for 'false'. ") + cog.outl(" // Defines 'type' as 'FalseType'.") + cog.outl(" template ") + cog.outl(" struct choose_type") + cog.outl(" {") + cog.outl(" typedef FalseType type;") + cog.outl(" };") + cog.outl("") + cog.outl("public:") + cog.outl("") + cog.outl(" // Define 'smallest_other' as 'smallest_type' with all but the first parameter. ") + cog.out(" typedef typename smallest_type<") + for n in range(2, int(NTypes)): + cog.out("T%s, " % n) + if n % 16 == 0: + cog.outl("") + cog.out(" ") + cog.outl("T%s>::type smallest_other;" % int(NTypes)) + cog.outl("") + cog.outl(" // Set 'type' to be the smallest of the first parameter and any of the others.") + cog.outl(" // This is recursive.") + cog.outl(" typedef typename choose_type<(sizeof(T1) < sizeof(smallest_other)), // Boolean") + cog.outl(" T1, // TrueType") + cog.outl(" smallest_other> // FalseType") + cog.outl(" ::type type; // The smallest type of the two.") + cog.outl("") + cog.outl(" // The size of the smallest type.") + cog.outl(" enum") + cog.outl(" {") + cog.outl(" size = sizeof(type)") + cog.outl(" };") + cog.outl("};") + cog.outl("") + cog.outl("//***************************************************************************") + cog.outl("// Specialisation for one template parameter.") + cog.outl("//***************************************************************************") + cog.outl("template ") + cog.out("struct smallest_type") + cog.outl("{") + cog.outl(" typedef T1 type;") + cog.outl("") + cog.outl(" enum") + cog.outl(" {") + cog.outl(" size = sizeof(type)") + cog.outl(" };") + cog.outl("};") + ]]]*/ + /*[[[end]]]*/ + diff --git a/include/etl/generators/smallest_generator.h b/include/etl/generators/smallest_generator.h deleted file mode 100644 index 1690119c..00000000 --- a/include/etl/generators/smallest_generator.h +++ /dev/null @@ -1,432 +0,0 @@ -///\file - -/****************************************************************************** -The MIT License(MIT) - -Embedded Template Library. -https://github.com/ETLCPP/etl -https://www.etlcpp.com - -Copyright(c) 2014 John Wellbelove - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files(the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions : - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -******************************************************************************/ - -/*[[[cog -import cog -cog.outl("#if 0") -]]]*/ -/*[[[end]]]*/ -#error THIS HEADER IS A GENERATOR. DO NOT INCLUDE. -/*[[[cog -import cog -cog.outl("#endif") -]]]*/ -/*[[[end]]]*/ - -/*[[[cog -import cog -cog.outl("//***************************************************************************") -cog.outl("// THIS FILE HAS BEEN AUTO GENERATED. DO NOT EDIT THIS FILE.") -cog.outl("//***************************************************************************") -]]]*/ -/*[[[end]]]*/ - -//*************************************************************************** -// To generate to header file, run this at the command line. -// Note: You will need Python and COG installed. -// -// cog -d -e -osmallest.h -DNTypes= smallest_generator.h -// Where is the number of types to support. -// -// e.g. -// To generate handlers for up to 16 types... -// cog -d -e -osmallest.h -DNTypes=16 smallest_generator.h -// -// See generate.bat -//*************************************************************************** - -#ifndef ETL_SMALLEST_INCLUDED -#define ETL_SMALLEST_INCLUDED - -#include "platform.h" -#include "integral_limits.h" - -#include - -///\defgroup smallest smallest -///\ingroup utilities - -namespace etl -{ -#if ETL_USING_CPP11 && !defined(ETL_SMALLEST_TYPE_FORCE_CPP03_IMPLEMENTATION) - //*************************************************************************** - /// Template to determine the largest type and size. - /// Defines 'value_type' which is the type of the largest parameter. - /// Defines 'size' which is the size of the largest parameter. - ///\ingroup largest - //*************************************************************************** - template - class smallest_type - { - private: - - // Define 'smallest_other' as 'smallest_type' with all but the first parameter. - using smallest_other = typename smallest_type::type; - - public: - - // Set 'type' to be the smallest of the first parameter and any of the others. - // This is recursive. - using type = typename etl::conditional<(etl::size_of::value < etl::size_of::value), // Boolean - T1, // TrueType - smallest_other> // FalseType - ::type; // The smallest type of the two. - - // The size of the smallest type. - enum - { - size = etl::size_of::value - }; - }; - - //*************************************************************************** - // Specialisation for one template parameter. - //*************************************************************************** - template - class smallest_type - { - public: - - using type = T1; - - enum - { - size = etl::size_of::value - }; - }; - -#if ETL_USING_CPP11 - template - using smallest_type_t = typename smallest_type::type; -#endif - -#if ETL_USING_CPP17 - template - constexpr size_t smallest_type_v = smallest_type::size; -#endif - -#else - /*[[[cog - import cog - cog.outl("//***************************************************************************") - cog.outl("/// Template to determine the smallest type and size.") - cog.outl("/// Supports up to %s types." % NTypes) - cog.outl("/// Defines 'value_type' which is the type of the smallest parameter.") - cog.outl("/// Defines 'size' which is the size of the smallest parameter.") - cog.outl("///\\ingroup smallest") - cog.outl("//***************************************************************************") - cog.out("template " % int(NTypes)) - cog.outl("struct smallest_type") - cog.outl("{") - cog.outl("private:") - cog.outl("") - cog.outl(" // Declaration.") - cog.outl(" template ") - cog.outl(" struct choose_type;") - cog.outl("") - cog.outl(" // Specialisation for 'true'.") - cog.outl(" // Defines 'type' as 'TrueType'.") - cog.outl(" template ") - cog.outl(" struct choose_type") - cog.outl(" {") - cog.outl(" typedef TrueType type;") - cog.outl(" };") - cog.outl("") - cog.outl(" // Specialisation for 'false'. ") - cog.outl(" // Defines 'type' as 'FalseType'.") - cog.outl(" template ") - cog.outl(" struct choose_type") - cog.outl(" {") - cog.outl(" typedef FalseType type;") - cog.outl(" };") - cog.outl("") - cog.outl("public:") - cog.outl("") - cog.outl(" // Define 'smallest_other' as 'smallest_type' with all but the first parameter. ") - cog.out(" typedef typename smallest_type<") - for n in range(2, int(NTypes)): - cog.out("T%s, " % n) - if n % 16 == 0: - cog.outl("") - cog.out(" ") - cog.outl("T%s>::type smallest_other;" % int(NTypes)) - cog.outl("") - cog.outl(" // Set 'type' to be the smallest of the first parameter and any of the others.") - cog.outl(" // This is recursive.") - cog.outl(" typedef typename choose_type<(sizeof(T1) < sizeof(smallest_other)), // Boolean") - cog.outl(" T1, // TrueType") - cog.outl(" smallest_other> // FalseType") - cog.outl(" ::type type; // The smallest type of the two.") - cog.outl("") - cog.outl(" // The size of the smallest type.") - cog.outl(" enum") - cog.outl(" {") - cog.outl(" size = sizeof(type)") - cog.outl(" };") - cog.outl("};") - cog.outl("") - cog.outl("//***************************************************************************") - cog.outl("// Specialisation for one template parameter.") - cog.outl("//***************************************************************************") - cog.outl("template ") - cog.out("struct smallest_type") - cog.outl("{") - cog.outl(" typedef T1 type;") - cog.outl("") - cog.outl(" enum") - cog.outl(" {") - cog.outl(" size = sizeof(type)") - cog.outl(" };") - cog.outl("};") - ]]]*/ - /*[[[end]]]*/ -#endif - - namespace private_smallest - { - //************************************************************************* - // Determine the type to hold the number of bits based on the index. - //************************************************************************* - template - struct best_fit_uint_type; - - //************************************************************************* - // Less than or equal to 8 bits. - //************************************************************************* - template <> - struct best_fit_uint_type<0> - { - typedef uint_least8_t type; - }; - - //************************************************************************* - // 9 to 16 bits. - //************************************************************************* - template <> - struct best_fit_uint_type<1> - { - typedef uint_least16_t type; - }; - - //************************************************************************* - // 17 to 31 bits. - //************************************************************************* - template <> - struct best_fit_uint_type<2> - { - typedef uint_least32_t type; - }; - -#if ETL_USING_64BIT_TYPES - //************************************************************************* - // Greater than 32 bits. - //************************************************************************* - template <> - struct best_fit_uint_type<3> - { - typedef uint_least64_t type; - }; -#endif - - //************************************************************************* - // Determine the type to hold the number of bits based on the index. - //************************************************************************* - template - struct best_fit_int_type; - - //************************************************************************* - // Less than or equal to 8 bits. - //************************************************************************* - template <> - struct best_fit_int_type<0> - { - typedef int_least8_t type; - }; - - //************************************************************************* - // 9 to 16 bits. - //************************************************************************* - template <> - struct best_fit_int_type<1> - { - typedef int_least16_t type; - }; - - //************************************************************************* - // 17 to 31 bits. - //************************************************************************* - template <> - struct best_fit_int_type<2> - { - typedef int_least32_t type; - }; - -#if ETL_USING_64BIT_TYPES - //************************************************************************* - // Greater than 32 bits. - //************************************************************************* - template <> - struct best_fit_int_type<3> - { - typedef int_least64_t type; - }; -#endif - } - - //*************************************************************************** - /// Template to determine the smallest unsigned int type that can contain a - /// value with the specified number of bits. - /// Defines 'type' which is the type of the smallest unsigned integer. - ///\ingroup smallest - //*************************************************************************** - template - struct smallest_uint_for_bits - { - private: - - // Determines the index of the best unsigned type for the required number of bits. - static ETL_CONSTANT int TYPE_INDEX = ((NBITS > 8) ? 1 : 0) + - ((NBITS > 16) ? 1 : 0) + - ((NBITS > 32) ? 1 : 0); - - public: - - typedef typename private_smallest::best_fit_uint_type::type type; - }; - - template - ETL_CONSTANT int smallest_uint_for_bits::TYPE_INDEX; - -#if ETL_USING_CPP11 - template - using smallest_uint_for_bits_t = typename smallest_uint_for_bits::type; -#endif - - //*************************************************************************** - /// Template to determine the smallest signed int type that can contain a - /// value with the specified number of bits. - /// Defines 'type' which is the type of the smallest signed integer. - ///\ingroup smallest - //*************************************************************************** - template - struct smallest_int_for_bits - { - private: - - // Determines the index of the best unsigned type for the required number of bits. - static ETL_CONSTANT int TYPE_INDEX = ((NBITS > 8) ? 1 : 0) + - ((NBITS > 16) ? 1 : 0) + - ((NBITS > 32) ? 1 : 0); - - public: - - typedef typename private_smallest::best_fit_int_type::type type; - }; - - template - ETL_CONSTANT int smallest_int_for_bits::TYPE_INDEX; - -#if ETL_USING_CPP11 - template - using smallest_int_for_bits_t = typename smallest_int_for_bits::type; -#endif - - //*************************************************************************** - /// Template to determine the smallest unsigned int type that can contain the - /// specified unsigned value. - /// Defines 'type' which is the type of the smallest unsigned integer. - ///\ingroup smallest - //*************************************************************************** - template - struct smallest_uint_for_value - { - private: - - // Determines the index of the best unsigned type for the required value. - static ETL_CONSTANT int TYPE_INDEX = ((VALUE > UINT_LEAST8_MAX) ? 1 : 0) + - ((VALUE > UINT16_MAX) ? 1 : 0) + - ((VALUE > UINT32_MAX) ? 1 : 0); - - public: - - typedef typename private_smallest::best_fit_uint_type::type type; - }; - - template - ETL_CONSTANT int smallest_uint_for_value::TYPE_INDEX; - -#if ETL_USING_CPP11 - template - using smallest_uint_for_value_t = typename smallest_uint_for_value::type; -#endif - - //*************************************************************************** - /// Template to determine the smallest int type that can contain the - /// specified signed value. - /// Defines 'type' which is the type of the smallest signed integer. - ///\ingroup smallest - //*************************************************************************** - template - struct smallest_int_for_value - { - private: - - // Determines the index of the best signed type for the required value. - static ETL_CONSTANT int TYPE_INDEX = (((VALUE > intmax_t(INT_LEAST8_MAX)) || (VALUE < intmax_t(INT_LEAST8_MIN))) ? 1 : 0) + - (((VALUE > intmax_t(INT16_MAX)) || (VALUE < intmax_t(INT16_MIN))) ? 1 : 0) + - (((VALUE > intmax_t(INT32_MAX)) || (VALUE < intmax_t(INT32_MIN))) ? 1 : 0); - - public: - - typedef typename private_smallest::best_fit_int_type::type type; - }; - - template - ETL_CONSTANT int smallest_int_for_value::TYPE_INDEX; - -#if ETL_USING_CPP11 - template - using smallest_int_for_value_t = typename smallest_int_for_value::type; -#endif -} - -#endif diff --git a/include/etl/generators/type_lookup_cpp03_generator.h b/include/etl/generators/type_lookup_cpp03_generator.h new file mode 100644 index 00000000..065e3465 --- /dev/null +++ b/include/etl/generators/type_lookup_cpp03_generator.h @@ -0,0 +1,109 @@ +//*************************************************************************** +// THIS FILE HAS BEEN AUTO GENERATED. DO NOT EDIT THIS FILE. +//*************************************************************************** + + + /*[[[cog + import cog + cog.outl("//***************************************************************************") + cog.outl("// For %s types." % int(NTypes)) + cog.outl("//***************************************************************************") + cog.outl("template , -%s>," %(n, n)) + cog.outl(" typename T%s = etl::type_id_pair, -%s> >" %(NTypes, NTypes)) + cog.outl("struct type_id_lookup") + cog.outl("{") + cog.outl("public:") + cog.outl("") + cog.outl(" //************************************") + cog.outl(" template ") + cog.outl(" struct type_from_id") + cog.outl(" {") + cog.outl(" typedef") + for n in range(1, int(NTypes) + 1): + cog.outl(" typename etl::conditional >") + for n in range(1, int(NTypes) + 1): + if n == int(NTypes): + cog.outl("::type type;") + else: + cog.out("::type>") + if n % 4 == 0: + if n != int(NTypes): + cog.outl("") + cog.out(" ") + cog.outl("") + cog.outl(" ETL_STATIC_ASSERT(!(etl::is_same, type>::value), \"Invalid id\");") + cog.outl(" };") + cog.outl("") + cog.outl(" //************************************") + cog.outl(" enum") + cog.outl(" {") + cog.outl(" UNKNOWN = UINT_MAX") + cog.outl(" };") + cog.outl("") + cog.outl(" template ") + cog.outl(" struct id_from_type") + cog.outl(" {") + cog.outl(" enum") + cog.outl(" {") + cog.outl(" value =") + for n in range(1, int(NTypes) + 1) : + cog.outl(" (unsigned int) etl::is_same::value ? (unsigned int)T%s::Id :" % (n, n)) + cog.outl(" (unsigned int) UNKNOWN") + cog.outl(" };") + cog.outl("") + cog.outl(" ETL_STATIC_ASSERT(((unsigned int)value != (unsigned int)UNKNOWN), \"Invalid type\");") + cog.outl(" };") + cog.outl("") + cog.outl(" //************************************") + cog.outl(" template ") + cog.outl(" static unsigned int get_id_from_type(const T&)") + cog.outl(" {") + cog.outl(" return get_id_from_type();") + cog.outl(" }") + cog.outl("") + cog.outl(" //************************************") + cog.outl(" template ") + cog.outl(" static unsigned int get_id_from_type()") + cog.outl(" {") + cog.outl(" return id_from_type::value;") + cog.outl(" }") + cog.outl("};") + cog.outl("") + cog.outl("//***************************************************************************") + cog.outl("// For %s types." % int(NTypes)) + cog.outl("//***************************************************************************") + cog.outl("template , etl::null_type<0> >," %n) + cog.outl(" typename T%s = etl::type_type_pair, etl::null_type<0> > >" %NTypes) + cog.outl("struct type_type_lookup") + cog.outl("{") + cog.outl("public:") + cog.outl("") + cog.outl(" //************************************") + cog.outl(" template ") + cog.outl(" struct type_from_type") + cog.outl(" {") + cog.outl(" typedef") + for n in range(1, int(NTypes) + 1): + cog.outl(" typename etl::conditional::value, typename T%s::type2," %(n, n)) + cog.out(" etl::null_type<0> >") + for n in range(1, int(NTypes) + 1): + if n == int(NTypes): + cog.outl("::type type;") + else: + cog.out("::type>") + if n % 8 == 0: + if n != int(NTypes): + cog.outl("") + cog.out(" ") + cog.outl("") + cog.outl(" ETL_STATIC_ASSERT(!(etl::is_same, type>::value), \"Invalid type\");") + cog.outl(" };") + cog.outl("};") + ]]]*/ + /*[[[end]]]*/ + diff --git a/include/etl/generators/type_lookup_generator.h b/include/etl/generators/type_lookup_generator.h deleted file mode 100644 index b024bf8d..00000000 --- a/include/etl/generators/type_lookup_generator.h +++ /dev/null @@ -1,337 +0,0 @@ -/****************************************************************************** -The MIT License(MIT) - -Embedded Template Library. -https://github.com/ETLCPP/etl -https://www.etlcpp.com - -Copyright(c) 2017 John Wellbelove - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files(the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions : - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -******************************************************************************/ - -#ifndef ETL_TYPE_LOOKUP_INCLUDED -#define ETL_TYPE_LOOKUP_INCLUDED - -#include "platform.h" -#include "type_traits.h" -#include "static_assert.h" -#include "integral_limits.h" -#include "null_type.h" - -#include - -/*[[[cog -import cog -cog.outl("#if 0") -]]]*/ -/*[[[end]]]*/ -#error THIS HEADER IS A GENERATOR. DO NOT INCLUDE. -/*[[[cog -import cog -cog.outl("#endif") -]]]*/ -/*[[[end]]]*/ - -/*[[[cog -import cog -cog.outl("//***************************************************************************") -cog.outl("// THIS FILE HAS BEEN AUTO GENERATED. DO NOT EDIT THIS FILE.") -cog.outl("//***************************************************************************") -]]]*/ -/*[[[end]]]*/ - -namespace etl -{ - //*************************************************************************** - /// The type/id pair type to use for type/id lookup template parameters. - //*************************************************************************** - template - struct type_id_pair - { - typedef T type; - - enum - { - Id = ID_ - }; - }; - - //*************************************************************************** - /// The type/type pair type to use for type/type lookup template parameters. - //*************************************************************************** - template - struct type_type_pair - { - typedef T1 type1; - typedef T2 type2; - }; - -#if ETL_USING_CPP11 && !defined(ETL_TYPE_SELECT_FORCE_CPP03_IMPLEMENTATION) - //*************************************************************************** - // type_id_lookup - //*************************************************************************** - template - struct type_id_lookup - { - private: - - // The type for no match. - struct nulltype {}; - - // For N type pairs. - template - struct type_from_id_helper - { - using type = typename etl::conditional::type>::type; - }; - - // Specialisation for 1 type pair. - template - struct type_from_id_helper - { - using type = typename etl::conditional::type; - }; - - public: - - //************************************ - // type_from_id - //************************************ - template - struct type_from_id - { - using type = typename type_from_id_helper::type; - - static_assert(!(etl::is_same::value), "Invalid id"); - }; - - template - using type_from_id_t = typename type_from_id::type; - - private: - - static constexpr size_t UNKNOWN = etl::integral_limits::max; - - // For N type pairs. - template - struct id_from_type_helper - { - static constexpr size_t value = etl::is_same::value ? size_t(T1::Id) : id_from_type_helper::value; - }; - - // Specialisation for 1 type pair. - template - struct id_from_type_helper - { - static constexpr size_t value = etl::is_same::value ? size_t(T1::Id) : UNKNOWN; - }; - - public: - - //************************************ - // id_from_type - //************************************ - template - struct id_from_type - { - static constexpr size_t value = id_from_type_helper::value; - - static_assert(value != UNKNOWN, "Invalid type"); - }; - -#if ETL_USING_CPP17 - template - static constexpr size_t id_from_type_v = id_from_type::value; -#endif - - //************************************ - template - static unsigned int get_id_from_type(const T&) - { - return get_id_from_type(); - } - - //************************************ - template - static unsigned int get_id_from_type() - { - return id_from_type::value; - } - }; - - //*************************************************************************** - // type_type_lookup - //*************************************************************************** - template - class type_type_lookup - { - private: - - // The type for no match. - struct nulltype {}; - - template - struct type_from_type_helper - { - using type = typename etl::conditional::value, - typename T1::type2, - typename type_from_type_helper::type>::type; - }; - - template - struct type_from_type_helper - { - using type = typename etl::conditional::value, - typename T1::type2, - nulltype>::type; - }; - - public: - - template - class type_from_type - { - public: - - // The matched type or nulltype - using type = typename type_from_type_helper::type; - - static_assert(!etl::is_same::value, "Type match not found"); - }; - - // Template alias. - template - using type_from_type_t = typename type_from_type::type; - }; - -#else - - /*[[[cog - import cog - cog.outl("//***************************************************************************") - cog.outl("// For %s types." % int(NTypes)) - cog.outl("//***************************************************************************") - cog.outl("template , -%s>," %(n, n)) - cog.outl(" typename T%s = etl::type_id_pair, -%s> >" %(NTypes, NTypes)) - cog.outl("struct type_id_lookup") - cog.outl("{") - cog.outl("public:") - cog.outl("") - cog.outl(" //************************************") - cog.outl(" template ") - cog.outl(" struct type_from_id") - cog.outl(" {") - cog.outl(" typedef") - for n in range(1, int(NTypes) + 1): - cog.outl(" typename etl::conditional >") - for n in range(1, int(NTypes) + 1): - if n == int(NTypes): - cog.outl("::type type;") - else: - cog.out("::type>") - if n % 4 == 0: - if n != int(NTypes): - cog.outl("") - cog.out(" ") - cog.outl("") - cog.outl(" ETL_STATIC_ASSERT(!(etl::is_same, type>::value), \"Invalid id\");") - cog.outl(" };") - cog.outl("") - cog.outl(" //************************************") - cog.outl(" enum") - cog.outl(" {") - cog.outl(" UNKNOWN = UINT_MAX") - cog.outl(" };") - cog.outl("") - cog.outl(" template ") - cog.outl(" struct id_from_type") - cog.outl(" {") - cog.outl(" enum") - cog.outl(" {") - cog.outl(" value =") - for n in range(1, int(NTypes) + 1) : - cog.outl(" (unsigned int) etl::is_same::value ? (unsigned int)T%s::Id :" % (n, n)) - cog.outl(" (unsigned int) UNKNOWN") - cog.outl(" };") - cog.outl("") - cog.outl(" ETL_STATIC_ASSERT(((unsigned int)value != (unsigned int)UNKNOWN), \"Invalid type\");") - cog.outl(" };") - cog.outl("") - cog.outl(" //************************************") - cog.outl(" template ") - cog.outl(" static unsigned int get_id_from_type(const T&)") - cog.outl(" {") - cog.outl(" return get_id_from_type();") - cog.outl(" }") - cog.outl("") - cog.outl(" //************************************") - cog.outl(" template ") - cog.outl(" static unsigned int get_id_from_type()") - cog.outl(" {") - cog.outl(" return id_from_type::value;") - cog.outl(" }") - cog.outl("};") - cog.outl("") - cog.outl("//***************************************************************************") - cog.outl("// For %s types." % int(NTypes)) - cog.outl("//***************************************************************************") - cog.outl("template , etl::null_type<0> >," %n) - cog.outl(" typename T%s = etl::type_type_pair, etl::null_type<0> > >" %NTypes) - cog.outl("struct type_type_lookup") - cog.outl("{") - cog.outl("public:") - cog.outl("") - cog.outl(" //************************************") - cog.outl(" template ") - cog.outl(" struct type_from_type") - cog.outl(" {") - cog.outl(" typedef") - for n in range(1, int(NTypes) + 1): - cog.outl(" typename etl::conditional::value, typename T%s::type2," %(n, n)) - cog.out(" etl::null_type<0> >") - for n in range(1, int(NTypes) + 1): - if n == int(NTypes): - cog.outl("::type type;") - else: - cog.out("::type>") - if n % 8 == 0: - if n != int(NTypes): - cog.outl("") - cog.out(" ") - cog.outl("") - cog.outl(" ETL_STATIC_ASSERT(!(etl::is_same, type>::value), \"Invalid type\");") - cog.outl(" };") - cog.outl("};") - ]]]*/ - /*[[[end]]]*/ - -#endif -} - -#endif \ No newline at end of file diff --git a/include/etl/generators/type_select_cpp03_generator.h b/include/etl/generators/type_select_cpp03_generator.h new file mode 100644 index 00000000..4ec3cd9a --- /dev/null +++ b/include/etl/generators/type_select_cpp03_generator.h @@ -0,0 +1,73 @@ +//*************************************************************************** +// THIS FILE HAS BEEN AUTO GENERATED. DO NOT EDIT THIS FILE. +//*************************************************************************** + +/*[[[cog +import cog +cog.outl("") +cog.outl(" //***************************************************************************") +cog.outl(" // For %s types." % int(NTypes)) +cog.outl(" //***************************************************************************") +cog.outl(" template " %(int(NTypes) - 1)) +cog.outl(" struct type_select") +cog.outl(" {") +cog.outl(" public:") +cog.outl("") +cog.outl(" template ") +cog.outl(" struct select") +cog.outl(" {") +cog.outl(" typedef typename etl::conditional >") +cog.out(" ") +for n in range(1, int(NTypes)) : + cog.out("::type>") + if n % 8 == 0: + cog.outl("") + cog.out(" ") +cog.outl("::type type;") +cog.outl(""); +cog.outl(" ETL_STATIC_ASSERT(Id < %s, \"Invalid Id\");" % int(NTypes)); +cog.outl(" };") +cog.outl(" };") + +for s in range(int(NTypes) - 1, 0, -1): + cog.outl("") + cog.outl(" //***************************************************************************") + cog.outl(" // For %s types." % int(s)) + cog.outl(" //***************************************************************************") + cog.out(" template <") + for n in range(0, s - 1): + cog.outl("typename T%s, " % n) + cog.out(" ") + cog.outl("typename T%s>" % (s - 1)) + cog.out(" struct type_select<") + for n in range(0, s - 1): + cog.out("T%s, " % n) + cog.outl("T%s>" % (s - 1)) + cog.outl(" {") + cog.outl(" public:") + cog.outl(" template ") + cog.outl(" struct select") + cog.outl(" {") + cog.outl(" typedef typename etl::conditional >") + cog.out(" ") + for n in range(1, s) : + cog.out("::type>") + if n % 8 == 0: + cog.outl("") + cog.out(" ") + cog.outl("::type type;") + cog.outl(""); + cog.outl(" ETL_STATIC_ASSERT(Id < %s, \"Invalid Id\");" % s); + cog.outl(" };") + cog.outl(" };") +]]]*/ +/*[[[end]]]*/ diff --git a/include/etl/generators/type_select_generator.h b/include/etl/generators/type_select_generator.h deleted file mode 100644 index aab2d0f3..00000000 --- a/include/etl/generators/type_select_generator.h +++ /dev/null @@ -1,177 +0,0 @@ -/****************************************************************************** -The MIT License(MIT) - -Embedded Template Library. -https://github.com/ETLCPP/etl -https://www.etlcpp.com - -Copyright(c) 2018 John Wellbelove - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files(the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions : - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -******************************************************************************/ - -#ifndef ETL_TYPE_SELECT_INCLUDED -#define ETL_TYPE_SELECT_INCLUDED - -#include "platform.h" -#include "static_assert.h" -#include "type_traits.h" -#include "null_type.h" - -/*[[[cog -import cog -cog.outl("#if 0") -]]]*/ -/*[[[end]]]*/ -#error THIS HEADER IS A GENERATOR. DO NOT INCLUDE. -/*[[[cog -import cog -cog.outl("#endif") -]]]*/ -/*[[[end]]]*/ - -/*[[[cog -import cog -cog.outl("//***************************************************************************") -cog.outl("// THIS FILE HAS BEEN AUTO GENERATED. DO NOT EDIT THIS FILE.") -cog.outl("//***************************************************************************") -]]]*/ -/*[[[end]]]*/ - -namespace etl -{ -#if ETL_USING_CPP11 && !defined(ETL_TYPE_SELECT_FORCE_CPP03_IMPLEMENTATION) - //*************************************************************************** - // Variadic version. - //*************************************************************************** - template - struct type_select - { - private: - - //*********************************** - template - struct type_select_helper - { - using type = typename etl::conditional::type>::type; - }; - - //*********************************** - template - struct type_select_helper - { - using type = T1; - }; - - public: - - template - struct select - { - static_assert(Id < sizeof...(TTypes), "Illegal type_select::select index"); - - using type = typename type_select_helper::type; - }; - - template - using select_t = typename select::type; - }; - - //*************************************************************************** - // Select type alias - //*************************************************************************** - template - using type_select_t = typename etl::type_select:: template select_t; - -#else - - /*[[[cog - import cog - cog.outl("//***************************************************************************") - cog.outl("// For %s types." % int(NTypes)) - cog.outl("//***************************************************************************") - cog.outl("template " %(int(NTypes) - 1)) - cog.outl("struct type_select") - cog.outl("{") - cog.outl("public:") - cog.outl("") - cog.outl(" template ") - cog.outl(" struct select") - cog.outl(" {") - cog.outl(" typedef typename etl::conditional >") - cog.out(" ") - for n in range(1, int(NTypes)) : - cog.out("::type>") - if n % 8 == 0: - cog.outl("") - cog.out(" ") - cog.outl("::type type;") - cog.outl(""); - cog.outl(" ETL_STATIC_ASSERT(Id < %s, \"Invalid Id\");" % int(NTypes)); - cog.outl(" };") - cog.outl("};") - - for s in range(int(NTypes) - 1, 0, -1): - cog.outl("") - cog.outl("//***************************************************************************") - cog.outl("// For %s types." % int(s)) - cog.outl("//***************************************************************************") - cog.out("template <") - for n in range(0, s - 1): - cog.outl("typename T%s, " % n) - cog.out(" ") - cog.outl("typename T%s>" % (s - 1)) - cog.out("struct type_select<") - for n in range(0, s - 1): - cog.out("T%s, " % n) - cog.outl("T%s>" % (s - 1)) - cog.outl("{") - cog.outl("public:") - cog.outl(" template ") - cog.outl(" struct select") - cog.outl(" {") - cog.outl(" typedef typename etl::conditional >") - cog.out(" ") - for n in range(1, s) : - cog.out("::type>") - if n % 8 == 0: - cog.outl("") - cog.out(" ") - cog.outl("::type type;") - cog.outl(""); - cog.outl(" ETL_STATIC_ASSERT(Id < %s, \"Invalid Id\");" % s); - cog.outl(" };") - cog.outl("};") - ]]]*/ - /*[[[end]]]*/ -#endif -} - -#endif diff --git a/include/etl/generators/type_traits_cpp03_generator.h b/include/etl/generators/type_traits_cpp03_generator.h new file mode 100644 index 00000000..7c8d260d --- /dev/null +++ b/include/etl/generators/type_traits_cpp03_generator.h @@ -0,0 +1,28 @@ +//*************************************************************************** +// THIS FILE HAS BEEN AUTO GENERATED. DO NOT EDIT THIS FILE. +//*************************************************************************** + + /*[[[cog + import cog + cog.outl("//***************************************************************************") + cog.outl("/// Template to determine if a type is one of a specified list.") + cog.outl("///\\ingroup types") + cog.outl("template " % IsOneOf) + cog.outl("struct is_one_of") + cog.outl("{") + cog.outl(" static const bool value =") + for n in range(1, int(IsOneOf)): + cog.outl(" etl::is_same::value ||" % n) + cog.outl(" etl::is_same::value;" % IsOneOf) + cog.outl("};") + ]]]*/ + /*[[[end]]]*/ + diff --git a/include/etl/generators/type_traits_generator.h b/include/etl/generators/type_traits_generator.h deleted file mode 100644 index 843ce343..00000000 --- a/include/etl/generators/type_traits_generator.h +++ /dev/null @@ -1,3272 +0,0 @@ -///\file - -/****************************************************************************** -The MIT License(MIT) - -Embedded Template Library. -https://github.com/ETLCPP/etl -https://www.etlcpp.com - -Copyright(c) 2014 John Wellbelove - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files(the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions : - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -******************************************************************************/ - -/*[[[cog -import cog -cog.outl("#if 0") -]]]*/ -/*[[[end]]]*/ -#error THIS HEADER IS A GENERATOR. DO NOT INCLUDE. -/*[[[cog -import cog -cog.outl("#endif") -]]]*/ -/*[[[end]]]*/ - -/*[[[cog -import cog -cog.outl("//***************************************************************************") -cog.outl("// THIS FILE HAS BEEN AUTO GENERATED. DO NOT EDIT THIS FILE.") -cog.outl("//***************************************************************************") -]]]*/ -/*[[[end]]]*/ - -//*************************************************************************** -// To generate to header file, run this at the command line. -// Note: You will need Python and COG installed. -// -// cog -d -e -otypes.h -DHandlers= types_generator.h -// Where is the number of types to support. -// -// e.g. -// To generate handlers for up to 16 types... -// cog -d -e -otype_traits.h -DIsOneOf=16 type_traits_generator.h -// -// See generate.bat -//*************************************************************************** - -#ifndef ETL_TYPE_TRAITS_INCLUDED -#define ETL_TYPE_TRAITS_INCLUDED - -#include "platform.h" -#include "nullptr.h" -#include "static_assert.h" - -#include -#include - -///\defgroup type_traits type_traits -/// A set of type traits definitions. -/// Derived from either the standard or alternate definitions, dependent on whether or not ETL_NO_STL is defined. -/// \ingroup utilities - -#if ETL_USING_STL && ETL_USING_CPP11 - #include -#endif - -namespace etl -{ -#if ETL_USING_CPP11 - template - using void_t = void; -#endif - -#if ETL_NOT_USING_STL || ETL_CPP11_NOT_SUPPORTED - - //***************************************************************************** - // Traits are defined by the ETL - //***************************************************************************** - - //*************************************************************************** - /// integral_constant - template - struct integral_constant - { - static const T value = VALUE; - - typedef T value_type; - typedef integral_constant type; - - operator value_type() const - { - return value; - } - }; - - /// integral_constant specialisations - typedef integral_constant false_type; - typedef integral_constant true_type; - - template - const T integral_constant::value; - -#if ETL_USING_CPP17 - template - inline constexpr T integral_constant_v = etl::integral_constant::value; -#endif - -#if ETL_USING_CPP11 - template - using bool_constant = integral_constant; -#else - template - struct bool_constant : etl::integral_constant { }; -#endif - -#if ETL_USING_CPP17 - template - inline constexpr bool bool_constant_v = bool_constant::value; -#endif - - //*************************************************************************** - /// negation - template - struct negation : etl::bool_constant - { - }; - -#if ETL_USING_CPP17 - template - inline constexpr bool negation_v = negation::value; -#endif - - //*************************************************************************** - /// remove_reference - template struct remove_reference { typedef T type; }; - template struct remove_reference { typedef T type; }; -#if ETL_USING_CPP11 - template struct remove_reference { typedef T type; }; -#endif - -#if ETL_USING_CPP11 - template - using remove_reference_t = typename remove_reference::type; -#endif - - //*************************************************************************** - /// remove_pointer - template struct remove_pointer { typedef T type; }; - template struct remove_pointer { typedef T type; }; - template struct remove_pointer { typedef const T type; }; - template struct remove_pointer { typedef volatile T type; }; - template struct remove_pointer { typedef const volatile T type; }; - template struct remove_pointer { typedef T type; }; - template struct remove_pointer { typedef const T type; }; - template struct remove_pointer { typedef volatile T type; }; - template struct remove_pointer { typedef const volatile T type; }; - -#if ETL_USING_CPP11 - template - using remove_pointer_t = typename remove_pointer::type; -#endif - - //*************************************************************************** - /// add_pointer - template struct add_pointer { typedef typename remove_reference::type* type; }; - -#if ETL_USING_CPP11 - template - using add_pointer_t = typename add_pointer::type; -#endif - - //*************************************************************************** - /// is_const - template struct is_const : false_type {}; - template struct is_const : true_type {}; - template struct is_const : true_type {}; - -#if ETL_USING_CPP17 - template - inline constexpr bool is_const_v = is_const::value; -#endif - - //*************************************************************************** - /// remove_const - template struct remove_const { typedef T type; }; - template struct remove_const { typedef T type; }; - -#if ETL_USING_CPP11 - template - using remove_const_t = typename remove_const::type; -#endif - - //*************************************************************************** - /// add_const - template struct add_const { typedef const T type; }; - template struct add_const { typedef const T type; }; - -#if ETL_USING_CPP11 - template - using add_const_t = typename add_const::type; -#endif - - //*************************************************************************** - /// is_volatile - template struct is_volatile : false_type {}; - template struct is_volatile : true_type {}; - template struct is_volatile : true_type {}; - -#if ETL_USING_CPP17 - template - inline constexpr bool is_volatile_v = is_volatile::value; -#endif - - //*************************************************************************** - /// remove_volatile - template struct remove_volatile { typedef T type; }; - template struct remove_volatile { typedef T type; }; - -#if ETL_USING_CPP11 - template - using remove_volatile_t = typename remove_volatile::type; -#endif - - //*************************************************************************** - /// add_volatile - template struct add_volatile { typedef volatile T type; }; - template struct add_volatile { typedef volatile T type; }; - -#if ETL_USING_CPP11 - template - using add_volatile_t = typename add_volatile::type; -#endif - - //*************************************************************************** - /// remove_cv - template struct remove_cv - { - typedef typename remove_volatile::type>::type type; - }; - -#if ETL_USING_CPP11 - template - using remove_cv_t = typename remove_cv::type; -#endif - - //*************************************************************************** - /// add_cv - template struct add_cv - { - typedef typename add_volatile::type>::type type; - }; - -#if ETL_USING_CPP11 - template - using add_cv_t = typename add_cv::type; -#endif - - //*************************************************************************** - /// remove_cvref - template struct remove_cvref - { - typedef typename remove_cv::type>::type type; - }; - -#if ETL_USING_CPP11 - template - using remove_cvref_t = typename remove_cvref::type; -#endif - - //*************************************************************************** - /// is_integral - template struct is_integral : false_type {}; - template <> struct is_integral : true_type {}; - template <> struct is_integral : true_type {}; - template <> struct is_integral : true_type {}; - template <> struct is_integral : true_type {}; - template <> struct is_integral : true_type {}; - template <> struct is_integral : true_type {}; - template <> struct is_integral : true_type {}; - template <> struct is_integral : true_type {}; - template <> struct is_integral : true_type {}; - template <> struct is_integral : true_type {}; - template <> struct is_integral : true_type {}; - template <> struct is_integral : true_type {}; - template <> struct is_integral : true_type {}; -#if ETL_HAS_NATIVE_CHAR8_T - template <> struct is_integral : true_type {}; -#endif -#if ETL_HAS_NATIVE_CHAR16_T - template <> struct is_integral : true_type {}; -#endif -#if ETL_HAS_NATIVE_CHAR32_T - template <> struct is_integral : true_type {}; -#endif - template struct is_integral : is_integral {}; - template struct is_integral : is_integral {}; - template struct is_integral : is_integral {}; - -#if ETL_USING_CPP17 - template - inline constexpr bool is_integral_v = is_integral::value; -#endif - - //*************************************************************************** - /// is_signed - template struct is_signed : false_type {}; - template <> struct is_signed : etl::bool_constant<(char(255) < 0)> {}; - template <> struct is_signed : public etl::bool_constant {}; - template <> struct is_signed : true_type {}; - template <> struct is_signed : true_type {}; - template <> struct is_signed : true_type {}; - template <> struct is_signed : true_type {}; - template <> struct is_signed : true_type {}; - template <> struct is_signed : true_type {}; - template <> struct is_signed : true_type {}; - template <> struct is_signed : true_type {}; -#if ETL_HAS_NATIVE_CHAR8_T - template <> struct is_signed : true_type {}; -#endif -#if ETL_HAS_NATIVE_CHAR16_T - template <> struct is_signed : true_type {}; -#endif -#if ETL_HAS_NATIVE_CHAR32_T - template <> struct is_signed : true_type {}; -#endif - template struct is_signed : is_signed {}; - template struct is_signed : is_signed {}; - template struct is_signed : is_signed {}; - -#if ETL_USING_CPP17 - template - inline constexpr bool is_signed_v = is_signed::value; -#endif - - //*************************************************************************** - /// is_unsigned - template struct is_unsigned : false_type {}; - template <> struct is_unsigned : true_type {}; - template <> struct is_unsigned : etl::bool_constant<(char(255) > 0)> {}; - template <> struct is_unsigned : true_type {}; - template <> struct is_unsigned : public etl::bool_constant<(wchar_t(-1) > wchar_t(0))> {}; - template <> struct is_unsigned : true_type {}; - template <> struct is_unsigned : true_type {}; - template <> struct is_unsigned : true_type {}; - template <> struct is_unsigned : true_type {}; - template struct is_unsigned : is_unsigned {}; - template struct is_unsigned : is_unsigned {}; - template struct is_unsigned : is_unsigned {}; - -#if ETL_USING_CPP17 - template - inline constexpr bool is_unsigned_v = is_unsigned::value; -#endif - - //*************************************************************************** - /// is_floating_point - template struct is_floating_point : false_type {}; - template <> struct is_floating_point : true_type {}; - template <> struct is_floating_point : true_type {}; - template <> struct is_floating_point : true_type {}; - template struct is_floating_point : is_floating_point {}; - template struct is_floating_point : is_floating_point {}; - template struct is_floating_point : is_floating_point {}; - -#if ETL_USING_CPP17 - template - inline constexpr bool is_floating_point_v = is_floating_point::value; -#endif - - //*************************************************************************** - /// is_same - template struct is_same : public false_type {}; - template struct is_same : public true_type {}; - -#if ETL_USING_CPP17 - template - inline constexpr bool is_same_v = is_same::value; -#endif - - //*************************************************************************** - /// is_void - template struct is_void : false_type {}; - template<> struct is_void : true_type {}; - -#if ETL_USING_CPP17 - template - inline constexpr bool is_void_v = is_void::value; -#endif - - //*************************************************************************** - /// is_arithmetic - template struct is_arithmetic : etl::bool_constant::value || is_floating_point::value> {}; - -#if ETL_USING_CPP17 - template - inline constexpr bool is_arithmetic_v = is_arithmetic::value; -#endif - - //*************************************************************************** - /// is_fundamental - template struct is_fundamental : etl::bool_constant::value || is_void::value> {}; - -#if ETL_USING_CPP17 - template - inline constexpr bool is_fundamental_v = is_fundamental::value; -#endif - - //*************************************************************************** - /// is_compound - template struct is_compound : etl::bool_constant::value> {}; - -#if ETL_USING_CPP17 - template - inline constexpr bool is_compound_v = is_compound::value; -#endif - - //*************************************************************************** - /// is_array - template struct is_array : false_type {}; - template struct is_array : true_type {}; - template struct is_array : true_type {}; - -#if ETL_USING_CPP17 - template - inline constexpr bool is_array_v = is_array::value; -#endif - - //*************************************************************************** - /// is_pointer - template struct is_pointer_helper : false_type {}; - template struct is_pointer_helper : true_type {}; - template struct is_pointer_helper : is_pointer_helper {}; - template struct is_pointer_helper : is_pointer_helper {}; - template struct is_pointer_helper : is_pointer_helper {}; - template struct is_pointer : is_pointer_helper::type> {}; - -#if ETL_USING_CPP17 - template - inline constexpr bool is_pointer_v = is_pointer::value; -#endif - - //*************************************************************************** - /// is_lvalue_reference - template struct is_lvalue_reference_helper : false_type {}; - template struct is_lvalue_reference_helper : true_type {}; - template struct is_lvalue_reference : is_lvalue_reference_helper::type> {}; - -#if ETL_USING_CPP17 - template - inline constexpr bool is_lvalue_reference_v = etl::is_lvalue_reference::value; -#endif - -#if ETL_USING_CPP11 - //*************************************************************************** - /// is_rvalue_reference - template struct is_rvalue_reference_helper : false_type {}; - template struct is_rvalue_reference_helper : true_type {}; - template struct is_rvalue_reference : is_rvalue_reference_helper::type> {}; - -#if ETL_USING_CPP17 - template - inline constexpr bool is_rvalue_reference_v = etl::is_rvalue_reference::value; -#endif -#endif - - //*************************************************************************** - /// is_reference - // Either lvalue or rvalue (for CPP11) - template struct is_reference : integral_constant::value - #if ETL_USING_CPP11 - || is_rvalue_reference::value - #endif - >{}; - -#if ETL_USING_CPP17 - template - inline constexpr bool is_reference_v = is_reference::value; -#endif - - //*************************************************************************** - /// is_pod - /// Only fundamental and pointers types are recognised. - template struct is_pod : etl::bool_constant::value || etl::is_pointer::value> {}; - -#if ETL_USING_CPP17 - template - inline constexpr bool is_pod_v = etl::is_pod::value; -#endif - - //*************************************************************************** - /// conditional - template struct conditional { typedef T type; }; - template struct conditional { typedef F type; }; - -#if ETL_USING_CPP11 - template - using conditional_t = typename conditional::type; -#endif - - //*************************************************************************** - /// make_signed - template struct make_signed { typedef T type; }; - template <> struct make_signed { typedef signed char type; }; - template <> struct make_signed { typedef signed char type; }; - - template <> struct make_signed - { - typedef etl::conditional::type>::type type; - }; - - template <> struct make_signed { typedef short type; }; - template <> struct make_signed { typedef int type; }; - template <> struct make_signed { typedef long type; }; - template <> struct make_signed { typedef long long type; }; - template struct make_signed : add_const::type> {}; - template struct make_signed : add_volatile::type> {}; - template struct make_signed : add_const::type>::type> {}; - -#if ETL_USING_CPP11 - template - using make_signed_t = typename make_signed::type; -#endif - - //*************************************************************************** - /// make_unsigned - template struct make_unsigned { typedef T type; }; - template <> struct make_unsigned { typedef unsigned char type; }; - template <> struct make_unsigned { typedef unsigned char type; }; - template <> struct make_unsigned { typedef unsigned short type; }; - - template <> struct make_unsigned - { - typedef etl::conditional::type>::type type; - }; - - template <> struct make_unsigned { typedef unsigned int type; }; - template <> struct make_unsigned { typedef unsigned long type; }; - template <> struct make_unsigned { typedef unsigned long long type; }; - template struct make_unsigned : add_const::type> {}; - template struct make_unsigned : add_volatile::type> {}; - template struct make_unsigned : add_const::type>::type> {}; - -#if ETL_USING_CPP11 - template - using make_unsigned_t = typename make_unsigned::type; -#endif - - //*************************************************************************** - /// enable_if - template struct enable_if {}; - template struct enable_if { typedef T type; }; - -#if ETL_USING_CPP11 - template - using enable_if_t = typename enable_if::type; -#endif - - //*************************************************************************** - /// extent - template - struct extent : integral_constant {}; - - template - struct extent : integral_constant {}; - - template - struct extent : integral_constant::value> {}; - - template - struct extent : integral_constant {}; - - template - struct extent : integral_constant::value> {}; - -#if ETL_USING_CPP17 - template - inline constexpr size_t extent_v = extent::value; -#endif - - //*************************************************************************** - /// remove_extent - template struct remove_extent { typedef T type; }; - template struct remove_extent { typedef T type; }; - template struct remove_extent { typedef T type; }; - -#if ETL_USING_CPP11 - template - using remove_extent_t = typename remove_extent::type; -#endif - - //*************************************************************************** - /// remove_all_extents - template struct remove_all_extents { typedef T type; }; - template struct remove_all_extents { typedef typename remove_all_extents::type type; }; - template struct remove_all_extents { typedef typename remove_all_extents::type type; }; - -#if ETL_USING_CPP11 - template - using remove_all_extents_t = typename remove_all_extents::type; -#endif - - //*************************************************************************** - /// rank - template struct rank : integral_constant {}; - template struct rank : public integral_constant::value + 1> {}; - template struct rank : public integral_constant::value + 1> {}; - -#if ETL_USING_CPP17 - template - inline constexpr size_t rank_v = rank::value; -#endif - - //*************************************************************************** - /// decay - template - struct decay - { - typedef typename etl::remove_reference::type U; - typedef typename etl::conditional::value, - typename etl::remove_extent::type*, - typename etl::remove_cv::type>::type type; - }; - -#if ETL_USING_CPP11 - template - using decay_t = typename decay::type; -#endif - - //*************************************************************************** - /// is_class - namespace private_type_traits - { - template char test(int T::*); // Match for classes. - - struct dummy { char c[2]; }; - template dummy test(...); // Match for non-classes. - } - - template - struct is_class : etl::bool_constant(0)) == 1U> {}; - -#if ETL_USING_CPP17 - template - inline constexpr bool is_class_v = is_class::value; -#endif - - //*************************************************************************** - /// is_base_of -#if ETL_USING_CPP11 - namespace private_type_traits - { - template - etl::true_type test_ptr_conv(const volatile B*); - template - etl::false_type test_ptr_conv(const volatile void*); - - template - auto test_is_base_of(int) -> decltype(test_ptr_conv(static_cast(nullptr))); - template - auto test_is_base_of(...) -> etl::true_type; // private or ambiguous base - } - - template - struct is_base_of: etl::integral_constant< - bool, - etl::is_class::value && - etl::is_class::value && - decltype(private_type_traits::test_is_base_of(0))::value - > {}; -#else - template::value || etl::is_fundamental::value || etl::is_array::value)> - struct is_base_of - { - private: - - static TBase* check(TBase*) { return (TBase*)0; } - static char check(...) { return 0; } - - public: - - static const bool value = (sizeof(check((TDerived*)0)) == sizeof(TBase*)); - }; - - // For when TBase or TDerived is a fundamental type. - template - struct is_base_of - { - static const bool value = false; - }; -#endif - -#if ETL_USING_CPP17 - template - inline constexpr bool is_base_of_v = is_base_of::value; -#endif - - //*************************************************************************** - /// add_lvalue_reference - template struct add_lvalue_reference { typedef T& type; }; - template struct add_lvalue_reference { typedef T& type; }; - template <> struct add_lvalue_reference { typedef void type; }; - template <> struct add_lvalue_reference { typedef const void type; }; - template <> struct add_lvalue_reference { typedef volatile void type; }; - template <> struct add_lvalue_reference { typedef const volatile void type; }; - -#if ETL_USING_CPP11 - template - using add_lvalue_reference_t = typename etl::add_lvalue_reference::type; -#endif - - //*************************************************************************** - /// add_rvalue_reference -#if ETL_USING_CPP11 - template struct add_rvalue_reference { using type = T && ; }; - template struct add_rvalue_reference { using type = T & ; }; - template <> struct add_rvalue_reference { using type = void; }; - template <> struct add_rvalue_reference { using type = const void; }; - template <> struct add_rvalue_reference { using type = volatile void; }; - template <> struct add_rvalue_reference { using type = const volatile void; }; -#endif - -#if ETL_USING_CPP11 - template - using add_rvalue_reference_t = typename etl::add_rvalue_reference::type; -#endif - - //*************************************************************************** - /// declval -#if ETL_USING_CPP11 - template - typename etl::add_rvalue_reference::type declval() ETL_NOEXCEPT; -#endif - -#if ETL_USING_CPP11 - //*************************************************************************** - /// is_enum - ///\ingroup type_traits - /// Implemented by checking if type is convertible to an integer through static_cast - - namespace private_type_traits - { - // Base case - template - struct is_convertible_to_int - : false_type - { - }; - - // Selected if `static_cast(declval())` is a valid statement - // 2nd template argument of base case defaults to int to ensure that this partial specialization is always tried first - template - struct is_convertible_to_int(declval()))> - : true_type - { - }; - } - - template - struct is_enum - : integral_constant::value && - !is_class::value && - !is_arithmetic::value && - !is_reference::value> - { - }; - -#if ETL_USING_CPP17 - template - inline constexpr bool is_enum_v = etl::is_enum::value; -#endif -#else - namespace private_type_traits - { - // Helper to detect if a type is convertible to an integer - template - struct is_convertible_to_int - { - static char test(int); // Match if T is convertible to int - static double test(...); // Fallback for other types - - static const bool value = sizeof(test(static_cast(0))) == sizeof(char); - }; - } - - // Implementation of is_enum - template - struct is_enum - { - static const bool value = private_type_traits::is_convertible_to_int::value && - !is_class::value && - !is_arithmetic::value && - !is_reference::value; - }; -#endif - - //*************************************************************************** - /// is_convertible - ///\ingroup type_traits -#if ETL_USING_CPP11 - namespace private_type_traits - { - template - using true_type_for = etl::true_type; - - template - auto returnable(int)->true_type_for; - - template - auto returnable(...)->etl::false_type; - - template - auto nonvoid_convertible(int)->true_type_for()(etl::declval())) - >; - template - auto nonvoid_convertible(...)->etl::false_type; - } - -#if defined(ETL_COMPILER_ARM5) - template - struct is_convertible : etl::bool_constant<__is_convertible_to(TFrom, TTo)> {}; -#else - template - struct is_convertible : etl::bool_constant<(decltype(private_type_traits::returnable(0))::value && - decltype(private_type_traits::nonvoid_convertible(0))::value) || - (etl::is_void::value && etl::is_void::value)> {}; -#endif - - // Is convertible and the conversion is noexcept. - template - struct is_nothrow_convertible - { - private: - // Helper: a function taking TTo to require the conversion. - static void sink(TTo) noexcept; - - // Selected only if 'sink(declval())' is a valid expression. - template - static auto test(int) -> etl::bool_constant()))>; - - // Fallback if conversion is not viable. - template - static etl::false_type test(...); - - public: - static ETL_CONSTANT bool value = decltype(test(0))::value; - }; -#else - namespace private_type_traits - { - typedef char yes; - struct no { char dummy[2]; }; - - template - struct is_convertible_impl - { - static yes test(TTo); - static no test(...); - static TFrom make(); - static const bool value = (sizeof(test(make())) == sizeof(yes)); - }; - - template - struct is_convertible_impl - { - static const bool value = false; - }; - - template - struct is_convertible_impl - { - static const bool value = false; - }; - - template <> - struct is_convertible_impl - { - static const bool value = true; - }; - } - - template - struct is_convertible : etl::bool_constant::value> {}; -#endif - -#if ETL_USING_CPP17 - template - inline constexpr bool is_convertible_v = etl::is_convertible::value; - - template - inline constexpr bool is_nothrow_convertible_v = etl::is_nothrow_convertible::value; -#endif - - //*************************************************************************** - /// Alignment templates. - /// These require compiler specific intrinsics. -#if ETL_USING_CPP11 && !defined(ETL_COMPILER_ARM5) - template struct alignment_of : integral_constant { }; -#elif defined(ETL_COMPILER_MICROSOFT) - template struct alignment_of : integral_constant {}; -#elif defined(ETL_COMPILER_IAR) || defined(ETL_COMPILER_TI) - template struct alignment_of : integral_constant {}; -#else - template struct alignment_of : integral_constant {}; -#endif - - /// Specialisation of 'alignment_of' for 'void'. - ///\ingroup type_traits - template <> struct alignment_of : integral_constant {}; - template <> struct alignment_of : integral_constant {}; - -#if ETL_USING_CPP17 - template - inline constexpr size_t alignment_of_v = etl::alignment_of::value; -#endif - -#else // Condition = ETL_USING_STL && ETL_USING_CPP11 - -//***************************************************************************** -// Traits are derived from the STL -//***************************************************************************** - - //*************************************************************************** - /// integral_constant - ///\ingroup type_traits - template - struct integral_constant : std::integral_constant {}; - -/// integral_constant specialisations -///\ingroup type_traits -typedef integral_constant false_type; -typedef integral_constant true_type; - -#if ETL_USING_CPP17 - template - inline constexpr T integral_constant_v = std::integral_constant::value; -#endif - -#if ETL_USING_CPP17 - template - using bool_constant = std::bool_constant; -#else - template - struct bool_constant : std::integral_constant { }; -#endif - -#if ETL_USING_CPP17 - template - inline constexpr bool bool_constant_v = bool_constant::value; -#endif - - //*************************************************************************** - /// negation - ///\ingroup type_traits -#if ETL_USING_CPP17 - template - using negation = std::negation; -#else - template - struct negation : etl::bool_constant - { - }; -#endif - -#if ETL_USING_CPP17 - template - inline constexpr bool negation_v = std::negation_v; -#endif - - //*************************************************************************** - /// remove_reference - ///\ingroup type_traits - template struct remove_reference : std::remove_reference {}; - -#if ETL_USING_CPP11 - template - using remove_reference_t = typename std::remove_reference::type; -#endif - - //*************************************************************************** - /// remove_pointer - ///\ingroup type_traits - template struct remove_pointer : std::remove_pointer {}; - -#if ETL_USING_CPP11 - template - using remove_pointer_t = typename std::remove_pointer::type; -#endif - - //*************************************************************************** - /// add_pointer - ///\ingroup type_traits - template struct add_pointer : std::add_pointer {}; - -#if ETL_USING_CPP11 - template - using add_pointer_t = typename std::add_pointer::type; -#endif - - //*************************************************************************** - /// is_const - ///\ingroup type_traits - template struct is_const : std::is_const {}; - -#if ETL_USING_CPP17 - template - inline constexpr bool is_const_v = std::is_const_v; -#endif - - //*************************************************************************** - /// remove_const - ///\ingroup type_traits - template struct remove_const : std::remove_const {}; - -#if ETL_USING_CPP11 - template - using remove_const_t = typename std::remove_const::type; -#endif - - //*************************************************************************** - /// add_const - ///\ingroup type_traits - template struct add_const : std::add_const {}; - -#if ETL_USING_CPP11 - template - using add_const_t = typename std::add_const::type; -#endif - - //*************************************************************************** - /// is_volatile - ///\ingroup type_traits - template struct is_volatile : std::is_volatile {}; - -#if ETL_USING_CPP17 - template - inline constexpr bool is_volatile_v = std::is_volatile_v; -#endif - - //*************************************************************************** - /// remove_volatile - ///\ingroup type_traits - template struct remove_volatile : std::remove_volatile {}; - -#if ETL_USING_CPP11 - template - using remove_volatile_t = typename std::remove_volatile::type; -#endif - - //*************************************************************************** - /// add_volatile - ///\ingroup type_traits - template struct add_volatile : std::add_volatile {}; - -#if ETL_USING_CPP11 - template - using add_volatile_t = typename std::add_volatile::type; -#endif - - //*************************************************************************** - /// remove_cv - ///\ingroup type_traits - template struct remove_cv : std::remove_cv {}; - -#if ETL_USING_CPP11 - template - using remove_cv_t = typename std::remove_cv::type; -#endif - - //*************************************************************************** - /// add_cv - ///\ingroup type_traits - template struct add_cv : std::add_cv {}; - -#if ETL_USING_CPP11 - template - using add_cv_t = typename std::add_cv::type; -#endif - - //*************************************************************************** - /// remove_cvref - ///\ingroup type_traits - template struct remove_cvref - { - typedef typename std::remove_cv::type>::type type; - }; - -#if ETL_USING_CPP11 - template - using remove_cvref_t = typename etl::remove_cvref::type; -#endif - - //*************************************************************************** - /// is_integral - ///\ingroup type_traits - template struct is_integral : std::is_integral {}; - -#if ETL_USING_CPP17 - template - inline constexpr bool is_integral_v = std::is_integral_v; -#endif - - //*************************************************************************** - /// is_signed - ///\ingroup type_traits - template struct is_signed : std::is_signed {}; - -#if ETL_USING_CPP17 - template - inline constexpr bool is_signed_v = std::is_signed_v; -#endif - - //*************************************************************************** - /// is_unsigned - ///\ingroup type_traits - template struct is_unsigned : std::is_unsigned {}; - -#if ETL_USING_CPP17 - template - inline constexpr bool is_unsigned_v = std::is_unsigned_v; -#endif - - //*************************************************************************** - /// is_floating_point - ///\ingroup type_traits - template struct is_floating_point : std::is_floating_point {}; - -#if ETL_USING_CPP17 - template - inline constexpr bool is_floating_point_v = std::is_floating_point_v; -#endif - - //*************************************************************************** - /// is_same - ///\ingroup type_traits - template struct is_same : std::is_same {}; - -#if ETL_USING_CPP17 - template - inline constexpr bool is_same_v = std::is_same_v; -#endif - - //*************************************************************************** - /// is_void - ///\ingroup type_traits - template struct is_void : std::is_void {}; - -#if ETL_USING_CPP17 - template - inline constexpr bool is_void_v = std::is_void_v; -#endif - - //*************************************************************************** - /// is_arithmetic - ///\ingroup type_traits - template struct is_arithmetic : std::is_arithmetic {}; - -#if ETL_USING_CPP17 - template - inline constexpr bool is_arithmetic_v = std::is_arithmetic_v; -#endif - - //*************************************************************************** - /// is_fundamental - ///\ingroup type_traits - template struct is_fundamental : std::is_fundamental {}; - -#if ETL_USING_CPP17 - template - inline constexpr bool is_fundamental_v = std::is_fundamental_v; -#endif - - //*************************************************************************** - /// is_compound - ///\ingroup type_traits - template struct is_compound : std::is_compound {}; - -#if ETL_USING_CPP17 - template - inline constexpr bool is_compound_v = std::is_compound_v; -#endif - - //*************************************************************************** - /// is_array - ///\ingroup type_traits - template struct is_array : std::is_array {}; - -#if ETL_USING_CPP17 - template - inline constexpr bool is_array_v = std::is_array_v; -#endif - - //*************************************************************************** - /// is_pointer - ///\ingroup type_traits - template struct is_pointer : std::is_pointer {}; - -#if ETL_USING_CPP17 - template - inline constexpr bool is_pointer_v = std::is_pointer_v; -#endif - - //*************************************************************************** - /// is_reference - ///\ingroup type_traits - template struct is_reference : std::is_reference {}; - -#if ETL_USING_CPP17 - template - inline constexpr bool is_reference_v = std::is_reference_v; -#endif - - //*************************************************************************** - /// is_lvalue_reference - ///\ingroup type_traits - template struct is_lvalue_reference : std::is_lvalue_reference {}; - -#if ETL_USING_CPP17 - template - inline constexpr bool is_lvalue_reference_v = std::is_lvalue_reference_v; -#endif - - //*************************************************************************** - /// is_rvalue_reference - ///\ingroup type_traits -#if ETL_USING_CPP11 - template struct is_rvalue_reference : std::is_rvalue_reference {}; - -#if ETL_USING_CPP17 - template - inline constexpr bool is_rvalue_reference_v = std::is_rvalue_reference_v; -#endif -#endif - - //*************************************************************************** - /// is_pod - ///\ingroup type_traits - template - struct is_pod : std::integral_constant::value && std::is_trivially_default_constructible::value && std::is_trivially_copyable::value> {}; - -#if ETL_USING_CPP17 - template - inline constexpr bool is_pod_v = std::is_standard_layout_v && std::is_trivially_default_constructible_v && std::is_trivially_copyable_v; -#endif - -#if defined(ETL_COMPILER_GCC) - #if ETL_COMPILER_VERSION >= 5 - #define ETL_GCC_V5_TYPE_TRAITS_SUPPORTED - #endif -#endif - - //*************************************************************************** - /// conditional - ///\ingroup type_traits - template struct conditional { typedef T type; }; - template struct conditional { typedef F type; }; - -#if ETL_USING_CPP11 - template - using conditional_t = typename conditional::type; -#endif - - //*************************************************************************** - /// make_signed - ///\ingroup type_traits - template struct make_signed : std::make_signed {}; - -#if ETL_USING_CPP11 - template - using make_signed_t = typename std::make_signed::type; -#endif - - //*************************************************************************** - /// make_unsigned - ///\ingroup type_traits - template struct make_unsigned : std::make_unsigned {}; - -#if ETL_USING_CPP11 - template - using make_unsigned_t = typename std::make_unsigned::type; -#endif - - //*************************************************************************** - /// enable_if - ///\ingroup type_traits - template struct enable_if : std::enable_if {}; - -#if ETL_USING_CPP11 - template - using enable_if_t = typename std::enable_if::type; -#endif - - //*************************************************************************** - /// extent - ///\ingroup type_traits - template - struct extent : std::extent {}; - -#if ETL_USING_CPP17 - template - inline constexpr size_t extent_v = std::extent_v; -#endif - - //*************************************************************************** - /// remove_extent - ///\ingroup type_traits - template struct remove_extent : std::remove_extent { }; - -#if ETL_USING_CPP11 - template - using remove_extent_t = typename std::remove_extent::type; -#endif - - //*************************************************************************** - /// remove_all_extents - ///\ingroup type_traits - template struct remove_all_extents : std::remove_all_extents { }; - -#if ETL_USING_CPP11 - template - using remove_all_extents_t = typename std::remove_all_extents::type; -#endif - - //*************************************************************************** - /// rank - ///\ingroup type_traits - template struct rank : std::rank {}; - -#if ETL_USING_CPP17 - template - inline constexpr size_t rank_v = std::rank_v; -#endif - - //*************************************************************************** - /// decay - ///\ingroup type_traits - template struct decay : std::decay {}; - -#if ETL_USING_CPP11 - template - using decay_t = typename std::decay::type; -#endif - - //*************************************************************************** - /// is_base_of - ///\ingroup type_traits - template struct is_base_of : std::is_base_of {}; - -#if ETL_USING_CPP17 - template - inline constexpr bool is_base_of_v = std::is_base_of_v; -#endif - - //*************************************************************************** - /// is_class - template struct is_class : std::is_class{}; - -#if ETL_USING_CPP17 - template - inline constexpr bool is_class_v = is_class::value; -#endif - - //*************************************************************************** - /// add_lvalue_reference - template struct add_lvalue_reference : std::add_lvalue_reference {}; - -#if ETL_USING_CPP11 - template - using add_lvalue_reference_t = typename std::add_lvalue_reference::type; -#endif - - //*************************************************************************** - /// add_rvalue_reference -#if ETL_USING_CPP11 - template struct add_rvalue_reference : std::add_rvalue_reference {}; -#endif - -#if ETL_USING_CPP11 - template - using add_rvalue_reference_t = typename std::add_rvalue_reference::type; -#endif - - //*************************************************************************** - /// declval -#if ETL_USING_CPP11 - template - typename std::add_rvalue_reference::type declval() ETL_NOEXCEPT; -#endif - -#if ETL_USING_CPP11 - //*************************************************************************** - /// is_enum - ///\ingroup type_traits - template - struct is_enum : std::is_enum - { - }; - -#if ETL_USING_CPP17 - template - inline constexpr bool is_enum_v = etl::is_enum::value; -#endif - -#endif - - //*************************************************************************** - /// is_convertible - ///\ingroup type_traits -#if ETL_USING_CPP11 - template - struct is_convertible : std::is_convertible {}; - - // Is convertible and the conversion is noexcept. - template - struct is_nothrow_convertible - { - private: - // Helper: a function taking TTo to require the conversion. - static void sink(TTo) noexcept; - - // Selected only if 'sink(declval())' is a valid expression. - template - static auto test(int) -> etl::bool_constant()))>; - - // Fallback if conversion is not viable. - template - static etl::false_type test(...); - - public: - static ETL_CONSTANT bool value = decltype(test(0))::value; - }; -#else - namespace private_type_traits - { - typedef char yes; - struct no { char dummy[2]; }; - - template - struct is_convertible_impl - { - static yes test(TTo); - static no test(...); - static TFrom make(); - static const bool value = (sizeof(test(make())) == sizeof(yes)); - }; - - template - struct is_convertible_impl - { - static const bool value = false; - }; - - template - struct is_convertible_impl - { - static const bool value = false; - }; - - template <> - struct is_convertible_impl - { - static const bool value = true; - }; - } - - template - struct is_convertible : etl::bool_constant::value> {}; -#endif - -#if ETL_USING_CPP17 - template - inline constexpr bool is_convertible_v = std::is_convertible_v; - - template - inline constexpr bool is_nothrow_convertible_v = is_nothrow_convertible::value; -#endif - - //*************************************************************************** - /// Alignment templates. - ///\ingroup type_traits - template struct alignment_of : std::alignment_of {}; - template <> struct alignment_of : std::integral_constant {}; - template <> struct alignment_of : std::integral_constant {}; - -#if ETL_USING_CPP17 - template - inline constexpr size_t alignment_of_v = std::alignment_of_v; -#endif - -#endif // Condition = ETL_USING_STL && ETL_USING_CPP11 - - //*************************************************************************** - // ETL extended type traits. - //*************************************************************************** - -#if ETL_USING_CPP11 - //*************************************************************************** - /// conjunction -#if ETL_USING_CPP11 - template - struct conjunction : public etl::true_type - { - }; - - template - struct conjunction : public etl::conditional_t, T1> - { - }; - - template - struct conjunction : public T - { - }; -#endif - -#if ETL_USING_CPP17 - template - inline constexpr bool conjunction_v = conjunction::value; -#endif - - //*************************************************************************** - /// disjunction -#if ETL_USING_CPP11 - template - struct disjunction : public etl::false_type - { - }; - - template - struct disjunction : public etl::conditional_t> - { - }; - - template struct disjunction : public T1 - { - }; -#endif - -#if ETL_USING_CPP17 - template - inline constexpr bool disjunction_v = etl::disjunction::value; -#endif - -#endif - - //*************************************************************************** - /// exclusive_disjunction -#if ETL_USING_CPP11 - template - struct exclusive_disjunction; - - template - struct exclusive_disjunction : public etl::bool_constant - { - }; - - // Recursive case: XOR the first two values and recurse - template - struct exclusive_disjunction : public etl::exclusive_disjunction::value && !etl::conjunction::value>, TRest...> - { - }; -#endif - -#if ETL_USING_CPP17 - template - inline constexpr bool exclusive_disjunction_v = etl::exclusive_disjunction::value; -#endif - - //*************************************************************************** - /// conditional_integral_constant - // /\ingroup type_traits - template - struct conditional_integral_constant; - - template - struct conditional_integral_constant - { - ETL_STATIC_ASSERT(etl::is_integral::value, "Not an integral type"); - static const T value = TRUE_VALUE; - }; - - template - struct conditional_integral_constant - { - ETL_STATIC_ASSERT(etl::is_integral::value, "Not an integral type"); - static const T value = FALSE_VALUE; - }; - -#if ETL_USING_CPP11 - //*************************************************************************** - /// Template to determine if a type is a base of all types in a specified list. - ///\ingroup types - template - struct is_one_of : etl::disjunction...> - { - }; -#else - /*[[[cog - import cog - cog.outl("//***************************************************************************") - cog.outl("/// Template to determine if a type is one of a specified list.") - cog.outl("///\\ingroup types") - cog.outl("template " % IsOneOf) - cog.outl("struct is_one_of") - cog.outl("{") - cog.outl(" static const bool value =") - for n in range(1, int(IsOneOf)): - cog.outl(" etl::is_same::value ||" % n) - cog.outl(" etl::is_same::value;" % IsOneOf) - cog.outl("};") - ]]]*/ - /*[[[end]]]*/ -#endif - -#if ETL_USING_CPP17 - template - inline constexpr bool is_one_of_v = etl::is_one_of::value; -#endif - -#if ETL_USING_CPP11 - namespace private_type_traits - { - //*************************************************************************** - // Helper to count occurrences of a type in a list of types - template - struct count_type; - - // Base case: zero occurrences - template - struct count_type : etl::integral_constant - { - }; - - // Recursive case: increment count if head is the same as T, otherwise continue with tail - template - struct count_type : etl::integral_constant::value ? 1 : 0) + count_type::value> - { - }; - } - - template - struct has_duplicates_of - : etl::integral_constant::value > 1)> - { - }; -#endif - -#if ETL_USING_CPP17 - template - inline constexpr bool has_duplicates_of_v = etl::has_duplicates_of::value; -#endif - -#if ETL_USING_CPP11 - //*************************************************************************** - /// Template to determine if a type is a base of all types in a specified list. - ///\ingroup types - template - struct is_base_of_all : etl::conjunction...> - { - }; -#endif - -#if ETL_USING_CPP17 - template - inline constexpr bool is_base_of_all_v = etl::is_base_of_all::value; -#endif - -#if ETL_USING_CPP11 - //*************************************************************************** - /// Template to determine if a type is a base of any type in a specified list. - ///\ingroup types - template - struct is_base_of_any : etl::disjunction...> - { - }; - -#endif - -#if ETL_USING_CPP17 - template - inline constexpr bool is_base_of_any_v = etl::is_base_of_any::value; -#endif - - //*************************************************************************** - /// Get the Nth base of a recursively inherited type. - /// Requires that the class has defined 'base_type'. - //*************************************************************************** - // Recursive definition of the type. - template - struct nth_base - { - typedef typename nth_base::type type; - }; - - template - struct nth_base<0, TType> - { - typedef TType type; - }; - -#if ETL_USING_CPP11 - template - using nth_base_t = typename nth_base::type; -#endif - - //*************************************************************************** - /// A set of templates to allow related types to be derived. - ///\ingroup types - - // Default. - template - struct types - { - private: - - typedef typename etl::remove_reference::type>::type type_t; - - public: - - typedef type_t type; - typedef type_t& reference; - typedef const type_t& const_reference; - typedef type_t* pointer; - typedef const type_t* const_pointer; - typedef const type_t* const const_pointer_const; - -#if ETL_USING_CPP11 - typedef type_t&& rvalue_reference; -#endif - }; - - // Pointers. - template - struct types - { - private: - - typedef typename etl::remove_reference::type>::type type_t; - - public: - - typedef type_t type; - typedef type_t& reference; - typedef const type_t& const_reference; - typedef type_t* pointer; - typedef const type_t* const_pointer; - typedef const type_t* const const_pointer_const; - -#if ETL_USING_CPP11 - typedef type_t&& rvalue_reference; -#endif - }; - - // Pointers. - template - struct types - { - private: - - typedef typename etl::remove_reference::type>::type type_t; - - public: - - typedef type_t type; - typedef type_t& reference; - typedef const type_t& const_reference; - typedef type_t* pointer; - typedef const type_t* const_pointer; - typedef const type_t* const const_pointer_const; - -#if ETL_USING_CPP11 - typedef type_t&& rvalue_reference; -#endif - }; - - // References. - template - struct types - { - private: - - typedef typename etl::remove_reference::type>::type type_t; - - public: - - typedef type_t type; - typedef type_t& reference; - typedef const type_t& const_reference; - typedef type_t* pointer; - typedef const type_t* const_pointer; - typedef const type_t* const const_pointer_const; - -#if ETL_USING_CPP11 - typedef type_t&& rvalue_reference; -#endif - }; - -#if ETL_USING_CPP11 - // rvalue References. - template - struct types - { - private: - - typedef typename etl::remove_reference::type>::type type_t; - - public: - - typedef type_t type; - typedef type_t& reference; - typedef const type_t& const_reference; - typedef type_t* pointer; - typedef const type_t* const_pointer; - typedef const type_t* const const_pointer_const; - -#if ETL_USING_CPP11 - typedef type_t&& rvalue_reference; -#endif - }; -#endif - -#if ETL_USING_CPP11 - template - using types_t = typename types::type; - - template - using types_r = typename types::reference; - - template - using types_cr = typename types::const_reference; - - template - using types_rr = typename types::rvalue_reference; - - template - using types_p = typename types::pointer; - - template - using types_cp = typename types::const_pointer; - - template - using types_cpc = typename types::const_pointer_const; -#endif - - //*************************************************************************** - /// size_of - ///\ingroup types - template struct size_of : etl::integral_constant {}; - template <> struct size_of : etl::integral_constant {}; - -#if ETL_USING_CPP17 - template - inline constexpr size_t size_of_v = etl::size_of::value; -#endif - -#if ETL_USING_CPP11 - //*************************************************************************** - /// are_all_same - template - struct are_all_same : etl::conjunction...> - { - }; -#endif - -#if ETL_USING_CPP17 - template - inline constexpr bool are_all_same_v = are_all_same::value; -#endif - - //*************************************************************************** -#if ETL_USING_STL && ETL_USING_CPP11 && !defined(ETL_USE_TYPE_TRAITS_BUILTINS) && !defined(ETL_USER_DEFINED_TYPE_TRAITS) && ((!defined(ARDUINO) && ETL_NOT_USING_STLPORT) || defined(ETL_GCC_V5_TYPE_TRAITS_SUPPORTED)) - - //********************************************* - // Use the STL's definitions. - //********************************************* - - //********************************************* - // is_assignable - template - using is_assignable = std::is_assignable; - - //********************************************* - // is_constructible - template - using is_constructible = std::is_constructible; - - //********************************************* - // is_copy_constructible - template - using is_copy_constructible = std::is_copy_constructible; - - //********************************************* - // is_move_constructible - template - using is_move_constructible = std::is_move_constructible; - - //********************************************* - // is_copy_assignable - template - using is_copy_assignable = std::is_copy_assignable; - - //********************************************* - // is_move_assignable - template - using is_move_assignable = std::is_move_assignable; - - //********************************************* - // is_trivially_constructible -#if ETL_CPP11_TYPE_TRAITS_IS_TRIVIAL_SUPPORTED - template - using is_trivially_constructible = std::is_trivially_constructible; -#else - template - using is_trivially_constructible = etl::bool_constant::value || etl::is_pointer::value>; -#endif - - //********************************************* - // is_trivially_copy_constructible -#if ETL_CPP11_TYPE_TRAITS_IS_TRIVIAL_SUPPORTED - template - using is_trivially_copy_constructible = std::is_trivially_copy_constructible; -#else - template - using is_trivially_copy_constructible = etl::bool_constant::value || etl::is_pointer::value>; -#endif - - //********************************************* - // is_trivially_destructible -#if ETL_CPP11_TYPE_TRAITS_IS_TRIVIAL_SUPPORTED - template - using is_trivially_destructible = std::is_trivially_destructible; -#else - template - using is_trivially_destructible = etl::bool_constant::value || etl::is_pointer::value>; -#endif - - //********************************************* - // is_trivially_copy_assignable -#if ETL_CPP11_TYPE_TRAITS_IS_TRIVIAL_SUPPORTED - template - using is_trivially_copy_assignable = std::is_trivially_copy_assignable; -#else - template - using is_trivially_copy_assignable = etl::bool_constant::value || etl::is_pointer::value>; -#endif - - //********************************************* - // is_trivially_copyable -#if ETL_CPP11_TYPE_TRAITS_IS_TRIVIAL_SUPPORTED - template - using is_trivially_copyable = std::is_trivially_copyable; -#elif ETL_USING_BUILTIN_IS_TRIVIALLY_COPYABLE - template - using is_trivially_copyable = etl::bool_constant<__is_trivially_copyable(T)>; -#else - template - using is_trivially_copyable = etl::bool_constant::value || etl::is_pointer::value>; -#endif - -#elif defined(ETL_USE_TYPE_TRAITS_BUILTINS) && !defined(ETL_USER_DEFINED_TYPE_TRAITS) - - //********************************************* - // Use the compiler's builtins. - //********************************************* - - //********************************************* - // is_assignable - template - struct is_assignable - { - static ETL_CONSTANT bool value = __is_assignable(T1, T2); - }; - -#if ETL_USING_CPP11 - //********************************************* - // is_constructible - template - struct is_constructible - { - static ETL_CONSTANT bool value = __is_constructible(T, TArgs...); - }; -#else - //********************************************* - // is_constructible - template - struct is_constructible - { - static ETL_CONSTANT bool value = __is_constructible(T, TArgs); - }; - - //********************************************* - // is_constructible - template - struct is_constructible - { - static ETL_CONSTANT bool value = __is_constructible(T); - }; -#endif - - //********************************************* - // is_copy_constructible - template - struct is_copy_constructible : public etl::is_constructible::type> - { - }; - - //********************************************* - // is_move_constructible - template - struct is_move_constructible : public etl::is_constructible - { - }; - - //********************************************* - // is_copy_assignable - template - struct is_copy_assignable : public etl::is_assignable::type, - typename etl::add_lvalue_reference::type> - { - }; - - //********************************************* - // is_move_assignable -#if ETL_USING_CPP11 - template - struct is_move_assignable : public etl::is_assignable::type, - typename etl::add_rvalue_reference::type> - { - }; -#else - template - struct is_move_assignable : public etl::is_assignable::type, T> - { - }; -#endif - -#if ETL_USING_CPP11 - //********************************************* - // is_trivially_constructible - template - struct is_trivially_constructible - { -#if defined(ETL_COMPILER_GCC) - static ETL_CONSTANT bool value = __has_trivial_constructor(T); -#else - static ETL_CONSTANT bool value = __is_trivially_constructible(T, TArgs...); -#endif - }; -#else - //********************************************* - // is_trivially_constructible - template - struct is_trivially_constructible - { -#if defined(ETL_COMPILER_GCC) - static ETL_CONSTANT bool value = __has_trivial_constructor(T); -#else - static ETL_CONSTANT bool value = __is_trivially_constructible(T, TArgs); -#endif - }; - - //********************************************* - // is_trivially_constructible - template - struct is_trivially_constructible - { -#if defined(ETL_COMPILER_GCC) - static ETL_CONSTANT bool value = __has_trivial_constructor(T); -#else - static ETL_CONSTANT bool value = __is_trivially_constructible(T); -#endif - }; -#endif - - //********************************************* - // is_trivially_copy_constructible - template - struct is_trivially_copy_constructible : public is_trivially_constructible::type> - { - }; - - //********************************************* - // is_trivially_destructible - template - struct is_trivially_destructible - { -#if defined(ETL_COMPILER_GCC) - static ETL_CONSTANT bool value = __has_trivial_destructor(T); -#else - static ETL_CONSTANT bool value = __is_trivially_destructible(T); -#endif - }; - - //********************************************* - // is_trivially_copy_assignable - template - struct is_trivially_copy_assignable - { -#if defined(ETL_COMPILER_GCC) - static ETL_CONSTANT bool value = __has_trivial_copy(T); -#else - static ETL_CONSTANT bool value = __is_trivially_copyable(T); -#endif - }; - - //********************************************* - // is_trivially_copyable - template - struct is_trivially_copyable - { - static ETL_CONSTANT bool value = __is_trivially_copyable(T); - }; - -#elif defined(ETL_USER_DEFINED_TYPE_TRAITS) && !defined(ETL_USE_TYPE_TRAITS_BUILTINS) - - //********************************************* - // Force the user to provide specialisations for - // anything other than arithmetics and pointers. - //********************************************* - - //********************************************* - // is_assignable - template ::value || etl::is_pointer::value) && (etl::is_arithmetic::value || etl::is_pointer::value)> - struct is_assignable; - - template - struct is_assignable : public etl::true_type - { - }; - - template - struct is_assignable; - -#if ETL_USING_CPP11 - //********************************************* - // is_constructible - template - struct is_constructible_helper; - - template - struct is_constructible_helper : public etl::true_type - { - }; - - template - struct is_constructible_helper; - - template - struct is_constructible : public is_constructible_helper::value || etl::is_pointer::value, TArgs...> - { - }; -#endif - - //********************************************* - // is_copy_constructible - template ::value || etl::is_pointer::value> - struct is_copy_constructible; - - template - struct is_copy_constructible : public etl::true_type - { - }; - - template - struct is_copy_constructible; - - //********************************************* - // is_move_constructible - template ::value || etl::is_pointer::value> - struct is_move_constructible; - - template - struct is_move_constructible : public etl::true_type - { - }; - - template - struct is_move_constructible; - - //********************************************* - // is_copy_assignable - template ::value || etl::is_pointer::value> - struct is_copy_assignable; - - template - struct is_copy_assignable : public etl::true_type - { - }; - - template - struct is_copy_assignable; - - //********************************************* - // is_move_assignable - template ::value || etl::is_pointer::value> - struct is_move_assignable; - - template - struct is_move_assignable : public etl::true_type - { - }; - - template - struct is_move_assignable; - - //********************************************* - // is_trivially_constructible - template ::value || etl::is_pointer::value> - struct is_trivially_constructible; - - template - struct is_trivially_constructible : public etl::true_type - { - }; - - template - struct is_trivially_constructible; - - //********************************************* - // is_trivially_copy_constructible - template ::value || etl::is_pointer::value> - struct is_trivially_copy_constructible; - - template - struct is_trivially_copy_constructible : public etl::true_type - { - }; - - template - struct is_trivially_copy_constructible; - - //********************************************* - // is_trivially_destructible - template ::value || etl::is_pointer::value> - struct is_trivially_destructible; - - template - struct is_trivially_destructible : public etl::true_type - { - }; - - template - struct is_trivially_destructible; - - //********************************************* - // is_trivially_copy_assignable - template ::value || etl::is_pointer::value> - struct is_trivially_copy_assignable; - - template - struct is_trivially_copy_assignable : public etl::true_type - { - }; - - template - struct is_trivially_copy_assignable; - - //********************************************* - // is_trivially_copyable - template ::value || etl::is_pointer::value> - struct is_trivially_copyable; - - template - struct is_trivially_copyable : public etl::true_type - { - }; - - template - struct is_trivially_copyable; - -#else - - //********************************************* - // Assume that anything other than arithmetics - // and pointers return false for the traits. - //********************************************* - - //********************************************* - // is_assignable - template -#if ETL_USING_BUILTIN_IS_ASSIGNABLE - struct is_assignable : public etl::bool_constant<__is_assignable(T1, T2)> -#else - struct is_assignable : public etl::bool_constant<(etl::is_arithmetic::value || etl::is_pointer::value) && (etl::is_arithmetic::value || etl::is_pointer::value)> -#endif - { - }; - -#if ETL_USING_CPP11 - //*************************************************************************** - /// is_constructible - namespace private_type_traits - { - template - struct is_constructible_ : etl::false_type {}; - - template - struct is_constructible_()...))>, T, TArgs...> : etl::true_type {}; - } - - //********************************************* - // is_constructible - template - using is_constructible = private_type_traits::is_constructible_, T, TArgs...>; - - //********************************************* - // is_copy_constructible - template struct is_copy_constructible : public is_constructible::type>::type>{}; - template <> struct is_copy_constructible : public false_type{}; - template <> struct is_copy_constructible : public false_type{}; - template <> struct is_copy_constructible : public false_type{}; - template <> struct is_copy_constructible : public false_type{}; - - //********************************************* - // is_move_constructible - template struct is_move_constructible: public is_constructible::type>{}; - template <> struct is_move_constructible : public false_type{}; - template <> struct is_move_constructible : public false_type{}; - template <> struct is_move_constructible : public false_type{}; - template <> struct is_move_constructible : public false_type{}; - -#else - - //********************************************* - // is_copy_constructible - template - struct is_copy_constructible : public etl::bool_constant::value || etl::is_pointer::value> - { - }; - - //********************************************* - // is_move_constructible - template - struct is_move_constructible : public etl::bool_constant::value || etl::is_pointer::value> - { - }; -#endif - - //********************************************* - // is_copy_assignable - template - struct is_copy_assignable : public etl::is_assignable::type, - typename etl::add_lvalue_reference::type> - { - }; - -#if ETL_USING_CPP11 - //********************************************* - // is_move_assignable - template - struct is_move_assignable : public etl::is_assignable::type, - typename etl::add_rvalue_reference::type> - { - }; -#else - //********************************************* - // is_move_assignable - template - struct is_move_assignable : public etl::bool_constant::value || etl::is_pointer::value> - { - }; -#endif - - //********************************************* - // is_trivially_constructible - template - struct is_trivially_constructible : public etl::bool_constant::value || etl::is_pointer::value> - { - }; - - //********************************************* - // is_trivially_copy_constructible - template - struct is_trivially_copy_constructible : public etl::bool_constant::value || etl::is_pointer::value> - { - }; - - //********************************************* - // is_trivially_destructible - template - struct is_trivially_destructible : public etl::bool_constant::value || etl::is_pointer::value> - { - }; - - //********************************************* - // is_trivially_copy_assignable - template - struct is_trivially_copy_assignable : public etl::bool_constant::value || etl::is_pointer::value> - { - }; - - //********************************************* - // is_trivially_copyable - template -#if ETL_USING_BUILTIN_IS_TRIVIALLY_COPYABLE - struct is_trivially_copyable : public etl::bool_constant<__is_trivially_copyable(T)> -#else - struct is_trivially_copyable : public etl::bool_constant::value || etl::is_pointer::value> -#endif - { - }; - -#endif - - template - struct is_lvalue_assignable : public etl::is_assignable::type, - typename etl::add_lvalue_reference::type>::type> - { - }; - -#if ETL_USING_CPP11 - //********************************************* - // is_default_constructible - template - struct is_default_constructible : etl::false_type { }; - - template - struct is_default_constructible> : etl::true_type { }; -#else - template - struct is_default_constructible : public etl::bool_constant::value || etl::is_pointer::value> - { - }; -#endif - -#if ETL_USING_CPP17 - - template - inline constexpr bool is_assignable_v = etl::is_assignable::value; - - template - inline constexpr bool is_lvalue_assignable_v = etl::is_lvalue_assignable::value; - - template - inline constexpr bool is_constructible_v = etl::is_constructible::value; - - template - inline constexpr bool is_default_constructible_v = etl::is_default_constructible::value; - - template - inline constexpr bool is_copy_constructible_v = etl::is_copy_constructible::value; - - template - inline constexpr bool is_move_constructible_v = etl::is_move_constructible::value; - - template - inline constexpr bool is_copy_assignable_v = etl::is_copy_assignable::value; - - template - inline constexpr bool is_move_assignable_v = etl::is_move_assignable::value; - - template - inline constexpr bool is_trivially_constructible_v = etl::is_trivially_constructible::value; - - template - inline constexpr bool is_trivially_copy_constructible_v = etl::is_trivially_copy_constructible::value; - - template - inline constexpr bool is_trivially_destructible_v = etl::is_trivially_destructible::value; - - template - inline constexpr bool is_trivially_copy_assignable_v = etl::is_trivially_copy_assignable::value; - - template - inline constexpr bool is_trivially_copyable_v = etl::is_trivially_copyable::value; - -#endif - -#if ETL_USING_CPP11 - //********************************************* - // common_type - // Based on the sample implementation detailed on - // https://en.cppreference.com/w/cpp/types/common_type - //********************************************* - //*********************************** - // Primary template - template - struct common_type - { - }; - - //*********************************** - // One type - template - struct common_type : common_type - { - }; - - namespace private_common_type - { - template - using conditional_result_t = decltype(false ? declval() : declval()); - - template - struct decay_conditional_result - { - }; - - template - struct decay_conditional_result>> - : etl::decay> - { - }; - - template - struct common_type_2_impl - : decay_conditional_result - { - }; - - template - struct common_type_2_impl>> - : decay_conditional_result - { - }; - } - - //*********************************** - // Two types - template - struct common_type - : etl::conditional::type>::value&& etl::is_same::type>::value, - private_common_type::common_type_2_impl, - common_type::type, - typename etl::decay::type>>::type - { - }; - - //*********************************** - // Three or more types - namespace private_common_type - { - template - struct common_type_multi_impl - { - }; - - template - struct common_type_multi_impl::type>, T1, T2, TRest...> - : common_type::type, TRest...> - { - }; - } - - template - struct common_type - : private_common_type::common_type_multi_impl - { - }; - - template - using common_type_t = typename common_type::type; -#endif - - //*************************************************************************** - /// Defines one of five unsigned types that has the same size as T. - //*************************************************************************** - template - struct unsigned_type - { - typedef typename etl::conditional::type>::type>::type>::type type; - }; - -#if ETL_USING_CPP11 - template - using unsigned_type_t = typename unsigned_type::type; -#endif - - //*************************************************************************** - /// Defines one of five signed types that has the same size as T. - //*************************************************************************** - template - struct signed_type - { - typedef typename etl::conditional::type>::type>::type>::type type; - }; - -#if ETL_USING_CPP11 - template - using signed_type_t = typename signed_type::type; -#endif - - //********************************************* - // type_identity - - template - struct type_identity { typedef T type; }; - -#if ETL_USING_CPP11 - template - using type_identity_t = typename type_identity::type; -#endif - - //********************************************* - // underlying_type -#if ETL_USING_BUILTIN_UNDERLYING_TYPE - // Primary template for etl::underlying_type - template ::value> - struct underlying_type; - - // Specialization for non-enum types (invalid case) - template - struct underlying_type - { - // Static assertion to ensure this is only used with enums - ETL_STATIC_ASSERT(etl::is_enum::value, "etl::underlying_type can only be used with enumeration types."); - }; - - template - struct underlying_type - { - typedef __underlying_type(T) type; - }; -#else - /// Primary template for etl::underlying_type - /// Users must specialise this template for their enumerations. - template - struct underlying_type - { - typedef int type; - }; -#endif - -#if ETL_USING_CPP11 - template - using underlying_type_t = typename underlying_type::type; -#endif - -#if ETL_USING_CPP11 - //********************************************* - // has_duplicates - template - struct has_duplicates; - - template - struct has_duplicates : etl::conditional_t::value, - etl::true_type, - has_duplicates> {}; - - template - struct has_duplicates : etl::false_type {}; - - template <> - struct has_duplicates<> : etl::false_type {}; -#endif - -#if ETL_USING_CPP17 - template - inline constexpr bool has_duplicates_v = etl::has_duplicates::value; -#endif - -#if ETL_USING_CPP11 - //********************************************* - // count_of - template - struct count_of; - - template - struct count_of : etl::integral_constant::value + - count_of::value> {}; - - template - struct count_of : etl::integral_constant {}; -#endif - -#if ETL_USING_CPP17 - template - inline constexpr size_t count_of_v = etl::count_of::value; -#endif - -#if ETL_USING_CPP11 - //********************************************* - /// is_specialization - template class Template> - struct is_specialization : etl::false_type {}; - - template