1//
2// Copyright 2012-2020 Antony Polukhin.
3//
4// Distributed under the Boost Software License, Version 1.0. (See accompanying
5// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6//
7
8#ifndef BOOST_TYPE_INDEX_HPP
9#define BOOST_TYPE_INDEX_HPP
10
11/// \file boost/type_index.hpp
12/// \brief Includes minimal set of headers required to use the Boost.TypeIndex library.
13///
14/// By inclusion of this file most optimal type index classes will be included and used
15/// as a boost::typeindex::type_index and boost::typeindex::type_info.
16
17#include <boost/config.hpp>
18
19#ifdef BOOST_HAS_PRAGMA_ONCE
20# pragma once
21#endif
22
23#if defined(BOOST_TYPE_INDEX_USER_TYPEINDEX)
24# include BOOST_TYPE_INDEX_USER_TYPEINDEX
25# ifdef BOOST_HAS_PRAGMA_DETECT_MISMATCH
26# pragma detect_mismatch( "boost__type_index__abi", "user defined type_index class is used: " BOOST_STRINGIZE(BOOST_TYPE_INDEX_USER_TYPEINDEX))
27# endif
28#elif (!defined(BOOST_NO_RTTI) && !defined(BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY)) || defined(BOOST_MSVC)
29# include <boost/type_index/stl_type_index.hpp>
30# if defined(BOOST_NO_RTTI) || defined(BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY)
31# include <boost/type_index/detail/stl_register_class.hpp>
32# ifdef BOOST_HAS_PRAGMA_DETECT_MISMATCH
33# pragma detect_mismatch( "boost__type_index__abi", "RTTI is off - typeid() is used only for templates")
34# endif
35# else
36# ifdef BOOST_HAS_PRAGMA_DETECT_MISMATCH
37# pragma detect_mismatch( "boost__type_index__abi", "RTTI is used")
38# endif
39# endif
40#else
41# include <boost/type_index/ctti_type_index.hpp>
42# include <boost/type_index/detail/ctti_register_class.hpp>
43# ifdef BOOST_HAS_PRAGMA_DETECT_MISMATCH
44# pragma detect_mismatch( "boost__type_index__abi", "RTTI is off - using CTTI")
45# endif
46#endif
47
48#ifndef BOOST_TYPE_INDEX_REGISTER_CLASS
49#define BOOST_TYPE_INDEX_REGISTER_CLASS
50#endif
51
52namespace boost { namespace typeindex {
53
54#if defined(BOOST_TYPE_INDEX_DOXYGEN_INVOKED)
55
56/// \def BOOST_TYPE_INDEX_FUNCTION_SIGNATURE
57/// BOOST_TYPE_INDEX_FUNCTION_SIGNATURE is used by boost::typeindex::ctti_type_index class to
58/// deduce the name of a type. If your compiler is not recognized
59/// by the TypeIndex library and you wish to work with boost::typeindex::ctti_type_index, you may
60/// define this macro by yourself.
61///
62/// BOOST_TYPE_INDEX_FUNCTION_SIGNATURE must be defined to a compiler specific macro
63/// that outputs the \b whole function signature \b including \b template \b parameters.
64///
65/// If your compiler is not recognised and BOOST_TYPE_INDEX_FUNCTION_SIGNATURE is not defined,
66/// then a compile-time error will arise at any attempt to use boost::typeindex::ctti_type_index classes.
67///
68/// See BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS and BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING
69/// for an information of how to tune the implementation to make a nice pretty_name() output.
70#define BOOST_TYPE_INDEX_FUNCTION_SIGNATURE BOOST_CURRENT_FUNCTION
71
72/// \def BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING
73/// This is a helper macro for making correct pretty_names() with RTTI off.
74///
75/// BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING macro may be defined to
76/// '(begin_skip, end_skip, runtime_skip, runtime_skip_until)' with parameters for adding a
77/// support for compilers, that by default are not recognized by TypeIndex library.
78///
79/// \b Example:
80///
81/// Imagine the situation when
82/// \code boost::typeindex::ctti_type_index::type_id<int>().pretty_name() \endcode
83/// returns the following string:
84/// \code "static const char *boost::detail::ctti<int>::n() [T = int]" \endcode
85/// and \code boost::typeindex::ctti_type_index::type_id<short>().pretty_name() \endcode returns the following:
86/// \code "static const char *boost::detail::ctti<short>::n() [T = short]" \endcode
87///
88/// As we may see first 39 characters are "static const char *boost::detail::ctti<" and they do not depend on
89/// the type T. After first 39 characters we have a human readable type name which is duplicated at the end
90/// of a string. String always ends on ']', which consumes 1 character.
91///
92/// Now if we define `BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING` to
93/// `(39, 1, false, "")` we'll be getting \code "int>::n() [T = int" \endcode
94/// for `boost::typeindex::ctti_type_index::type_id<int>().pretty_name()` and \code "short>::n() [T = short" \endcode
95/// for `boost::typeindex::ctti_type_index::type_id<short>().pretty_name()`.
96///
97/// Now we need to take additional care of the characters that go before the last mention of our type. We'll
98/// do that by telling the macro that we need to cut off everything that goes before the "T = " including the "T = "
99/// itself:
100///
101/// \code (39, 1, true, "T = ") \endcode
102///
103/// In case of GCC or Clang command line we need to add the following line while compiling all the sources:
104///
105/// \code
106/// -DBOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING='(39, 1, true, "T = ")'
107/// \endcode
108/// \param begin_skip How many characters must be skipped at the beginning of the type holding string.
109/// Must be a compile time constant.
110/// \param end_skip How many characters must be skipped at the end of the type holding string.
111/// Must be a compile time constant.
112/// \param runtime_skip Do we need additional checks at runtime to cut off the more characters.
113/// Must be `true` or `false`.
114/// \param runtime_skip_until Skip all the characters before the following string (including the string itself).
115/// Must be a compile time array of characters.
116///
117/// See [RTTI emulation limitations](boost_typeindex/rtti_emulation_limitations.html) for more info.
118#define BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING (0, 0, false, "")
119
120
121 /// Depending on a compiler flags, optimal implementation of type_index will be used
122 /// as a default boost::typeindex::type_index.
123 ///
124 /// Could be a boost::typeindex::stl_type_index, boost::typeindex::ctti_type_index or
125 /// user defined type_index class.
126 ///
127 /// \b See boost::typeindex::type_index_facade for a full description of type_index functions.
128 typedef platform_specific type_index;
129#elif defined(BOOST_TYPE_INDEX_USER_TYPEINDEX)
130 // Nothing to do
131#elif (!defined(BOOST_NO_RTTI) && !defined(BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY)) || defined(BOOST_MSVC)
132 typedef boost::typeindex::stl_type_index type_index;
133#else
134 typedef boost::typeindex::ctti_type_index type_index;
135#endif
136
137/// Depending on a compiler flags, optimal implementation of type_info will be used
138/// as a default boost::typeindex::type_info.
139///
140/// Could be a std::type_info, boost::typeindex::detail::ctti_data or
141/// some user defined class.
142///
143/// type_info \b is \b not copyable or default constructible. It is \b not assignable too!
144typedef type_index::type_info_t type_info;
145
146#if defined(BOOST_TYPE_INDEX_DOXYGEN_INVOKED)
147
148/// \def BOOST_TYPE_INDEX_USER_TYPEINDEX
149/// BOOST_TYPE_INDEX_USER_TYPEINDEX can be defined to the path to header file
150/// with user provided implementation of type_index.
151///
152/// See [Making a custom type_index](boost_typeindex/making_a_custom_type_index.html) section
153/// of documentation for usage example.
154#define BOOST_TYPE_INDEX_USER_TYPEINDEX <full/absolute/path/to/header/with/type_index.hpp>
155
156
157/// \def BOOST_TYPE_INDEX_REGISTER_CLASS
158/// BOOST_TYPE_INDEX_REGISTER_CLASS is used to help to emulate RTTI.
159/// Put this macro into the public section of polymorphic class to allow runtime type detection.
160///
161/// Depending on the typeid() availability this macro will expand to nothing or to virtual helper function
162/// `virtual const type_info& boost_type_info_type_id_runtime_() const noexcept`.
163///
164/// \b Example:
165/// \code
166/// class A {
167/// public:
168/// BOOST_TYPE_INDEX_REGISTER_CLASS
169/// virtual ~A(){}
170/// };
171///
172/// struct B: public A {
173/// BOOST_TYPE_INDEX_REGISTER_CLASS
174/// };
175///
176/// struct C: public B {
177/// BOOST_TYPE_INDEX_REGISTER_CLASS
178/// };
179///
180/// ...
181///
182/// C c1;
183/// A* pc1 = &c1;
184/// assert(boost::typeindex::type_id<C>() == boost::typeindex::type_id_runtime(*pc1));
185/// \endcode
186#define BOOST_TYPE_INDEX_REGISTER_CLASS nothing-or-some-virtual-functions
187
188/// \def BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY
189/// BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY is a helper macro that must be defined if mixing
190/// RTTI on/off modules. See
191/// [Mixing sources with RTTI on and RTTI off](boost_typeindex/mixing_sources_with_rtti_on_and_.html)
192/// section of documentation for more info.
193#define BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY
194
195#endif // defined(BOOST_TYPE_INDEX_DOXYGEN_INVOKED)
196
197
198/// Function to get boost::typeindex::type_index for a type T.
199/// Removes const, volatile && and & modifiers from T.
200///
201/// \b Example:
202/// \code
203/// type_index ti = type_id<int&>();
204/// std::cout << ti.pretty_name(); // Outputs 'int'
205/// \endcode
206///
207/// \tparam T Type for which type_index must be created.
208/// \throw Nothing.
209/// \return boost::typeindex::type_index with information about the specified type T.
210template <class T>
211inline type_index type_id() BOOST_NOEXCEPT {
212 return type_index::type_id<T>();
213}
214
215/// Function for constructing boost::typeindex::type_index instance for type T.
216/// Does not remove const, volatile, & and && modifiers from T.
217///
218/// If T has no const, volatile, & and && modifiers, then returns exactly
219/// the same result as in case of calling `type_id<T>()`.
220///
221/// \b Example:
222/// \code
223/// type_index ti = type_id_with_cvr<int&>();
224/// std::cout << ti.pretty_name(); // Outputs 'int&'
225/// \endcode
226///
227/// \tparam T Type for which type_index must be created.
228/// \throw Nothing.
229/// \return boost::typeindex::type_index with information about the specified type T.
230template <class T>
231inline type_index type_id_with_cvr() BOOST_NOEXCEPT {
232 return type_index::type_id_with_cvr<T>();
233}
234
235/// Function that works exactly like C++ typeid(rtti_val) call, but returns boost::type_index.
236///
237/// Returns runtime information about specified type.
238///
239/// \b Requirements: RTTI available or Base and Derived classes must be marked with BOOST_TYPE_INDEX_REGISTER_CLASS.
240///
241/// \b Example:
242/// \code
243/// struct Base { virtual ~Base(){} };
244/// struct Derived: public Base {};
245/// ...
246/// Derived d;
247/// Base& b = d;
248/// type_index ti = type_id_runtime(b);
249/// std::cout << ti.pretty_name(); // Outputs 'Derived'
250/// \endcode
251///
252/// \param runtime_val Variable which runtime type must be returned.
253/// \throw Nothing.
254/// \return boost::typeindex::type_index with information about the specified variable.
255template <class T>
256inline type_index type_id_runtime(const T& runtime_val) BOOST_NOEXCEPT {
257 return type_index::type_id_runtime(runtime_val);
258}
259
260}} // namespace boost::typeindex
261
262
263
264#endif // BOOST_TYPE_INDEX_HPP
265
266

source code of include/boost/type_index.hpp