PageRenderTime 17ms CodeModel.GetById 8ms app.highlight 7ms RepoModel.GetById 1ms app.codeStats 0ms

/src/contrib/boost/statechart/detail/node_state.hpp

http://pythonocc.googlecode.com/
C++ Header | 156 lines | 102 code | 30 blank | 24 comment | 10 complexity | da429fc0b6f2e66d267bfeacc75aad13 MD5 | raw file
  1#ifndef BOOST_STATECHART_DETAIL_NODE_STATE_HPP_INCLUDED
  2#define BOOST_STATECHART_DETAIL_NODE_STATE_HPP_INCLUDED
  3//////////////////////////////////////////////////////////////////////////////
  4// Copyright 2002-2006 Andreas Huber Doenni
  5// Distributed under the Boost Software License, Version 1.0. (See accompany-
  6// ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  7//////////////////////////////////////////////////////////////////////////////
  8
  9
 10
 11#include <boost/statechart/detail/state_base.hpp>
 12
 13#include <boost/intrusive_ptr.hpp>
 14#include <boost/assert.hpp>  // BOOST_ASSERT
 15
 16#include <algorithm> // std::find_if
 17
 18
 19
 20namespace boost
 21{
 22namespace statechart
 23{
 24namespace detail
 25{
 26
 27
 28
 29template< class Allocator, class RttiPolicy >
 30class node_state_base : public state_base< Allocator, RttiPolicy >
 31{
 32  typedef state_base< Allocator, RttiPolicy > base_type;
 33  protected:
 34    //////////////////////////////////////////////////////////////////////////
 35    node_state_base( typename RttiPolicy::id_provider_type idProvider ) :
 36      base_type( idProvider )
 37    {
 38    }
 39
 40    ~node_state_base() {}
 41
 42  public:
 43    //////////////////////////////////////////////////////////////////////////
 44    // The following declarations should be private.
 45    // They are only public because many compilers lack template friends.
 46    //////////////////////////////////////////////////////////////////////////
 47    typedef base_type state_base_type;
 48    typedef intrusive_ptr< node_state_base > direct_state_base_ptr_type;
 49    virtual void exit_impl(
 50      direct_state_base_ptr_type & pSelf,
 51      typename base_type::node_state_base_ptr_type & pOutermostUnstableState,
 52      bool performFullExit ) = 0;
 53};
 54
 55//////////////////////////////////////////////////////////////////////////////
 56template< class OrthogonalRegionCount, class Allocator, class RttiPolicy >
 57class node_state : public node_state_base< Allocator, RttiPolicy >
 58{
 59  typedef node_state_base< Allocator, RttiPolicy > base_type;
 60  protected:
 61    //////////////////////////////////////////////////////////////////////////
 62    node_state( typename RttiPolicy::id_provider_type idProvider ) :
 63      base_type( idProvider )
 64    {
 65      for ( orthogonal_position_type pos = 0; 
 66            pos < OrthogonalRegionCount::value; ++pos )
 67      {
 68        pInnerStates[ pos ] = 0;
 69      }
 70    }
 71
 72    ~node_state() {}
 73
 74  public:
 75    //////////////////////////////////////////////////////////////////////////
 76    // The following declarations should be private.
 77    // They are only public because many compilers lack template friends.
 78    //////////////////////////////////////////////////////////////////////////
 79    typedef typename base_type::state_base_type state_base_type;
 80
 81    void add_inner_state( orthogonal_position_type position,
 82                          state_base_type * pInnerState )
 83    {
 84      BOOST_ASSERT( ( position < OrthogonalRegionCount::value ) &&
 85                    ( pInnerStates[ position ] == 0 ) );
 86      pInnerStates[ position ] = pInnerState;
 87    }
 88
 89    void remove_inner_state( orthogonal_position_type position )
 90    {
 91      BOOST_ASSERT( position < OrthogonalRegionCount::value );
 92      pInnerStates[ position ] = 0;
 93    }
 94
 95    virtual void remove_from_state_list(
 96      typename state_base_type::state_list_type::iterator & statesEnd,
 97      typename state_base_type::node_state_base_ptr_type &
 98        pOutermostUnstableState,
 99      bool performFullExit )
100    {
101      state_base_type ** const pPastEnd =
102        &pInnerStates[ OrthogonalRegionCount::value ];
103      // We must not iterate past the last inner state because *this* state
104      // will no longer exist when the last inner state has been removed
105      state_base_type ** const pFirstNonNull = std::find_if(
106        &pInnerStates[ 0 ], pPastEnd, &node_state::is_not_null );
107
108      if ( pFirstNonNull == pPastEnd )
109      {
110        // The state does not have inner states but is still alive, this must
111        // be the outermost unstable state then.
112        BOOST_ASSERT( get_pointer( pOutermostUnstableState ) == this );
113        typename state_base_type::node_state_base_ptr_type pSelf =
114          pOutermostUnstableState;
115        pSelf->exit_impl( pSelf, pOutermostUnstableState, performFullExit );
116      }
117      else
118      {
119        // Destroy inner states in the reverse order of construction
120        for ( state_base_type ** pState = pPastEnd; pState != pFirstNonNull; )
121        {
122          --pState;
123
124          // An inner orthogonal state might have been terminated long before,
125          // that's why we have to check for 0 pointers
126          if ( *pState != 0 )
127          {
128            ( *pState )->remove_from_state_list(
129              statesEnd, pOutermostUnstableState, performFullExit );
130          }
131        }
132      }
133    }
134
135    typedef typename base_type::direct_state_base_ptr_type
136      direct_state_base_ptr_type;
137
138  private:
139    //////////////////////////////////////////////////////////////////////////
140    static bool is_not_null( const state_base_type * pInner )
141    {
142      return pInner != 0;
143    }
144
145    state_base_type * pInnerStates[ OrthogonalRegionCount::value ];
146};
147
148
149
150} // namespace detail
151} // namespace statechart
152} // namespace boost
153
154
155
156#endif