Chris@16: #ifndef BOOST_STATECHART_DETAIL_RTTI_POLICY_HPP_INCLUDED Chris@16: #define BOOST_STATECHART_DETAIL_RTTI_POLICY_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 // BOOST_MSVC Chris@16: #include Chris@16: Chris@16: #include // std::type_info 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: ////////////////////////////////////////////////////////////////////////////// Chris@16: struct id_provider Chris@16: { Chris@16: const void * pCustomId_; Chris@16: #if defined( BOOST_ENABLE_ASSERT_HANDLER ) || !defined( NDEBUG ) Chris@16: const std::type_info * pCustomIdType_; Chris@16: #endif Chris@16: }; Chris@16: Chris@16: template< class MostDerived > Chris@16: struct id_holder Chris@16: { Chris@16: static id_provider idProvider_; Chris@16: }; Chris@16: Chris@16: template< class MostDerived > Chris@16: id_provider id_holder< MostDerived >::idProvider_; Chris@16: Chris@16: Chris@16: Chris@16: ////////////////////////////////////////////////////////////////////////////// Chris@16: struct rtti_policy Chris@16: { Chris@16: #ifdef BOOST_STATECHART_USE_NATIVE_RTTI Chris@16: class id_type Chris@16: { Chris@16: public: Chris@16: //////////////////////////////////////////////////////////////////////// Chris@16: explicit id_type( const std::type_info & id ) : id_( id ) {} Chris@16: Chris@16: bool operator==( id_type right ) const Chris@16: { Chris@16: return id_ == right.id_ != 0; Chris@16: } Chris@16: bool operator!=( id_type right ) const { return !( *this == right ); } Chris@16: Chris@16: bool operator<( id_type right ) const Chris@16: { Chris@16: return id_.before( right.id_ ) != 0; Chris@16: } Chris@16: bool operator>( id_type right ) const { return right < *this; } Chris@16: bool operator>=( id_type right ) const { return !( *this < right ); } Chris@16: bool operator<=( id_type right ) const { return !( right < *this ); } Chris@16: Chris@16: private: Chris@16: //////////////////////////////////////////////////////////////////////// Chris@16: const std::type_info & id_; Chris@16: }; Chris@16: Chris@16: typedef bool id_provider_type; // dummy Chris@16: #else Chris@16: typedef const void * id_type; Chris@16: typedef const id_provider * id_provider_type; Chris@16: #endif Chris@16: Chris@16: //////////////////////////////////////////////////////////////////////////// Chris@16: template< class Base > Chris@16: class rtti_base_type : public Base Chris@16: { Chris@16: public: Chris@16: //////////////////////////////////////////////////////////////////////// Chris@16: typedef rtti_policy::id_type id_type; Chris@16: Chris@16: id_type dynamic_type() const Chris@16: { Chris@16: #ifdef BOOST_STATECHART_USE_NATIVE_RTTI Chris@16: return id_type( typeid( *this ) ); Chris@16: #else Chris@16: return idProvider_; Chris@16: #endif Chris@16: } Chris@16: Chris@16: #ifndef BOOST_STATECHART_USE_NATIVE_RTTI Chris@16: template< typename CustomId > Chris@16: const CustomId * custom_dynamic_type_ptr() const Chris@16: { Chris@16: BOOST_ASSERT( Chris@16: ( idProvider_->pCustomId_ == 0 ) || Chris@16: ( *idProvider_->pCustomIdType_ == typeid( CustomId ) ) ); Chris@16: return static_cast< const CustomId * >( idProvider_->pCustomId_ ); Chris@16: } Chris@16: #endif Chris@16: Chris@16: protected: Chris@16: #ifdef BOOST_STATECHART_USE_NATIVE_RTTI Chris@16: rtti_base_type( id_provider_type ) {} 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 Chris@16: // there is currently no way to disable the "has virtual functions but Chris@16: // non-virtual destructor" warning on a class by class basis. Although Chris@16: // it can be done on the compiler command line with Chris@16: // -Wno-non-virtual-dtor, this is undesirable as this would also Chris@16: // suppress legitimate warnings for types that are not states. Chris@16: virtual ~rtti_base_type() {} Chris@16: #else Chris@16: ~rtti_base_type() {} Chris@16: #endif Chris@16: Chris@16: private: Chris@16: //////////////////////////////////////////////////////////////////////// Chris@16: // For typeid( *this ) to return a value that corresponds to the most- Chris@16: // derived type, we need to have a vptr. Since this type does not Chris@16: // contain any virtual functions we need to artificially declare one so. Chris@16: virtual void dummy() {} Chris@16: #else Chris@16: rtti_base_type( Chris@16: id_provider_type idProvider Chris@16: ) : Chris@16: idProvider_( idProvider ) Chris@16: { Chris@16: } Chris@16: Chris@16: ~rtti_base_type() {} Chris@16: Chris@16: private: Chris@16: //////////////////////////////////////////////////////////////////////// Chris@16: id_provider_type idProvider_; Chris@16: #endif Chris@16: }; Chris@16: Chris@16: //////////////////////////////////////////////////////////////////////////// Chris@16: template< class MostDerived, class Base > Chris@16: class rtti_derived_type : public Base Chris@16: { Chris@16: public: Chris@16: //////////////////////////////////////////////////////////////////////// Chris@16: static id_type static_type() Chris@16: { Chris@16: #ifdef BOOST_STATECHART_USE_NATIVE_RTTI Chris@16: return id_type( typeid( const MostDerived ) ); Chris@16: #else Chris@16: return &id_holder< MostDerived >::idProvider_; Chris@16: #endif Chris@16: } Chris@16: Chris@16: #ifndef BOOST_STATECHART_USE_NATIVE_RTTI Chris@16: template< class CustomId > Chris@16: static const CustomId * custom_static_type_ptr() Chris@16: { Chris@16: BOOST_ASSERT( Chris@16: ( id_holder< MostDerived >::idProvider_.pCustomId_ == 0 ) || Chris@16: ( *id_holder< MostDerived >::idProvider_.pCustomIdType_ == Chris@16: typeid( CustomId ) ) ); Chris@16: return static_cast< const CustomId * >( Chris@16: id_holder< MostDerived >::idProvider_.pCustomId_ ); Chris@16: } Chris@16: Chris@16: template< class CustomId > Chris@16: static void custom_static_type_ptr( const CustomId * pCustomId ) Chris@16: { Chris@16: #if defined( BOOST_ENABLE_ASSERT_HANDLER ) || !defined( NDEBUG ) Chris@16: id_holder< MostDerived >::idProvider_.pCustomIdType_ = Chris@16: &typeid( CustomId ); Chris@16: #endif Chris@16: id_holder< MostDerived >::idProvider_.pCustomId_ = pCustomId; Chris@16: } Chris@16: #endif Chris@16: Chris@16: protected: Chris@16: //////////////////////////////////////////////////////////////////////// Chris@16: ~rtti_derived_type() {} Chris@16: Chris@16: #ifdef BOOST_STATECHART_USE_NATIVE_RTTI Chris@16: rtti_derived_type() : Base( false ) {} Chris@16: #else Chris@16: rtti_derived_type() : Base( &id_holder< MostDerived >::idProvider_ ) {} Chris@16: #endif Chris@16: }; Chris@16: }; Chris@16: Chris@16: Chris@16: Chris@16: } // namespace detail Chris@16: } // namespace statechart Chris@16: } // namespace boost Chris@16: Chris@16: Chris@16: Chris@16: #endif