Added boost header

This commit is contained in:
Christophe Riccio
2012-01-08 01:26:07 +00:00
parent 9c3faaca40
commit c7d752cdf8
8946 changed files with 1732316 additions and 0 deletions

68
test/external/boost/msm/back/args.hpp vendored Normal file
View File

@@ -0,0 +1,68 @@
// Copyright 2008 Christophe Henry
// henry UNDERSCORE christophe AT hotmail DOT com
// This is an extended version of the state machine available in the boost::mpl library
// Distributed under the same license as the original.
// Copyright for the original version:
// Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
// under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_MSM_BACK_ARGS_H
#define BOOST_MSM_BACK_ARGS_H
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/arithmetic/sub.hpp>
#include <boost/preprocessor/punctuation/comma_if.hpp>
#include <boost/preprocessor/control/expr_if.hpp>
#include <boost/preprocessor/punctuation/comma.hpp>
#include <boost/preprocessor/arithmetic/add.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/comparison/less.hpp>
#include <boost/preprocessor/arithmetic/dec.hpp>
#include <boost/function.hpp>
#ifndef BOOST_MSM_VISITOR_ARG_SIZE
#define BOOST_MSM_VISITOR_ARG_SIZE 2 // default max number of arguments
#endif
namespace boost { namespace msm { namespace back
{
struct no_args {};
#define MSM_ARGS_TYPEDEF_SUB(z, n, unused) typedef ARG ## n argument ## n ;
#define MSM_ARGS_PRINT(z, n, data) data
#define MSM_ARGS_NONE_PRINT(z, n, data) class data ## n = no_args \
BOOST_PP_COMMA_IF( BOOST_PP_LESS(n, BOOST_PP_DEC(BOOST_MSM_VISITOR_ARG_SIZE) ) )
#define MSM_VISITOR_MAIN_ARGS(n) \
template <class RES, \
BOOST_PP_REPEAT(BOOST_MSM_VISITOR_ARG_SIZE, MSM_ARGS_NONE_PRINT, ARG)> \
struct args \
{ \
typedef ::boost::function<RES(BOOST_PP_ENUM_PARAMS(n, ARG))> type; \
enum {args_number=n}; \
BOOST_PP_REPEAT(n, MSM_ARGS_TYPEDEF_SUB, ~ ) \
};
#define MSM_VISITOR_ARGS(z, n, unused) \
template <class RES BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, class ARG)> \
struct args<RES, \
BOOST_PP_ENUM_PARAMS(n,ARG) \
BOOST_PP_COMMA_IF(n) \
BOOST_PP_ENUM(BOOST_PP_SUB(BOOST_MSM_VISITOR_ARG_SIZE,n), MSM_ARGS_PRINT, no_args) \
> \
{ \
typedef ::boost::function<RES(BOOST_PP_ENUM_PARAMS(n, ARG))> type; \
enum {args_number=n}; \
BOOST_PP_REPEAT(n, MSM_ARGS_TYPEDEF_SUB, ~ ) \
};
MSM_VISITOR_MAIN_ARGS(BOOST_MSM_VISITOR_ARG_SIZE)
BOOST_PP_REPEAT(BOOST_MSM_VISITOR_ARG_SIZE, MSM_VISITOR_ARGS, ~)
#undef MSM_VISITOR_ARGS
#undef MSM_ARGS_PRINT
}}}
#endif //BOOST_MSM_BACK_ARGS_H

View File

@@ -0,0 +1,41 @@
// Copyright 2008 Christophe Henry
// henry UNDERSCORE christophe AT hotmail DOT com
// This is an extended version of the state machine available in the boost::mpl library
// Distributed under the same license as the original.
// Copyright for the original version:
// Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
// under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_MSM_BACK_BIND_HELPERS_H
#define BOOST_MSM_BACK_BIND_HELPERS_H
#include <functional>
namespace boost { namespace msm { namespace back
{
// helper to replace std::plus as the lack of implicit conversion makes it not usable in one of our bind
template<class _Ty,class _Tz>
struct plus2
: public std::binary_function<_Ty, _Tz, _Ty>
{
// functor for operator+
_Ty operator()( _Ty _Left, _Tz _Right) const
{
// apply operator+ to operands
return (_Left + _Right);
}
};
// helper to dereference a pointer to a function pointer
template <class T>
struct deref
{
typedef T& result_type;
T& operator()(T* f) const
{
return *f;
}
};
} } }//boost::msm::back
#endif //BOOST_MSM_BACK_BIND_HELPERS_H

View File

@@ -0,0 +1,35 @@
// Copyright 2008 Christophe Henry
// henry UNDERSCORE christophe AT hotmail DOT com
// This is an extended version of the state machine available in the boost::mpl library
// Distributed under the same license as the original.
// Copyright for the original version:
// Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
// under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_MSM_COMMON_TYPES_H
#define BOOST_MSM_COMMON_TYPES_H
#include <boost/tuple/tuple.hpp>
#include <boost/msm/common.hpp>
namespace boost { namespace msm { namespace back
{
// used for disable_if
template <int> struct dummy { dummy(int) {} };
// return value for transition handling
typedef enum
{
HANDLED_FALSE=0,
HANDLED_TRUE =1,
HANDLED_GUARD_REJECT=2,
HANDLED_DEFERRED=4
} HandledEnum;
typedef HandledEnum execute_return;
}}}
#endif //BOOST_MSM_COMMON_TYPES_H

View File

@@ -0,0 +1,30 @@
// Copyright 2008 Christophe Henry
// henry UNDERSCORE christophe AT hotmail DOT com
// This is an extended version of the state machine available in the boost::mpl library
// Distributed under the same license as the original.
// Copyright for the original version:
// Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
// under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_MSM_BACK_COPY_POLICIES_H
#define BOOST_MSM_BACK_COPY_POLICIES_H
#include <boost/noncopyable.hpp>
namespace boost { namespace msm { namespace back
{
// deactivates copy
struct NoCopy : ::boost::noncopyable
{
};
// allows deep copy
struct DeepCopy
{
};
} } }//boost::msm::back
#endif //BOOST_MSM_BACK_COPY_POLICIES_H

View File

@@ -0,0 +1,25 @@
// Copyright 2008 Christophe Henry
// henry UNDERSCORE christophe AT hotmail DOT com
// This is an extended version of the state machine available in the boost::mpl library
// Distributed under the same license as the original.
// Copyright for the original version:
// Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
// under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_MSM_BACK_DEFAULT_COMPILE_POLICY_HPP
#define BOOST_MSM_BACK_DEFAULT_COMPILE_POLICY_HPP
#include <boost/mpl/bool.hpp>
namespace boost { namespace msm { namespace back
{
struct favor_runtime_speed
{
typedef int compile_policy;
typedef ::boost::mpl::true_ add_forwarding_rows;
};
}}}// boost::msm::back
#endif // BOOST_MSM_BACK_DEFAULT_COMPILE_POLICY_HPP

View File

