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