mirror of
https://github.com/ETLCPP/etl.git
synced 2026-04-30 19:09:10 +08:00
Merge remote-tracking branch 'origin/development'
# Conflicts: # test/codeblocks/ETL.depend # test/codeblocks/ETL.layout
This commit is contained in:
parent
20609e1caf
commit
099b3f8cfd
@ -418,6 +418,52 @@ namespace etl
|
||||
return o_begin;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// binary_find
|
||||
///\ingroup algorithm
|
||||
/// Does a binary search and returns an iterator to the value or end if not found.
|
||||
//***************************************************************************
|
||||
template <typename TIterator,
|
||||
typename TValue>
|
||||
TIterator binary_find(TIterator begin,
|
||||
TIterator end,
|
||||
const TValue& value)
|
||||
{
|
||||
TIterator it = std::lower_bound(begin, end, value);
|
||||
|
||||
if ((it == end) || (*it != value))
|
||||
{
|
||||
it = end;
|
||||
}
|
||||
|
||||
return it;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// binary_find
|
||||
///\ingroup algorithm
|
||||
/// Does a binary search and returns an iterator to the value or end if not found.
|
||||
//***************************************************************************
|
||||
template <typename TIterator,
|
||||
typename TValue,
|
||||
typename TBinaryPredicate,
|
||||
typename TBinaryEquality>
|
||||
TIterator binary_find(TIterator begin,
|
||||
TIterator end,
|
||||
const TValue& value,
|
||||
TBinaryPredicate predicate,
|
||||
TBinaryEquality equality)
|
||||
{
|
||||
TIterator it = std::lower_bound(begin, end, value, predicate);
|
||||
|
||||
if ((it == end) || !equality(*it, value))
|
||||
{
|
||||
it = end;
|
||||
}
|
||||
|
||||
return it;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// find_if_not
|
||||
///\ingroup algorithm
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -34,4 +34,6 @@
|
||||
34 fsm
|
||||
35 message_router
|
||||
36 scheduler
|
||||
37 task
|
||||
37 task
|
||||
38 message
|
||||
39 message_bus
|
||||
|
||||
569
src/fsm_generator.h
Normal file
569
src/fsm_generator.h
Normal file
@ -0,0 +1,569 @@
|
||||
/******************************************************************************
|
||||
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.
|
||||
******************************************************************************/
|
||||
|
||||
/*[[[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__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "array.h"
|
||||
#include "nullptr.h"
|
||||
#include "error_handler.h"
|
||||
#include "exception.h"
|
||||
#include "user_type.h"
|
||||
#include "message_router.h"
|
||||
#include "integral_limits.h"
|
||||
#include "largest.h"
|
||||
|
||||
#undef ETL_FILE
|
||||
#define ETL_FILE "34"
|
||||
|
||||
#ifdef ETL_COMPILER_MICROSOFT
|
||||
#undef max
|
||||
#endif
|
||||
|
||||
namespace etl
|
||||
{
|
||||
class fsm;
|
||||
|
||||
/// Allow alternative type for state id.
|
||||
#if !defined(ETL_FSM_STATE_ID_TYPE)
|
||||
typedef uint_least8_t fsm_state_id_t;
|
||||
#else
|
||||
typedef ETL_FSM_STATE_ID_TYPE fsm_state_id_t;
|
||||
#endif
|
||||
|
||||
// For internal FSM use.
|
||||
typedef typename etl::larger_type<etl::message_id_t>::type fsm_internal_id_t;
|
||||
|
||||
//***************************************************************************
|
||||
/// Base exception class for FSM.
|
||||
//***************************************************************************
|
||||
class fsm_exception : public etl::exception
|
||||
{
|
||||
public:
|
||||
|
||||
fsm_exception(string_type what, string_type file_name, numeric_type line_number)
|
||||
: etl::exception(what, file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Exception for null state pointer.
|
||||
//***************************************************************************
|
||||
class fsm_null_state_exception : public etl::fsm_exception
|
||||
{
|
||||
public:
|
||||
|
||||
fsm_null_state_exception(string_type file_name, numeric_type line_number)
|
||||
: etl::fsm_exception(ETL_ERROR_TEXT("fsm:null state", ETL_FILE"A"), file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Exception for invalid state id.
|
||||
//***************************************************************************
|
||||
class fsm_state_id_exception : public etl::fsm_exception
|
||||
{
|
||||
public:
|
||||
|
||||
fsm_state_id_exception(string_type file_name, numeric_type line_number)
|
||||
: etl::fsm_exception(ETL_ERROR_TEXT("fsm:state id", ETL_FILE"B"), file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Exception for incompatible state list.
|
||||
//***************************************************************************
|
||||
class fsm_state_list_exception : public etl::fsm_exception
|
||||
{
|
||||
public:
|
||||
|
||||
fsm_state_list_exception(string_type file_name, numeric_type line_number)
|
||||
: etl::fsm_exception(ETL_ERROR_TEXT("fsm:state list", ETL_FILE"C"), file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Interface class for FSM states.
|
||||
//***************************************************************************
|
||||
class ifsm_state
|
||||
{
|
||||
public:
|
||||
|
||||
/// Allows ifsm_state functions to be private.
|
||||
friend class fsm_helper;
|
||||
|
||||
//*******************************************
|
||||
/// Gets the id for this state.
|
||||
//*******************************************
|
||||
etl::fsm_state_id_t get_state_id() const
|
||||
{
|
||||
return state_id;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
//*******************************************
|
||||
/// Constructor.
|
||||
//*******************************************
|
||||
ifsm_state(etl::fsm_state_id_t state_id_)
|
||||
: state_id(state_id_),
|
||||
p_context(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
//*******************************************
|
||||
inline etl::fsm& get_fsm_context() const
|
||||
{
|
||||
return *p_context;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
virtual fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message) = 0;
|
||||
|
||||
virtual fsm_state_id_t on_enter_state() { return state_id; } // By default, do nothing.
|
||||
virtual void on_exit_state() {} // By default, do nothing.
|
||||
|
||||
//*******************************************
|
||||
void set_fsm_context(etl::fsm& context)
|
||||
{
|
||||
p_context = &context;
|
||||
}
|
||||
|
||||
// The state id.
|
||||
const etl::fsm_state_id_t state_id;
|
||||
|
||||
// A pointer to the FSM context.
|
||||
etl::fsm* p_context;
|
||||
|
||||
// Disabled.
|
||||
ifsm_state(const ifsm_state&);
|
||||
ifsm_state& operator =(const ifsm_state&);
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Helper class for FSM.
|
||||
/// Allows ifsm_state functions to be private.
|
||||
//***************************************************************************
|
||||
class fsm_helper
|
||||
{
|
||||
public:
|
||||
|
||||
//*******************************************
|
||||
inline void set_fsm_context(etl::ifsm_state& state,
|
||||
etl::fsm& context)
|
||||
{
|
||||
state.set_fsm_context(context);
|
||||
}
|
||||
|
||||
//*******************************************
|
||||
inline fsm_state_id_t process_event(etl::ifsm_state& state,
|
||||
etl::imessage_router& source,
|
||||
const etl::imessage& message)
|
||||
{
|
||||
return state.process_event(source, message);
|
||||
}
|
||||
|
||||
//*******************************************
|
||||
inline fsm_state_id_t on_enter_state(etl::ifsm_state& state)
|
||||
{
|
||||
return state.on_enter_state();
|
||||
}
|
||||
|
||||
//*******************************************
|
||||
inline void on_exit_state(etl::ifsm_state& state)
|
||||
{
|
||||
state.on_exit_state();
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// The FSM class.
|
||||
//***************************************************************************
|
||||
class fsm : public etl::imessage_router, protected etl::fsm_helper
|
||||
{
|
||||
public:
|
||||
|
||||
//*******************************************
|
||||
/// Constructor.
|
||||
//*******************************************
|
||||
fsm(etl::message_router_id_t id)
|
||||
: imessage_router(id),
|
||||
p_state(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
//*******************************************
|
||||
/// Set the states for the FSM
|
||||
//*******************************************
|
||||
template <typename TSize>
|
||||
void set_states(etl::ifsm_state** p_states, TSize size)
|
||||
{
|
||||
state_list = p_states;
|
||||
number_of_states = etl::fsm_state_id_t(size);
|
||||
|
||||
ETL_ASSERT((number_of_states > 0), ETL_ERROR(etl::fsm_state_list_exception));
|
||||
|
||||
for (etl::fsm_state_id_t i = 0; i < size; ++i)
|
||||
{
|
||||
ETL_ASSERT((state_list[i] != nullptr), ETL_ERROR(etl::fsm_null_state_exception));
|
||||
fsm_helper::set_fsm_context(*state_list[i], *this);
|
||||
}
|
||||
}
|
||||
|
||||
//*******************************************
|
||||
/// Starts the FSM.
|
||||
/// Can only be called once.
|
||||
/// Subsequent calls will do nothing.
|
||||
//*******************************************
|
||||
void start()
|
||||
{
|
||||
// Can only be started once.
|
||||
if (p_state == nullptr)
|
||||
{
|
||||
p_state = state_list[0];
|
||||
ETL_ASSERT(p_state != nullptr, ETL_ERROR(etl::fsm_null_state_exception));
|
||||
|
||||
fsm_helper::on_enter_state(*p_state);
|
||||
}
|
||||
}
|
||||
|
||||
//*******************************************
|
||||
/// Top level message handler for the FSM.
|
||||
//*******************************************
|
||||
void receive(const etl::imessage& message)
|
||||
{
|
||||
etl::null_message_router nmr;
|
||||
receive(nmr, message);
|
||||
}
|
||||
|
||||
//*******************************************
|
||||
/// Top level message handler for the FSM.
|
||||
//*******************************************
|
||||
void receive(etl::imessage_router& source, const etl::imessage& message)
|
||||
{
|
||||
etl::fsm_state_id_t next_state_id = fsm_helper::process_event(*p_state, source, message);
|
||||
ETL_ASSERT(next_state_id < number_of_states, ETL_ERROR(etl::fsm_state_id_exception));
|
||||
|
||||
etl::ifsm_state* p_next_state = state_list[next_state_id];
|
||||
|
||||
// Have we changed state?
|
||||
if (p_next_state != p_state)
|
||||
{
|
||||
do
|
||||
{
|
||||
p_state = p_next_state;
|
||||
fsm_helper::on_exit_state(*p_state);
|
||||
|
||||
next_state_id = fsm_helper::on_enter_state(*p_state);
|
||||
ETL_ASSERT(next_state_id < number_of_states, ETL_ERROR(etl::fsm_state_id_exception));
|
||||
|
||||
p_next_state = state_list[next_state_id];
|
||||
|
||||
} while (p_next_state != p_state); // Have we changed state again?
|
||||
}
|
||||
}
|
||||
|
||||
using imessage_router::accepts;
|
||||
|
||||
//*******************************************
|
||||
/// Does this FSM accept the message id?
|
||||
/// Yes, it accepts everything!
|
||||
//*******************************************
|
||||
bool accepts(etl::message_id_t id) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
//*******************************************
|
||||
/// Gets the current state id.
|
||||
//*******************************************
|
||||
etl::fsm_state_id_t get_state_id() const
|
||||
{
|
||||
ETL_ASSERT(p_state != nullptr, ETL_ERROR(etl::fsm_null_state_exception));
|
||||
return p_state->get_state_id();
|
||||
}
|
||||
|
||||
//*******************************************
|
||||
/// Gets a reference to the current state interface.
|
||||
//*******************************************
|
||||
ifsm_state& get_state()
|
||||
{
|
||||
ETL_ASSERT(p_state != nullptr, ETL_ERROR(etl::fsm_null_state_exception));
|
||||
return *p_state;
|
||||
}
|
||||
|
||||
//*******************************************
|
||||
/// Gets a const reference to the current state interface.
|
||||
//*******************************************
|
||||
const ifsm_state& get_state() const
|
||||
{
|
||||
ETL_ASSERT(p_state != nullptr, ETL_ERROR(etl::fsm_null_state_exception));
|
||||
return *p_state;
|
||||
}
|
||||
|
||||
//*******************************************
|
||||
/// Checks if the FSM has been started.
|
||||
//*******************************************
|
||||
bool is_started() const
|
||||
{
|
||||
return p_state != nullptr;
|
||||
}
|
||||
|
||||
//*******************************************
|
||||
/// Reset the FSM to pre-started state.
|
||||
//*******************************************
|
||||
void reset()
|
||||
{
|
||||
p_state = nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
etl::ifsm_state* p_state; ///< A pointer to the current state.
|
||||
etl::ifsm_state** state_list; ///< The list of added states.
|
||||
etl::fsm_state_id_t number_of_states; ///< The number of states.
|
||||
};
|
||||
|
||||
/*[[[cog
|
||||
import cog
|
||||
cog.outl("")
|
||||
################################################
|
||||
# The first definition for all of the events.
|
||||
################################################
|
||||
cog.outl("//***************************************************************************")
|
||||
cog.outl("// The definition for all %s message types." % Handlers)
|
||||
cog.outl("//***************************************************************************")
|
||||
cog.outl("template <typename TContext, typename TDerived, const etl::fsm_state_id_t STATE_ID_, ")
|
||||
cog.out(" ")
|
||||
for n in range(1, int(Handlers)):
|
||||
cog.out("typename T%s = void, " % n)
|
||||
if n % 4 == 0:
|
||||
cog.outl("")
|
||||
cog.out(" ")
|
||||
cog.outl("typename T%s = void>" % Handlers)
|
||||
cog.outl("class fsm_state : public ifsm_state")
|
||||
cog.outl("{")
|
||||
cog.outl("public:")
|
||||
cog.outl("")
|
||||
cog.outl(" enum")
|
||||
cog.outl(" {")
|
||||
cog.outl(" STATE_ID = STATE_ID_")
|
||||
cog.outl(" };")
|
||||
cog.outl("")
|
||||
cog.outl(" fsm_state()")
|
||||
cog.outl(" : ifsm_state(STATE_ID)")
|
||||
cog.outl(" {")
|
||||
cog.outl(" }")
|
||||
cog.outl("")
|
||||
cog.outl(" inline TContext& get_fsm_context() const")
|
||||
cog.outl(" {")
|
||||
cog.outl(" return static_cast<TContext&>(ifsm_state::get_fsm_context());")
|
||||
cog.outl(" }")
|
||||
cog.outl("")
|
||||
cog.outl("private:")
|
||||
cog.outl("")
|
||||
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("")
|
||||
cog.outl(" switch (event_id)")
|
||||
cog.outl(" {")
|
||||
for n in range(1, int(Handlers) + 1):
|
||||
cog.out(" case T%d::ID:" % n)
|
||||
cog.out(" new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T%d&>(message));" % n)
|
||||
cog.outl(" break;")
|
||||
cog.out(" default:")
|
||||
cog.out(" new_state_id = static_cast<TDerived*>(this)->on_event_unknown(source, message);")
|
||||
cog.outl(" break;")
|
||||
cog.outl(" }")
|
||||
cog.outl("")
|
||||
cog.outl(" return new_state_id;")
|
||||
cog.outl(" }")
|
||||
cog.outl("};")
|
||||
|
||||
####################################
|
||||
# All of the other specialisations.
|
||||
####################################
|
||||
for n in range(int(Handlers) - 1, 0, -1):
|
||||
cog.outl("")
|
||||
cog.outl("//***************************************************************************")
|
||||
if n == 1:
|
||||
cog.outl("// Specialisation for %d message type." % n)
|
||||
else:
|
||||
cog.outl("// Specialisation for %d message types." % n)
|
||||
cog.outl("//***************************************************************************")
|
||||
cog.outl("template <typename TContext, typename TDerived, const etl::fsm_state_id_t STATE_ID_, ")
|
||||
cog.out(" ")
|
||||
for t in range(1, n):
|
||||
cog.out("typename T%d, " % t)
|
||||
if t % 4 == 0:
|
||||
cog.outl("")
|
||||
cog.out(" ")
|
||||
cog.outl("typename T%d>" % n)
|
||||
cog.out("class fsm_state<TContext, TDerived, STATE_ID_, ")
|
||||
for t in range(1, n + 1):
|
||||
cog.out("T%d, " % t)
|
||||
if t % 16 == 0:
|
||||
cog.outl("")
|
||||
cog.out(" ")
|
||||
for t in range(n + 1, int(Handlers)):
|
||||
cog.out("void, ")
|
||||
if t % 16 == 0:
|
||||
cog.outl("")
|
||||
cog.out(" ")
|
||||
cog.outl("void> : public ifsm_state")
|
||||
cog.outl("{")
|
||||
cog.outl("public:")
|
||||
cog.outl("")
|
||||
cog.outl(" enum")
|
||||
cog.outl(" {")
|
||||
cog.outl(" STATE_ID = STATE_ID_")
|
||||
cog.outl(" };")
|
||||
cog.outl("")
|
||||
cog.outl(" fsm_state()")
|
||||
cog.outl(" : ifsm_state(STATE_ID)")
|
||||
cog.outl(" {")
|
||||
cog.outl(" }")
|
||||
cog.outl("")
|
||||
cog.outl(" inline TContext& get_fsm_context() const")
|
||||
cog.outl(" {")
|
||||
cog.outl(" return static_cast<TContext&>(ifsm_state::get_fsm_context());")
|
||||
cog.outl(" }")
|
||||
cog.outl("private:")
|
||||
cog.outl("")
|
||||
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("")
|
||||
cog.outl(" switch (event_id)")
|
||||
cog.outl(" {")
|
||||
for n in range(1, n + 1):
|
||||
cog.out(" case T%d::ID:" % n)
|
||||
cog.out(" new_state_id = static_cast<TDerived*>(this)->on_event(source, static_cast<const T%d&>(message));" % n)
|
||||
cog.outl(" break;")
|
||||
cog.out(" default:")
|
||||
cog.out(" new_state_id = static_cast<TDerived*>(this)->on_event_unknown(source, message);")
|
||||
cog.outl(" break;")
|
||||
cog.outl(" }")
|
||||
cog.outl("")
|
||||
cog.outl(" return new_state_id;")
|
||||
cog.outl(" }")
|
||||
cog.outl("};")
|
||||
####################################
|
||||
# Specialisation for zero messages.
|
||||
####################################
|
||||
cog.outl("")
|
||||
cog.outl("//***************************************************************************")
|
||||
cog.outl("// Specialisation for 0 message types.")
|
||||
cog.outl("//***************************************************************************")
|
||||
cog.outl("template <typename TContext, typename TDerived, const etl::fsm_state_id_t STATE_ID_>")
|
||||
cog.out("class fsm_state<TContext, TDerived, STATE_ID_, ")
|
||||
for t in range(1, int(Handlers)):
|
||||
cog.out("void, ")
|
||||
if t % 16 == 0:
|
||||
cog.outl("")
|
||||
cog.out(" ")
|
||||
cog.outl("void> : public ifsm_state")
|
||||
cog.outl("{")
|
||||
cog.outl("public:")
|
||||
cog.outl("")
|
||||
cog.outl(" enum")
|
||||
cog.outl(" {")
|
||||
cog.outl(" STATE_ID = STATE_ID_")
|
||||
cog.outl(" };")
|
||||
cog.outl("")
|
||||
cog.outl(" fsm_state()")
|
||||
cog.outl(" : ifsm_state(STATE_ID)")
|
||||
cog.outl(" {")
|
||||
cog.outl(" }")
|
||||
cog.outl("")
|
||||
cog.outl(" inline TContext& get_fsm_context() const")
|
||||
cog.outl(" {")
|
||||
cog.outl(" return static_cast<TContext&>(ifsm_state::get_fsm_context());")
|
||||
cog.outl(" }")
|
||||
cog.outl("private:")
|
||||
cog.outl("")
|
||||
cog.outl(" etl::fsm_state_id_t process_event(etl::imessage_router& source, const etl::imessage& message)")
|
||||
cog.outl(" {")
|
||||
cog.outl(" return static_cast<TDerived*>(this)->on_event_unknown(source, message);")
|
||||
cog.outl(" }")
|
||||
cog.outl("};")
|
||||
]]]*/
|
||||
/*[[[end]]]*/
|
||||
}
|
||||
|
||||
#undef ETL_FILE
|
||||
|
||||
#ifdef ETL_COMPILER_MICROSOFT
|
||||
#define max(a,b) (((a) > (b)) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#endif
|
||||
5
src/generate.bat
Normal file
5
src/generate.bat
Normal 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
|
||||
1
src/generate_fsm.bat
Normal file
1
src/generate_fsm.bat
Normal file
@ -0,0 +1 @@
|
||||
python -m cogapp -d -e -ofsm.h -DHandlers=16 fsm_generator.h
|
||||
1
src/generate_message_router.bat
Normal file
1
src/generate_message_router.bat
Normal file
@ -0,0 +1 @@
|
||||
python -m cogapp -d -e -omessage_router.h -DHandlers=16 message_router_generator.h
|
||||
107
src/largest.h
107
src/largest.h
@ -5,7 +5,7 @@ The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
http://www.etlcpp.com
|
||||
https://www.etlcpp.com
|
||||
|
||||
Copyright(c) 2014 jwellbelove
|
||||
|
||||
@ -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 -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 +69,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 +100,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 +120,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 +137,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 +158,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 +238,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
323
src/largest_generator.h
Normal file
@ -0,0 +1,323 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
https://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
|
||||
21
src/memory.h
21
src/memory.h
@ -662,6 +662,27 @@ namespace etl
|
||||
|
||||
return i_begin;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
/// Copy constructs a derived class to an address.
|
||||
///\tparam T The derived type.
|
||||
///\ingroup memory
|
||||
//*****************************************************************************
|
||||
template <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
|
||||
|
||||
96
src/message.h
Normal file
96
src/message.h
Normal file
@ -0,0 +1,96 @@
|
||||
/******************************************************************************
|
||||
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__
|
||||
#define __ETL_MESSAGE__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "error_handler.h"
|
||||
#include "exception.h"
|
||||
#include "message_types.h"
|
||||
|
||||
#undef ETL_FILE
|
||||
#define ETL_FILE "38"
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
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;
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
template <const etl::message_id_t ID_>
|
||||
class message : public imessage
|
||||
{
|
||||
public:
|
||||
|
||||
enum
|
||||
{
|
||||
ID = ID_
|
||||
};
|
||||
|
||||
//********************************************
|
||||
etl::message_id_t get_message_id() const
|
||||
{
|
||||
return ID;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#undef ETL_FILE
|
||||
|
||||
#endif
|
||||
389
src/message_bus.h
Normal file
389
src/message_bus.h
Normal file
@ -0,0 +1,389 @@
|
||||
/******************************************************************************
|
||||
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_MESSAGE_BUS_
|
||||
#define __ETL_MESSAGE_BUS_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <algorithm>
|
||||
|
||||
#include "algorithm.h"
|
||||
#include "vector.h"
|
||||
#include "nullptr.h"
|
||||
#include "error_handler.h"
|
||||
#include "exception.h"
|
||||
#include "message_types.h"
|
||||
#include "message.h"
|
||||
#include "message_router.h"
|
||||
|
||||
#undef ETL_FILE
|
||||
#define ETL_FILE "39"
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
/// Base exception class for message bus
|
||||
//***************************************************************************
|
||||
class message_bus_exception : public etl::exception
|
||||
{
|
||||
public:
|
||||
|
||||
message_bus_exception(string_type what, string_type file_name, numeric_type line_number)
|
||||
: etl::exception(what, file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Too many subscribers.
|
||||
//***************************************************************************
|
||||
class message_bus_too_many_subscribers : public etl::message_bus_exception
|
||||
{
|
||||
public:
|
||||
|
||||
message_bus_too_many_subscribers(string_type file_name, numeric_type line_number)
|
||||
: message_bus_exception(ETL_ERROR_TEXT("message bus:too many subscribers", ETL_FILE"A"), file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Interface for message bus
|
||||
//***************************************************************************
|
||||
class imessage_bus : public etl::imessage_router
|
||||
{
|
||||
private:
|
||||
|
||||
typedef etl::ivector<etl::imessage_router*> router_list_t;
|
||||
|
||||
public:
|
||||
|
||||
using etl::imessage_router::receive;
|
||||
|
||||
//*******************************************
|
||||
/// Subscribe to the bus.
|
||||
//*******************************************
|
||||
bool subscribe(etl::imessage_router& router)
|
||||
{
|
||||
bool ok = true;
|
||||
|
||||
// There's no point actually adding null routers.
|
||||
if (router.get_message_router_id() != etl::imessage_router::NULL_MESSAGE_ROUTER)
|
||||
{
|
||||
ok = !router_list.full();
|
||||
|
||||
ETL_ASSERT(ok, ETL_ERROR(etl::message_bus_too_many_subscribers));
|
||||
|
||||
if (ok)
|
||||
{
|
||||
if (router.get_message_router_id() == etl::imessage_router::MESSAGE_BUS)
|
||||
{
|
||||
// Message busses get added to the end.
|
||||
router_list.push_back(&router);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Routers get added in id order.
|
||||
router_list_t::iterator irouter = std::upper_bound(router_list.begin(),
|
||||
router_list.end(),
|
||||
router.get_message_router_id(),
|
||||
compare_router_id());
|
||||
|
||||
router_list.insert(irouter, &router);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
//*******************************************
|
||||
/// Unsubscribe from the bus.
|
||||
//*******************************************
|
||||
void unsubscribe(etl::message_router_id_t id)
|
||||
{
|
||||
if (id == etl::imessage_bus::ALL_MESSAGE_ROUTERS)
|
||||
{
|
||||
clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::pair<router_list_t::iterator, router_list_t::iterator> range = std::equal_range(router_list.begin(),
|
||||
router_list.end(),
|
||||
id,
|
||||
compare_router_id());
|
||||
|
||||
router_list.erase(range.first, range.second);
|
||||
}
|
||||
}
|
||||
|
||||
//*******************************************
|
||||
void unsubscribe(etl::imessage_router& router)
|
||||
{
|
||||
router_list_t::iterator irouter = std::find(router_list.begin(),
|
||||
router_list.end(),
|
||||
&router);
|
||||
|
||||
if (irouter != router_list.end())
|
||||
{
|
||||
router_list.erase(irouter);
|
||||
}
|
||||
}
|
||||
|
||||
//*******************************************
|
||||
void receive(const etl::imessage& message)
|
||||
{
|
||||
etl::null_message_router nmr;
|
||||
receive(nmr, etl::imessage_router::ALL_MESSAGE_ROUTERS, message);
|
||||
}
|
||||
|
||||
//*******************************************
|
||||
void receive(etl::message_router_id_t destination_router_id,
|
||||
const etl::imessage& message)
|
||||
{
|
||||
etl::null_message_router nmr;
|
||||
receive(nmr, destination_router_id, message);
|
||||
}
|
||||
|
||||
//*******************************************
|
||||
void receive(etl::imessage_router& source,
|
||||
const etl::imessage& message)
|
||||
{
|
||||
receive(source, etl::imessage_router::ALL_MESSAGE_ROUTERS, message);
|
||||
}
|
||||
|
||||
//*******************************************
|
||||
void receive(etl::imessage_router& source,
|
||||
etl::message_router_id_t destination_router_id,
|
||||
const etl::imessage& message)
|
||||
{
|
||||
switch (destination_router_id)
|
||||
{
|
||||
//*****************************
|
||||
// Null message router. These routers can never be subscribed.
|
||||
case etl::imessage_router::NULL_MESSAGE_ROUTER:
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
//*****************************
|
||||
// Broadcast to all routers.
|
||||
case etl::imessage_router::ALL_MESSAGE_ROUTERS:
|
||||
{
|
||||
router_list_t::iterator irouter = router_list.begin();
|
||||
|
||||
// Broadcast to everyone.
|
||||
while (irouter != router_list.end())
|
||||
{
|
||||
etl::imessage_router& router = **irouter;
|
||||
|
||||
if (router.get_message_router_id() == etl::imessage_router::MESSAGE_BUS)
|
||||
{
|
||||
// The router is actually a bus.
|
||||
etl::imessage_bus& bus = static_cast<etl::imessage_bus&>(router);
|
||||
|
||||
// So pass it on.
|
||||
bus.receive(source, destination_router_id, message);
|
||||
}
|
||||
else if (router.accepts(message.get_message_id()))
|
||||
{
|
||||
router.receive(source, message);
|
||||
}
|
||||
|
||||
++irouter;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
//*****************************
|
||||
// Must be an addressed message.
|
||||
default:
|
||||
{
|
||||
router_list_t::iterator irouter = router_list.begin();
|
||||
|
||||
// Find routers with the id.
|
||||
std::pair<router_list_t::iterator, router_list_t::iterator> range = std::equal_range(router_list.begin(),
|
||||
router_list.end(),
|
||||
destination_router_id,
|
||||
compare_router_id());
|
||||
|
||||
// Call all of them.
|
||||
while (range.first != range.second)
|
||||
{
|
||||
if ((*(range.first))->accepts(message.get_message_id()))
|
||||
{
|
||||
(*(range.first))->receive(source, message);
|
||||
}
|
||||
|
||||
++range.first;
|
||||
}
|
||||
|
||||
// Do any message buses.
|
||||
// These are always at the end of the list.
|
||||
irouter = std::lower_bound(router_list.begin(),
|
||||
router_list.end(),
|
||||
etl::imessage_bus::MESSAGE_BUS,
|
||||
compare_router_id());
|
||||
|
||||
while (irouter != router_list.end())
|
||||
{
|
||||
// The router is actually a bus.
|
||||
etl::imessage_bus& bus = static_cast<etl::imessage_bus&>(**irouter);
|
||||
|
||||
// So pass it on.
|
||||
bus.receive(source, destination_router_id, message);
|
||||
|
||||
++irouter;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
using imessage_router::accepts;
|
||||
|
||||
//*******************************************
|
||||
/// Does this message bus accept the message id?
|
||||
/// Yes!, it accepts everything!
|
||||
//*******************************************
|
||||
bool accepts(etl::message_id_t id) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
//*******************************************
|
||||
size_t size() const
|
||||
{
|
||||
return router_list.size();
|
||||
}
|
||||
|
||||
//*******************************************
|
||||
void clear()
|
||||
{
|
||||
return router_list.clear();
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
//*******************************************
|
||||
/// Constructor.
|
||||
//*******************************************
|
||||
imessage_bus(router_list_t& list)
|
||||
: imessage_router(etl::imessage_router::MESSAGE_BUS),
|
||||
router_list(list)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
//*******************************************
|
||||
// How to compare routers to router ids.
|
||||
//*******************************************
|
||||
struct compare_router_id
|
||||
{
|
||||
bool operator()(const etl::imessage_router* prouter, etl::message_router_id_t id) const
|
||||
{
|
||||
return prouter->get_message_router_id() < id;
|
||||
}
|
||||
|
||||
bool operator()(etl::message_router_id_t id, const etl::imessage_router* prouter) const
|
||||
{
|
||||
return id < prouter->get_message_router_id();
|
||||
}
|
||||
};
|
||||
|
||||
router_list_t& router_list;
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// The message bus
|
||||
//***************************************************************************
|
||||
template <uint_least8_t MAX_ROUTERS_>
|
||||
class message_bus : public etl::imessage_bus
|
||||
{
|
||||
public:
|
||||
|
||||
//*******************************************
|
||||
/// Constructor.
|
||||
//*******************************************
|
||||
message_bus()
|
||||
: imessage_bus(router_list)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
etl::vector<etl::imessage_router*, MAX_ROUTERS_> router_list;
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Send a message to a bus.
|
||||
//***************************************************************************
|
||||
inline static void send_message(etl::imessage_bus& bus,
|
||||
const etl::imessage& message)
|
||||
{
|
||||
bus.receive(message);
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Send a message to a bus.
|
||||
//***************************************************************************
|
||||
inline static void send_message(etl::imessage_bus& bus,
|
||||
etl::message_router_id_t id,
|
||||
const etl::imessage& message)
|
||||
{
|
||||
bus.receive(id, message);
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Send a message to a bus.
|
||||
//***************************************************************************
|
||||
inline static void send_message(etl::imessage_router& source,
|
||||
etl::imessage_bus& bus,
|
||||
const etl::imessage& message)
|
||||
{
|
||||
bus.receive(source, message);
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Send a message to a bus.
|
||||
//***************************************************************************
|
||||
inline static void send_message(etl::imessage_router& source,
|
||||
etl::imessage_bus& bus,
|
||||
etl::message_router_id_t id,
|
||||
const etl::imessage& message)
|
||||
{
|
||||
bus.receive(source, id, message);
|
||||
}
|
||||
}
|
||||
|
||||
#undef ETL_FILE
|
||||
|
||||
#endif
|
||||
2200
src/message_router.h
Normal file
2200
src/message_router.h
Normal file
File diff suppressed because it is too large
Load Diff
514
src/message_router_generator.h
Normal file
514
src/message_router_generator.h
Normal file
@ -0,0 +1,514 @@
|
||||
/******************************************************************************
|
||||
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.
|
||||
******************************************************************************/
|
||||
|
||||
/*[[[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 "message.h"
|
||||
#include "message_types.h"
|
||||
#include "alignment.h"
|
||||
#include "error_handler.h"
|
||||
#include "exception.h"
|
||||
#include "largest.h"
|
||||
|
||||
#undef ETL_FILE
|
||||
#define ETL_FILE "35"
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
/// Base exception class for message router
|
||||
//***************************************************************************
|
||||
class message_router_exception : public etl::exception
|
||||
{
|
||||
public:
|
||||
|
||||
message_router_exception(string_type what, string_type file_name, numeric_type line_number)
|
||||
: etl::exception(what, file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Router id is out of the legal range.
|
||||
//***************************************************************************
|
||||
class message_router_illegal_id : public etl::message_router_exception
|
||||
{
|
||||
public:
|
||||
|
||||
message_router_illegal_id(string_type file_name, numeric_type line_number)
|
||||
: message_router_exception(ETL_ERROR_TEXT("message router:illegal id", ETL_FILE"A"), file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
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());
|
||||
}
|
||||
|
||||
//********************************************
|
||||
etl::message_router_id_t get_message_router_id() const
|
||||
{
|
||||
return message_router_id;
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
NULL_MESSAGE_ROUTER = 255,
|
||||
MESSAGE_BUS = 254,
|
||||
ALL_MESSAGE_ROUTERS = 253,
|
||||
MAX_MESSAGE_ROUTER = 249
|
||||
};
|
||||
|
||||
protected:
|
||||
|
||||
imessage_router(etl::message_router_id_t id)
|
||||
: message_router_id(id)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// Disabled.
|
||||
imessage_router(const imessage_router&);
|
||||
imessage_router& operator =(const imessage_router&);
|
||||
|
||||
etl::message_router_id_t message_router_id;
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// This router can be used 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:
|
||||
|
||||
null_message_router()
|
||||
: imessage_router(imessage_router::NULL_MESSAGE_ROUTER)
|
||||
{
|
||||
}
|
||||
|
||||
//********************************************
|
||||
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& instance()
|
||||
{
|
||||
static null_message_router nmr;
|
||||
return nmr;
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// 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);
|
||||
}
|
||||
|
||||
/*[[[cog
|
||||
import cog
|
||||
################################################
|
||||
# The first definition for all of the messages.
|
||||
################################################
|
||||
cog.outl("//***************************************************************************")
|
||||
cog.outl("// The definition for all %s message types." % Handlers)
|
||||
cog.outl("//***************************************************************************")
|
||||
cog.outl("template <typename TDerived,")
|
||||
cog.out(" ")
|
||||
cog.out("typename T1, ")
|
||||
for n in range(2, int(Handlers)):
|
||||
cog.out("typename T%s = void, " % n)
|
||||
if n % 4 == 0:
|
||||
cog.outl("")
|
||||
cog.out(" ")
|
||||
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.get_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(" message_router(etl::message_router_id_t id)")
|
||||
cog.outl(" : imessage_router(id)")
|
||||
cog.outl(" {")
|
||||
cog.outl(" ETL_ASSERT(id <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id));")
|
||||
cog.outl(" }")
|
||||
cog.outl("")
|
||||
cog.outl(" //**********************************************")
|
||||
cog.outl(" void receive(const etl::imessage& msg)")
|
||||
cog.outl(" {")
|
||||
cog.outl(" receive(etl::null_message_router::instance(), 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("")
|
||||
cog.outl(" switch (id)")
|
||||
cog.outl(" {")
|
||||
for n in range(1, int(Handlers) + 1):
|
||||
cog.out(" case T%d::ID:" % n)
|
||||
cog.out(" static_cast<TDerived*>(this)->on_receive(source, static_cast<const T%d&>(msg));" % n)
|
||||
cog.outl(" break;")
|
||||
cog.out(" default:")
|
||||
cog.out(" static_cast<TDerived*>(this)->on_receive_unknown(source, msg);")
|
||||
cog.outl(" break;")
|
||||
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)")
|
||||
cog.outl(" {")
|
||||
cog.out(" ")
|
||||
for n in range(1, int(Handlers) + 1):
|
||||
cog.out("case T%d::ID: " % n)
|
||||
if n % 8 == 0:
|
||||
cog.outl("")
|
||||
cog.out(" ")
|
||||
cog.outl(" return true; break;")
|
||||
cog.outl(" default:")
|
||||
cog.outl(" return false; break;")
|
||||
cog.outl(" }")
|
||||
cog.outl(" }")
|
||||
cog.outl("};")
|
||||
|
||||
####################################
|
||||
# All of the other specialisations.
|
||||
####################################
|
||||
for n in range(int(Handlers) - 1, 0, -1):
|
||||
cog.outl("")
|
||||
cog.outl("//***************************************************************************")
|
||||
if n == 1:
|
||||
cog.outl("// Specialisation for %d message type." % n)
|
||||
else:
|
||||
cog.outl("// Specialisation for %d message types." % n)
|
||||
cog.outl("//***************************************************************************")
|
||||
cog.outl("template <typename TDerived, ")
|
||||
cog.out(" ")
|
||||
for t in range(1, n):
|
||||
cog.out("typename T%d, " % t)
|
||||
if t % 4 == 0:
|
||||
cog.outl("")
|
||||
cog.out(" ")
|
||||
cog.outl("typename T%d>" % n)
|
||||
cog.out("class message_router<TDerived, ")
|
||||
for t in range(1, n + 1):
|
||||
cog.out("T%d, " % t)
|
||||
if t % 16 == 0:
|
||||
cog.outl("")
|
||||
cog.out(" ")
|
||||
for t in range(n + 1, int(Handlers)):
|
||||
cog.out("void, ")
|
||||
if t % 16 == 0:
|
||||
cog.outl("")
|
||||
cog.out(" ")
|
||||
cog.outl("void>")
|
||||
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.get_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(" message_router(etl::message_router_id_t id)")
|
||||
cog.outl(" : imessage_router(id)")
|
||||
cog.outl(" {")
|
||||
cog.outl(" ETL_ASSERT(id <= etl::imessage_router::MAX_MESSAGE_ROUTER, ETL_ERROR(etl::message_router_illegal_id));")
|
||||
cog.outl(" }")
|
||||
cog.outl("")
|
||||
cog.outl(" //**********************************************")
|
||||
cog.outl(" void receive(const etl::imessage& msg)")
|
||||
cog.outl(" {")
|
||||
cog.outl(" receive(etl::null_message_router::instance(), 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("")
|
||||
cog.outl(" switch (id)")
|
||||
cog.outl(" {")
|
||||
for t in range(1, n + 1):
|
||||
cog.out(" case T%d::ID:" % t)
|
||||
cog.out(" static_cast<TDerived*>(this)->on_receive(source, static_cast<const T%d&>(msg));" % t)
|
||||
cog.outl(" break;")
|
||||
cog.out(" default:")
|
||||
cog.out(" static_cast<TDerived*>(this)->on_receive_unknown(source, msg);")
|
||||
cog.outl(" break;")
|
||||
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)")
|
||||
cog.outl(" {")
|
||||
cog.out(" ")
|
||||
for t in range(1, n + 1):
|
||||
cog.out("case T%d::ID: " % t)
|
||||
if t % 8 == 0:
|
||||
cog.outl("")
|
||||
cog.out(" ")
|
||||
cog.outl("")
|
||||
cog.outl(" return true; break;")
|
||||
cog.outl(" default:")
|
||||
cog.outl(" return false; break;")
|
||||
cog.outl(" }")
|
||||
cog.outl(" }")
|
||||
cog.outl("};")
|
||||
]]]*/
|
||||
/*[[[end]]]*/
|
||||
}
|
||||
|
||||
#undef ETL_FILE
|
||||
|
||||
#endif
|
||||
46
src/message_types.h
Normal file
46
src/message_types.h
Normal file
@ -0,0 +1,46 @@
|
||||
/******************************************************************************
|
||||
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_MESSAGE_DEFS__
|
||||
#define __ETL_MESSAGE_DEFS__
|
||||
|
||||
#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
|
||||
|
||||
typedef uint_least8_t message_router_id_t;
|
||||
}
|
||||
|
||||
#endif
|
||||
128
src/packet.h
Normal file
128
src/packet.h
Normal 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
|
||||
410
src/scheduler.h
Normal file
410
src/scheduler.h
Normal file
@ -0,0 +1,410 @@
|
||||
/******************************************************************************
|
||||
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_SCHEDULER__
|
||||
#define __ETL_SCHEDULER__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "vector.h"
|
||||
#include "nullptr.h"
|
||||
#include "error_handler.h"
|
||||
#include "exception.h"
|
||||
#include "task.h"
|
||||
#include "type_traits.h"
|
||||
#include "function.h"
|
||||
|
||||
#undef ETL_FILE
|
||||
#define ETL_FILE "36"
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
/// Base exception class for scheduler.
|
||||
//***************************************************************************
|
||||
class scheduler_exception : public etl::exception
|
||||
{
|
||||
public:
|
||||
|
||||
scheduler_exception(string_type what, string_type file_name, numeric_type line_number)
|
||||
: etl::exception(what, file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// 'No tasks' exception.
|
||||
//***************************************************************************
|
||||
class scheduler_no_tasks_exception : public etl::scheduler_exception
|
||||
{
|
||||
public:
|
||||
|
||||
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)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// 'Null tasks' exception.
|
||||
//***************************************************************************
|
||||
class scheduler_null_task_exception : public etl::scheduler_exception
|
||||
{
|
||||
public:
|
||||
|
||||
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)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// 'Too many tasks' exception.
|
||||
//***************************************************************************
|
||||
class scheduler_too_many_tasks_exception : public etl::scheduler_exception
|
||||
{
|
||||
public:
|
||||
|
||||
scheduler_too_many_tasks_exception(string_type file_name, numeric_type line_number)
|
||||
: etl::scheduler_exception(ETL_ERROR_TEXT("scheduler:too many tasks", ETL_FILE"C"), file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// 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_sequencial_single
|
||||
{
|
||||
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]);
|
||||
|
||||
if (task.task_request_work() > 0)
|
||||
{
|
||||
task.task_process_work();
|
||||
idle = false;
|
||||
}
|
||||
}
|
||||
|
||||
return idle;
|
||||
}
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// 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.
|
||||
//***************************************************************************
|
||||
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;
|
||||
break;
|
||||
}
|
||||
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:
|
||||
|
||||
//*******************************************
|
||||
// Virtuals.
|
||||
//*******************************************
|
||||
virtual void start() = 0;
|
||||
|
||||
virtual ~ischeduler()
|
||||
{
|
||||
}
|
||||
|
||||
//*******************************************
|
||||
/// Set the idle callback.
|
||||
//*******************************************
|
||||
void set_idle_callback(etl::ifunction<void>& callback)
|
||||
{
|
||||
p_idle_callback = &callback;
|
||||
}
|
||||
|
||||
//*******************************************
|
||||
/// Set the watchdog callback.
|
||||
//*******************************************
|
||||
void set_watchdog_callback(etl::ifunction<void>& callback)
|
||||
{
|
||||
p_watchdog_callback = &callback;
|
||||
}
|
||||
|
||||
//*******************************************
|
||||
/// Set the running state for the scheduler.
|
||||
//*******************************************
|
||||
void set_scheduler_running(bool scheduler_running_)
|
||||
{
|
||||
scheduler_running = scheduler_running_;
|
||||
}
|
||||
|
||||
//*******************************************
|
||||
/// Get the running state for the scheduler.
|
||||
//*******************************************
|
||||
bool scheduler_is_running() const
|
||||
{
|
||||
return scheduler_running;
|
||||
}
|
||||
|
||||
//*******************************************
|
||||
/// Force the scheduler to exit.
|
||||
//*******************************************
|
||||
void exit_scheduler()
|
||||
{
|
||||
scheduler_exit = true;
|
||||
}
|
||||
|
||||
//*******************************************
|
||||
/// Add a task.
|
||||
/// Add to the task list in priority order.
|
||||
//*******************************************
|
||||
void add_task(etl::task& task)
|
||||
{
|
||||
ETL_ASSERT(!task_list.full(), ETL_ERROR(etl::scheduler_too_many_tasks_exception))
|
||||
|
||||
if (!task_list.full())
|
||||
{
|
||||
typename task_list_t::iterator itask = std::upper_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]));
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
//*******************************************
|
||||
/// Constructor.
|
||||
//*******************************************
|
||||
ischeduler(etl::ivector<etl::task*>& task_list_)
|
||||
: scheduler_running(false),
|
||||
scheduler_exit(false),
|
||||
p_idle_callback(nullptr),
|
||||
p_watchdog_callback(nullptr),
|
||||
task_list(task_list_)
|
||||
{
|
||||
}
|
||||
|
||||
bool scheduler_running;
|
||||
bool scheduler_exit;
|
||||
etl::ifunction<void>* p_idle_callback;
|
||||
etl::ifunction<void>* p_watchdog_callback;
|
||||
|
||||
private:
|
||||
|
||||
//*******************************************
|
||||
// Used to order tasks in descending priority.
|
||||
//*******************************************
|
||||
struct compare_priority
|
||||
{
|
||||
bool operator()(etl::task* ptask, etl::task_priority_t priority) const
|
||||
{
|
||||
return ptask->get_task_priority() > priority;
|
||||
}
|
||||
|
||||
bool operator()(etl::task_priority_t priority, etl::task* ptask) const
|
||||
{
|
||||
return priority > ptask->get_task_priority();
|
||||
}
|
||||
};
|
||||
|
||||
typedef etl::ivector<etl::task*> task_list_t;
|
||||
task_list_t& task_list;
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Scheduler.
|
||||
//***************************************************************************
|
||||
template <typename TSchedulerPolicy, size_t MAX_TASKS_>
|
||||
class scheduler : public etl::ischeduler, protected TSchedulerPolicy
|
||||
{
|
||||
public:
|
||||
|
||||
enum
|
||||
{
|
||||
MAX_TASKS = MAX_TASKS_,
|
||||
};
|
||||
|
||||
scheduler()
|
||||
: ischeduler(task_list)
|
||||
{
|
||||
}
|
||||
|
||||
//*******************************************
|
||||
/// Start the scheduler. SEQUENCIAL_SINGLE
|
||||
/// Only calls the task to process work once, if it has work to do.
|
||||
//*******************************************
|
||||
void 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 (!scheduler_exit)
|
||||
{
|
||||
if (scheduler_running)
|
||||
{
|
||||
bool idle = TSchedulerPolicy::schedule_tasks(task_list);
|
||||
|
||||
if (p_watchdog_callback)
|
||||
{
|
||||
(*p_watchdog_callback)();
|
||||
}
|
||||
|
||||
if (idle && p_idle_callback)
|
||||
{
|
||||
(*p_idle_callback)();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
typedef etl::vector<etl::task*, MAX_TASKS> task_list_t;
|
||||
task_list_t task_list;
|
||||
};
|
||||
}
|
||||
|
||||
#undef ETL_FILE
|
||||
|
||||
#endif
|
||||
@ -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
|
||||
|
||||
@ -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
336
src/smallest_generator.h
Normal file
@ -0,0 +1,336 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
https://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
|
||||
125
src/task.h
Normal file
125
src/task.h
Normal file
@ -0,0 +1,125 @@
|
||||
/******************************************************************************
|
||||
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_TASK__
|
||||
#define __ETL_TASK__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "error_handler.h"
|
||||
#include "exception.h"
|
||||
|
||||
#undef ETL_FILE
|
||||
#define ETL_FILE "37"
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
/// Base exception class for task.
|
||||
//***************************************************************************
|
||||
class task_exception : public etl::exception
|
||||
{
|
||||
public:
|
||||
|
||||
task_exception(string_type what, string_type file_name, numeric_type line_number)
|
||||
: etl::exception(what, file_name, line_number)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
typedef uint_least8_t task_priority_t;
|
||||
|
||||
//***************************************************************************
|
||||
/// Scheduler.
|
||||
//***************************************************************************
|
||||
class task
|
||||
{
|
||||
public:
|
||||
|
||||
//*******************************************
|
||||
/// Constructor.
|
||||
//*******************************************
|
||||
task(task_priority_t priority)
|
||||
: task_running(true),
|
||||
task_priority(priority)
|
||||
{
|
||||
}
|
||||
|
||||
//*******************************************
|
||||
/// Destructor.
|
||||
//*******************************************
|
||||
virtual ~task()
|
||||
{
|
||||
}
|
||||
|
||||
//*******************************************
|
||||
/// Called to check if the task has work.
|
||||
/// Returns a score as to the amount of work it has to do.
|
||||
//*******************************************
|
||||
virtual uint32_t task_request_work() const = 0;
|
||||
|
||||
//*******************************************
|
||||
/// Called to get the task to do work.
|
||||
//*******************************************
|
||||
virtual void task_process_work() = 0;
|
||||
|
||||
//*******************************************
|
||||
/// Set the running state for the task.
|
||||
//*******************************************
|
||||
void set_task_running(bool task_running_)
|
||||
{
|
||||
task_running = task_running_;
|
||||
}
|
||||
|
||||
//*******************************************
|
||||
/// Get the running state for the task.
|
||||
//*******************************************
|
||||
bool task_is_running() const
|
||||
{
|
||||
return task_running;
|
||||
}
|
||||
|
||||
//*******************************************
|
||||
/// Get the priority of the task.
|
||||
/// Higher value = higher priority.
|
||||
//*******************************************
|
||||
etl::task_priority_t get_task_priority() const
|
||||
{
|
||||
return task_priority;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
bool task_running;
|
||||
etl::task_priority_t task_priority;
|
||||
};
|
||||
}
|
||||
|
||||
#undef ETL_FILE
|
||||
|
||||
#endif
|
||||
@ -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
|
||||
|
||||
@ -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 -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 +174,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 +258,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 +311,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 +414,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
500
src/type_traits_generator.h
Normal file
@ -0,0 +1,500 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
https://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
|
||||
@ -89,43 +89,16 @@ SOFTWARE.
|
||||
TypeName operator ++(int) { TypeName temp(*this); TypeName::operator ++(); return temp; } \
|
||||
TypeName& operator --() { --value; return *this; } \
|
||||
TypeName operator --(int) { TypeName temp(*this); TypeName::operator --(); return temp; } \
|
||||
TypeName& operator +=(const TypeName& rhs) { value += rhs.value; return *this; } \
|
||||
TypeName& operator -=(const TypeName& rhs) { value -= rhs.value; return *this; } \
|
||||
TypeName& operator *=(const TypeName& rhs) { value *= rhs.value; return *this; } \
|
||||
TypeName& operator /=(const TypeName& rhs) { value /= rhs.value; return *this; } \
|
||||
TypeName& operator %=(const TypeName& rhs) { value %= rhs.value; return *this; } \
|
||||
TypeName& operator &=(const TypeName& rhs) { value &= rhs.value; return *this; } \
|
||||
TypeName& operator &=(ValueType mask) { value &= mask; return *this; } \
|
||||
TypeName& operator |=(const TypeName& rhs) { value |= rhs.value; return *this; } \
|
||||
TypeName& operator |=(ValueType mask) { value &= mask; return *this; } \
|
||||
TypeName& operator ^=(const TypeName& rhs) { value ^= rhs.value; return *this; } \
|
||||
TypeName& operator ^=(ValueType mask) { value ^= mask; return *this; } \
|
||||
TypeName& operator +=(const ValueType& rhs) { value += rhs; return *this; } \
|
||||
TypeName& operator -=(const ValueType& rhs) { value -= rhs; return *this; } \
|
||||
TypeName& operator *=(const ValueType& rhs) { value *= rhs; return *this; } \
|
||||
TypeName& operator /=(const ValueType& rhs) { value /= rhs; return *this; } \
|
||||
TypeName& operator %=(const ValueType& rhs) { value %= rhs; return *this; } \
|
||||
TypeName& operator &=(const ValueType& rhs) { value &= rhs; return *this; } \
|
||||
TypeName& operator |=(const ValueType& rhs) { value |= rhs; return *this; } \
|
||||
TypeName& operator ^=(const ValueType& rhs) { value ^= rhs; return *this; } \
|
||||
TypeName& operator <<=(ValueType distance) { value <<= distance; return *this; } \
|
||||
TypeName& operator >>=(ValueType distance) { value >>= distance; return *this; } \
|
||||
\
|
||||
/* Volatile definitions.*/ \
|
||||
TypeName(const volatile TypeName &other) : value(other.value) {} \
|
||||
void operator=(const volatile TypeName &other) volatile { value = other.value; } \
|
||||
operator ValueType() volatile const { return value; } \
|
||||
volatile ValueType& get() volatile { return value; } \
|
||||
const volatile ValueType& get() volatile const { return value; } \
|
||||
void operator ++() volatile { ++value; } \
|
||||
volatile TypeName operator ++(int) volatile { volatile TypeName temp(*this); TypeName::operator ++(); return temp; } \
|
||||
void operator --() volatile { --value; } \
|
||||
volatile TypeName operator --(int) volatile { volatile TypeName temp(*this); TypeName::operator --(); return temp; } \
|
||||
void operator +=(const volatile TypeName& rhs) volatile { value += rhs.value; } \
|
||||
void operator -=(const volatile TypeName& rhs) volatile { value -= rhs.value; } \
|
||||
void operator *=(const volatile TypeName& rhs) volatile { value *= rhs.value; } \
|
||||
void operator /=(const volatile TypeName& rhs) volatile { value /= rhs.value; } \
|
||||
void operator %=(const volatile TypeName& rhs) volatile { value %= rhs.value; } \
|
||||
void operator &=(const volatile TypeName& rhs) volatile { value &= rhs.value; } \
|
||||
void operator &=(ValueType mask) volatile { value &= mask; } \
|
||||
void operator |=(const volatile TypeName& rhs) volatile { value |= rhs.value; } \
|
||||
void operator |=(ValueType mask) volatile { value &= mask; } \
|
||||
void operator ^=(const volatile TypeName& rhs) volatile { value ^= rhs.value; } \
|
||||
void operator ^=(ValueType mask) volatile { value ^= mask; } \
|
||||
void operator <<=(ValueType distance) volatile { value <<= distance; } \
|
||||
void operator >>=(ValueType distance) volatile { value >>= distance; } \
|
||||
private: \
|
||||
ValueType value; \
|
||||
public: \
|
||||
|
||||
124
src/variant.h
124
src/variant.h
@ -5,7 +5,7 @@ The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
http://www.etlcpp.com
|
||||
https://www.etlcpp.com
|
||||
|
||||
Copyright(c) 2014 jwellbelove
|
||||
|
||||
@ -42,7 +42,6 @@ SOFTWARE.
|
||||
#include "static_assert.h"
|
||||
#include "alignment.h"
|
||||
#include "error_handler.h"
|
||||
#include "largest.h"
|
||||
|
||||
#if defined(ETL_COMPILER_KEIL)
|
||||
#pragma diag_suppress 940
|
||||
@ -124,6 +123,11 @@ namespace etl
|
||||
//***************************************************************************
|
||||
typedef typename largest_type<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
984
temp/message_router.h
Normal 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
|
||||
@ -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,17 @@
|
||||
<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_bus.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/message_types.h" />
|
||||
<Unit filename="../../src/multimap.h" />
|
||||
<Unit filename="../../src/multiset.h" />
|
||||
<Unit filename="../../src/murmur3.h" />
|
||||
@ -206,6 +213,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 +234,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 +285,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 +304,15 @@
|
||||
<Unit filename="../test_map.cpp" />
|
||||
<Unit filename="../test_maths.cpp" />
|
||||
<Unit filename="../test_memory.cpp" />
|
||||
<Unit filename="../test_message_bus.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,12 +330,14 @@
|
||||
<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" />
|
||||
<Unit filename="../test_unordered_multimap.cpp" />
|
||||
<Unit filename="../test_unordered_multiset.cpp" />
|
||||
<Unit filename="../test_unordered_set.cpp" />
|
||||
<Unit filename="../test_user_type.cpp" />
|
||||
<Unit filename="../test_utility.cpp" />
|
||||
<Unit filename="../test_variant.cpp" />
|
||||
<Unit filename="../test_vector.cpp" />
|
||||
|
||||
@ -3289,7 +3289,7 @@
|
||||
"CurrentTest.h"
|
||||
"ReportAssertImpl.h"
|
||||
|
||||
1501066687 source:d:\users\john\documents\programming\github\etl\test\test_algorithm.cpp
|
||||
1501803139 source:d:\users\john\documents\programming\github\etl\test\test_algorithm.cpp
|
||||
"UnitTest++.h"
|
||||
"algorithm.h"
|
||||
"container.h"
|
||||
@ -3538,7 +3538,7 @@
|
||||
"static_assert.h"
|
||||
"exception.h"
|
||||
|
||||
1501067284 source:d:\users\john\documents\programming\github\etl\test\test_deque.cpp
|
||||
1501803126 source:d:\users\john\documents\programming\github\etl\test\test_deque.cpp
|
||||
"UnitTest++.h"
|
||||
"ExtraCheckMacros.h"
|
||||
"deque.h"
|
||||
@ -3727,7 +3727,7 @@
|
||||
|
||||
1482623723 v_1.h"
|
||||
|
||||
1497713618 source:d:\users\john\documents\programming\github\etl\test\test_forward_list.cpp
|
||||
1501803126 source:d:\users\john\documents\programming\github\etl\test\test_forward_list.cpp
|
||||
"UnitTest++.h"
|
||||
"ExtraCheckMacros.h"
|
||||
"data.h"
|
||||
@ -4151,12 +4151,12 @@
|
||||
"../exception.h"
|
||||
"../error_handler.h"
|
||||
|
||||
1500986416 source:d:\users\john\documents\programming\github\etl\test\test_type_traits.cpp
|
||||
1501803140 source:d:\users\john\documents\programming\github\etl\test\test_type_traits.cpp
|
||||
"UnitTest++.h"
|
||||
"type_traits.h"
|
||||
<type_traits>
|
||||
|
||||
1500986416 source:d:\users\john\documents\programming\github\etl\test\test_variant.cpp
|
||||
1501803140 source:d:\users\john\documents\programming\github\etl\test\test_variant.cpp
|
||||
"UnitTest++.h"
|
||||
"ExtraCheckMacros.h"
|
||||
"variant.h"
|
||||
@ -5302,7 +5302,7 @@
|
||||
"platform.h"
|
||||
"static_assert.h"
|
||||
|
||||
1501066686 d:\users\john\documents\programming\github\etl\src\algorithm.h
|
||||
1502118978 d:\users\john\documents\programming\github\etl\src\algorithm.h
|
||||
<algorithm>
|
||||
<iterator>
|
||||
<utility>
|
||||
@ -5312,7 +5312,7 @@
|
||||
"iterator.h"
|
||||
"type_traits.h"
|
||||
|
||||
1501066686 d:\users\john\documents\programming\github\etl\src\type_traits.h
|
||||
1502118978 d:\users\john\documents\programming\github\etl\src\type_traits.h
|
||||
<stddef.h>
|
||||
"platform.h"
|
||||
"nullptr.h"
|
||||
@ -5322,7 +5322,7 @@
|
||||
<stddef.h>
|
||||
<iterator>
|
||||
|
||||
1500986416 d:\users\john\documents\programming\github\etl\src\alignment.h
|
||||
1502118978 d:\users\john\documents\programming\github\etl\src\alignment.h
|
||||
<stdint.h>
|
||||
"type_traits.h"
|
||||
"static_assert.h"
|
||||
@ -5370,7 +5370,7 @@
|
||||
<stdint.h>
|
||||
"log.h"
|
||||
|
||||
1501066686 d:\users\john\documents\programming\github\etl\src\smallest.h
|
||||
1502118978 d:\users\john\documents\programming\github\etl\src\smallest.h
|
||||
<stdint.h>
|
||||
"integral_limits.h"
|
||||
|
||||
@ -5484,7 +5484,7 @@
|
||||
"static_assert.h"
|
||||
"exception.h"
|
||||
|
||||
1501067284 d:\users\john\documents\programming\github\etl\src\deque.h
|
||||
1501803126 d:\users\john\documents\programming\github\etl\src\deque.h
|
||||
<stddef.h>
|
||||
<stdint.h>
|
||||
<iterator>
|
||||
@ -5561,7 +5561,7 @@
|
||||
"../error_handler.h"
|
||||
"../debug_count.h"
|
||||
|
||||
1501067284 d:\users\john\documents\programming\github\etl\src\vector.h
|
||||
1501803126 d:\users\john\documents\programming\github\etl\src\vector.h
|
||||
<type_traits>
|
||||
<stddef.h>
|
||||
<stdint.h>
|
||||
@ -5606,7 +5606,7 @@
|
||||
"../ivector.h"
|
||||
"../error_handler.h"
|
||||
|
||||
1497713617 d:\users\john\documents\programming\github\etl\src\forward_list.h
|
||||
1501803126 d:\users\john\documents\programming\github\etl\src\forward_list.h
|
||||
<iterator>
|
||||
<algorithm>
|
||||
<functional>
|
||||
@ -5703,12 +5703,12 @@
|
||||
"nullptr.h"
|
||||
"parameter_type.h"
|
||||
|
||||
1501067284 d:\users\john\documents\programming\github\etl\src\largest.h
|
||||
1502118978 d:\users\john\documents\programming\github\etl\src\largest.h
|
||||
"type_traits.h"
|
||||
"smallest.h"
|
||||
"static_assert.h"
|
||||
|
||||
1501067284 d:\users\john\documents\programming\github\etl\src\list.h
|
||||
1502118941 d:\users\john\documents\programming\github\etl\src\list.h
|
||||
<iterator>
|
||||
<algorithm>
|
||||
<functional>
|
||||
@ -5930,7 +5930,7 @@
|
||||
"exception.h"
|
||||
"error_handler.h"
|
||||
|
||||
1500986416 d:\users\john\documents\programming\github\etl\src\variant.h
|
||||
1501803139 d:\users\john\documents\programming\github\etl\src\variant.h
|
||||
<stdint.h>
|
||||
"platform.h"
|
||||
"array.h"
|
||||
@ -5941,7 +5941,6 @@
|
||||
"static_assert.h"
|
||||
"alignment.h"
|
||||
"error_handler.h"
|
||||
"largest.h"
|
||||
|
||||
1479515291 d:\users\john\documents\programming\github\etl\src\visitor.h
|
||||
|
||||
@ -7825,7 +7824,7 @@
|
||||
<iterator>
|
||||
"type_traits.h"
|
||||
|
||||
1501066686 d:\users\john\documents\programming\github\etl\src\memory.h
|
||||
1502118978 d:\users\john\documents\programming\github\etl\src\memory.h
|
||||
<iterator>
|
||||
<algorithm>
|
||||
"type_traits.h"
|
||||
@ -7835,10 +7834,10 @@
|
||||
<assert.h>
|
||||
"platform.h"
|
||||
|
||||
1501067284 source:d:\users\john\documents\programming\github\etl\src\random.cpp
|
||||
1501803126 source:d:\users\john\documents\programming\github\etl\src\random.cpp
|
||||
"random.h"
|
||||
|
||||
1501067284 d:\users\john\documents\programming\github\etl\src\random.h
|
||||
1501803126 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
|
||||
@ -7933,7 +7932,7 @@
|
||||
"UnitTest++.h"
|
||||
"iterator.h"
|
||||
|
||||
1500986416 source:d:\users\john\documents\programming\github\etl\test\test_memory.cpp
|
||||
1501803139 source:d:\users\john\documents\programming\github\etl\test\test_memory.cpp
|
||||
"UnitTest++.h"
|
||||
"memory.h"
|
||||
"debug_count.h"
|
||||
@ -7944,7 +7943,7 @@
|
||||
<stdint.h>
|
||||
<vector>
|
||||
|
||||
1501067284 source:d:\users\john\documents\programming\github\etl\test\test_random.cpp
|
||||
1501803126 source:d:\users\john\documents\programming\github\etl\test\test_random.cpp
|
||||
"UnitTest++.h"
|
||||
<stdint.h>
|
||||
"random.h"
|
||||
@ -7952,7 +7951,7 @@
|
||||
<algorithm>
|
||||
<fstream>
|
||||
|
||||
1501067284 source:d:\users\john\documents\programming\github\etl\test\test_vector_non_trivial.cpp
|
||||
1501803126 source:d:\users\john\documents\programming\github\etl\test\test_vector_non_trivial.cpp
|
||||
"UnitTest++.h"
|
||||
<vector>
|
||||
<array>
|
||||
@ -8229,3 +8228,133 @@
|
||||
"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>
|
||||
|
||||
1501803139 source:d:\users\john\documents\programming\github\etl\test\test_fsm.cpp
|
||||
"UnitTest++.h"
|
||||
"fsm.h"
|
||||
"enum_type.h"
|
||||
"container.h"
|
||||
<iostream>
|
||||
|
||||
1501803139 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"
|
||||
|
||||
1501803139 d:\users\john\documents\programming\github\etl\src\user_type.h
|
||||
|
||||
1501803139 d:\users\john\documents\programming\github\etl\src\message_router.h
|
||||
<stdint.h>
|
||||
"message.h"
|
||||
"message_types.h"
|
||||
"alignment.h"
|
||||
"error_handler.h"
|
||||
"exception.h"
|
||||
"largest.h"
|
||||
|
||||
1501803140 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"
|
||||
|
||||
1501803139 d:\users\john\documents\programming\github\etl\src\packet.h
|
||||
"platform.h"
|
||||
"static_assert.h"
|
||||
"alignment.h"
|
||||
|
||||
1501803140 source:d:\users\john\documents\programming\github\etl\test\test_packet.cpp
|
||||
"UnitTest++.h"
|
||||
"ExtraCheckMacros.h"
|
||||
"packet.h"
|
||||
"largest.h"
|
||||
"queue.h"
|
||||
"pool.h"
|
||||
|
||||
1501803140 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"
|
||||
|
||||
1501803139 d:\users\john\documents\programming\github\etl\src\task.h
|
||||
<stdint.h>
|
||||
"error_handler.h"
|
||||
"exception.h"
|
||||
|
||||
1501803139 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"
|
||||
|
||||
1501803139 d:\users\john\documents\programming\github\etl\src\message.h
|
||||
<stdint.h>
|
||||
"error_handler.h"
|
||||
"exception.h"
|
||||
"message_types.h"
|
||||
|
||||
1501803139 d:\users\john\documents\programming\github\etl\src\message_types.h
|
||||
<stdint.h>
|
||||
|
||||
1501803139 source:d:\users\john\documents\programming\github\etl\test\test_message_bus.cpp
|
||||
"UnitTest++.h"
|
||||
"ExtraCheckMacros.h"
|
||||
"message_router.h"
|
||||
"message_bus.h"
|
||||
"queue.h"
|
||||
"largest.h"
|
||||
"packet.h"
|
||||
|
||||
1501803139 d:\users\john\documents\programming\github\etl\src\message_bus.h
|
||||
<stdint.h>
|
||||
<algorithm>
|
||||
"algorithm.h"
|
||||
"vector.h"
|
||||
"nullptr.h"
|
||||
"error_handler.h"
|
||||
"exception.h"
|
||||
"message_types.h"
|
||||
"message.h"
|
||||
"message_router.h"
|
||||
|
||||
1501803140 source:d:\users\john\documents\programming\github\etl\test\test_user_type.cpp
|
||||
"UnitTest++.h"
|
||||
<string>
|
||||
"user_type.h"
|
||||
|
||||
|
||||
@ -2,269 +2,24 @@
|
||||
<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\vector.h" open="0" top="0" tabpos="6" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||
<Cursor>
|
||||
<Cursor1 position="15560" topLine="342" />
|
||||
</Cursor>
|
||||
</File>
|
||||
<File name="..\..\src\error_handler.h" open="0" top="0" tabpos="4" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||
<Cursor>
|
||||
<Cursor1 position="4288" topLine="74" />
|
||||
</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="..\..\src\queue.h" open="0" top="0" tabpos="17" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||
<Cursor>
|
||||
<Cursor1 position="11193" topLine="229" />
|
||||
</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">
|
||||
<Cursor>
|
||||
<Cursor1 position="11590" topLine="274" />
|
||||
</Cursor>
|
||||
</File>
|
||||
<File name="..\test_type_traits.cpp" open="0" top="0" tabpos="11" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||
<Cursor>
|
||||
<Cursor1 position="37662" topLine="472" />
|
||||
</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="..\..\src\private\pvoidvector.h" open="0" top="0" tabpos="19" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||
<Cursor>
|
||||
<Cursor1 position="7770" topLine="137" />
|
||||
</Cursor>
|
||||
</File>
|
||||
<File name="..\..\src\deque.h" open="0" top="0" tabpos="3" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||
<Cursor>
|
||||
<Cursor1 position="54765" topLine="1616" />
|
||||
</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="..\test_vector.cpp" open="0" top="0" tabpos="9" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||
<Cursor>
|
||||
<Cursor1 position="1450" topLine="0" />
|
||||
</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">
|
||||
<Cursor>
|
||||
<Cursor1 position="22451" topLine="619" />
|
||||
</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">
|
||||
<Cursor>
|
||||
<Cursor1 position="699" 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_flat_multimap.cpp" open="0" top="0" tabpos="6" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||
<Cursor>
|
||||
<Cursor1 position="3425" topLine="85" />
|
||||
</Cursor>
|
||||
</File>
|
||||
<File name="..\..\src\alignment.h" open="0" top="0" tabpos="16" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||
<Cursor>
|
||||
<Cursor1 position="1527" topLine="15" />
|
||||
</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_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="..\..\src\intrusive_flat_map.h" open="0" top="0" tabpos="4" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||
<Cursor>
|
||||
<Cursor1 position="4065" topLine="242" />
|
||||
</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++\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="..\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="..\..\..\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++\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="..\test_vector_pointer.cpp" open="0" top="0" tabpos="10" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||
<Cursor>
|
||||
<Cursor1 position="1450" topLine="0" />
|
||||
</Cursor>
|
||||
</File>
|
||||
<File name="..\test_deque.cpp" open="0" top="0" tabpos="5" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||
<Cursor>
|
||||
<Cursor1 position="1445" topLine="0" />
|
||||
</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="..\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="..\..\src\flat_map.h" open="0" top="0" tabpos="8" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||
<Cursor>
|
||||
<Cursor1 position="2722" topLine="43" />
|
||||
</Cursor>
|
||||
</File>
|
||||
<File name="..\test_integral_limits.cpp" open="0" 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\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="..\..\..\unittest-cpp\UnitTest++\TestMacros.h" open="0" top="0" tabpos="13" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||
<Cursor>
|
||||
<Cursor1 position="1865" topLine="28" />
|
||||
</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="..\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>
|
||||
<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="..\..\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="..\..\src\flat_multimap.h" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||
<Cursor>
|
||||
<Cursor1 position="0" topLine="87" />
|
||||
</Cursor>
|
||||
</File>
|
||||
<File name="..\test_intrusive_forward_list.cpp" open="0" top="0" tabpos="1" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||
<Cursor>
|
||||
<Cursor1 position="29068" topLine="703" />
|
||||
</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" />
|
||||
</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">
|
||||
<Cursor>
|
||||
<Cursor1 position="22041" topLine="620" />
|
||||
</Cursor>
|
||||
</File>
|
||||
<File name="..\..\src\static_assert.h" open="0" 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="..\..\src\intrusive_flat_multiset.h" open="0" top="0" tabpos="11" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||
<Cursor>
|
||||
<Cursor1 position="7605" topLine="248" />
|
||||
</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\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="..\test_forward_list.cpp" open="1" top="1" tabpos="1" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||
<Cursor>
|
||||
<Cursor1 position="8719" topLine="184" />
|
||||
</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\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="..\..\src\type_traits.h" open="0" top="0" tabpos="12" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||
<Cursor>
|
||||
<Cursor1 position="16936" topLine="334" />
|
||||
</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="..\..\..\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="6722" topLine="118" />
|
||||
<Cursor1 position="883" 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">
|
||||
<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="426" 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\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" />
|
||||
<Cursor1 position="469" topLine="0" />
|
||||
</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">
|
||||
@ -272,4 +27,64 @@
|
||||
<Cursor1 position="7487" topLine="243" />
|
||||
</Cursor>
|
||||
</File>
|
||||
<File name="..\..\src\flat_map.h" open="0" top="0" tabpos="8" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||
<Cursor>
|
||||
<Cursor1 position="2722" topLine="43" />
|
||||
</Cursor>
|
||||
</File>
|
||||
<File name="..\..\src\error_handler.h" open="0" top="0" tabpos="4" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||
<Cursor>
|
||||
<Cursor1 position="4288" topLine="74" />
|
||||
</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\flat_multimap.h" open="0" top="0" tabpos="0" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||
<Cursor>
|
||||
<Cursor1 position="0" topLine="87" />
|
||||
</Cursor>
|
||||
</File>
|
||||
<File name="..\..\src\queue.h" open="0" top="0" tabpos="17" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||
<Cursor>
|
||||
<Cursor1 position="11193" topLine="229" />
|
||||
</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\message_bus.h" open="1" top="1" tabpos="2" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||
<Cursor>
|
||||
<Cursor1 position="10784" topLine="332" />
|
||||
</Cursor>
|
||||
</File>
|
||||
<File name="..\test_type_traits.cpp" open="0" top="0" tabpos="11" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||
<Cursor>
|
||||
<Cursor1 position="37662" topLine="472" />
|
||||
</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="..\test_forward_list.cpp" open="1" top="0" tabpos="1" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||
<Cursor>
|
||||
<Cursor1 position="16670" topLine="442" />
|
||||
</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">
|
||||
<Cursor>
|
||||
<Cursor1 position="3425" topLine="85" />
|
||||
</Cursor>
|
||||
</File>
|
||||
<File name="..\..\src\vector.h" open="0" top="0" tabpos="6" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
|
||||
<Cursor>
|
||||
<Cursor1 position="15560" topLine="342" />
|
||||
</Cursor>
|
||||
</File>
|
||||
</CodeBlocks_layout_file>
|
||||
|
||||
@ -42,6 +42,39 @@ namespace
|
||||
typedef std::vector<int> Data;
|
||||
Data data = { 2, 1, 4, 3, 6, 5, 8, 7, 10, 9 };
|
||||
|
||||
struct StructData
|
||||
{
|
||||
int a;
|
||||
int b;
|
||||
};
|
||||
|
||||
bool operator ==(const StructData& lhs, const StructData& rhs)
|
||||
{
|
||||
return (lhs.a == rhs.a) && (lhs.b == rhs.b);
|
||||
}
|
||||
|
||||
struct StructDataPredicate
|
||||
{
|
||||
bool operator ()(const StructData& lhs, const StructData& rhs) const
|
||||
{
|
||||
return lhs.a < rhs.a;
|
||||
}
|
||||
};
|
||||
|
||||
struct StructDataEquality
|
||||
{
|
||||
bool operator ()(const StructData& lhs, const StructData& rhs) const
|
||||
{
|
||||
return lhs.a == rhs.a;
|
||||
}
|
||||
};
|
||||
|
||||
std::ostream& operator << (std::ostream& os, const StructData& data)
|
||||
{
|
||||
os << data.a << "," << data.b;
|
||||
return os;
|
||||
}
|
||||
|
||||
SUITE(test_algorithm)
|
||||
{
|
||||
//=========================================================================
|
||||
@ -543,10 +576,40 @@ namespace
|
||||
int data1[] = { 1, 2, 3, 5, 6, 7, 8 };
|
||||
|
||||
// Find the element not less than 4.
|
||||
int* p = std::find_if_not(std::begin(data1), std::end(data1), std::bind2nd(std::less<int>(), 4));
|
||||
int* p = etl::find_if_not(std::begin(data1), std::end(data1), std::bind2nd(std::less<int>(), 4));
|
||||
CHECK_EQUAL(5, *p);
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
TEST(binary_find)
|
||||
{
|
||||
int data1[] = { 1, 2, 3, 5, 6, 7, 8 };
|
||||
|
||||
// Find the element of value 5.
|
||||
int* p = etl::binary_find(std::begin(data1), std::end(data1), 5);
|
||||
CHECK_EQUAL(5, *p);
|
||||
|
||||
// Find the element of value 4.
|
||||
p = etl::binary_find(std::begin(data1), std::end(data1), 4);
|
||||
CHECK_EQUAL(std::end(data1), p);
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
TEST(binary_find_StructDataPredicate_StructDataEquality)
|
||||
{
|
||||
StructData data1[] = { { 1, 8 }, { 2, 7 }, { 3, 6 },{ 4, 5 },{ 5, 4 },{ 6, 3 },{ 7, 2 },{ 8, 1 } };
|
||||
StructData test1 = { 4, 5 };
|
||||
StructData test2 = { 9, 0 };
|
||||
|
||||
// Find the element of value 5.
|
||||
StructData* p = etl::binary_find(std::begin(data1), std::end(data1), test1, StructDataPredicate(), StructDataEquality());
|
||||
CHECK_EQUAL(test1, *p);
|
||||
|
||||
// Find the element of value 4.
|
||||
p = etl::binary_find(std::begin(data1), std::end(data1), test2, StructDataPredicate(), StructDataEquality());
|
||||
CHECK_EQUAL(std::end(data1), p);
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
TEST(for_each_if)
|
||||
{
|
||||
|
||||
503
test/test_fsm.cpp
Normal file
503
test/test_fsm.cpp
Normal file
@ -0,0 +1,503 @@
|
||||
/******************************************************************************
|
||||
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 "fsm.h"
|
||||
#include "enum_type.h"
|
||||
#include "container.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace
|
||||
{
|
||||
const etl::message_router_id_t MOTOR_CONTROL = 0;
|
||||
|
||||
|
||||
//***************************************************************************
|
||||
// Events
|
||||
struct EventId
|
||||
{
|
||||
enum enum_type
|
||||
{
|
||||
START,
|
||||
STOP,
|
||||
STOPPED,
|
||||
SET_SPEED,
|
||||
UNSUPPORTED
|
||||
};
|
||||
|
||||
ETL_DECLARE_ENUM_TYPE(EventId, etl::message_id_t)
|
||||
ETL_ENUM_TYPE(START, "Start")
|
||||
ETL_ENUM_TYPE(STOP, "Stop")
|
||||
ETL_ENUM_TYPE(STOPPED, "Stopped")
|
||||
ETL_ENUM_TYPE(SET_SPEED, "Set Speed")
|
||||
ETL_ENUM_TYPE(UNSUPPORTED, "Unsupported")
|
||||
ETL_END_ENUM_TYPE
|
||||
};
|
||||
|
||||
//***********************************
|
||||
class Start : public etl::message<EventId::START>
|
||||
{
|
||||
};
|
||||
|
||||
//***********************************
|
||||
class Stop : public etl::message<EventId::STOP>
|
||||
{
|
||||
public:
|
||||
|
||||
Stop() : isEmergencyStop(false) {}
|
||||
Stop(bool emergency) : isEmergencyStop(emergency) {}
|
||||
|
||||
const bool isEmergencyStop;
|
||||
};
|
||||
|
||||
//***********************************
|
||||
class SetSpeed : public etl::message<EventId::SET_SPEED>
|
||||
{
|
||||
public:
|
||||
|
||||
SetSpeed(int speed) : speed(speed) {}
|
||||
|
||||
const int speed;
|
||||
};
|
||||
|
||||
//***********************************
|
||||
class Stopped : public etl::message<EventId::STOPPED>
|
||||
{
|
||||
};
|
||||
|
||||
//***********************************
|
||||
class Unsupported : public etl::message<EventId::UNSUPPORTED>
|
||||
{
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
// States
|
||||
struct StateId
|
||||
{
|
||||
enum enum_type
|
||||
{
|
||||
IDLE,
|
||||
RUNNING,
|
||||
WINDING_DOWN,
|
||||
LOCKED,
|
||||
NUMBER_OF_STATES
|
||||
};
|
||||
|
||||
ETL_DECLARE_ENUM_TYPE(StateId, etl::fsm_state_id_t)
|
||||
ETL_ENUM_TYPE(IDLE, "Idle")
|
||||
ETL_ENUM_TYPE(RUNNING, "Running")
|
||||
ETL_ENUM_TYPE(WINDING_DOWN, "Winding Down")
|
||||
ETL_ENUM_TYPE(LOCKED, "Locked")
|
||||
ETL_END_ENUM_TYPE
|
||||
};
|
||||
|
||||
//***********************************
|
||||
// The motor control FSM.
|
||||
//***********************************
|
||||
class MotorControl : public etl::fsm
|
||||
{
|
||||
public:
|
||||
|
||||
MotorControl(etl::ifsm_state** p_states, size_t size)
|
||||
: fsm(MOTOR_CONTROL)
|
||||
{
|
||||
set_states(p_states, size);
|
||||
ClearStatistics();
|
||||
}
|
||||
|
||||
//***********************************
|
||||
void ClearStatistics()
|
||||
{
|
||||
startCount = 0;
|
||||
stopCount = 0;
|
||||
setSpeedCount = 0;
|
||||
unknownCount = 0;
|
||||
stoppedCount = 0;
|
||||
isLampOn = false;
|
||||
speed = 0;
|
||||
}
|
||||
|
||||
//***********************************
|
||||
void SetSpeed(int speed_)
|
||||
{
|
||||
speed = speed_;
|
||||
}
|
||||
|
||||
//***********************************
|
||||
void TurnRunningLampOn()
|
||||
{
|
||||
isLampOn = true;
|
||||
}
|
||||
|
||||
//***********************************
|
||||
void TurnRunningLampOff()
|
||||
{
|
||||
isLampOn = false;
|
||||
}
|
||||
|
||||
int startCount;
|
||||
int stopCount;
|
||||
int setSpeedCount;
|
||||
int unknownCount;
|
||||
int stoppedCount;
|
||||
bool isLampOn;
|
||||
int speed;
|
||||
};
|
||||
|
||||
//***********************************
|
||||
// The idle state.
|
||||
//***********************************
|
||||
class Idle : public etl::fsm_state<MotorControl, Idle, StateId::IDLE, Start>
|
||||
{
|
||||
public:
|
||||
|
||||
//***********************************
|
||||
etl::fsm_state_id_t on_event(etl::imessage_router& sender, const Start& event)
|
||||
{
|
||||
++get_fsm_context().startCount;
|
||||
return StateId::RUNNING;
|
||||
}
|
||||
|
||||
//***********************************
|
||||
etl::fsm_state_id_t on_event_unknown(etl::imessage_router& sender, const etl::imessage& event)
|
||||
{
|
||||
++get_fsm_context().unknownCount;
|
||||
return STATE_ID;
|
||||
}
|
||||
|
||||
//***********************************
|
||||
etl::fsm_state_id_t on_enter_state()
|
||||
{
|
||||
get_fsm_context().TurnRunningLampOff();
|
||||
return StateId::LOCKED;
|
||||
}
|
||||
};
|
||||
|
||||
//***********************************
|
||||
// The running state.
|
||||
//***********************************
|
||||
class Running : public etl::fsm_state<MotorControl, Running, StateId::RUNNING, Stop, SetSpeed>
|
||||
{
|
||||
public:
|
||||
|
||||
//***********************************
|
||||
etl::fsm_state_id_t on_event(etl::imessage_router& sender, const Stop& event)
|
||||
{
|
||||
++get_fsm_context().stopCount;
|
||||
|
||||
if (event.isEmergencyStop)
|
||||
{
|
||||
return StateId::IDLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return StateId::WINDING_DOWN;
|
||||
}
|
||||
}
|
||||
|
||||
//***********************************
|
||||
etl::fsm_state_id_t on_event(etl::imessage_router& sender, const SetSpeed& event)
|
||||
{
|
||||
++get_fsm_context().setSpeedCount;
|
||||
get_fsm_context().SetSpeed(event.speed);
|
||||
return STATE_ID;
|
||||
}
|
||||
|
||||
//***********************************
|
||||
etl::fsm_state_id_t on_event_unknown(etl::imessage_router& sender, const etl::imessage& event)
|
||||
{
|
||||
++get_fsm_context().unknownCount;
|
||||
return STATE_ID;
|
||||
}
|
||||
|
||||
//***********************************
|
||||
etl::fsm_state_id_t on_enter_state()
|
||||
{
|
||||
get_fsm_context().TurnRunningLampOn();
|
||||
|
||||
return STATE_ID;
|
||||
}
|
||||
};
|
||||
|
||||
//***********************************
|
||||
// The winding down state.
|
||||
//***********************************
|
||||
class WindingDown : public etl::fsm_state<MotorControl, WindingDown, StateId::WINDING_DOWN, Stopped>
|
||||
{
|
||||
public:
|
||||
|
||||
//***********************************
|
||||
etl::fsm_state_id_t on_event(etl::imessage_router& source, const Stopped& event)
|
||||
{
|
||||
++get_fsm_context().stoppedCount;
|
||||
return StateId::IDLE;
|
||||
}
|
||||
|
||||
//***********************************
|
||||
etl::fsm_state_id_t on_event_unknown(etl::imessage_router& source, const etl::imessage& event)
|
||||
{
|
||||
++get_fsm_context().unknownCount;
|
||||
return STATE_ID;
|
||||
}
|
||||
};
|
||||
|
||||
//***********************************
|
||||
// The locked state.
|
||||
//***********************************
|
||||
class Locked : public etl::fsm_state<MotorControl, Locked, StateId::LOCKED>
|
||||
{
|
||||
public:
|
||||
|
||||
//***********************************
|
||||
etl::fsm_state_id_t on_event_unknown(etl::imessage_router& source, const etl::imessage& event)
|
||||
{
|
||||
++get_fsm_context().unknownCount;
|
||||
return STATE_ID;
|
||||
}
|
||||
};
|
||||
|
||||
// The states.
|
||||
Idle idle;
|
||||
Running running;
|
||||
WindingDown windingDown;
|
||||
Locked locked;
|
||||
|
||||
etl::ifsm_state* stateList[StateId::NUMBER_OF_STATES] =
|
||||
{
|
||||
&idle, &running, &windingDown, &locked
|
||||
};
|
||||
|
||||
MotorControl motorControl(stateList, etl::size(stateList));
|
||||
|
||||
SUITE(test_map)
|
||||
{
|
||||
//*************************************************************************
|
||||
TEST(test_fsm)
|
||||
{
|
||||
etl::null_message_router nmr;
|
||||
|
||||
motorControl.reset();
|
||||
motorControl.ClearStatistics();
|
||||
|
||||
CHECK(!motorControl.is_started());
|
||||
|
||||
// Start the FSM.
|
||||
motorControl.start();
|
||||
CHECK(motorControl.is_started());
|
||||
|
||||
// Now in Idle state.
|
||||
|
||||
CHECK_EQUAL(StateId::IDLE, int(motorControl.get_state_id()));
|
||||
CHECK_EQUAL(StateId::IDLE, int(motorControl.get_state().get_state_id()));
|
||||
|
||||
CHECK_EQUAL(false, motorControl.isLampOn);
|
||||
CHECK_EQUAL(0, motorControl.setSpeedCount);
|
||||
CHECK_EQUAL(0, motorControl.speed);
|
||||
CHECK_EQUAL(0, motorControl.startCount);
|
||||
CHECK_EQUAL(0, motorControl.stopCount);
|
||||
CHECK_EQUAL(0, motorControl.stoppedCount);
|
||||
CHECK_EQUAL(0, motorControl.unknownCount);
|
||||
|
||||
// Send unhandled events.
|
||||
motorControl.receive(nmr, Stop());
|
||||
motorControl.receive(nmr, Stopped());
|
||||
motorControl.receive(nmr, SetSpeed(10));
|
||||
|
||||
CHECK_EQUAL(StateId::IDLE, motorControl.get_state_id());
|
||||
CHECK_EQUAL(StateId::IDLE, motorControl.get_state().get_state_id());
|
||||
|
||||
CHECK_EQUAL(false, motorControl.isLampOn);
|
||||
CHECK_EQUAL(0, motorControl.setSpeedCount);
|
||||
CHECK_EQUAL(0, motorControl.speed);
|
||||
CHECK_EQUAL(0, motorControl.startCount);
|
||||
CHECK_EQUAL(0, motorControl.stopCount);
|
||||
CHECK_EQUAL(0, motorControl.stoppedCount);
|
||||
CHECK_EQUAL(3, motorControl.unknownCount);
|
||||
|
||||
// Send Start event.
|
||||
motorControl.receive(nmr, Start());
|
||||
|
||||
// Now in Running state.
|
||||
|
||||
CHECK_EQUAL(StateId::RUNNING, int(motorControl.get_state_id()));
|
||||
CHECK_EQUAL(StateId::RUNNING, int(motorControl.get_state().get_state_id()));
|
||||
|
||||
CHECK_EQUAL(true, motorControl.isLampOn);
|
||||
CHECK_EQUAL(0, motorControl.setSpeedCount);
|
||||
CHECK_EQUAL(0, motorControl.speed);
|
||||
CHECK_EQUAL(1, motorControl.startCount);
|
||||
CHECK_EQUAL(0, motorControl.stopCount);
|
||||
CHECK_EQUAL(0, motorControl.stoppedCount);
|
||||
CHECK_EQUAL(3, motorControl.unknownCount);
|
||||
|
||||
// Send unhandled events.
|
||||
motorControl.receive(nmr, Start());
|
||||
motorControl.receive(nmr, Stopped());
|
||||
|
||||
CHECK_EQUAL(StateId::RUNNING, int(motorControl.get_state_id()));
|
||||
CHECK_EQUAL(StateId::RUNNING, int(motorControl.get_state().get_state_id()));
|
||||
|
||||
CHECK_EQUAL(true, motorControl.isLampOn);
|
||||
CHECK_EQUAL(0, motorControl.setSpeedCount);
|
||||
CHECK_EQUAL(0, motorControl.speed);
|
||||
CHECK_EQUAL(1, motorControl.startCount);
|
||||
CHECK_EQUAL(0, motorControl.stopCount);
|
||||
CHECK_EQUAL(0, motorControl.stoppedCount);
|
||||
CHECK_EQUAL(5, motorControl.unknownCount);
|
||||
|
||||
// Send SetSpeed event.
|
||||
motorControl.receive(nmr, SetSpeed(100));
|
||||
|
||||
// Still in Running state.
|
||||
|
||||
CHECK_EQUAL(StateId::RUNNING, int(motorControl.get_state_id()));
|
||||
CHECK_EQUAL(StateId::RUNNING, int(motorControl.get_state().get_state_id()));
|
||||
|
||||
CHECK_EQUAL(true, motorControl.isLampOn);
|
||||
CHECK_EQUAL(1, motorControl.setSpeedCount);
|
||||
CHECK_EQUAL(100, motorControl.speed);
|
||||
CHECK_EQUAL(1, motorControl.startCount);
|
||||
CHECK_EQUAL(0, motorControl.stopCount);
|
||||
CHECK_EQUAL(0, motorControl.stoppedCount);
|
||||
CHECK_EQUAL(5, motorControl.unknownCount);
|
||||
|
||||
// Send Stop event.
|
||||
motorControl.receive(nmr, Stop());
|
||||
|
||||
// Now in WindingDown state.
|
||||
|
||||
CHECK_EQUAL(StateId::WINDING_DOWN, int(motorControl.get_state_id()));
|
||||
CHECK_EQUAL(StateId::WINDING_DOWN, int(motorControl.get_state().get_state_id()));
|
||||
|
||||
CHECK_EQUAL(true, motorControl.isLampOn);
|
||||
CHECK_EQUAL(1, motorControl.setSpeedCount);
|
||||
CHECK_EQUAL(100, motorControl.speed);
|
||||
CHECK_EQUAL(1, motorControl.startCount);
|
||||
CHECK_EQUAL(1, motorControl.stopCount);
|
||||
CHECK_EQUAL(0, motorControl.stoppedCount);
|
||||
CHECK_EQUAL(5, motorControl.unknownCount);
|
||||
|
||||
// Send unhandled events.
|
||||
motorControl.receive(nmr, Start());
|
||||
motorControl.receive(nmr, Stop());
|
||||
motorControl.receive(nmr, SetSpeed(100));
|
||||
|
||||
CHECK_EQUAL(StateId::WINDING_DOWN, int(motorControl.get_state_id()));
|
||||
CHECK_EQUAL(StateId::WINDING_DOWN, int(motorControl.get_state().get_state_id()));
|
||||
|
||||
CHECK_EQUAL(true, motorControl.isLampOn);
|
||||
CHECK_EQUAL(1, motorControl.setSpeedCount);
|
||||
CHECK_EQUAL(100, motorControl.speed);
|
||||
CHECK_EQUAL(1, motorControl.startCount);
|
||||
CHECK_EQUAL(1, motorControl.stopCount);
|
||||
CHECK_EQUAL(0, motorControl.stoppedCount);
|
||||
CHECK_EQUAL(8, motorControl.unknownCount);
|
||||
|
||||
// Send Stopped event.
|
||||
motorControl.receive(nmr, Stopped());
|
||||
|
||||
// Now in Locked state via Idle state.
|
||||
CHECK_EQUAL(StateId::LOCKED, int(motorControl.get_state_id()));
|
||||
CHECK_EQUAL(StateId::LOCKED, int(motorControl.get_state().get_state_id()));
|
||||
|
||||
CHECK_EQUAL(false, motorControl.isLampOn);
|
||||
CHECK_EQUAL(1, motorControl.setSpeedCount);
|
||||
CHECK_EQUAL(100, motorControl.speed);
|
||||
CHECK_EQUAL(1, motorControl.startCount);
|
||||
CHECK_EQUAL(1, motorControl.stopCount);
|
||||
CHECK_EQUAL(1, motorControl.stoppedCount);
|
||||
CHECK_EQUAL(8, motorControl.unknownCount);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_fsm_emergency_stop)
|
||||
{
|
||||
etl::null_message_router nmr;
|
||||
|
||||
motorControl.reset();
|
||||
motorControl.ClearStatistics();
|
||||
|
||||
CHECK(!motorControl.is_started());
|
||||
|
||||
// Start the FSM.
|
||||
motorControl.start();
|
||||
CHECK(motorControl.is_started());
|
||||
|
||||
// Now in Idle state.
|
||||
|
||||
// Send Start event.
|
||||
motorControl.receive(nmr, Start());
|
||||
|
||||
// Now in Running state.
|
||||
|
||||
CHECK_EQUAL(StateId::RUNNING, int(motorControl.get_state_id()));
|
||||
CHECK_EQUAL(StateId::RUNNING, int(motorControl.get_state().get_state_id()));
|
||||
|
||||
CHECK_EQUAL(true, motorControl.isLampOn);
|
||||
CHECK_EQUAL(0, motorControl.setSpeedCount);
|
||||
CHECK_EQUAL(0, motorControl.speed);
|
||||
CHECK_EQUAL(1, motorControl.startCount);
|
||||
CHECK_EQUAL(0, motorControl.stopCount);
|
||||
CHECK_EQUAL(0, motorControl.stoppedCount);
|
||||
CHECK_EQUAL(0, motorControl.unknownCount);
|
||||
|
||||
// Send emergency Stop event.
|
||||
motorControl.receive(nmr, Stop(true));
|
||||
|
||||
// Now in Locked state via Idle state.
|
||||
CHECK_EQUAL(StateId::LOCKED, int(motorControl.get_state_id()));
|
||||
CHECK_EQUAL(StateId::LOCKED, int(motorControl.get_state().get_state_id()));
|
||||
|
||||
CHECK_EQUAL(false, motorControl.isLampOn);
|
||||
CHECK_EQUAL(0, motorControl.setSpeedCount);
|
||||
CHECK_EQUAL(0, motorControl.speed);
|
||||
CHECK_EQUAL(1, motorControl.startCount);
|
||||
CHECK_EQUAL(1, motorControl.stopCount);
|
||||
CHECK_EQUAL(0, motorControl.stoppedCount);
|
||||
CHECK_EQUAL(0, motorControl.unknownCount);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_fsm_supported)
|
||||
{
|
||||
CHECK(motorControl.accepts(EventId::SET_SPEED));
|
||||
CHECK(motorControl.accepts(EventId::START));
|
||||
CHECK(motorControl.accepts(EventId::STOP));
|
||||
CHECK(motorControl.accepts(EventId::STOPPED));
|
||||
CHECK(motorControl.accepts(EventId::UNSUPPORTED));
|
||||
|
||||
CHECK(motorControl.accepts(SetSpeed(0)));
|
||||
CHECK(motorControl.accepts(Start()));
|
||||
CHECK(motorControl.accepts(Stop()));
|
||||
CHECK(motorControl.accepts(Stopped()));
|
||||
CHECK(motorControl.accepts(Unsupported()));
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
729
test/test_message_bus.cpp
Normal file
729
test/test_message_bus.cpp
Normal file
@ -0,0 +1,729 @@
|
||||
/******************************************************************************
|
||||
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 "ExtraCheckMacros.h"
|
||||
|
||||
#include "message_router.h"
|
||||
#include "message_bus.h"
|
||||
#include "queue.h"
|
||||
#include "largest.h"
|
||||
#include "packet.h"
|
||||
|
||||
//***************************************************************************
|
||||
// The set of messages.
|
||||
//***************************************************************************
|
||||
namespace
|
||||
{
|
||||
enum
|
||||
{
|
||||
MESSAGE1,
|
||||
MESSAGE2,
|
||||
MESSAGE3,
|
||||
MESSAGE4,
|
||||
MESSAGE5
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
ROUTER1 = 1,
|
||||
ROUTER2 = 2,
|
||||
ROUTER3 = 3,
|
||||
ROUTER4 = 4,
|
||||
ROUTER5 = 5
|
||||
};
|
||||
|
||||
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;
|
||||
Message2 message2;
|
||||
Message3 message3;
|
||||
Message4 message4;
|
||||
Message5 message5;
|
||||
|
||||
int call_order;
|
||||
|
||||
//***************************************************************************
|
||||
// Router that handles messages 1, 2, 3, 4, 5.
|
||||
//***************************************************************************
|
||||
class RouterA : public etl::message_router<RouterA, Message1, Message2, Message3, Message4, Message5>
|
||||
{
|
||||
public:
|
||||
|
||||
RouterA(etl::message_router_id_t id)
|
||||
: message_router(id),
|
||||
message1_count(0),
|
||||
message2_count(0),
|
||||
message3_count(0),
|
||||
message4_count(0),
|
||||
message5_count(0),
|
||||
message_unknown_count(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void on_receive(etl::imessage_router& sender, const Message1& msg)
|
||||
{
|
||||
++message1_count;
|
||||
etl::send_message(sender, message5);
|
||||
|
||||
order = call_order++;
|
||||
}
|
||||
|
||||
void on_receive(etl::imessage_router& sender, const Message2& msg)
|
||||
{
|
||||
++message2_count;
|
||||
etl::send_message(sender, message5);
|
||||
}
|
||||
|
||||
void on_receive(etl::imessage_router& sender, const Message3& msg)
|
||||
{
|
||||
++message3_count;
|
||||
etl::send_message(sender, message5);
|
||||
}
|
||||
|
||||
void on_receive(etl::imessage_router& sender, const Message4& msg)
|
||||
{
|
||||
++message4_count;
|
||||
etl::send_message(sender, message5);
|
||||
}
|
||||
|
||||
void on_receive(etl::imessage_router& sender, const Message5& msg)
|
||||
{
|
||||
++message5_count;
|
||||
}
|
||||
|
||||
void on_receive_unknown(etl::imessage_router& sender, const etl::imessage& msg)
|
||||
{
|
||||
++message_unknown_count;
|
||||
}
|
||||
|
||||
int message1_count;
|
||||
int message2_count;
|
||||
int message3_count;
|
||||
int message4_count;
|
||||
int message5_count;
|
||||
int message_unknown_count;
|
||||
int order;
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
// Router that handles messages 1, 2, 4 and 5 and returns nothing.
|
||||
//***************************************************************************
|
||||
class RouterB : public etl::message_router<RouterB, Message1, Message2, Message4, Message5>
|
||||
{
|
||||
public:
|
||||
|
||||
RouterB(etl::message_router_id_t id)
|
||||
: message_router(id),
|
||||
message1_count(0),
|
||||
message2_count(0),
|
||||
message4_count(0),
|
||||
message5_count(0),
|
||||
message_unknown_count(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void on_receive(etl::imessage_router& sender, const Message1& msg)
|
||||
{
|
||||
++message1_count;
|
||||
etl::send_message(sender, message5);
|
||||
}
|
||||
|
||||
void on_receive(etl::imessage_router& sender, const Message2& msg)
|
||||
{
|
||||
++message2_count;
|
||||
etl::send_message(sender, message5);
|
||||
}
|
||||
|
||||
void on_receive(etl::imessage_router& sender, const Message4& msg)
|
||||
{
|
||||
++message4_count;
|
||||
etl::send_message(sender, message5);
|
||||
}
|
||||
|
||||
void on_receive(etl::imessage_router& sender, const Message5& msg)
|
||||
{
|
||||
++message5_count;
|
||||
}
|
||||
|
||||
void on_receive_unknown(etl::imessage_router& sender, const etl::imessage& msg)
|
||||
{
|
||||
++message_unknown_count;
|
||||
etl::send_message(sender, message5);
|
||||
}
|
||||
|
||||
int message1_count;
|
||||
int message2_count;
|
||||
int message4_count;
|
||||
int message5_count;
|
||||
int message_unknown_count;
|
||||
};
|
||||
|
||||
etl::imessage_router* p_router;
|
||||
etl::imessage_bus* p_bus;
|
||||
|
||||
SUITE(test_message_router)
|
||||
{
|
||||
//=========================================================================
|
||||
TEST(message_bus_subscribe_unsubscribe)
|
||||
{
|
||||
etl::message_bus<2> bus1;
|
||||
|
||||
RouterA router1(0);
|
||||
RouterB router2(1);
|
||||
RouterA router3(2);
|
||||
|
||||
CHECK_EQUAL(0U, bus1.size());
|
||||
|
||||
CHECK_NO_THROW(bus1.subscribe(router1));
|
||||
CHECK_EQUAL(1U, bus1.size());
|
||||
|
||||
CHECK_NO_THROW(bus1.subscribe(router2));
|
||||
CHECK_EQUAL(2U, bus1.size());
|
||||
|
||||
CHECK_THROW(bus1.subscribe(router3), etl::message_bus_too_many_subscribers);
|
||||
CHECK_EQUAL(2U, bus1.size());
|
||||
|
||||
bus1.unsubscribe(router1);
|
||||
CHECK_EQUAL(1U, bus1.size());
|
||||
|
||||
// Erase router not in list.
|
||||
bus1.unsubscribe(router3);
|
||||
CHECK_EQUAL(1U, bus1.size());
|
||||
|
||||
// Erase using id.
|
||||
bus1.unsubscribe(router2.get_message_router_id());
|
||||
CHECK_EQUAL(0U, bus1.size());
|
||||
|
||||
// Erase router from empty list.
|
||||
bus1.unsubscribe(router2);
|
||||
CHECK_EQUAL(0U, bus1.size());
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
TEST(message_bus_subscribe_unsubscribe_sub_bus)
|
||||
{
|
||||
etl::message_bus<4> bus1;
|
||||
etl::message_bus<2> bus2;
|
||||
etl::message_bus<3> bus3;
|
||||
|
||||
RouterA router1(ROUTER1);
|
||||
RouterA router2(ROUTER2);
|
||||
RouterA router3(ROUTER3);
|
||||
RouterA router4(ROUTER4);
|
||||
|
||||
bus1.subscribe(router1);
|
||||
bus1.subscribe(router2);
|
||||
bus1.subscribe(bus2);
|
||||
bus1.subscribe(bus3);
|
||||
|
||||
bus2.subscribe(router3);
|
||||
bus3.subscribe(router4);
|
||||
|
||||
CHECK_EQUAL(4U, bus1.size());
|
||||
|
||||
bus1.unsubscribe(etl::imessage_bus::MESSAGE_BUS);
|
||||
CHECK_EQUAL(2U, bus1.size());
|
||||
|
||||
bus1.unsubscribe(etl::imessage_bus::ALL_MESSAGE_ROUTERS);
|
||||
CHECK_EQUAL(0U, bus1.size());
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
TEST(message_bus_broadcast)
|
||||
{
|
||||
etl::message_bus<2> bus1;
|
||||
|
||||
RouterA router1(ROUTER1);
|
||||
RouterB router2(ROUTER2);
|
||||
RouterA sender(ROUTER3);
|
||||
|
||||
bus1.subscribe(router1);
|
||||
bus1.subscribe(router2);
|
||||
|
||||
bus1.receive(sender, message1);
|
||||
|
||||
CHECK_EQUAL(1, router1.message1_count);
|
||||
CHECK_EQUAL(0, router1.message2_count);
|
||||
CHECK_EQUAL(0, router1.message3_count);
|
||||
CHECK_EQUAL(0, router1.message4_count);
|
||||
CHECK_EQUAL(0, router1.message5_count);
|
||||
CHECK_EQUAL(0, router1.message_unknown_count);
|
||||
|
||||
CHECK_EQUAL(1, router2.message1_count);
|
||||
CHECK_EQUAL(0, router2.message2_count);
|
||||
CHECK_EQUAL(0, router2.message4_count);
|
||||
CHECK_EQUAL(0, router2.message5_count);
|
||||
CHECK_EQUAL(0, router2.message_unknown_count);
|
||||
|
||||
CHECK_EQUAL(2, sender.message5_count);
|
||||
|
||||
bus1.receive(sender, message2);
|
||||
|
||||
CHECK_EQUAL(1, router1.message1_count);
|
||||
CHECK_EQUAL(1, router1.message2_count);
|
||||
CHECK_EQUAL(0, router1.message3_count);
|
||||
CHECK_EQUAL(0, router1.message4_count);
|
||||
CHECK_EQUAL(0, router1.message5_count);
|
||||
CHECK_EQUAL(0, router1.message_unknown_count);
|
||||
|
||||
CHECK_EQUAL(1, router2.message1_count);
|
||||
CHECK_EQUAL(1, router2.message2_count);
|
||||
CHECK_EQUAL(0, router2.message4_count);
|
||||
CHECK_EQUAL(0, router2.message5_count);
|
||||
CHECK_EQUAL(0, router2.message_unknown_count);
|
||||
|
||||
CHECK_EQUAL(4, sender.message5_count);
|
||||
|
||||
bus1.receive(sender, message3);
|
||||
|
||||
CHECK_EQUAL(1, router1.message1_count);
|
||||
CHECK_EQUAL(1, router1.message2_count);
|
||||
CHECK_EQUAL(1, router1.message3_count);
|
||||
CHECK_EQUAL(0, router1.message4_count);
|
||||
CHECK_EQUAL(0, router1.message5_count);
|
||||
CHECK_EQUAL(0, router1.message_unknown_count);
|
||||
|
||||
CHECK_EQUAL(1, router2.message1_count);
|
||||
CHECK_EQUAL(1, router2.message2_count);
|
||||
CHECK_EQUAL(0, router2.message4_count);
|
||||
CHECK_EQUAL(0, router2.message5_count);
|
||||
CHECK_EQUAL(0, router2.message_unknown_count);
|
||||
|
||||
CHECK_EQUAL(5, sender.message5_count);
|
||||
|
||||
// Use global function.
|
||||
etl::send_message(sender, bus1, message4);
|
||||
|
||||
CHECK_EQUAL(1, router1.message1_count);
|
||||
CHECK_EQUAL(1, router1.message2_count);
|
||||
CHECK_EQUAL(1, router1.message3_count);
|
||||
CHECK_EQUAL(1, router1.message4_count);
|
||||
CHECK_EQUAL(0, router1.message5_count);
|
||||
CHECK_EQUAL(0, router1.message_unknown_count);
|
||||
|
||||
CHECK_EQUAL(1, router2.message1_count);
|
||||
CHECK_EQUAL(1, router2.message2_count);
|
||||
CHECK_EQUAL(1, router2.message4_count);
|
||||
CHECK_EQUAL(0, router2.message5_count);
|
||||
CHECK_EQUAL(0, router2.message_unknown_count);
|
||||
|
||||
CHECK_EQUAL(7, sender.message5_count);
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
TEST(message_bus_broadcast_as_router)
|
||||
{
|
||||
etl::message_bus<2> bus1;
|
||||
|
||||
RouterA router1(ROUTER1);
|
||||
RouterB router2(ROUTER2);
|
||||
RouterA sender(ROUTER3);
|
||||
|
||||
bus1.subscribe(router1);
|
||||
bus1.subscribe(router2);
|
||||
|
||||
// Reference to router sub-type
|
||||
etl::imessage_router& irouter = bus1;
|
||||
|
||||
irouter.receive(sender, message1);
|
||||
|
||||
CHECK_EQUAL(1, router1.message1_count);
|
||||
CHECK_EQUAL(0, router1.message2_count);
|
||||
CHECK_EQUAL(0, router1.message3_count);
|
||||
CHECK_EQUAL(0, router1.message4_count);
|
||||
CHECK_EQUAL(0, router1.message5_count);
|
||||
CHECK_EQUAL(0, router1.message_unknown_count);
|
||||
|
||||
CHECK_EQUAL(1, router2.message1_count);
|
||||
CHECK_EQUAL(0, router2.message2_count);
|
||||
CHECK_EQUAL(0, router2.message4_count);
|
||||
CHECK_EQUAL(0, router2.message5_count);
|
||||
CHECK_EQUAL(0, router2.message_unknown_count);
|
||||
|
||||
CHECK_EQUAL(2, sender.message5_count);
|
||||
|
||||
irouter.receive(sender, message2);
|
||||
|
||||
CHECK_EQUAL(1, router1.message1_count);
|
||||
CHECK_EQUAL(1, router1.message2_count);
|
||||
CHECK_EQUAL(0, router1.message3_count);
|
||||
CHECK_EQUAL(0, router1.message4_count);
|
||||
CHECK_EQUAL(0, router1.message5_count);
|
||||
CHECK_EQUAL(0, router1.message_unknown_count);
|
||||
|
||||
CHECK_EQUAL(1, router2.message1_count);
|
||||
CHECK_EQUAL(1, router2.message2_count);
|
||||
CHECK_EQUAL(0, router2.message4_count);
|
||||
CHECK_EQUAL(0, router2.message5_count);
|
||||
CHECK_EQUAL(0, router2.message_unknown_count);
|
||||
|
||||
CHECK_EQUAL(4, sender.message5_count);
|
||||
|
||||
irouter.receive(sender, message3);
|
||||
|
||||
CHECK_EQUAL(1, router1.message1_count);
|
||||
CHECK_EQUAL(1, router1.message2_count);
|
||||
CHECK_EQUAL(1, router1.message3_count);
|
||||
CHECK_EQUAL(0, router1.message4_count);
|
||||
CHECK_EQUAL(0, router1.message5_count);
|
||||
CHECK_EQUAL(0, router1.message_unknown_count);
|
||||
|
||||
CHECK_EQUAL(1, router2.message1_count);
|
||||
CHECK_EQUAL(1, router2.message2_count);
|
||||
CHECK_EQUAL(0, router2.message4_count);
|
||||
CHECK_EQUAL(0, router2.message5_count);
|
||||
CHECK_EQUAL(0, router2.message_unknown_count);
|
||||
|
||||
CHECK_EQUAL(5, sender.message5_count);
|
||||
|
||||
// Use global function.
|
||||
etl::send_message(sender, irouter, message4);
|
||||
|
||||
CHECK_EQUAL(1, router1.message1_count);
|
||||
CHECK_EQUAL(1, router1.message2_count);
|
||||
CHECK_EQUAL(1, router1.message3_count);
|
||||
CHECK_EQUAL(1, router1.message4_count);
|
||||
CHECK_EQUAL(0, router1.message5_count);
|
||||
CHECK_EQUAL(0, router1.message_unknown_count);
|
||||
|
||||
CHECK_EQUAL(1, router2.message1_count);
|
||||
CHECK_EQUAL(1, router2.message2_count);
|
||||
CHECK_EQUAL(1, router2.message4_count);
|
||||
CHECK_EQUAL(0, router2.message5_count);
|
||||
CHECK_EQUAL(0, router2.message_unknown_count);
|
||||
|
||||
CHECK_EQUAL(7, sender.message5_count);
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
TEST(message_bus_addressed)
|
||||
{
|
||||
etl::message_bus<2> bus1;
|
||||
|
||||
RouterA router1(ROUTER1);
|
||||
RouterB router2(ROUTER2);
|
||||
RouterA sender(ROUTER3);
|
||||
|
||||
bus1.subscribe(router1);
|
||||
bus1.subscribe(router2);
|
||||
|
||||
bus1.receive(sender, ROUTER1, message1);
|
||||
|
||||
CHECK_EQUAL(1, router1.message1_count);
|
||||
CHECK_EQUAL(0, router1.message2_count);
|
||||
CHECK_EQUAL(0, router1.message3_count);
|
||||
CHECK_EQUAL(0, router1.message4_count);
|
||||
CHECK_EQUAL(0, router1.message5_count);
|
||||
CHECK_EQUAL(0, router1.message_unknown_count);
|
||||
|
||||
CHECK_EQUAL(0, router2.message1_count);
|
||||
CHECK_EQUAL(0, router2.message2_count);
|
||||
CHECK_EQUAL(0, router2.message4_count);
|
||||
CHECK_EQUAL(0, router2.message5_count);
|
||||
CHECK_EQUAL(0, router2.message_unknown_count);
|
||||
|
||||
CHECK_EQUAL(1, sender.message5_count);
|
||||
|
||||
bus1.receive(sender, ROUTER2, message2);
|
||||
|
||||
CHECK_EQUAL(1, router1.message1_count);
|
||||
CHECK_EQUAL(0, router1.message2_count);
|
||||
CHECK_EQUAL(0, router1.message3_count);
|
||||
CHECK_EQUAL(0, router1.message4_count);
|
||||
CHECK_EQUAL(0, router1.message5_count);
|
||||
CHECK_EQUAL(0, router1.message_unknown_count);
|
||||
|
||||
CHECK_EQUAL(0, router2.message1_count);
|
||||
CHECK_EQUAL(1, router2.message2_count);
|
||||
CHECK_EQUAL(0, router2.message4_count);
|
||||
CHECK_EQUAL(0, router2.message5_count);
|
||||
CHECK_EQUAL(0, router2.message_unknown_count);
|
||||
|
||||
CHECK_EQUAL(2, sender.message5_count);
|
||||
|
||||
bus1.receive(sender, ROUTER1, message3);
|
||||
|
||||
CHECK_EQUAL(1, router1.message1_count);
|
||||
CHECK_EQUAL(0, router1.message2_count);
|
||||
CHECK_EQUAL(1, router1.message3_count);
|
||||
CHECK_EQUAL(0, router1.message4_count);
|
||||
CHECK_EQUAL(0, router1.message5_count);
|
||||
CHECK_EQUAL(0, router1.message_unknown_count);
|
||||
|
||||
CHECK_EQUAL(0, router2.message1_count);
|
||||
CHECK_EQUAL(1, router2.message2_count);
|
||||
CHECK_EQUAL(0, router2.message4_count);
|
||||
CHECK_EQUAL(0, router2.message5_count);
|
||||
CHECK_EQUAL(0, router2.message_unknown_count);
|
||||
|
||||
CHECK_EQUAL(3, sender.message5_count);
|
||||
|
||||
// Use global function.
|
||||
etl::send_message(sender, bus1, ROUTER2, message4);
|
||||
|
||||
CHECK_EQUAL(1, router1.message1_count);
|
||||
CHECK_EQUAL(0, router1.message2_count);
|
||||
CHECK_EQUAL(1, router1.message3_count);
|
||||
CHECK_EQUAL(0, router1.message4_count);
|
||||
CHECK_EQUAL(0, router1.message5_count);
|
||||
CHECK_EQUAL(0, router1.message_unknown_count);
|
||||
|
||||
CHECK_EQUAL(0, router2.message1_count);
|
||||
CHECK_EQUAL(1, router2.message2_count);
|
||||
CHECK_EQUAL(1, router2.message4_count);
|
||||
CHECK_EQUAL(0, router2.message5_count);
|
||||
CHECK_EQUAL(0, router2.message_unknown_count);
|
||||
|
||||
CHECK_EQUAL(4, sender.message5_count);
|
||||
|
||||
// Send to a router not subscribed to the bus.
|
||||
bus1.receive(sender, ROUTER5, message1);
|
||||
|
||||
CHECK_EQUAL(1, router1.message1_count);
|
||||
CHECK_EQUAL(0, router1.message2_count);
|
||||
CHECK_EQUAL(1, router1.message3_count);
|
||||
CHECK_EQUAL(0, router1.message4_count);
|
||||
CHECK_EQUAL(0, router1.message5_count);
|
||||
CHECK_EQUAL(0, router1.message_unknown_count);
|
||||
|
||||
CHECK_EQUAL(0, router2.message1_count);
|
||||
CHECK_EQUAL(1, router2.message2_count);
|
||||
CHECK_EQUAL(1, router2.message4_count);
|
||||
CHECK_EQUAL(0, router2.message5_count);
|
||||
CHECK_EQUAL(0, router2.message_unknown_count);
|
||||
|
||||
CHECK_EQUAL(4, sender.message5_count);
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
TEST(message_bus_addressed_duplicate_router_id)
|
||||
{
|
||||
etl::message_bus<3> bus1;
|
||||
|
||||
RouterA router1(ROUTER1);
|
||||
RouterB router2(ROUTER1);
|
||||
RouterB router3(ROUTER2);
|
||||
RouterA sender(ROUTER3);
|
||||
|
||||
bus1.subscribe(router1);
|
||||
bus1.subscribe(router2);
|
||||
bus1.subscribe(router3);
|
||||
|
||||
bus1.receive(sender, ROUTER1, message1);
|
||||
|
||||
CHECK_EQUAL(1, router1.message1_count);
|
||||
CHECK_EQUAL(0, router1.message2_count);
|
||||
CHECK_EQUAL(0, router1.message3_count);
|
||||
CHECK_EQUAL(0, router1.message4_count);
|
||||
CHECK_EQUAL(0, router1.message5_count);
|
||||
CHECK_EQUAL(0, router1.message_unknown_count);
|
||||
|
||||
CHECK_EQUAL(1, router2.message1_count);
|
||||
CHECK_EQUAL(0, router2.message2_count);
|
||||
CHECK_EQUAL(0, router2.message4_count);
|
||||
CHECK_EQUAL(0, router2.message5_count);
|
||||
CHECK_EQUAL(0, router2.message_unknown_count);
|
||||
|
||||
CHECK_EQUAL(0, router3.message1_count);
|
||||
CHECK_EQUAL(0, router3.message2_count);
|
||||
CHECK_EQUAL(0, router3.message4_count);
|
||||
CHECK_EQUAL(0, router3.message5_count);
|
||||
CHECK_EQUAL(0, router3.message_unknown_count);
|
||||
|
||||
CHECK_EQUAL(2, sender.message5_count);
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
TEST(message_bus_broadcast_addressed_sub_bus)
|
||||
{
|
||||
etl::message_bus<3> bus1;
|
||||
etl::message_bus<2> bus2;
|
||||
|
||||
RouterA router1(ROUTER1);
|
||||
RouterA router2(ROUTER2);
|
||||
RouterA router3(ROUTER3);
|
||||
RouterA router4(ROUTER4);
|
||||
|
||||
RouterA sender(ROUTER5);
|
||||
|
||||
bus1.subscribe(router1);
|
||||
bus1.subscribe(router2);
|
||||
bus1.subscribe(bus2);
|
||||
|
||||
bus2.subscribe(router3);
|
||||
bus2.subscribe(router4);
|
||||
|
||||
// Broadcast to bus1
|
||||
bus1.receive(sender, message1);
|
||||
|
||||
CHECK_EQUAL(1, router1.message1_count);
|
||||
CHECK_EQUAL(0, router1.message2_count);
|
||||
CHECK_EQUAL(0, router1.message3_count);
|
||||
CHECK_EQUAL(0, router1.message4_count);
|
||||
CHECK_EQUAL(0, router1.message5_count);
|
||||
CHECK_EQUAL(0, router1.message_unknown_count);
|
||||
|
||||
CHECK_EQUAL(1, router2.message1_count);
|
||||
CHECK_EQUAL(0, router2.message2_count);
|
||||
CHECK_EQUAL(0, router2.message4_count);
|
||||
CHECK_EQUAL(0, router2.message5_count);
|
||||
CHECK_EQUAL(0, router2.message_unknown_count);
|
||||
|
||||
CHECK_EQUAL(1, router3.message1_count);
|
||||
CHECK_EQUAL(0, router3.message2_count);
|
||||
CHECK_EQUAL(0, router3.message4_count);
|
||||
CHECK_EQUAL(0, router3.message5_count);
|
||||
CHECK_EQUAL(0, router3.message_unknown_count);
|
||||
|
||||
CHECK_EQUAL(1, router4.message1_count);
|
||||
CHECK_EQUAL(0, router4.message2_count);
|
||||
CHECK_EQUAL(0, router4.message4_count);
|
||||
CHECK_EQUAL(0, router4.message5_count);
|
||||
CHECK_EQUAL(0, router4.message_unknown_count);
|
||||
|
||||
CHECK_EQUAL(4, sender.message5_count);
|
||||
|
||||
// Addressed to ROUTER2
|
||||
bus1.receive(sender, ROUTER2, message1);
|
||||
|
||||
CHECK_EQUAL(1, router1.message1_count);
|
||||
CHECK_EQUAL(0, router1.message2_count);
|
||||
CHECK_EQUAL(0, router1.message3_count);
|
||||
CHECK_EQUAL(0, router1.message4_count);
|
||||
CHECK_EQUAL(0, router1.message5_count);
|
||||
CHECK_EQUAL(0, router1.message_unknown_count);
|
||||
|
||||
CHECK_EQUAL(2, router2.message1_count);
|
||||
CHECK_EQUAL(0, router2.message2_count);
|
||||
CHECK_EQUAL(0, router2.message4_count);
|
||||
CHECK_EQUAL(0, router2.message5_count);
|
||||
CHECK_EQUAL(0, router2.message_unknown_count);
|
||||
|
||||
CHECK_EQUAL(1, router3.message1_count);
|
||||
CHECK_EQUAL(0, router3.message2_count);
|
||||
CHECK_EQUAL(0, router3.message4_count);
|
||||
CHECK_EQUAL(0, router3.message5_count);
|
||||
CHECK_EQUAL(0, router3.message_unknown_count);
|
||||
|
||||
CHECK_EQUAL(1, router4.message1_count);
|
||||
CHECK_EQUAL(0, router4.message2_count);
|
||||
CHECK_EQUAL(0, router4.message4_count);
|
||||
CHECK_EQUAL(0, router4.message5_count);
|
||||
CHECK_EQUAL(0, router4.message_unknown_count);
|
||||
|
||||
CHECK_EQUAL(5, sender.message5_count);
|
||||
|
||||
// Addressed to ROUTER3 via bus2
|
||||
bus1.receive(sender, ROUTER3, message1);
|
||||
|
||||
CHECK_EQUAL(1, router1.message1_count);
|
||||
CHECK_EQUAL(0, router1.message2_count);
|
||||
CHECK_EQUAL(0, router1.message3_count);
|
||||
CHECK_EQUAL(0, router1.message4_count);
|
||||
CHECK_EQUAL(0, router1.message5_count);
|
||||
CHECK_EQUAL(0, router1.message_unknown_count);
|
||||
|
||||
CHECK_EQUAL(2, router2.message1_count);
|
||||
CHECK_EQUAL(0, router2.message2_count);
|
||||
CHECK_EQUAL(0, router2.message4_count);
|
||||
CHECK_EQUAL(0, router2.message5_count);
|
||||
CHECK_EQUAL(0, router2.message_unknown_count);
|
||||
|
||||
CHECK_EQUAL(2, router3.message1_count);
|
||||
CHECK_EQUAL(0, router3.message2_count);
|
||||
CHECK_EQUAL(0, router3.message4_count);
|
||||
CHECK_EQUAL(0, router3.message5_count);
|
||||
CHECK_EQUAL(0, router3.message_unknown_count);
|
||||
|
||||
CHECK_EQUAL(1, router4.message1_count);
|
||||
CHECK_EQUAL(0, router4.message2_count);
|
||||
CHECK_EQUAL(0, router4.message4_count);
|
||||
CHECK_EQUAL(0, router4.message5_count);
|
||||
CHECK_EQUAL(0, router4.message_unknown_count);
|
||||
|
||||
CHECK_EQUAL(6, sender.message5_count);
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
TEST(message_bus_broadcast_order)
|
||||
{
|
||||
etl::message_bus<4> bus1;
|
||||
etl::message_bus<2> bus2;
|
||||
etl::message_bus<2> bus3;
|
||||
|
||||
RouterA router1(ROUTER1);
|
||||
RouterA router2(ROUTER2);
|
||||
RouterA router3(ROUTER3);
|
||||
RouterA router4a(ROUTER4);
|
||||
RouterA router4b(ROUTER4);
|
||||
|
||||
RouterA sender(ROUTER5);
|
||||
|
||||
bus1.subscribe(router1);
|
||||
bus1.subscribe(bus3);
|
||||
bus1.subscribe(bus2);
|
||||
bus1.subscribe(router2);
|
||||
|
||||
bus2.subscribe(router3);
|
||||
bus3.subscribe(router4b);
|
||||
bus3.subscribe(router4a);
|
||||
|
||||
call_order = 0;
|
||||
|
||||
bus1.receive(sender, message1);
|
||||
|
||||
CHECK_EQUAL(0, router1.order);
|
||||
CHECK_EQUAL(1, router2.order);
|
||||
CHECK_EQUAL(2, router4b.order);
|
||||
CHECK_EQUAL(3, router4a.order);
|
||||
CHECK_EQUAL(4, router3.order);
|
||||
}
|
||||
};
|
||||
}
|
||||
421
test/test_message_router.cpp
Normal file
421
test/test_message_router.cpp
Normal file
@ -0,0 +1,421 @@
|
||||
/******************************************************************************
|
||||
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 "ExtraCheckMacros.h"
|
||||
|
||||
#include "message_router.h"
|
||||
#include "queue.h"
|
||||
#include "largest.h"
|
||||
#include "packet.h"
|
||||
|
||||
//***************************************************************************
|
||||
// The set of messages.
|
||||
//***************************************************************************
|
||||
namespace
|
||||
{
|
||||
enum
|
||||
{
|
||||
MESSAGE1,
|
||||
MESSAGE2,
|
||||
MESSAGE3,
|
||||
MESSAGE4,
|
||||
MESSAGE5
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
ROUTER1,
|
||||
ROUTER2
|
||||
};
|
||||
|
||||
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;
|
||||
Message2 message2;
|
||||
Message3 message3;
|
||||
Message4 message4;
|
||||
Message5 message5;
|
||||
|
||||
//***************************************************************************
|
||||
// Router that handles messages 1, 2, 3, 4 and 5 and returns nothing.
|
||||
//***************************************************************************
|
||||
class Router1 : public etl::message_router<Router1, Message1, Message2, Message3, Message4, Message5>
|
||||
{
|
||||
public:
|
||||
|
||||
Router1()
|
||||
: message_router(ROUTER1),
|
||||
message1_count(0),
|
||||
message2_count(0),
|
||||
message3_count(0),
|
||||
message4_count(0),
|
||||
message_unknown_count(0),
|
||||
callback_count(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void on_receive(etl::imessage_router& sender, const Message1& msg)
|
||||
{
|
||||
++message1_count;
|
||||
etl::send_message(sender, message5);
|
||||
}
|
||||
|
||||
void on_receive(etl::imessage_router& sender, const Message2& msg)
|
||||
{
|
||||
++message2_count;
|
||||
etl::send_message(sender, message5);
|
||||
}
|
||||
|
||||
void on_receive(etl::imessage_router& sender, const Message3& msg)
|
||||
{
|
||||
++message3_count;
|
||||
etl::send_message(sender, message5);
|
||||
}
|
||||
|
||||
void on_receive(etl::imessage_router& sender, const Message4& msg)
|
||||
{
|
||||
++message4_count;
|
||||
etl::send_message(sender, message5);
|
||||
}
|
||||
|
||||
void on_receive(etl::imessage_router& sender, const Message5& msg)
|
||||
{
|
||||
++callback_count;
|
||||
}
|
||||
|
||||
void on_receive_unknown(etl::imessage_router& sender, const etl::imessage& msg)
|
||||
{
|
||||
++message_unknown_count;
|
||||
}
|
||||
|
||||
int message1_count;
|
||||
int message2_count;
|
||||
int message3_count;
|
||||
int message4_count;
|
||||
int message_unknown_count;
|
||||
int callback_count;
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
// Router that handles messages 1, 2, 4 and 5 and returns nothing.
|
||||
//***************************************************************************
|
||||
class Router2 : public etl::message_router<Router2, Message1, Message2, Message4, Message5>
|
||||
{
|
||||
public:
|
||||
|
||||
Router2()
|
||||
: message_router(ROUTER2),
|
||||
message1_count(0),
|
||||
message2_count(0),
|
||||
message4_count(0),
|
||||
message_unknown_count(0),
|
||||
callback_count(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void on_receive(etl::imessage_router& sender, const Message1& msg)
|
||||
{
|
||||
++message1_count;
|
||||
etl::send_message(sender, message5);
|
||||
}
|
||||
|
||||
void on_receive(etl::imessage_router& sender, const Message2& msg)
|
||||
{
|
||||
++message2_count;
|
||||
etl::send_message(sender, message5);
|
||||
}
|
||||
|
||||
void on_receive(etl::imessage_router& sender, const Message4& msg)
|
||||
{
|
||||
++message4_count;
|
||||
etl::send_message(sender, message5);
|
||||
}
|
||||
|
||||
void on_receive(etl::imessage_router& sender, const Message5& msg)
|
||||
{
|
||||
++callback_count;
|
||||
}
|
||||
|
||||
void on_receive_unknown(etl::imessage_router& sender, const etl::imessage& msg)
|
||||
{
|
||||
++message_unknown_count;
|
||||
etl::send_message(sender, message5);
|
||||
}
|
||||
|
||||
int message1_count;
|
||||
int message2_count;
|
||||
int message4_count;
|
||||
int message_unknown_count;
|
||||
int callback_count;
|
||||
};
|
||||
|
||||
|
||||
etl::imessage_router* p_router;
|
||||
|
||||
SUITE(test_message_router)
|
||||
{
|
||||
//=========================================================================
|
||||
TEST(message_router)
|
||||
{
|
||||
Router1 r1;
|
||||
Router2 r2;
|
||||
|
||||
p_router = &r1;
|
||||
|
||||
p_router->receive(r2, message1);
|
||||
CHECK_EQUAL(1, r1.message1_count);
|
||||
CHECK_EQUAL(0, r1.message2_count);
|
||||
CHECK_EQUAL(0, r1.message3_count);
|
||||
CHECK_EQUAL(0, r1.message4_count);
|
||||
CHECK_EQUAL(0, r1.message_unknown_count);
|
||||
CHECK_EQUAL(1, r2.callback_count);
|
||||
|
||||
p_router->receive(r2, message2);
|
||||
CHECK_EQUAL(1, r1.message1_count);
|
||||
CHECK_EQUAL(1, r1.message2_count);
|
||||
CHECK_EQUAL(0, r1.message3_count);
|
||||
CHECK_EQUAL(0, r1.message4_count);
|
||||
CHECK_EQUAL(0, r1.message_unknown_count);
|
||||
CHECK_EQUAL(2, r2.callback_count);
|
||||
|
||||
p_router->receive(r2, message3);
|
||||
CHECK_EQUAL(1, r1.message1_count);
|
||||
CHECK_EQUAL(1, r1.message2_count);
|
||||
CHECK_EQUAL(1, r1.message3_count);
|
||||
CHECK_EQUAL(0, r1.message4_count);
|
||||
CHECK_EQUAL(0, r1.message_unknown_count);
|
||||
CHECK_EQUAL(3, r2.callback_count);
|
||||
|
||||
p_router->receive(r2, message4);
|
||||
CHECK_EQUAL(1, r1.message1_count);
|
||||
CHECK_EQUAL(1, r1.message2_count);
|
||||
CHECK_EQUAL(1, r1.message3_count);
|
||||
CHECK_EQUAL(1, r1.message4_count);
|
||||
CHECK_EQUAL(0, r1.message_unknown_count);
|
||||
CHECK_EQUAL(4, r2.callback_count);
|
||||
|
||||
p_router = &r2;
|
||||
|
||||
p_router->receive(r1, message1);
|
||||
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);
|
||||
|
||||
p_router->receive(r1, message2);
|
||||
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);
|
||||
|
||||
p_router->receive(r1, message3);
|
||||
CHECK_EQUAL(1, r2.message1_count);
|
||||
CHECK_EQUAL(1, r2.message2_count);
|
||||
CHECK_EQUAL(0, r2.message4_count);
|
||||
CHECK_EQUAL(1, r2.message_unknown_count);
|
||||
CHECK_EQUAL(3, r1.callback_count);
|
||||
|
||||
p_router->receive(r1, message4);
|
||||
CHECK_EQUAL(1, r2.message1_count);
|
||||
CHECK_EQUAL(1, r2.message2_count);
|
||||
CHECK_EQUAL(1, r2.message4_count);
|
||||
CHECK_EQUAL(1, r2.message_unknown_count);
|
||||
CHECK_EQUAL(4, r1.callback_count);
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
TEST(message_null_router)
|
||||
{
|
||||
Router2 router;
|
||||
etl::null_message_router null_router;
|
||||
|
||||
// Send from the null router.
|
||||
etl::send_message(router, message1);
|
||||
CHECK_EQUAL(1, router.message1_count);
|
||||
CHECK_EQUAL(0, router.message2_count);
|
||||
CHECK_EQUAL(0, router.message4_count);
|
||||
CHECK_EQUAL(0, router.message_unknown_count);
|
||||
|
||||
etl::send_message(router, message2);
|
||||
CHECK_EQUAL(1, router.message1_count);
|
||||
CHECK_EQUAL(1, router.message2_count);
|
||||
CHECK_EQUAL(0, router.message4_count);
|
||||
CHECK_EQUAL(0, router.message_unknown_count);
|
||||
|
||||
etl::send_message(router, message3);
|
||||
CHECK_EQUAL(1, router.message1_count);
|
||||
CHECK_EQUAL(1, router.message2_count);
|
||||
CHECK_EQUAL(0, router.message4_count);
|
||||
CHECK_EQUAL(1, router.message_unknown_count);
|
||||
|
||||
etl::send_message(router, message4);
|
||||
CHECK_EQUAL(1, router.message1_count);
|
||||
CHECK_EQUAL(1, router.message2_count);
|
||||
CHECK_EQUAL(1, router.message4_count);
|
||||
CHECK_EQUAL(1, router.message_unknown_count);
|
||||
|
||||
// Send to the null router.
|
||||
etl::send_message(null_router, message1);
|
||||
CHECK_EQUAL(1, router.message1_count);
|
||||
CHECK_EQUAL(1, router.message2_count);
|
||||
CHECK_EQUAL(1, router.message4_count);
|
||||
CHECK_EQUAL(1, router.message_unknown_count);
|
||||
|
||||
etl::send_message(null_router, message2);
|
||||
CHECK_EQUAL(1, router.message1_count);
|
||||
CHECK_EQUAL(1, router.message2_count);
|
||||
CHECK_EQUAL(1, router.message4_count);
|
||||
CHECK_EQUAL(1, router.message_unknown_count);
|
||||
|
||||
etl::send_message(null_router, message3);
|
||||
CHECK_EQUAL(1, router.message1_count);
|
||||
CHECK_EQUAL(1, router.message2_count);
|
||||
CHECK_EQUAL(1, router.message4_count);
|
||||
CHECK_EQUAL(1, router.message_unknown_count);
|
||||
|
||||
etl::send_message(null_router, message4);
|
||||
CHECK_EQUAL(1, router.message1_count);
|
||||
CHECK_EQUAL(1, router.message2_count);
|
||||
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.get_message_id()));
|
||||
|
||||
CHECK(r2.accepts(message2));
|
||||
CHECK(r2.accepts(message2.get_message_id()));
|
||||
|
||||
CHECK(!r2.accepts(message3));
|
||||
CHECK(!r2.accepts(message3.get_message_id()));
|
||||
|
||||
CHECK(r2.accepts(message4));
|
||||
CHECK(r2.accepts(message4.get_message_id()));
|
||||
|
||||
CHECK(r2.accepts(message5));
|
||||
CHECK(r2.accepts(message5.get_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
183
test/test_packet.cpp
Normal 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
263
test/test_task_scheduler.cpp
Normal file
263
test/test_task_scheduler.cpp
Normal file
@ -0,0 +1,263 @@
|
||||
/******************************************************************************
|
||||
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()
|
||||
: idle_callback(*this, &Common::IdleCallback),
|
||||
watchdog_callback(*this, &Common::WatchdogCallback),
|
||||
watchdog_called(false)
|
||||
{
|
||||
}
|
||||
|
||||
//*********************************************
|
||||
void Clear()
|
||||
{
|
||||
workList.clear();
|
||||
}
|
||||
|
||||
//*********************************************
|
||||
void IdleCallback()
|
||||
{
|
||||
pScheduler->exit_scheduler();
|
||||
}
|
||||
|
||||
//*********************************************
|
||||
void WatchdogCallback()
|
||||
{
|
||||
watchdog_called = true;
|
||||
}
|
||||
|
||||
WorkList_t workList;
|
||||
etl::function<Common, void> idle_callback;
|
||||
etl::function<Common, void> watchdog_callback;
|
||||
etl::ischeduler* pScheduler;
|
||||
bool watchdog_called;
|
||||
};
|
||||
|
||||
//*****************************************************************************
|
||||
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_;
|
||||
}
|
||||
|
||||
//*********************************************
|
||||
uint32_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.idle_callback);
|
||||
s.set_watchdog_callback(common.watchdog_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);
|
||||
CHECK(common.watchdog_called);
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
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.idle_callback);
|
||||
s.set_watchdog_callback(common.watchdog_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);
|
||||
CHECK(common.watchdog_called);
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
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.idle_callback);
|
||||
s.set_watchdog_callback(common.watchdog_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);
|
||||
CHECK(common.watchdog_called);
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
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.idle_callback);
|
||||
s.set_watchdog_callback(common.watchdog_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);
|
||||
CHECK(common.watchdog_called);
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -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));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
224
test/test_user_type.cpp
Normal file
224
test/test_user_type.cpp
Normal file
@ -0,0 +1,224 @@
|
||||
/******************************************************************************
|
||||
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 <string>
|
||||
|
||||
#include "user_type.h"
|
||||
|
||||
ETL_DECLARE_USER_TYPE(CompassDirection, int)
|
||||
ETL_USER_TYPE(North, 0)
|
||||
ETL_USER_TYPE(South, 180)
|
||||
ETL_USER_TYPE(East, 90)
|
||||
ETL_USER_TYPE(West, 270)
|
||||
ETL_END_USER_TYPE(CompassDirection)
|
||||
|
||||
namespace
|
||||
{
|
||||
SUITE(test_user_type)
|
||||
{
|
||||
//*************************************************************************
|
||||
TEST(Values)
|
||||
{
|
||||
CHECK_EQUAL(0, CompassDirection::North);
|
||||
CHECK_EQUAL(180, CompassDirection::South);
|
||||
CHECK_EQUAL(90, CompassDirection::East);
|
||||
CHECK_EQUAL(270, CompassDirection::West);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_assignment)
|
||||
{
|
||||
CompassDirection value1 = CompassDirection::North;
|
||||
CompassDirection value2 = CompassDirection(135);
|
||||
|
||||
value1 = value2;
|
||||
|
||||
CHECK_EQUAL(135, value1);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_equality)
|
||||
{
|
||||
CompassDirection value1 = CompassDirection::North;
|
||||
CompassDirection value2 = CompassDirection::South;
|
||||
CompassDirection value3 = CompassDirection::South;
|
||||
|
||||
CHECK(value1 != value2);
|
||||
CHECK(value2 == value3);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_get_value)
|
||||
{
|
||||
CompassDirection actual = CompassDirection::North;
|
||||
CompassDirection expected = CompassDirection::North;
|
||||
|
||||
CHECK_EQUAL(expected, actual.get());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_pre_increment)
|
||||
{
|
||||
CompassDirection value = CompassDirection::North;
|
||||
CompassDirection expected = CompassDirection(CompassDirection::North + 1);
|
||||
|
||||
CHECK_EQUAL(expected, ++value);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_post_increment)
|
||||
{
|
||||
CompassDirection value = CompassDirection::North;
|
||||
CompassDirection expected = CompassDirection(CompassDirection::North + 1);
|
||||
|
||||
CHECK_EQUAL(CompassDirection::North, value++);
|
||||
CHECK_EQUAL(expected, value);
|
||||
}
|
||||
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_pre_decrement)
|
||||
{
|
||||
CompassDirection value = CompassDirection::North;
|
||||
CompassDirection expected = CompassDirection(CompassDirection::North - 1);
|
||||
|
||||
CHECK_EQUAL(expected, --value);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_post_decrement)
|
||||
{
|
||||
CompassDirection value = CompassDirection::North;
|
||||
CompassDirection expected = CompassDirection(CompassDirection::North - 1);
|
||||
|
||||
CHECK_EQUAL(CompassDirection::North, value--);
|
||||
CHECK_EQUAL(expected, value);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_add_equal)
|
||||
{
|
||||
CompassDirection value = CompassDirection::North;
|
||||
value += 3;
|
||||
CompassDirection expected = CompassDirection(CompassDirection::North + 3);
|
||||
|
||||
CHECK_EQUAL(expected, value);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_subtract_equal)
|
||||
{
|
||||
CompassDirection value = CompassDirection::North;
|
||||
value -= 3;
|
||||
CompassDirection expected = CompassDirection(CompassDirection::North - 3);
|
||||
|
||||
CHECK_EQUAL(expected, value);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_muliply_equal)
|
||||
{
|
||||
CompassDirection value = CompassDirection::North;
|
||||
value *= 3;
|
||||
CompassDirection expected = CompassDirection(CompassDirection::North * 3);
|
||||
|
||||
CHECK_EQUAL(expected, value);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_divide_equal)
|
||||
{
|
||||
CompassDirection value = CompassDirection::North;
|
||||
value /= 3;
|
||||
CompassDirection expected = CompassDirection(CompassDirection::North / 3);
|
||||
|
||||
CHECK_EQUAL(expected, value);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_mod_equal)
|
||||
{
|
||||
CompassDirection value = CompassDirection::North;
|
||||
value %= 3;
|
||||
CompassDirection expected = CompassDirection(CompassDirection::North % 3);
|
||||
|
||||
CHECK_EQUAL(expected, value);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_and_equal)
|
||||
{
|
||||
CompassDirection value = CompassDirection::North;
|
||||
value &= 0xAAAAAAAA;
|
||||
CompassDirection expected = CompassDirection(CompassDirection::North & 0xAAAAAAAA);
|
||||
|
||||
CHECK_EQUAL(expected, value);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_or_equal)
|
||||
{
|
||||
CompassDirection value = CompassDirection::North;
|
||||
value |= 0xAAAAAAAA;
|
||||
CompassDirection expected = CompassDirection(CompassDirection::North | 0xAAAAAAAA);
|
||||
|
||||
CHECK_EQUAL(expected, value);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_xor_equal)
|
||||
{
|
||||
CompassDirection value = CompassDirection::North;
|
||||
value ^= 0xAAAAAAAA;
|
||||
CompassDirection expected = CompassDirection(CompassDirection::North ^ 0xAAAAAAAA);
|
||||
|
||||
CHECK_EQUAL(expected, value);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_shift_left)
|
||||
{
|
||||
CompassDirection value = CompassDirection::North;
|
||||
value <<= 2;
|
||||
CompassDirection expected = CompassDirection(CompassDirection::North << 2);
|
||||
|
||||
CHECK_EQUAL(expected, value);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_shift_right)
|
||||
{
|
||||
CompassDirection value = CompassDirection::North;
|
||||
value >>= 2;
|
||||
CompassDirection expected = CompassDirection(CompassDirection::North >> 2);
|
||||
|
||||
CHECK_EQUAL(expected, value);
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -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)
|
||||
|
||||
@ -128,6 +128,19 @@
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\src\fsm.h" />
|
||||
<ClInclude Include="..\..\src\fsm_generator.h" />
|
||||
<ClInclude Include="..\..\src\largest_generator.h" />
|
||||
<ClInclude Include="..\..\src\message.h" />
|
||||
<ClInclude Include="..\..\src\message_bus.h" />
|
||||
<ClInclude Include="..\..\src\message_types.h" />
|
||||
<ClInclude Include="..\..\src\message_router.h" />
|
||||
<ClInclude Include="..\..\src\message_router_generator.h" />
|
||||
<ClInclude Include="..\..\src\packet.h" />
|
||||
<ClInclude Include="..\..\src\scheduler.h" />
|
||||
<ClInclude Include="..\..\src\smallest_generator.h" />
|
||||
<ClInclude Include="..\..\src\task.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" />
|
||||
@ -212,7 +225,6 @@
|
||||
<ClInclude Include="..\..\src\flat_map.h" />
|
||||
<ClInclude Include="..\..\src\map.h" />
|
||||
<ClInclude Include="..\..\src\memory.h" />
|
||||
<ClInclude Include="..\..\src\mru_cache.h" />
|
||||
<ClInclude Include="..\..\src\multimap.h" />
|
||||
<ClInclude Include="..\..\src\multiset.h" />
|
||||
<ClInclude Include="..\..\src\multi_array.h" />
|
||||
@ -236,7 +248,6 @@
|
||||
<ClInclude Include="..\..\src\reference_flat_multimap.h" />
|
||||
<ClInclude Include="..\..\src\reference_flat_multiset.h" />
|
||||
<ClInclude Include="..\..\src\reference_flat_set.h" />
|
||||
<ClInclude Include="..\..\src\rr_cache.h" />
|
||||
<ClInclude Include="..\..\src\set.h" />
|
||||
<ClInclude Include="..\..\src\smallest.h" />
|
||||
<ClInclude Include="..\..\src\stack.h" />
|
||||
@ -329,6 +340,7 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\test_fnv_1.cpp" />
|
||||
<ClCompile Include="..\test_forward_list.cpp" />
|
||||
<ClCompile Include="..\test_fsm.cpp" />
|
||||
<ClCompile Include="..\test_function.cpp" />
|
||||
<ClCompile Include="..\test_functional.cpp" />
|
||||
<ClCompile Include="..\test_hash.cpp" />
|
||||
@ -364,6 +376,8 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\test_maths.cpp" />
|
||||
<ClCompile Include="..\test_memory.cpp" />
|
||||
<ClCompile Include="..\test_message_bus.cpp" />
|
||||
<ClCompile Include="..\test_message_router.cpp" />
|
||||
<ClCompile Include="..\test_multimap.cpp" />
|
||||
<ClCompile Include="..\test_multiset.cpp" />
|
||||
<ClCompile Include="..\test_murmur3.cpp" />
|
||||
@ -373,6 +387,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" />
|
||||
@ -393,12 +408,14 @@
|
||||
<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" />
|
||||
<ClCompile Include="..\test_unordered_multimap.cpp" />
|
||||
<ClCompile Include="..\test_unordered_multiset.cpp" />
|
||||
<ClCompile Include="..\test_unordered_set.cpp" />
|
||||
<ClCompile Include="..\test_user_type.cpp" />
|
||||
<ClCompile Include="..\test_utility.cpp" />
|
||||
<ClCompile Include="..\test_variant.cpp" />
|
||||
<ClCompile Include="..\test_vector.cpp" />
|
||||
@ -410,6 +427,9 @@
|
||||
<ItemGroup>
|
||||
<None Include="..\..\Doxyfile" />
|
||||
<None Include="..\..\library.properties" />
|
||||
<None Include="..\..\src\generate.bat" />
|
||||
<None Include="..\..\src\generate_fsm.bat" />
|
||||
<None Include="..\..\src\generate_message_router.bat" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="..\..\src\file_error_numbers.txt" />
|
||||
|
||||
@ -38,7 +38,13 @@
|
||||
<UniqueIdentifier>{7028012c-30c4-4993-b2d9-3b1521a610ae}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="ETL\Frameworks">
|
||||
<UniqueIdentifier>{5de50c3d-4679-4eb3-9b76-e43e1aad6a66}</UniqueIdentifier>
|
||||
<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>
|
||||
@ -261,12 +267,6 @@
|
||||
<ClInclude Include="..\..\src\icache.h">
|
||||
<Filter>ETL\Containers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\mru_cache.h">
|
||||
<Filter>ETL\Containers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\rr_cache.h">
|
||||
<Filter>ETL\Containers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\intrusive_links.h">
|
||||
<Filter>ETL\Containers</Filter>
|
||||
</ClInclude>
|
||||
@ -438,6 +438,45 @@
|
||||
<ClInclude Include="..\..\unittest-cpp\UnitTest++\XmlTestReporter.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\fsm.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\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>
|
||||
<ClInclude Include="..\..\src\message.h">
|
||||
<Filter>ETL\Frameworks</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\message_bus.h">
|
||||
<Filter>ETL\Frameworks</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\message_types.h">
|
||||
<Filter>ETL\Frameworks</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\scheduler.h">
|
||||
<Filter>ETL\Frameworks</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\task.h">
|
||||
<Filter>ETL\Frameworks</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\main.cpp">
|
||||
@ -761,6 +800,24 @@
|
||||
<ClCompile Include="..\..\unittest-cpp\UnitTest++\XmlTestReporter.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\test_fsm.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<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>
|
||||
<ClCompile Include="..\test_message_bus.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\test_user_type.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\..\Doxyfile">
|
||||
@ -769,8 +826,14 @@
|
||||
<None Include="..\..\library.properties">
|
||||
<Filter>Resource Files</Filter>
|
||||
</None>
|
||||
<None Include="..\..\src\CreateMessageProcessor.bat">
|
||||
<Filter>Source Files</Filter>
|
||||
<None Include="..\..\src\generate.bat">
|
||||
<Filter>Resource Files</Filter>
|
||||
</None>
|
||||
<None Include="..\..\src\generate_message_router.bat">
|
||||
<Filter>Resource Files</Filter>
|
||||
</None>
|
||||
<None Include="..\..\src\generate_fsm.bat">
|
||||
<Filter>Resource Files</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
BIN
uml/FSM example.png
Normal file
BIN
uml/FSM example.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.4 KiB |
BIN
uml/Framework.png
Normal file
BIN
uml/Framework.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.3 KiB |
BIN
uml/MessageFramework.png
Normal file
BIN
uml/MessageFramework.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.3 KiB |
BIN
uml/source/FSM example.zargo
Normal file
BIN
uml/source/FSM example.zargo
Normal file
Binary file not shown.
BIN
uml/source/Message Framework.zargo
Normal file
BIN
uml/source/Message Framework.zargo
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user