@@ -0,0 +1,361 @@
// Copyright 2008 Christophe Henry
// henry UNDERSCORE christophe AT hotmail DOT com
// This is an extended version of the state machine available in the boost::mpl library
// Distributed under the same license as the original.
// Copyright for the original version:
// Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
// under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_MSM_BACK_DISPATCH_TABLE_H
#define BOOST_MSM_BACK_DISPATCH_TABLE_H
#include <utility>
#include <boost/mpl/reverse_fold.hpp>
#include <boost/mpl/greater.hpp>
#include <boost/mpl/filter_view.hpp>
#include <boost/mpl/pop_front.hpp>
#include <boost/mpl/for_each.hpp>
#include <boost/mpl/advance.hpp>
#include <boost/type_traits/is_base_of.hpp>
#include <boost/msm/back/metafunctions.hpp>
#include <boost/msm/back/common_types.hpp>
BOOST_MPL_HAS_XXX_TRAIT_DEF(is_frow)
namespace boost { namespace msm { namespace back
{
// Generates a singleton runtime lookup table that maps current state
// to a function that makes the SM take its transition on the given
// Event type.
template <class Fsm,class Stt, class Event,class CompilePolicy>
struct dispatch_table
{
private:
// This is a table of these function pointers.
typedef HandledEnum (*cell)(Fsm&, int,int,Event const&);
typedef bool (*guard)(Fsm&, Event const&);
// class used to build a chain (or sequence) of transitions for a given event and start state
// (like an UML diamond). Allows transition conflicts.
template< typename Seq,typename AnEvent,typename State >
struct chain_row
{
typedef State current_state_type;
typedef AnEvent transition_event;
// helper for building a disable/enable_if-controlled execute function
struct execute_helper
{
template <class Sequence>
static
HandledEnum
execute(Fsm& , int, int, Event const& , ::boost::mpl::true_ const & )
{
// if at least one guard rejected, this will be ignored, otherwise will generate an error
return HANDLED_FALSE;
}
template <class Sequence>
static
HandledEnum
execute(Fsm& fsm, int region_index , int state, Event const& evt,
::boost::mpl::false_ const & )
{
// try the first guard
typedef typename ::boost::mpl::front<Sequence>::type first_row;
HandledEnum res = first_row::execute(fsm,region_index,state,evt);
if (HANDLED_TRUE!=res)
{
// if the first rejected, move on to the next one
HandledEnum sub_res =
execute<typename ::boost::mpl::pop_front<Sequence>::type>(fsm,region_index,state,evt,
::boost::mpl::bool_<
::boost::mpl::empty<typename ::boost::mpl::pop_front<Sequence>::type>::type::value>());
// if at least one guards rejects, the event will not generate a call to no_transition
if ((HANDLED_FALSE==sub_res) && (HANDLED_GUARD_REJECT==res) )
return HANDLED_GUARD_REJECT;
else
return sub_res;
}
return res;
}
};
// Take the transition action and return the next state.
static HandledEnum execute(Fsm& fsm, int region_index, int state, Event const& evt)
{
// forward to helper
return execute_helper::template execute<Seq>(fsm,region_index,state,evt,
::boost::mpl::bool_< ::boost::mpl::empty<Seq>::type::value>());
}
};
// nullary metafunction whose only job is to prevent early evaluation of _1
template< typename Entry >
struct make_chain_row_from_map_entry
{
// if we have more than one frow with the same state as source, remove the ones extra
// note: we know the frow's are located at the beginning so we remove at the beginning (number of frows - 1) elements
enum {number_frows = ::boost::mpl::count_if< typename Entry::second,has_is_frow< ::boost::mpl::placeholders::_1> >::value};
//erases the first NumberToDelete rows
template<class Sequence, int NumberToDelete>
struct erase_first_rows
{
typedef typename ::boost::mpl::erase<
typename Entry::second,
typename ::boost::mpl::begin<Sequence>::type,
typename ::boost::mpl::advance<
typename ::boost::mpl::begin<Sequence>::type,
::boost::mpl::int_<NumberToDelete> >::type
>::type type;
};
// if we have more than 1 frow with this event (not allowed), delete the spare
typedef typename ::boost::mpl::eval_if<
typename ::boost::mpl::bool_< number_frows >= 2 >::type,
erase_first_rows<typename Entry::second,number_frows-1>,
::boost::mpl::identity<typename Entry::second>
>::type filtered_stt;
typedef chain_row<filtered_stt,Event,
typename Entry::first > type;
};
// helper for lazy evaluation in eval_if of change_frow_event
template <class Transition,class NewEvent>
struct replace_event
{
typedef typename Transition::template replace_event<NewEvent>::type type;
};
// changes the event type for a frow to the event we are dispatching
// this helps ensure that an event does not get processed more than once because of frows and base events.
template <class FrowTransition>
struct change_frow_event
{
typedef typename ::boost::mpl::eval_if<
typename has_is_frow<FrowTransition>::type,
replace_event<FrowTransition,Event>,
boost::mpl::identity<FrowTransition>
>::type type;
};
// Compute the maximum state value in the sm so we know how big
// to make the table
typedef typename generate_state_set<Stt>::type state_list;
BOOST_STATIC_CONSTANT(int, max_state = ( ::boost::mpl::size<state_list>::value));
// A function object for use with mpl::for_each that stuffs
// transitions into cells.
struct init_cell
{
init_cell(dispatch_table* self_)
: self(self_)
{}
// version for transition event not base of our event
// first for all transitions, then for internal ones of a fsm
template <class Transition>
typename ::boost::disable_if<
typename ::boost::is_same<typename Transition::current_state_type,Fsm>::type
,void>::type
init_event_base_case(Transition const&, ::boost::mpl::true_ const &) const
{
typedef typename create_stt<Fsm>::type stt;
BOOST_STATIC_CONSTANT(int, state_id =
(get_state_id<stt,typename Transition::current_state_type>::value));
self->entries[state_id+1] = reinterpret_cast<cell>(&Transition::execute);
}
template <class Transition>
typename ::boost::enable_if<
typename ::boost::is_same<typename Transition::current_state_type,Fsm>::type
,void>::type
init_event_base_case(Transition const&, ::boost::mpl::true_ const &) const
{
self->entries[0] = reinterpret_cast<cell>(&Transition::execute);
}
// version for transition event base of our event
// first for all transitions, then for internal ones of a fsm
template <class Transition>
typename ::boost::disable_if<
typename ::boost::is_same<typename Transition::current_state_type,Fsm>::type
,void>::type
init_event_base_case(Transition const&, ::boost::mpl::false_ const &) const
{
typedef typename create_stt<Fsm>::type stt;
BOOST_STATIC_CONSTANT(int, state_id =
(get_state_id<stt,typename Transition::current_state_type>::value));
self->entries[state_id+1] = &Transition::execute;
}
template <class Transition>
typename ::boost::enable_if<
typename ::boost::is_same<typename Transition::current_state_type,Fsm>::type
,void>::type
init_event_base_case(Transition const&, ::boost::mpl::false_ const &) const
{
self->entries[0] = &Transition::execute;
}
// Cell initializer function object, used with mpl::for_each
template <class Transition>
typename ::boost::enable_if<typename has_not_real_row_tag<Transition>::type,void >::type
operator()(Transition const&,boost::msm::back::dummy<0> = 0) const
{
// version for not real rows. No problem because irrelevant for process_event
}
template <class Transition>
typename ::boost::disable_if<typename has_not_real_row_tag<Transition>::type,void >::type
operator()(Transition const& tr,boost::msm::back::dummy<1> = 0) const
{
//only if the transition event is a base of our event is the reinterpret_case safe
init_event_base_case(tr,
::boost::mpl::bool_<
::boost::is_base_of<typename Transition::transition_event,Event>::type::value>() );
}
dispatch_table* self;
};
// Cell default-initializer function object, used with mpl::for_each
// initializes with call_no_transition, defer_transition or default_eventless_transition
// variant for non-anonymous transitions
template <class EventType,class Enable=void>
struct default_init_cell
{
default_init_cell(dispatch_table* self_,cell* tofill_entries_)
: self(self_),tofill_entries(tofill_entries_)
{}
template <class State>
typename ::boost::enable_if<typename has_state_delayed_event<State,Event>::type,void>::type
operator()(boost::msm::wrap<State> const&,boost::msm::back::dummy<0> = 0)
{
typedef typename create_stt<Fsm>::type stt;
BOOST_STATIC_CONSTANT(int, state_id = (get_state_id<stt,State>::value));
cell call_no_transition = &Fsm::defer_transition;
tofill_entries[state_id+1] = call_no_transition;
}
template <class State>
typename ::boost::disable_if<
typename ::boost::mpl::or_<
typename has_state_delayed_event<State,Event>::type,
typename ::boost::is_same<State,Fsm>::type
>::type
,void >::type
operator()(boost::msm::wrap<State> const&,boost::msm::back::dummy<1> = 0)
{
typedef typename create_stt<Fsm>::type stt;
BOOST_STATIC_CONSTANT(int, state_id = (get_state_id<stt,State>::value));
cell call_no_transition = &Fsm::call_no_transition;
tofill_entries[state_id+1] = call_no_transition;
}
// case for internal transitions of this fsm
template <class State>
typename ::boost::enable_if<
typename ::boost::mpl::and_<
typename ::boost::mpl::not_<typename has_state_delayed_event<State,Event>::type>::type,
typename ::boost::is_same<State,Fsm>::type
>::type
,void>::type
operator()(boost::msm::wrap<State> const&,boost::msm::back::dummy<2> = 0)
{
cell call_no_transition = &Fsm::call_no_transition_internal;
tofill_entries[0] = call_no_transition;
}
dispatch_table* self;
cell* tofill_entries;
};
// variant for anonymous transitions
template <class EventType>
struct default_init_cell<EventType,
typename ::boost::enable_if<
typename is_completion_event<EventType>::type>::type>
{
default_init_cell(dispatch_table* self_,cell* tofill_entries_)
: self(self_),tofill_entries(tofill_entries_)
{}
// this event is a compound one (not a real one, just one for use in event-less transitions)
// Note this event cannot be used as deferred!
template <class State>
void operator()(boost::msm::wrap<State> const&)
{
typedef typename create_stt<Fsm>::type stt;
BOOST_STATIC_CONSTANT(int, state_id = (get_state_id<stt,State>::value));
cell call_no_transition = &Fsm::default_eventless_transition;
tofill_entries[state_id+1] = call_no_transition;
}
dispatch_table* self;
cell* tofill_entries;
};
public:
// initialize the dispatch table for a given Event and Fsm
dispatch_table()
{
// Initialize cells for no transition
::boost::mpl::for_each<typename generate_state_set<Stt>::type,
boost::msm::wrap< ::boost::mpl::placeholders::_1> >
(default_init_cell<Event>(this,entries));
// build chaining rows for rows coming from the same state and the current event
// first we build a map of sequence for every source
// in reverse order so that the frow's are handled first (UML priority)
typedef typename ::boost::mpl::reverse_fold<
// filter on event
::boost::mpl::filter_view
<Stt, ::boost::is_base_of<transition_event< ::boost::mpl::placeholders::_>, Event> >,
// build a map
::boost::mpl::map<>,
::boost::mpl::if_<
// if we already have a row on this source state
::boost::mpl::has_key< ::boost::mpl::placeholders::_1,
transition_source_type< ::boost::mpl::placeholders::_2> >,
// insert a new element in the value type
::boost::mpl::insert<
::boost::mpl::placeholders::_1,
::boost::mpl::pair<transition_source_type< ::boost::mpl::placeholders::_2>,
::boost::mpl::push_back<
::boost::mpl::at< ::boost::mpl::placeholders::_1,
transition_source_type< ::boost::mpl::placeholders::_2> >,
change_frow_event< ::boost::mpl::placeholders::_2 > >
> >,
// first row on this source state, make a vector with 1 element
::boost::mpl::insert<
::boost::mpl::placeholders::_1,
::boost::mpl::pair<transition_source_type< ::boost::mpl::placeholders::_2>,
make_vector< change_frow_event< ::boost::mpl::placeholders::_2> > > >
>
>::type map_of_row_seq;
// and then build chaining rows for all source states having more than 1 row
typedef typename ::boost::mpl::fold<
map_of_row_seq,::boost::mpl::vector0<>,
::boost::mpl::if_<
::boost::mpl::greater< ::boost::mpl::size<
::boost::mpl::second< ::boost::mpl::placeholders::_2> >,
::boost::mpl::int_<1> >,
// we need row chaining
::boost::mpl::push_back< ::boost::mpl::placeholders::_1,
make_chain_row_from_map_entry< ::boost::mpl::placeholders::_2> >,
// just one row, no chaining, we rebuild the row like it was before
::boost::mpl::push_back< ::boost::mpl::placeholders::_1,
get_first_element_pair_second< ::boost::mpl::placeholders::_2> >
> >::type chained_rows;
// Go back and fill in cells for matching transitions.
::boost::mpl::for_each<chained_rows>(init_cell(this));
}
// The singleton instance.
static const dispatch_table instance;
public: // data members
// +1 => 0 is reserved for this fsm (internal transitions)
cell entries[max_state+1];
};
}}} // boost::msm::back
#endif //BOOST_MSM_BACK_DISPATCH_TABLE_H

