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
0005
0006
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;
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
0118
0119
0120
0121
0122
0123 virtual ~rtti_base_type() {}
0124 #else
0125 ~rtti_base_type() {}
0126 #endif
0127
0128 private:
0129
0130
0131
0132
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 }
0203 }
0204 }
0205
0206
0207
0208 #endif