PageRenderTime 82ms CodeModel.GetById 11ms app.highlight 61ms RepoModel.GetById 1ms app.codeStats 0ms

/Src/Dependencies/Boost/boost/statechart/simple_state.hpp

http://hadesmem.googlecode.com/
C++ Header | 998 lines | 783 code | 142 blank | 73 comment | 28 complexity | a68fd26e354ff7dff8a2686446f32904 MD5 | raw file
  1#ifndef BOOST_STATECHART_SIMPLE_STATE_HPP_INCLUDED
  2#define BOOST_STATECHART_SIMPLE_STATE_HPP_INCLUDED
  3//////////////////////////////////////////////////////////////////////////////
  4// Copyright 2002-2010 Andreas Huber Doenni
  5// Distributed under the Boost Software License, Version 1.0. (See accompany-
  6// ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  7//////////////////////////////////////////////////////////////////////////////
  8
  9
 10
 11#include <boost/statechart/event.hpp>
 12
 13#include <boost/statechart/detail/leaf_state.hpp>
 14#include <boost/statechart/detail/node_state.hpp>
 15#include <boost/statechart/detail/constructor.hpp>
 16#include <boost/statechart/detail/memory.hpp>
 17
 18#include <boost/mpl/eval_if.hpp>
 19#include <boost/mpl/if.hpp>
 20#include <boost/mpl/identity.hpp>
 21#include <boost/mpl/is_sequence.hpp>
 22#include <boost/mpl/list.hpp>
 23#include <boost/mpl/empty.hpp>
 24#include <boost/mpl/size.hpp>
 25#include <boost/mpl/front.hpp>
 26#include <boost/mpl/at.hpp>
 27#include <boost/mpl/find.hpp>
 28#include <boost/mpl/find_if.hpp>
 29#include <boost/mpl/contains.hpp>
 30#include <boost/mpl/distance.hpp>
 31#include <boost/mpl/deref.hpp>
 32#include <boost/mpl/pop_front.hpp>
 33#include <boost/mpl/push_front.hpp>
 34#include <boost/mpl/clear.hpp>
 35#include <boost/mpl/placeholders.hpp>
 36#include <boost/mpl/bool.hpp>
 37#include <boost/mpl/integral_c.hpp>
 38#include <boost/mpl/less.hpp>
 39#include <boost/mpl/equal_to.hpp>
 40#include <boost/mpl/not.hpp>
 41#include <boost/mpl/or.hpp>
 42
 43#include <boost/mpl/plus.hpp>
 44#include <boost/mpl/max_element.hpp>
 45#include <boost/mpl/greater.hpp>
 46
 47#include <boost/get_pointer.hpp>
 48#include <boost/intrusive_ptr.hpp>
 49#include <boost/assert.hpp>
 50#include <boost/type_traits/is_base_of.hpp>
 51#include <boost/type_traits/is_same.hpp>
 52#include <boost/static_assert.hpp>
 53#include <boost/cast.hpp> // boost::polymorphic_downcast
 54
 55#include <cstddef> // std::size_t
 56
 57
 58
 59namespace boost
 60{
 61namespace statechart
 62{
 63namespace detail
 64{
 65
 66
 67
 68//////////////////////////////////////////////////////////////////////////////
 69template< class T >
 70struct make_list : public mpl::eval_if<
 71  mpl::is_sequence< T >,
 72  mpl::identity< T >,
 73  mpl::identity< mpl::list< T > > > {};
 74
 75//////////////////////////////////////////////////////////////////////////////
 76template< class MostDerived, class Context, class InnerInitial >
 77struct simple_state_base_type
 78{
 79  private:
 80    typedef typename Context::outermost_context_base_type::allocator_type
 81      allocator_type;
 82    typedef typename Context::outermost_context_base_type::rtti_policy_type
 83      rtti_policy_type;
 84    typedef typename detail::make_list< InnerInitial >::type
 85      inner_initial_list;
 86    typedef typename mpl::size< inner_initial_list >::type
 87      inner_initial_list_size;
 88
 89  public:
 90    typedef typename mpl::eval_if<
 91      mpl::empty< inner_initial_list >,
 92      mpl::identity< typename rtti_policy_type::
 93        template rtti_derived_type< MostDerived, leaf_state<
 94          allocator_type,
 95          rtti_policy_type > > >,
 96      mpl::identity< typename rtti_policy_type::
 97        template rtti_derived_type< MostDerived, node_state<
 98          inner_initial_list_size,
 99          allocator_type,
100          rtti_policy_type > > > >::type type;
101};
102
103
104//////////////////////////////////////////////////////////////////////////////
105struct no_transition_function
106{
107  template< class CommonContext >
108  void operator()( CommonContext & ) const {}
109};
110
111template< class TransitionContext, class Event >
112class transition_function
113{
114  public:
115    transition_function(
116      void ( TransitionContext::*pTransitionAction )( const Event & ),
117      const Event & evt
118    ) :
119      pTransitionAction_( pTransitionAction ),
120      evt_( evt )
121    {
122    }
123
124    template< class CommonContext >
125    void operator()( CommonContext & commonContext ) const
126    {
127      ( commonContext.template context< TransitionContext >()
128        .*pTransitionAction_ )( evt_ );
129    }
130
131  private:
132    // avoids C4512 (assignment operator could not be generated)
133    transition_function & operator=( const transition_function & );
134
135    void ( TransitionContext::*pTransitionAction_ )( const Event & );
136    const Event & evt_;
137};
138
139
140template< bool contextHasInheritedDeepHistory, bool contextHasDeepHistory >
141struct deep_history_storer
142{
143  template< class HistorizedState, class LeafState, class Context >
144  static void store_deep_history( Context & ) {}
145};
146
147template<>
148struct deep_history_storer< true, false >
149{
150  template< class HistorizedState, class LeafState, class Context >
151  static void store_deep_history( Context & ctx )
152  {
153    ctx.template store_deep_history_impl< LeafState >();
154  }
155};
156
157template<>
158struct deep_history_storer< true, true >
159{
160  template< class HistorizedState, class LeafState, class Context >
161  static void store_deep_history( Context & ctx )
162  {
163    ctx.outermost_context_base().template store_deep_history<
164      HistorizedState, LeafState >();
165    ctx.template store_deep_history_impl< LeafState >();
166  }
167};
168
169
170
171} // namespace detail
172
173
174
175//////////////////////////////////////////////////////////////////////////////
176enum history_mode
177{
178  has_no_history,
179  has_shallow_history,
180  has_deep_history,
181  has_full_history // shallow & deep
182};
183
184
185
186//////////////////////////////////////////////////////////////////////////////
187template< class MostDerived,
188          class Context,
189          class InnerInitial = mpl::list<>,
190          history_mode historyMode = has_no_history >
191class simple_state : public detail::simple_state_base_type< MostDerived,
192  typename Context::inner_context_type, InnerInitial >::type
193{
194  typedef typename detail::simple_state_base_type<
195    MostDerived, typename Context::inner_context_type,
196    InnerInitial >::type base_type;
197
198  public:
199    //////////////////////////////////////////////////////////////////////////
200    typedef mpl::list<> reactions;
201
202    typedef typename Context::inner_context_type context_type;
203
204    template< detail::orthogonal_position_type innerOrthogonalPosition >
205    struct orthogonal
206    {
207      typedef mpl::integral_c<
208        detail::orthogonal_position_type,
209        innerOrthogonalPosition > inner_orthogonal_position;
210      typedef MostDerived inner_context_type;
211    };
212
213    typedef typename context_type::outermost_context_type
214      outermost_context_type;
215
216    outermost_context_type & outermost_context()
217    {
218      // This assert fails when an attempt is made to access the state machine
219      // from a constructor of a state that is *not* a subtype of state<>.
220      // To correct this, derive from state<> instead of simple_state<>.
221      BOOST_ASSERT( get_pointer( pContext_ ) != 0 );
222      return pContext_->outermost_context();
223    }
224
225    const outermost_context_type & outermost_context() const
226    {
227      // This assert fails when an attempt is made to access the state machine
228      // from a constructor of a state that is *not* a subtype of state<>.
229      // To correct this, derive from state<> instead of simple_state<>.
230      BOOST_ASSERT( get_pointer( pContext_ ) != 0 );
231      return pContext_->outermost_context();
232    }
233
234    template< class OtherContext >
235    OtherContext & context()
236    {
237      typedef typename mpl::if_<
238        is_base_of< OtherContext, MostDerived >,
239        context_impl_this_context,
240        context_impl_other_context
241      >::type impl;
242      return impl::template context_impl< OtherContext >( *this );
243    }
244
245    template< class OtherContext >
246    const OtherContext & context() const
247    {
248      typedef typename mpl::if_<
249        is_base_of< OtherContext, MostDerived >,
250        context_impl_this_context,
251        context_impl_other_context
252      >::type impl;
253      return impl::template context_impl< OtherContext >( *this );
254    }
255
256    template< class Target >
257    Target state_cast() const
258    {
259      return outermost_context_base().template state_cast< Target >();
260    }
261
262    template< class Target >
263    Target state_downcast() const
264    {
265      return outermost_context_base().template state_downcast< Target >();
266    }
267
268    typedef typename context_type::state_base_type state_base_type;
269    typedef typename context_type::state_iterator state_iterator;
270
271    state_iterator state_begin() const
272    {
273      return outermost_context_base().state_begin();
274    }
275
276    state_iterator state_end() const
277    {
278      return outermost_context_base().state_end();
279    }
280
281
282    typedef typename context_type::event_base_ptr_type event_base_ptr_type;
283
284    void post_event( const event_base_ptr_type & pEvent )
285    {
286      outermost_context_base().post_event_impl( pEvent );
287    }
288
289    void post_event( const event_base & evt )
290    {
291      outermost_context_base().post_event_impl( evt );
292    }
293
294    result discard_event()
295    {
296      return detail::result_utility::make_result( detail::do_discard_event );
297    }
298
299    result forward_event()
300    {
301      return detail::result_utility::make_result( detail::do_forward_event );
302    }
303
304    result defer_event()
305    {
306      this->state_base_type::defer_event();
307      return detail::result_utility::make_result( detail::do_defer_event );
308    }
309
310    template< class DestinationState >
311    result transit()
312    {
313      return transit_impl< DestinationState, outermost_context_type >(
314        detail::no_transition_function() );
315    }
316
317    template< class DestinationState, class TransitionContext, class Event >
318    result transit(
319      void ( TransitionContext::*pTransitionAction )( const Event & ),
320      const Event & evt )
321    {
322      return transit_impl< DestinationState, TransitionContext >(
323        detail::transition_function< TransitionContext, Event >(
324          pTransitionAction, evt ) );
325    }
326
327    result terminate()
328    {
329      outermost_context_base().terminate_as_reaction( *this );
330      return detail::result_utility::make_result( detail::do_discard_event );
331    }
332
333    template<
334      class HistoryContext,
335      detail::orthogonal_position_type orthogonalPosition >
336    void clear_shallow_history()
337    {
338      outermost_context_base().template clear_shallow_history<
339        HistoryContext, orthogonalPosition >();
340    }
341
342    template<
343      class HistoryContext,
344      detail::orthogonal_position_type orthogonalPosition >
345    void clear_deep_history()
346    {
347      outermost_context_base().template clear_deep_history<
348        HistoryContext, orthogonalPosition >();
349    }
350
351    const event_base * triggering_event() const
352    {
353      return outermost_context_base().triggering_event();
354    }
355
356  protected:
357    //////////////////////////////////////////////////////////////////////////
358    simple_state() : pContext_( 0 ) {}
359
360    ~simple_state()
361    {
362      // As a result of a throwing derived class constructor, this destructor
363      // can be called before the context is set.
364      if ( get_pointer( pContext_ ) != 0 )
365      {
366        if ( this->deferred_events() )
367        {
368          outermost_context_base().release_events();
369        }
370
371        pContext_->remove_inner_state( orthogonal_position::value );
372      }
373    }
374
375  public:
376    //////////////////////////////////////////////////////////////////////////
377    // The following declarations should be private.
378    // They are only public because many compilers lack template friends.
379    //////////////////////////////////////////////////////////////////////////
380    typedef typename Context::inner_orthogonal_position orthogonal_position;
381
382    // If you receive a
383    // "use of undefined type 'boost::STATIC_ASSERTION_FAILURE<x>'" or similar
384    // compiler error here then either this state resides in a non-existent
385    // orthogonal region of the outer state or the outer state does not have
386    // inner states.
387    BOOST_STATIC_ASSERT( ( mpl::less<
388      orthogonal_position,
389      typename context_type::no_of_orthogonal_regions >::value ) );
390
391    typedef MostDerived inner_context_type;
392    typedef mpl::integral_c< detail::orthogonal_position_type, 0 >
393      inner_orthogonal_position;
394
395    typedef typename context_type::event_base_type event_base_type;
396    typedef typename context_type::rtti_policy_type rtti_policy_type;
397
398    typedef typename context_type::outermost_context_base_type
399      outermost_context_base_type;
400    typedef typename context_type::inner_context_ptr_type context_ptr_type;
401    typedef typename context_type::state_list_type state_list_type;
402    typedef intrusive_ptr< inner_context_type > inner_context_ptr_type;
403    typedef typename detail::make_list< InnerInitial >::type
404      inner_initial_list;
405    typedef typename mpl::size< inner_initial_list >::type
406      inner_initial_list_size;
407    typedef mpl::integral_c<
408      detail::orthogonal_position_type,
409      inner_initial_list_size::value > no_of_orthogonal_regions;
410    typedef typename mpl::push_front<
411      typename context_type::context_type_list,
412      context_type >::type context_type_list;
413
414    // If you receive a
415    // "use of undefined type 'boost::STATIC_ASSERTION_FAILURE<x>'" or similar
416    // compiler error here then the direct or indirect context of this state
417    // has deep history _and_ this state has two or more orthogonal regions.
418    // Boost.Statechart does not currently support deep history in a state whose
419    // direct or indirect inner states have two or more orthogonal regions.
420    // Please consult the documentation on how to work around this limitation.
421    BOOST_STATIC_ASSERT( ( mpl::or_<
422      mpl::less<
423        no_of_orthogonal_regions,
424        mpl::integral_c< detail::orthogonal_position_type, 2 > >,
425      mpl::not_<
426        typename context_type::inherited_deep_history > >::value ) );
427
428    typedef mpl::bool_< ( historyMode & has_shallow_history ) != 0 >
429      shallow_history;
430    typedef typename context_type::shallow_history stores_shallow_history;
431
432    typedef mpl::bool_< ( historyMode & has_deep_history ) != 0 >
433      deep_history;
434    typedef typename mpl::or_<
435      deep_history, 
436      typename context_type::inherited_deep_history
437    >::type inherited_deep_history;
438    typedef typename mpl::and_<
439      inherited_deep_history,
440      mpl::empty< inner_initial_list > >::type stores_deep_history;
441
442    void * operator new( std::size_t size )
443    {
444      return detail::allocate< MostDerived,
445        typename outermost_context_type::allocator_type >( size );
446    }
447
448    void operator delete( void * pState )
449    {
450      detail::deallocate< MostDerived,
451        typename outermost_context_type::allocator_type >( pState );
452    }
453
454    outermost_context_base_type & outermost_context_base()
455    {
456      // This assert fails when an attempt is made to access the state machine
457      // from a constructor of a state that is *not* a subtype of state<>.
458      // To correct this, derive from state<> instead of simple_state<>.
459      BOOST_ASSERT( get_pointer( pContext_ ) != 0 );
460      return pContext_->outermost_context_base();
461    }
462
463    const outermost_context_base_type & outermost_context_base() const
464    {
465      // This assert fails when an attempt is made to access the state machine
466      // from a constructor of a state that is *not* a subtype of state<>.
467      // To correct this, derive from state<> instead of simple_state<>.
468      BOOST_ASSERT( get_pointer( pContext_ ) != 0 );
469      return pContext_->outermost_context_base();
470    }
471
472    virtual const state_base_type * outer_state_ptr() const
473    {
474      typedef typename mpl::if_<
475        is_same< outermost_context_type, context_type >,
476        outer_state_ptr_impl_outermost,
477        outer_state_ptr_impl_non_outermost
478      >::type impl;
479      return impl::outer_state_ptr_impl( *this );
480    }
481
482    virtual detail::reaction_result react_impl(
483      const event_base_type & evt,
484      typename rtti_policy_type::id_type eventType )
485    {
486      typedef typename detail::make_list<
487        typename MostDerived::reactions >::type reaction_list;
488      detail::reaction_result reactionResult =
489        local_react< reaction_list >( evt, eventType );
490
491      // At this point we can only safely access pContext_ if the handler did
492      // not return do_discard_event!
493      if ( reactionResult == detail::do_forward_event )
494      {
495        // TODO: The following call to react_impl of our outer state should
496        // be made with a context_type:: prefix to call directly instead of
497        // virtually. For some reason the compiler complains...
498        reactionResult = pContext_->react_impl( evt, eventType );
499      }
500
501      return reactionResult;
502    }
503
504    virtual void exit_impl(
505      typename base_type::direct_state_base_ptr_type & pSelf,
506      typename state_base_type::node_state_base_ptr_type &
507        pOutermostUnstableState,
508      bool performFullExit )
509    {
510      inner_context_ptr_type pMostDerivedSelf =
511        polymorphic_downcast< MostDerived * >( this );
512      pSelf = 0;
513      exit_impl( pMostDerivedSelf, pOutermostUnstableState, performFullExit );
514    }
515
516    void exit_impl(
517      inner_context_ptr_type & pSelf,
518      typename state_base_type::node_state_base_ptr_type &
519        pOutermostUnstableState,
520      bool performFullExit )
521    {
522      switch ( this->ref_count() )
523      {
524        case 2:
525          if ( get_pointer( pOutermostUnstableState ) ==
526            static_cast< state_base_type * >( this ) )
527          {
528            pContext_->set_outermost_unstable_state(
529              pOutermostUnstableState );
530            // fall through to next case intended
531          }
532          else
533          {
534            break;
535          }
536        case 1:
537        {
538          if ( get_pointer( pOutermostUnstableState ) == 0 )
539          {
540            pContext_->set_outermost_unstable_state(
541              pOutermostUnstableState );
542          }
543
544          if ( performFullExit )
545          {
546            pSelf->exit();
547            check_store_shallow_history< stores_shallow_history >();
548            check_store_deep_history< stores_deep_history >();
549          }
550
551          context_ptr_type pContext = pContext_;
552          pSelf = 0;
553          pContext->exit_impl(
554            pContext, pOutermostUnstableState, performFullExit );
555          break;
556        }
557        default:
558          break;
559      }
560    }
561
562    void set_outermost_unstable_state(
563      typename state_base_type::node_state_base_ptr_type &
564        pOutermostUnstableState )
565    {
566      pOutermostUnstableState = this;
567    }
568
569    template< class OtherContext >
570    const typename OtherContext::inner_context_ptr_type & context_ptr() const
571    {
572      typedef typename mpl::if_<
573        is_same< OtherContext, context_type >,
574        context_ptr_impl_my_context,
575        context_ptr_impl_other_context
576      >::type impl;
577
578      return impl::template context_ptr_impl< OtherContext >( *this );
579    }
580
581    static void initial_deep_construct(
582      outermost_context_base_type & outermostContextBase )
583    {
584      deep_construct( &outermostContextBase, outermostContextBase );
585    }
586
587    static void deep_construct(
588      const context_ptr_type & pContext,
589      outermost_context_base_type & outermostContextBase )
590    {
591      const inner_context_ptr_type pInnerContext(
592        shallow_construct( pContext, outermostContextBase ) );
593      deep_construct_inner< inner_initial_list >(
594        pInnerContext, outermostContextBase );
595    }
596
597    static inner_context_ptr_type shallow_construct(
598      const context_ptr_type & pContext,
599      outermost_context_base_type & outermostContextBase )
600    {
601      const inner_context_ptr_type pInnerContext( new MostDerived );
602      pInnerContext->set_context( pContext );
603      outermostContextBase.add( pInnerContext );
604      return pInnerContext;
605    }
606
607    void set_context( const context_ptr_type & pContext )
608    {
609      BOOST_ASSERT( get_pointer( pContext ) != 0 );
610      pContext_ = pContext;
611      base_type::set_context(
612        orthogonal_position::value, get_pointer( pContext ) );
613    }
614
615    template< class InnerList >
616    static void deep_construct_inner(
617      const inner_context_ptr_type & pInnerContext,
618      outermost_context_base_type & outermostContextBase )
619    {
620      typedef typename mpl::if_<
621        mpl::empty< InnerList >,
622        deep_construct_inner_impl_empty,
623        deep_construct_inner_impl_non_empty
624      >::type impl;
625      impl::template deep_construct_inner_impl< InnerList >(
626        pInnerContext, outermostContextBase );
627    }
628
629    template< class LeafState >
630    void store_deep_history_impl()
631    {
632      detail::deep_history_storer<
633        context_type::inherited_deep_history::value,
634        context_type::deep_history::value
635      >::template store_deep_history< MostDerived, LeafState >(
636        *pContext_ );
637    }
638
639  private:
640    //////////////////////////////////////////////////////////////////////////
641    struct context_ptr_impl_other_context
642    {
643      template< class OtherContext, class State >
644      static const typename OtherContext::inner_context_ptr_type &
645      context_ptr_impl( const State & stt )
646      {
647        // This assert fails when an attempt is made to access an outer 
648        // context from a constructor of a state that is *not* a subtype of
649        // state<>. To correct this, derive from state<> instead of
650        // simple_state<>.
651        BOOST_ASSERT( get_pointer( stt.pContext_ ) != 0 );
652        return stt.pContext_->template context_ptr< OtherContext >();
653      }
654    };
655    friend struct context_ptr_impl_other_context;
656
657    struct context_ptr_impl_my_context
658    {
659      template< class OtherContext, class State >
660      static const typename OtherContext::inner_context_ptr_type &
661      context_ptr_impl( const State & stt )
662      {
663        // This assert fails when an attempt is made to access an outer 
664        // context from a constructor of a state that is *not* a subtype of
665        // state<>. To correct this, derive from state<> instead of
666        // simple_state<>.
667        BOOST_ASSERT( get_pointer( stt.pContext_ ) != 0 );
668        return stt.pContext_;
669      }
670    };
671    friend struct context_ptr_impl_my_context;
672
673    struct context_impl_other_context
674    {
675      template< class OtherContext, class State >
676      static OtherContext & context_impl( State & stt )
677      {
678        // This assert fails when an attempt is made to access an outer 
679        // context from a constructor of a state that is *not* a subtype of
680        // state<>. To correct this, derive from state<> instead of
681        // simple_state<>.
682        BOOST_ASSERT( get_pointer( stt.pContext_ ) != 0 );
683        return stt.pContext_->template context< OtherContext >();
684      }
685    };
686    friend struct context_impl_other_context;
687
688    struct context_impl_this_context
689    {
690      template< class OtherContext, class State >
691      static OtherContext & context_impl( State & stt )
692      {
693        return *polymorphic_downcast< MostDerived * >( &stt );
694      }
695    };
696    friend struct context_impl_this_context;
697
698    template< class DestinationState,
699              class TransitionContext,
700              class TransitionAction >
701    result transit_impl( const TransitionAction & transitionAction )
702    {
703      typedef typename mpl::find_if<
704        context_type_list,
705        mpl::contains<
706          typename DestinationState::context_type_list,
707          mpl::placeholders::_ > >::type common_context_iter;
708      typedef typename mpl::deref< common_context_iter >::type
709        common_context_type;
710      typedef typename mpl::distance<
711        typename mpl::begin< context_type_list >::type,
712        common_context_iter >::type termination_state_position;
713      typedef typename mpl::push_front< context_type_list, MostDerived >::type
714        possible_transition_contexts;
715      typedef typename mpl::at<
716        possible_transition_contexts,
717        termination_state_position >::type termination_state_type;
718
719      termination_state_type & terminationState(
720        context< termination_state_type >() );
721      const typename
722        common_context_type::inner_context_ptr_type pCommonContext(
723          terminationState.template context_ptr< common_context_type >() );
724      outermost_context_base_type & outermostContextBase(
725        pCommonContext->outermost_context_base() );
726
727      #ifdef BOOST_STATECHART_RELAX_TRANSITION_CONTEXT
728      typedef typename mpl::distance<
729        typename mpl::begin< possible_transition_contexts >::type,
730        typename mpl::find<
731          possible_transition_contexts, TransitionContext >::type
732      >::type proposed_transition_context_position;
733
734      typedef typename mpl::plus<
735        termination_state_position,
736        mpl::long_< 1 >
737      >::type uml_transition_context_position;
738
739      typedef typename mpl::deref< typename mpl::max_element<
740        mpl::list<
741          proposed_transition_context_position,
742          uml_transition_context_position >,
743        mpl::greater< mpl::placeholders::_, mpl::placeholders::_ >
744      >::type >::type real_transition_context_position;
745
746      typedef typename mpl::at<
747        possible_transition_contexts,
748        real_transition_context_position >::type real_transition_context_type;
749
750      #ifdef BOOST_MSVC
751      #  pragma warning( push )
752      #  pragma warning( disable: 4127 ) // conditional expression is constant
753      #endif
754      if ( ( proposed_transition_context_position::value == 0 ) &&
755           ( inner_initial_list_size::value == 0 ) )
756      {
757        transitionAction( *polymorphic_downcast< MostDerived * >( this ) );
758        outermostContextBase.terminate_as_part_of_transit( terminationState );
759      }
760      else if ( proposed_transition_context_position::value >=
761                uml_transition_context_position::value )
762      {
763        real_transition_context_type & transitionContext =
764          context< real_transition_context_type >();
765        outermostContextBase.terminate_as_part_of_transit( terminationState );
766        transitionAction( transitionContext );
767      }
768      else
769      {
770        typename real_transition_context_type::inner_context_ptr_type
771          pTransitionContext = context_ptr< real_transition_context_type >();
772        outermostContextBase.terminate_as_part_of_transit(
773          *pTransitionContext );
774        transitionAction( *pTransitionContext );
775        pTransitionContext = 0;
776        outermostContextBase.terminate_as_part_of_transit( terminationState );
777      }
778      #ifdef BOOST_MSVC
779      #  pragma warning( pop )
780      #endif
781      #else
782      outermostContextBase.terminate_as_part_of_transit( terminationState );
783      transitionAction( *pCommonContext );
784      #endif
785
786      typedef typename detail::make_context_list<
787        common_context_type, DestinationState >::type context_list_type;
788
789      // If you receive a
790      // "use of undefined type 'boost::STATIC_ASSERTION_FAILURE<x>'" or
791      // similar compiler error here then you tried to make an invalid
792      // transition between different orthogonal regions.
793      BOOST_STATIC_ASSERT( ( mpl::equal_to<
794        typename termination_state_type::orthogonal_position,
795        typename mpl::front< context_list_type >::type::orthogonal_position
796      >::value ) );
797
798      detail::constructor<
799        context_list_type, outermost_context_base_type >::construct(
800          pCommonContext, outermostContextBase );
801
802      return detail::result_utility::make_result( detail::do_discard_event );
803    }
804
805    struct local_react_impl_non_empty
806    {
807      template< class ReactionList, class State >
808      static detail::reaction_result local_react_impl(
809        State & stt,
810        const event_base_type & evt,
811        typename rtti_policy_type::id_type eventType )
812      {
813        detail::reaction_result reactionResult =
814          mpl::front< ReactionList >::type::react(
815            *polymorphic_downcast< MostDerived * >( &stt ),
816            evt, eventType );
817
818        if ( reactionResult == detail::no_reaction )
819        {
820          reactionResult = stt.template local_react<
821            typename mpl::pop_front< ReactionList >::type >(
822              evt, eventType );
823        }
824
825        return reactionResult;
826      }
827    };
828    friend struct local_react_impl_non_empty;
829
830    struct local_react_impl_empty
831    {
832      template< class ReactionList, class State >
833      static detail::reaction_result local_react_impl(
834        State &, const event_base_type &, typename rtti_policy_type::id_type )
835      {
836        return detail::do_forward_event;
837      }
838    };
839
840    template< class ReactionList >
841    detail::reaction_result local_react(
842      const event_base_type & evt,
843      typename rtti_policy_type::id_type eventType )
844    {
845      typedef typename mpl::if_<
846        mpl::empty< ReactionList >,
847        local_react_impl_empty,
848        local_react_impl_non_empty
849      >::type impl;
850      return impl::template local_react_impl< ReactionList >(
851        *this, evt, eventType );
852    }
853
854    struct outer_state_ptr_impl_non_outermost
855    {
856      template< class State >
857      static const state_base_type * outer_state_ptr_impl( const State & stt )
858      {
859        return get_pointer( stt.pContext_ );
860      }
861    };
862    friend struct outer_state_ptr_impl_non_outermost;
863
864    struct outer_state_ptr_impl_outermost
865    {
866      template< class State >
867      static const state_base_type * outer_state_ptr_impl( const State & )
868      {
869        return 0;
870      }
871    };
872
873    struct deep_construct_inner_impl_non_empty
874    {
875      template< class InnerList >
876      static void deep_construct_inner_impl(
877        const inner_context_ptr_type & pInnerContext,
878        outermost_context_base_type & outermostContextBase )
879      {
880        typedef typename mpl::front< InnerList >::type current_inner;
881
882        // If you receive a
883        // "use of undefined type 'boost::STATIC_ASSERTION_FAILURE<x>'" or
884        // similar compiler error here then there is a mismatch between the
885        // orthogonal position of a state and its position in the inner
886        // initial list of its outer state.
887        BOOST_STATIC_ASSERT( ( is_same<
888          current_inner,
889          typename mpl::at<
890            typename current_inner::context_type::inner_initial_list,
891            typename current_inner::orthogonal_position >::type >::value ) );
892
893        current_inner::deep_construct( pInnerContext, outermostContextBase );
894        deep_construct_inner< typename mpl::pop_front< InnerList >::type >(
895          pInnerContext, outermostContextBase );
896      }
897    };
898
899    struct deep_construct_inner_impl_empty
900    {
901      template< class InnerList >
902      static void deep_construct_inner_impl(
903        const inner_context_ptr_type &, outermost_context_base_type & ) {}
904    };
905
906    struct check_store_shallow_history_impl_no
907    {
908      template< class State >
909      static void check_store_shallow_history_impl( State & ) {}
910    };
911
912    struct check_store_shallow_history_impl_yes
913    {
914      template< class State >
915      static void check_store_shallow_history_impl( State & stt )
916      {
917        stt.outermost_context_base().template store_shallow_history<
918          MostDerived >();
919      }
920    };
921    friend struct check_store_shallow_history_impl_yes;
922
923    template< class StoreShallowHistory >
924    void check_store_shallow_history()
925    {
926      typedef typename mpl::if_<
927        StoreShallowHistory,
928        check_store_shallow_history_impl_yes,
929        check_store_shallow_history_impl_no
930      >::type impl;
931      impl::check_store_shallow_history_impl( *this );
932    }
933
934    struct check_store_deep_history_impl_no
935    {
936      template< class State >
937      static void check_store_deep_history_impl( State & ) {}
938    };
939
940    struct check_store_deep_history_impl_yes
941    {
942      template< class State >
943      static void check_store_deep_history_impl( State & stt )
944      {
945        stt.template store_deep_history_impl< MostDerived >();
946      }
947    };
948    friend struct check_store_deep_history_impl_yes;
949
950    template< class StoreDeepHistory >
951    void check_store_deep_history()
952    {
953      typedef typename mpl::if_<
954        StoreDeepHistory,
955        check_store_deep_history_impl_yes,
956        check_store_deep_history_impl_no
957      >::type impl;
958      impl::check_store_deep_history_impl( *this );
959    }
960
961
962    context_ptr_type pContext_;
963};
964
965
966
967#ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
968} // namespace statechart
969#endif
970
971
972
973template< class MostDerived, class Context,
974          class InnerInitial, history_mode historyMode >
975inline void intrusive_ptr_release( const ::boost::statechart::simple_state<
976  MostDerived, Context, InnerInitial, historyMode > * pBase )
977{
978  if ( pBase->release() )
979  {
980    // The cast is necessary because the simple_state destructor is non-
981    // virtual (and inaccessible from this context)
982    delete polymorphic_downcast< const MostDerived * >( pBase );
983  }
984}
985
986
987
988#ifndef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
989} // namespace statechart
990#endif
991
992
993
994} // namespace boost
995
996
997
998#endif