View File

@@ -0,0 +1,319 @@
// Copyright 2008 Christophe Henry
// henry UNDERSCORE christophe AT hotmail DOT com
// This is an extended version of the state machine available in the boost::mpl library
// Distributed under the same license as the original.
// Copyright for the original version:
// Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
// under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_MSM_BACK_FAVOR_COMPILE_TIME_H
#define BOOST_MSM_BACK_FAVOR_COMPILE_TIME_H
#include <utility>
#include <deque>
#include <boost/mpl/filter_view.hpp>
#include <boost/mpl/for_each.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/any.hpp>
#include <boost/msm/common.hpp>
#include <boost/msm/back/metafunctions.hpp>
#include <boost/msm/back/common_types.hpp>
#include <boost/msm/back/dispatch_table.hpp>
namespace boost { namespace msm { namespace back
{
template <class Fsm>
struct process_any_event_helper
{
process_any_event_helper(msm::back::HandledEnum& res_,Fsm* self_,::boost::any any_event_):
res(res_),self(self_),any_event(any_event_),finished(false){}
template <class Event>
void operator()(boost::msm::wrap<Event> const&)
{
if ( ! finished && ::boost::any_cast<Event>(&any_event)!=0)
{
finished = true;
res = self->process_event(::boost::any_cast<Event>(any_event));
}
}
private:
msm::back::HandledEnum& res;
Fsm* self;
::boost::any any_event;
bool finished;
};
#define BOOST_MSM_BACK_GENERATE_PROCESS_EVENT(fsmname) \
namespace boost { namespace msm { namespace back{ \
template<> \
::boost::msm::back::HandledEnum fsmname::process_any_event( ::boost::any const& any_event) \
{ \
typedef ::boost::msm::back::recursive_get_transition_table<fsmname>::type stt; \
typedef ::boost::msm::back::generate_event_set<stt>::type stt_events; \
typedef ::boost::msm::back::recursive_get_internal_transition_table<fsmname, ::boost::mpl::true_ >::type istt; \
typedef ::boost::msm::back::generate_event_set<create_real_stt<fsmname,istt>::type >::type istt_events; \
typedef ::boost::msm::back::set_insert_range<stt_events,istt_events>::type all_events; \
::boost::msm::back::HandledEnum res= ::boost::msm::back::HANDLED_FALSE; \
::boost::mpl::for_each<all_events, ::boost::msm::wrap< ::boost::mpl::placeholders::_1> > \
(::boost::msm::back::process_any_event_helper<fsmname>(res,this,any_event)); \
return res; \
} \
}}}
struct favor_compile_time
{
typedef int compile_policy;
typedef ::boost::mpl::false_ add_forwarding_rows;
};
// Generates a singleton runtime lookup table that maps current state
// to a function that makes the SM take its transition on the given
// Event type.
template <class Fsm,class Stt, class Event>
struct dispatch_table < Fsm, Stt, Event, ::boost::msm::back::favor_compile_time>
{
private:
// This is a table of these function pointers.
typedef HandledEnum (*cell)(Fsm&, int,int,Event const&);
typedef bool (*guard)(Fsm&, Event const&);
// Compute the maximum state value in the sm so we know how big
// to make the table
typedef typename generate_state_set<Stt>::type state_list;
BOOST_STATIC_CONSTANT(int, max_state = ( ::boost::mpl::size<state_list>::value));
struct chain_row
{
HandledEnum operator()(Fsm& fsm, int region,int state,Event const& evt) const
{
HandledEnum res = HANDLED_FALSE;
typename std::deque<cell>::const_iterator it = one_state.begin();
while (it != one_state.end() && res != HANDLED_TRUE)
{
HandledEnum handled = (*it)(fsm,region,state,evt);
// reject is considered as erasing an error (HANDLED_FALSE)
if ((HANDLED_FALSE==handled) && (HANDLED_GUARD_REJECT==res) )
res = HANDLED_GUARD_REJECT;
else
res = handled;
++it;
}
return res;
}
std::deque<cell> one_state;
};
template <class TransitionState>
static HandledEnum call_submachine(Fsm& fsm, int region, int state, Event const& evt)
{
return (fsm.template get_state<TransitionState&>()).process_any_event( ::boost::any(evt));
}
// A function object for use with mpl::for_each that stuffs
// transitions into cells.
struct init_cell
{
init_cell(dispatch_table* self_)
: self(self_)
{}
// version for transition event not base of our event
template <class Transition>
typename ::boost::disable_if<
typename ::boost::is_same<typename Transition::current_state_type,Fsm>::type
,void>::type
init_event_base_case(Transition const&, ::boost::mpl::true_ const &) const
{
typedef typename create_stt<Fsm>::type stt;
BOOST_STATIC_CONSTANT(int, state_id =
(get_state_id<stt,typename Transition::current_state_type>::value));
self->entries[state_id+1].one_state.push_front(reinterpret_cast<cell>(&Transition::execute));
}
template <class Transition>
typename ::boost::enable_if<
typename ::boost::is_same<typename Transition::current_state_type,Fsm>::type
,void>::type
init_event_base_case(Transition const&, ::boost::mpl::true_ const &) const
{
self->entries[0].one_state.push_front(reinterpret_cast<cell>(&Transition::execute));
}
// version for transition event base of our event
template <class Transition>
typename ::boost::disable_if<
typename ::boost::is_same<typename Transition::current_state_type,Fsm>::type
,void>::type
init_event_base_case(Transition const&, ::boost::mpl::false_ const &) const
{
typedef typename create_stt<Fsm>::type stt;
BOOST_STATIC_CONSTANT(int, state_id =
(get_state_id<stt,typename Transition::current_state_type>::value));
self->entries[state_id+1].one_state.push_front(&Transition::execute);
}
template <class Transition>
typename ::boost::enable_if<
typename ::boost::is_same<typename Transition::current_state_type,Fsm>::type
,void>::type
init_event_base_case(Transition const&, ::boost::mpl::false_ const &) const
{
self->entries[0].one_state.push_front(&Transition::execute);
}
// Cell initializer function object, used with mpl::for_each
template <class Transition>
typename ::boost::enable_if<typename has_not_real_row_tag<Transition>::type,void >::type
operator()(Transition const&,boost::msm::back::dummy<0> = 0) const
{
// version for not real rows. No problem because irrelevant for process_event
}
template <class Transition>
typename ::boost::disable_if<typename has_not_real_row_tag<Transition>::type,void >::type
operator()(Transition const& tr,boost::msm::back::dummy<1> = 0) const
{
//only if the transition event is a base of our event is the reinterpret_case safe
init_event_base_case(tr,
::boost::mpl::bool_<
::boost::is_base_of<typename Transition::transition_event,Event>::type::value>() );
}
dispatch_table* self;
};
// Cell default-initializer function object, used with mpl::for_each
// initializes with call_no_transition, defer_transition or default_eventless_transition
// variant for non-anonymous transitions
template <class EventType,class Enable=void>
struct default_init_cell
{
default_init_cell(dispatch_table* self_,chain_row* tofill_entries_)
: self(self_),tofill_entries(tofill_entries_)
{}
template <bool deferred,bool composite, int some_dummy=0>
struct helper
{};
template <int some_dummy> struct helper<true,false,some_dummy>
{
template <class State>
static void execute(boost::msm::wrap<State> const&,chain_row* tofill)
{
typedef typename create_stt<Fsm>::type stt;
BOOST_STATIC_CONSTANT(int, state_id = (get_state_id<stt,State>::value));
cell call_no_transition = &Fsm::defer_transition;
tofill[state_id+1].one_state.push_back(call_no_transition);
}
};
template <int some_dummy> struct helper<true,true,some_dummy>
{
template <class State>
static void execute(boost::msm::wrap<State> const&,chain_row* tofill)
{
typedef typename create_stt<Fsm>::type stt;
BOOST_STATIC_CONSTANT(int, state_id = (get_state_id<stt,State>::value));
cell call_no_transition = &Fsm::defer_transition;
tofill[state_id+1].one_state.push_back(call_no_transition);
}
};
template <int some_dummy> struct helper<false,true,some_dummy>
{
template <class State>
static
typename ::boost::enable_if<
typename ::boost::is_same<State,Fsm>::type
,void>::type
execute(boost::msm::wrap<State> const&,chain_row* tofill,boost::msm::back::dummy<0> = 0)
{
// for internal tables
cell call_no_transition_internal = &Fsm::call_no_transition;
tofill[0].one_state.push_front(call_no_transition_internal);
}
template <class State>
static
typename ::boost::disable_if<
typename ::boost::is_same<State,Fsm>::type
,void>::type
execute(boost::msm::wrap<State> const&,chain_row* tofill,boost::msm::back::dummy<1> = 0)
{
typedef typename create_stt<Fsm>::type stt;
BOOST_STATIC_CONSTANT(int, state_id = (get_state_id<stt,State>::value));
cell call_no_transition = &call_submachine< State >;
tofill[state_id+1].one_state.push_front(call_no_transition);
}
};
template <int some_dummy> struct helper<false,false,some_dummy>
{
template <class State>
static void execute(boost::msm::wrap<State> const&,chain_row* tofill)
{
typedef typename create_stt<Fsm>::type stt;
BOOST_STATIC_CONSTANT(int, state_id = (get_state_id<stt,State>::value));
cell call_no_transition = &Fsm::call_no_transition;
tofill[state_id+1].one_state.push_back(call_no_transition);
}
};
template <class State>
void operator()(boost::msm::wrap<State> const& s)
{
helper<has_state_delayed_event<State,Event>::type::value,
is_composite_state<State>::type::value>::execute(s,tofill_entries);
}
dispatch_table* self;
chain_row* tofill_entries;
};
// variant for anonymous transitions
template <class EventType>
struct default_init_cell<EventType,
typename ::boost::enable_if<
typename is_completion_event<EventType>::type>::type>
{
default_init_cell(dispatch_table* self_,chain_row* tofill_entries_)
: self(self_),tofill_entries(tofill_entries_)
{}
// this event is a compound one (not a real one, just one for use in event-less transitions)
// Note this event cannot be used as deferred!
template <class State>
void operator()(boost::msm::wrap<State> const&)
{
typedef typename create_stt<Fsm>::type stt;
BOOST_STATIC_CONSTANT(int, state_id = (get_state_id<stt,State>::value));
cell call_no_transition = &Fsm::default_eventless_transition;
tofill_entries[state_id+1].one_state.push_back(call_no_transition);
}
dispatch_table* self;
chain_row* tofill_entries;
};
public:
// initialize the dispatch table for a given Event and Fsm
dispatch_table()
{
// Initialize cells for no transition
::boost::mpl::for_each<
::boost::mpl::filter_view<
Stt, ::boost::is_base_of<transition_event< ::boost::mpl::placeholders::_>, Event> > >
(init_cell(this));
::boost::mpl::for_each<
typename generate_state_set<Stt>::type,
boost::msm::wrap< ::boost::mpl::placeholders::_1> >
(default_init_cell<Event>(this,entries));
}
// The singleton instance.
static const dispatch_table instance;
public: // data members
chain_row entries[max_state+1];
};
template <class Fsm,class Stt, class Event>
const boost::msm::back::dispatch_table<Fsm,Stt, Event,favor_compile_time>
dispatch_table<Fsm,Stt, Event,favor_compile_time>::instance;
}}} // boost::msm::back
#endif //BOOST_MSM_BACK_FAVOR_COMPILE_TIME_H

