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