Lastest versions of FSM, Message Router and supporting functionality.

This commit is contained in:
John Wellbelove 2017-07-25 11:30:00 +01:00
parent 4e9e15d2c2
commit 0ccdd4fab4
29 changed files with 5354 additions and 810 deletions

View File

@ -113,7 +113,7 @@ namespace etl
template <typename T>
operator T& ()
{
STATIC_ASSERT(ALIGNMENT % etl::alignment_of<T>::value == 0, "Incompatible alignment");
STATIC_ASSERT((etl::is_same<T*, void*>:: value || ((ALIGNMENT % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
return reinterpret_cast<T&>(*data);
}
@ -121,7 +121,7 @@ namespace etl
template <typename T>
operator const T& () const
{
STATIC_ASSERT(ALIGNMENT % etl::alignment_of<T>::value == 0, "Incompatible alignment");
STATIC_ASSERT((etl::is_same<T*, void*>:: value || ((ALIGNMENT % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
return reinterpret_cast<const T&>(*data);
}
@ -129,7 +129,7 @@ namespace etl
template <typename T>
operator T* ()
{
STATIC_ASSERT(ALIGNMENT % etl::alignment_of<T>::value == 0, "Incompatible alignment");
STATIC_ASSERT((etl::is_same<T*, void*>:: value || ((ALIGNMENT % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
return reinterpret_cast<T*>(data);
}
@ -137,7 +137,7 @@ namespace etl
template <typename T>
operator const T* () const
{
STATIC_ASSERT(ALIGNMENT % etl::alignment_of<T>::value == 0, "Incompatible alignment");
STATIC_ASSERT((etl::is_same<T*, void*>:: value || ((ALIGNMENT % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
return reinterpret_cast<const T*>(data);
}
@ -145,7 +145,7 @@ namespace etl
template <typename T>
T& get_reference()
{
STATIC_ASSERT(ALIGNMENT % etl::alignment_of<T>::value == 0, "Incompatible alignment");
STATIC_ASSERT((etl::is_same<T*, void*>:: value || ((ALIGNMENT % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
return reinterpret_cast<T&>(*data);
}
@ -153,7 +153,7 @@ namespace etl
template <typename T>
const T& get_reference() const
{
STATIC_ASSERT(ALIGNMENT % etl::alignment_of<T>::value == 0, "Incompatible alignment");
STATIC_ASSERT((etl::is_same<T*, void*>:: value || ((ALIGNMENT % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
return reinterpret_cast<const T&>(*data);
}
@ -161,7 +161,7 @@ namespace etl
template <typename T>
T* get_address()
{
STATIC_ASSERT(ALIGNMENT % etl::alignment_of<T>::value == 0, "Incompatible alignment");
STATIC_ASSERT((etl::is_same<T*, void*>:: value || ((ALIGNMENT % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
return reinterpret_cast<T*>(data);
}
@ -169,7 +169,7 @@ namespace etl
template <typename T>
const T* get_address() const
{
STATIC_ASSERT(ALIGNMENT % etl::alignment_of<T>::value == 0, "Incompatible alignment");
STATIC_ASSERT((etl::is_same<T*, void*>:: value || ((ALIGNMENT % etl::alignment_of<T>::value) == 0)), "Incompatible alignment");
return reinterpret_cast<const T*>(data);
}

View File

@ -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=<n> fsm_generator.h
// Where <n> 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 <const fsm_internal_id_t ID1 = etl::integral_limits<fsm_internal_id_t>::max - 0,
const fsm_internal_id_t ID2 = etl::integral_limits<fsm_internal_id_t>::max - 1,
const fsm_internal_id_t ID3 = etl::integral_limits<fsm_internal_id_t>::max - 2,
@ -202,10 +217,7 @@ namespace etl
const fsm_internal_id_t ID14 = etl::integral_limits<fsm_internal_id_t>::max - 13,
const fsm_internal_id_t ID15 = etl::integral_limits<fsm_internal_id_t>::max - 14,
const fsm_internal_id_t ID16 = etl::integral_limits<fsm_internal_id_t>::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=<n> fsm_generator.h
// Where <n> 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)
{

View File

@ -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=<n> fsm_generator.h
// Where <n> 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<fsm_internal_id_t>::max - %d, " % (n, n - 1))
cog.out(" ")
cog.out("const fsm_internal_id_t ID%d = etl::integral_limits<fsm_internal_id_t>::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=<n> fsm_generator.h
// Where <n> 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(" {")

5
src/generate.bat Normal file
View File

@ -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

View File

@ -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=<n> largest_generator.h
// Where <n> 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 <typename T1, typename T2 = void, typename T3 = void, typename T4 = void,
typename T5 = void, typename T6 = void, typename T7 = void, typename T8 = void,
typename T9 = void, typename T10 = void, typename T11 = void, typename T12 = void,
template <typename T1, typename T2 = void, typename T3 = void, typename T4 = void,
typename T5 = void, typename T6 = void, typename T7 = void, typename T8 = void,
typename T9 = void, typename T10 = void, typename T11 = void, typename T12 = void,
typename T13 = void, typename T14 = void, typename T15 = void, typename T16 = void>
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<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>::type largest_other;
typedef typename largest_type<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>::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 <typename T1>
struct largest_type<T1, void, void, void,
void, void, void, void,
void, void, void, void,
void, void, void, void>
struct largest_type<T1, void, void, void, void, void, void, void,
void, void, void, void, void, void, void, void>
{
typedef T1 type;
@ -117,12 +133,14 @@ namespace etl
/// Defines <b>value</b> which is the largest alignment of all the parameters.
///\ingroup largest
//***************************************************************************
template <typename T1, typename T2 = void, typename T3 = void, typename T4 = void,
typename T5 = void, typename T6 = void, typename T7 = void, typename T8 = void,
typename T9 = void, typename T10 = void, typename T11 = void, typename T12 = void,
typename T13 = void, typename T14 = void, typename T15 = void, typename T16 = void>
template <typename T1, typename T2 = void, typename T3 = void, typename T4 = void,
typename T5 = void, typename T6 = void, typename T7 = void, typename T8 = void,
typename T9 = void, typename T10 = void, typename T11 = void, typename T12 = void,
typename T13 = void, typename T14 = void, typename T15 = void, typename T16 = void>
struct largest_alignment
{
private:
// Determine the largest size.
template <const size_t size1, const size_t size2>
struct max_size
@ -136,22 +154,22 @@ namespace etl
// All of the alignments.
enum
{
t1 = alignment_of<T1>::value,
t2 = alignment_of<T2>::value,
t3 = alignment_of<T3>::value,
t4 = alignment_of<T4>::value,
t5 = alignment_of<T5>::value,
t6 = alignment_of<T6>::value,
t7 = alignment_of<T7>::value,
t8 = alignment_of<T8>::value,
t9 = alignment_of<T9>::value,
t10 = alignment_of<T10>::value,
t11 = alignment_of<T11>::value,
t12 = alignment_of<T12>::value,
t13 = alignment_of<T13>::value,
t14 = alignment_of<T14>::value,
t15 = alignment_of<T15>::value,
t16 = alignment_of<T16>::value
t1 = etl::alignment_of<T1>::value,
t2 = etl::alignment_of<T2>::value,
t3 = etl::alignment_of<T3>::value,
t4 = etl::alignment_of<T4>::value,
t5 = etl::alignment_of<T5>::value,
t6 = etl::alignment_of<T6>::value,
t7 = etl::alignment_of<T7>::value,
t8 = etl::alignment_of<T8>::value,
t9 = etl::alignment_of<T9>::value,
t10 = etl::alignment_of<T10>::value,
t11 = etl::alignment_of<T11>::value,
t12 = etl::alignment_of<T12>::value,
t13 = etl::alignment_of<T13>::value,
t14 = etl::alignment_of<T14>::value,
t15 = etl::alignment_of<T15>::value,
t16 = etl::alignment_of<T16>::value
};
public:
@ -216,6 +234,27 @@ namespace etl
typedef typename etl::smallest_int_for_bits<etl::integral_limits<T>::bits + 1>::type type;
};
//***************************************************************************
/// Template to determine the largest type, size and alignment.
/// Supports up to 16 types.
/// Defines <b>value</b> which is the largest type, size and alignment of all the parameters.
///\ingroup largest
//***************************************************************************
template <typename T1, typename T2 = void, typename T3 = void, typename T4 = void,
typename T5 = void, typename T6 = void, typename T7 = void, typename T8 = void,
typename T9 = void, typename T10 = void, typename T11 = void, typename T12 = void,
typename T13 = void, typename T14 = void, typename T15 = void, typename T16 = void>
struct largest
{
typedef typename etl::largest_type<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>::type type;
enum
{
size = etl::largest_type<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>::size,
alignment = etl::largest_alignment<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>::value
};
};
}
#endif

323
src/largest_generator.h Normal file
View File

@ -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=<n> largest_generator.h
// Where <n> 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 <typename T1, ")
for n in range(2, int(NTypes)):
cog.out("typename T%s = void, " % n)
if n % 4 == 0:
cog.outl("")
cog.out(" ")
cog.outl("typename T%s = void>" % int(NTypes))
cog.outl("struct largest_type")
cog.outl("{")
cog.outl("private:")
cog.outl("")
cog.outl(" // Declaration.")
cog.outl(" template <const bool Boolean, typename TrueType, typename FalseType>")
cog.outl(" struct choose_type;")
cog.outl("")
cog.outl(" // Specialisation for 'true'.")
cog.outl(" // Defines 'type' as 'TrueType'.")
cog.outl(" template <typename TrueType, typename FalseType>")
cog.outl(" struct choose_type<true, TrueType, FalseType>")
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 <typename TrueType, typename FalseType>")
cog.outl(" struct choose_type<false, TrueType, FalseType>")
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 <typename T1>")
cog.out("struct largest_type<T1, ")
for n in range(2, int(NTypes)):
cog.out("void, ")
if n % 8 == 0:
cog.outl("")
cog.out(" ")
cog.outl("void>")
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 <b>value</b> which is the largest alignment of all the parameters.")
cog.outl("///\ingroup largest")
cog.outl("//***************************************************************************")
cog.out("template <typename T1, ")
for n in range(2, int(NTypes)):
cog.out("typename T%s = void, " % n)
if n % 4 == 0:
cog.outl("")
cog.out(" ")
cog.outl("typename T%s = void>" % NTypes)
cog.outl("struct largest_alignment")
cog.outl("{")
cog.outl("private:")
cog.outl("")
cog.outl(" // Determine the largest size.")
cog.outl(" template <const size_t size1, const size_t size2>")
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<T%s>::value," %(n, n))
cog.outl(" t%s = etl::alignment_of<T%s>::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<t%s, " %n)
if n % 8 == 0:
cog.outl("")
cog.out(" ")
cog.outl("t%s>" % 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 <typename T>
struct larger_int_type
{
STATIC_ASSERT(etl::is_integral<T>::value, "Must be an integral type");
typedef typename etl::smallest_int_for_bits<etl::integral_limits<typename etl::make_signed<T>::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 <typename T>
struct larger_uint_type
{
STATIC_ASSERT(etl::is_integral<T>::value, "Must be an integral type");
typedef typename etl::smallest_uint_for_bits<etl::integral_limits<typename etl::make_unsigned<T>::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 <typename T, bool IS_SIGNED = etl::is_signed<T>::value>
struct larger_type;
template <typename T>
struct larger_type<T, false>
{
STATIC_ASSERT(etl::is_integral<T>::value, "Must be an integral type");
typedef typename etl::smallest_uint_for_bits<etl::integral_limits<T>::bits + 1>::type type;
};
template <typename T>
struct larger_type<T, true>
{
STATIC_ASSERT(etl::is_integral<T>::value, "Must be an integral type");
typedef typename etl::smallest_int_for_bits<etl::integral_limits<T>::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 <b>value</b> which is the largest type, size and alignment of all the parameters.")
cog.outl("///\ingroup largest")
cog.outl("//***************************************************************************")
cog.out("template <typename T1, ")
for n in range(2, int(NTypes)):
cog.out("typename T%s = void, " % n)
if n % 4 == 0:
cog.outl("")
cog.out(" ")
cog.outl("typename T%s = void>" % 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

View File

@ -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 <typename T>
struct create_copy
{
void create_copy_at(void* p)
{
new (p) T(static_cast<const T&>(*this));
}
template <typename TCounter>
void create_copy_at(void* p, TCounter& count)
{
new (p) T(static_cast<const T&>(*this));
++count;
}
};
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -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=<n> message_router_generator.h
// Where <n> 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 <stdint.h>
#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 <const size_t ID_>
template <const etl::message_id_t ID_>
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=<n> message_router_generator.h
// Where <n> 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<const T%s&>(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 <typename T>")
cog.outl(" explicit message_packet(const T& msg)")
cog.outl(" {")
cog.out(" STATIC_ASSERT((etl::is_one_of<T, ")
for n in range(1, int(Handlers)):
cog.out("T%s, " % n)
if n % 16 == 0:
cog.outl("")
cog.out(" ")
cog.outl("""T%s>::value), "Unsupported type for this message packet");""" % int(Handlers))
cog.outl("")
cog.outl(" void* p = data;")
cog.outl(" ::new (p) T(static_cast<const T&>(msg));")
cog.outl(" }")
cog.outl("")
cog.outl(" //********************************************")
cog.outl(" ~message_packet()")
cog.outl(" {")
cog.outl(" static_cast<etl::imessage*>(data)->~imessage();")
cog.outl(" }")
cog.outl("")
cog.outl(" //********************************************")
cog.outl(" etl::imessage& get()")
cog.outl(" {")
cog.outl(" return *static_cast<etl::imessage*>(data);")
cog.outl(" }")
cog.outl("")
cog.outl(" //********************************************")
cog.outl(" const etl::imessage& get() const")
cog.outl(" {")
cog.outl(" return *static_cast<const etl::imessage*>(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<SIZE, ALIGNMENT>::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<const T%s&>(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 <typename T>")
cog.outl(" explicit message_packet(const T& msg)")
cog.outl(" {")
cog.out(" STATIC_ASSERT((etl::is_one_of<T, ")
for t in range(1, n):
cog.out("T%s, " % t)
if t % 16 == 0:
cog.outl("")
cog.out(" ")
cog.outl("""T%s>::value), "Unsupported type for this message packet");""" % n)
cog.outl("")
cog.outl(" void* p = data;")
cog.outl(" ::new (p) T(static_cast<const T&>(msg));")
cog.outl(" }")
cog.outl("")
cog.outl(" //********************************************")
cog.outl(" ~message_packet()")
cog.outl(" {")
cog.outl(" static_cast<etl::imessage*>(data)->~imessage();")
cog.outl(" }")
cog.outl("")
cog.outl(" //********************************************")
cog.outl(" etl::imessage& get()")
cog.outl(" {")
cog.outl(" return *static_cast<etl::imessage*>(data);")
cog.outl(" }")
cog.outl("")
cog.outl(" //********************************************")
cog.outl(" const etl::imessage& get() const")
cog.outl(" {")
cog.outl(" return *static_cast<const etl::imessage*>(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<SIZE, ALIGNMENT>::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)")

128
src/packet.h Normal file
View File

@ -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 <typename TBase, size_t SIZE, size_t ALIGNMENT>
class packet
{
public:
//***************************************************************************
/// Constructor that static asserts any types that do not conform to the max size and alignment.
//***************************************************************************
template <typename T>
explicit packet(const T& value)
{
STATIC_ASSERT((etl::is_base_of<TBase, T>::value), "Unsupported type");
STATIC_ASSERT(sizeof(T) <= SIZE, "Unsupported size");
STATIC_ASSERT(etl::alignment_of<T>::value <= ALIGNMENT, "Unsupported alignment");
::new (static_cast<T*>(data)) T(value);
}
//***************************************************************************
/// Destructor
//***************************************************************************
~packet()
{
static_cast<TBase*>(data)->~TBase();
}
//***************************************************************************
/// Assignment operator for type.
///\param value The value to assign.
//***************************************************************************
template <typename T>
packet& operator =(const T& value)
{
STATIC_ASSERT((etl::is_base_of<TBase, T>::value), "Unsupported type");
STATIC_ASSERT(sizeof(T) <= SIZE, "Unsupported size");
STATIC_ASSERT(etl::alignment_of<T>::value <= ALIGNMENT, "Unsupported alignment");
static_cast<TBase*>(data)->~TBase();
::new (static_cast<T*>(data)) T(value);
return *this;
}
//***************************************************************************
/// Get access to the contained object.
//***************************************************************************
TBase& get()
{
return *static_cast<TBase*>(data);
}
//***************************************************************************
/// Get access to the contained object.
//***************************************************************************
const TBase& get() const
{
return *static_cast<const TBase*>(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<SIZE, ALIGNMENT>::type data;
};
}
#undef ETL_FILE
#endif

View File

@ -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<etl::task*>& 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 <const size_t MAX_TASKS_, const size_t POLICY_>
class scheduler
struct scheduler_policy_sequencial_multiple
{
bool schedule_tasks(etl::ivector<etl::task*>& 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<etl::task*>& 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<etl::task*>& 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<void>& 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 <typename TSize>
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<void>* p_idle_callback;
};
//***************************************************************************
/// Scheduler.
//***************************************************************************
template <typename TSchedulerPolicy, size_t MAX_TASKS_>
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 <typename TSize>
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<POLICY == scheduler_policy::SEQUENCIAL_SINGLE, void>::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<POLICY == scheduler_policy::SEQUENCIAL_MULTIPLE, void>::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<POLICY == scheduler_policy::HIGHEST_PRIORITY, void>::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<etl::task*, MAX_TASKS> task_list_t;
task_list_t task_list;
bool scheduler_running;
};
}

View File

@ -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=<n> smallest_generator.h
// Where <n> 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 <typename T1, typename T2 = void, typename T3 = void, typename T4 = void,
typename T5 = void, typename T6 = void, typename T7 = void, typename T8 = void,
typename T9 = void, typename T10 = void, typename T11 = void, typename T12 = void,
template <typename T1, typename T2 = void, typename T3 = void, typename T4 = void,
typename T5 = void, typename T6 = void, typename T7 = void, typename T8 = void,
typename T9 = void, typename T10 = void, typename T11 = void, typename T12 = void,
typename T13 = void, typename T14 = void, typename T15 = void, typename T16 = void>
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 <typename T1>
struct smallest_type <T1, void, void, void,
void, void, void, void,
void, void, void, void,
void, void, void, void>
struct smallest_type<T1, void, void, void, void, void, void, void,
void, void, void, void, void, void, void, void>
{
typedef T1 type;

336
src/smallest_generator.h Normal file
View File

@ -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=<n> smallest_generator.h
// Where <n> 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 <stdint.h>
#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 <typename T1, ")
for n in range(2, int(NTypes)):
cog.out("typename T%s = void, " % n)
if n % 4 == 0:
cog.outl("")
cog.out(" ")
cog.outl("typename T%s = void>" % int(NTypes))
cog.outl("struct smallest_type")
cog.outl("{")
cog.outl("private:")
cog.outl("")
cog.outl(" // Declaration.")
cog.outl(" template <const bool Boolean, typename TrueType, typename FalseType>")
cog.outl(" struct choose_type;")
cog.outl("")
cog.outl(" // Specialisation for 'true'.")
cog.outl(" // Defines 'type' as 'TrueType'.")
cog.outl(" template <typename TrueType, typename FalseType>")
cog.outl(" struct choose_type<true, TrueType, FalseType>")
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 <typename TrueType, typename FalseType>")
cog.outl(" struct choose_type<false, TrueType, FalseType>")
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 <typename T1>")
cog.out("struct smallest_type<T1, ")
for n in range(2, int(NTypes)):
cog.out("void, ")
if n % 8 == 0:
cog.outl("")
cog.out(" ")
cog.outl("void>")
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 <const int index>
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 <const int index>
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 <const size_t NBITS>
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_INDEX>::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 <const size_t NBITS>
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_INDEX>::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 <const uintmax_t VALUE>
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_INDEX>::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 <const intmax_t VALUE>
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_INDEX>::type type;
};
}
#endif

View File

@ -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 <stdint.h>
@ -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;
};
}

View File

@ -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=<n> types_generator.h
// Where <n> 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 <typename T> struct is_integral<volatile T> : is_integral<T> {};
template <typename T> struct is_integral<const volatile T> : is_integral<T> {};
/// is_signed
///\ingroup type_traits
template <typename T> struct is_signed : false_type {};
@ -237,15 +254,15 @@ namespace etl
template <typename T> struct is_reference<T&> : 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 <typename T> struct is_pod : std::is_pod<T> {};
#else
/// For C++03, only fundamental and pointers types are recognised.
template <typename T> struct is_pod : etl::integral_constant<bool, etl::is_fundamental<T>::value ||
etl::is_pointer<T>::value> {};
etl::is_pointer<T>::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 <typename T> struct is_trivially_copy_assignable : etl::is_pod<T> {};
#endif
/// conditional
///\ingroup type_traits
template <bool B, typename T, typename F> struct conditional { typedef T type; };
@ -392,29 +410,80 @@ namespace etl
typename etl::remove_cv<U>::type>::type type;
};
/// is_base_of
///\ingroup type_traits
template<class TBase, class TDerived>
struct is_base_of
{
private:
template<typename T> struct dummy {};
struct internal: TDerived, dummy<int>{};
static TBase* check(TBase*);
template<typename T> static char check(dummy<T>*);
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 <typename T> struct alignment_of : integral_constant<size_t, size_t(alignof(T))> {};
#elif defined(ETL_COMPILER_MICROSOFT)
#ifdef ETL_COMPILER_MICROSOFT
template <typename T> struct alignment_of : integral_constant<size_t, size_t(__alignof(T))> {};
#elif defined(ETL_COMPILER_GCC)
#endif
#ifdef ETL_COMPILER_GCC
template <typename T> struct alignment_of : integral_constant<size_t, size_t(__alignof__(T))> {};
#elif defined(ETL_COMPILER_KEIL)
#endif
#ifdef ETL_COMPILER_KEIL
template <typename T> struct alignment_of : integral_constant<size_t, size_t(__alignof__(T))> {};
#elif defined(ETL_COMPILER_IAR)
#endif
#ifdef ETL_COMPILER_IAR
template <typename T> struct alignment_of : integral_constant<size_t, size_t(__ALIGNOF__(T))> {};
#elif defined(ETL_COMPILER_TI)
#endif
#ifdef ETL_COMPILER_TI
template <typename T> struct alignment_of : integral_constant<size_t, size_t(__ALIGNOF__(T))> {};
#else
// Best guess!
template <typename T> struct alignment_of : integral_constant<size_t, size_t(__alignof__(T))> {};
#endif
/// Specialisation of 'alignment_of' for 'void'.
///\ingroup type_traits
template <> struct alignment_of<void> : integral_constant <size_t, 0>{};
//***************************************************************************
/// Template to determine if a type is one of a specified list.
///\ingroup types
//***************************************************************************
template <typename T,
typename T1, typename T2 = void, typename T3 = void, typename T4 = void,
typename T5 = void, typename T6 = void, typename T7 = void, typename T8 = void,
typename T9 = void, typename T10 = void, typename T11 = void, typename T12 = void,
typename T13 = void, typename T14 = void, typename T15 = void, typename T16 = void>
struct is_one_of
{
static const bool value =
etl::is_same<T, T1>::value ||
etl::is_same<T, T2>::value ||
etl::is_same<T, T3>::value ||
etl::is_same<T, T4>::value ||
etl::is_same<T, T5>::value ||
etl::is_same<T, T6>::value ||
etl::is_same<T, T7>::value ||
etl::is_same<T, T8>::value ||
etl::is_same<T, T9>::value ||
etl::is_same<T, T10>::value ||
etl::is_same<T, T11>::value ||
etl::is_same<T, T12>::value ||
etl::is_same<T, T13>::value ||
etl::is_same<T, T14>::value ||
etl::is_same<T, T15>::value ||
etl::is_same<T, T16>::value;
};
}
#endif

500
src/type_traits_generator.h Normal file
View File

@ -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=<n> types_generator.h
// Where <n> 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 <stddef.h>
#include "platform.h"
#include "nullptr.h"
#if defined(ETL_C11_TYPE_TRAITS_SUPPORTED)
#include <type_traits>
#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 <typename T, const T VALUE>
struct integral_constant
{
static const T value = VALUE;
typedef T value_type;
typedef integral_constant<T, VALUE> type;
operator value_type() const
{
return value;
}
};
/// integral_constant specialisations
///\ingroup type_traits
typedef integral_constant<bool, false> false_type;
typedef integral_constant<bool, true> true_type;
/// remove_reference
///\ingroup type_traits
template <typename T> struct remove_reference { typedef T type; };
template <typename T> struct remove_reference<T&> { typedef T type; };
/// add_reference
///\ingroup type_traits
template <typename T> struct add_reference { typedef T& type; };
template <typename T> struct add_reference<T&> { typedef T& type; };
/// remove_pointer
///\ingroup type_traits
template <typename T> struct remove_pointer { typedef T type; };
template <typename T> struct remove_pointer<T*> { typedef T type; };
/// add_pointer
///\ingroup type_traits
template <typename T> struct add_pointer { typedef typename remove_reference<T>::type* type; };
/// is_const
///\ingroup type_traits
template <typename T> struct is_const : false_type {};
template <typename T> struct is_const<const T> : true_type {};
template <typename T> struct is_const<const volatile T> : true_type {};
/// remove_const
///\ingroup type_traits
template <typename T> struct remove_const { typedef T type; };
template <typename T> struct remove_const<const T> { typedef T type; };
/// add_const
///\ingroup type_traits
template <typename T> struct add_const { typedef const T type; };
template <typename T> struct add_const<const T> { typedef const T type; };
/// is_volatile
///\ingroup type_traits
template <typename T> struct is_volatile : false_type {};
template <typename T> struct is_volatile<volatile T> : true_type {};
template <typename T> struct is_volatile<const volatile T> : true_type {};
/// remove_volatile
///\ingroup type_traits
template <typename T> struct remove_volatile { typedef T type; };
template <typename T> struct remove_volatile<volatile T> { typedef T type; };
/// add_volatile
///\ingroup type_traits
template <typename T> struct add_volatile { typedef volatile T type; };
template <typename T> struct add_volatile<volatile T> { typedef volatile T type; };
/// remove_cv
///\ingroup type_traits
template <typename T> struct remove_cv
{
typedef typename remove_volatile<typename remove_const<T>::type>::type type;
};
/// add_cv
///\ingroup type_traits
template <typename T> struct add_cv
{
typedef typename add_volatile<typename add_const<T>::type>::type type;
};
/// is_integral
///\ingroup type_traits
template <typename T> struct is_integral : false_type {};
template <> struct is_integral<bool> : true_type {};
template <> struct is_integral<char> : true_type {};
template <> struct is_integral<unsigned char> : true_type {};
template <> struct is_integral<signed char> : true_type {};
template <> struct is_integral<wchar_t> : true_type {};
template <> struct is_integral<short> : true_type {};
template <> struct is_integral<unsigned short> : true_type {};
template <> struct is_integral<int> : true_type {};
template <> struct is_integral<unsigned int> : true_type {};
template <> struct is_integral<long> : true_type {};
template <> struct is_integral<unsigned long> : true_type {};
template <> struct is_integral<long long> : true_type {};
template <> struct is_integral<unsigned long long> : true_type {};
template <typename T> struct is_integral<const T> : is_integral<T> {};
template <typename T> struct is_integral<volatile T> : is_integral<T> {};
template <typename T> struct is_integral<const volatile T> : is_integral<T> {};
/// is_signed
///\ingroup type_traits
template <typename T> struct is_signed : false_type {};
template <> struct is_signed<char> : integral_constant<bool, (char(255) < 0)> {};
template <> struct is_signed<wchar_t> : public etl::integral_constant<bool, static_cast<bool>(wchar_t(-1) < wchar_t(0))> {};
template <> struct is_signed<signed char> : true_type {};
template <> struct is_signed<short> : true_type {};
template <> struct is_signed<int> : true_type {};
template <> struct is_signed<long> : true_type {};
template <> struct is_signed<long long> : true_type {};
template <> struct is_signed<float> : true_type{};
template <> struct is_signed<double> : true_type{};
template <> struct is_signed<long double> : true_type{};
template <typename T> struct is_signed<const T> : is_signed<T> {};
template <typename T> struct is_signed<volatile T> : is_signed<T> {};
template <typename T> struct is_signed<const volatile T> : is_signed<T> {};
/// is_unsigned
///\ingroup type_traits
template <typename T> struct is_unsigned : false_type {};
template <> struct is_unsigned<bool> : true_type {};
template <> struct is_unsigned<char> : integral_constant<bool, (char(255) > 0)> {};
template <> struct is_unsigned<unsigned char> : true_type {};
template <> struct is_unsigned<wchar_t> : public etl::integral_constant<bool, (wchar_t(-1) > wchar_t(0))> {};
template <> struct is_unsigned<unsigned short> : true_type {};
template <> struct is_unsigned<unsigned int> : true_type {};
template <> struct is_unsigned<unsigned long> : true_type {};
template <> struct is_unsigned<unsigned long long> : true_type {};
template <typename T> struct is_unsigned<const T> : is_unsigned<T> {};
template <typename T> struct is_unsigned<volatile T> : is_unsigned<T> {};
template <typename T> struct is_unsigned<const volatile T> : is_unsigned<T> {};
/// is_floating_point
///\ingroup type_traits
template <typename T> struct is_floating_point : false_type {};
template <> struct is_floating_point<float> : true_type {};
template <> struct is_floating_point<double> : true_type {};
template <> struct is_floating_point<long double> : true_type {};
template <typename T> struct is_floating_point<const T> : is_floating_point<T> {};
template <typename T> struct is_floating_point<volatile T> : is_floating_point<T> {};
template <typename T> struct is_floating_point<const volatile T> : is_floating_point<T> {};
/// is_same
///\ingroup type_traits
template <typename T1, typename T2> struct is_same : public false_type {};
template <typename T> struct is_same<T, T> : public true_type {};
/// is_void
///\ingroup type_traits
template<typename T> struct is_void : false_type {};
template<> struct is_void<void> : true_type {};
/// is_arithmetic
///\ingroup type_traits
template<typename T> struct is_arithmetic : integral_constant<bool, is_integral<T>::value || is_floating_point<T>::value> {};
/// is_fundamental
///\ingroup type_traits
template <typename T> struct is_fundamental : integral_constant<bool, is_arithmetic<T>::value ||
is_void<T>::value ||
is_same<std::nullptr_t,
typename remove_cv<T>::type>::value> {};
/// is_compound
///\ingroup type_traits
template <typename T> struct is_compound : integral_constant<bool, !is_fundamental<T>::value> {};
/// is_array
///\ingroup type_traits
template <typename T> struct is_array : false_type {};
template <typename T> struct is_array<T[]> : true_type {};
template <typename T, size_t MAXN> struct is_array<T[MAXN]> : true_type {};
/// is_pointer
///\ingroup type_traits
template <typename T> struct is_pointer : false_type {};
template <typename T> struct is_pointer<T*> : true_type {};
/// is_reference
///\ingroup type_traits
template <typename T> struct is_reference : false_type {};
template <typename T> struct is_reference<T&> : 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 <typename T> struct is_pod : std::is_pod<T> {};
#else
/// For C++03, only fundamental and pointers types are recognised.
template <typename T> struct is_pod : etl::integral_constant<bool, etl::is_fundamental<T>::value ||
etl::is_pointer<T>::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 <typename T> struct is_trivially_constructible : std::is_trivially_constructible<T> {};
/// is_trivially_copy_constructible
/// For C++03, only POD types are recognised.
///\ingroup type_traits
template <typename T> struct is_trivially_copy_constructible : std::is_trivially_copy_constructible<T> {};
/// is_trivially_destructible
/// For C++03, only POD types are recognised.
///\ingroup type_traits
template <typename T> struct is_trivially_destructible : std::is_trivially_destructible<T> {};
/// is_trivially_copy_assignable
/// For C++03, only POD types are recognised.
///\ingroup type_traits
template <typename T> struct is_trivially_copy_assignable : std::is_trivially_copy_assignable<T> {};
#else
/// is_trivially_constructible
/// For C++03, only POD types are recognised.
///\ingroup type_traits
template <typename T> struct is_trivially_constructible : etl::is_pod<T> {};
/// is_trivially_copy_constructible
/// For C++03, only POD types are recognised.
///\ingroup type_traits
template <typename T> struct is_trivially_copy_constructible : etl::is_pod<T> {};
/// is_trivially_destructible
/// For C++03, only POD types are recognised.
///\ingroup type_traits
template <typename T> struct is_trivially_destructible : etl::is_pod<T> {};
/// is_trivially_copy_assignable
/// For C++03, only POD types are recognised.
///\ingroup type_traits
template <typename T> struct is_trivially_copy_assignable : etl::is_pod<T> {};
#endif
/// conditional
///\ingroup type_traits
template <bool B, typename T, typename F> struct conditional { typedef T type; };
template <typename T, typename F> struct conditional<false, T, F> { typedef F type; };
/// make_signed
///\ingroup type_traits
template <typename T> struct make_signed { typedef T type; };
template <> struct make_signed<char> { typedef signed char type; };
template <> struct make_signed<unsigned char> { typedef signed char type; };
template <> struct make_signed<wchar_t>
{
typedef etl::conditional<sizeof(wchar_t) == sizeof(int16_t),
int16_t,
etl::conditional<sizeof(wchar_t) == sizeof(int32_t),
int32_t,
void>::type>::type type;
};
template <> struct make_signed<unsigned short> { typedef short type; };
template <> struct make_signed<unsigned int> { typedef int type; };
template <> struct make_signed<unsigned long> { typedef long type; };
template <> struct make_signed<unsigned long long> { typedef long long type; };
template <typename T> struct make_signed<const T> : add_const<typename make_signed<T>::type> {};
template <typename T> struct make_signed<volatile T> : add_volatile<typename make_signed<T>::type> {};
template <typename T> struct make_signed<const volatile T> : add_const<typename add_volatile<typename make_signed<T>::type>::type> {};
/// make_unsigned
///\ingroup type_traits
template <typename T> struct make_unsigned { typedef T type; };
template <> struct make_unsigned<char> { typedef unsigned char type; };
template <> struct make_unsigned<signed char> { typedef unsigned char type; };
template <> struct make_unsigned<short> { typedef unsigned short type; };
template <> struct make_unsigned<wchar_t>
{
typedef etl::conditional<sizeof(wchar_t) == sizeof(uint16_t),
uint16_t,
etl::conditional<sizeof(wchar_t) == sizeof(uint32_t),
uint32_t,
void>::type>::type type;
};
template <> struct make_unsigned<int> { typedef unsigned int type; };
template <> struct make_unsigned<long> { typedef unsigned long type; };
template <> struct make_unsigned<long long> { typedef unsigned long long type; };
template <typename T> struct make_unsigned<const T> : add_const<typename make_unsigned<T>::type> {};
template <typename T> struct make_unsigned<volatile T> : add_volatile<typename make_unsigned<T>::type> {};
template <typename T> struct make_unsigned<const volatile T> : add_const<typename add_volatile<typename make_unsigned<T>::type>::type> {};
/// enable_if
///\ingroup type_traits
template <bool B, typename T = void> struct enable_if {};
template <typename T> struct enable_if<true, T> { typedef T type; };
/// extent
///\ingroup type_traits
template <typename T, size_t MAXN = 0>
struct extent : integral_constant<size_t, 0> {};
template <typename T>
struct extent<T[], 0> : integral_constant<size_t, 0> {};
template <typename T, size_t MAXN>
struct extent<T[], MAXN> : integral_constant<size_t, extent<T, MAXN - 1>::value> {};
template <typename T, size_t MAXN>
struct extent<T[MAXN], 0> : integral_constant<size_t, MAXN> {};
template <typename T, size_t I, size_t MAXN>
struct extent<T[I], MAXN> : integral_constant<size_t, extent<T, MAXN - 1>::value> {};
/// remove_extent
///\ingroup type_traits
template <typename T> struct remove_extent { typedef T type; };
template <typename T> struct remove_extent<T[]> { typedef T type; };
template <typename T, size_t MAXN> struct remove_extent<T[MAXN]> { typedef T type;};
/// remove_all_extents
///\ingroup type_traits
template <typename T> struct remove_all_extents { typedef T type;};
template <typename T> struct remove_all_extents<T[]> { typedef typename remove_all_extents<T>::type type; };
template <typename T, size_t MAXN> struct remove_all_extents<T[MAXN]> { typedef typename remove_all_extents<T>::type type; };
/// rank
///\ingroup type_traits
template <typename T>struct rank : integral_constant<size_t, 0> {};
template <typename T> struct rank<T[]> : public integral_constant<size_t, rank<T>::value + 1> {};
template <typename T, size_t MAXN> struct rank<T[MAXN]> : public integral_constant<size_t, rank<T>::value + 1> {};
/// decay
///\ingroup type_traits
template <typename T>
struct decay
{
typedef typename etl::remove_reference<T>::type U;
typedef typename etl::conditional<etl::is_array<U>::value,
typename etl::remove_extent<U>::type*,
typename etl::remove_cv<U>::type>::type type;
};
/// is_base_of
///\ingroup type_traits
template<class TBase, class TDerived>
struct is_base_of
{
private:
template<typename T> struct dummy {};
struct internal: TDerived, dummy<int>{};
static TBase* check(TBase*);
template<typename T> static char check(dummy<T>*);
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 <typename T> struct alignment_of : integral_constant<size_t, size_t(__alignof(T))> {};
#endif
#ifdef ETL_COMPILER_GCC
template <typename T> struct alignment_of : integral_constant<size_t, size_t(__alignof__(T))> {};
#endif
#ifdef ETL_COMPILER_KEIL
template <typename T> struct alignment_of : integral_constant<size_t, size_t(__alignof__(T))> {};
#endif
#ifdef ETL_COMPILER_IAR
template <typename T> struct alignment_of : integral_constant<size_t, size_t(__ALIGNOF__(T))> {};
#endif
#ifdef ETL_COMPILER_TI
template <typename T> struct alignment_of : integral_constant<size_t, size_t(__ALIGNOF__(T))> {};
#endif
/// Specialisation of 'alignment_of' for 'void'.
///\ingroup type_traits
template <> struct alignment_of<void> : integral_constant <size_t, 0>{};
/*[[[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 <typename T,")
cog.out(" ")
cog.out("typename T1, ")
for n in range(2, int(IsOneOf)):
cog.out("typename T%s = void, " % n)
if n % 4 == 0:
cog.outl("")
cog.out(" ")
cog.outl("typename T%s = void>" % 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<T, T%s>::value ||" % n)
cog.outl(" etl::is_same<T, T%s>::value;" % IsOneOf)
cog.outl("};")
]]]*/
/*[[[end]]]*/
}
#endif

View File

@ -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<T1, T2, T3, T4, T5, T6, T7, T8>::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<type_id_t>::max;
//***************************************************************************
/// Do we pass this type by value?
//***************************************************************************
template <typename T>
struct pass_by_value : integral_constant<bool, etl::is_fundamental<T>::value || etl::is_pointer<T>::value>
{
};
//***************************************************************************
/// Define the type for a parameter.
//***************************************************************************
template <typename T, bool>
struct type_definition;
//***************************************************************************
/// Pass by value.
//***************************************************************************
template <typename T>
struct type_definition<T, true>
{
typedef T type;
};
//***************************************************************************
/// Pass by const reference.
//***************************************************************************
template <typename T>
struct type_definition<T, false>
{
typedef const T& type;
};
//***************************************************************************
/// Determines the type for parameters.
//***************************************************************************
template <typename T>
struct parameter_type : public type_definition<T, pass_by_value<T>::value>
{
};
//***************************************************************************
/// Short form of no_type placeholders.
//***************************************************************************
@ -249,14 +213,14 @@ namespace etl
friend class variant;
virtual void read(typename parameter_type<R1>::type value) = 0;
virtual void read(typename parameter_type<R2>::type value) = 0;
virtual void read(typename parameter_type<R3>::type value) = 0;
virtual void read(typename parameter_type<R4>::type value) = 0;
virtual void read(typename parameter_type<R5>::type value) = 0;
virtual void read(typename parameter_type<R6>::type value) = 0;
virtual void read(typename parameter_type<R7>::type value) = 0;
virtual void read(typename parameter_type<R8>::type value) = 0;
virtual void read(typename etl::parameter_type<R1>::type value) = 0;
virtual void read(typename etl::parameter_type<R2>::type value) = 0;
virtual void read(typename etl::parameter_type<R3>::type value) = 0;
virtual void read(typename etl::parameter_type<R4>::type value) = 0;
virtual void read(typename etl::parameter_type<R5>::type value) = 0;
virtual void read(typename etl::parameter_type<R6>::type value) = 0;
virtual void read(typename etl::parameter_type<R7>::type value) = 0;
virtual void read(typename etl::parameter_type<R8>::type value) = 0;
};
//*************************************************************************
@ -269,13 +233,13 @@ namespace etl
friend class variant;
virtual void read(typename parameter_type<R1>::type value) = 0;
virtual void read(typename parameter_type<R2>::type value) = 0;
virtual void read(typename parameter_type<R3>::type value) = 0;
virtual void read(typename parameter_type<R4>::type value) = 0;
virtual void read(typename parameter_type<R5>::type value) = 0;
virtual void read(typename parameter_type<R6>::type value) = 0;
virtual void read(typename parameter_type<R7>::type value) = 0;
virtual void read(typename etl::parameter_type<R1>::type value) = 0;
virtual void read(typename etl::parameter_type<R2>::type value) = 0;
virtual void read(typename etl::parameter_type<R3>::type value) = 0;
virtual void read(typename etl::parameter_type<R4>::type value) = 0;
virtual void read(typename etl::parameter_type<R5>::type value) = 0;
virtual void read(typename etl::parameter_type<R6>::type value) = 0;
virtual void read(typename etl::parameter_type<R7>::type value) = 0;
private:
@ -292,12 +256,12 @@ namespace etl
friend class variant;
virtual void read(typename parameter_type<R1>::type value) = 0;
virtual void read(typename parameter_type<R2>::type value) = 0;
virtual void read(typename parameter_type<R3>::type value) = 0;
virtual void read(typename parameter_type<R4>::type value) = 0;
virtual void read(typename parameter_type<R5>::type value) = 0;
virtual void read(typename parameter_type<R6>::type value) = 0;
virtual void read(typename etl::parameter_type<R1>::type value) = 0;
virtual void read(typename etl::parameter_type<R2>::type value) = 0;
virtual void read(typename etl::parameter_type<R3>::type value) = 0;
virtual void read(typename etl::parameter_type<R4>::type value) = 0;
virtual void read(typename etl::parameter_type<R5>::type value) = 0;
virtual void read(typename etl::parameter_type<R6>::type value) = 0;
private:
@ -315,11 +279,11 @@ namespace etl
friend class variant;
virtual void read(typename parameter_type<R1>::type value) = 0;
virtual void read(typename parameter_type<R2>::type value) = 0;
virtual void read(typename parameter_type<R3>::type value) = 0;
virtual void read(typename parameter_type<R4>::type value) = 0;
virtual void read(typename parameter_type<R5>::type value) = 0;
virtual void read(typename etl::parameter_type<R1>::type value) = 0;
virtual void read(typename etl::parameter_type<R2>::type value) = 0;
virtual void read(typename etl::parameter_type<R3>::type value) = 0;
virtual void read(typename etl::parameter_type<R4>::type value) = 0;
virtual void read(typename etl::parameter_type<R5>::type value) = 0;
private:
@ -338,10 +302,10 @@ namespace etl
friend class variant;
virtual void read(typename parameter_type<R1>::type value) = 0;
virtual void read(typename parameter_type<R2>::type value) = 0;
virtual void read(typename parameter_type<R3>::type value) = 0;
virtual void read(typename parameter_type<R4>::type value) = 0;
virtual void read(typename etl::parameter_type<R1>::type value) = 0;
virtual void read(typename etl::parameter_type<R2>::type value) = 0;
virtual void read(typename etl::parameter_type<R3>::type value) = 0;
virtual void read(typename etl::parameter_type<R4>::type value) = 0;
private:
@ -361,9 +325,9 @@ namespace etl
friend class variant;
virtual void read(typename parameter_type<R1>::type value) = 0;
virtual void read(typename parameter_type<R2>::type value) = 0;
virtual void read(typename parameter_type<R3>::type value) = 0;
virtual void read(typename etl::parameter_type<R1>::type value) = 0;
virtual void read(typename etl::parameter_type<R2>::type value) = 0;
virtual void read(typename etl::parameter_type<R3>::type value) = 0;
private:
@ -384,8 +348,8 @@ namespace etl
friend class variant;
virtual void read(typename parameter_type<R1>::type value) = 0;
virtual void read(typename parameter_type<R2>::type value) = 0;
virtual void read(typename etl::parameter_type<R1>::type value) = 0;
virtual void read(typename etl::parameter_type<R2>::type value) = 0;
private:
@ -407,7 +371,7 @@ namespace etl
friend class variant;
virtual void read(typename parameter_type<R1>::type value) = 0;
virtual void read(typename etl::parameter_type<R1>::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<sizeof(largest_t), etl::largest_alignment<T1, T2, T3, T4, T5, T6, T7, T8>::value>::type data;
typename etl::aligned_storage<SIZE, ALIGNMENT>::type data;
//***************************************************************************
/// The id of the current stored type.

984
temp/message_router.h Normal file
View File

@ -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 <stdint.h>
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 <const size_t ID_>
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=<n> message_router_generator.h
// Where <n> 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 <typename TProcessor,
typename T1, typename T2 = void, typename T3 = void, typename T4 = void,
typename T5 = void, typename T6 = void, typename T7 = void, typename T8 = void,
typename T9 = void, typename T10 = void, typename T11 = void, typename T12 = void,
typename T13 = void, typename T14 = void, typename T15 = void, typename T16 = void>
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<TProcessor*>(this)->on_receive(source, static_cast<const T1&>(msg)); break;
case T2::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T2&>(msg)); break;
case T3::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T3&>(msg)); break;
case T4::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T4&>(msg)); break;
case T5::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T5&>(msg)); break;
case T6::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T6&>(msg)); break;
case T7::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T7&>(msg)); break;
case T8::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T8&>(msg)); break;
case T9::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T9&>(msg)); break;
case T10::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T10&>(msg)); break;
case T11::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T11&>(msg)); break;
case T12::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T12&>(msg)); break;
case T13::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T13&>(msg)); break;
case T14::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T14&>(msg)); break;
case T15::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T15&>(msg)); break;
case T16::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T16&>(msg)); break;
default: static_cast<TProcessor*>(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 <typename TProcessor,
typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8,
typename T9, typename T10, typename T11, typename T12,
typename T13, typename T14, typename T15>
class message_router<TProcessor, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, void>
: 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<TProcessor*>(this)->on_receive(source, static_cast<const T1&>(msg)); break;
case T2::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T2&>(msg)); break;
case T3::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T3&>(msg)); break;
case T4::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T4&>(msg)); break;
case T5::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T5&>(msg)); break;
case T6::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T6&>(msg)); break;
case T7::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T7&>(msg)); break;
case T8::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T8&>(msg)); break;
case T9::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T9&>(msg)); break;
case T10::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T10&>(msg)); break;
case T11::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T11&>(msg)); break;
case T12::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T12&>(msg)); break;
case T13::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T13&>(msg)); break;
case T14::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T14&>(msg)); break;
case T15::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T15&>(msg)); break;
default: static_cast<TProcessor*>(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 <typename TProcessor,
typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8,
typename T9, typename T10, typename T11, typename T12,
typename T13, typename T14>
class message_router<TProcessor, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, void, void>
: 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<TProcessor*>(this)->on_receive(source, static_cast<const T1&>(msg)); break;
case T2::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T2&>(msg)); break;
case T3::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T3&>(msg)); break;
case T4::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T4&>(msg)); break;
case T5::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T5&>(msg)); break;
case T6::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T6&>(msg)); break;
case T7::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T7&>(msg)); break;
case T8::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T8&>(msg)); break;
case T9::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T9&>(msg)); break;
case T10::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T10&>(msg)); break;
case T11::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T11&>(msg)); break;
case T12::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T12&>(msg)); break;
case T13::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T13&>(msg)); break;
case T14::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T14&>(msg)); break;
default: static_cast<TProcessor*>(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 <typename TProcessor,
typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8,
typename T9, typename T10, typename T11, typename T12,
typename T13>
class message_router<TProcessor, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, void, void, void>
: 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<TProcessor*>(this)->on_receive(source, static_cast<const T1&>(msg)); break;
case T2::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T2&>(msg)); break;
case T3::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T3&>(msg)); break;
case T4::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T4&>(msg)); break;
case T5::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T5&>(msg)); break;
case T6::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T6&>(msg)); break;
case T7::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T7&>(msg)); break;
case T8::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T8&>(msg)); break;
case T9::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T9&>(msg)); break;
case T10::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T10&>(msg)); break;
case T11::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T11&>(msg)); break;
case T12::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T12&>(msg)); break;
case T13::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T13&>(msg)); break;
default: static_cast<TProcessor*>(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 <typename TProcessor,
typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8,
typename T9, typename T10, typename T11, typename T12>
class message_router<TProcessor, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, void, void, void, void>
: 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<TProcessor*>(this)->on_receive(source, static_cast<const T1&>(msg)); break;
case T2::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T2&>(msg)); break;
case T3::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T3&>(msg)); break;
case T4::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T4&>(msg)); break;
case T5::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T5&>(msg)); break;
case T6::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T6&>(msg)); break;
case T7::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T7&>(msg)); break;
case T8::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T8&>(msg)); break;
case T9::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T9&>(msg)); break;
case T10::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T10&>(msg)); break;
case T11::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T11&>(msg)); break;
case T12::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T12&>(msg)); break;
default: static_cast<TProcessor*>(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 <typename TProcessor,
typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8,
typename T9, typename T10, typename T11>
class message_router<TProcessor, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, void, void, void, void, void>
: 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<TProcessor*>(this)->on_receive(source, static_cast<const T1&>(msg)); break;
case T2::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T2&>(msg)); break;
case T3::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T3&>(msg)); break;
case T4::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T4&>(msg)); break;
case T5::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T5&>(msg)); break;
case T6::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T6&>(msg)); break;
case T7::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T7&>(msg)); break;
case T8::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T8&>(msg)); break;
case T9::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T9&>(msg)); break;
case T10::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T10&>(msg)); break;
case T11::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T11&>(msg)); break;
default: static_cast<TProcessor*>(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 <typename TProcessor,
typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8,
typename T9, typename T10>
class message_router<TProcessor, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, void, void, void, void, void, void>
: 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<TProcessor*>(this)->on_receive(source, static_cast<const T1&>(msg)); break;
case T2::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T2&>(msg)); break;
case T3::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T3&>(msg)); break;
case T4::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T4&>(msg)); break;
case T5::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T5&>(msg)); break;
case T6::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T6&>(msg)); break;
case T7::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T7&>(msg)); break;
case T8::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T8&>(msg)); break;
case T9::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T9&>(msg)); break;
case T10::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T10&>(msg)); break;
default: static_cast<TProcessor*>(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 <typename TProcessor,
typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8,
typename T9>
class message_router<TProcessor, T1, T2, T3, T4, T5, T6, T7, T8, T9, void, void, void, void, void, void, void>
: 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<TProcessor*>(this)->on_receive(source, static_cast<const T1&>(msg)); break;
case T2::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T2&>(msg)); break;
case T3::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T3&>(msg)); break;
case T4::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T4&>(msg)); break;
case T5::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T5&>(msg)); break;
case T6::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T6&>(msg)); break;
case T7::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T7&>(msg)); break;
case T8::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T8&>(msg)); break;
case T9::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T9&>(msg)); break;
default: static_cast<TProcessor*>(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 <typename TProcessor,
typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8>
class message_router<TProcessor, T1, T2, T3, T4, T5, T6, T7, T8, void, void, void, void, void, void, void, void>
: 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<TProcessor*>(this)->on_receive(source, static_cast<const T1&>(msg)); break;
case T2::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T2&>(msg)); break;
case T3::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T3&>(msg)); break;
case T4::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T4&>(msg)); break;
case T5::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T5&>(msg)); break;
case T6::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T6&>(msg)); break;
case T7::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T7&>(msg)); break;
case T8::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T8&>(msg)); break;
default: static_cast<TProcessor*>(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 <typename TProcessor,
typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7>
class message_router<TProcessor, T1, T2, T3, T4, T5, T6, T7, void, void, void, void, void, void, void, void, void>
: 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<TProcessor*>(this)->on_receive(source, static_cast<const T1&>(msg)); break;
case T2::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T2&>(msg)); break;
case T3::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T3&>(msg)); break;
case T4::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T4&>(msg)); break;
case T5::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T5&>(msg)); break;
case T6::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T6&>(msg)); break;
case T7::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T7&>(msg)); break;
default: static_cast<TProcessor*>(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 <typename TProcessor,
typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6>
class message_router<TProcessor, T1, T2, T3, T4, T5, T6, void, void, void, void, void, void, void, void, void, void>
: 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<TProcessor*>(this)->on_receive(source, static_cast<const T1&>(msg)); break;
case T2::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T2&>(msg)); break;
case T3::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T3&>(msg)); break;
case T4::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T4&>(msg)); break;
case T5::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T5&>(msg)); break;
case T6::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T6&>(msg)); break;
default: static_cast<TProcessor*>(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 <typename TProcessor,
typename T1, typename T2, typename T3, typename T4,
typename T5>
class message_router<TProcessor, T1, T2, T3, T4, T5, void, void, void, void, void, void, void, void, void, void, void>
: 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<TProcessor*>(this)->on_receive(source, static_cast<const T1&>(msg)); break;
case T2::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T2&>(msg)); break;
case T3::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T3&>(msg)); break;
case T4::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T4&>(msg)); break;
case T5::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T5&>(msg)); break;
default: static_cast<TProcessor*>(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 <typename TProcessor,
typename T1, typename T2, typename T3, typename T4>
class message_router<TProcessor, T1, T2, T3, T4, void, void, void, void, void, void, void, void, void, void, void, void>
: 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<TProcessor*>(this)->on_receive(source, static_cast<const T1&>(msg)); break;
case T2::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T2&>(msg)); break;
case T3::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T3&>(msg)); break;
case T4::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T4&>(msg)); break;
default: static_cast<TProcessor*>(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 <typename TProcessor,
typename T1, typename T2, typename T3>
class message_router<TProcessor, T1, T2, T3, void, void, void, void, void, void, void, void, void, void, void, void, void>
: 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<TProcessor*>(this)->on_receive(source, static_cast<const T1&>(msg)); break;
case T2::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T2&>(msg)); break;
case T3::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T3&>(msg)); break;
default: static_cast<TProcessor*>(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<const T1&>(msg)); break;
case T2::ID: new (&storage) T2(static_cast<const T2&>(msg)); break;
case T3::ID: new (&storage) T3(static_cast<const T3&>(msg)); break;
default: break;
}
}
~message_packet()
{
static_cast<const etl::imessage*>(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<const T1&>(msg)); break;
case T2::ID: new (&storage) T2(static_cast<const T2&>(msg)); break;
case T3::ID: new (&storage) T3(static_cast<const T3&>(msg)); break;
default: break;
}
}
message_packet& operator = (const message_packet& other)
{
if (this != &other)
{
static_cast<const etl::imessage*>(storage).~imessage();
new (this) message_packet(other);
}
}
const etl::imessage& get_imessage() const
{
return *reiniterpret_cast<const imessage*>(storage);
}
operator const imessage&() const
{
return get_imessage();
}
private:
etl::aligned_storage<etl::largest<T1, T2, T3>::size, etl::largest_alignment<T1, T2, T3>::value>::type storage;
};
};
//***************************************************************************
// Specialisation for 2 message types.
//***************************************************************************
template <typename TProcessor,
typename T1, typename T2>
class message_router<TProcessor, T1, T2, void, void, void, void, void, void, void, void, void, void, void, void, void, void>
: 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<TProcessor*>(this)->on_receive(source, static_cast<const T1&>(msg)); break;
case T2::ID: static_cast<TProcessor*>(this)->on_receive(source, static_cast<const T2&>(msg)); break;
default: static_cast<TProcessor*>(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 <typename TProcessor,
typename T1>
class message_router<TProcessor, T1, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void>
: 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<TProcessor*>(this)->on_receive(source, static_cast<const T1&>(msg)); break;
default: static_cast<TProcessor*>(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

View File

@ -172,6 +172,8 @@
<Unit filename="../../src/fnv_1.h" />
<Unit filename="../../src/forward_list.h" />
<Unit filename="../../src/frame_check_sequence.h" />
<Unit filename="../../src/fsm.h" />
<Unit filename="../../src/fsm_generator.h" />
<Unit filename="../../src/function.h" />
<Unit filename="../../src/functional.h" />
<Unit filename="../../src/functors.h" />
@ -193,12 +195,15 @@
<Unit filename="../../src/iterator.h" />
<Unit filename="../../src/jenkins.h" />
<Unit filename="../../src/largest.h" />
<Unit filename="../../src/largest_generator.h" />
<Unit filename="../../src/list.h" />
<Unit filename="../../src/log.h" />
<Unit filename="../../src/map.h" />
<Unit filename="../../src/memory.h" />
<Unit filename="../../src/message_processor.h" />
<Unit filename="../../src/message_processor_generator.h" />
<Unit filename="../../src/message_router.h" />
<Unit filename="../../src/message_router_generator.h" />
<Unit filename="../../src/multimap.h" />
<Unit filename="../../src/multiset.h" />
<Unit filename="../../src/murmur3.h" />
@ -206,6 +211,7 @@
<Unit filename="../../src/numeric.h" />
<Unit filename="../../src/observer.h" />
<Unit filename="../../src/optional.h" />
<Unit filename="../../src/packet.h" />
<Unit filename="../../src/parameter_type.h" />
<Unit filename="../../src/pearson.cpp" />
<Unit filename="../../src/pearson.h" />
@ -226,12 +232,16 @@
<Unit filename="../../src/reference_flat_multimap.h" />
<Unit filename="../../src/reference_flat_multiset.h" />
<Unit filename="../../src/reference_flat_set.h" />
<Unit filename="../../src/scheduler.h" />
<Unit filename="../../src/set.h" />
<Unit filename="../../src/smallest.h" />
<Unit filename="../../src/smallest_generator.h" />
<Unit filename="../../src/stack.h" />
<Unit filename="../../src/static_assert.h" />
<Unit filename="../../src/task.h" />
<Unit filename="../../src/type_def.h" />
<Unit filename="../../src/type_traits.h" />
<Unit filename="../../src/type_traits_generator.h" />
<Unit filename="../../src/u16string.h" />
<Unit filename="../../src/u32string.h" />
<Unit filename="../../src/unordered_map.h" />
@ -273,6 +283,7 @@
<Unit filename="../test_flat_set.cpp" />
<Unit filename="../test_fnv_1.cpp" />
<Unit filename="../test_forward_list.cpp" />
<Unit filename="../test_fsm.cpp" />
<Unit filename="../test_function.cpp" />
<Unit filename="../test_functional.cpp" />
<Unit filename="../test_hash.cpp" />
@ -291,12 +302,14 @@
<Unit filename="../test_map.cpp" />
<Unit filename="../test_maths.cpp" />
<Unit filename="../test_memory.cpp" />
<Unit filename="../test_message_router.cpp" />
<Unit filename="../test_multimap.cpp" />
<Unit filename="../test_multiset.cpp" />
<Unit filename="../test_murmur3.cpp" />
<Unit filename="../test_numeric.cpp" />
<Unit filename="../test_observer.cpp" />
<Unit filename="../test_optional.cpp" />
<Unit filename="../test_packet.cpp" />
<Unit filename="../test_pearson.cpp" />
<Unit filename="../test_pool.cpp" />
<Unit filename="../test_priority_queue.cpp" />
@ -314,6 +327,7 @@
<Unit filename="../test_string_u16.cpp" />
<Unit filename="../test_string_u32.cpp" />
<Unit filename="../test_string_wchar_t.cpp" />
<Unit filename="../test_task_scheduler.cpp" />
<Unit filename="../test_type_def.cpp" />
<Unit filename="../test_type_traits.cpp" />
<Unit filename="../test_unordered_map.cpp" />

View File

@ -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"
<limits>
<type_traits>
@ -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 @@
<stddef.h>
"exception.h"
1497713618 d:\users\john\documents\programming\github\etl\test\data.h
1500929827 d:\users\john\documents\programming\github\etl\test\data.h
<ostream>
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"
<set>
<array>
@ -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"
<list>
@ -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"
<type_traits>
@ -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>
"queue.h"
@ -3937,12 +3937,12 @@
<stddef.h>
"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"
<type_traits>
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"
<stack>
"data.h"
@ -3970,7 +3970,7 @@
<stddef.h>
"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"
<vector>
<array>
@ -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"
<type_traits>
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
<algorithm>
<iterator>
<utility>
@ -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
<stddef.h>
"platform.h"
"nullptr.h"
<type_traits>
1482948766 d:\users\john\documents\programming\github\etl\src\container.h
<stddef.h>
<iterator>
1496993010 d:\users\john\documents\programming\github\etl\src\alignment.h
1500929841 d:\users\john\documents\programming\github\etl\src\alignment.h
<stdint.h>
"type_traits.h"
"static_assert.h"
@ -5369,11 +5370,11 @@
<stdint.h>
"log.h"
1482948766 d:\users\john\documents\programming\github\etl\src\smallest.h
1500977554 d:\users\john\documents\programming\github\etl\src\smallest.h
<stdint.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
<algorithm>
<iterator>
<string.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
<stddef.h>
<stdint.h>
<iterator>
@ -5515,7 +5516,8 @@
1482948766 d:\users\john\documents\programming\github\etl\src\fixed_iterator.h
<iterator>
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
<stddef.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
<type_traits>
<stddef.h>
<stdint.h>
@ -5580,22 +5582,10 @@
"private/vector_base.h"
"private/ivectorpointer.h"
1494277860 d:\users\john\documents\programming\github\etl\src\flat_set.h
<stddef.h>
<iterator>
<functional>
<algorithm>
<utility>
"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
<iterator>
@ -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
<iterator>
<algorithm>
<functional>
@ -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"
<iterator>
<algorithm>
@ -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
<iterator>
<algorithm>
<functional>
@ -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
<stddef.h>
<iterator>
<functional>
@ -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
<stddef.h>
<stdint.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
<stddef.h>
<iterator>
<functional>
@ -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
<stddef.h>
<stdint.h>
<algorithm>
@ -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
<stdint.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
<stdint.h>
<limits.h>
@ -5988,20 +5979,10 @@
1479511691 at_multimap.h"
1497306512 d:\users\john\documents\programming\github\etl\src\flat_multimap.h
<stddef.h>
<iterator>
<algorithm>
<functional>
<utility>
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
<iterator>
@ -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"
<set>
<array>
@ -6035,22 +6016,10 @@
1479511691 at_multiset.h"
1494277860 d:\users\john\documents\programming\github\etl\src\flat_multiset.h
<stddef.h>
<iterator>
<functional>
<algorithm>
<functional>
<utility>
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
<iterator>
@ -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 @@
<vector>
<string>
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"
<iterator>
<algorithm>
@ -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
<stddef.h>
<iterator>
<functional>
@ -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
<stddef.h>
<iterator>
<functional>
@ -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"
<queue>
"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
<stddef.h>
<functional>
<algorithm>
@ -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
<stddef.h>
<iterator>
<functional>
@ -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"
<set>
<array>
@ -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"
<array>
<algorithm>
@ -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
<iterator>
<algorithm>
<functional>
@ -6503,7 +6471,7 @@
"intrusive_links.h"
<vector>
1482948766 d:\users\john\documents\programming\github\etl\src\intrusive_queue.h
1500929826 d:\users\john\documents\programming\github\etl\src\intrusive_queue.h
<stddef.h>
"type_traits.h"
"error_handler.h"
@ -6515,13 +6483,13 @@
"intrusive_links.h"
<vector>
1482948766 d:\users\john\documents\programming\github\etl\src\intrusive_stack.h
1500929826 d:\users\john\documents\programming\github\etl\src\intrusive_stack.h
<stddef.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"
<string>
<array>
@ -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
<stddef.h>
<stdint.h>
<iterator>
@ -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"
<string>
<array>
@ -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"
<string>
<array>
@ -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"
<string>
<array>
<algorithm>
"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"
<vector>
<array>
@ -7855,7 +7823,7 @@
<iterator>
"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
<iterator>
<algorithm>
"type_traits.h"
@ -7865,10 +7833,10 @@
<assert.h>
"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
<stdint.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 @@
<stdint.h>
<vector>
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"
<stdint.h>
"random.h"
@ -7982,7 +7950,7 @@
<algorithm>
<fstream>
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"
<vector>
<array>
@ -8166,7 +8134,7 @@
"HelperMacros.h"
<csetjmp>
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"
<map>
<array>
@ -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
<stddef.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"
<map>
<array>
@ -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
<stddef.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"
<set>
<array>
@ -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
<iterator>
<algorithm>
<functional>
@ -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"
<set>
<array>
@ -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
<iterator>
<algorithm>
<functional>
@ -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"
<algorithm>
1500808011 source:d:\users\john\documents\programming\github\etl\test\test_fsm.cpp
"UnitTest++.h"
"fsm.h"
"enum_type.h"
"container.h"
<iostream>
1500977554 d:\users\john\documents\programming\github\etl\src\fsm.h
<stdint.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
<stdint.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"
<stdint.h>
<string>
<vector>
"task.h"
"scheduler.h"
"container.h"
1500929841 d:\users\john\documents\programming\github\etl\src\task.h
<stdint.h>
"error_handler.h"
"exception.h"
1500929841 d:\users\john\documents\programming\github\etl\src\scheduler.h
<stdint.h>
"vector.h"
"nullptr.h"
"error_handler.h"
"exception.h"
"task.h"
"type_traits.h"
"function.h"

View File

@ -2,39 +2,74 @@
<CodeBlocks_layout_file>
<FileVersion major="1" minor="0" />
<ActiveTarget name="Windows" />
<File name="..\test_memory.cpp" open="0" top="0" tabpos="25" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="15446" topLine="391" />
</Cursor>
</File>
<File name="..\..\src\variant.h" open="0" top="0" tabpos="7" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="36839" topLine="839" />
</Cursor>
</File>
<File name="..\..\..\unittest-cpp\UnitTest++\Config.h" open="0" top="0" tabpos="5" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="792" topLine="7" />
</Cursor>
</File>
<File name="..\..\..\unittest-cpp\UnitTest++\Checks.h" open="0" top="0" tabpos="5" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="469" topLine="0" />
</Cursor>
</File>
<File name="..\..\src\integral_limits.h" open="0" top="0" tabpos="1" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="7252" topLine="152" />
</Cursor>
</File>
<File name="..\test_io_port.cpp" open="0" top="0" tabpos="14" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="1452" topLine="3" />
</Cursor>
</File>
<File name="..\..\..\unittest-cpp\UnitTest++\Win32\TimeHelpers.cpp" open="0" top="0" tabpos="9" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="..\test_vector.cpp" open="1" top="0" tabpos="9" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="103" topLine="6" />
<Cursor1 position="1450" topLine="13" />
</Cursor>
</File>
<File name="..\test_flat_multimap.cpp" open="0" top="0" tabpos="6" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="..\..\src\intrusive_flat_multimap.h" open="0" top="0" tabpos="9" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="3425" topLine="85" />
<Cursor1 position="3269" topLine="248" />
</Cursor>
</File>
<File name="..\..\src\algorithm.h" open="0" top="0" tabpos="3" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="..\test_algorithm.cpp" open="0" top="0" tabpos="8" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="0" topLine="0" />
<Cursor1 position="11590" topLine="274" />
</Cursor>
</File>
<File name="..\test_map.cpp" open="0" top="0" tabpos="19" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="..\..\src\intrusive_flat_set.h" open="0" top="0" tabpos="13" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="6368" topLine="164" />
<Cursor1 position="7487" topLine="243" />
</Cursor>
</File>
<File name="..\..\src\unordered_set.h" open="0" top="0" tabpos="8" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="..\..\src\forward_list.h" open="0" top="0" tabpos="11" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="22041" topLine="620" />
<Cursor1 position="31509" topLine="979" />
</Cursor>
</File>
<File name="..\..\..\unittest-cpp\UnitTest++\TestRunner.h" open="0" top="0" tabpos="21" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="..\..\..\unittest-cpp\UnitTest++\TestResults.cpp" open="0" top="0" tabpos="24" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="156" topLine="0" />
<Cursor1 position="537" topLine="0" />
</Cursor>
</File>
<File name="..\test_forward_list.cpp" open="1" top="0" tabpos="2" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="9321" topLine="239" />
</Cursor>
</File>
<File name="..\..\..\unittest-cpp\UnitTest++\TestReporterStdout.cpp" open="0" top="0" tabpos="25" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="883" topLine="0" />
</Cursor>
</File>
<File name="..\..\..\unittest-cpp\UnitTest++\TestMacros.h" open="0" top="0" tabpos="13" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
@ -42,9 +77,24 @@
<Cursor1 position="1865" topLine="28" />
</Cursor>
</File>
<File name="..\..\..\unittest-cpp\UnitTest++\TestRunner.cpp" open="0" top="0" tabpos="20" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="..\..\src\error_handler.h" open="1" top="0" tabpos="4" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="2279" topLine="25" />
<Cursor1 position="4288" topLine="74" />
</Cursor>
</File>
<File name="..\test_integral_limits.cpp" open="1" top="0" tabpos="18" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="0" topLine="49" />
</Cursor>
</File>
<File name="..\..\src\binary.h" open="0" top="0" tabpos="2" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="14624" topLine="373" />
</Cursor>
</File>
<File name="..\..\src\type_traits.h" open="1" top="0" tabpos="12" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="20800" topLine="432" />
</Cursor>
</File>
<File name="..\..\..\unittest-cpp\UnitTest++\Test.cpp" open="0" top="0" tabpos="19" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
@ -57,79 +107,14 @@
<Cursor1 position="1450" topLine="13" />
</Cursor>
</File>
<File name="..\..\src\intrusive_flat_set.h" open="0" top="0" tabpos="13" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="..\test_deque.cpp" open="1" top="0" tabpos="5" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="7487" topLine="243" />
<Cursor1 position="1445" topLine="14" />
</Cursor>
</File>
<File name="..\..\src\deque.h" open="1" top="0" tabpos="3" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="..\..\src\unordered_set.h" open="0" top="0" tabpos="8" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="54765" topLine="1632" />
</Cursor>
</File>
<File name="..\test_flat_multiset.cpp" open="0" top="0" tabpos="21" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="3011" topLine="58" />
</Cursor>
</File>
<File name="..\test_forward_list.cpp" open="1" top="1" tabpos="2" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="9321" topLine="239" />
</Cursor>
</File>
<File name="..\..\src\binary.h" open="0" top="0" tabpos="2" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="14624" topLine="373" />
</Cursor>
</File>
<File name="..\..\src\forward_list.h" open="0" top="0" tabpos="11" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="31509" topLine="979" />
</Cursor>
</File>
<File name="..\test_flat_map.cpp" open="0" top="0" tabpos="20" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="18781" topLine="559" />
</Cursor>
</File>
<File name="..\main.cpp" open="0" top="0" tabpos="18" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="141" topLine="0" />
</Cursor>
</File>
<File name="..\..\src\list.h" open="0" top="0" tabpos="22" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="35098" topLine="1063" />
</Cursor>
</File>
<File name="..\..\src\integral_limits.h" open="0" top="0" tabpos="1" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="7252" topLine="152" />
</Cursor>
</File>
<File name="..\..\src\error_handler.h" open="1" top="0" tabpos="4" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="4288" topLine="86" />
</Cursor>
</File>
<File name="..\..\..\unittest-cpp\UnitTest++\TestReporterStdout.cpp" open="0" top="0" tabpos="25" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="883" topLine="0" />
</Cursor>
</File>
<File name="..\test_memory.cpp" open="0" top="0" tabpos="25" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="15446" topLine="391" />
</Cursor>
</File>
<File name="..\..\src\variant.h" open="0" top="0" tabpos="7" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="36839" topLine="839" />
</Cursor>
</File>
<File name="..\test_intrusive_forward_list.cpp" open="1" top="0" tabpos="1" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="29068" topLine="732" />
<Cursor1 position="22041" topLine="620" />
</Cursor>
</File>
<File name="..\..\src\intrusive_flat_multiset.h" open="0" top="0" tabpos="11" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
@ -137,34 +122,24 @@
<Cursor1 position="7605" topLine="248" />
</Cursor>
</File>
<File name="..\..\..\unittest-cpp\UnitTest++\ExecuteTest.h" open="0" top="0" tabpos="18" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="426" topLine="0" />
</Cursor>
</File>
<File name="..\..\src\vector.h" open="1" top="0" tabpos="6" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="15560" topLine="381" />
</Cursor>
</File>
<File name="..\test_iterator.cpp" open="0" top="0" tabpos="16" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="..\..\src\queue.h" open="1" top="0" tabpos="17" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="6722" topLine="118" />
<Cursor1 position="11193" topLine="271" />
</Cursor>
</File>
<File name="..\test_list.cpp" open="0" top="0" tabpos="27" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="..\test_flat_multiset.cpp" open="0" top="0" tabpos="21" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="17914" topLine="493" />
<Cursor1 position="3011" topLine="58" />
</Cursor>
</File>
<File name="..\test_algorithm.cpp" open="0" top="0" tabpos="8" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="..\test_flat_multimap.cpp" open="0" top="0" tabpos="6" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="11590" topLine="274" />
</Cursor>
</File>
<File name="..\test_flat_set.cpp" open="0" top="0" tabpos="7" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="11541" topLine="359" />
<Cursor1 position="3425" topLine="85" />
</Cursor>
</File>
<File name="..\..\src\unordered_multiset.h" open="0" top="0" tabpos="9" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
@ -172,64 +147,19 @@
<Cursor1 position="22451" topLine="619" />
</Cursor>
</File>
<File name="..\test_deque.cpp" open="1" top="0" tabpos="5" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="..\..\src\deque.h" open="1" top="0" tabpos="3" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="1445" topLine="14" />
<Cursor1 position="54765" topLine="1632" />
</Cursor>
</File>
<File name="..\..\src\private\pvoidvector.h" open="0" top="0" tabpos="5" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="..\test_flat_map.cpp" open="0" top="0" tabpos="20" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="18115" topLine="443" />
<Cursor1 position="18781" topLine="559" />
</Cursor>
</File>
<File name="..\..\..\unittest-cpp\UnitTest++\Config.h" open="0" top="0" tabpos="5" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<File name="..\..\src\alignment.h" open="1" top="1" tabpos="16" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="792" topLine="7" />
</Cursor>
</File>
<File name="..\..\src\static_assert.h" open="1" top="0" tabpos="7" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="1477" topLine="19" />
</Cursor>
</File>
<File name="..\test_intrusive_list.cpp" open="0" top="0" tabpos="24" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="27580" topLine="735" />
</Cursor>
</File>
<File name="..\test_vector.cpp" open="1" top="0" tabpos="9" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="1450" topLine="13" />
</Cursor>
</File>
<File name="..\..\src\iterator.h" open="0" top="0" tabpos="17" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="1557" topLine="0" />
</Cursor>
</File>
<File name="..\..\..\unittest-cpp\UnitTest++\Checks.h" open="0" top="0" tabpos="5" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="469" topLine="0" />
</Cursor>
</File>
<File name="..\..\..\unittest-cpp\UnitTest++\CurrentTest.cpp" open="0" top="0" tabpos="26" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="368" topLine="0" />
</Cursor>
</File>
<File name="..\..\src\intrusive_flat_multimap.h" open="0" top="0" tabpos="9" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="3269" topLine="248" />
</Cursor>
</File>
<File name="..\..\src\flat_map.h" open="1" top="0" tabpos="8" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="2722" topLine="51" />
</Cursor>
</File>
<File name="..\..\..\unittest-cpp\UnitTest++\TestResults.cpp" open="0" top="0" tabpos="24" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="537" topLine="0" />
<Cursor1 position="4046" topLine="38" />
</Cursor>
</File>
<File name="..\..\src\intrusive_flat_map.h" open="0" top="0" tabpos="4" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
@ -237,9 +167,119 @@
<Cursor1 position="4065" topLine="242" />
</Cursor>
</File>
<File name="..\..\src\fsm.h" open="1" top="0" tabpos="14" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="11584" topLine="263" />
</Cursor>
</File>
<File name="..\test_list.cpp" open="0" top="0" tabpos="27" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="17914" topLine="493" />
</Cursor>
</File>
<File name="..\..\..\unittest-cpp\UnitTest++\TestRunner.cpp" open="0" top="0" tabpos="20" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="2279" topLine="25" />
</Cursor>
</File>
<File name="..\..\..\unittest-cpp\UnitTest++\CurrentTest.cpp" open="0" top="0" tabpos="26" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="368" topLine="0" />
</Cursor>
</File>
<File name="..\test_map.cpp" open="0" top="0" tabpos="19" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="6368" topLine="164" />
</Cursor>
</File>
<File name="..\..\src\flat_map.h" open="1" top="0" tabpos="8" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="2722" topLine="51" />
</Cursor>
</File>
<File name="..\..\..\unittest-cpp\UnitTest++\TestRunner.h" open="0" top="0" tabpos="21" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="156" topLine="0" />
</Cursor>
</File>
<File name="..\..\src\iterator.h" open="0" top="0" tabpos="17" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="1557" topLine="0" />
</Cursor>
</File>
<File name="..\..\src\unordered_multimap.h" open="0" top="0" tabpos="10" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="22871" topLine="625" />
</Cursor>
</File>
<File name="..\test_intrusive_list.cpp" open="0" top="0" tabpos="24" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="27580" topLine="735" />
</Cursor>
</File>
<File name="..\test_message_router.cpp" open="1" top="0" tabpos="15" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="10414" topLine="325" />
</Cursor>
</File>
<File name="..\..\src\list.h" open="0" top="0" tabpos="22" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="35098" topLine="1063" />
</Cursor>
</File>
<File name="..\test_intrusive_forward_list.cpp" open="1" top="0" tabpos="1" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="29068" topLine="732" />
</Cursor>
</File>
<File name="..\..\src\static_assert.h" open="1" top="0" tabpos="7" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="1477" topLine="0" />
</Cursor>
</File>
<File name="..\test_type_traits.cpp" open="1" top="0" tabpos="11" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="38481" topLine="526" />
</Cursor>
</File>
<File name="..\..\src\algorithm.h" open="0" top="0" tabpos="3" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="0" topLine="0" />
</Cursor>
</File>
<File name="..\..\..\unittest-cpp\UnitTest++\ExecuteTest.h" open="0" top="0" tabpos="18" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="426" topLine="0" />
</Cursor>
</File>
<File name="..\test_iterator.cpp" open="0" top="0" tabpos="16" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="6722" topLine="118" />
</Cursor>
</File>
<File name="..\..\..\unittest-cpp\UnitTest++\Win32\TimeHelpers.cpp" open="0" top="0" tabpos="9" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="103" topLine="6" />
</Cursor>
</File>
<File name="..\main.cpp" open="0" top="0" tabpos="18" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="141" topLine="0" />
</Cursor>
</File>
<File name="..\..\src\message_router.h" open="1" top="0" tabpos="13" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="71424" topLine="1785" />
</Cursor>
</File>
<File name="..\..\src\private\pvoidvector.h" open="1" top="0" tabpos="19" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="7770" topLine="182" />
</Cursor>
</File>
<File name="..\test_flat_set.cpp" open="0" top="0" tabpos="7" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="11541" topLine="359" />
</Cursor>
</File>
</CodeBlocks_layout_file>

View File

@ -445,5 +445,31 @@ namespace
etl::destroy(p, p + SIZE, count);
CHECK_EQUAL(0U, count);
}
//*************************************************************************
TEST(test_create_copy)
{
struct Test : etl::create_copy<Test>
{
std::string text;
};
char buffer[sizeof(Test)];
Test test1;
test1.text = "12345678";
test1.create_copy_at(buffer);
test1.text = "87654321";
Test& test2 = *reinterpret_cast<Test*>(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);
}
};
}

