Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:52:32

0001 #ifndef BOOST_STATECHART_SIMPLE_STATE_HPP_INCLUDED
0002 #define BOOST_STATECHART_SIMPLE_STATE_HPP_INCLUDED
0003 //////////////////////////////////////////////////////////////////////////////
0004 // Copyright 2002-2010 Andreas Huber Doenni
0005 // Distributed under the Boost Software License, Version 1.0. (See accompany-
0006 // ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0007 //////////////////////////////////////////////////////////////////////////////
0008 
0009 
0010 
0011 #include <boost/statechart/event.hpp>
0012 
0013 #include <boost/statechart/detail/leaf_state.hpp>
0014 #include <boost/statechart/detail/node_state.hpp>
0015 #include <boost/statechart/detail/constructor.hpp>
0016 #include <boost/statechart/detail/memory.hpp>
0017 
0018 #include <boost/mpl/eval_if.hpp>
0019 #include <boost/mpl/if.hpp>
0020 #include <boost/mpl/identity.hpp>
0021 #include <boost/mpl/is_sequence.hpp>
0022 #include <boost/mpl/list.hpp>
0023 #include <boost/mpl/empty.hpp>
0024 #include <boost/mpl/size.hpp>
0025 #include <boost/mpl/front.hpp>
0026 #include <boost/mpl/at.hpp>
0027 #include <boost/mpl/find.hpp>
0028 #include <boost/mpl/find_if.hpp>
0029 #include <boost/mpl/contains.hpp>
0030 #include <boost/mpl/distance.hpp>
0031 #include <boost/mpl/deref.hpp>
0032 #include <boost/mpl/pop_front.hpp>
0033 #include <boost/mpl/push_front.hpp>
0034 #include <boost/mpl/clear.hpp>
0035 #include <boost/mpl/placeholders.hpp>
0036 #include <boost/mpl/bool.hpp>
0037 #include <boost/mpl/integral_c.hpp>
0038 #include <boost/mpl/less.hpp>
0039 #include <boost/mpl/equal_to.hpp>
0040 #include <boost/mpl/not.hpp>
0041 #include <boost/mpl/or.hpp>
0042 
0043 #include <boost/mpl/plus.hpp>
0044 #include <boost/mpl/max_element.hpp>
0045 #include <boost/mpl/greater.hpp>
0046 
0047 #include <boost/get_pointer.hpp>
0048 #include <boost/intrusive_ptr.hpp>
0049 #include <boost/assert.hpp>
0050 #include <boost/type_traits/is_base_of.hpp>
0051 #include <boost/type_traits/is_same.hpp>
0052 #include <boost/static_assert.hpp>
0053 #include <boost/polymorphic_cast.hpp> // boost::polymorphic_downcast
0054 
0055 #include <cstddef> // std::size_t
0056 
0057 
0058 
0059 namespace boost
0060 {
0061 namespace statechart
0062 {
0063 namespace detail
0064 {
0065 
0066 
0067 
0068 //////////////////////////////////////////////////////////////////////////////
0069 template< class T >
0070 struct make_list : public mpl::eval_if<
0071   mpl::is_sequence< T >,
0072   mpl::identity< T >,
0073   mpl::identity< mpl::list< T > > > {};
0074 
0075 //////////////////////////////////////////////////////////////////////////////
0076 template< class MostDerived, class Context, class InnerInitial >
0077 struct simple_state_base_type
0078 {
0079   private:
0080     typedef typename Context::outermost_context_base_type::allocator_type
0081       allocator_type;
0082     typedef typename Context::outermost_context_base_type::rtti_policy_type
0083       rtti_policy_type;
0084     typedef typename detail::make_list< InnerInitial >::type
0085       inner_initial_list;
0086     typedef typename mpl::size< inner_initial_list >::type
0087       inner_initial_list_size;
0088 
0089   public:
0090     typedef typename mpl::eval_if<
0091       mpl::empty< inner_initial_list >,
0092       mpl::identity< typename rtti_policy_type::
0093         template rtti_derived_type< MostDerived, leaf_state<
0094           allocator_type,
0095           rtti_policy_type > > >,
0096       mpl::identity< typename rtti_policy_type::
0097         template rtti_derived_type< MostDerived, node_state<
0098           inner_initial_list_size,
0099           allocator_type,
0100           rtti_policy_type > > > >::type type;
0101 };
0102 
0103 
0104 //////////////////////////////////////////////////////////////////////////////
0105 struct no_transition_function
0106 {
0107   template< class CommonContext >
0108   void operator()( CommonContext & ) const {}
0109 };
0110 
0111 template< class TransitionContext, class Event >
0112 class transition_function
0113 {
0114   public:
0115     transition_function(
0116       void ( TransitionContext::*pTransitionAction )( const Event & ),
0117       const Event & evt
0118     ) :
0119       pTransitionAction_( pTransitionAction ),
0120       evt_( evt )
0121     {
0122     }
0123 
0124     template< class CommonContext >
0125     void operator()( CommonContext & commonContext ) const
0126     {
0127       ( commonContext.template context< TransitionContext >()
0128         .*pTransitionAction_ )( evt_ );
0129     }
0130 
0131   private:
0132     // avoids C4512 (assignment operator could not be generated)
0133     transition_function & operator=( const transition_function & );
0134 
0135     void ( TransitionContext::*pTransitionAction_ )( const Event & );
0136     const Event & evt_;
0137 };
0138 
0139 
0140 template< bool contextHasInheritedDeepHistory, bool contextHasDeepHistory >
0141 struct deep_history_storer
0142 {
0143   template< class HistorizedState, class LeafState, class Context >
0144   static void store_deep_history( Context & ) {}
0145 };
0146 
0147 template<>
0148 struct deep_history_storer< true, false >
0149 {
0150   template< class HistorizedState, class LeafState, class Context >
0151   static void store_deep_history( Context & ctx )
0152   {
0153     ctx.template store_deep_history_impl< LeafState >();
0154   }
0155 };
0156 
0157 template<>
0158 struct deep_history_storer< true, true >
0159 {
0160   template< class HistorizedState, class LeafState, class Context >
0161   static void store_deep_history( Context & ctx )
0162   {
0163     ctx.outermost_context_base().template store_deep_history<
0164       HistorizedState, LeafState >();
0165     ctx.template store_deep_history_impl< LeafState >();
0166   }
0167 };
0168 
0169 
0170 
0171 } // namespace detail
0172 
0173 
0174 
0175 //////////////////////////////////////////////////////////////////////////////
0176 enum history_mode
0177 {
0178   has_no_history,
0179   has_shallow_history,
0180   has_deep_history,
0181   has_full_history // shallow & deep
0182 };
0183 
0184 
0185 
0186 //////////////////////////////////////////////////////////////////////////////
0187 template< class MostDerived,
0188           class Context,
0189           class InnerInitial = mpl::list<>,
0190           history_mode historyMode = has_no_history >
0191 class simple_state : public detail::simple_state_base_type< MostDerived,
0192   typename Context::inner_context_type, InnerInitial >::type
0193 {
0194   typedef typename detail::simple_state_base_type<
0195     MostDerived, typename Context::inner_context_type,
0196     InnerInitial >::type base_type;
0197 
0198   public:
0199     //////////////////////////////////////////////////////////////////////////
0200     typedef mpl::list<> reactions;
0201 
0202     typedef typename Context::inner_context_type context_type;
0203 
0204     template< detail::orthogonal_position_type innerOrthogonalPosition >
0205     struct orthogonal
0206     {
0207       typedef mpl::integral_c<
0208         detail::orthogonal_position_type,
0209         innerOrthogonalPosition > inner_orthogonal_position;
0210       typedef MostDerived inner_context_type;
0211     };
0212 
0213     typedef typename context_type::outermost_context_type
0214       outermost_context_type;
0215 
0216     outermost_context_type & outermost_context()
0217     {
0218       // This assert fails when an attempt is made to access the state machine
0219       // from a constructor of a state that is *not* a subtype of state<>.
0220       // To correct this, derive from state<> instead of simple_state<>.
0221       BOOST_ASSERT( get_pointer( pContext_ ) != 0 );
0222       return pContext_->outermost_context();
0223     }
0224 
0225     const outermost_context_type & outermost_context() const
0226     {
0227       // This assert fails when an attempt is made to access the state machine
0228       // from a constructor of a state that is *not* a subtype of state<>.
0229       // To correct this, derive from state<> instead of simple_state<>.
0230       BOOST_ASSERT( get_pointer( pContext_ ) != 0 );
0231       return pContext_->outermost_context();
0232     }
0233 
0234     template< class OtherContext >
0235     OtherContext & context()
0236     {
0237       typedef typename mpl::if_<
0238         is_base_of< OtherContext, MostDerived >,
0239         context_impl_this_context,
0240         context_impl_other_context
0241       >::type impl;
0242       return impl::template context_impl< OtherContext >( *this );
0243     }
0244 
0245     template< class OtherContext >
0246     const OtherContext & context() const
0247     {
0248       typedef typename mpl::if_<
0249         is_base_of< OtherContext, MostDerived >,
0250         context_impl_this_context,
0251         context_impl_other_context
0252       >::type impl;
0253       return impl::template context_impl< OtherContext >( *this );
0254     }
0255 
0256     template< class Target >
0257     Target state_cast() const
0258     {
0259       return outermost_context_base().template state_cast< Target >();
0260     }
0261 
0262     template< class Target >
0263     Target state_downcast() const
0264     {
0265       return outermost_context_base().template state_downcast< Target >();
0266     }
0267 
0268     typedef typename context_type::state_base_type state_base_type;
0269     typedef typename context_type::state_iterator state_iterator;
0270 
0271     state_iterator state_begin() const
0272     {
0273       return outermost_context_base().state_begin();
0274     }
0275 
0276     state_iterator state_end() const
0277     {
0278       return outermost_context_base().state_end();
0279     }
0280 
0281 
0282     typedef typename context_type::event_base_ptr_type event_base_ptr_type;
0283 
0284     void post_event( const event_base_ptr_type & pEvent )
0285     {
0286       outermost_context_base().post_event_impl( pEvent );
0287     }
0288 
0289     void post_event( const event_base & evt )
0290     {
0291       outermost_context_base().post_event_impl( evt );
0292     }
0293 
0294     result discard_event()
0295     {
0296       return detail::result_utility::make_result( detail::do_discard_event );
0297     }
0298 
0299     result forward_event()
0300     {
0301       return detail::result_utility::make_result( detail::do_forward_event );
0302     }
0303 
0304     result defer_event()
0305     {
0306       this->state_base_type::defer_event();
0307       return detail::result_utility::make_result( detail::do_defer_event );
0308     }
0309 
0310     template< class DestinationState >
0311     result transit()
0312     {
0313       return transit_impl< DestinationState, outermost_context_type >(
0314         detail::no_transition_function() );
0315     }
0316 
0317     template< class DestinationState, class TransitionContext, class Event >
0318     result transit(
0319       void ( TransitionContext::*pTransitionAction )( const Event & ),
0320       const Event & evt )
0321     {
0322       return transit_impl< DestinationState, TransitionContext >(
0323         detail::transition_function< TransitionContext, Event >(
0324           pTransitionAction, evt ) );
0325     }
0326 
0327     result terminate()
0328     {
0329       outermost_context_base().terminate_as_reaction( *this );
0330       return detail::result_utility::make_result( detail::do_discard_event );
0331     }
0332 
0333     template<
0334       class HistoryContext,
0335       detail::orthogonal_position_type orthogonalPosition >
0336     void clear_shallow_history()
0337     {
0338       outermost_context_base().template clear_shallow_history<
0339         HistoryContext, orthogonalPosition >();
0340     }
0341 
0342     template<
0343       class HistoryContext,
0344       detail::orthogonal_position_type orthogonalPosition >
0345     void clear_deep_history()
0346     {
0347       outermost_context_base().template clear_deep_history<
0348         HistoryContext, orthogonalPosition >();
0349     }
0350 
0351     const event_base * triggering_event() const
0352     {
0353       return outermost_context_base().triggering_event();
0354     }
0355 
0356   protected:
0357     //////////////////////////////////////////////////////////////////////////
0358     simple_state() : pContext_( 0 ) {}
0359 
0360     ~simple_state()
0361     {
0362       // As a result of a throwing derived class constructor, this destructor
0363       // can be called before the context is set.
0364       if ( get_pointer( pContext_ ) != 0 )
0365       {
0366         if ( this->deferred_events() )
0367         {
0368           outermost_context_base().release_events();
0369         }
0370 
0371         pContext_->remove_inner_state( orthogonal_position::value );
0372       }
0373     }
0374 
0375   public:
0376     //////////////////////////////////////////////////////////////////////////
0377     // The following declarations should be private.
0378     // They are only public because many compilers lack template friends.
0379     //////////////////////////////////////////////////////////////////////////
0380     typedef typename Context::inner_orthogonal_position orthogonal_position;
0381 
0382     // If you receive a
0383     // "use of undefined type 'boost::STATIC_ASSERTION_FAILURE<x>'" or similar
0384     // compiler error here then either this state resides in a non-existent
0385     // orthogonal region of the outer state or the outer state does not have
0386     // inner states.
0387     BOOST_STATIC_ASSERT( ( mpl::less<
0388       orthogonal_position,
0389       typename context_type::no_of_orthogonal_regions >::value ) );
0390 
0391     typedef MostDerived inner_context_type;
0392     typedef mpl::integral_c< detail::orthogonal_position_type, 0 >
0393       inner_orthogonal_position;
0394 
0395     typedef typename context_type::event_base_type event_base_type;
0396     typedef typename context_type::rtti_policy_type rtti_policy_type;
0397 
0398     typedef typename context_type::outermost_context_base_type
0399       outermost_context_base_type;
0400     typedef typename context_type::inner_context_ptr_type context_ptr_type;
0401     typedef typename context_type::state_list_type state_list_type;
0402     typedef intrusive_ptr< inner_context_type > inner_context_ptr_type;
0403     typedef typename detail::make_list< InnerInitial >::type
0404       inner_initial_list;
0405     typedef typename mpl::size< inner_initial_list >::type
0406       inner_initial_list_size;
0407     typedef mpl::integral_c<
0408       detail::orthogonal_position_type,
0409       inner_initial_list_size::value > no_of_orthogonal_regions;
0410     typedef typename mpl::push_front<
0411       typename context_type::context_type_list,
0412       context_type >::type context_type_list;
0413 
0414     // If you receive a
0415     // "use of undefined type 'boost::STATIC_ASSERTION_FAILURE<x>'" or similar
0416     // compiler error here then the direct or indirect context of this state
0417     // has deep history _and_ this state has two or more orthogonal regions.
0418     // Boost.Statechart does not currently support deep history in a state whose
0419     // direct or indirect inner states have two or more orthogonal regions.
0420     // Please consult the documentation on how to work around this limitation.
0421     BOOST_STATIC_ASSERT( ( mpl::or_<
0422       mpl::less<
0423         no_of_orthogonal_regions,
0424         mpl::integral_c< detail::orthogonal_position_type, 2 > >,
0425       mpl::not_<
0426         typename context_type::inherited_deep_history > >::value ) );
0427 
0428     typedef mpl::bool_< ( historyMode & has_shallow_history ) != 0 >
0429       shallow_history;
0430     typedef typename context_type::shallow_history stores_shallow_history;
0431 
0432     typedef mpl::bool_< ( historyMode & has_deep_history ) != 0 >
0433       deep_history;
0434     typedef typename mpl::or_<
0435       deep_history, 
0436       typename context_type::inherited_deep_history
0437     >::type inherited_deep_history;
0438     typedef typename mpl::and_<
0439       inherited_deep_history,
0440       mpl::empty< inner_initial_list > >::type stores_deep_history;
0441 
0442     void * operator new( std::size_t size )
0443     {
0444       return detail::allocate< MostDerived,
0445         typename outermost_context_type::allocator_type >( size );
0446     }
0447 
0448     void operator delete( void * pState )
0449     {
0450       detail::deallocate< MostDerived,
0451         typename outermost_context_type::allocator_type >( pState );
0452     }
0453 
0454     outermost_context_base_type & outermost_context_base()
0455     {
0456       // This assert fails when an attempt is made to access the state machine
0457       // from a constructor of a state that is *not* a subtype of state<>.
0458       // To correct this, derive from state<> instead of simple_state<>.
0459       BOOST_ASSERT( get_pointer( pContext_ ) != 0 );
0460       return pContext_->outermost_context_base();
0461     }
0462 
0463     const outermost_context_base_type & outermost_context_base() const
0464     {
0465       // This assert fails when an attempt is made to access the state machine
0466       // from a constructor of a state that is *not* a subtype of state<>.
0467       // To correct this, derive from state<> instead of simple_state<>.
0468       BOOST_ASSERT( get_pointer( pContext_ ) != 0 );
0469       return pContext_->outermost_context_base();
0470     }
0471 
0472     virtual const state_base_type * outer_state_ptr() const
0473     {
0474       typedef typename mpl::if_<
0475         is_same< outermost_context_type, context_type >,
0476         outer_state_ptr_impl_outermost,
0477         outer_state_ptr_impl_non_outermost
0478       >::type impl;
0479       return impl::outer_state_ptr_impl( *this );
0480     }
0481 
0482     virtual detail::reaction_result react_impl(
0483       const event_base_type & evt,
0484       typename rtti_policy_type::id_type eventType )
0485     {
0486       typedef typename detail::make_list<
0487         typename MostDerived::reactions >::type reaction_list;
0488       detail::reaction_result reactionResult =
0489         local_react< reaction_list >( evt, eventType );
0490 
0491       // At this point we can only safely access pContext_ if the handler did
0492       // not return do_discard_event!
0493       if ( reactionResult == detail::do_forward_event )
0494       {
0495         // TODO: The following call to react_impl of our outer state should
0496         // be made with a context_type:: prefix to call directly instead of
0497         // virtually. For some reason the compiler complains...
0498         reactionResult = pContext_->react_impl( evt, eventType );
0499       }
0500 
0501       return reactionResult;
0502     }
0503 
0504     virtual void exit_impl(
0505       typename base_type::direct_state_base_ptr_type & pSelf,
0506       typename state_base_type::node_state_base_ptr_type &
0507         pOutermostUnstableState,
0508       bool performFullExit )
0509     {
0510       inner_context_ptr_type pMostDerivedSelf =
0511         polymorphic_downcast< MostDerived * >( this );
0512       pSelf = 0;
0513       exit_impl( pMostDerivedSelf, pOutermostUnstableState, performFullExit );
0514     }
0515 
0516     void exit_impl(
0517       inner_context_ptr_type & pSelf,
0518       typename state_base_type::node_state_base_ptr_type &
0519         pOutermostUnstableState,
0520       bool performFullExit )
0521     {
0522       switch ( this->ref_count() )
0523       {
0524         case 2:
0525           if ( get_pointer( pOutermostUnstableState ) ==
0526             static_cast< state_base_type * >( this ) )
0527           {
0528             pContext_->set_outermost_unstable_state(
0529               pOutermostUnstableState );
0530             BOOST_FALLTHROUGH;
0531           }
0532           else
0533           {
0534             break;
0535           }
0536         case 1:
0537         {
0538           if ( get_pointer( pOutermostUnstableState ) == 0 )
0539           {
0540             pContext_->set_outermost_unstable_state(
0541               pOutermostUnstableState );
0542           }
0543 
0544           if ( performFullExit )
0545           {
0546             pSelf->exit();
0547             check_store_shallow_history< stores_shallow_history >();
0548             check_store_deep_history< stores_deep_history >();
0549           }
0550 
0551           context_ptr_type pContext = pContext_;
0552           pSelf = 0;
0553           pContext->exit_impl(
0554             pContext, pOutermostUnstableState, performFullExit );
0555           break;
0556         }
0557         default:
0558           break;
0559       }
0560     }
0561 
0562     void set_outermost_unstable_state(
0563       typename state_base_type::node_state_base_ptr_type &
0564         pOutermostUnstableState )
0565     {
0566       pOutermostUnstableState = this;
0567     }
0568 
0569     template< class OtherContext >
0570     const typename OtherContext::inner_context_ptr_type & context_ptr() const
0571     {
0572       typedef typename mpl::if_<
0573         is_same< OtherContext, context_type >,
0574         context_ptr_impl_my_context,
0575         context_ptr_impl_other_context
0576       >::type impl;
0577 
0578       return impl::template context_ptr_impl< OtherContext >( *this );
0579     }
0580 
0581     static void initial_deep_construct(
0582       outermost_context_base_type & outermostContextBase )
0583     {
0584       deep_construct( &outermostContextBase, outermostContextBase );
0585     }
0586 
0587     static void deep_construct(
0588       const context_ptr_type & pContext,
0589       outermost_context_base_type & outermostContextBase )
0590     {
0591       const inner_context_ptr_type pInnerContext(
0592         shallow_construct( pContext, outermostContextBase ) );
0593       deep_construct_inner< inner_initial_list >(
0594         pInnerContext, outermostContextBase );
0595     }
0596 
0597     static inner_context_ptr_type shallow_construct(
0598       const context_ptr_type & pContext,
0599       outermost_context_base_type & outermostContextBase )
0600     {
0601       const inner_context_ptr_type pInnerContext( new MostDerived );
0602       pInnerContext->set_context( pContext );
0603       outermostContextBase.add( pInnerContext );
0604       return pInnerContext;
0605     }
0606 
0607     void set_context( const context_ptr_type & pContext )
0608     {
0609       BOOST_ASSERT( get_pointer( pContext ) != 0 );
0610       pContext_ = pContext;
0611       base_type::set_context(
0612         orthogonal_position::value, get_pointer( pContext ) );
0613     }
0614 
0615     template< class InnerList >
0616     static void deep_construct_inner(
0617       const inner_context_ptr_type & pInnerContext,
0618       outermost_context_base_type & outermostContextBase )
0619     {
0620       typedef typename mpl::if_<
0621         mpl::empty< InnerList >,
0622         deep_construct_inner_impl_empty,
0623         deep_construct_inner_impl_non_empty
0624       >::type impl;
0625       impl::template deep_construct_inner_impl< InnerList >(
0626         pInnerContext, outermostContextBase );
0627     }
0628 
0629     template< class LeafState >
0630     void store_deep_history_impl()
0631     {
0632       detail::deep_history_storer<
0633         context_type::inherited_deep_history::value,
0634         context_type::deep_history::value
0635       >::template store_deep_history< MostDerived, LeafState >(
0636         *pContext_ );
0637     }
0638 
0639   private:
0640     //////////////////////////////////////////////////////////////////////////
0641     struct context_ptr_impl_other_context
0642     {
0643       template< class OtherContext, class State >
0644       static const typename OtherContext::inner_context_ptr_type &
0645       context_ptr_impl( const State & stt )
0646       {
0647         // This assert fails when an attempt is made to access an outer 
0648         // context from a constructor of a state that is *not* a subtype of
0649         // state<>. To correct this, derive from state<> instead of
0650         // simple_state<>.
0651         BOOST_ASSERT( get_pointer( stt.pContext_ ) != 0 );
0652         return stt.pContext_->template context_ptr< OtherContext >();
0653       }
0654     };
0655     friend struct context_ptr_impl_other_context;
0656 
0657     struct context_ptr_impl_my_context
0658     {
0659       template< class OtherContext, class State >
0660       static const typename OtherContext::inner_context_ptr_type &
0661       context_ptr_impl( const State & stt )
0662       {
0663         // This assert fails when an attempt is made to access an outer 
0664         // context from a constructor of a state that is *not* a subtype of
0665         // state<>. To correct this, derive from state<> instead of
0666         // simple_state<>.
0667         BOOST_ASSERT( get_pointer( stt.pContext_ ) != 0 );
0668         return stt.pContext_;
0669       }
0670     };
0671     friend struct context_ptr_impl_my_context;
0672 
0673     struct context_impl_other_context
0674     {
0675       template< class OtherContext, class State >
0676       static OtherContext & context_impl( State & stt )
0677       {
0678         // This assert fails when an attempt is made to access an outer 
0679         // context from a constructor of a state that is *not* a subtype of
0680         // state<>. To correct this, derive from state<> instead of
0681         // simple_state<>.
0682         BOOST_ASSERT( get_pointer( stt.pContext_ ) != 0 );
0683         return stt.pContext_->template context< OtherContext >();
0684       }
0685     };
0686     friend struct context_impl_other_context;
0687 
0688     struct context_impl_this_context
0689     {
0690       template< class OtherContext, class State >
0691       static OtherContext & context_impl( State & stt )
0692       {
0693         return *polymorphic_downcast< MostDerived * >( &stt );
0694       }
0695     };
0696     friend struct context_impl_this_context;
0697 
0698     template< class DestinationState,
0699               class TransitionContext,
0700               class TransitionAction >
0701     result transit_impl( const TransitionAction & transitionAction )
0702     {
0703       typedef typename mpl::find_if<
0704         context_type_list,
0705         mpl::contains<
0706           typename DestinationState::context_type_list,
0707           mpl::placeholders::_ > >::type common_context_iter;
0708       typedef typename mpl::deref< common_context_iter >::type
0709         common_context_type;
0710       typedef typename mpl::distance<
0711         typename mpl::begin< context_type_list >::type,
0712         common_context_iter >::type termination_state_position;
0713       typedef typename mpl::push_front< context_type_list, MostDerived >::type
0714         possible_transition_contexts;
0715       typedef typename mpl::at<
0716         possible_transition_contexts,
0717         termination_state_position >::type termination_state_type;
0718 
0719       termination_state_type & terminationState(
0720         context< termination_state_type >() );
0721       const typename
0722         common_context_type::inner_context_ptr_type pCommonContext(
0723           terminationState.template context_ptr< common_context_type >() );
0724       outermost_context_base_type & outermostContextBase(
0725         pCommonContext->outermost_context_base() );
0726 
0727       #ifdef BOOST_STATECHART_RELAX_TRANSITION_CONTEXT
0728       typedef typename mpl::distance<
0729         typename mpl::begin< possible_transition_contexts >::type,
0730         typename mpl::find<
0731           possible_transition_contexts, TransitionContext >::type
0732       >::type proposed_transition_context_position;
0733 
0734       typedef typename mpl::plus<
0735         termination_state_position,
0736         mpl::long_< 1 >
0737       >::type uml_transition_context_position;
0738 
0739       typedef typename mpl::deref< typename mpl::max_element<
0740         mpl::list<
0741           proposed_transition_context_position,
0742           uml_transition_context_position >,
0743         mpl::greater< mpl::placeholders::_, mpl::placeholders::_ >
0744       >::type >::type real_transition_context_position;
0745 
0746       typedef typename mpl::at<
0747         possible_transition_contexts,
0748         real_transition_context_position >::type real_transition_context_type;
0749 
0750       #ifdef BOOST_MSVC
0751       #  pragma warning( push )
0752       #  pragma warning( disable: 4127 ) // conditional expression is constant
0753       #endif
0754       if ( ( proposed_transition_context_position::value == 0 ) &&
0755            ( inner_initial_list_size::value == 0 ) )
0756       {
0757         transitionAction( *polymorphic_downcast< MostDerived * >( this ) );
0758         outermostContextBase.terminate_as_part_of_transit( terminationState );
0759       }
0760       else if ( proposed_transition_context_position::value >=
0761                 uml_transition_context_position::value )
0762       {
0763         real_transition_context_type & transitionContext =
0764           context< real_transition_context_type >();
0765         outermostContextBase.terminate_as_part_of_transit( terminationState );
0766         transitionAction( transitionContext );
0767       }
0768       else
0769       {
0770         typename real_transition_context_type::inner_context_ptr_type
0771           pTransitionContext = context_ptr< real_transition_context_type >();
0772         outermostContextBase.terminate_as_part_of_transit(
0773           *pTransitionContext );
0774         transitionAction( *pTransitionContext );
0775         pTransitionContext = 0;
0776         outermostContextBase.terminate_as_part_of_transit( terminationState );
0777       }
0778       #ifdef BOOST_MSVC
0779       #  pragma warning( pop )
0780       #endif
0781       #else
0782       outermostContextBase.terminate_as_part_of_transit( terminationState );
0783       transitionAction( *pCommonContext );
0784       #endif
0785 
0786       typedef typename detail::make_context_list<
0787         common_context_type, DestinationState >::type context_list_type;
0788 
0789       // If you receive a
0790       // "use of undefined type 'boost::STATIC_ASSERTION_FAILURE<x>'" or
0791       // similar compiler error here then you tried to make an invalid
0792       // transition between different orthogonal regions.
0793       BOOST_STATIC_ASSERT( ( mpl::equal_to<
0794         typename termination_state_type::orthogonal_position,
0795         typename mpl::front< context_list_type >::type::orthogonal_position
0796       >::value ) );
0797 
0798       detail::constructor<
0799         context_list_type, outermost_context_base_type >::construct(
0800           pCommonContext, outermostContextBase );
0801 
0802       return detail::result_utility::make_result( detail::do_discard_event );
0803     }
0804 
0805     struct local_react_impl_non_empty
0806     {
0807       template< class ReactionList, class State >
0808       static detail::reaction_result local_react_impl(
0809         State & stt,
0810         const event_base_type & evt,
0811         typename rtti_policy_type::id_type eventType )
0812       {
0813         detail::reaction_result reactionResult =
0814           mpl::front< ReactionList >::type::react(
0815             *polymorphic_downcast< MostDerived * >( &stt ),
0816             evt, eventType );
0817 
0818         if ( reactionResult == detail::no_reaction )
0819         {
0820           reactionResult = stt.template local_react<
0821             typename mpl::pop_front< ReactionList >::type >(
0822               evt, eventType );
0823         }
0824 
0825         return reactionResult;
0826       }
0827     };
0828     friend struct local_react_impl_non_empty;
0829 
0830     struct local_react_impl_empty
0831     {
0832       template< class ReactionList, class State >
0833       static detail::reaction_result local_react_impl(
0834         State &, const event_base_type &, typename rtti_policy_type::id_type )
0835       {
0836         return detail::do_forward_event;
0837       }
0838     };
0839 
0840     template< class ReactionList >
0841     detail::reaction_result local_react(
0842       const event_base_type & evt,
0843       typename rtti_policy_type::id_type eventType )
0844     {
0845       typedef typename mpl::if_<
0846         mpl::empty< ReactionList >,
0847         local_react_impl_empty,
0848         local_react_impl_non_empty
0849       >::type impl;
0850       return impl::template local_react_impl< ReactionList >(
0851         *this, evt, eventType );
0852     }
0853 
0854     struct outer_state_ptr_impl_non_outermost
0855     {
0856       template< class State >
0857       static const state_base_type * outer_state_ptr_impl( const State & stt )
0858       {
0859         return get_pointer( stt.pContext_ );
0860       }
0861     };
0862     friend struct outer_state_ptr_impl_non_outermost;
0863 
0864     struct outer_state_ptr_impl_outermost
0865     {
0866       template< class State >
0867       static const state_base_type * outer_state_ptr_impl( const State & )
0868       {
0869         return 0;
0870       }
0871     };
0872 
0873     struct deep_construct_inner_impl_non_empty
0874     {
0875       template< class InnerList >
0876       static void deep_construct_inner_impl(
0877         const inner_context_ptr_type & pInnerContext,
0878         outermost_context_base_type & outermostContextBase )
0879       {
0880         typedef typename mpl::front< InnerList >::type current_inner;
0881 
0882         // If you receive a
0883         // "use of undefined type 'boost::STATIC_ASSERTION_FAILURE<x>'" or
0884         // similar compiler error here then there is a mismatch between the
0885         // orthogonal position of a state and its position in the inner
0886         // initial list of its outer state.
0887         BOOST_STATIC_ASSERT( ( is_same<
0888           current_inner,
0889           typename mpl::at<
0890             typename current_inner::context_type::inner_initial_list,
0891             typename current_inner::orthogonal_position >::type >::value ) );
0892 
0893         current_inner::deep_construct( pInnerContext, outermostContextBase );
0894         deep_construct_inner< typename mpl::pop_front< InnerList >::type >(
0895           pInnerContext, outermostContextBase );
0896       }
0897     };
0898 
0899     struct deep_construct_inner_impl_empty
0900     {
0901       template< class InnerList >
0902       static void deep_construct_inner_impl(
0903         const inner_context_ptr_type &, outermost_context_base_type & ) {}
0904     };
0905 
0906     struct check_store_shallow_history_impl_no
0907     {
0908       template< class State >
0909       static void check_store_shallow_history_impl( State & ) {}
0910     };
0911 
0912     struct check_store_shallow_history_impl_yes
0913     {
0914       template< class State >
0915       static void check_store_shallow_history_impl( State & stt )
0916       {
0917         stt.outermost_context_base().template store_shallow_history<
0918           MostDerived >();
0919       }
0920     };
0921     friend struct check_store_shallow_history_impl_yes;
0922 
0923     template< class StoreShallowHistory >
0924     void check_store_shallow_history()
0925     {
0926       typedef typename mpl::if_<
0927         StoreShallowHistory,
0928         check_store_shallow_history_impl_yes,
0929         check_store_shallow_history_impl_no
0930       >::type impl;
0931       impl::check_store_shallow_history_impl( *this );
0932     }
0933 
0934     struct check_store_deep_history_impl_no
0935     {
0936       template< class State >
0937       static void check_store_deep_history_impl( State & ) {}
0938     };
0939 
0940     struct check_store_deep_history_impl_yes
0941     {
0942       template< class State >
0943       static void check_store_deep_history_impl( State & stt )
0944       {
0945         stt.template store_deep_history_impl< MostDerived >();
0946       }
0947     };
0948     friend struct check_store_deep_history_impl_yes;
0949 
0950     template< class StoreDeepHistory >
0951     void check_store_deep_history()
0952     {
0953       typedef typename mpl::if_<
0954         StoreDeepHistory,
0955         check_store_deep_history_impl_yes,
0956         check_store_deep_history_impl_no
0957       >::type impl;
0958       impl::check_store_deep_history_impl( *this );
0959     }
0960 
0961 
0962     context_ptr_type pContext_;
0963 };
0964 
0965 
0966 
0967 #ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
0968 } // namespace statechart
0969 #endif
0970 
0971 
0972 
0973 template< class MostDerived, class Context,
0974           class InnerInitial, history_mode historyMode >
0975 inline void intrusive_ptr_release( const ::boost::statechart::simple_state<
0976   MostDerived, Context, InnerInitial, historyMode > * pBase )
0977 {
0978   if ( pBase->release() )
0979   {
0980     // The cast is necessary because the simple_state destructor is non-
0981     // virtual (and inaccessible from this context)
0982     delete polymorphic_downcast< const MostDerived * >( pBase );
0983   }
0984 }
0985 
0986 
0987 
0988 #ifndef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
0989 } // namespace statechart
0990 #endif
0991 
0992 
0993 
0994 } // namespace boost
0995 
0996 
0997 
0998 #endif