1 #ifndef BOOST_STATECHART_DETAIL_RTTI_POLICY_HPP_INCLUDED
2 #define BOOST_STATECHART_DETAIL_RTTI_POLICY_HPP_INCLUDED
3 //////////////////////////////////////////////////////////////////////////////
4 // Copyright 2002-2008 Andreas Huber Doenni
5 // Distributed under the Boost Software License, Version 1.0. (See accompany-
6 // ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 //////////////////////////////////////////////////////////////////////////////
11 #include <boost/assert.hpp>
12 #include <boost/config.hpp> // BOOST_MSVC
13 #include <boost/detail/workaround.hpp>
15 #include <typeinfo> // std::type_info
28 //////////////////////////////////////////////////////////////////////////////
31 const void * pCustomId_;
32 #if defined( BOOST_ENABLE_ASSERT_HANDLER ) || !defined( NDEBUG )
33 const std::type_info * pCustomIdType_;
37 template< class MostDerived >
40 static id_provider idProvider_;
43 template< class MostDerived >
44 id_provider id_holder< MostDerived >::idProvider_;
48 //////////////////////////////////////////////////////////////////////////////
51 #ifdef BOOST_STATECHART_USE_NATIVE_RTTI
55 ////////////////////////////////////////////////////////////////////////
56 explicit id_type( const std::type_info & id ) : id_( id ) {}
58 bool operator==( id_type right ) const
60 return id_ == right.id_ != 0;
62 bool operator!=( id_type right ) const { return !( *this == right ); }
64 bool operator<( id_type right ) const
66 return id_.before( right.id_ ) != 0;
68 bool operator>( id_type right ) const { return right < *this; }
69 bool operator>=( id_type right ) const { return !( *this < right ); }
70 bool operator<=( id_type right ) const { return !( right < *this ); }
73 ////////////////////////////////////////////////////////////////////////
74 const std::type_info & id_;
77 typedef bool id_provider_type; // dummy
79 typedef const void * id_type;
80 typedef const id_provider * id_provider_type;
83 ////////////////////////////////////////////////////////////////////////////
84 template< class Base >
85 class rtti_base_type : public Base
88 ////////////////////////////////////////////////////////////////////////
89 typedef rtti_policy::id_type id_type;
91 id_type dynamic_type() const
93 #ifdef BOOST_STATECHART_USE_NATIVE_RTTI
94 return id_type( typeid( *this ) );
100 #ifndef BOOST_STATECHART_USE_NATIVE_RTTI
101 template< typename CustomId >
102 const CustomId * custom_dynamic_type_ptr() const
105 ( idProvider_->pCustomId_ == 0 ) ||
106 ( *idProvider_->pCustomIdType_ == typeid( CustomId ) ) );
107 return static_cast< const CustomId * >( idProvider_->pCustomId_ );
112 #ifdef BOOST_STATECHART_USE_NATIVE_RTTI
113 rtti_base_type( id_provider_type ) {}
115 ////////////////////////////////////////////////////////////////////////
116 #if BOOST_WORKAROUND( __GNUC__, BOOST_TESTED_AT( 4 ) )
117 // We make the destructor virtual for GCC because with this compiler
118 // there is currently no way to disable the "has virtual functions but
119 // non-virtual destructor" warning on a class by class basis. Although
120 // it can be done on the compiler command line with
121 // -Wno-non-virtual-dtor, this is undesirable as this would also
122 // suppress legitimate warnings for types that are not states.
123 virtual ~rtti_base_type() {}
129 ////////////////////////////////////////////////////////////////////////
130 // For typeid( *this ) to return a value that corresponds to the most-
131 // derived type, we need to have a vptr. Since this type does not
132 // contain any virtual functions we need to artificially declare one so.
133 virtual void dummy() {}
136 id_provider_type idProvider
138 idProvider_( idProvider )
145 ////////////////////////////////////////////////////////////////////////
146 id_provider_type idProvider_;
150 ////////////////////////////////////////////////////////////////////////////
151 template< class MostDerived, class Base >
152 class rtti_derived_type : public Base
155 ////////////////////////////////////////////////////////////////////////
156 static id_type static_type()
158 #ifdef BOOST_STATECHART_USE_NATIVE_RTTI
159 return id_type( typeid( const MostDerived ) );
161 return &id_holder< MostDerived >::idProvider_;
165 #ifndef BOOST_STATECHART_USE_NATIVE_RTTI
166 template< class CustomId >
167 static const CustomId * custom_static_type_ptr()
170 ( id_holder< MostDerived >::idProvider_.pCustomId_ == 0 ) ||
171 ( *id_holder< MostDerived >::idProvider_.pCustomIdType_ ==
172 typeid( CustomId ) ) );
173 return static_cast< const CustomId * >(
174 id_holder< MostDerived >::idProvider_.pCustomId_ );
177 template< class CustomId >
178 static void custom_static_type_ptr( const CustomId * pCustomId )
180 #if defined( BOOST_ENABLE_ASSERT_HANDLER ) || !defined( NDEBUG )
181 id_holder< MostDerived >::idProvider_.pCustomIdType_ =
184 id_holder< MostDerived >::idProvider_.pCustomId_ = pCustomId;
189 ////////////////////////////////////////////////////////////////////////
190 ~rtti_derived_type() {}
192 #ifdef BOOST_STATECHART_USE_NATIVE_RTTI
193 rtti_derived_type() : Base( false ) {}
195 rtti_derived_type() : Base( &id_holder< MostDerived >::idProvider_ ) {}
202 } // namespace detail
203 } // namespace statechart