View File

@@ -0,0 +1,77 @@
// Copyright 2008 Christophe Henry
// henry UNDERSCORE christophe AT hotmail DOT com
// This is taken from Boost.Proto's documentation
// Copyright for the original version:
// Copyright 2008 Eric Niebler. Distributed
// under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_MSM_BACK_FOLD_TO_LIST_H
#define BOOST_MSM_BACK_FOLD_TO_LIST_H
#include <boost/msm/proto_config.hpp>
#include <boost/proto/core.hpp>
#include <boost/proto/transform.hpp>
#include <boost/msm/msm_grammar.hpp>
#include <boost/fusion/container/list/cons.hpp>
namespace boost { namespace msm { namespace back
{
struct state_copy_tag
{
};
template<class X = proto::is_proto_expr>
struct define_states_creation
{
BOOST_PROTO_BASIC_EXTENDS(
proto::terminal<state_copy_tag>::type
, define_states_creation
, boost::msm::msm_domain
)
};
define_states_creation<> const states_ = {{{}}};
struct FoldToList
: ::boost::proto::or_<
// Don't add the states_ terminal to the list
::boost::proto::when<
::boost::proto::terminal< state_copy_tag >
, ::boost::proto::_state
>
// Put all other terminals at the head of the
// list that we're building in the "state" parameter
// first states for the eUML states
, ::boost::proto::when<
::boost::proto::terminal< state_tag >
, boost::fusion::cons< ::boost::proto::_, ::boost::proto::_state>(
::boost::proto::_, ::boost::proto::_state
)
>
// then states from other front-ends
, ::boost::proto::when<
::boost::proto::terminal< proto::_ >
, boost::fusion::cons< ::boost::proto::_value, ::boost::proto::_state>(
::boost::proto::_value, ::boost::proto::_state
)
>
// For left-shift operations, first fold the right
// child to a list using the current state. Use
// the result as the state parameter when folding
// the left child to a list.
, ::boost::proto::when<
::boost::proto::shift_left<FoldToList, FoldToList>
, FoldToList(
::boost::proto::_left
, ::boost::proto::call<FoldToList( ::boost::proto::_right, ::boost::proto::_state )>
)
>
>
{};
}}}
#endif //BOOST_MSM_BACK_FOLD_TO_LIST_H

View File

@@ -0,0 +1,182 @@
// Copyright 2008 Christophe Henry
// henry UNDERSCORE christophe AT hotmail DOT com
// This is an extended version of the state machine available in the boost::mpl library
// Distributed under the same license as the original.
// Copyright for the original version:
// Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
// under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_MSM_BACK_HISTORY_POLICIES_H
#define BOOST_MSM_BACK_HISTORY_POLICIES_H
#include <boost/mpl/contains.hpp>
namespace boost { namespace msm { namespace back
{
// policy classes
// Default: no history used
template <int NumberOfRegions>
class NoHistoryImpl
{
public:
NoHistoryImpl(){}
~NoHistoryImpl(){}
void set_initial_states(int* const initial_states)
{
for (int i=0;i<NumberOfRegions;++i)
m_initialStates[i] = initial_states[i];
}
void history_exit(int* const )
{
// ignore
}
// returns the state where the state machine should be at start
template <class Event>
const int* history_entry(Event const& )
{
// always come back to the original state
return m_initialStates;
}
NoHistoryImpl<NumberOfRegions>& operator=(NoHistoryImpl<NumberOfRegions> const& rhs)
{
for (int i=0; i<NumberOfRegions;++i)
{
m_initialStates[i] = rhs.m_initialStates[i];
}
return *this;
}
template<class Archive>
void serialize(Archive & ar, const unsigned int)
{
ar & m_initialStates;
}
private:
int m_initialStates[NumberOfRegions];
};
// not UML standard. Always activates history, no matter which event generated the transition
template <int NumberOfRegions>
class AlwaysHistoryImpl
{
public:
AlwaysHistoryImpl(){}
~AlwaysHistoryImpl(){}
void set_initial_states(int* const initial_states)
{
for (int i=0;i<NumberOfRegions;++i)
m_initialStates[i] = initial_states[i];
}
void history_exit(int* const current_states)
{
for (int i=0;i<NumberOfRegions;++i)
m_initialStates[i] = current_states[i];
}
// returns the state where the state machine should be at start
template <class Event>
const int* history_entry(Event const& )
{
// always load back the last active state
return m_initialStates;
}
AlwaysHistoryImpl<NumberOfRegions>& operator=(AlwaysHistoryImpl<NumberOfRegions> const& rhs)
{
for (int i=0; i<NumberOfRegions;++i)
{
m_initialStates[i] = rhs.m_initialStates[i];
}
return *this;
}
template<class Archive>
void serialize(Archive & ar, const unsigned int)
{
ar & m_initialStates;
}
private:
int m_initialStates[NumberOfRegions];
};
// UML Shallow history. For deep history, just use this policy for all the contained state machines
template <class Events,int NumberOfRegions>
class ShallowHistoryImpl
{
public:
ShallowHistoryImpl(){}
~ShallowHistoryImpl(){}
void set_initial_states(int* const initial_states)
{
for (int i=0;i<NumberOfRegions;++i)
{
m_currentStates[i] = initial_states[i];
m_initialStates[i] = initial_states[i];
}
}
void history_exit(int* const current_states)
{
for (int i=0;i<NumberOfRegions;++i)
m_currentStates[i] = current_states[i];
}
// returns the state where the state machine should be at start
template <class Event>
const int* history_entry(Event const&)
{
if ( ::boost::mpl::contains<Events,Event>::value)
{
return m_currentStates;
}
// not one of our events, no history
return m_initialStates;
}
ShallowHistoryImpl<Events,NumberOfRegions>& operator=(ShallowHistoryImpl<Events,NumberOfRegions> const& rhs)
{
for (int i=0; i<NumberOfRegions;++i)
{
m_initialStates[i] = rhs.m_initialStates[i];
m_currentStates[i] = rhs.m_currentStates[i];
}
return *this;
}
template<class Archive>
void serialize(Archive & ar, const unsigned int)
{
ar & m_initialStates;
ar & m_currentStates;
}
private:
int m_initialStates[NumberOfRegions];
int m_currentStates[NumberOfRegions];
};
struct NoHistory
{
typedef int history_policy;
template <int NumberOfRegions>
struct apply
{
typedef NoHistoryImpl<NumberOfRegions> type;
};
};
struct AlwaysHistory
{
typedef int history_policy;
template <int NumberOfRegions>
struct apply
{
typedef AlwaysHistoryImpl<NumberOfRegions> type;
};
};
template <class Events>
struct ShallowHistory
{
typedef int history_policy;
template <int NumberOfRegions>
struct apply
{
typedef ShallowHistoryImpl<Events,NumberOfRegions> type;
};
};
} } }//boost::msm::back
#endif //BOOST_MSM_BACK_HISTORY_POLICIES_H