View File

@ -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<MESSAGE1>
{
};
struct Message2 : public etl::message<MESSAGE2>
{
};
struct Message3 : public etl::message<MESSAGE3>
{
int value[10];
};
struct Message4 : public etl::message<MESSAGE4>
{
};
struct Message5 : public etl::message<MESSAGE5>
{
};
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<Packet, 4> 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();
}
};
}

183
test/test_packet.cpp Normal file
View File

@ -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<derived_1, derived_2> types;
//
//// Test packet types.
typedef etl::packet<base, types::size, types::alignment> packet1_t;
typedef etl::packet<not_base, types::size, types::alignment> 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<packet1_t, 4> 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());
}
}
}

View File

@ -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 <stdint.h>
#include <string>
#include <vector>
#include "task.h"
#include "scheduler.h"
#include "container.h"
typedef std::vector<std::string> WorkList_t;
//*****************************************************************************
struct Common
{
//*********************************************
Common()
: callback(*this, &Common::IdleCallback)
{
}
//*********************************************
void Clear()
{
workList.clear();
}
//*********************************************
void IdleCallback()
{
pScheduler->exit_scheduler();
}
WorkList_t workList;
etl::function<Common, void> 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<etl::scheduler_policy_sequencial_single, sizeof(etl::array_size(taskList))> SchedulerSequencialSingle;
typedef etl::scheduler<etl::scheduler_policy_sequencial_multiple, sizeof(etl::array_size(taskList))> SchedulerSequencialMultiple;
typedef etl::scheduler<etl::scheduler_policy_highest_priority, sizeof(etl::array_size(taskList))> SchedulerHighestPriority;
typedef etl::scheduler<etl::scheduler_policy_most_work, sizeof(etl::array_size(taskList))> 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);
}
};
}

