libcwdversion 2.0.0
The C++ Debugging Support Library
Loading...
Searching...
No Matches
type_info.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2000-2005, 2007, 2018-2020, 2026 Carlo Wood
2// SPDX-License-Identifier: MIT
3
4#pragma once
5
9
10#ifndef LIBCWD_TYPE_INFO_H
11#define LIBCWD_TYPE_INFO_H
12
13#include <cstddef> // Needed for size_t
14#include <typeinfo> // Needed for typeid()
15
16namespace libcwd {
17namespace _private_ {
18
19extern char const* make_label(char const* mangled_name);
20
21template <typename T>
22struct size_of_completed
23{
24 static constexpr size_t size = sizeof(T);
25};
26
27struct size_of_not_completed
28{
29 static constexpr size_t size = 0;
30};
31
32template <typename T>
33struct sizeof_ref
34{
35 template <typename U>
36 static size_of_completed<T> test(int (*)[sizeof(U)]);
37
38 template <typename>
39 static size_of_not_completed test(...);
40
41 static constexpr size_t value = decltype(test<T>(nullptr))::size;
42};
43
44template <typename T>
45size_t sizeof_ref_v = sizeof_ref<T>::value;
46
47} // namespace _private_
48
55{
56 protected:
57 size_t type_size_;
59 char const* name_;
60 char const* demangled_name_;
61 public:
71 TypeInfo(int) : type_size_(0), dereferenced_type_size_(0), name_(NULL), demangled_name_("<unknown type>") { }
77 void init(char const* type_encoding, size_t s, size_t rs)
78 {
79 type_size_ = s;
81 name_ = type_encoding;
82 demangled_name_ = _private_::make_label(type_encoding);
83 }
84
85 char const* demangled_name() const { return demangled_name_; }
87 char const* name() const { return name_; }
89 size_t size() const { return type_size_; }
91 size_t ref_size() const { return dereferenced_type_size_; }
92};
93
94namespace _private_ {
95
96extern char const* extract_exact_name(char const*, char const*);
97
98//-------------------------------------------------------------------------------------------------
99// type_info_of
100
101// _private_::
102template <typename T>
103struct type_info
104{
105 private:
106 static TypeInfo s_value_;
107 static bool s_initialized_;
108
109 public:
110 static TypeInfo const& value();
111};
112
113// Specialization for general pointers.
114// _private_::
115template <typename T>
116struct type_info<T*>
117{
118 private:
119 static TypeInfo s_value_;
120 static bool s_initialized_;
121
122 public:
123 static TypeInfo const& value();
124};
125
126// Specialization for `void*'.
127// _private_::
128template <>
129struct type_info<void*>
130{
131 private:
132 static TypeInfo s_value_;
133 static bool s_initialized_;
134
135 public:
136 static TypeInfo const& value();
137};
138
139// _private_::
140template <typename T>
141TypeInfo type_info<T>::s_value_;
142
143// _private_::
144template <typename T>
145bool type_info<T>::s_initialized_;
146
147// _private_::
148template <typename T>
149TypeInfo const& type_info<T>::value()
150{
151 if (!s_initialized_)
152 {
153 s_value_.init(typeid(T).name(), sizeof(T), 0);
154 s_initialized_ = true;
155 }
156 return s_value_;
157}
158
159// _private_::
160template <typename T>
161TypeInfo type_info<T*>::s_value_;
162
163// _private_::
164template <typename T>
165bool type_info<T*>::s_initialized_;
166
167// _private_::
168template <typename T>
169TypeInfo const& type_info<T*>::value()
170{
171 if (!s_initialized_)
172 {
173 s_value_.init(typeid(T*).name(), sizeof(T*), sizeof_ref_v<T>);
174 s_initialized_ = true;
175 }
176 return s_value_;
177}
178
179} // namespace _private_
180} // namespace libcwd
181
182//---------------------------------------------------------------------------------------------------
183// libcwd_type_info_exact
184
185template <typename T>
186struct libcwd_type_info_exact
187{
188 private:
189 static ::libcwd::TypeInfo s_value_;
190 static bool s_initialized_;
191
192 public:
193 static ::libcwd::TypeInfo const& value();
194};
195
196// Specialization for general pointers.
197template <typename T>
198struct libcwd_type_info_exact<T*>
199{
200 private:
201 static ::libcwd::TypeInfo s_value_;
202 static bool s_initialized_;
203
204 public:
205 static ::libcwd::TypeInfo const& value();
206};
207
208// Specialization for `void*'.
209template <>
210struct libcwd_type_info_exact<void*>
211{
212 private:
213 static ::libcwd::TypeInfo s_value_;
214 static bool s_initialized_;
215
216 public:
217 static ::libcwd::TypeInfo const& value();
218};
219
220template <typename T>
221::libcwd::TypeInfo libcwd_type_info_exact<T>::s_value_;
222
223template <typename T>
224bool libcwd_type_info_exact<T>::s_initialized_;
225
226template <typename T>
227::libcwd::TypeInfo const& libcwd_type_info_exact<T>::value()
228{
229 if (!s_initialized_)
230 {
231 s_value_.init(::libcwd::_private_::extract_exact_name(
232 typeid(libcwd_type_info_exact<T>).name(),
233 typeid(T).name()),
234 sizeof(T),
235 0);
236 s_initialized_ = true;
237 }
238 return s_value_;
239}
240
241template <typename T>
242::libcwd::TypeInfo libcwd_type_info_exact<T*>::s_value_;
243
244template <typename T>
245bool libcwd_type_info_exact<T*>::s_initialized_;
246
247template <typename T>
248::libcwd::TypeInfo const& libcwd_type_info_exact<T*>::value()
249{
250 if (!s_initialized_)
251 {
252 s_value_.init(::libcwd::_private_::extract_exact_name(
253 typeid(libcwd_type_info_exact<T*>).name(),
254 typeid(T*).name()),
255 sizeof(T*),
256 ::libcwd::_private_::sizeof_ref_v<T>);
257 s_initialized_ = true;
258 }
259 return s_value_;
260}
261
262namespace libcwd {
263
266
267#ifndef LIBCWD_DOXYGEN
268// Prototype of `type_info_of'.
269template <typename T>
270inline TypeInfo const& type_info_of(T const&);
271#endif
272
289template <typename T>
290inline TypeInfo const& type_info_of()
291{
292 return ::libcwd_type_info_exact<T>::value();
293}
294
301template <typename T>
302inline TypeInfo const& type_info_of(
303 T const&) // If we don't use a reference, this would _still_ cause the copy constructor to be called.
304 // Besides, using `const&' doesn't harm the result as typeid() always ignores the top-level
305 // CV-qualifiers anyway (see C++ standard ISO+IEC+14882, 5.2.8 point 5).
306{
307 return _private_::type_info<T>::value();
308}
309
311
313
314} // namespace libcwd
315
316#endif // LIBCWD_TYPE_INFO_H
Class that holds type information for debugging purposes. Returned by type_info_of().
Definition type_info.h:55
void init(char const *type_encoding, size_t s, size_t rs)
Construct a TypeInfo object for a type (T) with encoding type_encoding, size s and size of reference ...
Definition type_info.h:77
char const * demangled_name_
Demangled type name of T.
Definition type_info.h:60
size_t dereferenced_type_size_
sizeof(*T) or 0 when T is not a pointer (or a pointer to an incomplete type).
Definition type_info.h:58
TypeInfo(int)
Constructor used for unknown_type_info_c.
Definition type_info.h:71
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:91
size_t size() const
sizeof(T).
Definition type_info.h:89
char const * name() const
The encoded type name (as returned by typeid(T).name()).
Definition type_info.h:87
size_t type_size_
sizeof(T).
Definition type_info.h:57
char const * demangled_name() const
The demangled type name.
Definition type_info.h:85
char const * name_
Encoded type of T (as returned by typeid(T).name()).
Definition type_info.h:59
TypeInfo()
Default constructor.
Definition type_info.h:66
TypeInfo const & type_info_of()
Get type information of a given class or type.
Definition type_info.h:290
TypeInfo const unknown_type_info_c(0)
Returned by type_info_of() for unknown types.
Definition type_info.h:310
namespace for libcwd.