View File

@@ -0,0 +1,930 @@
// Copyright 2008 Christophe Henry
// henry UNDERSCORE christophe AT hotmail DOT com
// This is an extended version of the state machine available in the boost::mpl library
// Distributed under the same license as the original.
// Copyright for the original version:
// Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
// under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_MSM_BACK_METAFUNCTIONS_H
#define BOOST_MSM_BACK_METAFUNCTIONS_H
#include <boost/mpl/set.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/pair.hpp>
#include <boost/mpl/map.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/has_xxx.hpp>
#include <boost/mpl/find.hpp>
#include <boost/mpl/count_if.hpp>
#include <boost/mpl/fold.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/has_key.hpp>
#include <boost/mpl/insert.hpp>
#include <boost/mpl/next_prior.hpp>
#include <boost/mpl/map.hpp>
#include <boost/mpl/push_back.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/is_sequence.hpp>
#include <boost/mpl/size.hpp>
#include <boost/mpl/transform.hpp>
#include <boost/mpl/begin_end.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/empty.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/insert_range.hpp>
#include <boost/mpl/front.hpp>
#include <boost/mpl/logical.hpp>
#include <boost/mpl/plus.hpp>
#include <boost/mpl/copy_if.hpp>
#include <boost/mpl/back_inserter.hpp>
#include <boost/mpl/transform.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/utility/enable_if.hpp>
// mpl_graph graph implementation and depth first search
#include <boost/msm/mpl_graph/incidence_list_graph.hpp>
#include <boost/msm/mpl_graph/depth_first_search.hpp>
BOOST_MPL_HAS_XXX_TRAIT_DEF(explicit_creation)
BOOST_MPL_HAS_XXX_TRAIT_DEF(pseudo_entry)
BOOST_MPL_HAS_XXX_TRAIT_DEF(pseudo_exit)
BOOST_MPL_HAS_XXX_TRAIT_DEF(concrete_exit_state)
BOOST_MPL_HAS_XXX_TRAIT_DEF(composite_tag)
BOOST_MPL_HAS_XXX_TRAIT_DEF(not_real_row_tag)
BOOST_MPL_HAS_XXX_TRAIT_DEF(event_blocking_flag)
BOOST_MPL_HAS_XXX_TRAIT_DEF(explicit_entry_state)
BOOST_MPL_HAS_XXX_TRAIT_DEF(completion_event)
BOOST_MPL_HAS_XXX_TRAIT_DEF(no_exception_thrown)
BOOST_MPL_HAS_XXX_TRAIT_DEF(no_message_queue)
BOOST_MPL_HAS_XXX_TRAIT_DEF(activate_deferred_events)
BOOST_MPL_HAS_XXX_TRAIT_DEF(wrapped_entry)
BOOST_MPL_HAS_XXX_TRAIT_DEF(active_state_switch_policy)
namespace boost { namespace msm { namespace back
{
template <typename Sequence, typename Range>
struct set_insert_range
{
typedef typename ::boost::mpl::fold<
Range,Sequence,
::boost::mpl::insert< ::boost::mpl::placeholders::_1, ::boost::mpl::placeholders::_2 >
>::type type;
};
// returns the current state type of a transition
template <class Transition>
struct transition_source_type
{
typedef typename Transition::current_state_type type;
};
// returns the target state type of a transition
template <class Transition>
struct transition_target_type
{
typedef typename Transition::next_state_type type;
};
// helper functions for generate_state_ids
// create a pair of a state and a passed id for source and target states
template <class Id,class Transition>
struct make_pair_source_state_id
{
typedef typename ::boost::mpl::pair<typename Transition::current_state_type,Id> type;
};
template <class Id,class Transition>
struct make_pair_target_state_id
{
typedef typename ::boost::mpl::pair<typename Transition::next_state_type,Id> type;
};
// iterates through a transition table and automatically generates ids starting at 0
// first the source states, transition up to down
// then the target states, up to down
template <class stt>
struct generate_state_ids
{
typedef typename
::boost::mpl::fold<
stt,::boost::mpl::pair< ::boost::mpl::map< >, ::boost::mpl::int_<0> >,
::boost::mpl::pair<
::boost::mpl::if_<
::boost::mpl::has_key< ::boost::mpl::first< ::boost::mpl::placeholders::_1>,
transition_source_type< ::boost::mpl::placeholders::_2> >,
::boost::mpl::first< ::boost::mpl::placeholders::_1>,
::boost::mpl::insert< ::boost::mpl::first<mpl::placeholders::_1>,
make_pair_source_state_id< ::boost::mpl::second< ::boost::mpl::placeholders::_1 >,
::boost::mpl::placeholders::_2> >
>,
::boost::mpl::if_<
::boost::mpl::has_key< ::boost::mpl::first< ::boost::mpl::placeholders::_1>,
transition_source_type< ::boost::mpl::placeholders::_2> >,
::boost::mpl::second< ::boost::mpl::placeholders::_1 >,
::boost::mpl::next< ::boost::mpl::second<mpl::placeholders::_1 > >
>
> //pair
>::type source_state_ids;
typedef typename ::boost::mpl::first<source_state_ids>::type source_state_map;
typedef typename ::boost::mpl::second<source_state_ids>::type highest_state_id;
typedef typename
::boost::mpl::fold<
stt,::boost::mpl::pair<source_state_map,highest_state_id >,
::boost::mpl::pair<
::boost::mpl::if_<
::boost::mpl::has_key< ::boost::mpl::first< ::boost::mpl::placeholders::_1>,
transition_target_type< ::boost::mpl::placeholders::_2> >,
::boost::mpl::first< ::boost::mpl::placeholders::_1>,
::boost::mpl::insert< ::boost::mpl::first< ::boost::mpl::placeholders::_1>,
make_pair_target_state_id< ::boost::mpl::second< ::boost::mpl::placeholders::_1 >,
::boost::mpl::placeholders::_2> >
>,
::boost::mpl::if_<
::boost::mpl::has_key< ::boost::mpl::first< ::boost::mpl::placeholders::_1>,
transition_target_type< ::boost::mpl::placeholders::_2> >,
::boost::mpl::second< ::boost::mpl::placeholders::_1 >,
::boost::mpl::next< ::boost::mpl::second< ::boost::mpl::placeholders::_1 > >
>
> //pair
>::type all_state_ids;
typedef typename ::boost::mpl::first<all_state_ids>::type type;
};
template <class Fsm>
struct get_active_state_switch_policy_helper
{
typedef typename Fsm::active_state_switch_policy type;
};
template <class Iter>
struct get_active_state_switch_policy_helper2
{
typedef typename boost::mpl::deref<Iter>::type Fsm;
typedef typename Fsm::active_state_switch_policy type;
};
// returns the active state switching policy
template <class Fsm>
struct get_active_state_switch_policy
{
typedef typename ::boost::mpl::find_if<
typename Fsm::configuration,
has_active_state_switch_policy< ::boost::mpl::placeholders::_1 > >::type iter;
typedef typename ::boost::mpl::eval_if<
typename ::boost::is_same<
iter,
typename ::boost::mpl::end<typename Fsm::configuration>::type
>::type,
get_active_state_switch_policy_helper<Fsm>,
get_active_state_switch_policy_helper2< iter >
>::type type;
};
// returns the id of a given state
template <class stt,class State>
struct get_state_id
{
typedef typename ::boost::mpl::at<typename generate_state_ids<stt>::type,State>::type type;
enum {value = type::value};
};
// returns a mpl::vector containing the init states of a state machine
template <class States>
struct get_initial_states
{
typedef typename ::boost::mpl::if_<
::boost::mpl::is_sequence<States>,
States,
typename ::boost::mpl::push_back< ::boost::mpl::vector0<>,States>::type >::type type;
};
// returns a mpl::int_ containing the size of a region. If the argument is not a sequence, returns 1
template <class region>
struct get_number_of_regions
{
typedef typename mpl::if_<
::boost::mpl::is_sequence<region>,
::boost::mpl::size<region>,
::boost::mpl::int_<1> >::type type;
};
// builds a mpl::vector of initial states
//TODO remove duplicate from get_initial_states
template <class region>
struct get_regions_as_sequence
{
typedef typename ::boost::mpl::if_<
::boost::mpl::is_sequence<region>,
region,
typename ::boost::mpl::push_back< ::boost::mpl::vector0<>,region>::type >::type type;
};
template <class ToCreateSeq>
struct get_explicit_creation_as_sequence
{
typedef typename ::boost::mpl::if_<
::boost::mpl::is_sequence<ToCreateSeq>,
ToCreateSeq,
typename ::boost::mpl::push_back< ::boost::mpl::vector0<>,ToCreateSeq>::type >::type type;
};
// returns true if 2 transitions have the same source (used to remove duplicates in search of composite states)
template <class stt,class Transition1,class Transition2>
struct have_same_source
{
enum {current_state1 = get_state_id<stt,typename Transition1::current_state_type >::type::value};
enum {current_state2 = get_state_id<stt,typename Transition2::current_state_type >::type::value};
enum {value = ((int)current_state1 == (int)current_state2) };
};
// A metafunction that returns the Event associated with a transition.
template <class Transition>
struct transition_event
{
typedef typename Transition::transition_event type;
};
// returns true for composite states
template <class State>
struct is_composite_state
{
enum {value = has_composite_tag<State>::type::value};
typedef typename has_composite_tag<State>::type type;
};
// transform a transition table in a container of source states
template <class stt>
struct keep_source_names
{
// instead of the rows we want only the names of the states (from source)
typedef typename
::boost::mpl::transform<
stt,transition_source_type< ::boost::mpl::placeholders::_1> >::type type;
};
// transform a transition table in a container of target states
template <class stt>
struct keep_target_names
{
// instead of the rows we want only the names of the states (from source)
typedef typename
::boost::mpl::transform<
stt,transition_target_type< ::boost::mpl::placeholders::_1> >::type type;
};
template <class stt>
struct generate_state_set
{
// keep in the original transition table only the source/target state types
typedef typename keep_source_names<stt>::type sources;
typedef typename keep_target_names<stt>::type targets;
typedef typename
::boost::mpl::fold<
sources, ::boost::mpl::set<>,
::boost::mpl::insert< ::boost::mpl::placeholders::_1, ::boost::mpl::placeholders::_2>
>::type source_set;
typedef typename
::boost::mpl::fold<
targets,source_set,
::boost::mpl::insert< ::boost::mpl::placeholders::_1, ::boost::mpl::placeholders::_2>
>::type type;
};
// iterates through the transition table and generate a mpl::set<> containing all the events
template <class stt>
struct generate_event_set
{
typedef typename
::boost::mpl::fold<
stt, ::boost::mpl::set<>,
::boost::mpl::if_<
::boost::mpl::has_key< ::boost::mpl::placeholders::_1,
transition_event< ::boost::mpl::placeholders::_2> >,
::boost::mpl::placeholders::_1,
::boost::mpl::insert< ::boost::mpl::placeholders::_1,
transition_event< ::boost::mpl::placeholders::_2> > >
>::type type;
};
// returns a mpl::bool_<true> if State has Event as deferred event
template <class State, class Event>
struct has_state_delayed_event
{
typedef typename ::boost::mpl::find<typename State::deferred_events,Event>::type found;
typedef typename ::boost::mpl::if_<
::boost::is_same<found,typename ::boost::mpl::end<typename State::deferred_events>::type >,
::boost::mpl::bool_<false>,
::boost::mpl::bool_<true> >::type type;
};
// returns a mpl::bool_<true> if State has any deferred event
template <class State>
struct has_state_delayed_events
{
typedef typename ::boost::mpl::if_<
::boost::mpl::empty<typename State::deferred_events>,
::boost::mpl::bool_<false>,
::boost::mpl::bool_<true> >::type type;
};
// Template used to create dummy entries for initial states not found in the stt.
template< typename T1 >
struct not_a_row
{
typedef int not_real_row_tag;
struct dummy_event
{
};
typedef T1 current_state_type;
typedef T1 next_state_type;
typedef dummy_event transition_event;
};
// metafunctions used to find out if a state is entry, exit or something else
template <class State>
struct is_pseudo_entry
{
typedef typename ::boost::mpl::if_< typename has_pseudo_entry<State>::type,
::boost::mpl::bool_<true>,::boost::mpl::bool_<false>
>::type type;
};
// says if a state is an exit pseudo state
template <class State>
struct is_pseudo_exit
{
typedef typename ::boost::mpl::if_< typename has_pseudo_exit<State>::type,
::boost::mpl::bool_<true>, ::boost::mpl::bool_<false>
>::type type;
};
// says if a state is an entry pseudo state or an explicit entry
template <class State>
struct is_direct_entry
{
typedef typename ::boost::mpl::if_< typename has_explicit_entry_state<State>::type,
::boost::mpl::bool_<true>, ::boost::mpl::bool_<false>
>::type type;
};
//converts a "fake" (simulated in a state_machine_ description )state into one which will really get created
template <class StateType,class CompositeType>
struct convert_fake_state
{
// converts a state (explicit entry) into the state we really are going to create (explicit<>)
typedef typename ::boost::mpl::if_<
typename is_direct_entry<StateType>::type,
typename CompositeType::template direct<StateType>,
typename ::boost::mpl::identity<StateType>::type
>::type type;
};
template <class StateType>
struct get_explicit_creation
{
typedef typename StateType::explicit_creation type;
};
template <class StateType>
struct get_wrapped_entry
{
typedef typename StateType::wrapped_entry type;
};
// used for states created with explicit_creation
// if the state is an explicit entry, we reach for the wrapped state
// otherwise, this returns the state itself
template <class StateType>
struct get_wrapped_state
{
typedef typename ::boost::mpl::eval_if<
typename has_wrapped_entry<StateType>::type,
get_wrapped_entry<StateType>,
::boost::mpl::identity<StateType> >::type type;
};
template <class Derived>
struct create_stt
{
//typedef typename Derived::transition_table stt;
typedef typename Derived::real_transition_table Stt;
// get the state set
typedef typename generate_state_set<Stt>::type states;
// transform the initial region(s) in a sequence
typedef typename get_regions_as_sequence<typename Derived::initial_state>::type init_states;
// iterate through the initial states and add them in the stt if not already there
typedef typename
::boost::mpl::fold<
init_states,Stt,
::boost::mpl::if_<
::boost::mpl::has_key<states, ::boost::mpl::placeholders::_2>,
::boost::mpl::placeholders::_1,
::boost::mpl::insert< ::boost::mpl::placeholders::_1, ::boost::mpl::end< ::boost::mpl::placeholders::_1>,
not_a_row< get_wrapped_state< ::boost::mpl::placeholders::_2> > >
>
>::type with_init;
// do the same for states marked as explicitly created
typedef typename get_explicit_creation_as_sequence<
typename ::boost::mpl::eval_if<
typename has_explicit_creation<Derived>::type,
get_explicit_creation<Derived>,
::boost::mpl::vector0<> >::type
>::type fake_explicit_created;
typedef typename
::boost::mpl::transform<
fake_explicit_created,convert_fake_state< ::boost::mpl::placeholders::_1,Derived> >::type explicit_created;
typedef typename
::boost::mpl::fold<
explicit_created,with_init,
::boost::mpl::if_<
::boost::mpl::has_key<states, ::boost::mpl::placeholders::_2>,
::boost::mpl::placeholders::_1,
::boost::mpl::insert< ::boost::mpl::placeholders::_1, ::boost::mpl::end<mpl::placeholders::_1>,
not_a_row< get_wrapped_state< ::boost::mpl::placeholders::_2> > >
>
>::type type;
};
// returns the transition table of a Composite state
template <class Composite>
struct get_transition_table
{
typedef typename create_stt<Composite>::type type;
};
// recursively builds an internal table including those of substates, sub-substates etc.
// variant for submachines
template <class StateType,class IsComposite>
struct recursive_get_internal_transition_table
{
// get the composite's internal table
typedef typename StateType::internal_transition_table composite_table;
// and for every substate (state of submachine), recursively get the internal transition table
typedef typename generate_state_set<typename StateType::stt>::type composite_states;
typedef typename ::boost::mpl::fold<
composite_states, composite_table,
::boost::mpl::insert_range< ::boost::mpl::placeholders::_1, ::boost::mpl::end< ::boost::mpl::placeholders::_1>,
recursive_get_internal_transition_table< ::boost::mpl::placeholders::_2, is_composite_state< ::boost::mpl::placeholders::_2> >
>
>::type type;
};
// stop iterating on leafs (simple states)
template <class StateType>
struct recursive_get_internal_transition_table<StateType, ::boost::mpl::false_ >
{
typedef typename StateType::internal_transition_table type;
};
// recursively get a transition table for a given composite state.
// returns the transition table for this state + the tables of all composite sub states recursively
template <class Composite>
struct recursive_get_transition_table
{
// get the transition table of the state if it's a state machine
typedef typename ::boost::mpl::eval_if<typename is_composite_state<Composite>::type,
get_transition_table<Composite>,
::boost::mpl::vector0<>
>::type org_table;
typedef typename generate_state_set<org_table>::type states;
// and for every substate, recursively get the transition table if it's a state machine
typedef typename ::boost::mpl::fold<
states,org_table,
::boost::mpl::insert_range< ::boost::mpl::placeholders::_1, ::boost::mpl::end<mpl::placeholders::_1>,
recursive_get_transition_table< ::boost::mpl::placeholders::_2 > >
>::type type;
};
// metafunction used to say if a SM has pseudo exit states
template <class Derived>
struct has_fsm_deferred_events
{
typedef typename create_stt<Derived>::type Stt;
typedef typename generate_state_set<Stt>::type state_list;
typedef typename ::boost::mpl::or_<
typename has_activate_deferred_events<Derived>::type,
::boost::mpl::bool_< ::boost::mpl::count_if<
typename Derived::configuration,
has_activate_deferred_events< ::boost::mpl::placeholders::_1 > >::value != 0>
>::type found_in_fsm;
typedef typename ::boost::mpl::or_<
found_in_fsm,
::boost::mpl::bool_< ::boost::mpl::count_if<
state_list,has_state_delayed_events<
::boost::mpl::placeholders::_1 > >::value != 0>
>::type type;
};
// returns a mpl::bool_<true> if State has any delayed event
template <class Event>
struct is_completion_event
{
typedef typename ::boost::mpl::if_<
has_completion_event<Event>,
::boost::mpl::bool_<true>,
::boost::mpl::bool_<false> >::type type;
};
// metafunction used to say if a SM has eventless transitions
template <class Derived>
struct has_fsm_eventless_transition
{
typedef typename create_stt<Derived>::type Stt;
typedef typename generate_event_set<Stt>::type event_list;
typedef ::boost::mpl::bool_< ::boost::mpl::count_if<
event_list,is_completion_event< ::boost::mpl::placeholders::_1 > >::value != 0> type;
};
template <class Derived>
struct find_completion_events
{
typedef typename create_stt<Derived>::type Stt;
typedef typename generate_event_set<Stt>::type event_list;
typedef typename ::boost::mpl::fold<
event_list, ::boost::mpl::set<>,
::boost::mpl::if_<
is_completion_event< ::boost::mpl::placeholders::_2>,
::boost::mpl::insert< ::boost::mpl::placeholders::_1, ::boost::mpl::placeholders::_2 >,
::boost::mpl::placeholders::_1 >
>::type type;
};
template <class Transition>
struct make_vector
{
typedef ::boost::mpl::vector<Transition> type;
};
template< typename Entry >
struct get_first_element_pair_second
{
typedef typename ::boost::mpl::front<typename Entry::second>::type type;
};
//returns the owner of an explicit_entry state
//which is the containing SM if the transition originates from outside the containing SM
//or else the explicit_entry state itself
template <class State,class ContainingSM>
struct get_owner
{
typedef typename ::boost::mpl::if_<
typename ::boost::mpl::not_<typename ::boost::is_same<typename State::owner,
ContainingSM >::type>::type,
typename State::owner,
State >::type type;
};
template <class Sequence,class ContainingSM>
struct get_fork_owner
{
typedef typename ::boost::mpl::front<Sequence>::type seq_front;
typedef typename ::boost::mpl::if_<
typename ::boost::mpl::not_<
typename ::boost::is_same<typename seq_front::owner,ContainingSM>::type>::type,
typename seq_front::owner,
seq_front >::type type;
};
template <class StateType,class ContainingSM>
struct make_exit
{
typedef typename ::boost::mpl::if_<
typename is_pseudo_exit<StateType>::type ,
typename ContainingSM::template exit_pt<StateType>,
typename ::boost::mpl::identity<StateType>::type
>::type type;
};
template <class StateType,class ContainingSM>
struct make_entry
{
typedef typename ::boost::mpl::if_<
typename is_pseudo_entry<StateType>::type ,
typename ContainingSM::template entry_pt<StateType>,
typename ::boost::mpl::if_<
typename is_direct_entry<StateType>::type,
typename ContainingSM::template direct<StateType>,
typename ::boost::mpl::identity<StateType>::type
>::type
>::type type;
};
// metafunction used to say if a SM has pseudo exit states
template <class StateType>
struct has_exit_pseudo_states_helper
{
typedef typename StateType::stt Stt;
typedef typename generate_state_set<Stt>::type state_list;
typedef ::boost::mpl::bool_< ::boost::mpl::count_if<
state_list,is_pseudo_exit< ::boost::mpl::placeholders::_1> >::value != 0> type;
};
template <class StateType>
struct has_exit_pseudo_states
{
typedef typename ::boost::mpl::eval_if<typename is_composite_state<StateType>::type,
has_exit_pseudo_states_helper<StateType>,
::boost::mpl::bool_<false> >::type type;
};
template <class StateType>
struct is_state_blocking
{
typedef typename ::boost::mpl::fold<
typename StateType::flag_list, ::boost::mpl::set<>,
::boost::mpl::if_<
has_event_blocking_flag< ::boost::mpl::placeholders::_2>,
::boost::mpl::insert< ::boost::mpl::placeholders::_1, ::boost::mpl::placeholders::_2 >,
::boost::mpl::placeholders::_1 >
>::type blocking_flags;
typedef typename ::boost::mpl::if_<
::boost::mpl::empty<blocking_flags>,
::boost::mpl::bool_<false>,
::boost::mpl::bool_<true> >::type type;
};
// returns a mpl::bool_<true> if fsm has an event blocking flag in one of its substates
template <class StateType>
struct has_fsm_blocking_states
{
typedef typename create_stt<StateType>::type Stt;
typedef typename generate_state_set<Stt>::type state_list;
typedef typename ::boost::mpl::fold<
state_list, ::boost::mpl::set<>,
::boost::mpl::if_<
is_state_blocking< ::boost::mpl::placeholders::_2>,
::boost::mpl::insert< ::boost::mpl::placeholders::_1, ::boost::mpl::placeholders::_2 >,
::boost::mpl::placeholders::_1 >
>::type blocking_states;
typedef typename ::boost::mpl::if_<
::boost::mpl::empty<blocking_states>,
::boost::mpl::bool_<false>,
::boost::mpl::bool_<true> >::type type;
};
template <class StateType>
struct is_no_exception_thrown
{
typedef ::boost::mpl::bool_< ::boost::mpl::count_if<
typename StateType::configuration,
has_no_exception_thrown< ::boost::mpl::placeholders::_1 > >::value != 0> found;
typedef typename ::boost::mpl::or_<
typename has_no_exception_thrown<StateType>::type,
found
>::type type;
};
template <class StateType>
struct is_no_message_queue
{
typedef ::boost::mpl::bool_< ::boost::mpl::count_if<
typename StateType::configuration,
has_no_message_queue< ::boost::mpl::placeholders::_1 > >::value != 0> found;
typedef typename ::boost::mpl::or_<
typename has_no_message_queue<StateType>::type,
found
>::type type;
};
template <class StateType>
struct is_active_state_switch_policy
{
typedef ::boost::mpl::bool_< ::boost::mpl::count_if<
typename StateType::configuration,
has_active_state_switch_policy< ::boost::mpl::placeholders::_1 > >::value != 0> found;
typedef typename ::boost::mpl::or_<
typename has_active_state_switch_policy<StateType>::type,
found
>::type type;
};
template <class StateType>
struct get_initial_event
{
typedef typename StateType::initial_event type;
};
template <class StateType>
struct get_final_event
{
typedef typename StateType::final_event type;
};
template <class TransitionTable, class InitState>
struct build_one_orthogonal_region
{
template<typename Row>
struct row_to_incidence :
::boost::mpl::vector<
::boost::mpl::pair<
typename Row::next_state_type,
typename Row::transition_event>,
typename Row::current_state_type,
typename Row::next_state_type
> {};
template <class Seq, class Elt>
struct transition_incidence_list_helper
{
typedef typename ::boost::mpl::push_back< Seq, row_to_incidence< Elt > >::type type;
};
typedef typename ::boost::mpl::fold<
TransitionTable,
::boost::mpl::vector<>,
transition_incidence_list_helper< ::boost::mpl::placeholders::_1, ::boost::mpl::placeholders::_2>
>::type transition_incidence_list;
typedef ::boost::msm::mpl_graph::incidence_list_graph<transition_incidence_list>
transition_graph;
struct preordering_dfs_visitor :
::boost::msm::mpl_graph::dfs_default_visitor_operations
{
template<typename Node, typename Graph, typename State>
struct discover_vertex :
::boost::mpl::insert<State, Node>
{};
};
typedef typename mpl::first<
typename ::boost::msm::mpl_graph::depth_first_search<
transition_graph,
preordering_dfs_visitor,
::boost::mpl::set<>,
InitState
>::type
>::type type;
};
template <class Fsm>
struct find_entry_states
{
typedef typename ::boost::mpl::copy<
typename Fsm::substate_list,
::boost::mpl::inserter<
::boost::mpl::set0<>,
::boost::mpl::if_<
has_explicit_entry_state< ::boost::mpl::placeholders::_2 >,
::boost::mpl::insert< ::boost::mpl::placeholders::_1, ::boost::mpl::placeholders::_2>,
::boost::mpl::placeholders::_1
>
>
>::type type;
};
template <class Set1, class Set2>
struct is_common_element
{
typedef typename ::boost::mpl::fold<
Set1, ::boost::mpl::false_,
::boost::mpl::if_<
::boost::mpl::has_key<
Set2,
::boost::mpl::placeholders::_2
>,
::boost::mpl::true_,
::boost::mpl::placeholders::_1
>
>::type type;
};
template <class EntryRegion, class AllRegions>
struct add_entry_region
{
typedef typename ::boost::mpl::transform<
AllRegions,
::boost::mpl::if_<
is_common_element<EntryRegion, ::boost::mpl::placeholders::_1>,
set_insert_range< ::boost::mpl::placeholders::_1, EntryRegion>,
::boost::mpl::placeholders::_1
>
>::type type;
};
// build a vector of regions states (as a set)
// one set of states for every region
template <class Fsm, class InitStates>
struct build_orthogonal_regions
{
typedef typename
::boost::mpl::fold<
InitStates, ::boost::mpl::vector0<>,
::boost::mpl::push_back<
::boost::mpl::placeholders::_1,
build_one_orthogonal_region< typename Fsm::stt, ::boost::mpl::placeholders::_2 > >
>::type without_entries;
typedef typename
::boost::mpl::fold<
typename find_entry_states<Fsm>::type, ::boost::mpl::vector0<>,
::boost::mpl::push_back<
::boost::mpl::placeholders::_1,
build_one_orthogonal_region< typename Fsm::stt, ::boost::mpl::placeholders::_2 > >
>::type only_entries;
typedef typename ::boost::mpl::fold<
only_entries , without_entries,
add_entry_region< ::boost::mpl::placeholders::_2, ::boost::mpl::placeholders::_1>
>::type type;
};
template <class GraphAsSeqOfSets, class StateType>
struct find_region_index
{
typedef typename
::boost::mpl::fold<
GraphAsSeqOfSets, ::boost::mpl::pair< ::boost::mpl::int_< -1 > /*res*/, ::boost::mpl::int_<0> /*counter*/ >,
::boost::mpl::if_<
::boost::mpl::has_key< ::boost::mpl::placeholders::_2, StateType >,
::boost::mpl::pair<
::boost::mpl::second< ::boost::mpl::placeholders::_1 >,
::boost::mpl::next< ::boost::mpl::second< ::boost::mpl::placeholders::_1 > >
>,
::boost::mpl::pair<
::boost::mpl::first< ::boost::mpl::placeholders::_1 >,
::boost::mpl::next< ::boost::mpl::second< ::boost::mpl::placeholders::_1 > >
>
>
>::type result_pair;
typedef typename ::boost::mpl::first<result_pair>::type type;
enum {value = type::value};
};
template <class Fsm>
struct check_regions_orthogonality
{
typedef typename build_orthogonal_regions< Fsm,typename Fsm::initial_states>::type regions;
typedef typename ::boost::mpl::fold<
regions, ::boost::mpl::int_<0>,
::boost::mpl::plus< ::boost::mpl::placeholders::_1 , ::boost::mpl::size< ::boost::mpl::placeholders::_2> >
>::type number_of_states_in_regions;
typedef typename ::boost::mpl::fold<
regions,mpl::set0<>,
set_insert_range<
::boost::mpl::placeholders::_1,
::boost::mpl::placeholders::_2 >
>::type one_big_states_set;
enum {states_in_regions_raw = number_of_states_in_regions::value};
enum {cumulated_states_in_regions_raw = ::boost::mpl::size<one_big_states_set>::value};
};
template <class Fsm>
struct check_no_unreachable_state
{
typedef typename check_regions_orthogonality<Fsm>::one_big_states_set states_in_regions;
typedef typename set_insert_range<
states_in_regions,
typename ::boost::mpl::eval_if<
typename has_explicit_creation<Fsm>::type,
get_explicit_creation<Fsm>,
::boost::mpl::vector0<>
>::type
>::type with_explicit_creation;
enum {states_in_fsm = ::boost::mpl::size< typename Fsm::substate_list >::value};
enum {cumulated_states_in_regions = ::boost::mpl::size< with_explicit_creation >::value};
};
// helper to find out if a SM has an active exit state and is therefore waiting for exiting
template <class StateType,class OwnerFct,class FSM>
inline
typename ::boost::enable_if<typename ::boost::mpl::and_<typename is_composite_state<FSM>::type,
typename is_pseudo_exit<StateType>::type>,bool >::type
is_exit_state_active(FSM& fsm)
{
typedef typename OwnerFct::type Composite;
//typedef typename create_stt<Composite>::type stt;
typedef typename Composite::stt stt;
int state_id = get_state_id<stt,StateType>::type::value;
Composite& comp = fsm.template get_state<Composite&>();
return (std::find(comp.current_state(),comp.current_state()+Composite::nr_regions::value,state_id)
!=comp.current_state()+Composite::nr_regions::value);
}
template <class StateType,class OwnerFct,class FSM>
inline
typename ::boost::disable_if<typename ::boost::mpl::and_<typename is_composite_state<FSM>::type,
typename is_pseudo_exit<StateType>::type>,bool >::type
is_exit_state_active(FSM&)
{
return false;
}
} } }//boost::msm::back
#endif // BOOST_MSM_BACK_METAFUNCTIONS_H

