rtti_policy.hpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  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. //////////////////////////////////////////////////////////////////////////////
  8. #include <boost/assert.hpp>
  9. #include <boost/config.hpp> // BOOST_MSVC
  10. #include <boost/detail/workaround.hpp>
  11. #include <typeinfo> // std::type_info
  12. namespace boost
  13. {
  14. namespace statechart
  15. {
  16. namespace detail
  17. {
  18. //////////////////////////////////////////////////////////////////////////////
  19. struct id_provider
  20. {
  21. const void * pCustomId_;
  22. #if defined( BOOST_ENABLE_ASSERT_HANDLER ) || !defined( NDEBUG )
  23. const std::type_info * pCustomIdType_;
  24. #endif
  25. };
  26. template< class MostDerived >
  27. struct id_holder
  28. {
  29. static id_provider idProvider_;
  30. };
  31. template< class MostDerived >
  32. id_provider id_holder< MostDerived >::idProvider_;
  33. //////////////////////////////////////////////////////////////////////////////
  34. struct rtti_policy
  35. {
  36. #ifdef BOOST_STATECHART_USE_NATIVE_RTTI
  37. class id_type
  38. {
  39. public:
  40. ////////////////////////////////////////////////////////////////////////
  41. explicit id_type( const std::type_info & id ) : id_( id ) {}
  42. bool operator==( id_type right ) const
  43. {
  44. return ( id_ == right.id_ ) != 0;
  45. }
  46. bool operator!=( id_type right ) const { return !( *this == right ); }
  47. bool operator<( id_type right ) const
  48. {
  49. return id_.before( right.id_ ) != 0;
  50. }
  51. bool operator>( id_type right ) const { return right < *this; }
  52. bool operator>=( id_type right ) const { return !( *this < right ); }
  53. bool operator<=( id_type right ) const { return !( right < *this ); }
  54. private:
  55. ////////////////////////////////////////////////////////////////////////
  56. const std::type_info & id_;
  57. };
  58. typedef bool id_provider_type; // dummy
  59. #else
  60. typedef const void * id_type;
  61. typedef const id_provider * id_provider_type;
  62. #endif
  63. ////////////////////////////////////////////////////////////////////////////
  64. template< class Base >
  65. class rtti_base_type : public Base
  66. {
  67. public:
  68. ////////////////////////////////////////////////////////////////////////
  69. typedef rtti_policy::id_type id_type;
  70. id_type dynamic_type() const
  71. {
  72. #ifdef BOOST_STATECHART_USE_NATIVE_RTTI
  73. return id_type( typeid( *this ) );
  74. #else
  75. return idProvider_;
  76. #endif
  77. }
  78. #ifndef BOOST_STATECHART_USE_NATIVE_RTTI
  79. template< typename CustomId >
  80. const CustomId * custom_dynamic_type_ptr() const
  81. {
  82. BOOST_ASSERT(
  83. ( idProvider_->pCustomId_ == 0 ) ||
  84. ( *idProvider_->pCustomIdType_ == typeid( CustomId ) ) );
  85. return static_cast< const CustomId * >( idProvider_->pCustomId_ );
  86. }
  87. #endif
  88. protected:
  89. #ifdef BOOST_STATECHART_USE_NATIVE_RTTI
  90. rtti_base_type( id_provider_type ) {}
  91. ////////////////////////////////////////////////////////////////////////
  92. #if BOOST_WORKAROUND( __GNUC__, BOOST_TESTED_AT( 4 ) )
  93. // We make the destructor virtual for GCC because with this compiler
  94. // there is currently no way to disable the "has virtual functions but
  95. // non-virtual destructor" warning on a class by class basis. Although
  96. // it can be done on the compiler command line with
  97. // -Wno-non-virtual-dtor, this is undesirable as this would also
  98. // suppress legitimate warnings for types that are not states.
  99. virtual ~rtti_base_type() {}
  100. #else
  101. ~rtti_base_type() {}
  102. #endif
  103. private:
  104. ////////////////////////////////////////////////////////////////////////
  105. // For typeid( *this ) to return a value that corresponds to the most-
  106. // derived type, we need to have a vptr. Since this type does not
  107. // contain any virtual functions we need to artificially declare one so.
  108. virtual void dummy() {}
  109. #else
  110. rtti_base_type(
  111. id_provider_type idProvider
  112. ) :
  113. idProvider_( idProvider )
  114. {
  115. }
  116. ~rtti_base_type() {}
  117. private:
  118. ////////////////////////////////////////////////////////////////////////
  119. id_provider_type idProvider_;
  120. #endif
  121. };
  122. ////////////////////////////////////////////////////////////////////////////
  123. template< class MostDerived, class Base >
  124. class rtti_derived_type : public Base
  125. {
  126. public:
  127. ////////////////////////////////////////////////////////////////////////
  128. static id_type static_type()
  129. {
  130. #ifdef BOOST_STATECHART_USE_NATIVE_RTTI
  131. return id_type( typeid( const MostDerived ) );
  132. #else
  133. return &id_holder< MostDerived >::idProvider_;
  134. #endif
  135. }
  136. #ifndef BOOST_STATECHART_USE_NATIVE_RTTI
  137. template< class CustomId >
  138. static const CustomId * custom_static_type_ptr()
  139. {
  140. BOOST_ASSERT(
  141. ( id_holder< MostDerived >::idProvider_.pCustomId_ == 0 ) ||
  142. ( *id_holder< MostDerived >::idProvider_.pCustomIdType_ ==
  143. typeid( CustomId ) ) );
  144. return static_cast< const CustomId * >(
  145. id_holder< MostDerived >::idProvider_.pCustomId_ );
  146. }
  147. template< class CustomId >
  148. static void custom_static_type_ptr( const CustomId * pCustomId )
  149. {
  150. #if defined( BOOST_ENABLE_ASSERT_HANDLER ) || !defined( NDEBUG )
  151. id_holder< MostDerived >::idProvider_.pCustomIdType_ =
  152. &typeid( CustomId );
  153. #endif
  154. id_holder< MostDerived >::idProvider_.pCustomId_ = pCustomId;
  155. }
  156. #endif
  157. protected:
  158. ////////////////////////////////////////////////////////////////////////
  159. ~rtti_derived_type() {}
  160. #ifdef BOOST_STATECHART_USE_NATIVE_RTTI
  161. rtti_derived_type() : Base( false ) {}
  162. #else
  163. rtti_derived_type() : Base( &id_holder< MostDerived >::idProvider_ ) {}
  164. #endif
  165. };
  166. };
  167. } // namespace detail
  168. } // namespace statechart
  169. } // namespace boost
  170. #endif