View File

@ -41,14 +41,20 @@ namespace std
#include "type_traits.h"
#include <type_traits>
// 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 <const int I>
struct Type
{
};
SUITE(test_type_traits)
{
//*************************************************************************
@ -525,5 +531,55 @@ namespace
CHECK(std::alignment_of<double>::value == etl::alignment_of<double>::value);
CHECK(std::alignment_of<Test>::value == etl::alignment_of<Test>::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<char, char>::value));
CHECK(!(etl::is_one_of<char, T0>::value));
CHECK(bool(etl::is_one_of<char, T0, char>::value));
CHECK(!(etl::is_one_of<char, T0, T1>::value));
CHECK(bool(etl::is_one_of<char, T0, T1, char>::value));
CHECK(!(etl::is_one_of<char, T0, T1, T2>::value));
CHECK(bool(etl::is_one_of<char, T0, T1, T2, char>::value));
CHECK(!(etl::is_one_of<char, T0, T1, T2, T3>::value));
CHECK(bool(etl::is_one_of<char, T0, T1, T2, char>::value));
CHECK(!(etl::is_one_of<char, T0, T1, T2, T3>::value));
CHECK(bool(etl::is_one_of<char, char, T0, T1, T2, T3>::value));
CHECK(bool(etl::is_one_of<char, T0, char, T1, T2, T3>::value));
CHECK(bool(etl::is_one_of<char, T0, T1, char, T2, T3>::value));
CHECK(bool(etl::is_one_of<char, T0, T1, T2, char, T3>::value));
CHECK(bool(etl::is_one_of<char, T0, T1, T2, T3, char>::value));
CHECK(!(etl::is_one_of<char, T0, T1, T2, T3, T4>::value));
}
//*************************************************************************
TEST(test_is_base_of)
{
struct A { };
struct B : public A { };
struct C { };
CHECK((std::is_base_of<A, A>::value) == (etl::is_base_of<A, A>::value));
CHECK((std::is_base_of<A, B>::value) == (etl::is_base_of<A, B>::value));
CHECK((std::is_base_of<A, C>::value) == (etl::is_base_of<A, C>::value));
CHECK((std::is_base_of<B, A>::value) == (etl::is_base_of<B, A>::value));
CHECK((std::is_base_of<B, B>::value) == (etl::is_base_of<B, B>::value));
CHECK((std::is_base_of<B, C>::value) == (etl::is_base_of<B, C>::value));
CHECK((std::is_base_of<C, A>::value) == (etl::is_base_of<C, A>::value));
CHECK((std::is_base_of<C, B>::value) == (etl::is_base_of<C, B>::value));
CHECK((std::is_base_of<C, C>::value) == (etl::is_base_of<C, C>::value));
}
};
}