View File

@@ -0,0 +1,48 @@
// Copyright 2008 Christophe Henry
// henry UNDERSCORE christophe AT hotmail DOT com
// This is an extended version of the state machine available in the boost::mpl library
// Distributed under the same license as the original.
// Copyright for the original version:
// Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
// under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_MSM_BACK_MPL_GRAPH_FSM_CHECK_H
#define BOOST_MSM_BACK_MPL_GRAPH_FSM_CHECK_H
#include <boost/mpl/assert.hpp>
#include <boost/msm/back/metafunctions.hpp>
namespace boost { namespace msm { namespace back
{
struct mpl_graph_fsm_check
{
typedef int fsm_check;
// checks that regions are truly orthogonal (one state belongs to 1 region)
// using the mpl_graph library (part of metagraph)
template <class Fsm>
static void check_orthogonality()
{
BOOST_MPL_ASSERT_RELATION( ::boost::msm::back::check_regions_orthogonality<Fsm>::states_in_regions_raw,
==,
::boost::msm::back::check_regions_orthogonality<Fsm>::cumulated_states_in_regions_raw );
}
// checks that all states are reachable or created using the explicit_creation typedef
// using the mpl_graph library (part of metagraph)
template <class Fsm>
static void check_unreachable_states()
{
BOOST_MPL_ASSERT_RELATION( ::boost::msm::back::check_no_unreachable_state<Fsm>::states_in_fsm,
==,
::boost::msm::back::check_no_unreachable_state<Fsm>::cumulated_states_in_regions );
}
};
} } }//boost::msm::back
#endif //BOOST_MSM_BACK_MPL_GRAPH_FSM_CHECK_H

