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