Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/boost/statechart/detail/rtti_policy.hpp @ 47

Last change on this file since 47 was 29, checked in by landauf, 16 years ago

updated boost from 1_33_1 to 1_34_1

File size: 6.4 KB
Line 
1#ifndef BOOST_STATECHART_DETAIL_RTTI_POLICY_HPP_INCLUDED
2#define BOOST_STATECHART_DETAIL_RTTI_POLICY_HPP_INCLUDED
3//////////////////////////////////////////////////////////////////////////////
4// Copyright 2002-2006 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
9
10
11#include <boost/assert.hpp>
12#include <boost/config.hpp> // BOOST_MSVC
13#include <boost/detail/workaround.hpp>
14
15#include <typeinfo> // std::type_info
16
17
18
19#ifdef BOOST_MSVC
20// We permanently turn off the following level 4 warnings because users will
21// have to do so themselves anyway if we turn them back on
22#  pragma warning( disable: 4511 ) // copy constructor could not be generated
23#  pragma warning( disable: 4512 ) // assignment operator could not be generated
24#endif
25
26
27
28namespace boost
29{
30namespace statechart
31{
32namespace detail
33{
34
35
36
37//////////////////////////////////////////////////////////////////////////////
38struct id_provider
39{
40  const void * pCustomId_;
41  #if defined( BOOST_ENABLE_ASSERT_HANDLER ) || !defined( NDEBUG )
42  const std::type_info * pCustomIdType_;
43  #endif
44};
45
46template< class MostDerived >
47struct id_holder
48{
49  static id_provider idProvider_;
50};
51
52template< class MostDerived >
53id_provider id_holder< MostDerived >::idProvider_;
54
55
56
57//////////////////////////////////////////////////////////////////////////////
58struct rtti_policy
59{
60  #ifdef BOOST_STATECHART_USE_NATIVE_RTTI
61  class id_type
62  {
63    public:
64      ////////////////////////////////////////////////////////////////////////
65      explicit id_type( const std::type_info & id ) : id_( id ) {}
66
67      bool operator==( id_type right ) const
68      {
69        return id_ == right.id_ != 0;
70      }
71      bool operator!=( id_type right ) const { return !( *this == right ); }
72
73      bool operator<( id_type right ) const
74      {
75        return id_.before( right.id_ ) != 0;
76      }
77      bool operator>( id_type right ) const { return right < *this; }
78      bool operator>=( id_type right ) const { return !( *this < right ); }
79      bool operator<=( id_type right ) const { return !( right < *this ); }
80
81    private:
82      ////////////////////////////////////////////////////////////////////////
83      const std::type_info & id_;
84  };
85
86  typedef bool id_provider_type; // dummy
87  #else
88  typedef const void * id_type;
89  typedef const id_provider & id_provider_type;
90  #endif
91
92  ////////////////////////////////////////////////////////////////////////////
93  template< class Base >
94  class rtti_base_type : public Base
95  {
96    public:
97      ////////////////////////////////////////////////////////////////////////
98      typedef rtti_policy::id_type id_type;
99
100      id_type dynamic_type() const
101      {
102        #ifdef BOOST_STATECHART_USE_NATIVE_RTTI
103        return id_type( typeid( *this ) );
104        #else
105        return &idProvider_;
106        #endif
107      }
108
109      #ifndef BOOST_STATECHART_USE_NATIVE_RTTI
110      template< typename CustomId >
111      const CustomId * custom_dynamic_type_ptr() const
112      {
113        BOOST_ASSERT(
114          ( idProvider_.pCustomId_ == 0 ) ||
115          ( *idProvider_.pCustomIdType_ == typeid( CustomId ) ) );
116        return static_cast< const CustomId * >( idProvider_.pCustomId_ );
117      }
118      #endif
119
120    protected:
121    #ifdef BOOST_STATECHART_USE_NATIVE_RTTI
122      rtti_base_type( id_provider_type ) {}
123
124      ////////////////////////////////////////////////////////////////////////
125      #if BOOST_WORKAROUND( __GNUC__, BOOST_TESTED_AT( 4 ) )
126      // We make the destructor virtual for GCC because with this compiler
127      // there is currently no way to disable the "has virtual functions but
128      // non-virtual destructor" warning on a class by class basis. Although
129      // it can be done on the compiler command line with
130      // -Wno-non-virtual-dtor, this is undesirable as this would also
131      // suppress legitimate warnings for types that are not states.
132      virtual ~rtti_base_type() {}
133      #else
134      ~rtti_base_type() {}
135      #endif
136
137    private:
138      ////////////////////////////////////////////////////////////////////////
139      // For typeid( *this ) to return a value that corresponds to the most-
140      // derived type, we need to have a vptr. Since this type does not
141      // contain any virtual functions we need to artificially declare one so.
142      virtual void dummy() {}
143    #else
144      rtti_base_type(
145        id_provider_type idProvider
146      ) :
147        idProvider_( idProvider )
148      {
149      }
150
151      ~rtti_base_type() {}
152
153    private:
154      ////////////////////////////////////////////////////////////////////////
155      id_provider_type idProvider_;
156    #endif
157  };
158
159  ////////////////////////////////////////////////////////////////////////////
160  template< class MostDerived, class Base >
161  class rtti_derived_type : public Base
162  {
163    public:
164      ////////////////////////////////////////////////////////////////////////
165      static id_type static_type()
166      {
167        #ifdef BOOST_STATECHART_USE_NATIVE_RTTI
168        return id_type( typeid( const MostDerived ) );
169        #else
170        return &id_holder< MostDerived >::idProvider_;
171        #endif
172      }
173
174      #ifndef BOOST_STATECHART_USE_NATIVE_RTTI
175      template< class CustomId >
176      static const CustomId * custom_static_type_ptr()
177      {
178        BOOST_ASSERT(
179          ( id_holder< MostDerived >::idProvider_.pCustomId_ == 0 ) ||
180          ( *id_holder< MostDerived >::idProvider_.pCustomIdType_ ==
181            typeid( CustomId ) ) );
182        return static_cast< const CustomId * >(
183          id_holder< MostDerived >::idProvider_.pCustomId_ );
184      }
185
186      template< class CustomId >
187      static void custom_static_type_ptr( const CustomId * pCustomId )
188      {
189        #if defined( BOOST_ENABLE_ASSERT_HANDLER ) || !defined( NDEBUG )
190        id_holder< MostDerived >::idProvider_.pCustomIdType_ =
191          &typeid( CustomId );
192        #endif
193        id_holder< MostDerived >::idProvider_.pCustomId_ = pCustomId;
194      }
195      #endif
196
197    protected:
198      ////////////////////////////////////////////////////////////////////////
199      ~rtti_derived_type() {}
200
201      #ifdef BOOST_STATECHART_USE_NATIVE_RTTI
202      rtti_derived_type() : Base( false ) {}
203      #else
204      rtti_derived_type() : Base( id_holder< MostDerived >::idProvider_ ) {}
205      #endif
206  };
207};
208
209
210
211} // namespace detail
212} // namespace statechart
213} // namespace boost
214
215
216
217#endif
Note: See TracBrowser for help on using the repository browser.