From b88b75b3294979a943ef2a2758667109b9b865e3 Mon Sep 17 00:00:00 2001 From: Antony Polukhin Date: Tue, 26 Jun 2012 21:17:42 +0400 Subject: [PATCH] * Performance update for GGC 4.5 and newer * type_id_rtti_only function added * Documentation and tests updates --- boost/type_index.hpp | 31 +++++++++++++++-- libs/type_index/doc/type_index.qbk | 4 ++- libs/type_index/test/type_index_test.cpp | 42 ++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 3 deletions(-) diff --git a/boost/type_index.hpp b/boost/type_index.hpp index f437ce1..3e07992 100644 --- a/boost/type_index.hpp +++ b/boost/type_index.hpp @@ -225,9 +225,9 @@ template_index template_id_with_cvr() BOOST_NOEXCEPT { // for this compiler at least, cross-shared-library type_info // comparisons don't work, so use typeid(x).name() instead. It's not // yet clear what the best default strategy is. -# if (defined(__GNUC__) && __GNUC__ >= 3) \ +# if (defined(__GNUC__) && __GNUC__ >= 3 && __GNUC_MINOR__ < 5) \ || defined(_AIX) \ - || ( defined(__sgi) && defined(__host_mips)) \ + || (defined(__sgi) && defined(__host_mips)) \ || (defined(__hpux) && defined(__HP_aCC)) \ || (defined(linux) && defined(__INTEL_COMPILER) && defined(__ICC)) # define BOOST_CLASSINFO_COMPARE_BY_NAMES @@ -279,6 +279,20 @@ public: return type_index(typeid(no_cvr_t)); } + /// Factory function, that works exactly like C++ typeid(rtti_val) call, but returns boost::type_index. + /// This method available only with RTTI enabled. + template + static type_index construct_rtti_only(T& rtti_val) { + return type_index(typeid(rtti_val)); + } + + /// Factory function, that works exactly like C++ typeid(rtti_val) call, but returns boost::type_index. + /// This method available only with RTTI enabled. + template + static type_index construct_rtti_only(T* rtti_val) { + return type_index(typeid(rtti_val)); + } + /// Returns true if the type precedes the type of rhs in the collation order. /// The collation order is just an internal order. bool before(type_index const& rhs) const BOOST_NOEXCEPT { @@ -428,6 +442,19 @@ type_index type_id() { return type_index::construct(); } +/// Function, that works exactly like C++ typeid(rtti_val) call, but returns boost::type_index. +/// This method available only with RTTI enabled. +template +type_index type_id_rtti_only(T& rtti_val) { + 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. +template +type_index type_id_rtti_only(T* rtti_val) { + return type_index::construct_rtti_only(rtti_val); +} /* *************** type_index free functions ******************* */ diff --git a/libs/type_index/doc/type_index.qbk b/libs/type_index/doc/type_index.qbk index e2f36e4..0cb64f8 100644 --- a/libs/type_index/doc/type_index.qbk +++ b/libs/type_index/doc/type_index.qbk @@ -23,6 +23,8 @@ Sometimes getting and storing at runtime information about template type is requ Boost.TypeIndex was designed to work around those issues. +[note `T` means here type. Think of it, as of `T` in `template ` ] + [warning This library is not accepted to Boost, it is currrently waiting for review. ] [endsect] @@ -30,7 +32,7 @@ Boost.TypeIndex was designed to work around those issues. [section Getting started] In short: -Just replace `&typeid(T)`, `typeid(T)` with `boost::type_id()` and `const std::type_info&`, `std::type_index` with `boost::type_index`. That's all, you are now using Boost.TypeIndex. +Just replace `&typeid(T)`, `typeid(T)` with `boost::type_id()` and `const std::type_info&`, `std::type_index` with `boost::type_index`. For cases when RTTI is really required, replace `typeid(variable)` with `boost::type_id_rtti_only(variable)`. That's all, you are now using Boost.TypeIndex. To get nice human readable name, use `name_demangled()` member function: `` diff --git a/libs/type_index/test/type_index_test.cpp b/libs/type_index/test/type_index_test.cpp index bd0a3df..1a4f29e 100644 --- a/libs/type_index/test/type_index_test.cpp +++ b/libs/type_index/test/type_index_test.cpp @@ -309,4 +309,46 @@ BOOST_AUTO_TEST_CASE(template_index_user_defined_class_test) } +#ifndef BOOST_NO_RTTI + +class A { public: virtual ~A(){} }; +class B: public A{}; +class C: public B {}; + +BOOST_AUTO_TEST_CASE(comparators_type_id_rtti_only) +{ + C c1; + B b1; + A* pc1 = &c1; + A& rc1 = c1; + A* pb1 = &b1; + A& rb1 = b1; + BOOST_CHECK(typeid(rc1) == typeid(*pc1)); + BOOST_CHECK(typeid(rb1) == typeid(*pb1)); + + BOOST_CHECK(typeid(rc1) != typeid(*pb1)); + BOOST_CHECK(typeid(rb1) != typeid(*pc1)); + + BOOST_CHECK(typeid(&rc1) == typeid(pb1)); + BOOST_CHECK(typeid(&rb1) == typeid(pc1)); + + BOOST_CHECK_EQUAL(boost::type_id_rtti_only(rc1), boost::type_id_rtti_only(*pc1)); + BOOST_CHECK_EQUAL(boost::type_id_rtti_only(rb1), boost::type_id_rtti_only(*pb1)); + + BOOST_CHECK_NE(boost::type_id_rtti_only(rc1), boost::type_id_rtti_only(*pb1)); + BOOST_CHECK_NE(boost::type_id_rtti_only(rb1), boost::type_id_rtti_only(*pc1)); + BOOST_CHECK_EQUAL(boost::type_id_rtti_only(&rc1), boost::type_id_rtti_only(pb1)); + BOOST_CHECK_EQUAL(boost::type_id_rtti_only(&rb1), boost::type_id_rtti_only(pc1)); + + BOOST_CHECK(boost::type_id_rtti_only(rc1) == typeid(*pc1)); + BOOST_CHECK(boost::type_id_rtti_only(rb1) == typeid(*pb1)); + + BOOST_CHECK(boost::type_id_rtti_only(rc1) != typeid(*pb1)); + BOOST_CHECK(boost::type_id_rtti_only(rb1) != typeid(*pc1)); + BOOST_CHECK(boost::type_id_rtti_only(&rc1) == typeid(pb1)); + BOOST_CHECK(boost::type_id_rtti_only(&rb1) == typeid(pc1)); +} + +#endif // BOOST_NO_RTTI +