| 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_tnamespace 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#endiftemplate< 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
 |