Line data Source code
1 : // 2 : // Copyright (c) 2012-2019 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 : 52 : namespace 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! 144 : typedef 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. 210 : template <class T> 211 16 : inline 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. 230 : template <class T> 231 : inline 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. 255 : template <class T> 256 : inline 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 :