123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998 |
- #ifndef BOOST_STATECHART_SIMPLE_STATE_HPP_INCLUDED
- #define BOOST_STATECHART_SIMPLE_STATE_HPP_INCLUDED
- //////////////////////////////////////////////////////////////////////////////
- // Copyright 2002-2010 Andreas Huber Doenni
- // Distributed under the Boost Software License, Version 1.0. (See accompany-
- // ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- //////////////////////////////////////////////////////////////////////////////
- #include <boost/statechart/event.hpp>
- #include <boost/statechart/detail/leaf_state.hpp>
- #include <boost/statechart/detail/node_state.hpp>
- #include <boost/statechart/detail/constructor.hpp>
- #include <boost/statechart/detail/memory.hpp>
- #include <boost/mpl/eval_if.hpp>
- #include <boost/mpl/if.hpp>
- #include <boost/mpl/identity.hpp>
- #include <boost/mpl/is_sequence.hpp>
- #include <boost/mpl/list.hpp>
- #include <boost/mpl/empty.hpp>
- #include <boost/mpl/size.hpp>
- #include <boost/mpl/front.hpp>
- #include <boost/mpl/at.hpp>
- #include <boost/mpl/find.hpp>
- #include <boost/mpl/find_if.hpp>
- #include <boost/mpl/contains.hpp>
- #include <boost/mpl/distance.hpp>
- #include <boost/mpl/deref.hpp>
- #include <boost/mpl/pop_front.hpp>
- #include <boost/mpl/push_front.hpp>
- #include <boost/mpl/clear.hpp>
- #include <boost/mpl/placeholders.hpp>
- #include <boost/mpl/bool.hpp>
- #include <boost/mpl/integral_c.hpp>
- #include <boost/mpl/less.hpp>
- #include <boost/mpl/equal_to.hpp>
- #include <boost/mpl/not.hpp>
- #include <boost/mpl/or.hpp>
- #include <boost/mpl/plus.hpp>
- #include <boost/mpl/max_element.hpp>
- #include <boost/mpl/greater.hpp>
- #include <boost/get_pointer.hpp>
- #include <boost/intrusive_ptr.hpp>
- #include <boost/assert.hpp>
- #include <boost/type_traits/is_base_of.hpp>
- #include <boost/type_traits/is_same.hpp>
- #include <boost/static_assert.hpp>
- #include <boost/polymorphic_cast.hpp> // boost::polymorphic_downcast
- #include <cstddef> // std::size_t
- namespace boost
- {
- namespace statechart
- {
- namespace detail
- {
- //////////////////////////////////////////////////////////////////////////////
- template< class T >
- struct make_list : public mpl::eval_if<
- mpl::is_sequence< T >,
- mpl::identity< T >,
- mpl::identity< mpl::list< T > > > {};
- //////////////////////////////////////////////////////////////////////////////
- template< class MostDerived, class Context, class InnerInitial >
- struct simple_state_base_type
- {
- private:
- typedef typename Context::outermost_context_base_type::allocator_type
- allocator_type;
- typedef typename Context::outermost_context_base_type::rtti_policy_type
- rtti_policy_type;
- typedef typename detail::make_list< InnerInitial >::type
- inner_initial_list;
- typedef typename mpl::size< inner_initial_list >::type
- inner_initial_list_size;
- public:
- typedef typename mpl::eval_if<
- mpl::empty< inner_initial_list >,
- mpl::identity< typename rtti_policy_type::
- template rtti_derived_type< MostDerived, leaf_state<
- allocator_type,
- rtti_policy_type > > >,
- mpl::identity< typename rtti_policy_type::
- template rtti_derived_type< MostDerived, node_state<
- inner_initial_list_size,
- allocator_type,
- rtti_policy_type > > > >::type type;
- };
- //////////////////////////////////////////////////////////////////////////////
- struct no_transition_function
- {
- template< class CommonContext >
- void operator()( CommonContext & ) const {}
- };
- template< class TransitionContext, class Event >
- class transition_function
- {
- public:
- transition_function(
- void ( TransitionContext::*pTransitionAction )( const Event & ),
- const Event & evt
- ) :
- pTransitionAction_( pTransitionAction ),
- evt_( evt )
- {
- }
- template< class CommonContext >
- void operator()( CommonContext & commonContext ) const
- {
- ( commonContext.template context< TransitionContext >()
- .*pTransitionAction_ )( evt_ );
- }
- private:
- // avoids C4512 (assignment operator could not be generated)
- transition_function & operator=( const transition_function & );
- void ( TransitionContext::*pTransitionAction_ )( const Event & );
- const Event & evt_;
- };
- template< bool contextHasInheritedDeepHistory, bool contextHasDeepHistory >
- struct deep_history_storer
- {
- template< class HistorizedState, class LeafState, class Context >
- static void store_deep_history( Context & ) {}
- };
- template<>
- struct deep_history_storer< true, false >
- {
- template< class HistorizedState, class LeafState, class Context >
- static void store_deep_history( Context & ctx )
- {
- ctx.template store_deep_history_impl< LeafState >();
- }
- };
- template<>
- struct deep_history_storer< true, true >
- {
- template< class HistorizedState, class LeafState, class Context >
- static void store_deep_history( Context & ctx )
- {
- ctx.outermost_context_base().template store_deep_history<
- HistorizedState, LeafState >();
- ctx.template store_deep_history_impl< LeafState >();
- }
- };
- } // namespace detail
- //////////////////////////////////////////////////////////////////////////////
- enum history_mode
- {
- has_no_history,
- has_shallow_history,
- has_deep_history,
- has_full_history // shallow & deep
- };
- //////////////////////////////////////////////////////////////////////////////
- template< class MostDerived,
- class Context,
- class InnerInitial = mpl::list<>,
- history_mode historyMode = has_no_history >
- class simple_state : public detail::simple_state_base_type< MostDerived,
- typename Context::inner_context_type, InnerInitial >::type
- {
- typedef typename detail::simple_state_base_type<
- MostDerived, typename Context::inner_context_type,
- InnerInitial >::type base_type;
- public:
- //////////////////////////////////////////////////////////////////////////
- typedef mpl::list<> reactions;
- typedef typename Context::inner_context_type context_type;
- template< detail::orthogonal_position_type innerOrthogonalPosition >
- struct orthogonal
- {
- typedef mpl::integral_c<
- detail::orthogonal_position_type,
- innerOrthogonalPosition > inner_orthogonal_position;
- typedef MostDerived inner_context_type;
- };
- typedef typename context_type::outermost_context_type
- outermost_context_type;
- outermost_context_type & outermost_context()
- {
- // This assert fails when an attempt is made to access the state machine
- // from a constructor of a state that is *not* a subtype of state<>.
- // To correct this, derive from state<> instead of simple_state<>.
- BOOST_ASSERT( get_pointer( pContext_ ) != 0 );
- return pContext_->outermost_context();
- }
- const outermost_context_type & outermost_context() const
- {
- // This assert fails when an attempt is made to access the state machine
- // from a constructor of a state that is *not* a subtype of state<>.
- // To correct this, derive from state<> instead of simple_state<>.
- BOOST_ASSERT( get_pointer( pContext_ ) != 0 );
- return pContext_->outermost_context();
- }
- template< class OtherContext >
- OtherContext & context()
- {
- typedef typename mpl::if_<
- is_base_of< OtherContext, MostDerived >,
- context_impl_this_context,
- context_impl_other_context
- >::type impl;
- return impl::template context_impl< OtherContext >( *this );
- }
- template< class OtherContext >
- const OtherContext & context() const
- {
- typedef typename mpl::if_<
- is_base_of< OtherContext, MostDerived >,
- context_impl_this_context,
- context_impl_other_context
- >::type impl;
- return impl::template context_impl< OtherContext >( *this );
- }
- template< class Target >
- Target state_cast() const
- {
- return outermost_context_base().template state_cast< Target >();
- }
- template< class Target >
- Target state_downcast() const
- {
- return outermost_context_base().template state_downcast< Target >();
- }
- typedef typename context_type::state_base_type state_base_type;
- typedef typename context_type::state_iterator state_iterator;
- state_iterator state_begin() const
- {
- return outermost_context_base().state_begin();
- }
- state_iterator state_end() const
- {
- return outermost_context_base().state_end();
- }
- typedef typename context_type::event_base_ptr_type event_base_ptr_type;
- void post_event( const event_base_ptr_type & pEvent )
- {
- outermost_context_base().post_event_impl( pEvent );
- }
- void post_event( const event_base & evt )
- {
- outermost_context_base().post_event_impl( evt );
- }
- result discard_event()
- {
- return detail::result_utility::make_result( detail::do_discard_event );
- }
- result forward_event()
- {
- return detail::result_utility::make_result( detail::do_forward_event );
- }
- result defer_event()
- {
- this->state_base_type::defer_event();
- return detail::result_utility::make_result( detail::do_defer_event );
- }
- template< class DestinationState >
- result transit()
- {
- return transit_impl< DestinationState, outermost_context_type >(
- detail::no_transition_function() );
- }
- template< class DestinationState, class TransitionContext, class Event >
- result transit(
- void ( TransitionContext::*pTransitionAction )( const Event & ),
- const Event & evt )
- {
- return transit_impl< DestinationState, TransitionContext >(
- detail::transition_function< TransitionContext, Event >(
- pTransitionAction, evt ) );
- }
- result terminate()
- {
- outermost_context_base().terminate_as_reaction( *this );
- return detail::result_utility::make_result( detail::do_discard_event );
- }
- template<
- class HistoryContext,
- detail::orthogonal_position_type orthogonalPosition >
- void clear_shallow_history()
- {
- outermost_context_base().template clear_shallow_history<
- HistoryContext, orthogonalPosition >();
- }
- template<
- class HistoryContext,
- detail::orthogonal_position_type orthogonalPosition >
- void clear_deep_history()
- {
- outermost_context_base().template clear_deep_history<
- HistoryContext, orthogonalPosition >();
- }
- const event_base * triggering_event() const
- {
- return outermost_context_base().triggering_event();
- }
- protected:
- //////////////////////////////////////////////////////////////////////////
- simple_state() : pContext_( 0 ) {}
- ~simple_state()
- {
- // As a result of a throwing derived class constructor, this destructor
- // can be called before the context is set.
- if ( get_pointer( pContext_ ) != 0 )
- {
- if ( this->deferred_events() )
- {
- outermost_context_base().release_events();
- }
- pContext_->remove_inner_state( orthogonal_position::value );
- }
- }
- public:
- //////////////////////////////////////////////////////////////////////////
- // The following declarations should be private.
- // They are only public because many compilers lack template friends.
- //////////////////////////////////////////////////////////////////////////
- typedef typename Context::inner_orthogonal_position orthogonal_position;
- // If you receive a
- // "use of undefined type 'boost::STATIC_ASSERTION_FAILURE<x>'" or similar
- // compiler error here then either this state resides in a non-existent
- // orthogonal region of the outer state or the outer state does not have
- // inner states.
- BOOST_STATIC_ASSERT( ( mpl::less<
- orthogonal_position,
- typename context_type::no_of_orthogonal_regions >::value ) );
- typedef MostDerived inner_context_type;
- typedef mpl::integral_c< detail::orthogonal_position_type, 0 >
- inner_orthogonal_position;
- typedef typename context_type::event_base_type event_base_type;
- typedef typename context_type::rtti_policy_type rtti_policy_type;
- typedef typename context_type::outermost_context_base_type
- outermost_context_base_type;
- typedef typename context_type::inner_context_ptr_type context_ptr_type;
- typedef typename context_type::state_list_type state_list_type;
- typedef intrusive_ptr< inner_context_type > inner_context_ptr_type;
- typedef typename detail::make_list< InnerInitial >::type
- inner_initial_list;
- typedef typename mpl::size< inner_initial_list >::type
- inner_initial_list_size;
- typedef mpl::integral_c<
- detail::orthogonal_position_type,
- inner_initial_list_size::value > no_of_orthogonal_regions;
- typedef typename mpl::push_front<
- typename context_type::context_type_list,
- context_type >::type context_type_list;
- // If you receive a
- // "use of undefined type 'boost::STATIC_ASSERTION_FAILURE<x>'" or similar
- // compiler error here then the direct or indirect context of this state
- // has deep history _and_ this state has two or more orthogonal regions.
- // Boost.Statechart does not currently support deep history in a state whose
- // direct or indirect inner states have two or more orthogonal regions.
- // Please consult the documentation on how to work around this limitation.
- BOOST_STATIC_ASSERT( ( mpl::or_<
- mpl::less<
- no_of_orthogonal_regions,
- mpl::integral_c< detail::orthogonal_position_type, 2 > >,
- mpl::not_<
- typename context_type::inherited_deep_history > >::value ) );
- typedef mpl::bool_< ( historyMode & has_shallow_history ) != 0 >
- shallow_history;
- typedef typename context_type::shallow_history stores_shallow_history;
- typedef mpl::bool_< ( historyMode & has_deep_history ) != 0 >
- deep_history;
- typedef typename mpl::or_<
- deep_history,
- typename context_type::inherited_deep_history
- >::type inherited_deep_history;
- typedef typename mpl::and_<
- inherited_deep_history,
- mpl::empty< inner_initial_list > >::type stores_deep_history;
- void * operator new( std::size_t size )
- {
- return detail::allocate< MostDerived,
- typename outermost_context_type::allocator_type >( size );
- }
- void operator delete( void * pState )
- {
- detail::deallocate< MostDerived,
- typename outermost_context_type::allocator_type >( pState );
- }
- outermost_context_base_type & outermost_context_base()
- {
- // This assert fails when an attempt is made to access the state machine
- // from a constructor of a state that is *not* a subtype of state<>.
- // To correct this, derive from state<> instead of simple_state<>.
- BOOST_ASSERT( get_pointer( pContext_ ) != 0 );
- return pContext_->outermost_context_base();
- }
- const outermost_context_base_type & outermost_context_base() const
- {
- // This assert fails when an attempt is made to access the state machine
- // from a constructor of a state that is *not* a subtype of state<>.
- // To correct this, derive from state<> instead of simple_state<>.
- BOOST_ASSERT( get_pointer( pContext_ ) != 0 );
- return pContext_->outermost_context_base();
- }
- virtual const state_base_type * outer_state_ptr() const
- {
- typedef typename mpl::if_<
- is_same< outermost_context_type, context_type >,
- outer_state_ptr_impl_outermost,
- outer_state_ptr_impl_non_outermost
- >::type impl;
- return impl::outer_state_ptr_impl( *this );
- }
- virtual detail::reaction_result react_impl(
- const event_base_type & evt,
- typename rtti_policy_type::id_type eventType )
- {
- typedef typename detail::make_list<
- typename MostDerived::reactions >::type reaction_list;
- detail::reaction_result reactionResult =
- local_react< reaction_list >( evt, eventType );
- // At this point we can only safely access pContext_ if the handler did
- // not return do_discard_event!
- if ( reactionResult == detail::do_forward_event )
- {
- // TODO: The following call to react_impl of our outer state should
- // be made with a context_type:: prefix to call directly instead of
- // virtually. For some reason the compiler complains...
- reactionResult = pContext_->react_impl( evt, eventType );
- }
- return reactionResult;
- }
- virtual void exit_impl(
- typename base_type::direct_state_base_ptr_type & pSelf,
- typename state_base_type::node_state_base_ptr_type &
- pOutermostUnstableState,
- bool performFullExit )
- {
- inner_context_ptr_type pMostDerivedSelf =
- polymorphic_downcast< MostDerived * >( this );
- pSelf = 0;
- exit_impl( pMostDerivedSelf, pOutermostUnstableState, performFullExit );
- }
- void exit_impl(
- inner_context_ptr_type & pSelf,
- typename state_base_type::node_state_base_ptr_type &
- pOutermostUnstableState,
- bool performFullExit )
- {
- switch ( this->ref_count() )
- {
- case 2:
- if ( get_pointer( pOutermostUnstableState ) ==
- static_cast< state_base_type * >( this ) )
- {
- pContext_->set_outermost_unstable_state(
- pOutermostUnstableState );
- BOOST_FALLTHROUGH;
- }
- else
- {
- break;
- }
- case 1:
- {
- if ( get_pointer( pOutermostUnstableState ) == 0 )
- {
- pContext_->set_outermost_unstable_state(
- pOutermostUnstableState );
- }
- if ( performFullExit )
- {
- pSelf->exit();
- check_store_shallow_history< stores_shallow_history >();
- check_store_deep_history< stores_deep_history >();
- }
- context_ptr_type pContext = pContext_;
- pSelf = 0;
- pContext->exit_impl(
- pContext, pOutermostUnstableState, performFullExit );
- break;
- }
- default:
- break;
- }
- }
- void set_outermost_unstable_state(
- typename state_base_type::node_state_base_ptr_type &
- pOutermostUnstableState )
- {
- pOutermostUnstableState = this;
- }
- template< class OtherContext >
- const typename OtherContext::inner_context_ptr_type & context_ptr() const
- {
- typedef typename mpl::if_<
- is_same< OtherContext, context_type >,
- context_ptr_impl_my_context,
- context_ptr_impl_other_context
- >::type impl;
- return impl::template context_ptr_impl< OtherContext >( *this );
- }
- static void initial_deep_construct(
- outermost_context_base_type & outermostContextBase )
- {
- deep_construct( &outermostContextBase, outermostContextBase );
- }
- static void deep_construct(
- const context_ptr_type & pContext,
- outermost_context_base_type & outermostContextBase )
- {
- const inner_context_ptr_type pInnerContext(
- shallow_construct( pContext, outermostContextBase ) );
- deep_construct_inner< inner_initial_list >(
- pInnerContext, outermostContextBase );
- }
- static inner_context_ptr_type shallow_construct(
- const context_ptr_type & pContext,
- outermost_context_base_type & outermostContextBase )
- {
- const inner_context_ptr_type pInnerContext( new MostDerived );
- pInnerContext->set_context( pContext );
- outermostContextBase.add( pInnerContext );
- return pInnerContext;
- }
- void set_context( const context_ptr_type & pContext )
- {
- BOOST_ASSERT( get_pointer( pContext ) != 0 );
- pContext_ = pContext;
- base_type::set_context(
- orthogonal_position::value, get_pointer( pContext ) );
- }
- template< class InnerList >
- static void deep_construct_inner(
- const inner_context_ptr_type & pInnerContext,
- outermost_context_base_type & outermostContextBase )
- {
- typedef typename mpl::if_<
- mpl::empty< InnerList >,
- deep_construct_inner_impl_empty,
- deep_construct_inner_impl_non_empty
- >::type impl;
- impl::template deep_construct_inner_impl< InnerList >(
- pInnerContext, outermostContextBase );
- }
- template< class LeafState >
- void store_deep_history_impl()
- {
- detail::deep_history_storer<
- context_type::inherited_deep_history::value,
- context_type::deep_history::value
- >::template store_deep_history< MostDerived, LeafState >(
- *pContext_ );
- }
- private:
- //////////////////////////////////////////////////////////////////////////
- struct context_ptr_impl_other_context
- {
- template< class OtherContext, class State >
- static const typename OtherContext::inner_context_ptr_type &
- context_ptr_impl( const State & stt )
- {
- // This assert fails when an attempt is made to access an outer
- // context from a constructor of a state that is *not* a subtype of
- // state<>. To correct this, derive from state<> instead of
- // simple_state<>.
- BOOST_ASSERT( get_pointer( stt.pContext_ ) != 0 );
- return stt.pContext_->template context_ptr< OtherContext >();
- }
- };
- friend struct context_ptr_impl_other_context;
- struct context_ptr_impl_my_context
- {
- template< class OtherContext, class State >
- static const typename OtherContext::inner_context_ptr_type &
- context_ptr_impl( const State & stt )
- {
- // This assert fails when an attempt is made to access an outer
- // context from a constructor of a state that is *not* a subtype of
- // state<>. To correct this, derive from state<> instead of
- // simple_state<>.
- BOOST_ASSERT( get_pointer( stt.pContext_ ) != 0 );
- return stt.pContext_;
- }
- };
- friend struct context_ptr_impl_my_context;
- struct context_impl_other_context
- {
- template< class OtherContext, class State >
- static OtherContext & context_impl( State & stt )
- {
- // This assert fails when an attempt is made to access an outer
- // context from a constructor of a state that is *not* a subtype of
- // state<>. To correct this, derive from state<> instead of
- // simple_state<>.
- BOOST_ASSERT( get_pointer( stt.pContext_ ) != 0 );
- return stt.pContext_->template context< OtherContext >();
- }
- };
- friend struct context_impl_other_context;
- struct context_impl_this_context
- {
- template< class OtherContext, class State >
- static OtherContext & context_impl( State & stt )
- {
- return *polymorphic_downcast< MostDerived * >( &stt );
- }
- };
- friend struct context_impl_this_context;
- template< class DestinationState,
- class TransitionContext,
- class TransitionAction >
- result transit_impl( const TransitionAction & transitionAction )
- {
- typedef typename mpl::find_if<
- context_type_list,
- mpl::contains<
- typename DestinationState::context_type_list,
- mpl::placeholders::_ > >::type common_context_iter;
- typedef typename mpl::deref< common_context_iter >::type
- common_context_type;
- typedef typename mpl::distance<
- typename mpl::begin< context_type_list >::type,
- common_context_iter >::type termination_state_position;
- typedef typename mpl::push_front< context_type_list, MostDerived >::type
- possible_transition_contexts;
- typedef typename mpl::at<
- possible_transition_contexts,
- termination_state_position >::type termination_state_type;
- termination_state_type & terminationState(
- context< termination_state_type >() );
- const typename
- common_context_type::inner_context_ptr_type pCommonContext(
- terminationState.template context_ptr< common_context_type >() );
- outermost_context_base_type & outermostContextBase(
- pCommonContext->outermost_context_base() );
- #ifdef BOOST_STATECHART_RELAX_TRANSITION_CONTEXT
- typedef typename mpl::distance<
- typename mpl::begin< possible_transition_contexts >::type,
- typename mpl::find<
- possible_transition_contexts, TransitionContext >::type
- >::type proposed_transition_context_position;
- typedef typename mpl::plus<
- termination_state_position,
- mpl::long_< 1 >
- >::type uml_transition_context_position;
- typedef typename mpl::deref< typename mpl::max_element<
- mpl::list<
- proposed_transition_context_position,
- uml_transition_context_position >,
- mpl::greater< mpl::placeholders::_, mpl::placeholders::_ >
- >::type >::type real_transition_context_position;
- typedef typename mpl::at<
- possible_transition_contexts,
- real_transition_context_position >::type real_transition_context_type;
- #ifdef BOOST_MSVC
- # pragma warning( push )
- # pragma warning( disable: 4127 ) // conditional expression is constant
- #endif
- if ( ( proposed_transition_context_position::value == 0 ) &&
- ( inner_initial_list_size::value == 0 ) )
- {
- transitionAction( *polymorphic_downcast< MostDerived * >( this ) );
- outermostContextBase.terminate_as_part_of_transit( terminationState );
- }
- else if ( proposed_transition_context_position::value >=
- uml_transition_context_position::value )
- {
- real_transition_context_type & transitionContext =
- context< real_transition_context_type >();
- outermostContextBase.terminate_as_part_of_transit( terminationState );
- transitionAction( transitionContext );
- }
- else
- {
- typename real_transition_context_type::inner_context_ptr_type
- pTransitionContext = context_ptr< real_transition_context_type >();
- outermostContextBase.terminate_as_part_of_transit(
- *pTransitionContext );
- transitionAction( *pTransitionContext );
- pTransitionContext = 0;
- outermostContextBase.terminate_as_part_of_transit( terminationState );
- }
- #ifdef BOOST_MSVC
- # pragma warning( pop )
- #endif
- #else
- outermostContextBase.terminate_as_part_of_transit( terminationState );
- transitionAction( *pCommonContext );
- #endif
- typedef typename detail::make_context_list<
- common_context_type, DestinationState >::type context_list_type;
- // If you receive a
- // "use of undefined type 'boost::STATIC_ASSERTION_FAILURE<x>'" or
- // similar compiler error here then you tried to make an invalid
- // transition between different orthogonal regions.
- BOOST_STATIC_ASSERT( ( mpl::equal_to<
- typename termination_state_type::orthogonal_position,
- typename mpl::front< context_list_type >::type::orthogonal_position
- >::value ) );
- detail::constructor<
- context_list_type, outermost_context_base_type >::construct(
- pCommonContext, outermostContextBase );
- return detail::result_utility::make_result( detail::do_discard_event );
- }
- struct local_react_impl_non_empty
- {
- template< class ReactionList, class State >
- static detail::reaction_result local_react_impl(
- State & stt,
- const event_base_type & evt,
- typename rtti_policy_type::id_type eventType )
- {
- detail::reaction_result reactionResult =
- mpl::front< ReactionList >::type::react(
- *polymorphic_downcast< MostDerived * >( &stt ),
- evt, eventType );
- if ( reactionResult == detail::no_reaction )
- {
- reactionResult = stt.template local_react<
- typename mpl::pop_front< ReactionList >::type >(
- evt, eventType );
- }
- return reactionResult;
- }
- };
- friend struct local_react_impl_non_empty;
- struct local_react_impl_empty
- {
- template< class ReactionList, class State >
- static detail::reaction_result local_react_impl(
- State &, const event_base_type &, typename rtti_policy_type::id_type )
- {
- return detail::do_forward_event;
- }
- };
- template< class ReactionList >
- detail::reaction_result local_react(
- const event_base_type & evt,
- typename rtti_policy_type::id_type eventType )
- {
- typedef typename mpl::if_<
- mpl::empty< ReactionList >,
- local_react_impl_empty,
- local_react_impl_non_empty
- >::type impl;
- return impl::template local_react_impl< ReactionList >(
- *this, evt, eventType );
- }
- struct outer_state_ptr_impl_non_outermost
- {
- template< class State >
- static const state_base_type * outer_state_ptr_impl( const State & stt )
- {
- return get_pointer( stt.pContext_ );
- }
- };
- friend struct outer_state_ptr_impl_non_outermost;
- struct outer_state_ptr_impl_outermost
- {
- template< class State >
- static const state_base_type * outer_state_ptr_impl( const State & )
- {
- return 0;
- }
- };
- struct deep_construct_inner_impl_non_empty
- {
- template< class InnerList >
- static void deep_construct_inner_impl(
- const inner_context_ptr_type & pInnerContext,
- outermost_context_base_type & outermostContextBase )
- {
- typedef typename mpl::front< InnerList >::type current_inner;
- // If you receive a
- // "use of undefined type 'boost::STATIC_ASSERTION_FAILURE<x>'" or
- // similar compiler error here then there is a mismatch between the
- // orthogonal position of a state and its position in the inner
- // initial list of its outer state.
- BOOST_STATIC_ASSERT( ( is_same<
- current_inner,
- typename mpl::at<
- typename current_inner::context_type::inner_initial_list,
- typename current_inner::orthogonal_position >::type >::value ) );
- current_inner::deep_construct( pInnerContext, outermostContextBase );
- deep_construct_inner< typename mpl::pop_front< InnerList >::type >(
- pInnerContext, outermostContextBase );
- }
- };
- struct deep_construct_inner_impl_empty
- {
- template< class InnerList >
- static void deep_construct_inner_impl(
- const inner_context_ptr_type &, outermost_context_base_type & ) {}
- };
- struct check_store_shallow_history_impl_no
- {
- template< class State >
- static void check_store_shallow_history_impl( State & ) {}
- };
- struct check_store_shallow_history_impl_yes
- {
- template< class State >
- static void check_store_shallow_history_impl( State & stt )
- {
- stt.outermost_context_base().template store_shallow_history<
- MostDerived >();
- }
- };
- friend struct check_store_shallow_history_impl_yes;
- template< class StoreShallowHistory >
- void check_store_shallow_history()
- {
- typedef typename mpl::if_<
- StoreShallowHistory,
- check_store_shallow_history_impl_yes,
- check_store_shallow_history_impl_no
- >::type impl;
- impl::check_store_shallow_history_impl( *this );
- }
- struct check_store_deep_history_impl_no
- {
- template< class State >
- static void check_store_deep_history_impl( State & ) {}
- };
- struct check_store_deep_history_impl_yes
- {
- template< class State >
- static void check_store_deep_history_impl( State & stt )
- {
- stt.template store_deep_history_impl< MostDerived >();
- }
- };
- friend struct check_store_deep_history_impl_yes;
- template< class StoreDeepHistory >
- void check_store_deep_history()
- {
- typedef typename mpl::if_<
- StoreDeepHistory,
- check_store_deep_history_impl_yes,
- check_store_deep_history_impl_no
- >::type impl;
- impl::check_store_deep_history_impl( *this );
- }
- context_ptr_type pContext_;
- };
- #ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
- } // namespace statechart
- #endif
- template< class MostDerived, class Context,
- class InnerInitial, history_mode historyMode >
- inline void intrusive_ptr_release( const ::boost::statechart::simple_state<
- MostDerived, Context, InnerInitial, historyMode > * pBase )
- {
- if ( pBase->release() )
- {
- // The cast is necessary because the simple_state destructor is non-
- // virtual (and inaccessible from this context)
- delete polymorphic_downcast< const MostDerived * >( pBase );
- }
- }
- #ifndef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
- } // namespace statechart
- #endif
- } // namespace boost
- #endif
|