os/ossrv/ossrv_pub/boost_apis/boost/statechart/simple_state.hpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/ossrv/ossrv_pub/boost_apis/boost/statechart/simple_state.hpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,996 @@
     1.4 +#ifndef BOOST_STATECHART_SIMPLE_STATE_HPP_INCLUDED
     1.5 +#define BOOST_STATECHART_SIMPLE_STATE_HPP_INCLUDED
     1.6 +//////////////////////////////////////////////////////////////////////////////
     1.7 +// Copyright 2002-2006 Andreas Huber Doenni
     1.8 +// Distributed under the Boost Software License, Version 1.0. (See accompany-
     1.9 +// ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
    1.10 +//////////////////////////////////////////////////////////////////////////////
    1.11 +
    1.12 +
    1.13 +
    1.14 +#include <boost/statechart/event.hpp>
    1.15 +
    1.16 +#include <boost/statechart/detail/leaf_state.hpp>
    1.17 +#include <boost/statechart/detail/node_state.hpp>
    1.18 +#include <boost/statechart/detail/constructor.hpp>
    1.19 +#include <boost/statechart/detail/memory.hpp>
    1.20 +
    1.21 +#include <boost/mpl/eval_if.hpp>
    1.22 +#include <boost/mpl/if.hpp>
    1.23 +#include <boost/mpl/identity.hpp>
    1.24 +#include <boost/mpl/is_sequence.hpp>
    1.25 +#include <boost/mpl/list.hpp>
    1.26 +#include <boost/mpl/empty.hpp>
    1.27 +#include <boost/mpl/size.hpp>
    1.28 +#include <boost/mpl/front.hpp>
    1.29 +#include <boost/mpl/at.hpp>
    1.30 +#include <boost/mpl/find.hpp>
    1.31 +#include <boost/mpl/find_if.hpp>
    1.32 +#include <boost/mpl/contains.hpp>
    1.33 +#include <boost/mpl/distance.hpp>
    1.34 +#include <boost/mpl/deref.hpp>
    1.35 +#include <boost/mpl/pop_front.hpp>
    1.36 +#include <boost/mpl/push_front.hpp>
    1.37 +#include <boost/mpl/clear.hpp>
    1.38 +#include <boost/mpl/placeholders.hpp>
    1.39 +#include <boost/mpl/bool.hpp>
    1.40 +#include <boost/mpl/integral_c.hpp>
    1.41 +#include <boost/mpl/less.hpp>
    1.42 +#include <boost/mpl/equal_to.hpp>
    1.43 +#include <boost/mpl/not.hpp>
    1.44 +#include <boost/mpl/or.hpp>
    1.45 +
    1.46 +#include <boost/mpl/plus.hpp>
    1.47 +#include <boost/mpl/max_element.hpp>
    1.48 +#include <boost/mpl/greater.hpp>
    1.49 +
    1.50 +#include <boost/get_pointer.hpp>
    1.51 +#include <boost/intrusive_ptr.hpp>
    1.52 +#include <boost/assert.hpp>
    1.53 +#include <boost/type_traits/is_same.hpp>
    1.54 +#include <boost/static_assert.hpp>
    1.55 +#include <boost/cast.hpp> // boost::polymorphic_downcast
    1.56 +
    1.57 +#include <cstddef> // std::size_t
    1.58 +
    1.59 +
    1.60 +
    1.61 +namespace boost
    1.62 +{
    1.63 +namespace statechart
    1.64 +{
    1.65 +namespace detail
    1.66 +{
    1.67 +
    1.68 +
    1.69 +
    1.70 +//////////////////////////////////////////////////////////////////////////////
    1.71 +template< class T >
    1.72 +struct make_list : public mpl::eval_if<
    1.73 +  mpl::is_sequence< T >,
    1.74 +  mpl::identity< T >,
    1.75 +  mpl::identity< mpl::list< T > > > {};
    1.76 +
    1.77 +//////////////////////////////////////////////////////////////////////////////
    1.78 +template< class MostDerived, class Context, class InnerInitial >
    1.79 +struct simple_state_base_type
    1.80 +{
    1.81 +  private:
    1.82 +    typedef typename Context::outermost_context_base_type::allocator_type
    1.83 +      allocator_type;
    1.84 +    typedef typename Context::outermost_context_base_type::rtti_policy_type
    1.85 +      rtti_policy_type;
    1.86 +    typedef typename detail::make_list< InnerInitial >::type
    1.87 +      inner_initial_list;
    1.88 +    typedef typename mpl::size< inner_initial_list >::type
    1.89 +      inner_initial_list_size;
    1.90 +
    1.91 +  public:
    1.92 +    typedef typename mpl::eval_if<
    1.93 +      mpl::empty< inner_initial_list >,
    1.94 +      mpl::identity< typename rtti_policy_type::
    1.95 +        template rtti_derived_type< MostDerived, leaf_state<
    1.96 +          allocator_type,
    1.97 +          rtti_policy_type > > >,
    1.98 +      mpl::identity< typename rtti_policy_type::
    1.99 +        template rtti_derived_type< MostDerived, node_state<
   1.100 +          inner_initial_list_size,
   1.101 +          allocator_type,
   1.102 +          rtti_policy_type > > > >::type type;
   1.103 +};
   1.104 +
   1.105 +
   1.106 +//////////////////////////////////////////////////////////////////////////////
   1.107 +struct no_transition_function
   1.108 +{
   1.109 +  template< class CommonContext >
   1.110 +  void operator()( CommonContext & ) const {}
   1.111 +};
   1.112 +
   1.113 +template< class TransitionContext, class Event >
   1.114 +class transition_function
   1.115 +{
   1.116 +  public:
   1.117 +    transition_function(
   1.118 +      void ( TransitionContext::*pTransitionAction )( const Event & ),
   1.119 +      const Event & evt
   1.120 +    ) :
   1.121 +      pTransitionAction_( pTransitionAction ),
   1.122 +      evt_( evt )
   1.123 +    {
   1.124 +    }
   1.125 +
   1.126 +    template< class CommonContext >
   1.127 +    void operator()( CommonContext & commonContext ) const
   1.128 +    {
   1.129 +      ( commonContext.template context< TransitionContext >()
   1.130 +        .*pTransitionAction_ )( evt_ );
   1.131 +    }
   1.132 +
   1.133 +  private:
   1.134 +    void ( TransitionContext::*pTransitionAction_ )( const Event & );
   1.135 +    const Event & evt_;
   1.136 +};
   1.137 +
   1.138 +
   1.139 +template< bool contextHasInheritedDeepHistory, bool contextHasDeepHistory >
   1.140 +struct deep_history_storer
   1.141 +{
   1.142 +  template< class HistorizedState, class LeafState, class Context >
   1.143 +  static void store_deep_history( Context & ) {}
   1.144 +};
   1.145 +
   1.146 +template<>
   1.147 +struct deep_history_storer< true, false >
   1.148 +{
   1.149 +  template< class HistorizedState, class LeafState, class Context >
   1.150 +  static void store_deep_history( Context & ctx )
   1.151 +  {
   1.152 +    ctx.template store_deep_history_impl< LeafState >();
   1.153 +  }
   1.154 +};
   1.155 +
   1.156 +template<>
   1.157 +struct deep_history_storer< true, true >
   1.158 +{
   1.159 +  template< class HistorizedState, class LeafState, class Context >
   1.160 +  static void store_deep_history( Context & ctx )
   1.161 +  {
   1.162 +    ctx.outermost_context_base().template store_deep_history<
   1.163 +      HistorizedState, LeafState >();
   1.164 +    ctx.template store_deep_history_impl< LeafState >();
   1.165 +  }
   1.166 +};
   1.167 +
   1.168 +
   1.169 +
   1.170 +} // namespace detail
   1.171 +
   1.172 +
   1.173 +
   1.174 +//////////////////////////////////////////////////////////////////////////////
   1.175 +enum history_mode
   1.176 +{
   1.177 +  has_no_history,
   1.178 +  has_shallow_history,
   1.179 +  has_deep_history,
   1.180 +  has_full_history // shallow & deep
   1.181 +};
   1.182 +
   1.183 +
   1.184 +
   1.185 +//////////////////////////////////////////////////////////////////////////////
   1.186 +template< class MostDerived,
   1.187 +          class Context,
   1.188 +          class InnerInitial = mpl::list<>,
   1.189 +          history_mode historyMode = has_no_history >
   1.190 +class simple_state : public detail::simple_state_base_type< MostDerived,
   1.191 +  typename Context::inner_context_type, InnerInitial >::type
   1.192 +{
   1.193 +  typedef typename detail::simple_state_base_type<
   1.194 +    MostDerived, typename Context::inner_context_type,
   1.195 +    InnerInitial >::type base_type;
   1.196 +
   1.197 +  public:
   1.198 +    //////////////////////////////////////////////////////////////////////////
   1.199 +    typedef mpl::list<> reactions;
   1.200 +
   1.201 +    typedef typename Context::inner_context_type context_type;
   1.202 +
   1.203 +    template< detail::orthogonal_position_type innerOrthogonalPosition >
   1.204 +    struct orthogonal
   1.205 +    {
   1.206 +      typedef mpl::integral_c<
   1.207 +        detail::orthogonal_position_type,
   1.208 +        innerOrthogonalPosition > inner_orthogonal_position;
   1.209 +      typedef MostDerived inner_context_type;
   1.210 +    };
   1.211 +
   1.212 +    typedef typename context_type::outermost_context_type
   1.213 +      outermost_context_type;
   1.214 +
   1.215 +    outermost_context_type & outermost_context()
   1.216 +    {
   1.217 +      // This assert fails when an attempt is made to access the state machine
   1.218 +      // from a constructor of a state that is *not* a subtype of state<>.
   1.219 +      // To correct this, derive from state<> instead of simple_state<>.
   1.220 +      BOOST_ASSERT( get_pointer( pContext_ ) != 0 );
   1.221 +      return pContext_->outermost_context();
   1.222 +    }
   1.223 +
   1.224 +    const outermost_context_type & outermost_context() const
   1.225 +    {
   1.226 +      // This assert fails when an attempt is made to access the state machine
   1.227 +      // from a constructor of a state that is *not* a subtype of state<>.
   1.228 +      // To correct this, derive from state<> instead of simple_state<>.
   1.229 +      BOOST_ASSERT( get_pointer( pContext_ ) != 0 );
   1.230 +      return pContext_->outermost_context();
   1.231 +    }
   1.232 +
   1.233 +    template< class OtherContext >
   1.234 +    OtherContext & context()
   1.235 +    {
   1.236 +      typedef typename mpl::if_<
   1.237 +        is_same< OtherContext, MostDerived >,
   1.238 +        context_impl_this_context,
   1.239 +        context_impl_other_context
   1.240 +      >::type impl;
   1.241 +      return impl::template context_impl< OtherContext >( *this );
   1.242 +    }
   1.243 +
   1.244 +    template< class OtherContext >
   1.245 +    const OtherContext & context() const
   1.246 +    {
   1.247 +      typedef typename mpl::if_<
   1.248 +        is_same< OtherContext, MostDerived >,
   1.249 +        context_impl_this_context,
   1.250 +        context_impl_other_context
   1.251 +      >::type impl;
   1.252 +      return impl::template context_impl< OtherContext >( *this );
   1.253 +    }
   1.254 +
   1.255 +    template< class Target >
   1.256 +    Target state_cast() const
   1.257 +    {
   1.258 +      return outermost_context_base().template state_cast< Target >();
   1.259 +    }
   1.260 +
   1.261 +    template< class Target >
   1.262 +    Target state_downcast() const
   1.263 +    {
   1.264 +      return outermost_context_base().template state_downcast< Target >();
   1.265 +    }
   1.266 +
   1.267 +    typedef typename context_type::state_base_type state_base_type;
   1.268 +    typedef typename context_type::state_iterator state_iterator;
   1.269 +
   1.270 +    state_iterator state_begin() const
   1.271 +    {
   1.272 +      return outermost_context_base().state_begin();
   1.273 +    }
   1.274 +
   1.275 +    state_iterator state_end() const
   1.276 +    {
   1.277 +      return outermost_context_base().state_end();
   1.278 +    }
   1.279 +
   1.280 +
   1.281 +    typedef typename context_type::event_base_ptr_type event_base_ptr_type;
   1.282 +
   1.283 +    void post_event( const event_base_ptr_type & pEvent )
   1.284 +    {
   1.285 +      outermost_context_base().post_event( pEvent );
   1.286 +    }
   1.287 +
   1.288 +    void post_event( const event_base & evt )
   1.289 +    {
   1.290 +      outermost_context_base().post_event( evt );
   1.291 +    }
   1.292 +
   1.293 +    result discard_event()
   1.294 +    {
   1.295 +      return detail::result_utility::make_result( detail::do_discard_event );
   1.296 +    }
   1.297 +
   1.298 +    result forward_event()
   1.299 +    {
   1.300 +      return detail::result_utility::make_result( detail::do_forward_event );
   1.301 +    }
   1.302 +
   1.303 +    result defer_event()
   1.304 +    {
   1.305 +      this->state_base_type::defer_event();
   1.306 +      return detail::result_utility::make_result( detail::do_defer_event );
   1.307 +    }
   1.308 +
   1.309 +    template< class DestinationState >
   1.310 +    result transit()
   1.311 +    {
   1.312 +      return transit_impl< DestinationState, outermost_context_type >(
   1.313 +        detail::no_transition_function() );
   1.314 +    }
   1.315 +
   1.316 +    template< class DestinationState, class TransitionContext, class Event >
   1.317 +    result transit(
   1.318 +      void ( TransitionContext::*pTransitionAction )( const Event & ),
   1.319 +      const Event & evt )
   1.320 +    {
   1.321 +      return transit_impl< DestinationState, TransitionContext >(
   1.322 +        detail::transition_function< TransitionContext, Event >(
   1.323 +          pTransitionAction, evt ) );
   1.324 +    }
   1.325 +
   1.326 +    result terminate()
   1.327 +    {
   1.328 +      outermost_context_base().terminate_as_reaction( *this );
   1.329 +      return detail::result_utility::make_result( detail::do_discard_event );
   1.330 +    }
   1.331 +
   1.332 +    template<
   1.333 +      class HistoryContext,
   1.334 +      detail::orthogonal_position_type orthogonalPosition >
   1.335 +    void clear_shallow_history()
   1.336 +    {
   1.337 +      outermost_context_base().template clear_shallow_history<
   1.338 +        HistoryContext, orthogonalPosition >();
   1.339 +    }
   1.340 +
   1.341 +    template<
   1.342 +      class HistoryContext,
   1.343 +      detail::orthogonal_position_type orthogonalPosition >
   1.344 +    void clear_deep_history()
   1.345 +    {
   1.346 +      outermost_context_base().template clear_deep_history<
   1.347 +        HistoryContext, orthogonalPosition >();
   1.348 +    }
   1.349 +
   1.350 +  protected:
   1.351 +    //////////////////////////////////////////////////////////////////////////
   1.352 +    simple_state() : pContext_( 0 ) {}
   1.353 +
   1.354 +    ~simple_state()
   1.355 +    {
   1.356 +      // As a result of a throwing derived class constructor, this destructor
   1.357 +      // can be called before the context is set.
   1.358 +      if ( get_pointer( pContext_ ) != 0 )
   1.359 +      {
   1.360 +        if ( this->deferred_events() )
   1.361 +        {
   1.362 +          outermost_context_base().release_events( this );
   1.363 +        }
   1.364 +
   1.365 +        pContext_->remove_inner_state( orthogonal_position::value );
   1.366 +      }
   1.367 +    }
   1.368 +
   1.369 +  public:
   1.370 +    //////////////////////////////////////////////////////////////////////////
   1.371 +    // The following declarations should be private.
   1.372 +    // They are only public because many compilers lack template friends.
   1.373 +    //////////////////////////////////////////////////////////////////////////
   1.374 +    typedef typename Context::inner_orthogonal_position orthogonal_position;
   1.375 +
   1.376 +    // If you receive a
   1.377 +    // "use of undefined type 'boost::STATIC_ASSERTION_FAILURE<x>'" or similar
   1.378 +    // compiler error here then either this state resides in a non-existent
   1.379 +    // orthogonal region of the outer state or the outer state does not have
   1.380 +    // inner states.
   1.381 +    BOOST_STATIC_ASSERT( ( mpl::less<
   1.382 +      orthogonal_position,
   1.383 +      typename context_type::no_of_orthogonal_regions >::value ) );
   1.384 +
   1.385 +    typedef MostDerived inner_context_type;
   1.386 +    typedef mpl::integral_c< detail::orthogonal_position_type, 0 >
   1.387 +      inner_orthogonal_position;
   1.388 +
   1.389 +    typedef typename context_type::event_base_type event_base_type;
   1.390 +    typedef typename context_type::rtti_policy_type rtti_policy_type;
   1.391 +
   1.392 +    typedef typename context_type::outermost_context_base_type
   1.393 +      outermost_context_base_type;
   1.394 +    typedef typename context_type::inner_context_ptr_type context_ptr_type;
   1.395 +    typedef typename context_type::state_list_type state_list_type;
   1.396 +    typedef intrusive_ptr< inner_context_type > inner_context_ptr_type;
   1.397 +    typedef typename detail::make_list< InnerInitial >::type
   1.398 +      inner_initial_list;
   1.399 +    typedef typename mpl::size< inner_initial_list >::type
   1.400 +      inner_initial_list_size;
   1.401 +    typedef mpl::integral_c<
   1.402 +      detail::orthogonal_position_type,
   1.403 +      inner_initial_list_size::value > no_of_orthogonal_regions;
   1.404 +    typedef typename mpl::push_front<
   1.405 +      typename context_type::context_type_list,
   1.406 +      context_type >::type context_type_list;
   1.407 +
   1.408 +    // If you receive a
   1.409 +    // "use of undefined type 'boost::STATIC_ASSERTION_FAILURE<x>'" or similar
   1.410 +    // compiler error here then the direct or indirect context of this state
   1.411 +    // has deep history _and_ this state has two or more orthogonal regions.
   1.412 +    // Boost.Statechart does not currently support deep history in a state whose
   1.413 +    // direct or indirect inner states have two or more orthogonal regions.
   1.414 +    // Please consult the documentation on how to work around this limitation.
   1.415 +    BOOST_STATIC_ASSERT( ( mpl::or_<
   1.416 +      mpl::less<
   1.417 +        no_of_orthogonal_regions,
   1.418 +        mpl::integral_c< detail::orthogonal_position_type, 2 > >,
   1.419 +      mpl::not_<
   1.420 +        typename context_type::inherited_deep_history > >::value ) );
   1.421 +
   1.422 +    typedef mpl::bool_< ( historyMode & has_shallow_history ) != 0 >
   1.423 +      shallow_history;
   1.424 +    typedef typename context_type::shallow_history stores_shallow_history;
   1.425 +
   1.426 +    typedef mpl::bool_< ( historyMode & has_deep_history ) != 0 >
   1.427 +      deep_history;
   1.428 +    typedef typename mpl::or_<
   1.429 +      deep_history, 
   1.430 +      typename context_type::inherited_deep_history
   1.431 +    >::type inherited_deep_history;
   1.432 +    typedef typename mpl::and_<
   1.433 +      inherited_deep_history,
   1.434 +      mpl::empty< inner_initial_list > >::type stores_deep_history;
   1.435 +
   1.436 +    void * operator new( std::size_t size )
   1.437 +    {
   1.438 +      return detail::allocate< MostDerived,
   1.439 +        typename outermost_context_type::allocator_type >( size );
   1.440 +    }
   1.441 +
   1.442 +    void operator delete( void * pState )
   1.443 +    {
   1.444 +      detail::deallocate< MostDerived,
   1.445 +        typename outermost_context_type::allocator_type >( pState );
   1.446 +    }
   1.447 +
   1.448 +    outermost_context_base_type & outermost_context_base()
   1.449 +    {
   1.450 +      // This assert fails when an attempt is made to access the state machine
   1.451 +      // from a constructor of a state that is *not* a subtype of state<>.
   1.452 +      // To correct this, derive from state<> instead of simple_state<>.
   1.453 +      BOOST_ASSERT( get_pointer( pContext_ ) != 0 );
   1.454 +      return pContext_->outermost_context_base();
   1.455 +    }
   1.456 +
   1.457 +    const outermost_context_base_type & outermost_context_base() const
   1.458 +    {
   1.459 +      // This assert fails when an attempt is made to access the state machine
   1.460 +      // from a constructor of a state that is *not* a subtype of state<>.
   1.461 +      // To correct this, derive from state<> instead of simple_state<>.
   1.462 +      BOOST_ASSERT( get_pointer( pContext_ ) != 0 );
   1.463 +      return pContext_->outermost_context_base();
   1.464 +    }
   1.465 +
   1.466 +    virtual const state_base_type * outer_state_ptr() const
   1.467 +    {
   1.468 +      typedef typename mpl::if_<
   1.469 +        is_same< outermost_context_type, context_type >,
   1.470 +        outer_state_ptr_impl_outermost,
   1.471 +        outer_state_ptr_impl_non_outermost
   1.472 +      >::type impl;
   1.473 +      return impl::outer_state_ptr_impl( *this );
   1.474 +    }
   1.475 +
   1.476 +    virtual detail::reaction_result react_impl(
   1.477 +      const event_base_type & evt,
   1.478 +      typename rtti_policy_type::id_type eventType )
   1.479 +    {
   1.480 +      typedef typename detail::make_list<
   1.481 +        typename MostDerived::reactions >::type reaction_list;
   1.482 +      detail::reaction_result reactionResult =
   1.483 +        local_react< reaction_list >( evt, eventType );
   1.484 +
   1.485 +      // At this point we can only safely access pContext_ if the handler did
   1.486 +      // not return do_discard_event!
   1.487 +      switch ( reactionResult )
   1.488 +      {
   1.489 +        case detail::do_forward_event:
   1.490 +          // TODO: The following call to react_impl of our outer state should
   1.491 +          // be made with a context_type:: prefix to call directly instead of
   1.492 +          // virtually. For some reason the compiler complains...
   1.493 +          reactionResult = pContext_->react_impl( evt, eventType );
   1.494 +          break;
   1.495 +        case detail::do_defer_event:
   1.496 +          outermost_context_base().defer_event( evt, this );
   1.497 +          break;
   1.498 +        default:
   1.499 +          break;
   1.500 +      }
   1.501 +
   1.502 +      return reactionResult;
   1.503 +    }
   1.504 +
   1.505 +    virtual void exit_impl(
   1.506 +      typename base_type::direct_state_base_ptr_type & pSelf,
   1.507 +      typename state_base_type::node_state_base_ptr_type &
   1.508 +        pOutermostUnstableState,
   1.509 +      bool performFullExit )
   1.510 +    {
   1.511 +      inner_context_ptr_type pMostDerivedSelf =
   1.512 +        polymorphic_downcast< MostDerived * >( this );
   1.513 +      pSelf = 0;
   1.514 +      exit_impl( pMostDerivedSelf, pOutermostUnstableState, performFullExit );
   1.515 +    }
   1.516 +
   1.517 +    void exit_impl(
   1.518 +      inner_context_ptr_type & pSelf,
   1.519 +      typename state_base_type::node_state_base_ptr_type &
   1.520 +        pOutermostUnstableState,
   1.521 +      bool performFullExit )
   1.522 +    {
   1.523 +      switch ( this->ref_count() )
   1.524 +      {
   1.525 +        case 2:
   1.526 +          if ( get_pointer( pOutermostUnstableState ) ==
   1.527 +            static_cast< state_base_type * >( this ) )
   1.528 +          {
   1.529 +            pContext_->set_outermost_unstable_state(
   1.530 +              pOutermostUnstableState );
   1.531 +            // fall through to next case intended
   1.532 +          }
   1.533 +          else
   1.534 +          {
   1.535 +            break;
   1.536 +          }
   1.537 +        case 1:
   1.538 +        {
   1.539 +          if ( get_pointer( pOutermostUnstableState ) == 0 )
   1.540 +          {
   1.541 +            pContext_->set_outermost_unstable_state(
   1.542 +              pOutermostUnstableState );
   1.543 +          }
   1.544 +
   1.545 +          if ( performFullExit )
   1.546 +          {
   1.547 +            pSelf->exit();
   1.548 +            check_store_shallow_history< stores_shallow_history >();
   1.549 +            check_store_deep_history< stores_deep_history >();
   1.550 +          }
   1.551 +
   1.552 +          context_ptr_type pContext = pContext_;
   1.553 +          pSelf = 0;
   1.554 +          pContext->exit_impl(
   1.555 +            pContext, pOutermostUnstableState, performFullExit );
   1.556 +          break;
   1.557 +        }
   1.558 +        default:
   1.559 +          break;
   1.560 +      }
   1.561 +    }
   1.562 +
   1.563 +    void set_outermost_unstable_state(
   1.564 +      typename state_base_type::node_state_base_ptr_type &
   1.565 +        pOutermostUnstableState )
   1.566 +    {
   1.567 +      pOutermostUnstableState = this;
   1.568 +    }
   1.569 +
   1.570 +    template< class OtherContext >
   1.571 +    const typename OtherContext::inner_context_ptr_type & context_ptr() const
   1.572 +    {
   1.573 +      typedef typename mpl::if_<
   1.574 +        is_same< OtherContext, context_type >,
   1.575 +        context_ptr_impl_my_context,
   1.576 +        context_ptr_impl_other_context
   1.577 +      >::type impl;
   1.578 +
   1.579 +      return impl::template context_ptr_impl< OtherContext >( *this );
   1.580 +    }
   1.581 +
   1.582 +    static void initial_deep_construct(
   1.583 +      outermost_context_base_type & outermostContextBase )
   1.584 +    {
   1.585 +      deep_construct( &outermostContextBase, outermostContextBase );
   1.586 +    }
   1.587 +
   1.588 +    static void deep_construct(
   1.589 +      const context_ptr_type & pContext,
   1.590 +      outermost_context_base_type & outermostContextBase )
   1.591 +    {
   1.592 +      const inner_context_ptr_type pInnerContext(
   1.593 +        shallow_construct( pContext, outermostContextBase ) );
   1.594 +      deep_construct_inner< inner_initial_list >(
   1.595 +        pInnerContext, outermostContextBase );
   1.596 +    }
   1.597 +
   1.598 +    static inner_context_ptr_type shallow_construct(
   1.599 +      const context_ptr_type & pContext,
   1.600 +      outermost_context_base_type & outermostContextBase )
   1.601 +    {
   1.602 +      const inner_context_ptr_type pInnerContext( new MostDerived );
   1.603 +      pInnerContext->set_context( pContext );
   1.604 +      outermostContextBase.add( pInnerContext );
   1.605 +      return pInnerContext;
   1.606 +    }
   1.607 +
   1.608 +    void set_context( const context_ptr_type & pContext )
   1.609 +    {
   1.610 +      BOOST_ASSERT( get_pointer( pContext ) != 0 );
   1.611 +      pContext_ = pContext;
   1.612 +      base_type::set_context(
   1.613 +        orthogonal_position::value, get_pointer( pContext ) );
   1.614 +    }
   1.615 +
   1.616 +    template< class InnerList >
   1.617 +    static void deep_construct_inner(
   1.618 +      const inner_context_ptr_type & pInnerContext,
   1.619 +      outermost_context_base_type & outermostContextBase )
   1.620 +    {
   1.621 +      typedef typename mpl::if_<
   1.622 +        mpl::empty< InnerList >,
   1.623 +        deep_construct_inner_impl_empty,
   1.624 +        deep_construct_inner_impl_non_empty
   1.625 +      >::type impl;
   1.626 +      impl::template deep_construct_inner_impl< InnerList >(
   1.627 +        pInnerContext, outermostContextBase );
   1.628 +    }
   1.629 +
   1.630 +    template< class LeafState >
   1.631 +    void store_deep_history_impl()
   1.632 +    {
   1.633 +      detail::deep_history_storer<
   1.634 +        context_type::inherited_deep_history::value,
   1.635 +        context_type::deep_history::value
   1.636 +      >::template store_deep_history< MostDerived, LeafState >(
   1.637 +        *pContext_ );
   1.638 +    }
   1.639 +
   1.640 +  private:
   1.641 +    //////////////////////////////////////////////////////////////////////////
   1.642 +    struct context_ptr_impl_other_context
   1.643 +    {
   1.644 +      template< class OtherContext, class State >
   1.645 +      static const typename OtherContext::inner_context_ptr_type &
   1.646 +      context_ptr_impl( const State & stt )
   1.647 +      {
   1.648 +        // This assert fails when an attempt is made to access an outer 
   1.649 +        // context from a constructor of a state that is *not* a subtype of
   1.650 +        // state<>. To correct this, derive from state<> instead of
   1.651 +        // simple_state<>.
   1.652 +        BOOST_ASSERT( get_pointer( stt.pContext_ ) != 0 );
   1.653 +        return stt.pContext_->template context_ptr< OtherContext >();
   1.654 +      }
   1.655 +    };
   1.656 +    friend struct context_ptr_impl_other_context;
   1.657 +
   1.658 +    struct context_ptr_impl_my_context
   1.659 +    {
   1.660 +      template< class OtherContext, class State >
   1.661 +      static const typename OtherContext::inner_context_ptr_type &
   1.662 +      context_ptr_impl( const State & stt )
   1.663 +      {
   1.664 +        // This assert fails when an attempt is made to access an outer 
   1.665 +        // context from a constructor of a state that is *not* a subtype of
   1.666 +        // state<>. To correct this, derive from state<> instead of
   1.667 +        // simple_state<>.
   1.668 +        BOOST_ASSERT( get_pointer( stt.pContext_ ) != 0 );
   1.669 +        return stt.pContext_;
   1.670 +      }
   1.671 +    };
   1.672 +    friend struct context_ptr_impl_my_context;
   1.673 +
   1.674 +    struct context_impl_other_context
   1.675 +    {
   1.676 +      template< class OtherContext, class State >
   1.677 +      static OtherContext & context_impl( State & stt )
   1.678 +      {
   1.679 +        // This assert fails when an attempt is made to access an outer 
   1.680 +        // context from a constructor of a state that is *not* a subtype of
   1.681 +        // state<>. To correct this, derive from state<> instead of
   1.682 +        // simple_state<>.
   1.683 +        BOOST_ASSERT( get_pointer( stt.pContext_ ) != 0 );
   1.684 +        return stt.pContext_->template context< OtherContext >();
   1.685 +      }
   1.686 +    };
   1.687 +    friend struct context_impl_other_context;
   1.688 +
   1.689 +    struct context_impl_this_context
   1.690 +    {
   1.691 +      template< class OtherContext, class State >
   1.692 +      static OtherContext & context_impl( State & stt )
   1.693 +      {
   1.694 +        return *polymorphic_downcast< MostDerived * >( &stt );
   1.695 +      }
   1.696 +    };
   1.697 +    friend struct context_impl_this_context;
   1.698 +
   1.699 +    template< class DestinationState,
   1.700 +              class TransitionContext,
   1.701 +              class TransitionAction >
   1.702 +    result transit_impl( const TransitionAction & transitionAction )
   1.703 +    {
   1.704 +      typedef typename mpl::find_if<
   1.705 +        context_type_list,
   1.706 +        mpl::contains<
   1.707 +          typename DestinationState::context_type_list,
   1.708 +          mpl::placeholders::_ > >::type common_context_iter;
   1.709 +      typedef typename mpl::deref< common_context_iter >::type
   1.710 +        common_context_type;
   1.711 +      typedef typename mpl::distance<
   1.712 +        typename mpl::begin< context_type_list >::type,
   1.713 +        common_context_iter >::type termination_state_position;
   1.714 +      typedef typename mpl::push_front< context_type_list, MostDerived >::type
   1.715 +        possible_transition_contexts;
   1.716 +      typedef typename mpl::at<
   1.717 +        possible_transition_contexts,
   1.718 +        termination_state_position >::type termination_state_type;
   1.719 +
   1.720 +      termination_state_type & terminationState(
   1.721 +        context< termination_state_type >() );
   1.722 +      const typename
   1.723 +        common_context_type::inner_context_ptr_type pCommonContext(
   1.724 +          terminationState.context_ptr< common_context_type >() );
   1.725 +      outermost_context_base_type & outermostContextBase(
   1.726 +        pCommonContext->outermost_context_base() );
   1.727 +
   1.728 +      #ifdef BOOST_STATECHART_RELAX_TRANSITION_CONTEXT
   1.729 +      typedef typename mpl::distance<
   1.730 +        typename mpl::begin< possible_transition_contexts >::type,
   1.731 +        typename mpl::find<
   1.732 +          possible_transition_contexts, TransitionContext >::type
   1.733 +      >::type proposed_transition_context_position;
   1.734 +
   1.735 +      typedef typename mpl::plus<
   1.736 +        termination_state_position,
   1.737 +        mpl::long_< 1 >
   1.738 +      >::type uml_transition_context_position;
   1.739 +
   1.740 +      typedef typename mpl::deref< typename mpl::max_element<
   1.741 +        mpl::list<
   1.742 +          proposed_transition_context_position,
   1.743 +          uml_transition_context_position >,
   1.744 +        mpl::greater< mpl::placeholders::_, mpl::placeholders::_ >
   1.745 +      >::type >::type real_transition_context_position;
   1.746 +
   1.747 +      typedef typename mpl::at<
   1.748 +        possible_transition_contexts,
   1.749 +        real_transition_context_position >::type real_transition_context_type;
   1.750 +
   1.751 +      #ifdef BOOST_MSVC
   1.752 +      #  pragma warning( push )
   1.753 +      #  pragma warning( disable: 4127 ) // conditional expression is constant
   1.754 +      #endif
   1.755 +      if ( ( proposed_transition_context_position::value == 0 ) &&
   1.756 +           ( inner_initial_list_size::value == 0 ) )
   1.757 +      {
   1.758 +        transitionAction( *polymorphic_downcast< MostDerived * >( this ) );
   1.759 +        outermostContextBase.terminate_as_part_of_transit( terminationState );
   1.760 +      }
   1.761 +      else if ( proposed_transition_context_position::value >=
   1.762 +                uml_transition_context_position::value )
   1.763 +      {
   1.764 +        real_transition_context_type & transitionContext =
   1.765 +          context< real_transition_context_type >();
   1.766 +        outermostContextBase.terminate_as_part_of_transit( terminationState );
   1.767 +        transitionAction( transitionContext );
   1.768 +      }
   1.769 +      else
   1.770 +      {
   1.771 +        typename real_transition_context_type::inner_context_ptr_type
   1.772 +          pTransitionContext = context_ptr< real_transition_context_type >();
   1.773 +        outermostContextBase.terminate_as_part_of_transit(
   1.774 +          *pTransitionContext );
   1.775 +        transitionAction( *pTransitionContext );
   1.776 +        pTransitionContext = 0;
   1.777 +        outermostContextBase.terminate_as_part_of_transit( terminationState );
   1.778 +      }
   1.779 +      #ifdef BOOST_MSVC
   1.780 +      #  pragma warning( pop )
   1.781 +      #endif
   1.782 +      #else
   1.783 +      outermostContextBase.terminate_as_part_of_transit( terminationState );
   1.784 +      transitionAction( *pCommonContext );
   1.785 +      #endif
   1.786 +
   1.787 +      typedef typename detail::make_context_list<
   1.788 +        common_context_type, DestinationState >::type context_list_type;
   1.789 +
   1.790 +      // If you receive a
   1.791 +      // "use of undefined type 'boost::STATIC_ASSERTION_FAILURE<x>'" or
   1.792 +      // similar compiler error here then you tried to make an invalid
   1.793 +      // transition between different orthogonal regions.
   1.794 +      BOOST_STATIC_ASSERT( ( mpl::equal_to<
   1.795 +        typename termination_state_type::orthogonal_position,
   1.796 +        typename mpl::front< context_list_type >::type::orthogonal_position
   1.797 +      >::value ) );
   1.798 +
   1.799 +      detail::constructor<
   1.800 +        context_list_type, outermost_context_base_type >::construct(
   1.801 +          pCommonContext, outermostContextBase );
   1.802 +
   1.803 +      return detail::result_utility::make_result( detail::do_discard_event );
   1.804 +    }
   1.805 +
   1.806 +    struct local_react_impl_non_empty
   1.807 +    {
   1.808 +      template< class ReactionList, class State >
   1.809 +      static detail::reaction_result local_react_impl(
   1.810 +        State & stt,
   1.811 +        const event_base_type & evt,
   1.812 +        typename rtti_policy_type::id_type eventType )
   1.813 +      {
   1.814 +        detail::reaction_result reactionResult =
   1.815 +          mpl::front< ReactionList >::type::react(
   1.816 +            *polymorphic_downcast< MostDerived * >( &stt ),
   1.817 +            evt, eventType );
   1.818 +
   1.819 +        if ( reactionResult == detail::no_reaction )
   1.820 +        {
   1.821 +          reactionResult = stt.template local_react<
   1.822 +            typename mpl::pop_front< ReactionList >::type >(
   1.823 +              evt, eventType );
   1.824 +        }
   1.825 +
   1.826 +        return reactionResult;
   1.827 +      }
   1.828 +    };
   1.829 +    friend struct local_react_impl_non_empty;
   1.830 +
   1.831 +    struct local_react_impl_empty
   1.832 +    {
   1.833 +      template< class ReactionList, class State >
   1.834 +      static detail::reaction_result local_react_impl(
   1.835 +        State &, const event_base_type &, typename rtti_policy_type::id_type )
   1.836 +      {
   1.837 +        return detail::do_forward_event;
   1.838 +      }
   1.839 +    };
   1.840 +
   1.841 +    template< class ReactionList >
   1.842 +    detail::reaction_result local_react(
   1.843 +      const event_base_type & evt,
   1.844 +      typename rtti_policy_type::id_type eventType )
   1.845 +    {
   1.846 +      typedef typename mpl::if_<
   1.847 +        mpl::empty< ReactionList >,
   1.848 +        local_react_impl_empty,
   1.849 +        local_react_impl_non_empty
   1.850 +      >::type impl;
   1.851 +      return impl::template local_react_impl< ReactionList >(
   1.852 +        *this, evt, eventType );
   1.853 +    }
   1.854 +
   1.855 +    struct outer_state_ptr_impl_non_outermost
   1.856 +    {
   1.857 +      template< class State >
   1.858 +      static const state_base_type * outer_state_ptr_impl( const State & stt )
   1.859 +      {
   1.860 +        return get_pointer( stt.pContext_ );
   1.861 +      }
   1.862 +    };
   1.863 +    friend struct outer_state_ptr_impl_non_outermost;
   1.864 +
   1.865 +    struct outer_state_ptr_impl_outermost
   1.866 +    {
   1.867 +      template< class State >
   1.868 +      static const state_base_type * outer_state_ptr_impl( const State & )
   1.869 +      {
   1.870 +        return 0;
   1.871 +      }
   1.872 +    };
   1.873 +
   1.874 +    struct deep_construct_inner_impl_non_empty
   1.875 +    {
   1.876 +      template< class InnerList >
   1.877 +      static void deep_construct_inner_impl(
   1.878 +        const inner_context_ptr_type & pInnerContext,
   1.879 +        outermost_context_base_type & outermostContextBase )
   1.880 +      {
   1.881 +        typedef typename mpl::front< InnerList >::type current_inner;
   1.882 +
   1.883 +        // If you receive a
   1.884 +        // "use of undefined type 'boost::STATIC_ASSERTION_FAILURE<x>'" or
   1.885 +        // similar compiler error here then there is a mismatch between the
   1.886 +        // orthogonal position of a state and its position in the inner
   1.887 +        // initial list of its outer state.
   1.888 +        BOOST_STATIC_ASSERT( ( is_same<
   1.889 +          current_inner,
   1.890 +          typename mpl::at<
   1.891 +            typename current_inner::context_type::inner_initial_list,
   1.892 +            typename current_inner::orthogonal_position >::type >::value ) );
   1.893 +
   1.894 +        current_inner::deep_construct( pInnerContext, outermostContextBase );
   1.895 +        deep_construct_inner< typename mpl::pop_front< InnerList >::type >(
   1.896 +          pInnerContext, outermostContextBase );
   1.897 +      }
   1.898 +    };
   1.899 +
   1.900 +    struct deep_construct_inner_impl_empty
   1.901 +    {
   1.902 +      template< class InnerList >
   1.903 +      static void deep_construct_inner_impl(
   1.904 +        const inner_context_ptr_type &, outermost_context_base_type & ) {}
   1.905 +    };
   1.906 +
   1.907 +    struct check_store_shallow_history_impl_no
   1.908 +    {
   1.909 +      template< class State >
   1.910 +      static void check_store_shallow_history_impl( State & ) {}
   1.911 +    };
   1.912 +
   1.913 +    struct check_store_shallow_history_impl_yes
   1.914 +    {
   1.915 +      template< class State >
   1.916 +      static void check_store_shallow_history_impl( State & stt )
   1.917 +      {
   1.918 +        stt.outermost_context_base().template store_shallow_history<
   1.919 +          MostDerived >();
   1.920 +      }
   1.921 +    };
   1.922 +    friend struct check_store_shallow_history_impl_yes;
   1.923 +
   1.924 +    template< class StoreShallowHistory >
   1.925 +    void check_store_shallow_history()
   1.926 +    {
   1.927 +      typedef typename mpl::if_<
   1.928 +        StoreShallowHistory,
   1.929 +        check_store_shallow_history_impl_yes,
   1.930 +        check_store_shallow_history_impl_no
   1.931 +      >::type impl;
   1.932 +      impl::check_store_shallow_history_impl( *this );
   1.933 +    }
   1.934 +
   1.935 +    struct check_store_deep_history_impl_no
   1.936 +    {
   1.937 +      template< class State >
   1.938 +      static void check_store_deep_history_impl( State & ) {}
   1.939 +    };
   1.940 +
   1.941 +    struct check_store_deep_history_impl_yes
   1.942 +    {
   1.943 +      template< class State >
   1.944 +      static void check_store_deep_history_impl( State & stt )
   1.945 +      {
   1.946 +        stt.store_deep_history_impl< MostDerived >();
   1.947 +      }
   1.948 +    };
   1.949 +    friend struct check_store_deep_history_impl_yes;
   1.950 +
   1.951 +    template< class StoreDeepHistory >
   1.952 +    void check_store_deep_history()
   1.953 +    {
   1.954 +      typedef typename mpl::if_<
   1.955 +        StoreDeepHistory,
   1.956 +        check_store_deep_history_impl_yes,
   1.957 +        check_store_deep_history_impl_no
   1.958 +      >::type impl;
   1.959 +      impl::check_store_deep_history_impl( *this );
   1.960 +    }
   1.961 +
   1.962 +
   1.963 +    context_ptr_type pContext_;
   1.964 +};
   1.965 +
   1.966 +
   1.967 +
   1.968 +#ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
   1.969 +} // namespace statechart
   1.970 +#endif
   1.971 +
   1.972 +
   1.973 +
   1.974 +template< class MostDerived, class Context,
   1.975 +          class InnerInitial, history_mode historyMode >
   1.976 +inline void intrusive_ptr_release( const ::boost::statechart::simple_state<
   1.977 +  MostDerived, Context, InnerInitial, historyMode > * pBase )
   1.978 +{
   1.979 +  if ( pBase->release() )
   1.980 +  {
   1.981 +    // The cast is necessary because the simple_state destructor is non-
   1.982 +    // virtual (and inaccessible from this context)
   1.983 +    delete polymorphic_downcast< const MostDerived * >( pBase );
   1.984 +  }
   1.985 +}
   1.986 +
   1.987 +
   1.988 +
   1.989 +#ifndef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
   1.990 +} // namespace statechart
   1.991 +#endif
   1.992 +
   1.993 +
   1.994 +
   1.995 +} // namespace boost
   1.996 +
   1.997 +
   1.998 +
   1.999 +#endif