diff --git a/boost/type_index.hpp b/boost/type_index.hpp index 721a0bf..eab0960 100644 --- a/boost/type_index.hpp +++ b/boost/type_index.hpp @@ -11,8 +11,9 @@ /// \file type_index.hpp /// \brief Includes all the headers of the Boost.TypeIndex library. /// -/// By inclusion of this file classes `type_index` (if RTTI is on) and `template_index` will be available. -/// Consider including `` if you need only a type_index type with and without RTTI. +/// By inclusion of this file both classes (`type_index` (if RTTI is on) and `template_index`) will be available. +/// Consider including `` if you do not whant to include `template_index` class +/// while RTTI is available (this is recommended). // MS compatible compilers support #pragma once #if defined(_MSC_VER) @@ -23,3 +24,4 @@ #include #endif // BOOST_TYPE_INDEX_HPP + diff --git a/boost/type_index/template_index_impl.hpp b/boost/type_index/template_index_impl.hpp index 8c58dab..df608b4 100644 --- a/boost/type_index/template_index_impl.hpp +++ b/boost/type_index/template_index_impl.hpp @@ -14,6 +14,11 @@ # pragma once #endif +#ifndef BOOST_TYPE_INDEX_TYPE_INDEX_MINIMAL_HPP +#error "Header must not be included directly." +#error "Include or instead." +#endif + /// \file template_index_impl.hpp /// \brief Contains implementation of template_index class. /// @@ -145,7 +150,7 @@ public: } /// Factory method for constructing template_index instance for type T. - /// Does not strips const, volatile and & modifiers from T + /// Does not strip const, volatile and & modifiers from T template static template_index construct_with_cvr() { # if (defined(__EDG_VERSION__) && __EDG_VERSION__ < 245) \ @@ -214,7 +219,7 @@ template_index template_id() BOOST_NOEXCEPT { } /// Factory method for constructing template_index instance for type T. -/// Does not strips const, volatile and & modifiers from T. +/// Does not strip const, volatile and & modifiers from T. /// If T has no const, volatile, & and && modifiers, then returns exactly /// the same result as in case of calling `template_id()`. template diff --git a/boost/type_index/type_index_impl.hpp b/boost/type_index/type_index_impl.hpp index e017350..143977c 100644 --- a/boost/type_index/type_index_impl.hpp +++ b/boost/type_index/type_index_impl.hpp @@ -13,6 +13,11 @@ # pragma once #endif +#ifndef BOOST_TYPE_INDEX_TYPE_INDEX_MINIMAL_HPP +#error "Header must not be included directly." +#error "Include or instead." +#endif + /// \file type_index_impl.hpp /// \brief Contains implementation of type_index class. /// @@ -116,7 +121,7 @@ public: } /// Factory method for constructing type_index instance for type T. - /// Does not strips const, volatile, & and && modifiers from T. + /// Does not strip const, volatile, & and && modifiers from T. /// If T has no const, volatile, & and && modifiers, then returns exactly /// the same result as in case of calling `construct()`. template @@ -320,7 +325,7 @@ type_index type_id() BOOST_NOEXCEPT { } /// Function for constructing type_index instance for type T. -/// Does not strips const, volatile, & and && modifiers from T. +/// Does not strip const, volatile, & and && modifiers from T. /// If T has no const, volatile, & and && modifiers, then returns exactly /// the same result as in case of calling `type_id()`. template @@ -329,14 +334,16 @@ type_index type_id_with_cvr() BOOST_NOEXCEPT { } /// Function, that works exactly like C++ typeid(rtti_val) call, but returns boost::type_index. -/// This method available only with RTTI enabled. +/// This method available only with RTTI enabled. Without RTTI support it won't compile, +/// producing a compile-time error with message: "boost::type_id_rtti_only(T&) requires RTTI" template type_index type_id_rtti_only(T& rtti_val) BOOST_NOEXCEPT { return type_index::construct_rtti_only(rtti_val); } /// Function, that works exactly like C++ typeid(rtti_val) call, but returns boost::type_index. -/// This method available only with RTTI enabled. +/// This method available only with RTTI enabled. Without RTTI support it won't compile, +/// producing a compile-time error with message: "boost::type_id_rtti_only(T*) requires RTTI" template type_index type_id_rtti_only(T* rtti_val) { return type_index::construct_rtti_only(rtti_val); diff --git a/boost/type_index/type_index_minimal.hpp b/boost/type_index/type_index_minimal.hpp index 52662af..398a968 100644 --- a/boost/type_index/type_index_minimal.hpp +++ b/boost/type_index/type_index_minimal.hpp @@ -20,25 +20,40 @@ /// It includes only the minamally required headers and does the `typedef template_index type_index;` /// when RTTI is disabled. +#include + #ifndef BOOST_NO_RTTI # include #else # include +# include namespace boost { typedef template_index type_index; template -type_index type_id() { +type_index type_id() BOOST_NOEXCEPT { return template_index::construct(); } template -type_index type_id_with_cvr() { +type_index type_id_with_cvr() BOOST_NOEXCEPT { return template_index::construct_with_cvr(); } +template +type_index type_id_rtti_only(T& rtti_val) BOOST_NOEXCEPT { + BOOST_STATIC_ASSERT_MSG(sizeof(T) && false, "boost::type_id_rtti_only(T&) requires RTTI"); + return type_index(); +} + +template +type_index type_id_rtti_only(T* rtti_val) { + BOOST_STATIC_ASSERT_MSG(sizeof(T) && false, "boost::type_id_rtti_only(T*) requires RTTI"); + return type_index(); +} + } // namespace boost #endif // BOOST_NO_RTTI diff --git a/libs/type_index/doc/type_index.qbk b/libs/type_index/doc/type_index.qbk index 26148e8..fe772cf 100644 --- a/libs/type_index/doc/type_index.qbk +++ b/libs/type_index/doc/type_index.qbk @@ -16,7 +16,7 @@ Sometimes getting and storing information about a type at runtime is required. F * `typeid(T)` and `std::type_index` require Run Time Type Info (RTTI) * some implementations of `typeid(T)` strip const, volatile and references from type, while others don't * some compilers have bugs and do not correctly compare `std::type_info` objects across shared libraries -* only a few implementations of Standart Library currently provide `std::type_index` +* only a few implementations of Standard Library currently provide `std::type_index` * no easy way to store type info without stripping const, volatile and references * no nice and portable way to get human readable type names @@ -74,17 +74,39 @@ std::string nice_name_with_const_volatile_ref [xinclude autodoc.xml] -[section Performance] +[section Space and Performance] -`type_index` and `template_index` classes hold a single pointer, so they are easy and fast to copy. Calls to `const char* name()` do not require dynamic memory allocation and usually just return a pointer to an array of chars in a read-only section of the binary image. Comparison operators are optimized as much as possible, and will at worst execute a single `std::strcmp`. Calls to `std::string name_demangled()` for `type_index` do usually require dynamic memory allocation and some computations, so they are not recomended for usage in performance critical sections. Calls to `std::string name_demangled()` for `template_index` only require a single `std::strlen` call and are considerably faster than `std::string name_demangled()` for `type_index`. +* `template_index` uses the `BOOST_CURRENT_FUNCTION` macro which could lead to code bloat, so prefer using `type_index` type. +* `type_index` and `template_index` classes hold a single pointer, so they are easy and fast to copy. +* Calls to `const char* name()` do not require dynamic memory allocation and usually just return a pointer to an array of chars in a read-only section of the binary image. +* Comparison operators are optimized as much as possible, and will at worst execute a single `std::strcmp`. +* Calls to `std::string name_demangled()` for `type_index` do usually require dynamic memory allocation and some computations, so they are not recomended for usage in performance critical sections. +* Calls to `std::string name_demangled()` for `template_index` only require a single `std::strlen` call and are considerably faster than `std::string name_demangled()` for `type_index`. -`template_index` uses the `BOOST_CURRENT_FUNCTION` macro which could lead to code bloat, so prefer using `type_index` type. +[endsect] + +[section Code bloat] + +Without RTTI TypeIndex library will switch from using `boost::type_index` class to `boost::template_index`. `boost::template_index` uses the `BOOST_CURRENT_FUNCTION` for each type that is passed to `type_id()` and `type_id_with_cvr()` +functions. + +This leads to big strings in binary file: +``` +static const char* boost::detail::ctti::n() [with T = int] +static const char* boost::detail::ctti::n() [with T = user_defined_type] +``` +While using RTTI, you'll get the following (more compact) string in binary file: + +``` +i +17user_defined_type +``` [endsect] [section Compiler support] -TypeIndex has been tested on MSVC2010, GCC-4.5, Clang-2.9. If your compiler is not in a list of tested compilers, you shall correctly define `BOOST_TYPE_INDEX_CTTI_BEGIN_SKIP` and `BOOST_TYPE_INDEX_CTTI_END_SKIP` macroses: +TypeIndex has been tested and sucessfully work on MSVC2010, GCC-4.5, Clang-2.9. If your compiler is not in a list of tested compilers, you shall correctly define `BOOST_TYPE_INDEX_CTTI_BEGIN_SKIP` and `BOOST_TYPE_INDEX_CTTI_END_SKIP` macroses: # define `BOOST_TYPE_INDEX_CTTI_BEGIN_SKIP` and `BOOST_TYPE_INDEX_CTTI_END_SKIP` to `0` # get the output of `boost::detail::ctti::n()` diff --git a/libs/type_index/examples/demangled_names.cpp b/libs/type_index/examples/demangled_names.cpp index 89085c1..c3dc67e 100644 --- a/libs/type_index/examples/demangled_names.cpp +++ b/libs/type_index/examples/demangled_names.cpp @@ -6,8 +6,11 @@ //[type_index_names_example -//`The following example shows how short (mangled) and human readable type names could be obtained from a type. -// Works with and without RTTI. +/*` + The following example shows how short (mangled) and human readable type names could be obtained from a type. + Works with and without RTTI. +*/ + #include #include @@ -25,18 +28,23 @@ int main() { foo(1); // will output something like this: // - // Short name: .H - // Readable name: int + // (RTTI on) (RTTI off) + // Short name: i Short name: int] + // Readable name: int Readable name: int user_defined_type t; foo(t); // Will output: // - // Short name: .?AUuser_defined_type@@ - // Readable name: struct user_defined_type + // (RTTI on) (RTTI off) + // Short name: 17user_defined_type user_defined_type] + // Readable name: user_defined_type user_defined_type } -// The example +/*` + Short names are very compiler dependant: some compiler will output `.H`, others `i`. + Readable names may also differ between compilers: `struct user_defined_type`, `user_defined_type`. +*/ //] [/type_index_names_example] diff --git a/libs/type_index/examples/exact_types_match.cpp b/libs/type_index/examples/exact_types_match.cpp index 3bb40ee..04f1366 100644 --- a/libs/type_index/examples/exact_types_match.cpp +++ b/libs/type_index/examples/exact_types_match.cpp @@ -16,6 +16,7 @@ #include #include #include +#include class type_erased_unary_function { void* function_ptr_; diff --git a/libs/type_index/examples/inheritance.cpp b/libs/type_index/examples/inheritance.cpp index 01339f5..3684297 100644 --- a/libs/type_index/examples/inheritance.cpp +++ b/libs/type_index/examples/inheritance.cpp @@ -8,7 +8,8 @@ /*` The following example shows that `boost::type_index` is able to store the real type, successfully getting through all the inheritances. - Example works with RTTI only. + Example works with RTTI only. Without RTTI support it won't compile, producing a compile-time error with message: + "boost::type_id_rtti_only(T&) requires RTTI" */ #include diff --git a/libs/type_index/test/Jamfile.v2 b/libs/type_index/test/Jamfile.v2 index 02fdff3..3a5dec8 100644 --- a/libs/type_index/test/Jamfile.v2 +++ b/libs/type_index/test/Jamfile.v2 @@ -22,9 +22,10 @@ test-suite type_index [ run testing_minimal.cpp ] [ run testing_minimal_no_rtti.cpp : : : off ] # Examples that must work even with RTTI disabled - [ run ../examples/registry.cpp : : : off ] - [ run ../examples/exact_types_match.cpp : : : off ] - [ run ../examples/demangled_names.cpp : : : off ] + [ run ../examples/registry.cpp : : : off : registry_no_rtti ] + [ run ../examples/exact_types_match.cpp : : : off : exact_types_match_no_rtti ] + [ run ../examples/demangled_names.cpp : : : off : demangled_names_no_rtti ] + [ compile-fail ../examples/inheritance.cpp : off : failing_inheritance_example ] ; # Assuring that examples compile and run. Adding sources from `examples` directory to the `type_index` test suite. diff --git a/libs/type_index/test/template_index_test.cpp b/libs/type_index/test/template_index_test.cpp index b32ea9e..415a0d8 100644 --- a/libs/type_index/test/template_index_test.cpp +++ b/libs/type_index/test/template_index_test.cpp @@ -7,6 +7,10 @@ #define BOOST_TEST_MODULE template_index_test_module #include + +// Byapssing internal assertion for correct header inclusion +#define BOOST_TYPE_INDEX_TYPE_INDEX_MINIMAL_HPP + #include namespace my_namespace1 { diff --git a/libs/type_index/test/type_index_test.cpp b/libs/type_index/test/type_index_test.cpp index e3da35c..ce68309 100644 --- a/libs/type_index/test/type_index_test.cpp +++ b/libs/type_index/test/type_index_test.cpp @@ -7,6 +7,10 @@ #define BOOST_TEST_MODULE type_index_test_module #include + +// Byapssing internal assertion for correct header inclusion +#define BOOST_TYPE_INDEX_TYPE_INDEX_MINIMAL_HPP + #include namespace my_namespace1 {