Main Page   Reference Manual   Namespace List   Compound List   Namespace Members   Compound Members   File Members  

type_info.h
Go to the documentation of this file.
1 // $Header$
2 //
3 // Copyright (C) 2000 - 2004, by
4 //
5 // Carlo Wood, Run on IRC <carlo@alinoe.com>
6 // RSA-1024 0x624ACAD5 1997-01-26 Sign & Encrypt
7 // Fingerprint16 = 32 EC A7 B6 AC DB 65 A6 F6 F6 55 DD 1C DC FF 61
8 //
9 // This file may be distributed under the terms of the Q Public License
10 // version 1.0 as appearing in the file LICENSE.QPL included in the
11 // packaging of this file.
12 //
13 
18 #ifndef LIBCWD_TYPE_INFO_H
19 #define LIBCWD_TYPE_INFO_H
20 
21 #ifndef LIBCWD_PRIVATE_THREADING_H
23 #endif
24 #ifndef LIBCW_TYPEINFO
25 #define LIBCW_TYPEINFO
26 #include <typeinfo> // Needed for typeid()
27 #endif
28 #ifndef LIBCW_CSTDDEF
29 #define LIBCW_CSTDDEF
30 #include <cstddef> // Needed for size_t
31 #endif
32 
33 namespace libcwd {
34 
35 namespace _private_ {
36  extern char const* make_label(char const* mangled_name);
37 } // namespace _private_
38 
44 class type_info_ct {
45 protected:
46  size_t M_type_size;
47  size_t M_type_ref_size;
48  char const* M_name;
49  char const* M_dem_name;
50 public:
55  type_info_ct(void) { }
60  type_info_ct(int) : M_type_size(0), M_type_ref_size(0), M_name(NULL), M_dem_name("<unknown type>") { }
65  void init(char const* type_encoding, size_t s, size_t rs)
66  {
67  M_type_size = s;
68  M_type_ref_size = rs;
69  M_name = type_encoding;
70  M_dem_name = _private_::make_label(type_encoding);
71  }
73  char const* demangled_name(void) const { return M_dem_name; }
75  char const* name(void) const { return M_name; }
77  size_t size(void) const { return M_type_size; }
79  size_t ref_size(void) const { return M_type_ref_size; }
80 };
81 
82 namespace _private_ {
83 
84  extern char const* extract_exact_name(char const*, char const* LIBCWD_COMMA_TSD_PARAM);
85 
86  //-------------------------------------------------------------------------------------------------
87  // type_info_of
88 
89  // _private_::
90  template<typename T>
91  struct type_info {
92  private:
93  static type_info_ct S_value;
94  static bool S_initialized;
95  public:
96  static type_info_ct const& value(void);
97  };
98 
99  // Specialization for general pointers.
100  // _private_::
101  template<typename T>
102  struct type_info<T*> {
103  private:
104  static type_info_ct S_value;
105  static bool S_initialized;
106  public:
107  static type_info_ct const& value(void);
108  };
109 
110  // Specialization for `void*'.
111  // _private_::
112  template<>
113  struct type_info<void*> {
114  private:
115  static type_info_ct S_value;
116  static bool S_initialized;
117  public:
118  static type_info_ct const& value(void);
119  };
120 
121  // _private_::
122  template<typename T>
123  type_info_ct type_info<T>::S_value;
124 
125  // _private_::
126  template<typename T>
127  bool type_info<T>::S_initialized;
128 
129  // _private_::
130  template<typename T>
131  type_info_ct const& type_info<T>::value(void)
132  {
133  if (!S_initialized)
134  {
135  S_value.init(typeid(T).name(), sizeof(T), 0);
136  S_initialized = true;
137  }
138  return S_value;
139  }
140 
141  // _private_::
142  template<typename T>
143  type_info_ct type_info<T*>::S_value;
144 
145  // _private_::
146  template<typename T>
147  bool type_info<T*>::S_initialized;
148 
149  // _private_::
150  template<typename T>
151  type_info_ct const& type_info<T*>::value(void)
152  {
153  if (!S_initialized)
154  {
155  S_value.init(typeid(T*).name(), sizeof(T*), sizeof(T));
156  S_initialized = true;
157  }
158  return S_value;
159  }
160 
161 } // namespace _private_
162 
163 } // namespace libcwd
164 
165 //---------------------------------------------------------------------------------------------------
166 // libcwd_type_info_exact
167 
168 template<typename T>
169  struct libcwd_type_info_exact {
170  private:
171  static ::libcwd::type_info_ct S_value;
172  static bool S_initialized;
173  public:
174  static ::libcwd::type_info_ct const& value(void);
175  };
176 
177 // Specialization for general pointers.
178 template<typename T>
179  struct libcwd_type_info_exact<T*> {
180  private:
181  static ::libcwd::type_info_ct S_value;
182  static bool S_initialized;
183  public:
184  static ::libcwd::type_info_ct const& value(void);
185  };
186 
187 // Specialization for `void*'.
188 template<>
189  struct libcwd_type_info_exact<void*> {
190  private:
191  static ::libcwd::type_info_ct S_value;
192  static bool S_initialized;
193  public:
194  static ::libcwd::type_info_ct const& value(void);
195  };
196 
197 template<typename T>
198  ::libcwd::type_info_ct libcwd_type_info_exact<T>::S_value;
199 
200 template<typename T>
201  bool libcwd_type_info_exact<T>::S_initialized;
202 
203 template<typename T>
204  ::libcwd::type_info_ct const& libcwd_type_info_exact<T>::value(void)
205  {
206  if (!S_initialized)
207  {
208  S_value.init(::libcwd::_private_::extract_exact_name(typeid(libcwd_type_info_exact<T>).name(), typeid(T).name() LIBCWD_COMMA_TSD_INSTANCE), sizeof(T), 0);
209  S_initialized = true;
210  }
211  return S_value;
212  }
213 
214 template<typename T>
215  ::libcwd::type_info_ct libcwd_type_info_exact<T*>::S_value;
216 
217 template<typename T>
218  bool libcwd_type_info_exact<T*>::S_initialized;
219 
220 template<typename T>
221  ::libcwd::type_info_ct const& libcwd_type_info_exact<T*>::value(void)
222  {
223  if (!S_initialized)
224  {
225  S_value.init(::libcwd::_private_::extract_exact_name(typeid(libcwd_type_info_exact<T*>).name(), typeid(T*).name() LIBCWD_COMMA_TSD_INSTANCE), sizeof(T*), sizeof(T));
226  S_initialized = true;
227  }
228  return S_value;
229  }
230 
231 namespace libcwd {
232 
236 #ifndef LIBCWD_DOXYGEN
237 // Prototype of `type_info_of'.
238 template<typename T>
239  inline
240  type_info_ct const&
241  type_info_of(T const&);
242 #endif
243 
260 template<typename T>
261  inline
262  type_info_ct const&
264  {
265  return ::libcwd_type_info_exact<T>::value();
266  }
267 
274 template<typename T>
275  inline
276  type_info_ct const&
277  type_info_of(T const&) // If we don't use a reference, this would _still_ cause the copy constructor to be called.
278  // Besides, using `const&' doesn't harm the result as typeid() always ignores the top-level
279  // CV-qualifiers anyway (see C++ standard ISO+IEC+14882, 5.2.8 point 5).
280  {
281  return _private_::type_info<T>::value();
282  }
283 
284 extern type_info_ct const unknown_type_info_c;
285 
288 } // namespace libcwd
289 
290 #endif // LIBCWD_TYPE_INFO_H
char const * M_name
Encoded type of T (as returned by typeid(T).name()).
Definition: type_info.h:48
size_t ref_size(void) const
sizeof(*T) or 0 when T is not a pointer.
Definition: type_info.h:79
type_info_ct(void)
Default constructor.
Definition: type_info.h:55
type_info_ct(int)
Constructor used for unknown_type_info_c.
Definition: type_info.h:60
Class that holds type information for debugging purposes.  Returned by type_info_of().
Definition: type_info.h:44
size_t M_type_size
sizeof(T).
Definition: type_info.h:46
size_t M_type_ref_size
sizeof(*T) or 0 when T is not a pointer.
Definition: type_info.h:47
char const * demangled_name(void) const
The demangled type name.
Definition: type_info.h:73
size_t size(void) const
sizeof(T).
Definition: type_info.h:77
type_info_ct const & type_info_of(void)
Get type information of a given class or type.
Definition: type_info.h:263
char const * name(void) const
The encoded type name (as returned by typeid(T).name()).
Definition: type_info.h:75
void init(char const *type_encoding, size_t s, size_t rs)
Construct a type_info_ct object for a type (T) with encoding type_encoding, size s and size of refere...
Definition: type_info.h:65
char const * M_dem_name
Demangled type name of T.
Definition: type_info.h:49
Copyright © 2001 - 2004 Carlo Wood.  All rights reserved.