| #ifndef BOOST_STATECHART_DETAIL_STATE_BASE_HPP_INCLUDED |
| #define BOOST_STATECHART_DETAIL_STATE_BASE_HPP_INCLUDED |
| ////////////////////////////////////////////////////////////////////////////// |
| // Copyright 2002-2008 Andreas Huber Doenni |
| // Distributed under the Boost Software License, Version 1.0. (See accompany- |
| // ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
| ////////////////////////////////////////////////////////////////////////////// |
| |
| |
| |
| #include <boost/statechart/result.hpp> |
| #include <boost/statechart/event.hpp> |
| |
| #include <boost/statechart/detail/counted_base.hpp> |
| |
| #include <boost/intrusive_ptr.hpp> |
| #include <boost/noncopyable.hpp> |
| #include <boost/assert.hpp> |
| #include <boost/config.hpp> // BOOST_MSVC |
| |
| #include <boost/detail/workaround.hpp> |
| #include <boost/detail/allocator_utilities.hpp> |
| |
| #ifdef BOOST_MSVC |
| # pragma warning( push ) |
| # pragma warning( disable: 4702 ) // unreachable code (in release mode only) |
| #endif |
| |
| #include <list> |
| |
| #ifdef BOOST_MSVC |
| # pragma warning( pop ) |
| #endif |
| |
| |
| |
| namespace boost |
| { |
| namespace statechart |
| { |
| namespace detail |
| { |
| |
| |
| |
| template< class Allocator, class RttiPolicy > |
| class leaf_state; |
| template< class Allocator, class RttiPolicy > |
| class node_state_base; |
| |
| typedef unsigned char orthogonal_position_type; |
| |
| |
| |
| ////////////////////////////////////////////////////////////////////////////// |
| template< class Allocator, class RttiPolicy > |
| class state_base : |
| #ifndef NDEBUG |
| noncopyable, |
| #endif |
| public RttiPolicy::template rtti_base_type< |
| // Derived class objects will be created, handled and destroyed by exactly |
| // one thread --> locking is not necessary |
| counted_base< false > > |
| { |
| typedef typename RttiPolicy::template rtti_base_type< |
| counted_base< false > > base_type; |
| |
| public: |
| ////////////////////////////////////////////////////////////////////////// |
| void exit() {} |
| |
| virtual const state_base * outer_state_ptr() const = 0; |
| |
| protected: |
| ////////////////////////////////////////////////////////////////////////// |
| state_base( typename RttiPolicy::id_provider_type idProvider ) : |
| base_type( idProvider ), |
| deferredEvents_( false ) |
| { |
| } |
| |
| #if BOOST_WORKAROUND( __GNUC__, BOOST_TESTED_AT( 4 ) ) |
| // We make the destructor virtual for GCC because with this compiler there |
| // is currently no way to disable the "has virtual functions but |
| // non-virtual destructor" warning on a class by class basis. Although it |
| // can be done on the compiler command line with -Wno-non-virtual-dtor, |
| // this is undesirable as this would also suppress legitimate warnings for |
| // types that are not states. |
| virtual ~state_base() {} |
| #else |
| // This destructor is not virtual for performance reasons. The library |
| // ensures that a state object is never deleted through a state_base |
| // pointer but only through a pointer to the most-derived type. |
| ~state_base() {} |
| #endif |
| |
| protected: |
| ////////////////////////////////////////////////////////////////////////// |
| // The following declarations should be private. |
| // They are only protected because many compilers lack template friends. |
| ////////////////////////////////////////////////////////////////////////// |
| void defer_event() |
| { |
| deferredEvents_ = true; |
| } |
| |
| bool deferred_events() const |
| { |
| return deferredEvents_; |
| } |
| |
| template< class Context > |
| void set_context( orthogonal_position_type position, Context * pContext ) |
| { |
| pContext->add_inner_state( position, this ); |
| } |
| |
| public: |
| ////////////////////////////////////////////////////////////////////////// |
| // The following declarations should be private. |
| // They are only public because many compilers lack template friends. |
| ////////////////////////////////////////////////////////////////////////// |
| virtual detail::reaction_result react_impl( |
| const event_base & evt, |
| typename RttiPolicy::id_type eventType ) = 0; |
| |
| typedef intrusive_ptr< node_state_base< Allocator, RttiPolicy > > |
| node_state_base_ptr_type; |
| typedef intrusive_ptr< leaf_state< Allocator, RttiPolicy > > |
| leaf_state_ptr_type; |
| typedef std::list< |
| leaf_state_ptr_type, |
| typename boost::detail::allocator::rebind_to< |
| Allocator, leaf_state_ptr_type >::type |
| > state_list_type; |
| |
| virtual void remove_from_state_list( |
| typename state_list_type::iterator & statesEnd, |
| node_state_base_ptr_type & pOutermostUnstableState, |
| bool performFullExit ) = 0; |
| |
| private: |
| ////////////////////////////////////////////////////////////////////////// |
| bool deferredEvents_; |
| }; |
| |
| |
| |
| #ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP |
| } // namespace detail |
| } // namespace statechart |
| #endif |
| |
| |
| |
| template< class Allocator, class RttiPolicy > |
| inline void intrusive_ptr_add_ref( |
| const ::boost::statechart::detail::state_base< Allocator, RttiPolicy > * pBase ) |
| { |
| pBase->add_ref(); |
| } |
| |
| template< class Allocator, class RttiPolicy > |
| inline void intrusive_ptr_release( |
| const ::boost::statechart::detail::state_base< Allocator, RttiPolicy > * pBase ) |
| { |
| if ( pBase->release() ) |
| { |
| // The state_base destructor is *not* virtual for performance reasons |
| // but intrusive_ptr< state_base > objects are nevertheless used to point |
| // to states. This assert ensures that such a pointer is never the last |
| // one referencing a state object. |
| BOOST_ASSERT( false ); |
| } |
| } |
| |
| |
| |
| #ifndef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP |
| } // namespace detail |
| } // namespace statechart |
| #endif |
| |
| |
| |
| } // namespace boost |
| |
| |
| |
| #endif |