123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208 |
- #ifndef BOOST_STATECHART_DETAIL_RTTI_POLICY_HPP_INCLUDED
- #define BOOST_STATECHART_DETAIL_RTTI_POLICY_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/assert.hpp>
- #include <boost/config.hpp> // BOOST_MSVC
- #include <boost/detail/workaround.hpp>
- #include <typeinfo> // std::type_info
- namespace boost
- {
- namespace statechart
- {
- namespace detail
- {
- //////////////////////////////////////////////////////////////////////////////
- struct id_provider
- {
- const void * pCustomId_;
- #if defined( BOOST_ENABLE_ASSERT_HANDLER ) || !defined( NDEBUG )
- const std::type_info * pCustomIdType_;
- #endif
- };
- template< class MostDerived >
- struct id_holder
- {
- static id_provider idProvider_;
- };
- template< class MostDerived >
- id_provider id_holder< MostDerived >::idProvider_;
- //////////////////////////////////////////////////////////////////////////////
- struct rtti_policy
- {
- #ifdef BOOST_STATECHART_USE_NATIVE_RTTI
- class id_type
- {
- public:
- ////////////////////////////////////////////////////////////////////////
- explicit id_type( const std::type_info & id ) : id_( id ) {}
- bool operator==( id_type right ) const
- {
- return ( id_ == right.id_ ) != 0;
- }
- bool operator!=( id_type right ) const { return !( *this == right ); }
- bool operator<( id_type right ) const
- {
- return id_.before( right.id_ ) != 0;
- }
- bool operator>( id_type right ) const { return right < *this; }
- bool operator>=( id_type right ) const { return !( *this < right ); }
- bool operator<=( id_type right ) const { return !( right < *this ); }
- private:
- ////////////////////////////////////////////////////////////////////////
- const std::type_info & id_;
- };
- typedef bool id_provider_type; // dummy
- #else
- typedef const void * id_type;
- typedef const id_provider * id_provider_type;
- #endif
- ////////////////////////////////////////////////////////////////////////////
- template< class Base >
- class rtti_base_type : public Base
- {
- public:
- ////////////////////////////////////////////////////////////////////////
- typedef rtti_policy::id_type id_type;
- id_type dynamic_type() const
- {
- #ifdef BOOST_STATECHART_USE_NATIVE_RTTI
- return id_type( typeid( *this ) );
- #else
- return idProvider_;
- #endif
- }
- #ifndef BOOST_STATECHART_USE_NATIVE_RTTI
- template< typename CustomId >
- const CustomId * custom_dynamic_type_ptr() const
- {
- BOOST_ASSERT(
- ( idProvider_->pCustomId_ == 0 ) ||
- ( *idProvider_->pCustomIdType_ == typeid( CustomId ) ) );
- return static_cast< const CustomId * >( idProvider_->pCustomId_ );
- }
- #endif
- protected:
- #ifdef BOOST_STATECHART_USE_NATIVE_RTTI
- rtti_base_type( id_provider_type ) {}
- ////////////////////////////////////////////////////////////////////////
- #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 ~rtti_base_type() {}
- #else
- ~rtti_base_type() {}
- #endif
- private:
- ////////////////////////////////////////////////////////////////////////
- // For typeid( *this ) to return a value that corresponds to the most-
- // derived type, we need to have a vptr. Since this type does not
- // contain any virtual functions we need to artificially declare one so.
- virtual void dummy() {}
- #else
- rtti_base_type(
- id_provider_type idProvider
- ) :
- idProvider_( idProvider )
- {
- }
- ~rtti_base_type() {}
- private:
- ////////////////////////////////////////////////////////////////////////
- id_provider_type idProvider_;
- #endif
- };
- ////////////////////////////////////////////////////////////////////////////
- template< class MostDerived, class Base >
- class rtti_derived_type : public Base
- {
- public:
- ////////////////////////////////////////////////////////////////////////
- static id_type static_type()
- {
- #ifdef BOOST_STATECHART_USE_NATIVE_RTTI
- return id_type( typeid( const MostDerived ) );
- #else
- return &id_holder< MostDerived >::idProvider_;
- #endif
- }
- #ifndef BOOST_STATECHART_USE_NATIVE_RTTI
- template< class CustomId >
- static const CustomId * custom_static_type_ptr()
- {
- BOOST_ASSERT(
- ( id_holder< MostDerived >::idProvider_.pCustomId_ == 0 ) ||
- ( *id_holder< MostDerived >::idProvider_.pCustomIdType_ ==
- typeid( CustomId ) ) );
- return static_cast< const CustomId * >(
- id_holder< MostDerived >::idProvider_.pCustomId_ );
- }
- template< class CustomId >
- static void custom_static_type_ptr( const CustomId * pCustomId )
- {
- #if defined( BOOST_ENABLE_ASSERT_HANDLER ) || !defined( NDEBUG )
- id_holder< MostDerived >::idProvider_.pCustomIdType_ =
- &typeid( CustomId );
- #endif
- id_holder< MostDerived >::idProvider_.pCustomId_ = pCustomId;
- }
- #endif
- protected:
- ////////////////////////////////////////////////////////////////////////
- ~rtti_derived_type() {}
- #ifdef BOOST_STATECHART_USE_NATIVE_RTTI
- rtti_derived_type() : Base( false ) {}
- #else
- rtti_derived_type() : Base( &id_holder< MostDerived >::idProvider_ ) {}
- #endif
- };
- };
- } // namespace detail
- } // namespace statechart
- } // namespace boost
- #endif
|