/usr/include/boost/msm/back
Edit: /usr/include/boost/msm/back/metafunctions.hpp (35629B)
// 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
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
// mpl_graph graph implementation and depth first search
#include
#include
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
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
struct transition_source_type
{
typedef typename Transition::current_state_type type;
};
// returns the target state type of a transition
template
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
struct make_pair_source_state_id
{
typedef typename ::boost::mpl::pair type;
};
template
struct make_pair_target_state_id
{
typedef typename ::boost::mpl::pair 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
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,
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 >
>
> //pair
>::type source_state_ids;
typedef typename ::boost::mpl::first::type source_state_map;
typedef typename ::boost::mpl::second::type highest_state_id;
typedef typename
::boost::mpl::fold<
stt,::boost::mpl::pair,
::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::type type;
};
template
struct get_active_state_switch_policy_helper
{
typedef typename Fsm::active_state_switch_policy type;
};
template
struct get_active_state_switch_policy_helper2
{
typedef typename boost::mpl::deref::type Fsm;
typedef typename Fsm::active_state_switch_policy type;
};
// returns the active state switching policy
template
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::type
>::type,
get_active_state_switch_policy_helper,
get_active_state_switch_policy_helper2< iter >
>::type type;
};
// returns the id of a given state
template
struct get_state_id
{
typedef typename ::boost::mpl::at::type,State>::type type;
enum {value = type::value};
};
// returns a mpl::vector containing the init states of a state machine
template
struct get_initial_states
{
typedef typename ::boost::mpl::if_<
::boost::mpl::is_sequence,
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
struct get_number_of_regions
{
typedef typename mpl::if_<
::boost::mpl::is_sequence,
::boost::mpl::size,
::boost::mpl::int_<1> >::type type;
};
// builds a mpl::vector of initial states
//TODO remove duplicate from get_initial_states
template
struct get_regions_as_sequence
{
typedef typename ::boost::mpl::if_<
::boost::mpl::is_sequence,
region,
typename ::boost::mpl::push_back< ::boost::mpl::vector0<>,region>::type >::type type;
};
template
struct get_explicit_creation_as_sequence
{
typedef typename ::boost::mpl::if_<
::boost::mpl::is_sequence,
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
struct have_same_source
{
enum {current_state1 = get_state_id::type::value};
enum {current_state2 = get_state_id::type::value};
enum {value = ((int)current_state1 == (int)current_state2) };
};
// A metafunction that returns the Event associated with a transition.
template
struct transition_event
{
typedef typename Transition::transition_event type;
};
// returns true for composite states
template
struct is_composite_state
{
enum {value = has_composite_tag::type::value};
typedef typename has_composite_tag::type type;
};
// transform a transition table in a container of source states
template
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
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
struct generate_state_set
{
// keep in the original transition table only the source/target state types
typedef typename keep_source_names::type sources;
typedef typename keep_target_names::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
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_ if State has Event as deferred event
template
struct has_state_delayed_event
{
typedef typename ::boost::mpl::find::type found;
typedef typename ::boost::mpl::if_<
::boost::is_same::type >,
::boost::mpl::bool_,
::boost::mpl::bool_ >::type type;
};
// returns a mpl::bool_ if State has any deferred event
template
struct has_state_delayed_events
{
typedef typename ::boost::mpl::if_<
::boost::mpl::empty,
::boost::mpl::bool_,
::boost::mpl::bool_ >::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
struct is_pseudo_entry
{
typedef typename ::boost::mpl::if_< typename has_pseudo_entry::type,
::boost::mpl::bool_,::boost::mpl::bool_
>::type type;
};
// says if a state is an exit pseudo state
template
struct is_pseudo_exit
{
typedef typename ::boost::mpl::if_< typename has_pseudo_exit::type,
::boost::mpl::bool_, ::boost::mpl::bool_
>::type type;
};
// says if a state is an entry pseudo state or an explicit entry
template
struct is_direct_entry
{
typedef typename ::boost::mpl::if_< typename has_explicit_entry_state::type,
::boost::mpl::bool_, ::boost::mpl::bool_
>::type type;
};
//converts a "fake" (simulated in a state_machine_ description )state into one which will really get created
template
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::type,
typename CompositeType::template direct,
typename ::boost::mpl::identity::type
>::type type;
};
template
struct get_explicit_creation
{
typedef typename StateType::explicit_creation type;
};
template
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
struct get_wrapped_state
{
typedef typename ::boost::mpl::eval_if<
typename has_wrapped_entry::type,
get_wrapped_entry,
::boost::mpl::identity >::type type;
};
template
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::type states;
// transform the initial region(s) in a sequence
typedef typename get_regions_as_sequence::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,
::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::type,
get_explicit_creation,
::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,
::boost::mpl::placeholders::_1,
::boost::mpl::insert< ::boost::mpl::placeholders::_1, ::boost::mpl::end,
not_a_row< get_wrapped_state< ::boost::mpl::placeholders::_2> > >
>
>::type type;
};
// returns the transition table of a Composite state
template
struct get_transition_table
{
typedef typename create_stt::type type;
};
// recursively builds an internal table including those of substates, sub-substates etc.
// variant for submachines
template
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::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
struct recursive_get_internal_transition_table
{
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
struct recursive_get_transition_table
{
// get the transition table of the state if it's a state machine
typedef typename ::boost::mpl::eval_if::type,
get_transition_table,
::boost::mpl::vector0<>
>::type org_table;
typedef typename generate_state_set::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,
recursive_get_transition_table< ::boost::mpl::placeholders::_2 > >
>::type type;
};
// metafunction used to say if a SM has pseudo exit states
template
struct has_fsm_deferred_events
{
typedef typename create_stt::type Stt;
typedef typename generate_state_set::type state_list;
typedef typename ::boost::mpl::or_<
typename has_activate_deferred_events::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_ if State has any delayed event
template
struct is_completion_event
{
typedef typename ::boost::mpl::if_<
has_completion_event,
::boost::mpl::bool_,
::boost::mpl::bool_ >::type type;
};
// metafunction used to say if a SM has eventless transitions
template
struct has_fsm_eventless_transition
{
typedef typename create_stt::type Stt;
typedef typename generate_event_set::type event_list;
typedef ::boost::mpl::bool_< ::boost::mpl::count_if<
event_list,is_completion_event< ::boost::mpl::placeholders::_1 > >::value != 0> type;
};
template
struct find_completion_events
{
typedef typename create_stt::type Stt;
typedef typename generate_event_set::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
struct make_vector
{
typedef ::boost::mpl::vector type;
};
template< typename Entry >
struct get_first_element_pair_second
{
typedef typename ::boost::mpl::front::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
struct get_owner
{
typedef typename ::boost::mpl::if_<
typename ::boost::mpl::not_::type>::type,
typename State::owner,
State >::type type;
};
template
struct get_fork_owner
{
typedef typename ::boost::mpl::front::type seq_front;
typedef typename ::boost::mpl::if_<
typename ::boost::mpl::not_<
typename ::boost::is_same::type>::type,
typename seq_front::owner,
seq_front >::type type;
};
template
struct make_exit
{
typedef typename ::boost::mpl::if_<
typename is_pseudo_exit::type ,
typename ContainingSM::template exit_pt,
typename ::boost::mpl::identity::type
>::type type;
};
template
struct make_entry
{
typedef typename ::boost::mpl::if_<
typename is_pseudo_entry::type ,
typename ContainingSM::template entry_pt,
typename ::boost::mpl::if_<
typename is_direct_entry::type,
typename ContainingSM::template direct,
typename ::boost::mpl::identity::type
>::type
>::type type;
};
// metafunction used to say if a SM has pseudo exit states
template
struct has_exit_pseudo_states_helper
{
typedef typename StateType::stt Stt;
typedef typename generate_state_set::type state_list;
typedef ::boost::mpl::bool_< ::boost::mpl::count_if<
state_list,is_pseudo_exit< ::boost::mpl::placeholders::_1> >::value != 0> type;
};
template
struct has_exit_pseudo_states
{
typedef typename ::boost::mpl::eval_if::type,
has_exit_pseudo_states_helper,
::boost::mpl::bool_ >::type type;
};
// builds flags (add internal_flag_list and flag_list). internal_flag_list is used for terminate/interrupt states
template
struct get_flag_list
{
typedef typename ::boost::mpl::insert_range<
typename StateType::flag_list,
typename ::boost::mpl::end< typename StateType::flag_list >::type,
typename StateType::internal_flag_list
>::type type;
};
template
struct is_state_blocking
{
typedef typename ::boost::mpl::fold<
typename get_flag_list::type, ::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,
::boost::mpl::bool_,
::boost::mpl::bool_ >::type type;
};
// returns a mpl::bool_ if fsm has an event blocking flag in one of its substates
template
struct has_fsm_blocking_states
{
typedef typename create_stt::type Stt;
typedef typename generate_state_set::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,
::boost::mpl::bool_,
::boost::mpl::bool_ >::type type;
};
template
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::type,
found
>::type type;
};
template
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::type,
found
>::type type;
};
template
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::type,
found
>::type type;
};
template
struct get_initial_event
{
typedef typename StateType::initial_event type;
};
template
struct get_final_event
{
typedef typename StateType::final_event type;
};
template
struct build_one_orthogonal_region
{
template
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
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_graph;
struct preordering_dfs_visitor :
::boost::msm::mpl_graph::dfs_default_visitor_operations
{
template
struct discover_vertex :
::boost::mpl::insert
{};
};
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
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
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
struct add_entry_region
{
typedef typename ::boost::mpl::transform<
AllRegions,
::boost::mpl::if_<
is_common_element,
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
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::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
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::type type;
enum {value = type::value};
};
template
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::value};
};
template
struct check_no_unreachable_state
{
typedef typename check_regions_orthogonality::one_big_states_set states_in_regions;
typedef typename set_insert_range<
states_in_regions,
typename ::boost::mpl::eval_if<
typename has_explicit_creation::type,
get_explicit_creation,
::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
inline
typename ::boost::enable_if::type,
typename is_pseudo_exit::type>,bool >::type
is_exit_state_active(FSM& fsm)
{
typedef typename OwnerFct::type Composite;
//typedef typename create_stt::type stt;
typedef typename Composite::stt stt;
int state_id = get_state_id::type::value;
Composite& comp = fsm.template get_state();
return (std::find(comp.current_state(),comp.current_state()+Composite::nr_regions::value,state_id)
!=comp.current_state()+Composite::nr_regions::value);
}
template
inline
typename ::boost::disable_if::type,
typename is_pseudo_exit::type>,bool >::type
is_exit_state_active(FSM&)
{
return false;
}
// transformation metafunction to end interrupt flags
template
struct transform_to_end_interrupt
{
typedef boost::msm::EndInterruptFlag type;
};
// transform a sequence of events into another one of EndInterruptFlag
template
struct apply_end_interrupt_flag
{
typedef typename
::boost::mpl::transform<
Events,transform_to_end_interrupt< ::boost::mpl::placeholders::_1> >::type type;
};
// returns a mpl vector containing all end interrupt events if sequence, otherwise the same event
template
struct get_interrupt_events
{
typedef typename ::boost::mpl::eval_if<
::boost::mpl::is_sequence,
boost::msm::back::apply_end_interrupt_flag,
boost::mpl::vector1 > >::type type;
};
template
struct build_interrupt_state_flag_list
{
typedef ::boost::mpl::vector first_part;
typedef typename ::boost::mpl::insert_range<
first_part,
typename ::boost::mpl::end< first_part >::type,
Events
>::type type;
};
} } }//boost::msm::back
#endif // BOOST_MSM_BACK_METAFUNCTIONS_H