View File

@@ -0,0 +1,37 @@
// Copyright 2008 Christophe Henry
// henry UNDERSCORE christophe AT hotmail DOT com
// This is an extended version of the state machine available in the boost::mpl library
// Distributed under the same license as the original.
// Copyright for the original version:
// Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
// under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_MSM_BACK_NO_FSM_CHECK_H
#define BOOST_MSM_BACK_NO_FSM_CHECK_H
#include <boost/mpl/assert.hpp>
#include <boost/msm/back/metafunctions.hpp>
namespace boost { namespace msm { namespace back
{
struct no_fsm_check
{
typedef int fsm_check;
// no fsm structure checking
template <class Fsm>
static void check_orthogonality()
{
}
template <class Fsm>
static void check_unreachable_states()
{
}
};
} } }//boost::msm::back
#endif //BOOST_MSM_BACK_NO_FSM_CHECK_H

View File

@@ -0,0 +1,32 @@
// Copyright 2008 Christophe Henry
// henry UNDERSCORE christophe AT hotmail DOT com
// This is an extended version of the state machine available in the boost::mpl library
// Distributed under the same license as the original.
// Copyright for the original version:
// Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
// under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_MSM_BACK_QUEUE_CONTAINER_CIRCULAR_H
#define BOOST_MSM_BACK_QUEUE_CONTAINER_CIRCULAR_H
#include <boost/circular_buffer.hpp>
namespace boost { namespace msm { namespace back
{
struct queue_container_circular
{
typedef int queue_container_policy;
template <class Element>
struct In
{
typedef typename boost::circular_buffer<Element> type;
};
};
} } }//boost::msm::back
#endif //BOOST_MSM_BACK_QUEUE_CONTAINER_CIRCULAR_H

