diff --git a/src/alignment.h b/src/alignment.h index 18f20aea..578ae40c 100644 --- a/src/alignment.h +++ b/src/alignment.h @@ -113,7 +113,7 @@ namespace etl template operator T& () { - STATIC_ASSERT(ALIGNMENT % etl::alignment_of::value == 0, "Incompatible alignment"); + STATIC_ASSERT((etl::is_same:: value || ((ALIGNMENT % etl::alignment_of::value) == 0)), "Incompatible alignment"); return reinterpret_cast(*data); } @@ -121,7 +121,7 @@ namespace etl template operator const T& () const { - STATIC_ASSERT(ALIGNMENT % etl::alignment_of::value == 0, "Incompatible alignment"); + STATIC_ASSERT((etl::is_same:: value || ((ALIGNMENT % etl::alignment_of::value) == 0)), "Incompatible alignment"); return reinterpret_cast(*data); } @@ -129,7 +129,7 @@ namespace etl template operator T* () { - STATIC_ASSERT(ALIGNMENT % etl::alignment_of::value == 0, "Incompatible alignment"); + STATIC_ASSERT((etl::is_same:: value || ((ALIGNMENT % etl::alignment_of::value) == 0)), "Incompatible alignment"); return reinterpret_cast(data); } @@ -137,7 +137,7 @@ namespace etl template operator const T* () const { - STATIC_ASSERT(ALIGNMENT % etl::alignment_of::value == 0, "Incompatible alignment"); + STATIC_ASSERT((etl::is_same:: value || ((ALIGNMENT % etl::alignment_of::value) == 0)), "Incompatible alignment"); return reinterpret_cast(data); } @@ -145,7 +145,7 @@ namespace etl template T& get_reference() { - STATIC_ASSERT(ALIGNMENT % etl::alignment_of::value == 0, "Incompatible alignment"); + STATIC_ASSERT((etl::is_same:: value || ((ALIGNMENT % etl::alignment_of::value) == 0)), "Incompatible alignment"); return reinterpret_cast(*data); } @@ -153,7 +153,7 @@ namespace etl template const T& get_reference() const { - STATIC_ASSERT(ALIGNMENT % etl::alignment_of::value == 0, "Incompatible alignment"); + STATIC_ASSERT((etl::is_same:: value || ((ALIGNMENT % etl::alignment_of::value) == 0)), "Incompatible alignment"); return reinterpret_cast(*data); } @@ -161,7 +161,7 @@ namespace etl template T* get_address() { - STATIC_ASSERT(ALIGNMENT % etl::alignment_of::value == 0, "Incompatible alignment"); + STATIC_ASSERT((etl::is_same:: value || ((ALIGNMENT % etl::alignment_of::value) == 0)), "Incompatible alignment"); return reinterpret_cast(data); } @@ -169,7 +169,7 @@ namespace etl template const T* get_address() const { - STATIC_ASSERT(ALIGNMENT % etl::alignment_of::value == 0, "Incompatible alignment"); + STATIC_ASSERT((etl::is_same:: value || ((ALIGNMENT % etl::alignment_of::value) == 0)), "Incompatible alignment"); return reinterpret_cast(data); } diff --git a/src/fsm.h b/src/fsm.h index 7bd6b343..54b84fff 100644 --- a/src/fsm.h +++ b/src/fsm.h @@ -26,6 +26,24 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ +//*************************************************************************** +// 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. +// +// python -m cogapp -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... +// python -m cogapp -d -e -ofsm.h -DHandlers=16 fsm_generator.h +// +// See generate.bat +//*************************************************************************** + #ifndef __ETL_FSM__ #define __ETL_FSM__ @@ -183,9 +201,6 @@ namespace etl } }; - //*************************************************************************** - // The code below has been auto generated. Do not manually edit. - //*************************************************************************** template ::max - 0, const fsm_internal_id_t ID2 = etl::integral_limits::max - 1, const fsm_internal_id_t ID3 = etl::integral_limits::max - 2, @@ -202,10 +217,7 @@ namespace etl const fsm_internal_id_t ID14 = etl::integral_limits::max - 13, const fsm_internal_id_t ID15 = etl::integral_limits::max - 14, const fsm_internal_id_t ID16 = etl::integral_limits::max - 15> - //*************************************************************************** - // The code above has been auto generated. Do not manually edit. - //*************************************************************************** - class fsm : public etl::imessage_router , protected etl::fsm_helper + class fsm : public etl::imessage_router, protected etl::fsm_helper { public: @@ -285,22 +297,13 @@ namespace etl } } - //******************************************* - /// Does this FSM accept the message? - //******************************************* - bool accepts(const etl::imessage& msg) const - { - return accepts(msg.get_message_id()); - } + using imessage_router::accepts; //******************************************* /// Does this FSM accept the message id? //******************************************* bool accepts(etl::message_id_t id) const { - //*************************************************************************** - // The code below has been auto generated. Do not manually edit. - //*************************************************************************** switch (fsm_internal_id_t(id)) { case ID1: case ID2: case ID3: case ID4: case ID5: case ID6: case ID7: case ID8: @@ -309,9 +312,6 @@ namespace etl default: return false; break; } - //*************************************************************************** - // The code above has been auto generated. Do not manually edit. - //*************************************************************************** } //******************************************* @@ -364,23 +364,6 @@ namespace etl etl::fsm_state_id_t number_of_states; ///< The number of states. }; - //*************************************************************************** - // To generate to header file, run this at the command line. - // Note: You will need Python and COG installed. - // - // python -m cogapp -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... - // python -m cogapp -d -e -ofsm.h -DHandlers=16 fsm_generator.h - // - // See CreateFSM.bat - //*************************************************************************** - - //*************************************************************************** - // The code below has been auto generated. Do not manually edit. - //*************************************************************************** //*************************************************************************** // The definition for all 16 message types. @@ -409,7 +392,7 @@ namespace etl etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message) { etl::fsm_state_id_t new_state_id; - etl::message_id_t event_id = message.get_message_id(); + etl::message_id_t event_id = message.message_id; switch (event_id) { @@ -463,7 +446,7 @@ namespace etl etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message) { etl::fsm_state_id_t new_state_id; - etl::message_id_t event_id = message.get_message_id(); + etl::message_id_t event_id = message.message_id; switch (event_id) { @@ -516,7 +499,7 @@ namespace etl etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message) { etl::fsm_state_id_t new_state_id; - etl::message_id_t event_id = message.get_message_id(); + etl::message_id_t event_id = message.message_id; switch (event_id) { @@ -568,7 +551,7 @@ namespace etl etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message) { etl::fsm_state_id_t new_state_id; - etl::message_id_t event_id = message.get_message_id(); + etl::message_id_t event_id = message.message_id; switch (event_id) { @@ -618,7 +601,7 @@ namespace etl etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message) { etl::fsm_state_id_t new_state_id; - etl::message_id_t event_id = message.get_message_id(); + etl::message_id_t event_id = message.message_id; switch (event_id) { @@ -667,7 +650,7 @@ namespace etl etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message) { etl::fsm_state_id_t new_state_id; - etl::message_id_t event_id = message.get_message_id(); + etl::message_id_t event_id = message.message_id; switch (event_id) { @@ -715,7 +698,7 @@ namespace etl etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message) { etl::fsm_state_id_t new_state_id; - etl::message_id_t event_id = message.get_message_id(); + etl::message_id_t event_id = message.message_id; switch (event_id) { @@ -762,7 +745,7 @@ namespace etl etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message) { etl::fsm_state_id_t new_state_id; - etl::message_id_t event_id = message.get_message_id(); + etl::message_id_t event_id = message.message_id; switch (event_id) { @@ -807,7 +790,7 @@ namespace etl etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message) { etl::fsm_state_id_t new_state_id; - etl::message_id_t event_id = message.get_message_id(); + etl::message_id_t event_id = message.message_id; switch (event_id) { @@ -851,7 +834,7 @@ namespace etl etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message) { etl::fsm_state_id_t new_state_id; - etl::message_id_t event_id = message.get_message_id(); + etl::message_id_t event_id = message.message_id; switch (event_id) { @@ -894,7 +877,7 @@ namespace etl etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message) { etl::fsm_state_id_t new_state_id; - etl::message_id_t event_id = message.get_message_id(); + etl::message_id_t event_id = message.message_id; switch (event_id) { @@ -936,7 +919,7 @@ namespace etl etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message) { etl::fsm_state_id_t new_state_id; - etl::message_id_t event_id = message.get_message_id(); + etl::message_id_t event_id = message.message_id; switch (event_id) { @@ -976,7 +959,7 @@ namespace etl etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message) { etl::fsm_state_id_t new_state_id; - etl::message_id_t event_id = message.get_message_id(); + etl::message_id_t event_id = message.message_id; switch (event_id) { @@ -1015,7 +998,7 @@ namespace etl etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message) { etl::fsm_state_id_t new_state_id; - etl::message_id_t event_id = message.get_message_id(); + etl::message_id_t event_id = message.message_id; switch (event_id) { @@ -1053,7 +1036,7 @@ namespace etl etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message) { etl::fsm_state_id_t new_state_id; - etl::message_id_t event_id = message.get_message_id(); + etl::message_id_t event_id = message.message_id; switch (event_id) { @@ -1090,7 +1073,7 @@ namespace etl etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message) { etl::fsm_state_id_t new_state_id; - etl::message_id_t event_id = message.get_message_id(); + etl::message_id_t event_id = message.message_id; switch (event_id) { diff --git a/src/fsm_generator.h b/src/fsm_generator.h index a5879b0a..bec171a6 100644 --- a/src/fsm_generator.h +++ b/src/fsm_generator.h @@ -26,6 +26,40 @@ 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. +// +// python -m cogapp -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... +// python -m cogapp -d -e -ofsm.h -DHandlers=16 fsm_generator.h +// +// See generate.bat +//*************************************************************************** + #ifndef __ETL_FSM__ #define __ETL_FSM__ @@ -185,21 +219,15 @@ namespace etl /*[[[cog import cog - cog.outl("//***************************************************************************") - cog.outl("// The code below has been auto generated. Do not manually edit.") - cog.outl("//***************************************************************************") cog.out("template <") for n in range(1, int(Handlers)): cog.outl("const fsm_internal_id_t ID%d = etl::integral_limits::max - %d, " % (n, n - 1)) cog.out(" ") cog.out("const fsm_internal_id_t ID%d = etl::integral_limits::max - %d" % (int(Handlers), int(Handlers) - 1)) cog.outl(">") - cog.outl("//***************************************************************************") - cog.outl("// The code above has been auto generated. Do not manually edit.") - cog.outl("//***************************************************************************") ]]]*/ /*[[[end]]]*/ - class fsm : public etl::imessage_router , protected etl::fsm_helper + class fsm : public etl::imessage_router, protected etl::fsm_helper { public: @@ -279,13 +307,7 @@ namespace etl } } - //******************************************* - /// Does this FSM accept the message? - //******************************************* - bool accepts(const etl::imessage& msg) const - { - return accepts(msg.get_message_id()); - } + using imessage_router::accepts; //******************************************* /// Does this FSM accept the message id? @@ -294,9 +316,6 @@ namespace etl { /*[[[cog import cog - cog.outl("//***************************************************************************") - cog.outl("// The code below has been auto generated. Do not manually edit.") - cog.outl("//***************************************************************************") cog.outl("switch (fsm_internal_id_t(id))") cog.outl("{") cog.out(" ") @@ -309,9 +328,6 @@ namespace etl cog.outl(" default:") cog.outl(" return false; break;") cog.outl("}") - cog.outl("//***************************************************************************") - cog.outl("// The code above has been auto generated. Do not manually edit.") - cog.outl("//***************************************************************************") ]]]*/ /*[[[end]]]*/ } @@ -366,25 +382,8 @@ namespace etl etl::fsm_state_id_t number_of_states; ///< The number of states. }; - //*************************************************************************** - // To generate to header file, run this at the command line. - // Note: You will need Python and COG installed. - // - // python -m cogapp -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... - // python -m cogapp -d -e -ofsm.h -DHandlers=16 fsm_generator.h - // - // See CreateFSM.bat - //*************************************************************************** - /*[[[cog import cog - cog.outl("//***************************************************************************") - cog.outl("// The code below has been auto generated. Do not manually edit.") - cog.outl("//***************************************************************************") cog.outl("") ################################################ # The first definition for all of the events. @@ -419,7 +418,7 @@ namespace etl cog.outl(" etl::fsm_state_id_t process_event(etl::imessage_router& source, 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(" etl::message_id_t event_id = message.message_id;") cog.outl("") cog.outl(" switch (event_id)") cog.outl(" {") @@ -485,7 +484,7 @@ namespace etl cog.outl(" etl::fsm_state_id_t process_event(etl::imessage_router& source, 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(" etl::message_id_t event_id = message.message_id;") cog.outl("") cog.outl(" switch (event_id)") cog.outl(" {") diff --git a/src/generate.bat b/src/generate.bat new file mode 100644 index 00000000..8902cbde --- /dev/null +++ b/src/generate.bat @@ -0,0 +1,5 @@ +python -m cogapp -d -e -ofsm.h -DHandlers=16 fsm_generator.h +python -m cogapp -d -e -omessage_router.h -DHandlers=16 message_router_generator.h +python -m cogapp -d -e -olargest.h -DNTypes=16 largest_generator.h +python -m cogapp -d -e -osmallest.h -DNTypes=16 smallest_generator.h +python -m cogapp -d -e -otype_traits.h -DIsOneOf=16 type_traits_generator.h \ No newline at end of file diff --git a/src/largest.h b/src/largest.h index 311adc0b..502eee3e 100644 --- a/src/largest.h +++ b/src/largest.h @@ -28,6 +28,24 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ +//*************************************************************************** +// 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. +// +// python -m cogapp -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... +// python -m cogapp -d -e -olargest.h -DNTypes=16 largest_generator.h +// +// See generate.bat +//*************************************************************************** + #ifndef __ETL_LARGEST__ #define __ETL_LARGEST__ @@ -47,9 +65,9 @@ namespace etl /// Defines 'size' which is the size of the largest parameter. ///\ingroup largest //*************************************************************************** - template struct largest_type { @@ -78,14 +96,14 @@ namespace etl public: // Define 'largest_other' as 'largest_type' with all but the first parameter. - typedef typename largest_type::type largest_other; + typedef typename largest_type::type largest_other; // Set 'type' to be the largest of the first parameter and any of the others. // This is recursive. typedef typename choose_type<(sizeof(T1) > sizeof(largest_other)), // Boolean - T1, // TrueType - largest_other> // FalseType - ::type type; // The largest type of the two. + T1, // TrueType + largest_other> // FalseType + ::type type; // The largest type of the two. // The size of the largest type. enum @@ -98,10 +116,8 @@ namespace etl // Specialisation for one template parameter. //*************************************************************************** template - struct largest_type + struct largest_type { typedef T1 type; @@ -117,12 +133,14 @@ namespace etl /// Defines value which is the largest alignment of all the parameters. ///\ingroup largest //*************************************************************************** - template + template struct largest_alignment { + private: + // Determine the largest size. template struct max_size @@ -136,22 +154,22 @@ namespace etl // All of the alignments. enum { - t1 = alignment_of::value, - t2 = alignment_of::value, - t3 = alignment_of::value, - t4 = alignment_of::value, - t5 = alignment_of::value, - t6 = alignment_of::value, - t7 = alignment_of::value, - t8 = alignment_of::value, - t9 = alignment_of::value, - t10 = alignment_of::value, - t11 = alignment_of::value, - t12 = alignment_of::value, - t13 = alignment_of::value, - t14 = alignment_of::value, - t15 = alignment_of::value, - t16 = alignment_of::value + t1 = etl::alignment_of::value, + t2 = etl::alignment_of::value, + t3 = etl::alignment_of::value, + t4 = etl::alignment_of::value, + t5 = etl::alignment_of::value, + t6 = etl::alignment_of::value, + t7 = etl::alignment_of::value, + t8 = etl::alignment_of::value, + t9 = etl::alignment_of::value, + t10 = etl::alignment_of::value, + t11 = etl::alignment_of::value, + t12 = etl::alignment_of::value, + t13 = etl::alignment_of::value, + t14 = etl::alignment_of::value, + t15 = etl::alignment_of::value, + t16 = etl::alignment_of::value }; public: @@ -216,6 +234,27 @@ namespace etl typedef typename etl::smallest_int_for_bits::bits + 1>::type type; }; + + //*************************************************************************** + /// Template to determine the largest type, size and alignment. + /// Supports up to 16 types. + /// Defines value which is the largest type, size and alignment of all the parameters. + ///\ingroup largest + //*************************************************************************** + template + struct largest + { + typedef typename etl::largest_type::type type; + + enum + { + size = etl::largest_type::size, + alignment = etl::largest_alignment::value + }; + }; } #endif diff --git a/src/largest_generator.h b/src/largest_generator.h new file mode 100644 index 00000000..c785bf5e --- /dev/null +++ b/src/largest_generator.h @@ -0,0 +1,323 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +http://www.etlcpp.com + +Copyright(c) 2014 jwellbelove + +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. +// +// python -m cogapp -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... +// python -m cogapp -d -e -olargest.h -DNTypes=16 largest_generator.h +// +// See generate.bat +//*************************************************************************** + +#ifndef __ETL_LARGEST__ +#define __ETL_LARGEST__ + +///\defgroup largest largest +///\ingroup utilities + +#include "type_traits.h" +#include "smallest.h" +#include "static_assert.h" + +namespace etl +{ + /*[[[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("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 '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 choose_type<(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]]]*/ + + /*[[[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 " % NTypes) + cog.outl("struct largest_alignment") + cog.outl("{") + cog.outl("private:") + cog.outl("") + cog.outl(" // Determine the largest size.") + cog.outl(" template ") + cog.outl(" struct max_size") + cog.outl(" {") + cog.outl(" enum") + cog.outl(" {") + cog.outl(" value = (size1 > size2) ? size1 : size2") + cog.outl(" };") + cog.outl(" };") + cog.outl("") + cog.outl(" // All of the alignments.") + cog.outl(" enum") + cog.outl(" {") + for n in range(1, int(NTypes)): + cog.outl(" t%s = etl::alignment_of::value," %(n, n)) + cog.outl(" t%s = etl::alignment_of::value" % (NTypes, NTypes)) + cog.outl(" };") + cog.outl("") + cog.outl("public:") + cog.outl("") + cog.outl(" // The largest of all of them.") + cog.outl(" enum") + cog.outl(" {") + cog.out(" value = ") + for n in range(1, int(NTypes)): + cog.out("max_size" % int(NTypes)) + cog.out(" ") + for n in range(1, int(NTypes) - 1): + cog.out("::value>") + if n % 8 == 0: + cog.outl("") + cog.out(" ") + cog.outl("::value") + cog.outl(" };") + cog.outl("};") + ]]]*/ + /*[[[end]]]*/ + + //*************************************************************************** + /// 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 + { + STATIC_ASSERT(etl::is_integral::value, "Must be an integral type"); + + typedef typename etl::smallest_int_for_bits::type>::bits + 1>::type type; + }; + + //*************************************************************************** + /// 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 + { + STATIC_ASSERT(etl::is_integral::value, "Must be an integral type"); + + typedef typename etl::smallest_uint_for_bits::type>::bits + 1>::type type; + }; + + //*************************************************************************** + /// 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 + { + 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 + { + STATIC_ASSERT(etl::is_integral::value, "Must be an integral type"); + + typedef typename etl::smallest_int_for_bits::bits + 1>::type type; + }; + + /*[[[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 diff --git a/src/memory.h b/src/memory.h index 947c1124..1920f0b2 100644 --- a/src/memory.h +++ b/src/memory.h @@ -662,6 +662,27 @@ namespace etl return i_begin; } + + //***************************************************************************** + /// Copy constructs a derived class to an address. + ///\tparam T The derived type. + ///\ingroup memory + //***************************************************************************** + template + struct create_copy + { + void create_copy_at(void* p) + { + new (p) T(static_cast(*this)); + } + + template + void create_copy_at(void* p, TCounter& count) + { + new (p) T(static_cast(*this)); + ++count; + } + }; } #endif diff --git a/src/message_router.h b/src/message_router.h index 0a443ad5..2367a247 100644 --- a/src/message_router.h +++ b/src/message_router.h @@ -26,31 +26,89 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ +//*************************************************************************** +// 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. +// +// python -m cogapp -d -e -omessage_router.h -DHandlers= message_router_generator.h +// Where is the number of messages to support. +// +// e.g. +// To generate handlers for up to 16 messages... +// python -m cogapp -d -e -omessage_router.h -DHandlers=16 message_router_generator.h +// +// See generate.bat +//*************************************************************************** + #ifndef __ETL_MESSAGE_ROUTER__ #define __ETL_MESSAGE_ROUTER__ #include +#include "alignment.h" +#include "error_handler.h" +#include "exception.h" +#include "largest.h" + +#undef ETL_FILE +#define ETL_FILE "35" + namespace etl { /// Allow alternative type for message id. #if !defined(ETL_MESSAGE_ID_TYPE) - typedef uint_least8_t message_id_t; + typedef uint_least8_t message_id_t; #else - typedef ETL_MESSAGE_ID_TYPE message_id_t; + typedef ETL_MESSAGE_ID_TYPE message_id_t; #endif + //*************************************************************************** + class message_exception : public etl::exception + { + public: + + message_exception(string_type what, string_type file_name, numeric_type line_number) + : exception(what, file_name, line_number) + { + } + }; + + //*************************************************************************** + class unhandled_message_exception : public etl::message_exception + { + public: + + unhandled_message_exception(string_type file_name, numeric_type line_number) + : message_exception(ETL_ERROR_TEXT("message:unknown", ETL_FILE"A"), file_name, line_number) + { + } + }; + //*************************************************************************** class imessage { public: - + + //******************************************** virtual ~imessage() {} - virtual etl::message_id_t get_message_id() const = 0; + + const etl::message_id_t message_id; + + protected: + + //******************************************** + imessage(etl::message_id_t id) + : message_id(id) + { + } }; //*************************************************************************** - template + template class message : public imessage { public: @@ -60,9 +118,10 @@ namespace etl ID = ID_ }; - etl::message_id_t get_message_id() const + //******************************************** + message() + : imessage(ID_) { - return etl::message_id_t(ID); } }; @@ -76,11 +135,13 @@ namespace etl virtual bool accepts(etl::message_id_t id) const = 0; + //******************************************** bool accepts(const etl::imessage& msg) const { - return accepts(msg.get_message_id()); + return accepts(msg.message_id); } + //******************************************** void send_message(imessage_router& destination, const etl::imessage& message) { @@ -96,14 +157,17 @@ namespace etl { public: + //******************************************** void receive(const etl::imessage& message) { } + //******************************************** void receive(etl::imessage_router& source, const etl::imessage& message) { } + //******************************************** bool accepts(etl::message_id_t id) const { return false; @@ -130,23 +194,6 @@ namespace etl destination.receive(source, message); } - //*************************************************************************** - // To generate to header file, run this at the command line. - // Note: You will need Python and COG installed. - // - // python -m cogapp -d -e -omessage_router.h -DHandlers= message_router_generator.h - // Where is the number of messages to support. - // - // e.g. - // To generate handlers for up to 16 messages... - // python -m cogapp -d -e -omessage_router.h -DHandlers=16 message_router_generator.h - // - // See CreateMessageProcessor.bat - //*************************************************************************** - - //*************************************************************************** - // The code below has been auto generated. Do not manually edit. - //*************************************************************************** //*************************************************************************** // The definition for all 16 message types. @@ -160,15 +207,90 @@ namespace etl { public: + //********************************************** + class message_packet + { + public: + + //******************************************** + explicit message_packet(const etl::imessage& msg) + { + const size_t id = msg.message_id; + + void* p = data; + + switch (id) + { + case T1::ID: ::new (p) T1(static_cast(msg)); break; + case T2::ID: ::new (p) T2(static_cast(msg)); break; + case T3::ID: ::new (p) T3(static_cast(msg)); break; + case T4::ID: ::new (p) T4(static_cast(msg)); break; + case T5::ID: ::new (p) T5(static_cast(msg)); break; + case T6::ID: ::new (p) T6(static_cast(msg)); break; + case T7::ID: ::new (p) T7(static_cast(msg)); break; + case T8::ID: ::new (p) T8(static_cast(msg)); break; + case T9::ID: ::new (p) T9(static_cast(msg)); break; + case T10::ID: ::new (p) T10(static_cast(msg)); break; + case T11::ID: ::new (p) T11(static_cast(msg)); break; + case T12::ID: ::new (p) T12(static_cast(msg)); break; + case T13::ID: ::new (p) T13(static_cast(msg)); break; + case T14::ID: ::new (p) T14(static_cast(msg)); break; + case T15::ID: ::new (p) T15(static_cast(msg)); break; + case T16::ID: ::new (p) T16(static_cast(msg)); break; + default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break; + } + } + + //******************************************** + template + explicit message_packet(const T& msg) + { + STATIC_ASSERT((etl::is_one_of::value), "Unsupported type for this message packet"); + + void* p = data; + ::new (p) T(static_cast(msg)); + } + + //******************************************** + ~message_packet() + { + static_cast(data)->~imessage(); + } + + //******************************************** + etl::imessage& get() + { + return *static_cast(data); + } + + //******************************************** + const etl::imessage& get() const + { + return *static_cast(data); + } + + enum + { + SIZE = etl::largest::size, + ALIGNMENT = etl::largest::alignment + }; + + private: + + typename etl::aligned_storage::type data; + }; + + //********************************************** void receive(const etl::imessage& msg) { etl::null_message_router nmr; receive(nmr, msg); } + //********************************************** void receive(etl::imessage_router& source, const etl::imessage& msg) { - const etl::message_id_t id = msg.get_message_id(); + const etl::message_id_t id = msg.message_id; switch (id) { @@ -192,6 +314,9 @@ namespace etl } } + using imessage_router::accepts; + + //********************************************** bool accepts(etl::message_id_t id) const { switch (id) @@ -218,15 +343,89 @@ namespace etl { public: + //********************************************** + class message_packet + { + public: + + //******************************************** + explicit message_packet(const etl::imessage& msg) + { + const size_t id = msg.message_id; + + void* p = data; + + switch (id) + { + case T1::ID: ::new (p) T1(static_cast(msg)); break; + case T2::ID: ::new (p) T2(static_cast(msg)); break; + case T3::ID: ::new (p) T3(static_cast(msg)); break; + case T4::ID: ::new (p) T4(static_cast(msg)); break; + case T5::ID: ::new (p) T5(static_cast(msg)); break; + case T6::ID: ::new (p) T6(static_cast(msg)); break; + case T7::ID: ::new (p) T7(static_cast(msg)); break; + case T8::ID: ::new (p) T8(static_cast(msg)); break; + case T9::ID: ::new (p) T9(static_cast(msg)); break; + case T10::ID: ::new (p) T10(static_cast(msg)); break; + case T11::ID: ::new (p) T11(static_cast(msg)); break; + case T12::ID: ::new (p) T12(static_cast(msg)); break; + case T13::ID: ::new (p) T13(static_cast(msg)); break; + case T14::ID: ::new (p) T14(static_cast(msg)); break; + case T15::ID: ::new (p) T15(static_cast(msg)); break; + default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break; + } + } + + //******************************************** + template + explicit message_packet(const T& msg) + { + STATIC_ASSERT((etl::is_one_of::value), "Unsupported type for this message packet"); + + void* p = data; + ::new (p) T(static_cast(msg)); + } + + //******************************************** + ~message_packet() + { + static_cast(data)->~imessage(); + } + + //******************************************** + etl::imessage& get() + { + return *static_cast(data); + } + + //******************************************** + const etl::imessage& get() const + { + return *static_cast(data); + } + + enum + { + SIZE = etl::largest::size, + ALIGNMENT = etl::largest::alignment + }; + + private: + + typename etl::aligned_storage::type data; + }; + + //********************************************** void receive(const etl::imessage& msg) { etl::null_message_router nmr; receive(nmr, msg); } + //********************************************** void receive(etl::imessage_router& source, const etl::imessage& msg) { - const size_t id = msg.get_message_id(); + const size_t id = msg.message_id; switch (id) { @@ -249,6 +448,9 @@ namespace etl } } + using imessage_router::accepts; + + //********************************************** bool accepts(etl::message_id_t id) const { switch (id) @@ -275,15 +477,88 @@ namespace etl { public: + //********************************************** + class message_packet + { + public: + + //******************************************** + explicit message_packet(const etl::imessage& msg) + { + const size_t id = msg.message_id; + + void* p = data; + + switch (id) + { + case T1::ID: ::new (p) T1(static_cast(msg)); break; + case T2::ID: ::new (p) T2(static_cast(msg)); break; + case T3::ID: ::new (p) T3(static_cast(msg)); break; + case T4::ID: ::new (p) T4(static_cast(msg)); break; + case T5::ID: ::new (p) T5(static_cast(msg)); break; + case T6::ID: ::new (p) T6(static_cast(msg)); break; + case T7::ID: ::new (p) T7(static_cast(msg)); break; + case T8::ID: ::new (p) T8(static_cast(msg)); break; + case T9::ID: ::new (p) T9(static_cast(msg)); break; + case T10::ID: ::new (p) T10(static_cast(msg)); break; + case T11::ID: ::new (p) T11(static_cast(msg)); break; + case T12::ID: ::new (p) T12(static_cast(msg)); break; + case T13::ID: ::new (p) T13(static_cast(msg)); break; + case T14::ID: ::new (p) T14(static_cast(msg)); break; + default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break; + } + } + + //******************************************** + template + explicit message_packet(const T& msg) + { + STATIC_ASSERT((etl::is_one_of::value), "Unsupported type for this message packet"); + + void* p = data; + ::new (p) T(static_cast(msg)); + } + + //******************************************** + ~message_packet() + { + static_cast(data)->~imessage(); + } + + //******************************************** + etl::imessage& get() + { + return *static_cast(data); + } + + //******************************************** + const etl::imessage& get() const + { + return *static_cast(data); + } + + enum + { + SIZE = etl::largest::size, + ALIGNMENT = etl::largest::alignment + }; + + private: + + typename etl::aligned_storage::type data; + }; + + //********************************************** void receive(const etl::imessage& msg) { etl::null_message_router nmr; receive(nmr, msg); } + //********************************************** void receive(etl::imessage_router& source, const etl::imessage& msg) { - const size_t id = msg.get_message_id(); + const size_t id = msg.message_id; switch (id) { @@ -305,6 +580,9 @@ namespace etl } } + using imessage_router::accepts; + + //********************************************** bool accepts(etl::message_id_t id) const { switch (id) @@ -331,15 +609,87 @@ namespace etl { public: + //********************************************** + class message_packet + { + public: + + //******************************************** + explicit message_packet(const etl::imessage& msg) + { + const size_t id = msg.message_id; + + void* p = data; + + switch (id) + { + case T1::ID: ::new (p) T1(static_cast(msg)); break; + case T2::ID: ::new (p) T2(static_cast(msg)); break; + case T3::ID: ::new (p) T3(static_cast(msg)); break; + case T4::ID: ::new (p) T4(static_cast(msg)); break; + case T5::ID: ::new (p) T5(static_cast(msg)); break; + case T6::ID: ::new (p) T6(static_cast(msg)); break; + case T7::ID: ::new (p) T7(static_cast(msg)); break; + case T8::ID: ::new (p) T8(static_cast(msg)); break; + case T9::ID: ::new (p) T9(static_cast(msg)); break; + case T10::ID: ::new (p) T10(static_cast(msg)); break; + case T11::ID: ::new (p) T11(static_cast(msg)); break; + case T12::ID: ::new (p) T12(static_cast(msg)); break; + case T13::ID: ::new (p) T13(static_cast(msg)); break; + default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break; + } + } + + //******************************************** + template + explicit message_packet(const T& msg) + { + STATIC_ASSERT((etl::is_one_of::value), "Unsupported type for this message packet"); + + void* p = data; + ::new (p) T(static_cast(msg)); + } + + //******************************************** + ~message_packet() + { + static_cast(data)->~imessage(); + } + + //******************************************** + etl::imessage& get() + { + return *static_cast(data); + } + + //******************************************** + const etl::imessage& get() const + { + return *static_cast(data); + } + + enum + { + SIZE = etl::largest::size, + ALIGNMENT = etl::largest::alignment + }; + + private: + + typename etl::aligned_storage::type data; + }; + + //********************************************** void receive(const etl::imessage& msg) { etl::null_message_router nmr; receive(nmr, msg); } + //********************************************** void receive(etl::imessage_router& source, const etl::imessage& msg) { - const size_t id = msg.get_message_id(); + const size_t id = msg.message_id; switch (id) { @@ -360,6 +710,9 @@ namespace etl } } + using imessage_router::accepts; + + //********************************************** bool accepts(etl::message_id_t id) const { switch (id) @@ -385,15 +738,86 @@ namespace etl { public: + //********************************************** + class message_packet + { + public: + + //******************************************** + explicit message_packet(const etl::imessage& msg) + { + const size_t id = msg.message_id; + + void* p = data; + + switch (id) + { + case T1::ID: ::new (p) T1(static_cast(msg)); break; + case T2::ID: ::new (p) T2(static_cast(msg)); break; + case T3::ID: ::new (p) T3(static_cast(msg)); break; + case T4::ID: ::new (p) T4(static_cast(msg)); break; + case T5::ID: ::new (p) T5(static_cast(msg)); break; + case T6::ID: ::new (p) T6(static_cast(msg)); break; + case T7::ID: ::new (p) T7(static_cast(msg)); break; + case T8::ID: ::new (p) T8(static_cast(msg)); break; + case T9::ID: ::new (p) T9(static_cast(msg)); break; + case T10::ID: ::new (p) T10(static_cast(msg)); break; + case T11::ID: ::new (p) T11(static_cast(msg)); break; + case T12::ID: ::new (p) T12(static_cast(msg)); break; + default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break; + } + } + + //******************************************** + template + explicit message_packet(const T& msg) + { + STATIC_ASSERT((etl::is_one_of::value), "Unsupported type for this message packet"); + + void* p = data; + ::new (p) T(static_cast(msg)); + } + + //******************************************** + ~message_packet() + { + static_cast(data)->~imessage(); + } + + //******************************************** + etl::imessage& get() + { + return *static_cast(data); + } + + //******************************************** + const etl::imessage& get() const + { + return *static_cast(data); + } + + enum + { + SIZE = etl::largest::size, + ALIGNMENT = etl::largest::alignment + }; + + private: + + typename etl::aligned_storage::type data; + }; + + //********************************************** void receive(const etl::imessage& msg) { etl::null_message_router nmr; receive(nmr, msg); } + //********************************************** void receive(etl::imessage_router& source, const etl::imessage& msg) { - const size_t id = msg.get_message_id(); + const size_t id = msg.message_id; switch (id) { @@ -413,6 +837,9 @@ namespace etl } } + using imessage_router::accepts; + + //********************************************** bool accepts(etl::message_id_t id) const { switch (id) @@ -438,15 +865,85 @@ namespace etl { public: + //********************************************** + class message_packet + { + public: + + //******************************************** + explicit message_packet(const etl::imessage& msg) + { + const size_t id = msg.message_id; + + void* p = data; + + switch (id) + { + case T1::ID: ::new (p) T1(static_cast(msg)); break; + case T2::ID: ::new (p) T2(static_cast(msg)); break; + case T3::ID: ::new (p) T3(static_cast(msg)); break; + case T4::ID: ::new (p) T4(static_cast(msg)); break; + case T5::ID: ::new (p) T5(static_cast(msg)); break; + case T6::ID: ::new (p) T6(static_cast(msg)); break; + case T7::ID: ::new (p) T7(static_cast(msg)); break; + case T8::ID: ::new (p) T8(static_cast(msg)); break; + case T9::ID: ::new (p) T9(static_cast(msg)); break; + case T10::ID: ::new (p) T10(static_cast(msg)); break; + case T11::ID: ::new (p) T11(static_cast(msg)); break; + default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break; + } + } + + //******************************************** + template + explicit message_packet(const T& msg) + { + STATIC_ASSERT((etl::is_one_of::value), "Unsupported type for this message packet"); + + void* p = data; + ::new (p) T(static_cast(msg)); + } + + //******************************************** + ~message_packet() + { + static_cast(data)->~imessage(); + } + + //******************************************** + etl::imessage& get() + { + return *static_cast(data); + } + + //******************************************** + const etl::imessage& get() const + { + return *static_cast(data); + } + + enum + { + SIZE = etl::largest::size, + ALIGNMENT = etl::largest::alignment + }; + + private: + + typename etl::aligned_storage::type data; + }; + + //********************************************** void receive(const etl::imessage& msg) { etl::null_message_router nmr; receive(nmr, msg); } + //********************************************** void receive(etl::imessage_router& source, const etl::imessage& msg) { - const size_t id = msg.get_message_id(); + const size_t id = msg.message_id; switch (id) { @@ -465,6 +962,9 @@ namespace etl } } + using imessage_router::accepts; + + //********************************************** bool accepts(etl::message_id_t id) const { switch (id) @@ -490,15 +990,84 @@ namespace etl { public: + //********************************************** + class message_packet + { + public: + + //******************************************** + explicit message_packet(const etl::imessage& msg) + { + const size_t id = msg.message_id; + + void* p = data; + + switch (id) + { + case T1::ID: ::new (p) T1(static_cast(msg)); break; + case T2::ID: ::new (p) T2(static_cast(msg)); break; + case T3::ID: ::new (p) T3(static_cast(msg)); break; + case T4::ID: ::new (p) T4(static_cast(msg)); break; + case T5::ID: ::new (p) T5(static_cast(msg)); break; + case T6::ID: ::new (p) T6(static_cast(msg)); break; + case T7::ID: ::new (p) T7(static_cast(msg)); break; + case T8::ID: ::new (p) T8(static_cast(msg)); break; + case T9::ID: ::new (p) T9(static_cast(msg)); break; + case T10::ID: ::new (p) T10(static_cast(msg)); break; + default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break; + } + } + + //******************************************** + template + explicit message_packet(const T& msg) + { + STATIC_ASSERT((etl::is_one_of::value), "Unsupported type for this message packet"); + + void* p = data; + ::new (p) T(static_cast(msg)); + } + + //******************************************** + ~message_packet() + { + static_cast(data)->~imessage(); + } + + //******************************************** + etl::imessage& get() + { + return *static_cast(data); + } + + //******************************************** + const etl::imessage& get() const + { + return *static_cast(data); + } + + enum + { + SIZE = etl::largest::size, + ALIGNMENT = etl::largest::alignment + }; + + private: + + typename etl::aligned_storage::type data; + }; + + //********************************************** void receive(const etl::imessage& msg) { etl::null_message_router nmr; receive(nmr, msg); } + //********************************************** void receive(etl::imessage_router& source, const etl::imessage& msg) { - const size_t id = msg.get_message_id(); + const size_t id = msg.message_id; switch (id) { @@ -516,6 +1085,9 @@ namespace etl } } + using imessage_router::accepts; + + //********************************************** bool accepts(etl::message_id_t id) const { switch (id) @@ -541,15 +1113,83 @@ namespace etl { public: + //********************************************** + class message_packet + { + public: + + //******************************************** + explicit message_packet(const etl::imessage& msg) + { + const size_t id = msg.message_id; + + void* p = data; + + switch (id) + { + case T1::ID: ::new (p) T1(static_cast(msg)); break; + case T2::ID: ::new (p) T2(static_cast(msg)); break; + case T3::ID: ::new (p) T3(static_cast(msg)); break; + case T4::ID: ::new (p) T4(static_cast(msg)); break; + case T5::ID: ::new (p) T5(static_cast(msg)); break; + case T6::ID: ::new (p) T6(static_cast(msg)); break; + case T7::ID: ::new (p) T7(static_cast(msg)); break; + case T8::ID: ::new (p) T8(static_cast(msg)); break; + case T9::ID: ::new (p) T9(static_cast(msg)); break; + default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break; + } + } + + //******************************************** + template + explicit message_packet(const T& msg) + { + STATIC_ASSERT((etl::is_one_of::value), "Unsupported type for this message packet"); + + void* p = data; + ::new (p) T(static_cast(msg)); + } + + //******************************************** + ~message_packet() + { + static_cast(data)->~imessage(); + } + + //******************************************** + etl::imessage& get() + { + return *static_cast(data); + } + + //******************************************** + const etl::imessage& get() const + { + return *static_cast(data); + } + + enum + { + SIZE = etl::largest::size, + ALIGNMENT = etl::largest::alignment + }; + + private: + + typename etl::aligned_storage::type data; + }; + + //********************************************** void receive(const etl::imessage& msg) { etl::null_message_router nmr; receive(nmr, msg); } + //********************************************** void receive(etl::imessage_router& source, const etl::imessage& msg) { - const size_t id = msg.get_message_id(); + const size_t id = msg.message_id; switch (id) { @@ -566,6 +1206,9 @@ namespace etl } } + using imessage_router::accepts; + + //********************************************** bool accepts(etl::message_id_t id) const { switch (id) @@ -590,15 +1233,82 @@ namespace etl { public: + //********************************************** + class message_packet + { + public: + + //******************************************** + explicit message_packet(const etl::imessage& msg) + { + const size_t id = msg.message_id; + + void* p = data; + + switch (id) + { + case T1::ID: ::new (p) T1(static_cast(msg)); break; + case T2::ID: ::new (p) T2(static_cast(msg)); break; + case T3::ID: ::new (p) T3(static_cast(msg)); break; + case T4::ID: ::new (p) T4(static_cast(msg)); break; + case T5::ID: ::new (p) T5(static_cast(msg)); break; + case T6::ID: ::new (p) T6(static_cast(msg)); break; + case T7::ID: ::new (p) T7(static_cast(msg)); break; + case T8::ID: ::new (p) T8(static_cast(msg)); break; + default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break; + } + } + + //******************************************** + template + explicit message_packet(const T& msg) + { + STATIC_ASSERT((etl::is_one_of::value), "Unsupported type for this message packet"); + + void* p = data; + ::new (p) T(static_cast(msg)); + } + + //******************************************** + ~message_packet() + { + static_cast(data)->~imessage(); + } + + //******************************************** + etl::imessage& get() + { + return *static_cast(data); + } + + //******************************************** + const etl::imessage& get() const + { + return *static_cast(data); + } + + enum + { + SIZE = etl::largest::size, + ALIGNMENT = etl::largest::alignment + }; + + private: + + typename etl::aligned_storage::type data; + }; + + //********************************************** void receive(const etl::imessage& msg) { etl::null_message_router nmr; receive(nmr, msg); } + //********************************************** void receive(etl::imessage_router& source, const etl::imessage& msg) { - const size_t id = msg.get_message_id(); + const size_t id = msg.message_id; switch (id) { @@ -614,6 +1324,9 @@ namespace etl } } + using imessage_router::accepts; + + //********************************************** bool accepts(etl::message_id_t id) const { switch (id) @@ -638,15 +1351,81 @@ namespace etl { public: + //********************************************** + class message_packet + { + public: + + //******************************************** + explicit message_packet(const etl::imessage& msg) + { + const size_t id = msg.message_id; + + void* p = data; + + switch (id) + { + case T1::ID: ::new (p) T1(static_cast(msg)); break; + case T2::ID: ::new (p) T2(static_cast(msg)); break; + case T3::ID: ::new (p) T3(static_cast(msg)); break; + case T4::ID: ::new (p) T4(static_cast(msg)); break; + case T5::ID: ::new (p) T5(static_cast(msg)); break; + case T6::ID: ::new (p) T6(static_cast(msg)); break; + case T7::ID: ::new (p) T7(static_cast(msg)); break; + default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break; + } + } + + //******************************************** + template + explicit message_packet(const T& msg) + { + STATIC_ASSERT((etl::is_one_of::value), "Unsupported type for this message packet"); + + void* p = data; + ::new (p) T(static_cast(msg)); + } + + //******************************************** + ~message_packet() + { + static_cast(data)->~imessage(); + } + + //******************************************** + etl::imessage& get() + { + return *static_cast(data); + } + + //******************************************** + const etl::imessage& get() const + { + return *static_cast(data); + } + + enum + { + SIZE = etl::largest::size, + ALIGNMENT = etl::largest::alignment + }; + + private: + + typename etl::aligned_storage::type data; + }; + + //********************************************** void receive(const etl::imessage& msg) { etl::null_message_router nmr; receive(nmr, msg); } + //********************************************** void receive(etl::imessage_router& source, const etl::imessage& msg) { - const size_t id = msg.get_message_id(); + const size_t id = msg.message_id; switch (id) { @@ -661,6 +1440,9 @@ namespace etl } } + using imessage_router::accepts; + + //********************************************** bool accepts(etl::message_id_t id) const { switch (id) @@ -684,15 +1466,80 @@ namespace etl { public: + //********************************************** + class message_packet + { + public: + + //******************************************** + explicit message_packet(const etl::imessage& msg) + { + const size_t id = msg.message_id; + + void* p = data; + + switch (id) + { + case T1::ID: ::new (p) T1(static_cast(msg)); break; + case T2::ID: ::new (p) T2(static_cast(msg)); break; + case T3::ID: ::new (p) T3(static_cast(msg)); break; + case T4::ID: ::new (p) T4(static_cast(msg)); break; + case T5::ID: ::new (p) T5(static_cast(msg)); break; + case T6::ID: ::new (p) T6(static_cast(msg)); break; + default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break; + } + } + + //******************************************** + template + explicit message_packet(const T& msg) + { + STATIC_ASSERT((etl::is_one_of::value), "Unsupported type for this message packet"); + + void* p = data; + ::new (p) T(static_cast(msg)); + } + + //******************************************** + ~message_packet() + { + static_cast(data)->~imessage(); + } + + //******************************************** + etl::imessage& get() + { + return *static_cast(data); + } + + //******************************************** + const etl::imessage& get() const + { + return *static_cast(data); + } + + enum + { + SIZE = etl::largest::size, + ALIGNMENT = etl::largest::alignment + }; + + private: + + typename etl::aligned_storage::type data; + }; + + //********************************************** void receive(const etl::imessage& msg) { etl::null_message_router nmr; receive(nmr, msg); } + //********************************************** void receive(etl::imessage_router& source, const etl::imessage& msg) { - const size_t id = msg.get_message_id(); + const size_t id = msg.message_id; switch (id) { @@ -706,6 +1553,9 @@ namespace etl } } + using imessage_router::accepts; + + //********************************************** bool accepts(etl::message_id_t id) const { switch (id) @@ -729,15 +1579,79 @@ namespace etl { public: + //********************************************** + class message_packet + { + public: + + //******************************************** + explicit message_packet(const etl::imessage& msg) + { + const size_t id = msg.message_id; + + void* p = data; + + switch (id) + { + case T1::ID: ::new (p) T1(static_cast(msg)); break; + case T2::ID: ::new (p) T2(static_cast(msg)); break; + case T3::ID: ::new (p) T3(static_cast(msg)); break; + case T4::ID: ::new (p) T4(static_cast(msg)); break; + case T5::ID: ::new (p) T5(static_cast(msg)); break; + default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break; + } + } + + //******************************************** + template + explicit message_packet(const T& msg) + { + STATIC_ASSERT((etl::is_one_of::value), "Unsupported type for this message packet"); + + void* p = data; + ::new (p) T(static_cast(msg)); + } + + //******************************************** + ~message_packet() + { + static_cast(data)->~imessage(); + } + + //******************************************** + etl::imessage& get() + { + return *static_cast(data); + } + + //******************************************** + const etl::imessage& get() const + { + return *static_cast(data); + } + + enum + { + SIZE = etl::largest::size, + ALIGNMENT = etl::largest::alignment + }; + + private: + + typename etl::aligned_storage::type data; + }; + + //********************************************** void receive(const etl::imessage& msg) { etl::null_message_router nmr; receive(nmr, msg); } + //********************************************** void receive(etl::imessage_router& source, const etl::imessage& msg) { - const size_t id = msg.get_message_id(); + const size_t id = msg.message_id; switch (id) { @@ -750,6 +1664,9 @@ namespace etl } } + using imessage_router::accepts; + + //********************************************** bool accepts(etl::message_id_t id) const { switch (id) @@ -772,15 +1689,78 @@ namespace etl { public: + //********************************************** + class message_packet + { + public: + + //******************************************** + explicit message_packet(const etl::imessage& msg) + { + const size_t id = msg.message_id; + + void* p = data; + + switch (id) + { + case T1::ID: ::new (p) T1(static_cast(msg)); break; + case T2::ID: ::new (p) T2(static_cast(msg)); break; + case T3::ID: ::new (p) T3(static_cast(msg)); break; + case T4::ID: ::new (p) T4(static_cast(msg)); break; + default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break; + } + } + + //******************************************** + template + explicit message_packet(const T& msg) + { + STATIC_ASSERT((etl::is_one_of::value), "Unsupported type for this message packet"); + + void* p = data; + ::new (p) T(static_cast(msg)); + } + + //******************************************** + ~message_packet() + { + static_cast(data)->~imessage(); + } + + //******************************************** + etl::imessage& get() + { + return *static_cast(data); + } + + //******************************************** + const etl::imessage& get() const + { + return *static_cast(data); + } + + enum + { + SIZE = etl::largest::size, + ALIGNMENT = etl::largest::alignment + }; + + private: + + typename etl::aligned_storage::type data; + }; + + //********************************************** void receive(const etl::imessage& msg) { etl::null_message_router nmr; receive(nmr, msg); } + //********************************************** void receive(etl::imessage_router& source, const etl::imessage& msg) { - const size_t id = msg.get_message_id(); + const size_t id = msg.message_id; switch (id) { @@ -792,6 +1772,9 @@ namespace etl } } + using imessage_router::accepts; + + //********************************************** bool accepts(etl::message_id_t id) const { switch (id) @@ -814,15 +1797,77 @@ namespace etl { public: + //********************************************** + class message_packet + { + public: + + //******************************************** + explicit message_packet(const etl::imessage& msg) + { + const size_t id = msg.message_id; + + void* p = data; + + switch (id) + { + case T1::ID: ::new (p) T1(static_cast(msg)); break; + case T2::ID: ::new (p) T2(static_cast(msg)); break; + case T3::ID: ::new (p) T3(static_cast(msg)); break; + default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break; + } + } + + //******************************************** + template + explicit message_packet(const T& msg) + { + STATIC_ASSERT((etl::is_one_of::value), "Unsupported type for this message packet"); + + void* p = data; + ::new (p) T(static_cast(msg)); + } + + //******************************************** + ~message_packet() + { + static_cast(data)->~imessage(); + } + + //******************************************** + etl::imessage& get() + { + return *static_cast(data); + } + + //******************************************** + const etl::imessage& get() const + { + return *static_cast(data); + } + + enum + { + SIZE = etl::largest::size, + ALIGNMENT = etl::largest::alignment + }; + + private: + + typename etl::aligned_storage::type data; + }; + + //********************************************** void receive(const etl::imessage& msg) { etl::null_message_router nmr; receive(nmr, msg); } + //********************************************** void receive(etl::imessage_router& source, const etl::imessage& msg) { - const size_t id = msg.get_message_id(); + const size_t id = msg.message_id; switch (id) { @@ -833,6 +1878,9 @@ namespace etl } } + using imessage_router::accepts; + + //********************************************** bool accepts(etl::message_id_t id) const { switch (id) @@ -855,15 +1903,76 @@ namespace etl { public: + //********************************************** + class message_packet + { + public: + + //******************************************** + explicit message_packet(const etl::imessage& msg) + { + const size_t id = msg.message_id; + + void* p = data; + + switch (id) + { + case T1::ID: ::new (p) T1(static_cast(msg)); break; + case T2::ID: ::new (p) T2(static_cast(msg)); break; + default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break; + } + } + + //******************************************** + template + explicit message_packet(const T& msg) + { + STATIC_ASSERT((etl::is_one_of::value), "Unsupported type for this message packet"); + + void* p = data; + ::new (p) T(static_cast(msg)); + } + + //******************************************** + ~message_packet() + { + static_cast(data)->~imessage(); + } + + //******************************************** + etl::imessage& get() + { + return *static_cast(data); + } + + //******************************************** + const etl::imessage& get() const + { + return *static_cast(data); + } + + enum + { + SIZE = etl::largest::size, + ALIGNMENT = etl::largest::alignment + }; + + private: + + typename etl::aligned_storage::type data; + }; + + //********************************************** void receive(const etl::imessage& msg) { etl::null_message_router nmr; receive(nmr, msg); } + //********************************************** void receive(etl::imessage_router& source, const etl::imessage& msg) { - const size_t id = msg.get_message_id(); + const size_t id = msg.message_id; switch (id) { @@ -873,6 +1982,9 @@ namespace etl } } + using imessage_router::accepts; + + //********************************************** bool accepts(etl::message_id_t id) const { switch (id) @@ -895,15 +2007,75 @@ namespace etl { public: + //********************************************** + class message_packet + { + public: + + //******************************************** + explicit message_packet(const etl::imessage& msg) + { + const size_t id = msg.message_id; + + void* p = data; + + switch (id) + { + case T1::ID: ::new (p) T1(static_cast(msg)); break; + default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break; + } + } + + //******************************************** + template + explicit message_packet(const T& msg) + { + STATIC_ASSERT((etl::is_one_of::value), "Unsupported type for this message packet"); + + void* p = data; + ::new (p) T(static_cast(msg)); + } + + //******************************************** + ~message_packet() + { + static_cast(data)->~imessage(); + } + + //******************************************** + etl::imessage& get() + { + return *static_cast(data); + } + + //******************************************** + const etl::imessage& get() const + { + return *static_cast(data); + } + + enum + { + SIZE = etl::largest::size, + ALIGNMENT = etl::largest::alignment + }; + + private: + + typename etl::aligned_storage::type data; + }; + + //********************************************** void receive(const etl::imessage& msg) { etl::null_message_router nmr; receive(nmr, msg); } + //********************************************** void receive(etl::imessage_router& source, const etl::imessage& msg) { - const size_t id = msg.get_message_id(); + const size_t id = msg.message_id; switch (id) { @@ -912,6 +2084,9 @@ namespace etl } } + using imessage_router::accepts; + + //********************************************** bool accepts(etl::message_id_t id) const { switch (id) @@ -925,4 +2100,6 @@ namespace etl }; } +#undef ETL_FILE + #endif diff --git a/src/message_router_generator.h b/src/message_router_generator.h index 7ad5cc81..0ac54884 100644 --- a/src/message_router_generator.h +++ b/src/message_router_generator.h @@ -26,11 +26,50 @@ 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. +// +// python -m cogapp -d -e -omessage_router.h -DHandlers= message_router_generator.h +// Where is the number of messages to support. +// +// e.g. +// To generate handlers for up to 16 messages... +// python -m cogapp -d -e -omessage_router.h -DHandlers=16 message_router_generator.h +// +// See generate.bat +//*************************************************************************** + #ifndef __ETL_MESSAGE_ROUTER__ #define __ETL_MESSAGE_ROUTER__ #include +#include "alignment.h" +#include "error_handler.h" +#include "exception.h" +#include "largest.h" + #undef ETL_FILE #define ETL_FILE "35" @@ -38,22 +77,54 @@ namespace etl { /// Allow alternative type for message id. #if !defined(ETL_MESSAGE_ID_TYPE) - typedef uint_least8_t message_id_t; + typedef uint_least8_t message_id_t; #else - typedef ETL_MESSAGE_ID_TYPE message_id_t; + typedef ETL_MESSAGE_ID_TYPE message_id_t; #endif + //*************************************************************************** + class message_exception : public etl::exception + { + public: + + message_exception(string_type what, string_type file_name, numeric_type line_number) + : exception(what, file_name, line_number) + { + } + }; + + //*************************************************************************** + class unhandled_message_exception : public etl::message_exception + { + public: + + unhandled_message_exception(string_type file_name, numeric_type line_number) + : message_exception(ETL_ERROR_TEXT("message:unknown", ETL_FILE"A"), file_name, line_number) + { + } + }; + //*************************************************************************** class imessage { public: - + + //******************************************** virtual ~imessage() {} - virtual etl::message_id_t get_message_id() const = 0; + + const etl::message_id_t message_id; + + protected: + + //******************************************** + imessage(etl::message_id_t id) + : message_id(id) + { + } }; //*************************************************************************** - template + template class message : public imessage { public: @@ -63,9 +134,10 @@ namespace etl ID = ID_ }; - etl::message_id_t get_message_id() const + //******************************************** + message() + : imessage(ID_) { - return etl::message_id_t(ID); } }; @@ -79,11 +151,13 @@ namespace etl virtual bool accepts(etl::message_id_t id) const = 0; + //******************************************** bool accepts(const etl::imessage& msg) const { - return accepts(msg.get_message_id()); + return accepts(msg.message_id); } + //******************************************** void send_message(imessage_router& destination, const etl::imessage& message) { @@ -99,14 +173,17 @@ namespace etl { public: + //******************************************** void receive(const etl::imessage& message) { } + //******************************************** void receive(etl::imessage_router& source, const etl::imessage& message) { } + //******************************************** bool accepts(etl::message_id_t id) const { return false; @@ -133,25 +210,8 @@ namespace etl destination.receive(source, message); } - //*************************************************************************** - // To generate to header file, run this at the command line. - // Note: You will need Python and COG installed. - // - // python -m cogapp -d -e -omessage_router.h -DHandlers= message_router_generator.h - // Where is the number of messages to support. - // - // e.g. - // To generate handlers for up to 16 messages... - // python -m cogapp -d -e -omessage_router.h -DHandlers=16 message_router_generator.h - // - // See CreateMessageProcessor.bat - //*************************************************************************** - /*[[[cog import cog - cog.outl("//***************************************************************************") - cog.outl("// The code below has been auto generated. Do not manually edit.") - cog.outl("//***************************************************************************") cog.outl("") ################################################ # The first definition for all of the messages. @@ -167,21 +227,94 @@ namespace etl if n % 4 == 0: cog.outl("") cog.out(" ") - cog.outl("typename T%s = void>" % Handlers) + cog.outl("typename T%s = void>" % int(Handlers)) cog.out("class message_router") cog.outl(" : public imessage_router") cog.outl("{") cog.outl("public:") cog.outl("") + cog.outl(" //**********************************************") + cog.outl(" class message_packet") + cog.outl(" {") + cog.outl(" public:") + cog.outl("") + cog.outl(" //********************************************") + cog.outl(" explicit message_packet(const etl::imessage& msg)") + cog.outl(" {") + cog.outl(" const size_t id = msg.message_id;") + cog.outl("") + cog.outl(" void* p = data;") + cog.outl("") + cog.outl(" switch (id)") + cog.outl(" {") + for n in range(1, int(Handlers) + 1): + cog.outl(" case T%s::ID: ::new (p) T%s(static_cast(msg)); break;" % (n, n, n)) + cog.outl(" default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break;") + cog.outl(" }") + cog.outl(" }") + cog.outl("") + cog.outl(" //********************************************") + cog.outl(" template ") + cog.outl(" explicit message_packet(const T& msg)") + cog.outl(" {") + cog.out(" STATIC_ASSERT((etl::is_one_of::value), "Unsupported type for this message packet");""" % int(Handlers)) + cog.outl("") + cog.outl(" void* p = data;") + cog.outl(" ::new (p) T(static_cast(msg));") + cog.outl(" }") + cog.outl("") + cog.outl(" //********************************************") + cog.outl(" ~message_packet()") + cog.outl(" {") + cog.outl(" static_cast(data)->~imessage();") + cog.outl(" }") + cog.outl("") + cog.outl(" //********************************************") + cog.outl(" etl::imessage& get()") + cog.outl(" {") + cog.outl(" return *static_cast(data);") + cog.outl(" }") + cog.outl("") + cog.outl(" //********************************************") + cog.outl(" const etl::imessage& get() const") + cog.outl(" {") + cog.outl(" return *static_cast(data);") + cog.outl(" }") + cog.outl("") + cog.outl(" enum") + cog.outl(" {") + cog.out(" SIZE = etl::largest<") + for n in range(1, int(Handlers)): + cog.out("T%s, " % n) + cog.outl("T%s>::size," % int(Handlers)) + cog.out(" ALIGNMENT = etl::largest<") + for n in range(1, int(Handlers)): + cog.out("T%s, " % n) + cog.outl("T%s>::alignment" % int(Handlers)) + cog.outl(" };") + cog.outl("") + cog.outl(" private:") + cog.outl("") + cog.outl(" typename etl::aligned_storage::type data;") + cog.outl(" };") + cog.outl("") + cog.outl(" //**********************************************") cog.outl(" void receive(const etl::imessage& msg)") cog.outl(" {") cog.outl(" etl::null_message_router nmr;") cog.outl(" receive(nmr, msg);") cog.outl(" }") cog.outl("") + cog.outl(" //**********************************************") cog.outl(" void receive(etl::imessage_router& source, const etl::imessage& msg)") cog.outl(" {") - cog.outl(" const etl::message_id_t id = msg.get_message_id();") + cog.outl(" const etl::message_id_t id = msg.message_id;") cog.outl("") cog.outl(" switch (id)") cog.outl(" {") @@ -195,6 +328,9 @@ namespace etl cog.outl(" }") cog.outl(" }") cog.outl("") + cog.outl(" using imessage_router::accepts;") + cog.outl("") + cog.outl(" //**********************************************") cog.outl(" bool accepts(etl::message_id_t id) const") cog.outl(" {") cog.outl(" switch (id)") @@ -247,15 +383,88 @@ namespace etl cog.outl("{") cog.outl("public:") cog.outl("") + cog.outl(" //**********************************************") + cog.outl(" class message_packet") + cog.outl(" {") + cog.outl(" public:") + cog.outl("") + cog.outl(" //********************************************") + cog.outl(" explicit message_packet(const etl::imessage& msg)") + cog.outl(" {") + cog.outl(" const size_t id = msg.message_id;") + cog.outl("") + cog.outl(" void* p = data;") + cog.outl("") + cog.outl(" switch (id)") + cog.outl(" {") + for t in range(1, n + 1): + cog.outl(" case T%s::ID: ::new (p) T%s(static_cast(msg)); break;" % (t, t, t)) + cog.outl(" default: ETL_ASSERT(false, ETL_ERROR(unhandled_message_exception)); break;") + cog.outl(" }") + cog.outl(" }") + cog.outl("") + cog.outl(" //********************************************") + cog.outl(" template ") + cog.outl(" explicit message_packet(const T& msg)") + cog.outl(" {") + cog.out(" STATIC_ASSERT((etl::is_one_of::value), "Unsupported type for this message packet");""" % n) + cog.outl("") + cog.outl(" void* p = data;") + cog.outl(" ::new (p) T(static_cast(msg));") + cog.outl(" }") + cog.outl("") + cog.outl(" //********************************************") + cog.outl(" ~message_packet()") + cog.outl(" {") + cog.outl(" static_cast(data)->~imessage();") + cog.outl(" }") + cog.outl("") + cog.outl(" //********************************************") + cog.outl(" etl::imessage& get()") + cog.outl(" {") + cog.outl(" return *static_cast(data);") + cog.outl(" }") + cog.outl("") + cog.outl(" //********************************************") + cog.outl(" const etl::imessage& get() const") + cog.outl(" {") + cog.outl(" return *static_cast(data);") + cog.outl(" }") + cog.outl("") + cog.outl(" enum") + cog.outl(" {") + cog.out(" SIZE = etl::largest<") + for t in range(1, n): + cog.out("T%s, " % t) + cog.outl("T%s>::size," % n) + cog.out(" ALIGNMENT = etl::largest<") + for t in range(1, n): + cog.out("T%s, " % t) + cog.outl("T%s>::alignment" % n) + cog.outl(" };") + cog.outl("") + cog.outl(" private:") + cog.outl("") + cog.outl(" typename etl::aligned_storage::type data;") + cog.outl(" };") + cog.outl("") + cog.outl(" //**********************************************") cog.outl(" void receive(const etl::imessage& msg)") cog.outl(" {") cog.outl(" etl::null_message_router nmr;") cog.outl(" receive(nmr, msg);") cog.outl(" }") cog.outl("") + cog.outl(" //**********************************************") cog.outl(" void receive(etl::imessage_router& source, const etl::imessage& msg)") cog.outl(" {") - cog.outl(" const size_t id = msg.get_message_id();") + cog.outl(" const size_t id = msg.message_id;") cog.outl("") cog.outl(" switch (id)") cog.outl(" {") @@ -269,6 +478,9 @@ namespace etl cog.outl(" }") cog.outl(" }") cog.outl("") + cog.outl(" using imessage_router::accepts;") + cog.outl("") + cog.outl(" //**********************************************") cog.outl(" bool accepts(etl::message_id_t id) const") cog.outl(" {") cog.outl(" switch (id)") diff --git a/src/packet.h b/src/packet.h new file mode 100644 index 00000000..ef0e2d79 --- /dev/null +++ b/src/packet.h @@ -0,0 +1,128 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2017 jwellbelove + +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_PACKET__ +#define __ETL_PACKET__ + +#include "platform.h" +#include "static_assert.h" +#include "alignment.h" + +#undef ETL_FILE +#define ETL_FILE "38" + +//***************************************************************************** +///\defgroup packet packet +/// A class that can contain one a several related types. +///\ingroup containers +//***************************************************************************** + +namespace etl +{ + //*************************************************************************** + /// A template class that can store any types derived from TBase that conform + /// to the size and alignment requirements. + ///\ingroup packet + //*************************************************************************** + template + class packet + { + public: + + //*************************************************************************** + /// Constructor that static asserts any types that do not conform to the max size and alignment. + //*************************************************************************** + template + explicit packet(const T& value) + { + STATIC_ASSERT((etl::is_base_of::value), "Unsupported type"); + STATIC_ASSERT(sizeof(T) <= SIZE, "Unsupported size"); + STATIC_ASSERT(etl::alignment_of::value <= ALIGNMENT, "Unsupported alignment"); + + ::new (static_cast(data)) T(value); + } + + //*************************************************************************** + /// Destructor + //*************************************************************************** + ~packet() + { + static_cast(data)->~TBase(); + } + + //*************************************************************************** + /// Assignment operator for type. + ///\param value The value to assign. + //*************************************************************************** + template + packet& operator =(const T& value) + { + STATIC_ASSERT((etl::is_base_of::value), "Unsupported type"); + STATIC_ASSERT(sizeof(T) <= SIZE, "Unsupported size"); + STATIC_ASSERT(etl::alignment_of::value <= ALIGNMENT, "Unsupported alignment"); + + static_cast(data)->~TBase(); + ::new (static_cast(data)) T(value); + + return *this; + } + + //*************************************************************************** + /// Get access to the contained object. + //*************************************************************************** + TBase& get() + { + return *static_cast(data); + } + + //*************************************************************************** + /// Get access to the contained object. + //*************************************************************************** + const TBase& get() const + { + return *static_cast(data); + } + + private: + + packet(const packet& other); + packet& operator =(const packet& other); + + //*************************************************************************** + /// The internal storage. + /// Aligned on a suitable boundary, which should be good for all types. + //*************************************************************************** + typename etl::aligned_storage::type data; + }; +} + +#undef ETL_FILE + +#endif diff --git a/src/scheduler.h b/src/scheduler.h index ee3eee2e..4581444f 100644 --- a/src/scheduler.h +++ b/src/scheduler.h @@ -37,6 +37,7 @@ SOFTWARE. #include "exception.h" #include "task.h" #include "type_traits.h" +#include "function.h" #undef ETL_FILE #define ETL_FILE "36" @@ -63,8 +64,8 @@ namespace etl { public: - scheduler_no_tasks_exception(string_type what, string_type file_name, numeric_type line_number) - : etl::scheduler_exception(ETL_ERROR_TEXT("scheduler:no tasks", ETL_FILE"A"), file_name, line_number)) + scheduler_no_tasks_exception(string_type file_name, numeric_type line_number) + : etl::scheduler_exception(ETL_ERROR_TEXT("scheduler:no tasks", ETL_FILE"A"), file_name, line_number) { } }; @@ -76,70 +77,157 @@ namespace etl { public: - scheduler_null_task_exception(string_type what, string_type file_name, numeric_type line_number) - : etl::scheduler_exception(ETL_ERROR_TEXT("scheduler:null task", ETL_FILE"B"), file_name, line_number)) + scheduler_null_task_exception(string_type file_name, numeric_type line_number) + : etl::scheduler_exception(ETL_ERROR_TEXT("scheduler:null task", ETL_FILE"B"), file_name, line_number) { } }; //*************************************************************************** - /// The policy the scheduler uses to decide what to do next. + /// Sequencial Single. + /// A policy the scheduler can use to decide what to do next. + /// Only calls the task to process work once, if it has work to do. //*************************************************************************** - struct scheduler_policy + struct scheduler_policy_sequencial_single { - enum + bool schedule_tasks(etl::ivector& task_list) { - SEQUENTIAL_SINGLE, - SEQUENTIAL_MULTIPLE, - HIGHEST_PRIORITY - }; + bool idle = true; + + for (size_t index = 0; index < task_list.size(); ++index) + { + etl::task& task = *(task_list[index]); + + if (task.task_request_work() > 0) + { + task.task_process_work(); + idle = false; + } + } + + return idle; + } }; //*************************************************************************** - /// Scheduler. + /// Sequencial Multiple. + /// A policy the scheduler can use to decide what to do next. + /// Calls the task to process work until it reports that it has no more. //*************************************************************************** - template - class scheduler + struct scheduler_policy_sequencial_multiple + { + bool schedule_tasks(etl::ivector& task_list) + { + bool idle = true; + + for (size_t index = 0; index < task_list.size(); ++index) + { + etl::task& task = *(task_list[index]); + + while (task.task_request_work() > 0) + { + task.task_process_work(); + idle = false; + } + } + + return idle; + } + }; + + //*************************************************************************** + /// Highest Priority. + /// A policy the scheduler can use to decide what to do next. + /// Calls the highest priority task that has work. + //*************************************************************************** + struct scheduler_policy_highest_priority + { + bool schedule_tasks(etl::ivector& task_list) + { + bool idle = true; + + size_t index = 0; + while (index < task_list.size()) + { + etl::task& task = *(task_list[index]); + + if (task.task_request_work() > 0) + { + task.task_process_work(); + idle = false; + index = 0; // Restart from the top of the list. + } + else + { + ++index; + } + } + + return idle; + } + }; + + //*************************************************************************** + /// Most Work. + /// A policy the scheduler can use to decide what to do next. + /// Calls the task that has the most work. + /// Starts looking from the task with the highest priority. + //*************************************************************************** + struct scheduler_policy_most_work + { + bool schedule_tasks(etl::ivector& task_list) + { + bool idle = true; + + size_t most_index = 0; + uint_least8_t most_work = 0; + + for (size_t index = 0; index < task_list.size(); ++index) + { + etl::task& task = *(task_list[index]); + + uint_least8_t n_work = task.task_request_work(); + + if (n_work > most_work) + { + most_index = index; + most_work = n_work; + idle = false; + } + } + + if (!idle) + { + task_list[most_index]->task_process_work(); + } + + return idle; + } + }; + + //*************************************************************************** + /// Scheduler base. + //*************************************************************************** + class ischeduler { public: - enum - { - MAX_TASKS = MAX_TASKS_, - POLICY = POLICY_ - }; - //******************************************* - /// Destructor. + /// Constructor. //******************************************* - virtual ~scheduler() + ischeduler() + : scheduler_running(false), + scheduler_exit(false), + p_idle_callback(nullptr) { } //******************************************* - /// Add a task. + /// Set the idle callback. //******************************************* - void add_task(etl::task& task) + void set_idle_callback(etl::ifunction& callback) { - task_list_t::iterator itask = std::lower_bound(task_list.begin(), - task_list.end(), - task.get_task_priority(), - compare_priority()); - - task_list.insert(itask, &task); - } - - //******************************************* - /// Add a task list. - //******************************************* - template - void add_task_list(etl::task** p_tasks, TSize size) - { - for (TSize i = 0; i < size; ++i) - { - ETL_ASSERT((p_tasks[i] != nullptr), ETL_ERROR(etl::scheduler_null_task_exception)); - add_task(*(p_tasks[i]); - } + p_idle_callback = &callback; } //******************************************* @@ -158,11 +246,68 @@ namespace etl return scheduler_running; } + //******************************************* + /// Force the scheduler to exit. + //******************************************* + void exit_scheduler() + { + scheduler_exit = true; + } + + protected: + + bool scheduler_running; + bool scheduler_exit; + etl::ifunction* p_idle_callback; + }; + + //*************************************************************************** + /// Scheduler. + //*************************************************************************** + template + class scheduler : public etl::ischeduler, protected TSchedulerPolicy + { + public: + + enum + { + MAX_TASKS = MAX_TASKS_, + }; + + //******************************************* + /// Add a task. + /// Add to the task list in priority order. + //******************************************* + void add_task(etl::task& task) + { + typename task_list_t::iterator itask = std::lower_bound(task_list.begin(), + task_list.end(), + task.get_task_priority(), + compare_priority()); + + task_list.insert(itask, &task); + } + + //******************************************* + /// Add a task list. + /// Adds to the tasks to the internal task list in priority order. + /// Input order is ignored. + //******************************************* + template + void add_task_list(etl::task** p_tasks, TSize size) + { + for (TSize i = 0; i < size; ++i) + { + ETL_ASSERT((p_tasks[i] != nullptr), ETL_ERROR(etl::scheduler_null_task_exception)); + add_task(*(p_tasks[i])); + } + } + //******************************************* /// Start the scheduler. SEQUENCIAL_SINGLE + /// Only calls the task to process work once, if it has work to do. //******************************************* - etl::enable_if::type - start() + void start() { ETL_ASSERT(task_list.size() > 0, ETL_ERROR(etl::scheduler_no_tasks_exception)); @@ -170,101 +315,15 @@ namespace etl scheduler_running = true; - while (true) + while (!scheduler_exit) { if (scheduler_running) { - bool idle = true; + bool idle = TSchedulerPolicy::schedule_tasks(task_list); - for (size_t index = 0; index < task_list_size; ++index) + if (idle && p_idle_callback) { - etl::task& task = *(task_list[index]); - - if (task.task_request_work()) - { - task.task_process_work(); - idle = false; - } - } - - if (idle) - { - on_scheduler_idle(); - } - } - } - } - - //******************************************* - /// Start the scheduler. SEQUENCIAL_MULTIPLE - //******************************************* - etl::enable_if::type - start() - { - ETL_ASSERT((task_list.size() > 0), ETL_ERROR(etl::scheduler_no_tasks_exception)); - - const size_t task_list_size = task_list.size(); - - scheduler_running = true; - - while (true) - { - if (scheduler_running) - { - bool idle = true; - - for (size_t index = 0; index < task_list_size; ++index) - { - etl::task& task = *(task_list[index]); - - while (task.task_request_work()) - { - task.task_process_work(); - idle = false; - } - } - - if (idle) - { - on_scheduler_idle(); - } - } - } - } - - //******************************************* - /// Start the scheduler. HIGHEST_PRIORITY - //******************************************* - etl::enable_if::type - start() - { - ETL_ASSERT(task_list.size() > 0, ETL_ERROR(etl::scheduler_no_tasks_exception)); - - const size_t task_list_size = task_list.size(); - - scheduler_running = true; - - while (true) - { - if (scheduler_running) - { - bool idle = true; - - for (size_t index = 0; index < task_list_size; ++index) - { - etl::task& task = *(task_list[index]); - - if (task.task_request_work()) - { - task.task_process_work(); - idle = false; - index = 0; // Restart from the top of the list. - } - } - - if (idle) - { - on_scheduler_idle(); + (*p_idle_callback)(); } } } @@ -281,19 +340,10 @@ namespace etl { return ptask->get_task_priority() > priority; } - } - - //******************************************* - /// Called when no work has been done in one cycle. - //******************************************* - virtual void on_scheduler_idle() - { - // By default do nothing. - } + }; typedef etl::vector task_list_t; task_list_t task_list; - bool scheduler_running; }; } diff --git a/src/smallest.h b/src/smallest.h index b9ac9e22..d90ac740 100644 --- a/src/smallest.h +++ b/src/smallest.h @@ -28,6 +28,28 @@ 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. +// +// python -m cogapp -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... +// python -m cogapp -d -e -osmallest.h -DNTypes=16 smallest_generator.h +// +// See generate.bat +//*************************************************************************** + #ifndef __ETL_SMALLEST__ #define __ETL_SMALLEST__ @@ -47,9 +69,9 @@ namespace etl /// Defines 'size' which is the size of the smallest parameter. ///\ingroup smallest //*************************************************************************** - template struct smallest_type { @@ -82,10 +104,10 @@ namespace etl // Set 'type' to be the smallest of the first parameter and any of the others. // This is recursive. - typedef typename choose_type<(sizeof(T1) < sizeof(smallest_other)),// Boolean - T1, // TrueType - smallest_other> // FalseType - ::type type; // The smallest type of the two. + typedef typename choose_type<(sizeof(T1) < sizeof(smallest_other)), // Boolean + T1, // TrueType + smallest_other> // FalseType + ::type type; // The smallest type of the two. // The size of the smallest type. enum @@ -98,10 +120,8 @@ namespace etl // Specialisation for one template parameter. //*************************************************************************** template - struct smallest_type + struct smallest_type { typedef T1 type; diff --git a/src/smallest_generator.h b/src/smallest_generator.h new file mode 100644 index 00000000..6b74bf1c --- /dev/null +++ b/src/smallest_generator.h @@ -0,0 +1,336 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +http://www.etlcpp.com + +Copyright(c) 2014 jwellbelove + +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. +// +// python -m cogapp -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... +// python -m cogapp -d -e -osmallest.h -DNTypes=16 smallest_generator.h +// +// See generate.bat +//*************************************************************************** + +#ifndef __ETL_SMALLEST__ +#define __ETL_SMALLEST__ + +#include + +#include "integral_limits.h" + +///\defgroup smallest smallest +///\ingroup utilities + +namespace etl +{ + /*[[[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]]]*/ + + 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; + }; + + //************************************************************************* + // Greater than 32 bits. + //************************************************************************* + template <> + struct best_fit_uint_type<3> + { + typedef uint_least64_t type; + }; + + //************************************************************************* + // 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; + }; + + //************************************************************************* + // Greater than 32 bits. + //************************************************************************* + template <> + struct best_fit_int_type<3> + { + typedef int_least64_t type; + }; + } + + //*************************************************************************** + /// 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 const 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 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 const 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 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 const 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 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 const int TYPE_INDEX = (((VALUE > INT_LEAST8_MAX) || (VALUE < INT_LEAST8_MIN)) ? 1 : 0) + + (((VALUE > INT16_MAX) || (VALUE < INT16_MIN)) ? 1 : 0) + + (((VALUE > INT32_MAX) || (VALUE < INT32_MIN)) ? 1 : 0); + + public: + + typedef typename __private_smallest__::best_fit_int_type::type type; + }; +} + +#endif diff --git a/src/task.h b/src/task.h index 13d9da05..8e42a051 100644 --- a/src/task.h +++ b/src/task.h @@ -26,8 +26,8 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ -#ifndef __ETL_SCHEDULER__ -#define __ETL_SCHEDULER__ +#ifndef __ETL_TASK__ +#define __ETL_TASK__ #include @@ -52,6 +52,8 @@ namespace etl } }; + typedef uint_least8_t task_priority_t; + //*************************************************************************** /// Scheduler. //*************************************************************************** @@ -59,8 +61,6 @@ namespace etl { public: - typedef uint_least8_t task_priority_t; - //******************************************* /// Constructor. //******************************************* @@ -78,13 +78,10 @@ namespace etl } //******************************************* - /// Returns 'true' if the task has work to do - /// and is in the running state. + /// Called to check if the task has work. + /// Returns a score as to the amount of work it has to do. //******************************************* - bool task_request_work() const - { - return (task_running && task_has_work()); - } + virtual uint_least8_t task_request_work() const = 0; //******************************************* /// Called to get the task to do work. @@ -118,10 +115,8 @@ namespace etl private: - bool task_has_work() const = 0; - bool task_running; - uint_least8_t task_priority; + etl::task_priority_t task_priority; }; } diff --git a/src/type_traits.h b/src/type_traits.h index 5c9876a5..4cce9267 100644 --- a/src/type_traits.h +++ b/src/type_traits.h @@ -28,6 +28,24 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ +//*************************************************************************** +// 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. +// +// python -m cogapp -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... +// python -m cogapp -d -e -otype_traits.h -DIsOneOf=16 type_traits_generator.h +// +// See generate.bat +//*************************************************************************** + #ifndef __ETL_TYPE_TRAITS__ #define __ETL_TYPE_TRAITS__ @@ -152,7 +170,6 @@ namespace etl template struct is_integral : is_integral {}; template struct is_integral : is_integral {}; - /// is_signed ///\ingroup type_traits template struct is_signed : false_type {}; @@ -237,15 +254,15 @@ namespace etl template struct is_reference : true_type {}; /// is_pod + /// For C++03, only fundamental and pointers types are recognised. ///\ingroup type_traits - #if defined(ETL_C11_TYPE_TRAITS_SUPPORTED)// && !defined(ETL_IN_UNIT_TEST) // For compilers that support C++11 template struct is_pod : std::is_pod {}; #else /// For C++03, only fundamental and pointers types are recognised. template struct is_pod : etl::integral_constant::value || - etl::is_pointer::value> {}; + etl::is_pointer::value> {}; #endif #if defined(ETL_C11_TYPE_TRAITS_SUPPORTED) && defined(ETL_C11_TYPE_TRAITS_IS_TRIVIAL_SUPPORTED)// && !defined(ETL_IN_UNIT_TEST) @@ -290,6 +307,7 @@ namespace etl template struct is_trivially_copy_assignable : etl::is_pod {}; #endif + /// conditional ///\ingroup type_traits template struct conditional { typedef T type; }; @@ -392,29 +410,80 @@ namespace etl typename etl::remove_cv::type>::type type; }; + /// is_base_of + ///\ingroup type_traits + template + struct is_base_of + { + private: + + template struct dummy {}; + struct internal: TDerived, dummy{}; + + static TBase* check(TBase*); + template static char check(dummy*); + + public: + + static const bool value = (sizeof(check((internal*)0)) == sizeof(TBase*)); + }; + /// Alignment templates. /// These require compiler specific intrinsics. ///\ingroup type_traits -#if defined(ETL_C11_ALIGNOF_SUPPORTED) - template struct alignment_of : integral_constant {}; -#elif defined(ETL_COMPILER_MICROSOFT) +#ifdef ETL_COMPILER_MICROSOFT template struct alignment_of : integral_constant {}; -#elif defined(ETL_COMPILER_GCC) +#endif + +#ifdef ETL_COMPILER_GCC template struct alignment_of : integral_constant {}; -#elif defined(ETL_COMPILER_KEIL) +#endif + +#ifdef ETL_COMPILER_KEIL template struct alignment_of : integral_constant {}; -#elif defined(ETL_COMPILER_IAR) +#endif + +#ifdef ETL_COMPILER_IAR template struct alignment_of : integral_constant {}; -#elif defined(ETL_COMPILER_TI) +#endif + +#ifdef ETL_COMPILER_TI template struct alignment_of : integral_constant {}; -#else - // Best guess! - template struct alignment_of : integral_constant {}; #endif /// Specialisation of 'alignment_of' for 'void'. ///\ingroup type_traits template <> struct alignment_of : integral_constant {}; + + //*************************************************************************** + /// Template to determine if a type is one of a specified list. + ///\ingroup types + //*************************************************************************** + template + struct is_one_of + { + static const bool value = + etl::is_same::value || + etl::is_same::value || + etl::is_same::value || + etl::is_same::value || + etl::is_same::value || + etl::is_same::value || + etl::is_same::value || + etl::is_same::value || + etl::is_same::value || + etl::is_same::value || + etl::is_same::value || + etl::is_same::value || + etl::is_same::value || + etl::is_same::value || + etl::is_same::value || + etl::is_same::value; + }; } #endif diff --git a/src/type_traits_generator.h b/src/type_traits_generator.h new file mode 100644 index 00000000..56cd91cd --- /dev/null +++ b/src/type_traits_generator.h @@ -0,0 +1,500 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +http://www.etlcpp.com + +Copyright(c) 2014 jwellbelove + +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. +// +// python -m cogapp -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... +// python -m cogapp -d -e -otype_traits.h -DIsOneOf=16 type_traits_generator.h +// +// See generate.bat +//*************************************************************************** + +#ifndef __ETL_TYPE_TRAITS__ +#define __ETL_TYPE_TRAITS__ + +#include + +#include "platform.h" +#include "nullptr.h" + +#if defined(ETL_C11_TYPE_TRAITS_SUPPORTED) + #include +#endif + +///\defgroup type_traits type_traits +/// A set of type traits definitions for compilers that do not support the standard header. +/// \ingroup utilities + +namespace etl +{ + /// integral_constant + ///\ingroup type_traits + 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 + ///\ingroup type_traits + typedef integral_constant false_type; + typedef integral_constant true_type; + + /// remove_reference + ///\ingroup type_traits + template struct remove_reference { typedef T type; }; + template struct remove_reference { typedef T type; }; + + /// add_reference + ///\ingroup type_traits + template struct add_reference { typedef T& type; }; + template struct add_reference { typedef T& type; }; + + /// remove_pointer + ///\ingroup type_traits + template struct remove_pointer { typedef T type; }; + template struct remove_pointer { typedef T type; }; + + /// add_pointer + ///\ingroup type_traits + template struct add_pointer { typedef typename remove_reference::type* type; }; + + /// is_const + ///\ingroup type_traits + template struct is_const : false_type {}; + template struct is_const : true_type {}; + template struct is_const : true_type {}; + + /// remove_const + ///\ingroup type_traits + template struct remove_const { typedef T type; }; + template struct remove_const { typedef T type; }; + + /// add_const + ///\ingroup type_traits + template struct add_const { typedef const T type; }; + template struct add_const { typedef const T type; }; + + /// is_volatile + ///\ingroup type_traits + template struct is_volatile : false_type {}; + template struct is_volatile : true_type {}; + template struct is_volatile : true_type {}; + + /// remove_volatile + ///\ingroup type_traits + template struct remove_volatile { typedef T type; }; + template struct remove_volatile { typedef T type; }; + + /// add_volatile + ///\ingroup type_traits + template struct add_volatile { typedef volatile T type; }; + template struct add_volatile { typedef volatile T type; }; + + /// remove_cv + ///\ingroup type_traits + template struct remove_cv + { + typedef typename remove_volatile::type>::type type; + }; + + /// add_cv + ///\ingroup type_traits + template struct add_cv + { + typedef typename add_volatile::type>::type type; + }; + + /// is_integral + ///\ingroup type_traits + 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 {}; + template struct is_integral : is_integral {}; + template struct is_integral : is_integral {}; + template struct is_integral : is_integral {}; + + /// is_signed + ///\ingroup type_traits + template struct is_signed : false_type {}; + template <> struct is_signed : integral_constant {}; + template <> struct is_signed : public etl::integral_constant(wchar_t(-1) < wchar_t(0))> {}; + 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{}; + template struct is_signed : is_signed {}; + template struct is_signed : is_signed {}; + template struct is_signed : is_signed {}; + + /// is_unsigned + ///\ingroup type_traits + template struct is_unsigned : false_type {}; + template <> struct is_unsigned : true_type {}; + template <> struct is_unsigned : integral_constant 0)> {}; + template <> struct is_unsigned : true_type {}; + template <> struct is_unsigned : public etl::integral_constant 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 {}; + + /// is_floating_point + ///\ingroup type_traits + 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 {}; + + /// is_same + ///\ingroup type_traits + template struct is_same : public false_type {}; + template struct is_same : public true_type {}; + + /// is_void + ///\ingroup type_traits + template struct is_void : false_type {}; + template<> struct is_void : true_type {}; + + /// is_arithmetic + ///\ingroup type_traits + template struct is_arithmetic : integral_constant::value || is_floating_point::value> {}; + + /// is_fundamental + ///\ingroup type_traits + template struct is_fundamental : integral_constant::value || + is_void::value || + is_same::type>::value> {}; + + /// is_compound + ///\ingroup type_traits + template struct is_compound : integral_constant::value> {}; + + /// is_array + ///\ingroup type_traits + template struct is_array : false_type {}; + template struct is_array : true_type {}; + template struct is_array : true_type {}; + + /// is_pointer + ///\ingroup type_traits + template struct is_pointer : false_type {}; + template struct is_pointer : true_type {}; + + /// is_reference + ///\ingroup type_traits + template struct is_reference : false_type {}; + template struct is_reference : true_type {}; + + /// is_pod + /// For C++03, only fundamental and pointers types are recognised. + ///\ingroup type_traits +#if defined(ETL_C11_TYPE_TRAITS_SUPPORTED)// && !defined(ETL_IN_UNIT_TEST) + // For compilers that support C++11 + template struct is_pod : std::is_pod {}; +#else + /// For C++03, only fundamental and pointers types are recognised. + template struct is_pod : etl::integral_constant::value || + etl::is_pointer::value> {}; +#endif + +#if defined(ETL_C11_TYPE_TRAITS_SUPPORTED) && defined(ETL_C11_TYPE_TRAITS_IS_TRIVIAL_SUPPORTED)// && !defined(ETL_IN_UNIT_TEST) + /// is_trivially_constructible + /// For C++03, only POD types are recognised. + ///\ingroup type_traits + template struct is_trivially_constructible : std::is_trivially_constructible {}; + + /// is_trivially_copy_constructible + /// For C++03, only POD types are recognised. + ///\ingroup type_traits + template struct is_trivially_copy_constructible : std::is_trivially_copy_constructible {}; + + /// is_trivially_destructible + /// For C++03, only POD types are recognised. + ///\ingroup type_traits + template struct is_trivially_destructible : std::is_trivially_destructible {}; + + /// is_trivially_copy_assignable + /// For C++03, only POD types are recognised. + ///\ingroup type_traits + template struct is_trivially_copy_assignable : std::is_trivially_copy_assignable {}; +#else + /// is_trivially_constructible + /// For C++03, only POD types are recognised. + ///\ingroup type_traits + template struct is_trivially_constructible : etl::is_pod {}; + + /// is_trivially_copy_constructible + /// For C++03, only POD types are recognised. + ///\ingroup type_traits + template struct is_trivially_copy_constructible : etl::is_pod {}; + + /// is_trivially_destructible + /// For C++03, only POD types are recognised. + ///\ingroup type_traits + template struct is_trivially_destructible : etl::is_pod {}; + + /// is_trivially_copy_assignable + /// For C++03, only POD types are recognised. + ///\ingroup type_traits + template struct is_trivially_copy_assignable : etl::is_pod {}; +#endif + + + /// conditional + ///\ingroup type_traits + template struct conditional { typedef T type; }; + template struct conditional { typedef F type; }; + + /// make_signed + ///\ingroup type_traits + 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> {}; + + /// make_unsigned + ///\ingroup type_traits + 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> {}; + + /// enable_if + ///\ingroup type_traits + template struct enable_if {}; + template struct enable_if { typedef T type; }; + + /// extent + ///\ingroup type_traits + 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> {}; + + /// remove_extent + ///\ingroup type_traits + template struct remove_extent { typedef T type; }; + template struct remove_extent { typedef T type; }; + template struct remove_extent { typedef T type;}; + + /// remove_all_extents + ///\ingroup type_traits + 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; }; + + /// rank + ///\ingroup type_traits + template struct rank : integral_constant {}; + template struct rank : public integral_constant::value + 1> {}; + template struct rank : public integral_constant::value + 1> {}; + + /// decay + ///\ingroup type_traits + 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; + }; + + /// is_base_of + ///\ingroup type_traits + template + struct is_base_of + { + private: + + template struct dummy {}; + struct internal: TDerived, dummy{}; + + static TBase* check(TBase*); + template static char check(dummy*); + + public: + + static const bool value = (sizeof(check((internal*)0)) == sizeof(TBase*)); + }; + + /// Alignment templates. + /// These require compiler specific intrinsics. + ///\ingroup type_traits +#ifdef ETL_COMPILER_MICROSOFT + template struct alignment_of : integral_constant {}; +#endif + +#ifdef ETL_COMPILER_GCC + template struct alignment_of : integral_constant {}; +#endif + +#ifdef ETL_COMPILER_KEIL + template struct alignment_of : integral_constant {}; +#endif + +#ifdef ETL_COMPILER_IAR + template struct alignment_of : integral_constant {}; +#endif + +#ifdef ETL_COMPILER_TI + template struct alignment_of : integral_constant {}; +#endif + + /// Specialisation of 'alignment_of' for 'void'. + ///\ingroup type_traits + template <> struct alignment_of : integral_constant {}; + + /*[[[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("//***************************************************************************") + 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 diff --git a/src/variant.h b/src/variant.h index 6b2931eb..0d57a4a4 100644 --- a/src/variant.h +++ b/src/variant.h @@ -5,7 +5,7 @@ The MIT License(MIT) Embedded Template Library. https://github.com/ETLCPP/etl -http://www.etlcpp.com +https://www.etlcpp.com Copyright(c) 2014 jwellbelove @@ -42,7 +42,6 @@ SOFTWARE. #include "static_assert.h" #include "alignment.h" #include "error_handler.h" -#include "largest.h" #if defined(ETL_COMPILER_KEIL) #pragma diag_suppress 940 @@ -124,6 +123,11 @@ namespace etl //*************************************************************************** typedef typename largest_type::type largest_t; + //*************************************************************************** + /// The largest size. + //*************************************************************************** + static const size_t SIZE = sizeof(largest_t); + //*************************************************************************** /// The largest alignment. //*************************************************************************** @@ -139,46 +143,6 @@ namespace etl //*************************************************************************** static const type_id_t UNSUPPORTED_TYPE_ID = integral_limits::max; - //*************************************************************************** - /// Do we pass this type by value? - //*************************************************************************** - template - struct pass_by_value : integral_constant::value || etl::is_pointer::value> - { - }; - - //*************************************************************************** - /// Define the type for a parameter. - //*************************************************************************** - template - struct type_definition; - - //*************************************************************************** - /// Pass by value. - //*************************************************************************** - template - struct type_definition - { - typedef T type; - }; - - //*************************************************************************** - /// Pass by const reference. - //*************************************************************************** - template - struct type_definition - { - typedef const T& type; - }; - - //*************************************************************************** - /// Determines the type for parameters. - //*************************************************************************** - template - struct parameter_type : public type_definition::value> - { - }; - //*************************************************************************** /// Short form of no_type placeholders. //*************************************************************************** @@ -249,14 +213,14 @@ namespace etl friend class variant; - virtual void read(typename parameter_type::type value) = 0; - virtual void read(typename parameter_type::type value) = 0; - virtual void read(typename parameter_type::type value) = 0; - virtual void read(typename parameter_type::type value) = 0; - virtual void read(typename parameter_type::type value) = 0; - virtual void read(typename parameter_type::type value) = 0; - virtual void read(typename parameter_type::type value) = 0; - virtual void read(typename parameter_type::type value) = 0; + virtual void read(typename etl::parameter_type::type value) = 0; + virtual void read(typename etl::parameter_type::type value) = 0; + virtual void read(typename etl::parameter_type::type value) = 0; + virtual void read(typename etl::parameter_type::type value) = 0; + virtual void read(typename etl::parameter_type::type value) = 0; + virtual void read(typename etl::parameter_type::type value) = 0; + virtual void read(typename etl::parameter_type::type value) = 0; + virtual void read(typename etl::parameter_type::type value) = 0; }; //************************************************************************* @@ -269,13 +233,13 @@ namespace etl friend class variant; - virtual void read(typename parameter_type::type value) = 0; - virtual void read(typename parameter_type::type value) = 0; - virtual void read(typename parameter_type::type value) = 0; - virtual void read(typename parameter_type::type value) = 0; - virtual void read(typename parameter_type::type value) = 0; - virtual void read(typename parameter_type::type value) = 0; - virtual void read(typename parameter_type::type value) = 0; + virtual void read(typename etl::parameter_type::type value) = 0; + virtual void read(typename etl::parameter_type::type value) = 0; + virtual void read(typename etl::parameter_type::type value) = 0; + virtual void read(typename etl::parameter_type::type value) = 0; + virtual void read(typename etl::parameter_type::type value) = 0; + virtual void read(typename etl::parameter_type::type value) = 0; + virtual void read(typename etl::parameter_type::type value) = 0; private: @@ -292,12 +256,12 @@ namespace etl friend class variant; - virtual void read(typename parameter_type::type value) = 0; - virtual void read(typename parameter_type::type value) = 0; - virtual void read(typename parameter_type::type value) = 0; - virtual void read(typename parameter_type::type value) = 0; - virtual void read(typename parameter_type::type value) = 0; - virtual void read(typename parameter_type::type value) = 0; + virtual void read(typename etl::parameter_type::type value) = 0; + virtual void read(typename etl::parameter_type::type value) = 0; + virtual void read(typename etl::parameter_type::type value) = 0; + virtual void read(typename etl::parameter_type::type value) = 0; + virtual void read(typename etl::parameter_type::type value) = 0; + virtual void read(typename etl::parameter_type::type value) = 0; private: @@ -315,11 +279,11 @@ namespace etl friend class variant; - virtual void read(typename parameter_type::type value) = 0; - virtual void read(typename parameter_type::type value) = 0; - virtual void read(typename parameter_type::type value) = 0; - virtual void read(typename parameter_type::type value) = 0; - virtual void read(typename parameter_type::type value) = 0; + virtual void read(typename etl::parameter_type::type value) = 0; + virtual void read(typename etl::parameter_type::type value) = 0; + virtual void read(typename etl::parameter_type::type value) = 0; + virtual void read(typename etl::parameter_type::type value) = 0; + virtual void read(typename etl::parameter_type::type value) = 0; private: @@ -338,10 +302,10 @@ namespace etl friend class variant; - virtual void read(typename parameter_type::type value) = 0; - virtual void read(typename parameter_type::type value) = 0; - virtual void read(typename parameter_type::type value) = 0; - virtual void read(typename parameter_type::type value) = 0; + virtual void read(typename etl::parameter_type::type value) = 0; + virtual void read(typename etl::parameter_type::type value) = 0; + virtual void read(typename etl::parameter_type::type value) = 0; + virtual void read(typename etl::parameter_type::type value) = 0; private: @@ -361,9 +325,9 @@ namespace etl friend class variant; - virtual void read(typename parameter_type::type value) = 0; - virtual void read(typename parameter_type::type value) = 0; - virtual void read(typename parameter_type::type value) = 0; + virtual void read(typename etl::parameter_type::type value) = 0; + virtual void read(typename etl::parameter_type::type value) = 0; + virtual void read(typename etl::parameter_type::type value) = 0; private: @@ -384,8 +348,8 @@ namespace etl friend class variant; - virtual void read(typename parameter_type::type value) = 0; - virtual void read(typename parameter_type::type value) = 0; + virtual void read(typename etl::parameter_type::type value) = 0; + virtual void read(typename etl::parameter_type::type value) = 0; private: @@ -407,7 +371,7 @@ namespace etl friend class variant; - virtual void read(typename parameter_type::type value) = 0; + virtual void read(typename etl::parameter_type::type value) = 0; private: @@ -862,7 +826,7 @@ namespace etl //*************************************************************************** void clear() { - type_id = UNSUPPORTED_TYPE_ID; + destruct_current(); } //*************************************************************************** @@ -962,7 +926,7 @@ namespace etl /// The internal storage. /// Aligned on a suitable boundary, which should be good for all types. //*************************************************************************** - typename etl::aligned_storage::value>::type data; + typename etl::aligned_storage::type data; //*************************************************************************** /// The id of the current stored type. diff --git a/temp/message_router.h b/temp/message_router.h new file mode 100644 index 00000000..85d95fe0 --- /dev/null +++ b/temp/message_router.h @@ -0,0 +1,984 @@ +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +http://www.etlcpp.com + +Copyright(c) 2017 jwellbelove + +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_MESSAGE_ROUTER__ +#define __ETL_MESSAGE_ROUTER__ + +#include + +namespace etl +{ + /// Allow alternative type for message id. +#if !defined(ETL_MESSAGE_ID_TYPE) + typedef uint_least8_t message_id_t; +#else + typedef ETL_MESSAGE_ID_TYPE message_id_t; +#endif + + //*************************************************************************** + class imessage + { + public: + + virtual ~imessage() {} + virtual etl::message_id_t get_message_id() const = 0; + }; + + //*************************************************************************** + template + class message : public imessage + { + public: + + enum + { + ID = ID_ + }; + + //******************************************* + etl::message_id_t get_message_id() const + { + return etl::message_id_t(ID); + } + }; + + //*************************************************************************** + class imessage_router + { + public: + + virtual ~imessage_router() {} + virtual void receive(const etl::imessage& message) = 0; + virtual void receive(imessage_router& source, const etl::imessage& message) = 0; + virtual bool accepts(etl::message_id_t id) const = 0; + + //******************************************* + bool accepts(const etl::imessage& msg) const + { + return accepts(msg.get_message_id()); + } + + //******************************************* + void send_message(imessage_router& destination, + const etl::imessage& message) + { + destination.receive(*this, message); + } + }; + + //*************************************************************************** + /// This router can be used either as a sink for messages + /// or as a producer-only of messages such an interrupt routine. + //*************************************************************************** + class null_message_router : public imessage_router + { + public: + + //******************************************* + void receive(const etl::imessage& message) + { + } + + //******************************************* + void receive(etl::imessage_router& source, const etl::imessage& message) + { + } + + //******************************************* + bool accepts(etl::message_id_t id) const + { + return false; + } + + //******************************************* + static null_message_router& get() + { + static null_message_router instance; + return instance; + } + }; + + //*************************************************************************** + /// Send a message to a router. + /// Sets the 'sender' to etl::null_message_router type. + //*************************************************************************** + inline static void send_message(etl::imessage_router& destination, + const etl::imessage& message) + { + destination.receive(message); + } + + //*************************************************************************** + /// Send a message to a router. + //*************************************************************************** + inline static void send_message(etl::imessage_router& source, + etl::imessage_router& destination, + const etl::imessage& message) + { + destination.receive(source, message); + } + + //*************************************************************************** + // To generate to header file, run this at the command line. + // Note: You will need Python and COG installed. + // + // python -m cogapp -d -e -omessage_router.h -DHandlers= message_router_generator.h + // Where is the number of messages to support. + // + // e.g. + // To generate handlers for up to 16 messages... + // python -m cogapp -d -e -omessage_router.h -DHandlers=16 message_router_generator.h + // + // See CreateMessageProcessor.bat + //*************************************************************************** + + //*************************************************************************** + // The code below has been auto generated. Do not manually edit. + //*************************************************************************** + + //*************************************************************************** + // The definition for all 16 message types. + //*************************************************************************** + template + class message_router : public imessage_router + { + public: + + void receive(const etl::imessage& msg) + { + receive(etl::null_message_router::get(), msg); + } + + void receive(etl::imessage_router& source, const etl::imessage& msg) + { + const etl::message_id_t id = msg.get_message_id(); + + switch (id) + { + case T1::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T2::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T3::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T4::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T5::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T6::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T7::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T8::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T9::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T10::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T11::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T12::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T13::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T14::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T15::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T16::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + default: static_cast(this)->on_receive_unknown(source, msg); break; + } + } + + bool accepts(etl::message_id_t id) const + { + switch (id) + { + case T1::ID: case T2::ID: case T3::ID: case T4::ID: case T5::ID: case T6::ID: case T7::ID: case T8::ID: + case T9::ID: case T10::ID: case T11::ID: case T12::ID: case T13::ID: case T14::ID: case T15::ID: case T16::ID: + return true; break; + default: + return false; break; + } + } + }; + + //*************************************************************************** + // Specialisation for 15 message types. + //*************************************************************************** + template + class message_router + : public imessage_router + { + public: + + void receive(const etl::imessage& msg) + { + receive(etl::null_message_router::get(), msg); + } + + void receive(etl::imessage_router& source, const etl::imessage& msg) + { + const size_t id = msg.get_message_id(); + + switch (id) + { + case T1::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T2::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T3::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T4::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T5::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T6::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T7::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T8::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T9::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T10::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T11::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T12::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T13::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T14::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T15::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + default: static_cast(this)->on_receive_unknown(source, msg); break; + } + } + + bool accepts(etl::message_id_t id) const + { + switch (id) + { + case T1::ID: case T2::ID: case T3::ID: case T4::ID: case T5::ID: case T6::ID: case T7::ID: case T8::ID: + case T9::ID: case T10::ID: case T11::ID: case T12::ID: case T13::ID: case T14::ID: case T15::ID: + return true; break; + default: + return false; break; + } + } + }; + + //*************************************************************************** + // Specialisation for 14 message types. + //*************************************************************************** + template + class message_router + : public imessage_router + { + public: + + void receive(const etl::imessage& msg) + { + receive(etl::null_message_router::get(), msg); + } + + void receive(etl::imessage_router& source, const etl::imessage& msg) + { + const size_t id = msg.get_message_id(); + + switch (id) + { + case T1::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T2::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T3::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T4::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T5::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T6::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T7::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T8::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T9::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T10::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T11::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T12::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T13::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T14::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + default: static_cast(this)->on_receive_unknown(source, msg); break; + } + } + + bool accepts(etl::message_id_t id) const + { + switch (id) + { + case T1::ID: case T2::ID: case T3::ID: case T4::ID: case T5::ID: case T6::ID: case T7::ID: case T8::ID: + case T9::ID: case T10::ID: case T11::ID: case T12::ID: case T13::ID: case T14::ID: + return true; break; + default: + return false; break; + } + } + }; + + //*************************************************************************** + // Specialisation for 13 message types. + //*************************************************************************** + template + class message_router + : public imessage_router + { + public: + + void receive(const etl::imessage& msg) + { + receive(etl::null_message_router::get(), msg); + } + + void receive(etl::imessage_router& source, const etl::imessage& msg) + { + const size_t id = msg.get_message_id(); + + switch (id) + { + case T1::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T2::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T3::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T4::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T5::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T6::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T7::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T8::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T9::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T10::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T11::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T12::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T13::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + default: static_cast(this)->on_receive_unknown(source, msg); break; + } + } + + bool accepts(etl::message_id_t id) const + { + switch (id) + { + case T1::ID: case T2::ID: case T3::ID: case T4::ID: case T5::ID: case T6::ID: case T7::ID: case T8::ID: + case T9::ID: case T10::ID: case T11::ID: case T12::ID: case T13::ID: + return true; break; + default: + return false; break; + } + } + }; + + //*************************************************************************** + // Specialisation for 12 message types. + //*************************************************************************** + template + class message_router + : public imessage_router + { + public: + + void receive(const etl::imessage& msg) + { + receive(etl::null_message_router::get(), msg); + } + + void receive(etl::imessage_router& source, const etl::imessage& msg) + { + const size_t id = msg.get_message_id(); + + switch (id) + { + case T1::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T2::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T3::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T4::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T5::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T6::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T7::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T8::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T9::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T10::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T11::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T12::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + default: static_cast(this)->on_receive_unknown(source, msg); break; + } + } + + bool accepts(etl::message_id_t id) const + { + switch (id) + { + case T1::ID: case T2::ID: case T3::ID: case T4::ID: case T5::ID: case T6::ID: case T7::ID: case T8::ID: + case T9::ID: case T10::ID: case T11::ID: case T12::ID: + return true; break; + default: + return false; break; + } + } + }; + + //*************************************************************************** + // Specialisation for 11 message types. + //*************************************************************************** + template + class message_router + : public imessage_router + { + public: + + void receive(const etl::imessage& msg) + { + receive(etl::null_message_router::get(), msg); + } + + void receive(etl::imessage_router& source, const etl::imessage& msg) + { + const size_t id = msg.get_message_id(); + + switch (id) + { + case T1::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T2::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T3::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T4::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T5::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T6::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T7::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T8::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T9::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T10::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T11::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + default: static_cast(this)->on_receive_unknown(source, msg); break; + } + } + + bool accepts(etl::message_id_t id) const + { + switch (id) + { + case T1::ID: case T2::ID: case T3::ID: case T4::ID: case T5::ID: case T6::ID: case T7::ID: case T8::ID: + case T9::ID: case T10::ID: case T11::ID: + return true; break; + default: + return false; break; + } + } + }; + + //*************************************************************************** + // Specialisation for 10 message types. + //*************************************************************************** + template + class message_router + : public imessage_router + { + public: + + void receive(const etl::imessage& msg) + { + receive(etl::null_message_router::get(), msg); + } + + void receive(etl::imessage_router& source, const etl::imessage& msg) + { + const size_t id = msg.get_message_id(); + + switch (id) + { + case T1::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T2::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T3::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T4::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T5::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T6::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T7::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T8::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T9::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T10::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + default: static_cast(this)->on_receive_unknown(source, msg); break; + } + } + + bool accepts(etl::message_id_t id) const + { + switch (id) + { + case T1::ID: case T2::ID: case T3::ID: case T4::ID: case T5::ID: case T6::ID: case T7::ID: case T8::ID: + case T9::ID: case T10::ID: + return true; break; + default: + return false; break; + } + } + }; + + //*************************************************************************** + // Specialisation for 9 message types. + //*************************************************************************** + template + class message_router + : public imessage_router + { + public: + + void receive(const etl::imessage& msg) + { + receive(etl::null_message_router::get(), msg); + } + + void receive(etl::imessage_router& source, const etl::imessage& msg) + { + const size_t id = msg.get_message_id(); + + switch (id) + { + case T1::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T2::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T3::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T4::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T5::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T6::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T7::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T8::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T9::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + default: static_cast(this)->on_receive_unknown(source, msg); break; + } + } + + bool accepts(etl::message_id_t id) const + { + switch (id) + { + case T1::ID: case T2::ID: case T3::ID: case T4::ID: case T5::ID: case T6::ID: case T7::ID: case T8::ID: + case T9::ID: + return true; break; + default: + return false; break; + } + } + }; + + //*************************************************************************** + // Specialisation for 8 message types. + //*************************************************************************** + template + class message_router + : public imessage_router + { + public: + + void receive(const etl::imessage& msg) + { + receive(etl::null_message_router::get(), msg); + } + + void receive(etl::imessage_router& source, const etl::imessage& msg) + { + const size_t id = msg.get_message_id(); + + switch (id) + { + case T1::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T2::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T3::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T4::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T5::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T6::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T7::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T8::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + default: static_cast(this)->on_receive_unknown(source, msg); break; + } + } + + bool accepts(etl::message_id_t id) const + { + switch (id) + { + case T1::ID: case T2::ID: case T3::ID: case T4::ID: case T5::ID: case T6::ID: case T7::ID: case T8::ID: + + return true; break; + default: + return false; break; + } + } + }; + + //*************************************************************************** + // Specialisation for 7 message types. + //*************************************************************************** + template + class message_router + : public imessage_router + { + public: + + void receive(const etl::imessage& msg) + { + receive(etl::null_message_router::get(), msg); + } + + void receive(etl::imessage_router& source, const etl::imessage& msg) + { + const size_t id = msg.get_message_id(); + + switch (id) + { + case T1::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T2::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T3::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T4::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T5::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T6::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T7::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + default: static_cast(this)->on_receive_unknown(source, msg); break; + } + } + + bool accepts(etl::message_id_t id) const + { + switch (id) + { + case T1::ID: case T2::ID: case T3::ID: case T4::ID: case T5::ID: case T6::ID: case T7::ID: + return true; break; + default: + return false; break; + } + } + }; + + //*************************************************************************** + // Specialisation for 6 message types. + //*************************************************************************** + template + class message_router + : public imessage_router + { + public: + + void receive(const etl::imessage& msg) + { + receive(etl::null_message_router::get(), msg); + } + + void receive(etl::imessage_router& source, const etl::imessage& msg) + { + const size_t id = msg.get_message_id(); + + switch (id) + { + case T1::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T2::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T3::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T4::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T5::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T6::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + default: static_cast(this)->on_receive_unknown(source, msg); break; + } + } + + bool accepts(etl::message_id_t id) const + { + switch (id) + { + case T1::ID: case T2::ID: case T3::ID: case T4::ID: case T5::ID: case T6::ID: + return true; break; + default: + return false; break; + } + } + }; + + //*************************************************************************** + // Specialisation for 5 message types. + //*************************************************************************** + template + class message_router + : public imessage_router + { + public: + + void receive(const etl::imessage& msg) + { + receive(etl::null_message_router::get(), msg); + } + + void receive(etl::imessage_router& source, const etl::imessage& msg) + { + const size_t id = msg.get_message_id(); + + switch (id) + { + case T1::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T2::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T3::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T4::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T5::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + default: static_cast(this)->on_receive_unknown(source, msg); break; + } + } + + bool accepts(etl::message_id_t id) const + { + switch (id) + { + case T1::ID: case T2::ID: case T3::ID: case T4::ID: case T5::ID: + return true; break; + default: + return false; break; + } + } + }; + + //*************************************************************************** + // Specialisation for 4 message types. + //*************************************************************************** + template + class message_router + : public imessage_router + { + public: + + void receive(const etl::imessage& msg) + { + receive(etl::null_message_router::get(), msg); + } + + void receive(etl::imessage_router& source, const etl::imessage& msg) + { + const size_t id = msg.get_message_id(); + + switch (id) + { + case T1::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T2::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T3::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T4::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + default: static_cast(this)->on_receive_unknown(source, msg); break; + } + } + + bool accepts(etl::message_id_t id) const + { + switch (id) + { + case T1::ID: case T2::ID: case T3::ID: case T4::ID: + return true; break; + default: + return false; break; + } + } + }; + + //*************************************************************************** + // Specialisation for 3 message types. + //*************************************************************************** + template + class message_router + : public imessage_router + { + public: + + void receive(const etl::imessage& msg) + { + receive(etl::null_message_router::get(), msg); + } + + void receive(etl::imessage_router& source, const etl::imessage& msg) + { + const size_t id = msg.get_message_id(); + + switch (id) + { + case T1::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T2::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T3::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + default: static_cast(this)->on_receive_unknown(source, msg); break; + } + } + + bool accepts(etl::message_id_t id) const + { + switch (id) + { + case T1::ID: case T2::ID: case T3::ID: + return true; break; + default: + return false; break; + } + } + + class message_packet + { + public: + + explicit message_packet(const imessage& msg) + { + const etl::message_id_t id = msg.get_message_id(); + + switch (id) + { + case T1::ID: new (&storage) T1(static_cast(msg)); break; + case T2::ID: new (&storage) T2(static_cast(msg)); break; + case T3::ID: new (&storage) T3(static_cast(msg)); break; + default: break; + } + } + + ~message_packet() + { + static_cast(storage).~imessage(); + } + + message_packet(const message_packet& other) + { + const etl::message_id_t id = other.get_imessage().get_message_id(); + + switch (id) + { + case T1::ID: new (&storage) T1(static_cast(msg)); break; + case T2::ID: new (&storage) T2(static_cast(msg)); break; + case T3::ID: new (&storage) T3(static_cast(msg)); break; + default: break; + } + } + + message_packet& operator = (const message_packet& other) + { + if (this != &other) + { + static_cast(storage).~imessage(); + new (this) message_packet(other); + } + } + + const etl::imessage& get_imessage() const + { + return *reiniterpret_cast(storage); + } + + operator const imessage&() const + { + return get_imessage(); + } + + private: + + etl::aligned_storage::size, etl::largest_alignment::value>::type storage; + }; + }; + + //*************************************************************************** + // Specialisation for 2 message types. + //*************************************************************************** + template + class message_router + : public imessage_router + { + public: + + void receive(const etl::imessage& msg) + { + receive(etl::null_message_router::get(), msg); + } + + void receive(etl::imessage_router& source, const etl::imessage& msg) + { + const size_t id = msg.get_message_id(); + + switch (id) + { + case T1::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + case T2::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + default: static_cast(this)->on_receive_unknown(source, msg); break; + } + } + + bool accepts(etl::message_id_t id) const + { + switch (id) + { + case T1::ID: case T2::ID: + return true; break; + default: + return false; break; + } + } + }; + + //*************************************************************************** + // Specialisation for 1 message type. + //*************************************************************************** + template + class message_router + : public imessage_router + { + public: + + void receive(const etl::imessage& msg) + { + receive(etl::null_message_router::get(), msg); + } + + void receive(etl::imessage_router& source, const etl::imessage& msg) + { + const size_t id = msg.get_message_id(); + + switch (id) + { + case T1::ID: static_cast(this)->on_receive(source, static_cast(msg)); break; + default: static_cast(this)->on_receive_unknown(source, msg); break; + } + } + + bool accepts(etl::message_id_t id) const + { + switch (id) + { + case T1::ID: + return true; break; + default: + return false; break; + } + } + }; +} + +#endif diff --git a/test/codeblocks/ETL.cbp b/test/codeblocks/ETL.cbp index 963db74b..98f3ea08 100644 --- a/test/codeblocks/ETL.cbp +++ b/test/codeblocks/ETL.cbp @@ -172,6 +172,8 @@ + + @@ -193,12 +195,15 @@ + + + @@ -206,6 +211,7 @@ + @@ -226,12 +232,16 @@ + + + + @@ -273,6 +283,7 @@ + @@ -291,12 +302,14 @@ + + @@ -314,6 +327,7 @@ + diff --git a/test/codeblocks/ETL.depend b/test/codeblocks/ETL.depend index f33d7180..ac76d392 100644 --- a/test/codeblocks/ETL.depend +++ b/test/codeblocks/ETL.depend @@ -3289,7 +3289,7 @@ "CurrentTest.h" "ReportAssertImpl.h" -1497706369 source:d:\users\john\documents\programming\github\etl\test\test_algorithm.cpp +1500929827 source:d:\users\john\documents\programming\github\etl\test\test_algorithm.cpp "UnitTest++.h" "algorithm.h" "container.h" @@ -3423,7 +3423,7 @@ "exception.h" "error_handler.h" -1497713623 source:d:\users\john\documents\programming\github\etl\test\test_bitset.cpp +1500929827 source:d:\users\john\documents\programming\github\etl\test\test_bitset.cpp "UnitTest++.h" @@ -3538,7 +3538,7 @@ "static_assert.h" "exception.h" -1497713693 source:d:\users\john\documents\programming\github\etl\test\test_deque.cpp +1500929827 source:d:\users\john\documents\programming\github\etl\test\test_deque.cpp "UnitTest++.h" "ExtraCheckMacros.h" "deque.h" @@ -3583,7 +3583,7 @@ "exception.h" -1497713618 d:\users\john\documents\programming\github\etl\test\data.h +1500929827 d:\users\john\documents\programming\github\etl\test\data.h 1494277861 source:d:\users\john\documents\programming\github\etl\test\test_endian.cpp @@ -3678,7 +3678,7 @@ "alignment.h" "array.h" -1494277861 source:d:\users\john\documents\programming\github\etl\test\test_flat_set.cpp +1500929827 source:d:\users\john\documents\programming\github\etl\test\test_flat_set.cpp "UnitTest++.h" @@ -3727,7 +3727,7 @@ 1482623723 v_1.h" -1497713618 source:d:\users\john\documents\programming\github\etl\test\test_forward_list.cpp +1500929827 source:d:\users\john\documents\programming\github\etl\test\test_forward_list.cpp "UnitTest++.h" "ExtraCheckMacros.h" "data.h" @@ -3785,7 +3785,7 @@ 1479511692 nction.h" -1497685058 source:d:\users\john\documents\programming\github\etl\test\test_functional.cpp +1497717749 source:d:\users\john\documents\programming\github\etl\test\test_functional.cpp "UnitTest++.h" "functional.h" @@ -3837,7 +3837,7 @@ "nullptr.h" "parameter_type.h" -1494277861 source:d:\users\john\documents\programming\github\etl\test\test_largest.cpp +1500667862 source:d:\users\john\documents\programming\github\etl\test\test_largest.cpp "UnitTest++.h" "largest.h" @@ -3845,7 +3845,7 @@ 1450265856 d:\users\john\documents\programming\github\etl\largest.h "type_traits.h" -1497713618 source:d:\users\john\documents\programming\github\etl\test\test_list.cpp +1500929827 source:d:\users\john\documents\programming\github\etl\test\test_list.cpp "UnitTest++.h" "ExtraCheckMacros.h" "list.h" @@ -3911,7 +3911,7 @@ "exception.h" "error_handler.h" -1494277861 source:d:\users\john\documents\programming\github\etl\test\test_queue.cpp +1500667550 source:d:\users\john\documents\programming\github\etl\test\test_queue.cpp "UnitTest++.h" "queue.h" @@ -3937,12 +3937,12 @@ "exception.h" -1494277861 source:d:\users\john\documents\programming\github\etl\test\test_smallest.cpp +1498993355 source:d:\users\john\documents\programming\github\etl\test\test_smallest.cpp "UnitTest++.h" "smallest.h" -1494277861 source:d:\users\john\documents\programming\github\etl\test\test_stack.cpp +1500667550 source:d:\users\john\documents\programming\github\etl\test\test_stack.cpp "UnitTest++.h" "data.h" @@ -3970,7 +3970,7 @@ "exception.h" -1497713693 source:d:\users\john\documents\programming\github\etl\test\test_vector.cpp +1500929828 source:d:\users\john\documents\programming\github\etl\test\test_vector.cpp "UnitTest++.h" @@ -4151,12 +4151,12 @@ "../exception.h" "../error_handler.h" -1494277861 source:d:\users\john\documents\programming\github\etl\test\test_type_traits.cpp +1500929841 source:d:\users\john\documents\programming\github\etl\test\test_type_traits.cpp "UnitTest++.h" "type_traits.h" -1494277861 source:d:\users\john\documents\programming\github\etl\test\test_variant.cpp +1500929841 source:d:\users\john\documents\programming\github\etl\test\test_variant.cpp "UnitTest++.h" "ExtraCheckMacros.h" "variant.h" @@ -5233,7 +5233,7 @@ 1452516033 /home/jwellbelove/Programming/etl/visitor.h -1497713618 source:d:\users\john\documents\programming\github\etl\test\test_intrusive_forward_list.cpp +1500929827 source:d:\users\john\documents\programming\github\etl\test\test_intrusive_forward_list.cpp "UnitTest++.h" "ExtraCheckMacros.h" "data.h" @@ -5302,7 +5302,7 @@ "platform.h" "static_assert.h" -1489253239 d:\users\john\documents\programming\github\etl\src\algorithm.h +1500929826 d:\users\john\documents\programming\github\etl\src\algorithm.h @@ -5312,16 +5312,17 @@ "iterator.h" "type_traits.h" -1497713693 d:\users\john\documents\programming\github\etl\src\type_traits.h +1500977554 d:\users\john\documents\programming\github\etl\src\type_traits.h "platform.h" "nullptr.h" + 1482948766 d:\users\john\documents\programming\github\etl\src\container.h -1496993010 d:\users\john\documents\programming\github\etl\src\alignment.h +1500929841 d:\users\john\documents\programming\github\etl\src\alignment.h "type_traits.h" "static_assert.h" @@ -5369,11 +5370,11 @@ "log.h" -1482948766 d:\users\john\documents\programming\github\etl\src\smallest.h +1500977554 d:\users\john\documents\programming\github\etl\src\smallest.h "integral_limits.h" -1497685058 d:\users\john\documents\programming\github\etl\src\bitset.h +1497717748 d:\users\john\documents\programming\github\etl\src\bitset.h @@ -5483,7 +5484,7 @@ "static_assert.h" "exception.h" -1497713692 d:\users\john\documents\programming\github\etl\src\deque.h +1500929826 d:\users\john\documents\programming\github\etl\src\deque.h @@ -5515,7 +5516,8 @@ 1482948766 d:\users\john\documents\programming\github\etl\src\fixed_iterator.h -1497713623 d:\users\john\documents\programming\github\etl\src\flat_map.h +1500929826 d:\users\john\documents\programming\github\etl\src\flat_map.h + "platform.h" "reference_flat_map.h" "pool.h" @@ -5552,13 +5554,13 @@ 1482748239 vectorpointer.h" -1497713693 d:\users\john\documents\programming\github\etl\src\private\vector_base.h +1500929827 d:\users\john\documents\programming\github\etl\src\private\vector_base.h "../exception.h" "../error_handler.h" "../debug_count.h" -1497713693 d:\users\john\documents\programming\github\etl\src\vector.h +1500929827 d:\users\john\documents\programming\github\etl\src\vector.h @@ -5580,22 +5582,10 @@ "private/vector_base.h" "private/ivectorpointer.h" -1494277860 d:\users\john\documents\programming\github\etl\src\flat_set.h - - - - - - "vector.h" - "pool.h" - "exception.h" - "debug_count.h" +1500929826 d:\users\john\documents\programming\github\etl\src\flat_set.h "platform.h" - "type_traits.h" - "parameter_type.h" - "vector.h" + "reference_flat_set.h" "pool.h" - "error_handler.h" 1482748239 d:\users\john\documents\programming\github\etl\src\iflat_set.h @@ -5615,7 +5605,7 @@ "../ivector.h" "../error_handler.h" -1497713617 d:\users\john\documents\programming\github\etl\src\forward_list.h +1500929826 d:\users\john\documents\programming\github\etl\src\forward_list.h @@ -5682,7 +5672,7 @@ 1479515290 d:\users\john\documents\programming\github\etl\src\instance_count.h -1497713617 d:\users\john\documents\programming\github\etl\src\intrusive_forward_list.h +1500929826 d:\users\john\documents\programming\github\etl\src\intrusive_forward_list.h "platform.h" @@ -5712,10 +5702,12 @@ "nullptr.h" "parameter_type.h" -1485905321 d:\users\john\documents\programming\github\etl\src\largest.h +1500977554 d:\users\john\documents\programming\github\etl\src\largest.h "type_traits.h" + "smallest.h" + "static_assert.h" -1497713617 d:\users\john\documents\programming\github\etl\src\list.h +1500929827 d:\users\john\documents\programming\github\etl\src\list.h @@ -5748,7 +5740,7 @@ "../exception.h" "../error_handler.h" -1497306512 d:\users\john\documents\programming\github\etl\src\map.h +1500929827 d:\users\john\documents\programming\github\etl\src\map.h @@ -5802,7 +5794,7 @@ "exception.h" "error_handler.h" -1494277860 d:\users\john\documents\programming\github\etl\src\queue.h +1500929827 d:\users\john\documents\programming\github\etl\src\queue.h "container.h" @@ -5826,7 +5818,7 @@ "../exception.h" "../error_handler.h" -1497685058 d:\users\john\documents\programming\github\etl\src\set.h +1500929827 d:\users\john\documents\programming\github\etl\src\set.h @@ -5859,7 +5851,7 @@ "../exception.h" "../error_handler.h" -1494277861 d:\users\john\documents\programming\github\etl\src\stack.h +1500929827 d:\users\john\documents\programming\github\etl\src\stack.h @@ -5937,7 +5929,7 @@ "exception.h" "error_handler.h" -1488104217 d:\users\john\documents\programming\github\etl\src\variant.h +1500929841 d:\users\john\documents\programming\github\etl\src\variant.h "platform.h" "array.h" @@ -5948,11 +5940,10 @@ "static_assert.h" "alignment.h" "error_handler.h" - "largest.h" 1479515291 d:\users\john\documents\programming\github\etl\src\visitor.h -1497713692 d:\users\john\documents\programming\github\etl\src\platform.h +1500929827 d:\users\john\documents\programming\github\etl\src\platform.h @@ -5988,20 +5979,10 @@ 1479511691 at_multimap.h" -1497306512 d:\users\john\documents\programming\github\etl\src\flat_multimap.h - - - - - +1500929826 d:\users\john\documents\programming\github\etl\src\flat_multimap.h "platform.h" - "vector.h" + "reference_flat_multimap.h" "pool.h" - "exception.h" - "error_handler.h" - "debug_count.h" - "type_traits.h" - "parameter_type.h" 1482748239 d:\users\john\documents\programming\github\etl\src\iflat_multimap.h @@ -6021,7 +6002,7 @@ "../ivector.h" "../error_handler.h" -1494277861 source:d:\users\john\documents\programming\github\etl\test\test_flat_multiset.cpp +1500929827 source:d:\users\john\documents\programming\github\etl\test\test_flat_multiset.cpp "UnitTest++.h" @@ -6035,22 +6016,10 @@ 1479511691 at_multiset.h" -1494277860 d:\users\john\documents\programming\github\etl\src\flat_multiset.h - - - - - - +1500929826 d:\users\john\documents\programming\github\etl\src\flat_multiset.h "platform.h" - "vector.h" + "reference_flat_multiset.h" "pool.h" - "exception.h" - "vector.h" - "error_handler.h" - "debug_count.h" - "type_traits.h" - "parameter_type.h" 1482748239 d:\users\john\documents\programming\github\etl\src\iflat_multiset.h @@ -6078,7 +6047,7 @@ 1482358550 trusive_links.h" -1497713618 source:d:\users\john\documents\programming\github\etl\test\test_intrusive_list.cpp +1500929827 source:d:\users\john\documents\programming\github\etl\test\test_intrusive_list.cpp "UnitTest++.h" "ExtraCheckMacros.h" "data.h" @@ -6089,7 +6058,7 @@ -1497713617 d:\users\john\documents\programming\github\etl\src\intrusive_list.h +1500929826 d:\users\john\documents\programming\github\etl\src\intrusive_list.h "platform.h" @@ -6135,7 +6104,7 @@ 1479511692 ltimap.h" -1497306512 d:\users\john\documents\programming\github\etl\src\multimap.h +1500929827 d:\users\john\documents\programming\github\etl\src\multimap.h @@ -6180,7 +6149,7 @@ 1479511692 ltiset.h" -1497306512 d:\users\john\documents\programming\github\etl\src\multiset.h +1500929827 d:\users\john\documents\programming\github\etl\src\multiset.h @@ -6250,14 +6219,14 @@ "array.h" "container.h" -1494277861 source:d:\users\john\documents\programming\github\etl\test\test_priority_queue.cpp +1500667550 source:d:\users\john\documents\programming\github\etl\test\test_priority_queue.cpp "UnitTest++.h" "priority_queue.h" 1482624474 iority_queue.h" -1494277860 d:\users\john\documents\programming\github\etl\src\priority_queue.h +1500929827 d:\users\john\documents\programming\github\etl\src\priority_queue.h @@ -6292,7 +6261,7 @@ 1482625301 ordered_multimap.h" -1497306512 d:\users\john\documents\programming\github\etl\src\unordered_multimap.h +1500929827 d:\users\john\documents\programming\github\etl\src\unordered_multimap.h @@ -6310,7 +6279,6 @@ "nullptr.h" "pool.h" "error_handler.h" - "intrusive_forward_list.h" "exception.h" "debug_count.h" @@ -6331,7 +6299,7 @@ "exception.h" "error_handler.h" -1494277861 source:d:\users\john\documents\programming\github\etl\test\test_unordered_multiset.cpp +1500667550 source:d:\users\john\documents\programming\github\etl\test\test_unordered_multiset.cpp "UnitTest++.h" @@ -6382,7 +6350,7 @@ "exception.h" "error_handler.h" -1494277861 source:d:\users\john\documents\programming\github\etl\test\test_unordered_set.cpp +1500667550 source:d:\users\john\documents\programming\github\etl\test\test_unordered_set.cpp "UnitTest++.h" @@ -6471,7 +6439,7 @@ 1482079098 or.h" -1497713692 d:\users\john\documents\programming\github\etl\src\private\pvoidvector.h +1500929827 d:\users\john\documents\programming\github\etl\src\private\pvoidvector.h @@ -6503,7 +6471,7 @@ "intrusive_links.h" -1482948766 d:\users\john\documents\programming\github\etl\src\intrusive_queue.h +1500929826 d:\users\john\documents\programming\github\etl\src\intrusive_queue.h "type_traits.h" "error_handler.h" @@ -6515,13 +6483,13 @@ "intrusive_links.h" -1482948766 d:\users\john\documents\programming\github\etl\src\intrusive_stack.h +1500929826 d:\users\john\documents\programming\github\etl\src\intrusive_stack.h "type_traits.h" "error_handler.h" "intrusive_links.h" -1497713753 source:d:\users\john\documents\programming\github\etl\test\test_string_char.cpp +1500929828 source:d:\users\john\documents\programming\github\etl\test\test_string_char.cpp "UnitTest++.h" @@ -6531,12 +6499,12 @@ 1482181573 tring.h" -1497713693 d:\users\john\documents\programming\github\etl\src\cstring.h +1500929826 d:\users\john\documents\programming\github\etl\src\cstring.h "platform.h" "basic_string.h" "hash.h" -1497713692 d:\users\john\documents\programming\github\etl\src\basic_string.h +1500929826 d:\users\john\documents\programming\github\etl\src\basic_string.h @@ -6575,7 +6543,7 @@ "../exception.h" "../error_handler.h" -1497713788 source:d:\users\john\documents\programming\github\etl\test\test_string_u16.cpp +1500929828 source:d:\users\john\documents\programming\github\etl\test\test_string_u16.cpp "UnitTest++.h" @@ -6584,12 +6552,12 @@ 1482099557 6string.h" -1497713693 d:\users\john\documents\programming\github\etl\src\u16string.h +1500929827 d:\users\john\documents\programming\github\etl\src\u16string.h "platform.h" "basic_string.h" "hash.h" -1497713815 source:d:\users\john\documents\programming\github\etl\test\test_string_u32.cpp +1500929828 source:d:\users\john\documents\programming\github\etl\test\test_string_u32.cpp "UnitTest++.h" @@ -6598,19 +6566,19 @@ 1482099666 2string.h" -1497713693 d:\users\john\documents\programming\github\etl\src\u32string.h +1500929827 d:\users\john\documents\programming\github\etl\src\u32string.h "platform.h" "basic_string.h" "hash.h" -1497713864 source:d:\users\john\documents\programming\github\etl\test\test_string_wchar_t.cpp +1500929828 source:d:\users\john\documents\programming\github\etl\test\test_string_wchar_t.cpp "UnitTest++.h" "wstring.h" -1497713693 d:\users\john\documents\programming\github\etl\src\wstring.h +1500929827 d:\users\john\documents\programming\github\etl\src\wstring.h "platform.h" "basic_string.h" "hash.h" @@ -6633,7 +6601,7 @@ 1482948766 d:\users\john\documents\programming\github\etl\src\utility.h "type_traits.h" -1497713693 source:d:\users\john\documents\programming\github\etl\test\test_vector_pointer.cpp +1500929828 source:d:\users\john\documents\programming\github\etl\test\test_vector_pointer.cpp "UnitTest++.h" @@ -7855,7 +7823,7 @@ "type_traits.h" -1497713692 d:\users\john\documents\programming\github\etl\src\memory.h +1500929841 d:\users\john\documents\programming\github\etl\src\memory.h "type_traits.h" @@ -7865,10 +7833,10 @@ "platform.h" -1488104217 source:d:\users\john\documents\programming\github\etl\src\random.cpp +1500929827 source:d:\users\john\documents\programming\github\etl\src\random.cpp "random.h" -1492164439 d:\users\john\documents\programming\github\etl\src\random.h +1500929827 d:\users\john\documents\programming\github\etl\src\random.h 1494277861 source:d:\users\john\documents\programming\github\etl\test\test_intrusive_flat_map.cpp @@ -7963,7 +7931,7 @@ "UnitTest++.h" "iterator.h" -1494283539 source:d:\users\john\documents\programming\github\etl\test\test_memory.cpp +1500929841 source:d:\users\john\documents\programming\github\etl\test\test_memory.cpp "UnitTest++.h" "memory.h" "debug_count.h" @@ -7974,7 +7942,7 @@ -1497713618 source:d:\users\john\documents\programming\github\etl\test\test_random.cpp +1500929827 source:d:\users\john\documents\programming\github\etl\test\test_random.cpp "UnitTest++.h" "random.h" @@ -7982,7 +7950,7 @@ -1497685854 source:d:\users\john\documents\programming\github\etl\test\test_vector_non_trivial.cpp +1500667550 source:d:\users\john\documents\programming\github\etl\test\test_vector_non_trivial.cpp "UnitTest++.h" @@ -8166,7 +8134,7 @@ "HelperMacros.h" -1497308006 source:d:\users\john\documents\programming\github\etl\test\test_reference_flat_map.cpp +1500929827 source:d:\users\john\documents\programming\github\etl\test\test_reference_flat_map.cpp "UnitTest++.h" @@ -8179,7 +8147,7 @@ "data.h" "reference_flat_map.h" -1497308006 d:\users\john\documents\programming\github\etl\src\reference_flat_map.h +1500929827 d:\users\john\documents\programming\github\etl\src\reference_flat_map.h "platform.h" "vector.h" @@ -8190,7 +8158,7 @@ "exception.h" "static_assert.h" -1494363271 source:d:\users\john\documents\programming\github\etl\test\test_reference_flat_multimap.cpp +1500929827 source:d:\users\john\documents\programming\github\etl\test\test_reference_flat_multimap.cpp "UnitTest++.h" @@ -8202,14 +8170,14 @@ "data.h" "reference_flat_multimap.h" -1497685058 d:\users\john\documents\programming\github\etl\src\reference_flat_multimap.h +1500929827 d:\users\john\documents\programming\github\etl\src\reference_flat_multimap.h "exception.h" "error_handler.h" "debug_count.h" "vector.h" -1494363271 source:d:\users\john\documents\programming\github\etl\test\test_reference_flat_multiset.cpp +1500929827 source:d:\users\john\documents\programming\github\etl\test\test_reference_flat_multiset.cpp "UnitTest++.h" @@ -8221,7 +8189,7 @@ "data.h" "reference_flat_multiset.h" -1494363271 d:\users\john\documents\programming\github\etl\src\reference_flat_multiset.h +1500929827 d:\users\john\documents\programming\github\etl\src\reference_flat_multiset.h @@ -8234,7 +8202,7 @@ "error_handler.h" "exception.h" -1494363271 source:d:\users\john\documents\programming\github\etl\test\test_reference_flat_set.cpp +1500929828 source:d:\users\john\documents\programming\github\etl\test\test_reference_flat_set.cpp "UnitTest++.h" @@ -8246,7 +8214,7 @@ "data.h" "reference_flat_set.h" -1494363271 d:\users\john\documents\programming\github\etl\src\reference_flat_set.h +1500929827 d:\users\john\documents\programming\github\etl\src\reference_flat_set.h @@ -8259,3 +8227,96 @@ "exception.h" "vector.h" +1479515291 source:d:\users\john\documents\programming\github\etl\test\test_compile.cpp + "algorithm.h" + "alignment.h" + "array.h" + "bitset.h" + "container.h" + "crc8_ccitt.h" + "crc16.h" + "crc16_ccitt.h" + "crc16_kermit.h" + "crc32.h" + "crc64_ecma.h" + "cyclic_value.h" + "deque.h" + "io_port.h" + "vector.h" + "variant.h" + "list.h" + "map.h" + + +1500808011 source:d:\users\john\documents\programming\github\etl\test\test_fsm.cpp + "UnitTest++.h" + "fsm.h" + "enum_type.h" + "container.h" + + +1500977554 d:\users\john\documents\programming\github\etl\src\fsm.h + + "array.h" + "nullptr.h" + "error_handler.h" + "exception.h" + "user_type.h" + "message_router.h" + "integral_limits.h" + "largest.h" + +1500929827 d:\users\john\documents\programming\github\etl\src\user_type.h + +1500977554 d:\users\john\documents\programming\github\etl\src\message_router.h + + "alignment.h" + "error_handler.h" + "exception.h" + "largest.h" + +1500974943 source:d:\users\john\documents\programming\github\etl\test\test_message_router.cpp + "UnitTest++.h" + "ExtraCheckMacros.h" + "message_router.h" + "queue.h" + "largest.h" + "packet.h" + +1500972720 d:\users\john\documents\programming\github\etl\src\packet.h + "platform.h" + "static_assert.h" + "alignment.h" + +1500973942 source:d:\users\john\documents\programming\github\etl\test\test_packet.cpp + "UnitTest++.h" + "ExtraCheckMacros.h" + "packet.h" + "largest.h" + "queue.h" + "pool.h" + +1500929841 source:d:\users\john\documents\programming\github\etl\test\test_task_scheduler.cpp + "UnitTest++.h" + + + + "task.h" + "scheduler.h" + "container.h" + +1500929841 d:\users\john\documents\programming\github\etl\src\task.h + + "error_handler.h" + "exception.h" + +1500929841 d:\users\john\documents\programming\github\etl\src\scheduler.h + + "vector.h" + "nullptr.h" + "error_handler.h" + "exception.h" + "task.h" + "type_traits.h" + "function.h" + diff --git a/test/codeblocks/ETL.layout b/test/codeblocks/ETL.layout index d9b115fe..e8031a1d 100644 --- a/test/codeblocks/ETL.layout +++ b/test/codeblocks/ETL.layout @@ -2,39 +2,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + - + - + - + - + - + - + - + - + + + + + + + + + + + @@ -42,9 +77,24 @@ - + - + + + + + + + + + + + + + + + + @@ -57,79 +107,14 @@ - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -137,34 +122,24 @@ - - - - - - + - + - + - + - + - - - - - - + @@ -172,64 +147,19 @@ - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -237,9 +167,119 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/test_memory.cpp b/test/test_memory.cpp index 44b5f0d6..1e237565 100644 --- a/test/test_memory.cpp +++ b/test/test_memory.cpp @@ -445,5 +445,31 @@ namespace etl::destroy(p, p + SIZE, count); CHECK_EQUAL(0U, count); } + + //************************************************************************* + TEST(test_create_copy) + { + struct Test : etl::create_copy + { + std::string text; + }; + + char buffer[sizeof(Test)]; + + Test test1; + test1.text = "12345678"; + test1.create_copy_at(buffer); + test1.text = "87654321"; + + Test& test2 = *reinterpret_cast(buffer); + + CHECK_EQUAL(std::string("87654321"), test1.text); + CHECK_EQUAL(std::string("12345678"), test2.text); + + int count = 0; + test1.create_copy_at(buffer, count); + + CHECK_EQUAL(1, count); + } }; } diff --git a/test/test_message_router.cpp b/test/test_message_router.cpp index 21d36330..efe912fa 100644 --- a/test/test_message_router.cpp +++ b/test/test_message_router.cpp @@ -30,6 +30,9 @@ SOFTWARE. #include "ExtraCheckMacros.h" #include "message_router.h" +#include "queue.h" +#include "largest.h" +#include "packet.h" //*************************************************************************** // The set of messages. @@ -47,27 +50,23 @@ namespace struct Message1 : public etl::message { - }; struct Message2 : public etl::message { - }; struct Message3 : public etl::message { - + int value[10]; }; struct Message4 : public etl::message { - }; struct Message5 : public etl::message { - }; Message1 message1; @@ -321,5 +320,94 @@ namespace CHECK_EQUAL(1, router.message4_count); CHECK_EQUAL(1, router.message_unknown_count); } + + //========================================================================= + TEST(message_router_accepts) + { + Router2 r2; + + CHECK(r2.accepts(message1)); + CHECK(r2.accepts(message1.message_id)); + + CHECK(r2.accepts(message2)); + CHECK(r2.accepts(message2.message_id)); + + CHECK(!r2.accepts(message3)); + CHECK(!r2.accepts(message3.message_id)); + + CHECK(r2.accepts(message4)); + CHECK(r2.accepts(message4.message_id)); + + CHECK(r2.accepts(message5)); + CHECK(r2.accepts(message5.message_id)); + } + + //========================================================================= + TEST(message_router_queue) + { + Router1 r1; + Router2 r2; + + typedef Router2::message_packet Packet; + typedef etl::queue Queue; + + Queue queue; + + etl::imessage* im; + + // Queue some messages in the message packet queue. + im = &message1; + queue.emplace(*im); + + im = &message2; + queue.emplace(*im); + + // The router2 queue doesn't accept Message3 types. + im = &message3; + CHECK_THROW(queue.emplace(*im), etl::unhandled_message_exception); + + im = &message4; + queue.emplace(*im); + + im = &message4; + queue.emplace(*im); + + etl::imessage& imr1 = queue.front().get(); + r2.receive(r1, imr1); + CHECK_EQUAL(1, r2.message1_count); + CHECK_EQUAL(0, r2.message2_count); + CHECK_EQUAL(0, r2.message4_count); + CHECK_EQUAL(0, r2.message_unknown_count); + CHECK_EQUAL(1, r1.callback_count); + queue.pop(); + + etl::imessage& imr2 = queue.front().get(); + r2.receive(r1, imr2); + CHECK_EQUAL(1, r2.message1_count); + CHECK_EQUAL(1, r2.message2_count); + CHECK_EQUAL(0, r2.message4_count); + CHECK_EQUAL(0, r2.message_unknown_count); + CHECK_EQUAL(2, r1.callback_count); + queue.pop(); + + const etl::imessage& imr3 = queue.front().get(); + r2.receive(r1, imr3); + CHECK_EQUAL(1, r2.message1_count); + CHECK_EQUAL(1, r2.message2_count); + CHECK_EQUAL(1, r2.message4_count); + CHECK_EQUAL(0, r2.message_unknown_count); + CHECK_EQUAL(3, r1.callback_count); + queue.pop(); + + const Queue& crqueue = queue; + const etl::imessage& imr4 = crqueue.front().get(); + r2.receive(r1, imr4); + CHECK_EQUAL(1, r2.message1_count); + CHECK_EQUAL(1, r2.message2_count); + CHECK_EQUAL(2, r2.message4_count); + CHECK_EQUAL(0, r2.message_unknown_count); + CHECK_EQUAL(4, r1.callback_count); + queue.pop(); + } }; } diff --git a/test/test_packet.cpp b/test/test_packet.cpp new file mode 100644 index 00000000..90f70c67 --- /dev/null +++ b/test/test_packet.cpp @@ -0,0 +1,183 @@ +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2017 jwellbelove + +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. +******************************************************************************/ + +#include "UnitTest++.h" +#include "ExtraCheckMacros.h" + +#include "packet.h" +#include "largest.h" +#include "queue.h" +#include "pool.h" + +namespace +{ + // Test classes for polymorphic tests. + struct base + { + base(int v_) + : v(v_) + { + } + + virtual ~base() + { + } + + virtual int value() const = 0; + + protected: + + const int v; + }; + + struct not_base + { + not_base() + { + } + }; + + struct derived_1 : public base + { + derived_1(int value) + : base(value) + { + } + + int value() const + { + return v; + } + + static int count; + }; + + struct derived_2 : public base + { + derived_2(int value) + : base(value) + { + } + + int value() const + { + return v; + } + }; + + typedef etl::largest types; + // + //// Test packet types. + typedef etl::packet packet1_t; + typedef etl::packet packet2_t; + + SUITE(test_packet) + { + //************************************************************************* + TEST(test_constructor_value) + { + derived_1 d1(1); + derived_2 d2(2); + + packet1_t p11(d1); + packet1_t p12(d2); + + base* b; + b = &p11.get(); + CHECK_EQUAL(d1.value(), b->value()); + + b = &p12.get(); + CHECK_EQUAL(d2.value(), b->value()); + + // These lines should fail to compile. + //p11 = p12; + //packet2_t p21(d1); + //packet2_t p22(d1); + } + + //************************************************************************* + TEST(test_assignment) + { + derived_1 d1(1); + derived_2 d2(2); + + packet1_t p(d1); + + base* b; + b = &p.get(); + CHECK_EQUAL(d1.value(), b->value()); + + p = d2; + CHECK_EQUAL(d2.value(), b->value()); + } + + //************************************************************************* + TEST(test_packet_queueing) + { + derived_1 da(1); + derived_2 db(2); + derived_1 dc(3); + derived_2 dd(4); + + etl::queue queue; + + queue.emplace(da); + queue.emplace(db); + queue.emplace(dc); + queue.emplace(dd); + + CHECK_EQUAL(da.value(), queue.front().get().value()); + queue.pop(); + + CHECK_EQUAL(db.value(), queue.front().get().value()); + queue.pop(); + + CHECK_EQUAL(dc.value(), queue.front().get().value()); + queue.pop(); + + CHECK_EQUAL(dd.value(), queue.front().get().value()); + queue.pop(); + } + + //************************************************************************* + TEST(test_packet_get) + { + derived_1 da(1); + + // Non-const. + packet1_t p1(da); + base& rb = p1.get(); + CHECK_EQUAL(da.value(), rb.value()); + + // Const. + const packet1_t p2(da); + const base& crb = p2.get(); + CHECK_EQUAL(da.value(), crb.value()); + } + } +} diff --git a/test/test_task_scheduler.cpp b/test/test_task_scheduler.cpp new file mode 100644 index 00000000..5e371819 --- /dev/null +++ b/test/test_task_scheduler.cpp @@ -0,0 +1,245 @@ +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +http://www.etlcpp.com + +Copyright(c) 2017 jwellbelove + +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. +******************************************************************************/ + +#include "UnitTest++.h" + +#include +#include +#include + +#include "task.h" +#include "scheduler.h" +#include "container.h" + +typedef std::vector WorkList_t; + +//***************************************************************************** +struct Common +{ + //********************************************* + Common() + : callback(*this, &Common::IdleCallback) + { + } + + //********************************************* + void Clear() + { + workList.clear(); + } + + //********************************************* + void IdleCallback() + { + pScheduler->exit_scheduler(); + } + + WorkList_t workList; + etl::function callback; + etl::ischeduler* pScheduler; +}; + +//***************************************************************************** +class Task : public etl::task +{ +public: + + //********************************************* + Task(etl::task_priority_t priority, WorkList_t& work, Common& common) + : task(priority), + work(work), + common(common), + workIndex(0), + addAtIndex(0), + workToAdd(""), + pTaskToAddTo(nullptr) + { + workCopy = work; + } + + //********************************************* + void Reset() + { + workIndex = 0; + addAtIndex = 0; + workToAdd = ""; + pTaskToAddTo = nullptr; + work = workCopy; + } + + //********************************************* + void WorkToAdd(int addAtIndex_, const std::string& workToAdd_, Task& taskToAddTo_) + { + addAtIndex = addAtIndex_; + workToAdd = workToAdd_; + pTaskToAddTo = &taskToAddTo_; + } + + //********************************************* + uint_least8_t task_request_work() const + { + return uint_least8_t(work.size() - workIndex); + } + + //********************************************* + void task_process_work() + { + common.workList.push_back(work[workIndex]); + ++workIndex; + + if (workIndex == addAtIndex) + { + pTaskToAddTo->work.push_back(workToAdd); + } + } + +private: + + WorkList_t work; + WorkList_t workCopy; + Common &common; + uint_least8_t workIndex; + int addAtIndex; + std::string workToAdd; + Task* pTaskToAddTo; +}; + +Common common; + +WorkList_t work1 = { "T1W1", "T1W2", "T1W3" }; +WorkList_t work2 = { "T2W1", "T2W2", "T2W3", "T2W4" }; +WorkList_t work3 = { "T3W1", "T3W2" }; + +Task task1(1, work1, common); +Task task2(2, work2, common); +Task task3(3, work3, common); + +etl::task* taskList[] = { &task1, &task2, &task3 }; + +typedef etl::scheduler SchedulerSequencialSingle; +typedef etl::scheduler SchedulerSequencialMultiple; +typedef etl::scheduler SchedulerHighestPriority; +typedef etl::scheduler SchedulerMostWork; + +namespace +{ + SUITE(test_task_scheduler) + { + //========================================================================= + TEST(test_scheduler_sequencial_single) + { + SchedulerSequencialSingle s; + + task1.Reset(); + task2.Reset(); + task3.Reset(); + + task2.WorkToAdd(2, "T3W3", task3); + + common.Clear(); + common.pScheduler = &s; + + s.set_idle_callback(common.callback); + s.add_task_list(taskList, etl::size(taskList)); + s.start(); // If 'start' returns then the idle callback was sucessfully called. + + WorkList_t expected = { "T3W1", "T2W1", "T1W1", "T3W2", "T2W2", "T1W2", "T3W3", "T2W3", "T1W3", "T2W4" }; + + CHECK(expected == common.workList); + } + + //========================================================================= + TEST(test_scheduler_sequencial_multiple) + { + SchedulerSequencialMultiple s; + + task1.Reset(); + task2.Reset(); + task3.Reset(); + + task2.WorkToAdd(2, "T3W3", task3); + + common.Clear(); + common.pScheduler = &s; + + s.set_idle_callback(common.callback); + s.add_task_list(taskList, etl::size(taskList)); + s.start(); // If 'start' returns then the idle callback was sucessfully called. + + WorkList_t expected = { "T3W1", "T3W2", "T2W1", "T2W2", "T2W3", "T2W4", "T1W1", "T1W2", "T1W3", "T3W3" }; + + CHECK(expected == common.workList); + } + + //========================================================================= + TEST(test_scheduler_highest_priority) + { + SchedulerHighestPriority s; + + task1.Reset(); + task2.Reset(); + task3.Reset(); + + task2.WorkToAdd(2, "T3W3", task3); + + common.Clear(); + common.pScheduler = &s; + + s.set_idle_callback(common.callback); + s.add_task_list(taskList, etl::size(taskList)); + s.start(); // If 'start' returns then the idle callback was sucessfully called. + + WorkList_t expected = { "T3W1", "T3W2", "T2W1", "T2W2", "T3W3", "T2W3", "T2W4", "T1W1", "T1W2", "T1W3" }; + + CHECK(expected == common.workList); + } + + //========================================================================= + TEST(test_scheduler_most_work) + { + SchedulerMostWork s; + + task1.Reset(); + task2.Reset(); + task3.Reset(); + + task2.WorkToAdd(3, "T3W3", task3); + + common.Clear(); + common.pScheduler = &s; + + s.set_idle_callback(common.callback); + s.add_task_list(taskList, etl::size(taskList)); + s.start(); // If 'start' returns then the idle callback was sucessfully called. + + WorkList_t expected = { "T2W1", "T2W2", "T1W1", "T3W1", "T2W3", "T3W2", "T1W2", "T3W3", "T2W4", "T1W3" }; + + CHECK(expected == common.workList); + } + }; +} diff --git a/test/test_type_traits.cpp b/test/test_type_traits.cpp index b9e624d7..5f80210e 100644 --- a/test/test_type_traits.cpp +++ b/test/test_type_traits.cpp @@ -41,14 +41,20 @@ namespace std #include "type_traits.h" #include -// A class to test non-fundamental types. -struct Test -{ - int a; -}; - namespace { + // A class to test non-fundamental types. + struct Test + { + int a; + }; + + // A class to test etl::is_one_of + template + struct Type + { + }; + SUITE(test_type_traits) { //************************************************************************* @@ -525,5 +531,55 @@ namespace CHECK(std::alignment_of::value == etl::alignment_of::value); CHECK(std::alignment_of::value == etl::alignment_of::value); } + + //************************************************************************* + TEST(test_is_one_of) + { + typedef Type<0> T0; + typedef Type<1> T1; + typedef Type<2> T2; + typedef Type<3> T3; + typedef Type<4> T4; + + CHECK(bool(etl::is_one_of::value)); + CHECK(!(etl::is_one_of::value)); + + CHECK(bool(etl::is_one_of::value)); + CHECK(!(etl::is_one_of::value)); + + CHECK(bool(etl::is_one_of::value)); + CHECK(!(etl::is_one_of::value)); + + CHECK(bool(etl::is_one_of::value)); + CHECK(!(etl::is_one_of::value)); + + CHECK(bool(etl::is_one_of::value)); + CHECK(!(etl::is_one_of::value)); + + CHECK(bool(etl::is_one_of::value)); + CHECK(bool(etl::is_one_of::value)); + CHECK(bool(etl::is_one_of::value)); + CHECK(bool(etl::is_one_of::value)); + CHECK(bool(etl::is_one_of::value)); + CHECK(!(etl::is_one_of::value)); + } + + //************************************************************************* + TEST(test_is_base_of) + { + struct A { }; + struct B : public A { }; + struct C { }; + + CHECK((std::is_base_of::value) == (etl::is_base_of::value)); + CHECK((std::is_base_of::value) == (etl::is_base_of::value)); + CHECK((std::is_base_of::value) == (etl::is_base_of::value)); + CHECK((std::is_base_of::value) == (etl::is_base_of::value)); + CHECK((std::is_base_of::value) == (etl::is_base_of::value)); + CHECK((std::is_base_of::value) == (etl::is_base_of::value)); + CHECK((std::is_base_of::value) == (etl::is_base_of::value)); + CHECK((std::is_base_of::value) == (etl::is_base_of::value)); + CHECK((std::is_base_of::value) == (etl::is_base_of::value)); + } }; } diff --git a/test/test_variant.cpp b/test/test_variant.cpp index 0430c7f6..5b3324e9 100644 --- a/test/test_variant.cpp +++ b/test/test_variant.cpp @@ -35,70 +35,70 @@ SOFTWARE. #include #include -// Test classes for polymorphic tests. -struct base -{ - virtual ~base() - { - } - - base() - : value(0) - { - } - - virtual void set() = 0; - int value; -}; - -struct not_base -{ - not_base() - : value(0) - { - } - - virtual void set() = 0; - int value; -}; - -struct derived_1 : public base -{ - void set() - { - value = 1; - } -}; - -struct derived_2 : public base -{ - void set() - { - value = 2; - } -}; - -// Test variant types. -typedef etl::variant test_variant_3a; -typedef etl::variant test_variant_3b; - -typedef etl::variant test_variant_1; -typedef etl::variant test_variant_2; -typedef etl::variant test_variant_3; -typedef etl::variant test_variant_4; -typedef etl::variant test_variant_5; -typedef etl::variant test_variant_6; -typedef etl::variant test_variant_7; -typedef etl::variant test_variant_8; - -typedef etl::variant test_variant_polymorphic; -typedef etl::variant test_variant_max_types; - -// This line should compile with no errors. -test_variant_max_types variant_max; - namespace { + // Test classes for polymorphic tests. + struct base + { + virtual ~base() + { + } + + base() + : value(0) + { + } + + virtual void set() = 0; + int value; + }; + + struct not_base + { + not_base() + : value(0) + { + } + + virtual void set() = 0; + int value; + }; + + struct derived_1 : public base + { + void set() + { + value = 1; + } + }; + + struct derived_2 : public base + { + void set() + { + value = 2; + } + }; + + // Test variant types. + typedef etl::variant test_variant_3a; + typedef etl::variant test_variant_3b; + + typedef etl::variant test_variant_1; + typedef etl::variant test_variant_2; + typedef etl::variant test_variant_3; + typedef etl::variant test_variant_4; + typedef etl::variant test_variant_5; + typedef etl::variant test_variant_6; + typedef etl::variant test_variant_7; + typedef etl::variant test_variant_8; + + typedef etl::variant test_variant_polymorphic; + typedef etl::variant test_variant_max_types; + + // This line should compile with no errors. + test_variant_max_types variant_max; + SUITE(test_variant) { TEST(test_alignment) diff --git a/test/vs2017/etl.vcxproj b/test/vs2017/etl.vcxproj index 736afc28..18257869 100644 --- a/test/vs2017/etl.vcxproj +++ b/test/vs2017/etl.vcxproj @@ -130,8 +130,12 @@ + + + + @@ -377,6 +381,7 @@ false + @@ -397,6 +402,7 @@ + @@ -414,8 +420,7 @@ - - + diff --git a/test/vs2017/etl.vcxproj.filters b/test/vs2017/etl.vcxproj.filters index cd16db12..641d1707 100644 --- a/test/vs2017/etl.vcxproj.filters +++ b/test/vs2017/etl.vcxproj.filters @@ -40,6 +40,12 @@ {6be3bc76-e17c-4be0-8b0b-d1053e1a1761} + + {c1264f38-22fa-4fcb-8cab-f254b1290eab} + + + {39015d44-a7cb-47f0-a7dd-27714f852363} + @@ -435,14 +441,26 @@ ETL\Frameworks - - ETL\Frameworks - ETL\Frameworks + + ETL\Containers + + + ETL\Frameworks\Generators + - ETL\Frameworks + ETL\Frameworks\Generators + + + ETL\Utilities\Generators + + + ETL\Utilities\Generators + + + ETL\Utilities\Generators @@ -773,6 +791,12 @@ Source Files + + Source Files + + + Source Files + @@ -781,11 +805,8 @@ Resource Files - - ETL\Frameworks - - - ETL\Frameworks + + Resource Files