Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:52:31

0001 #ifndef BOOST_STATECHART_DETAIL_RTTI_POLICY_HPP_INCLUDED
0002 #define BOOST_STATECHART_DETAIL_RTTI_POLICY_HPP_INCLUDED
0003 //////////////////////////////////////////////////////////////////////////////
0004 // Copyright 2002-2008 Andreas Huber Doenni
0005 // Distributed under the Boost Software License, Version 1.0. (See accompany-
0006 // ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0007 //////////////////////////////////////////////////////////////////////////////
0008 
0009 
0010 
0011 #include <boost/assert.hpp>
0012 #include <boost/config.hpp> // BOOST_MSVC
0013 #include <boost/detail/workaround.hpp>
0014 
0015 #include <typeinfo> // std::type_info
0016 
0017 
0018 
0019 namespace boost
0020 {
0021 namespace statechart
0022 {
0023 namespace detail
0024 {
0025 
0026 
0027 
0028 //////////////////////////////////////////////////////////////////////////////
0029 struct id_provider
0030 {
0031   const void * pCustomId_;
0032   #if defined( BOOST_ENABLE_ASSERT_HANDLER ) || !defined( NDEBUG )
0033   const std::type_info * pCustomIdType_;
0034   #endif
0035 };
0036 
0037 template< class MostDerived >
0038 struct id_holder
0039 {
0040   static id_provider idProvider_;
0041 };
0042 
0043 template< class MostDerived >
0044 id_provider id_holder< MostDerived >::idProvider_;
0045 
0046 
0047 
0048 //////////////////////////////////////////////////////////////////////////////
0049 struct rtti_policy
0050 {
0051   #ifdef BOOST_STATECHART_USE_NATIVE_RTTI
0052   class id_type
0053   {
0054     public:
0055       ////////////////////////////////////////////////////////////////////////
0056       explicit id_type( const std::type_info & id ) : id_( id ) {}
0057 
0058       bool operator==( id_type right ) const
0059       {
0060         return ( id_ == right.id_ ) != 0;
0061       }
0062       bool operator!=( id_type right ) const { return !( *this == right ); }
0063 
0064       bool operator<( id_type right ) const
0065       {
0066         return id_.before( right.id_ ) != 0;
0067       }
0068       bool operator>( id_type right ) const { return right < *this; }
0069       bool operator>=( id_type right ) const { return !( *this < right ); }
0070       bool operator<=( id_type right ) const { return !( right < *this ); }
0071 
0072     private:
0073       ////////////////////////////////////////////////////////////////////////
0074       const std::type_info & id_;
0075   };
0076 
0077   typedef bool id_provider_type; // dummy
0078   #else
0079   typedef const void * id_type;
0080   typedef const id_provider * id_provider_type;
0081   #endif
0082 
0083   ////////////////////////////////////////////////////////////////////////////
0084   template< class Base >
0085   class rtti_base_type : public Base
0086   {
0087     public:
0088       ////////////////////////////////////////////////////////////////////////
0089       typedef rtti_policy::id_type id_type;
0090 
0091       id_type dynamic_type() const
0092       {
0093         #ifdef BOOST_STATECHART_USE_NATIVE_RTTI
0094         return id_type( typeid( *this ) );
0095         #else
0096         return idProvider_;
0097         #endif
0098       }
0099 
0100       #ifndef BOOST_STATECHART_USE_NATIVE_RTTI
0101       template< typename CustomId >
0102       const CustomId * custom_dynamic_type_ptr() const
0103       {
0104         BOOST_ASSERT(
0105           ( idProvider_->pCustomId_ == 0 ) ||
0106           ( *idProvider_->pCustomIdType_ == typeid( CustomId ) ) );
0107         return static_cast< const CustomId * >( idProvider_->pCustomId_ );
0108       }
0109       #endif
0110 
0111     protected:
0112     #ifdef BOOST_STATECHART_USE_NATIVE_RTTI
0113       rtti_base_type( id_provider_type ) {}
0114 
0115       ////////////////////////////////////////////////////////////////////////
0116       #if BOOST_WORKAROUND( __GNUC__, BOOST_TESTED_AT( 4 ) )
0117       // We make the destructor virtual for GCC because with this compiler
0118       // there is currently no way to disable the "has virtual functions but
0119       // non-virtual destructor" warning on a class by class basis. Although
0120       // it can be done on the compiler command line with
0121       // -Wno-non-virtual-dtor, this is undesirable as this would also
0122       // suppress legitimate warnings for types that are not states.
0123       virtual ~rtti_base_type() {}
0124       #else
0125       ~rtti_base_type() {}
0126       #endif
0127 
0128     private:
0129       ////////////////////////////////////////////////////////////////////////
0130       // For typeid( *this ) to return a value that corresponds to the most-
0131       // derived type, we need to have a vptr. Since this type does not
0132       // contain any virtual functions we need to artificially declare one so.
0133       virtual void dummy() {}
0134     #else
0135       rtti_base_type(
0136         id_provider_type idProvider
0137       ) :
0138         idProvider_( idProvider )
0139       {
0140       }
0141 
0142       ~rtti_base_type() {}
0143 
0144     private:
0145       ////////////////////////////////////////////////////////////////////////
0146       id_provider_type idProvider_;
0147     #endif
0148   };
0149 
0150   ////////////////////////////////////////////////////////////////////////////
0151   template< class MostDerived, class Base >
0152   class rtti_derived_type : public Base
0153   {
0154     public:
0155       ////////////////////////////////////////////////////////////////////////
0156       static id_type static_type()
0157       {
0158         #ifdef BOOST_STATECHART_USE_NATIVE_RTTI
0159         return id_type( typeid( const MostDerived ) );
0160         #else
0161         return &id_holder< MostDerived >::idProvider_;
0162         #endif
0163       }
0164 
0165       #ifndef BOOST_STATECHART_USE_NATIVE_RTTI
0166       template< class CustomId >
0167       static const CustomId * custom_static_type_ptr()
0168       {
0169         BOOST_ASSERT(
0170           ( id_holder< MostDerived >::idProvider_.pCustomId_ == 0 ) ||
0171           ( *id_holder< MostDerived >::idProvider_.pCustomIdType_ ==
0172             typeid( CustomId ) ) );
0173         return static_cast< const CustomId * >(
0174           id_holder< MostDerived >::idProvider_.pCustomId_ );
0175       }
0176 
0177       template< class CustomId >
0178       static void custom_static_type_ptr( const CustomId * pCustomId )
0179       {
0180         #if defined( BOOST_ENABLE_ASSERT_HANDLER ) || !defined( NDEBUG )
0181         id_holder< MostDerived >::idProvider_.pCustomIdType_ =
0182           &typeid( CustomId );
0183         #endif
0184         id_holder< MostDerived >::idProvider_.pCustomId_ = pCustomId;
0185       }
0186       #endif
0187 
0188     protected:
0189       ////////////////////////////////////////////////////////////////////////
0190       ~rtti_derived_type() {}
0191 
0192       #ifdef BOOST_STATECHART_USE_NATIVE_RTTI
0193       rtti_derived_type() : Base( false ) {}
0194       #else
0195       rtti_derived_type() : Base( &id_holder< MostDerived >::idProvider_ ) {}
0196       #endif
0197   };
0198 };
0199 
0200 
0201 
0202 } // namespace detail
0203 } // namespace statechart
0204 } // namespace boost
0205 
0206 
0207 
0208 #endif