View File

@@ -0,0 +1,32 @@
// Copyright 2008 Christophe Henry
// henry UNDERSCORE christophe AT hotmail DOT com
// This is an extended version of the state machine available in the boost::mpl library
// Distributed under the same license as the original.
// Copyright for the original version:
// Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
// under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_MSM_BACK_QUEUE_CONTAINER_DEQUE_H
#define BOOST_MSM_BACK_QUEUE_CONTAINER_DEQUE_H
#include <deque>
namespace boost { namespace msm { namespace back
{
struct queue_container_deque
{
typedef int queue_container_policy;
template <class Element>
struct In
{
typedef typename std::deque<Element> type;
};
};
} } }//boost::msm::back
#endif //BOOST_MSM_BACK_QUEUE_CONTAINER_DEQUE_H

File diff suppressed because it is too large Load Diff

68
test/external/boost/msm/back/tools.hpp vendored Normal file
View File

@@ -0,0 +1,68 @@
// Copyright 2008 Christophe Henry
// henry UNDERSCORE christophe AT hotmail DOT com
// This is an extended version of the state machine available in the boost::mpl library
// Distributed under the same license as the original.
// Copyright for the original version:
// Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
// under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_MSM_BACK_TOOLS_H
#define BOOST_MSM_BACK_TOOLS_H
#include <string>
#include <iostream>
#include <boost/msm/back/common_types.hpp>
#include <boost/msm/back/metafunctions.hpp>
namespace boost { namespace msm { namespace back
{
// fills the array passed in with the state names in the correct order
// the array must be big enough. To know the needed size, use mpl::size
// on fsm::generate_state_set
template <class stt>
struct fill_state_names
{
fill_state_names(char const** names):m_names(names){}
template <class StateType>
void operator()(boost::msm::wrap<StateType> const&)
{
m_names[get_state_id<stt,StateType>::value]= typeid(StateType).name();
}
private:
char const** m_names;
};
// fills the typeid-generated name of the given state in the string passed as argument
template <class stt>
struct get_state_name
{
get_state_name(std::string& name_to_fill, int state_id):m_name(name_to_fill),m_state_id(state_id){}
template <class StateType>
void operator()(boost::msm::wrap<StateType> const&)
{
if (get_state_id<stt,StateType>::value == m_state_id)
{
m_name = typeid(StateType).name();
}
}
private:
std::string& m_name;
int m_state_id;
};
// displays the typeid of the given Type
struct display_type
{
template <class Type>
void operator()(boost::msm::wrap<Type> const&)
{
std::cout << typeid(Type).name() << std::endl;
}
};
} } }//boost::msm::back
#endif //BOOST_MSM_BACK_TOOLS_H