View File

@ -35,70 +35,70 @@ SOFTWARE.
#include <vector>
#include <algorithm>
// 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<char, int, std::string> test_variant_3a;
typedef etl::variant<int, short, double> test_variant_3b;
typedef etl::variant<int8_t> test_variant_1;
typedef etl::variant<int8_t, uint8_t> test_variant_2;
typedef etl::variant<int8_t, uint8_t, int16_t> test_variant_3;
typedef etl::variant<int8_t, uint8_t, int16_t, uint16_t> test_variant_4;
typedef etl::variant<int8_t, uint8_t, int16_t, uint16_t, int32_t> test_variant_5;
typedef etl::variant<int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t> test_variant_6;
typedef etl::variant<int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t, int64_t> test_variant_7;
typedef etl::variant<int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t, int64_t, uint64_t> test_variant_8;
typedef etl::variant<derived_1, derived_2> test_variant_polymorphic;
typedef etl::variant<char, unsigned char, short, unsigned short, int, unsigned int, long, unsigned long> 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<char, int, std::string> test_variant_3a;
typedef etl::variant<int, short, double> test_variant_3b;
typedef etl::variant<int8_t> test_variant_1;
typedef etl::variant<int8_t, uint8_t> test_variant_2;
typedef etl::variant<int8_t, uint8_t, int16_t> test_variant_3;
typedef etl::variant<int8_t, uint8_t, int16_t, uint16_t> test_variant_4;
typedef etl::variant<int8_t, uint8_t, int16_t, uint16_t, int32_t> test_variant_5;
typedef etl::variant<int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t> test_variant_6;
typedef etl::variant<int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t, int64_t> test_variant_7;
typedef etl::variant<int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t, int64_t, uint64_t> test_variant_8;
typedef etl::variant<derived_1, derived_2> test_variant_polymorphic;
typedef etl::variant<char, unsigned char, short, unsigned short, int, unsigned int, long, unsigned long> test_variant_max_types;
// This line should compile with no errors.
test_variant_max_types variant_max;
SUITE(test_variant)
{
TEST(test_alignment)

View File

@ -130,8 +130,12 @@
<ItemGroup>
<ClInclude Include="..\..\src\fsm.h" />
<ClInclude Include="..\..\src\fsm_generator.h" />
<ClInclude Include="..\..\src\largest_generator.h" />
<ClInclude Include="..\..\src\message_router.h" />
<ClInclude Include="..\..\src\message_router_generator.h" />
<ClInclude Include="..\..\src\packet.h" />
<ClInclude Include="..\..\src\smallest_generator.h" />
<ClInclude Include="..\..\src\type_traits_generator.h" />
<ClInclude Include="..\..\unittest-cpp\UnitTest++\AssertException.h" />
<ClInclude Include="..\..\unittest-cpp\UnitTest++\CheckMacros.h" />
<ClInclude Include="..\..\unittest-cpp\UnitTest++\Checks.h" />
@ -377,6 +381,7 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug No Unit Tests|Win32'">false</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\test_optional.cpp" />
<ClCompile Include="..\test_packet.cpp" />
<ClCompile Include="..\test_pearson.cpp" />
<ClCompile Include="..\test_pool.cpp" />
<ClCompile Include="..\test_priority_queue.cpp" />
@ -397,6 +402,7 @@
<ClCompile Include="..\test_string_u16.cpp" />
<ClCompile Include="..\test_string_u32.cpp" />
<ClCompile Include="..\test_string_wchar_t.cpp" />
<ClCompile Include="..\test_task_scheduler.cpp" />
<ClCompile Include="..\test_type_def.cpp" />
<ClCompile Include="..\test_type_traits.cpp" />
<ClCompile Include="..\test_unordered_map.cpp" />
@ -414,8 +420,7 @@
<ItemGroup>
<None Include="..\..\Doxyfile" />
<None Include="..\..\library.properties" />
<None Include="..\..\src\CreateFSM.bat" />
<None Include="..\..\src\CreateMessageRouter.bat" />
<None Include="..\..\src\generate.bat" />
</ItemGroup>
<ItemGroup>
<Text Include="..\..\src\file_error_numbers.txt" />

View File

@ -40,6 +40,12 @@
<Filter Include="ETL\Frameworks">
<UniqueIdentifier>{6be3bc76-e17c-4be0-8b0b-d1053e1a1761}</UniqueIdentifier>
</Filter>
<Filter Include="ETL\Frameworks\Generators">
<UniqueIdentifier>{c1264f38-22fa-4fcb-8cab-f254b1290eab}</UniqueIdentifier>
</Filter>
<Filter Include="ETL\Utilities\Generators">
<UniqueIdentifier>{39015d44-a7cb-47f0-a7dd-27714f852363}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\src\doxygen.h">
@ -435,14 +441,26 @@
<ClInclude Include="..\..\src\fsm.h">
<Filter>ETL\Frameworks</Filter>
</ClInclude>
<ClInclude Include="..\..\src\fsm_generator.h">
<Filter>ETL\Frameworks</Filter>
</ClInclude>
<ClInclude Include="..\..\src\message_router.h">
<Filter>ETL\Frameworks</Filter>
</ClInclude>
<ClInclude Include="..\..\src\packet.h">
<Filter>ETL\Containers</Filter>
</ClInclude>
<ClInclude Include="..\..\src\fsm_generator.h">
<Filter>ETL\Frameworks\Generators</Filter>
</ClInclude>
<ClInclude Include="..\..\src\message_router_generator.h">
<Filter>ETL\Frameworks</Filter>
<Filter>ETL\Frameworks\Generators</Filter>
</ClInclude>
<ClInclude Include="..\..\src\largest_generator.h">
<Filter>ETL\Utilities\Generators</Filter>
</ClInclude>
<ClInclude Include="..\..\src\type_traits_generator.h">
<Filter>ETL\Utilities\Generators</Filter>
</ClInclude>
<ClInclude Include="..\..\src\smallest_generator.h">
<Filter>ETL\Utilities\Generators</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
@ -773,6 +791,12 @@
<ClCompile Include="..\test_message_router.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\test_packet.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\test_task_scheduler.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\..\Doxyfile">
@ -781,11 +805,8 @@
<None Include="..\..\library.properties">
<Filter>Resource Files</Filter>
</None>
<None Include="..\..\src\CreateFSM.bat">
<Filter>ETL\Frameworks</Filter>
</None>
<None Include="..\..\src\CreateMessageRouter.bat">
<Filter>ETL\Frameworks</Filter>
<None Include="..\..\src\generate.bat">
<Filter>Resource Files</Filter>
</None>
</ItemGroup>
<ItemGroup>