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
22 #include "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 
38  template<typename T>
39  struct size_of_completed {
40  static constexpr size_t size = sizeof(T);
41  };
42 
43  struct size_of_not_completed {
44  static constexpr size_t size = 0;
45  };
46 
47  template<typename T>
48  struct sizeof_ref {
49  template<typename U>
50  static size_of_completed<T> test(int (*)[sizeof(U)]);
51 
52  template<typename>
53  static size_of_not_completed test(...);
54 
55  static constexpr size_t value = decltype(test<T>(nullptr))::size;
56  };
57 
58  template<typename T>
59  size_t sizeof_ref_v = sizeof_ref<T>::value;
60 } // namespace _private_
61 
67 class type_info_ct {
68 protected:
69  size_t M_type_size;
70  size_t M_type_ref_size;
71  char const* M_name;
72  char const* M_dem_name;
73 public:
83  type_info_ct(int) : M_type_size(0), M_type_ref_size(0), M_name(NULL), M_dem_name("<unknown type>") { }
88  void init(char const* type_encoding, size_t s, size_t rs)
89  {
90  M_type_size = s;
91  M_type_ref_size = rs;
92  M_name = type_encoding;
93  M_dem_name = _private_::make_label(type_encoding);
94  }
96  char const* demangled_name() const { return M_dem_name; }
98  char const* name() const { return M_name; }
100  size_t size() const { return M_type_size; }
102  size_t ref_size() const { return M_type_ref_size; }
103 };
104 
105 namespace _private_ {
106 
107  extern char const* extract_exact_name(char const*, char const* LIBCWD_COMMA_TSD_PARAM);
108 
109  //-------------------------------------------------------------------------------------------------
110  // type_info_of
111 
112  // _private_::
113  template<typename T>
114  struct type_info {
115  private:
116  static type_info_ct S_value;
117  static bool S_initialized;
118  public:
119  static type_info_ct const& value();
120  };
121 
122  // Specialization for general pointers.
123  // _private_::
124  template<typename T>
125  struct type_info<T*> {
126  private:
127  static type_info_ct S_value;
128  static bool S_initialized;
129  public:
130  static type_info_ct const& value();
131  };
132 
133  // Specialization for `void*'.
134  // _private_::
135  template<>
136  struct type_info<void*> {
137  private:
138  static type_info_ct S_value;
139  static bool S_initialized;
140  public:
141  static type_info_ct const& value();
142  };
143 
144  // _private_::
145  template<typename T>
146  type_info_ct type_info<T>::S_value;
147 
148  // _private_::
149  template<typename T>
150  bool type_info<T>::S_initialized;
151 
152  // _private_::
153  template<typename T>
154  type_info_ct const& type_info<T>::value()
155  {
156  if (!S_initialized)
157  {
158  S_value.init(typeid(T).name(), sizeof(T), 0);
159  S_initialized = true;
160  }
161  return S_value;
162  }
163 
164  // _private_::
165  template<typename T>
166  type_info_ct type_info<T*>::S_value;
167 
168  // _private_::
169  template<typename T>
170  bool type_info<T*>::S_initialized;
171 
172  // _private_::
173  template<typename T>
174  type_info_ct const& type_info<T*>::value()
175  {
176  if (!S_initialized)
177  {
178  S_value.init(typeid(T*).name(), sizeof(T*), sizeof_ref_v<T>);
179  S_initialized = true;
180  }
181  return S_value;
182  }
183 
184 } // namespace _private_
185 
186 } // namespace libcwd
187 
188 //---------------------------------------------------------------------------------------------------
189 // libcwd_type_info_exact
190 
191 template<typename T>
192  struct libcwd_type_info_exact {
193  private:
194  static ::libcwd::type_info_ct S_value;
195  static bool S_initialized;
196  public:
197  static ::libcwd::type_info_ct const& value();
198  };
199 
200 // Specialization for general pointers.
201 template<typename T>
202  struct libcwd_type_info_exact<T*> {
203  private:
204  static ::libcwd::type_info_ct S_value;
205  static bool S_initialized;
206  public:
207  static ::libcwd::type_info_ct const& value();
208  };
209 
210 // Specialization for `void*'.
211 template<>
212  struct libcwd_type_info_exact<void*> {
213  private:
214  static ::libcwd::type_info_ct S_value;
215  static bool S_initialized;
216  public:
217  static ::libcwd::type_info_ct const& value();
218  };
219 
220 template<typename T>
221  ::libcwd::type_info_ct libcwd_type_info_exact<T>::S_value;
222 
223 template<typename T>
224  bool libcwd_type_info_exact<T>::S_initialized;
225 
226 template<typename T>
227  ::libcwd::type_info_ct const& libcwd_type_info_exact<T>::value()
228  {
229  if (!S_initialized)
230  {
231  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);
232  S_initialized = true;
233  }
234  return S_value;
235  }
236 
237 template<typename T>
238  ::libcwd::type_info_ct libcwd_type_info_exact<T*>::S_value;
239 
240 template<typename T>
241  bool libcwd_type_info_exact<T*>::S_initialized;
242 
243 template<typename T>
244  ::libcwd::type_info_ct const& libcwd_type_info_exact<T*>::value()
245  {
246  if (!S_initialized)
247  {
248  S_value.init(::libcwd::_private_::extract_exact_name(typeid(libcwd_type_info_exact<T*>).name(), typeid(T*).name() LIBCWD_COMMA_TSD_INSTANCE), sizeof(T*), ::libcwd::_private_::sizeof_ref_v<T>);
249  S_initialized = true;
250  }
251  return S_value;
252  }
253 
254 namespace libcwd {
255 
259 #ifndef LIBCWD_DOXYGEN
260 // Prototype of `type_info_of'.
261 template<typename T>
262  inline
263  type_info_ct const&
264  type_info_of(T const&);
265 #endif
266 
283 template<typename T>
284  inline
285  type_info_ct const&
287  {
288  return ::libcwd_type_info_exact<T>::value();
289  }
290 
297 template<typename T>
298  inline
299  type_info_ct const&
300  type_info_of(T const&) // If we don't use a reference, this would _still_ cause the copy constructor to be called.
301  // Besides, using `const&' doesn't harm the result as typeid() always ignores the top-level
302  // CV-qualifiers anyway (see C++ standard ISO+IEC+14882, 5.2.8 point 5).
303  {
304  return _private_::type_info<T>::value();
305  }
306 
307 extern type_info_ct const unknown_type_info_c;
308 
311 } // namespace libcwd
312 
313 #endif // LIBCWD_TYPE_INFO_H
Class that holds type information for debugging purposes.&#160; Returned by type_info_of().
Definition: type_info.h:67
size_t M_type_size
sizeof(T).
Definition: type_info.h:69
char const * M_name
Encoded type of T (as returned by typeid(T).name()).
Definition: type_info.h:71
type_info_ct()
Default constructor.
Definition: type_info.h:78
size_t M_type_ref_size
sizeof(*T) or 0 when T is not a pointer (or a pointer to an incomplete type).
Definition: type_info.h:70
char const * name() const
The encoded type name (as returned by typeid(T).name()).
Definition: type_info.h:98
size_t ref_size() const
sizeof(*T) or 0 when T is not a pointer (or a pointer to an incomplete type).
Definition: type_info.h:102
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:88
size_t size() const
sizeof(T).
Definition: type_info.h:100
char const * demangled_name() const
The demangled type name.
Definition: type_info.h:96
type_info_ct(int)
Constructor used for unknown_type_info_c.
Definition: type_info.h:83
char const * M_dem_name
Demangled type name of T.
Definition: type_info.h:72
type_info_ct const & type_info_of()
Get type information of a given class or type.
Definition: type_info.h:286
namespace for libcwd.
Definition: debug.cc:87
Copyright © 2001 - 2004 Carlo Wood.  All rights reserved.