diff --git a/boost/type_index/template_index_impl.hpp b/boost/type_index/template_info_impl.hpp similarity index 66% rename from boost/type_index/template_index_impl.hpp rename to boost/type_index/template_info_impl.hpp index a64cea4..3183cca 100644 --- a/boost/type_index/template_index_impl.hpp +++ b/boost/type_index/template_info_impl.hpp @@ -6,25 +6,20 @@ // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // -#ifndef BOOST_TYPE_INDEX_TEMPLATE_INDEX_IMPL_HPP -#define BOOST_TYPE_INDEX_TEMPLATE_INDEX_IMPL_HPP +#ifndef BOOST_TYPE_INDEX_TEMPLATE_INFO_IMPL_HPP +#define BOOST_TYPE_INDEX_TEMPLATE_INFO_IMPL_HPP // MS compatible compilers support #pragma once #if defined(_MSC_VER) # 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 boost::template_index class. +/// \file template_info_impl.hpp +/// \brief Contains implementation of boost::template_info class. /// -/// boost::template_index class is used instead of boost::type_index class in situations when RTTI is disabled. +/// boost::template_info class is used instead of boost::type_info in situations when RTTI is disabled. /// -/// Consider including or instead of this file. +/// Consider including or instead of this file. #include #include @@ -35,42 +30,33 @@ #include #include -#if !defined(BOOST_NO_IOSTREAM) -#if !defined(BOOST_NO_IOSFWD) -#include // for std::basic_ostream -#else -#include -#endif -#endif - - namespace boost { namespace detail { #if defined(BOOST_TYPE_INDEX_DOXYGEN_INVOKED) /// \def BOOST_TYPE_INDEX_FUNCTION_SIGNATURE -/// BOOST_TYPE_INDEX_FUNCTION_SIGNATURE is used by boost::template_index class to +/// BOOST_TYPE_INDEX_FUNCTION_SIGNATURE is used by boost::template_info class to /// deduce the name of a template parameter. If your compiler is not recognized -/// by the TypeIndex library and you wish to work with boost::template_index, you may +/// by the TypeIndex library and you wish to work with boost::template_info, you may /// define this macro by yourself. /// /// BOOST_TYPE_INDEX_FUNCTION_SIGNATURE must be defined to a compiler specific macro, /// that outputs the WHOLE function signature, including template parameters. /// /// If your compiler is not recognised and BOOST_TYPE_INDEX_FUNCTION_SIGNATURE is not defined, -/// then a compile-time error will arise at any attempt to use boost::template_index class. +/// then a compile-time error will arise at any attempt to use boost::template_info class. #define BOOST_TYPE_INDEX_FUNCTION_SIGNATURE BOOST_CURRENT_FUNCTION #elif defined(BOOST_TYPE_INDEX_FUNCTION_SIGNATURE) template -inline void lazy_function_signature_assert(){} +inline void lazy_function_signature_assert() BOOST_NOEXCEPT {} #elif defined(__FUNCSIG__) template -inline void lazy_function_signature_assert(){} +inline void lazy_function_signature_assert() BOOST_NOEXCEPT {} #define BOOST_TYPE_INDEX_FUNCTION_SIGNATURE __FUNCSIG__ #elif defined(__PRETTY_FUNCTION__) \ @@ -81,13 +67,13 @@ inline void lazy_function_signature_assert(){} || defined(__DMC__) template -inline void lazy_function_signature_assert(){} +inline void lazy_function_signature_assert() BOOST_NOEXCEPT {} #define BOOST_TYPE_INDEX_FUNCTION_SIGNATURE __PRETTY_FUNCTION__ #else template -inline void lazy_function_signature_assert() { +inline void lazy_function_signature_assert() BOOST_NOEXCEPT { BOOST_STATIC_ASSERT_MSG( sizeof(T) && false, "TypeIndex library could not detect your compiler. " @@ -149,48 +135,26 @@ inline void lazy_function_signature_assert() { static const char* name() BOOST_NOEXCEPT { return this_type::n(); } - - /// Returns true if the type precedes the type of rhs in the collation order. - /// The collation order is just an internal order. - template - static bool before() BOOST_NOEXCEPT { - return std::strcmp(this_type::n(), ctti::n()) < 0; - } - - /// Returns length of demangled name - static std::size_t name_length() BOOST_NOEXCEPT { - return std::strlen(this_type::n() + detail::ctti_skip_size_at_end); - } - - /// Returns user-friendly name - static std::string name_demangled() BOOST_NOEXCEPT { - return std::string(this_type::n(), this_type::name_length()); - } }; } // namespace detail /// Copyable type_info that does not require RTTI and could store const, /// volatile and references if constructed via construct_with_cvr() -class template_index { +class template_info: boost::noncopyable { private: const char* name_; /// @cond - explicit template_index(const char* name) BOOST_NOEXCEPT + explicit template_info(const char* name) BOOST_NOEXCEPT : name_(name) {} /// @endcond public: - /// Default constructor. - template_index() BOOST_NOEXCEPT - : name_(detail::ctti::name()) - {} - /// Factory method for constructing template_index instance for type T. /// Strips const, volatile and & modifiers from T template - static template_index construct(){ + static const template_info& construct() BOOST_NOEXCEPT { typedef BOOST_DEDUCED_TYPENAME boost::remove_reference::type no_ref_t; typedef BOOST_DEDUCED_TYPENAME boost::remove_cv::type no_cvr_t; @@ -200,26 +164,28 @@ public: , "Your EDG-based compiler seems to mistakenly distinguish 'int' from 'signed int', in typeid() expressions."); #endif - return template_index(detail::ctti::name()); + static const template_index ret(detail::ctti::name()) + return ret; } /// Factory method for constructing template_index instance for type T. /// Does not strip const, volatile and & modifiers from T template - static template_index construct_with_cvr() { + static const template_info& construct_with_cvr() BOOST_NOEXCEPT { # if (defined(__EDG_VERSION__) && __EDG_VERSION__ < 245) \ || (defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 744) BOOST_STATIC_ASSERT_MSG( !boost::is_arithmetic::type::value , "Your EDG-based compiler seems to mistakenly distinguish 'int' from 'signed int', in typeid() expressions."); #endif - return template_index(detail::ctti::name()); + static const template_index ret(detail::ctti::name()) + return ret; } /// Returns true if the type precedes the type of rhs in the collation order. /// The collation order is just an internal order. - bool before(const template_index& rhs) const BOOST_NOEXCEPT { + bool before(const template_info& rhs) const BOOST_NOEXCEPT { return std::strcmp(name(), rhs.name()) < 0; } @@ -233,32 +199,14 @@ public: return std::string(name_, std::strlen(name_ + detail::ctti_skip_size_at_end)); } - /// @cond - bool operator == (const template_index& rhs) const BOOST_NOEXCEPT { + bool operator == (const template_info& rhs) const BOOST_NOEXCEPT { return !std::strcmp(name_, rhs.name()); } - bool operator != (const template_index& rhs) const BOOST_NOEXCEPT { + bool operator != (const template_info& rhs) const BOOST_NOEXCEPT { return !!std::strcmp(name_, rhs.name()); } - - bool operator < (const template_index& rhs) const BOOST_NOEXCEPT { - return std::strcmp(name_, rhs.name()) < 0; - } - - bool operator > (const template_index& rhs) const BOOST_NOEXCEPT { - return std::strcmp(name_, rhs.name()) > 0; - } - - bool operator <= (const template_index& rhs) const BOOST_NOEXCEPT { - return std::strcmp(name_, rhs.name()) <= 0; - } - - bool operator >= (const template_index& rhs) const BOOST_NOEXCEPT { - return std::strcmp(name_, rhs.name()) >= 0; - } - /// @endcond - + /// Function for getting hash value std::size_t hash_code() const BOOST_NOEXCEPT { return boost::hash_range(name_, name_ + std::strlen(name_ + detail::ctti_skip_size_at_end)); @@ -268,7 +216,7 @@ public: /// Method for constructing template_index instance for type T. /// Strips const, volatile and & modifiers from T. template -inline template_index template_id() BOOST_NOEXCEPT { +inline const template_info& template_id() BOOST_NOEXCEPT { return template_index::construct(); } @@ -277,31 +225,13 @@ inline template_index template_id() BOOST_NOEXCEPT { /// If T has no const, volatile, & and && modifiers, then returns exactly /// the same result as in case of calling `template_id()`. template -inline template_index template_id_with_cvr() BOOST_NOEXCEPT { +inline const template_info& template_id_with_cvr() BOOST_NOEXCEPT { return template_index::construct_with_cvr(); } -/* *************** template_index free functions ******************* */ - -#ifndef BOOST_NO_IOSTREAM -#ifdef BOOST_NO_TEMPLATED_IOSTREAMS -/// Ostream operator that will output demangled name -inline std::ostream& operator<<(std::ostream& ostr, template_index const& ind) { - ostr << ind.name_demangled(); - return ostr; -} -#else -/// Ostream operator that will output demangled name -template -inline std::basic_ostream& operator<<(std::basic_ostream& ostr, template_index const& ind) { - ostr << ind.name_demangled(); - return ostr; -} -#endif // BOOST_NO_TEMPLATED_IOSTREAMS -#endif // BOOST_NO_IOSTREAM - +/* *************** template_info free functions ******************* */ /// hash_value function overload for template_index -inline std::size_t hash_value(template_index const& v) BOOST_NOEXCEPT { +inline std::size_t hash_value(template_info const& v) BOOST_NOEXCEPT { return v.hash_code(); } diff --git a/boost/type_index/type_index_minimal.hpp b/boost/type_index/type_index.hpp similarity index 100% rename from boost/type_index/type_index_minimal.hpp rename to boost/type_index/type_index.hpp diff --git a/boost/type_index/type_info.hpp b/boost/type_index/type_info.hpp new file mode 100644 index 0000000..255d4cf --- /dev/null +++ b/boost/type_index/type_info.hpp @@ -0,0 +1,70 @@ +// +// Copyright (c) Antony Polukhin, 2012-2013. +// +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef BOOST_TYPE_INDEX_TYPE_INDEX_MINIMAL_HPP +#define BOOST_TYPE_INDEX_TYPE_INDEX_MINIMAL_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/// \file type_index_minimal.hpp +/// \brief This is the header that required for ussage of boost::type_index with/without RTTI. +/// +/// It includes only the minamally required headers and does the 'typedef template_index type_index;' +/// when RTTI is disabled. + +#include + +#if !defined(BOOST_NO_RTTI) && !defined(BOOST_TYPE_INDEX_FORCE_NORTTI_COMPATIBILITY) +# include +#else +# include +# include + +namespace boost { + +typedef template_index type_index; + +template +inline type_index type_id() BOOST_NOEXCEPT { + return template_index::construct(); +} + +template +inline type_index type_id_with_cvr() BOOST_NOEXCEPT { + return template_index::construct_with_cvr(); +} + +template +inline 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 +inline 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 + +#if defined(BOOST_TYPE_INDEX_DOXYGEN_INVOKED) +/// \def BOOST_TYPE_INDEX_FORCE_NORTTI_COMPATIBILITY +/// Define the BOOST_TYPE_INDEX_FORCE_NORTTI_COMPATIBILITY macro if you are mixing objects +/// compiled with different RTTI flags. This will force the usage of boost::template_index +/// class instead of boost::type_index. +#define BOOST_TYPE_INDEX_FORCE_NORTTI_COMPATIBILITY +#endif // BOOST_TYPE_INDEX_DOXYGEN_INVOKED + +#endif // BOOST_TYPE_INDEX_TYPE_INDEX_MINIMAL_HPP + diff --git a/boost/type_index/type_index_impl.hpp b/boost/type_index/type_info_impl.hpp similarity index 55% rename from boost/type_index/type_index_impl.hpp rename to boost/type_index/type_info_impl.hpp index d9faf66..037220d 100644 --- a/boost/type_index/type_index_impl.hpp +++ b/boost/type_index/type_info_impl.hpp @@ -18,14 +18,14 @@ #error "Include or instead." #endif -/// \file type_index_impl.hpp -/// \brief Contains implementation of boost::type_index class. +/// \file type_info_impl.hpp +/// \brief Contains implementation of boost::type_info class. /// -/// boost::type_index class is used in situations when RTTI is enabled. -/// When RTTI is disabled or BOOST_TYPE_INDEX_FORCE_NORTTI_COMPATIBILITY macro is defined boost::template_index +/// boost::type_info class is used in situations when RTTI is enabled. +/// When RTTI is disabled or BOOST_TYPE_INDEX_FORCE_NORTTI_COMPATIBILITY macro is defined boost::template_info /// is used instead. /// -/// Consider including or instead of this file. +/// Consider including or instead of this file. #include @@ -87,32 +87,58 @@ namespace detail { #endif template class cvr_saver{}; +} +/// boost::type_info is a class that can be used as a drop-in replacement for std::type_info +class type_info: public detail::stl_type_info { +public: + /// Factory method for constructing boost::type_info instance for type T. + /// Strips const, volatile and & modifiers from T. template - struct strip_cvr { + static const boost::type_info& construct() BOOST_NOEXCEPT { typedef BOOST_DEDUCED_TYPENAME boost::remove_reference::type no_ref_t; - typedef BOOST_DEDUCED_TYPENAME boost::remove_cv::type type; + typedef BOOST_DEDUCED_TYPENAME boost::remove_cv::type no_cvr_t; # if (defined(__EDG_VERSION__) && __EDG_VERSION__ < 245) \ || (defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 744) BOOST_STATIC_ASSERT_MSG( !boost::is_arithmetic::type::value , "Your EDG-based compiler seems to mistakenly distinguish 'int' from 'signed int', in typeid() expressions."); #endif - }; + return reinterpret_cast(typeid(no_cvr_t)); + } + + /// Factory method for constructing boost::type_index instance for type 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 - struct save_cvr: boost::mpl::if_c< - boost::is_reference::value - || boost::is_const::value - || boost::is_volatile::value, - detail::cvr_saver, - T - >{}; -} + static const boost::type_info& construct_with_cvr() BOOST_NOEXCEPT { + typedef typename boost::mpl::if_c< + boost::is_reference::value + || boost::is_const::value + || boost::is_volatile::value, + detail::cvr_saver, + T + >::type type; + + return reinterpret_cast(typeid(type)); + } + + /// 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 const type_index& construct_rtti_only(T& rtti_val) BOOST_NOEXCEPT { + return reinterpret_cast(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 const type_index& construct_rtti_only(T* rtti_val) { + return reinterpret_cast(typeid(rtti_val)); + } -// -class type_info: public detail::stl_type_info { -public: const char* name() const BOOST_NOEXCEPT { #ifdef _MSC_VER return detail::stl_type_info::raw_name(); @@ -157,122 +183,12 @@ public: return ret.substr(pos, end - pos); } -}; -/// Copyable type_index class that requires RTTI. -/// Drop-in replacemant for std::type_index. -class type_index { -private: - const boost::type_info* pinfo_; - -public: - typedef detail::stl_type_info stl_type_info; - - /// Default constructor. - type_index() BOOST_NOEXCEPT - : pinfo_(reinterpret_cast(&typeid(void))) - {} - - /// Constructs type_index from an instance of boost::type_info. - type_index(const boost::type_info& inf) BOOST_NOEXCEPT - : pinfo_(&inf) - {} - - /// Constructs type_index from an instance of std::type_info. - explicit type_index(const stl_type_info& inf) BOOST_NOEXCEPT - : pinfo_(reinterpret_cast(&inf)) - {} - - /// Factory method for constructing type_index instance for type T. - /// Strips const, volatile and & modifiers from T. - template - static type_index construct() BOOST_NOEXCEPT { - typedef BOOST_DEDUCED_TYPENAME boost::detail::strip_cvr::type no_cvr_t; - return type_index(typeid(no_cvr_t)); - } - - /// Factory method for constructing type_index instance for type 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 - static type_index construct_with_cvr() BOOST_NOEXCEPT { - typedef typename boost::detail::save_cvr::type type; - return type_index(typeid(type)); - } - - /// 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 { - return !!pinfo_->before(*rhs.pinfo_); - } - - /// Returns raw name - const char* name() const BOOST_NOEXCEPT { - #ifdef _MSC_VER - return pinfo_->raw_name(); - #else - return pinfo_->name(); - #endif - } - - /// Returns user-friendly name - std::string name_demangled() const { - #if defined(__GNUC__) - std::string ret; - int status = 0; - char* demang = abi::__cxa_demangle(pinfo_->name(), NULL, 0, &status); - BOOST_ASSERT(!status); - - BOOST_TRY { - ret = demang; // may throw out of memory exception - } BOOST_CATCH (...) { - free(demang); - BOOST_RETHROW; - } BOOST_CATCH_END - - free(demang); - #else - std::string ret = pinfo_->name(); - #endif - std::string::size_type pos = ret.find("boost::detail::cvr_saver<"); - if (pos == std::string::npos) { - return ret; - } - - pos += sizeof("boost::detail::cvr_saver<") - 1; - while (ret[pos] == ' ') { - ++ pos; - } - std::string::size_type end = ret.rfind(">"); - BOOST_ASSERT(end != std::string::npos); - while (ret[end] == ' ') { - -- end; - } - - return ret.substr(pos, end - pos); - } - -#ifndef BOOST_TYPE_INDEX_DOXYGEN_INVOKED bool operator == (type_index const& rhs) const BOOST_NOEXCEPT { #ifdef BOOST_CLASSINFO_COMPARE_BY_NAMES - return !std::strcmp(pinfo_->name(), rhs.pinfo_->name()); + return !std::strcmp(name(), rhs.name()); #else - return *pinfo_ == *rhs.pinfo_; + return *this == rhs; #endif } @@ -280,114 +196,34 @@ public: return !(*this == rhs); } - bool operator < (type_index const& rhs) const BOOST_NOEXCEPT { + /// 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 { #ifdef BOOST_CLASSINFO_COMPARE_BY_NAMES - return std::strcmp(pinfo_->name(), rhs.pinfo_->name()) < 0; + return std::strcmp(name(), rhs.name()) < 0; #else - return before(rhs); + return this->before(rhs); #endif } - bool operator > (type_index const& rhs) const BOOST_NOEXCEPT { - return (rhs < *this); - } - - bool operator <= (type_index const& rhs) const BOOST_NOEXCEPT { - return !(*this > rhs); - } - - bool operator >= (type_index const& rhs) const BOOST_NOEXCEPT { - return !(*this < rhs); - } - - bool operator == (stl_type_info const& rhs) const BOOST_NOEXCEPT { - #ifdef BOOST_CLASSINFO_COMPARE_BY_NAMES - return !std::strcmp(pinfo_->name(), rhs.name()); - #else - return *pinfo_ == rhs; - #endif - } - - bool operator != (stl_type_info const& rhs) const BOOST_NOEXCEPT { - return !(*this == rhs); - } - - bool operator < (stl_type_info const& rhs) const BOOST_NOEXCEPT { - #ifdef BOOST_CLASSINFO_COMPARE_BY_NAMES - return std::strcmp(pinfo_->name(), rhs.name()) < 0; - #else - return !!pinfo_->before(rhs); - #endif - } - - bool operator > (stl_type_info const& rhs) const BOOST_NOEXCEPT { - #ifdef BOOST_CLASSINFO_COMPARE_BY_NAMES - return std::strcmp(pinfo_->name(), rhs.name()) > 0; - #else - return !!rhs.before(*pinfo_); - #endif - } - - bool operator <= (stl_type_info const& rhs) const BOOST_NOEXCEPT { - return !(*this > rhs); - } - - bool operator >= (stl_type_info const& rhs) const BOOST_NOEXCEPT { - return !(*this < rhs); - } -#endif // BOOST_TYPE_INDEX_DOXYGEN_INVOKED - /// Function for getting hash value std::size_t hash_code() const BOOST_NOEXCEPT { #if _MSC_VER >= 1600 || (__GNUC__ == 4 && __GNUC_MINOR__ > 5 && defined(__GXX_EXPERIMENTAL_CXX0X__)) - return pinfo_->hash_code(); + return detail::stl_type_info::hash_code(); #else return boost::hash_range(name(), name() + std::strlen(name())); #endif } }; -#ifndef BOOST_TYPE_INDEX_DOXYGEN_INVOKED - -/* *************** type_index free functions ******************* */ - -inline bool operator == (type_index::stl_type_info const& lhs, type_index const& rhs) BOOST_NOEXCEPT { - return rhs == lhs; // Operation is commutative -} - -inline bool operator != (type_index::stl_type_info const& lhs, type_index const& rhs) BOOST_NOEXCEPT { - return rhs != lhs; // Operation is commutative -} - -inline bool operator < (type_index::stl_type_info const& lhs, type_index const& rhs) BOOST_NOEXCEPT { - return rhs > lhs; -} - -inline bool operator > (type_index::stl_type_info const& lhs, type_index const& rhs) BOOST_NOEXCEPT { - return rhs < lhs; -} - -inline bool operator <= (type_index::stl_type_info const& lhs, type_index const& rhs) BOOST_NOEXCEPT { - return rhs >= lhs; -} - -inline bool operator >= (type_index::stl_type_info const& lhs, type_index const& rhs) BOOST_NOEXCEPT { - return rhs <= lhs; -} - -#endif // BOOST_TYPE_INDEX_DOXYGEN_INVOKED - #ifdef BOOST_CLASSINFO_COMPARE_BY_NAMES #undef BOOST_CLASSINFO_COMPARE_BY_NAMES #endif -/// @endcond - /// Function, to get std::type_info for a type T. Strips const, volatile and & modifiers from T. template inline const type_info& type_id() BOOST_NOEXCEPT { - typedef BOOST_DEDUCED_TYPENAME boost::detail::strip_cvr::type no_cvr_t; - return reinterpret_cast(typeid(no_cvr_t)); + return type_info::construct(); } /// Function for constructing std::type_info instance for type T. @@ -396,8 +232,7 @@ inline const type_info& type_id() BOOST_NOEXCEPT { /// the same result as in case of calling `type_id()`. template inline const type_info& type_id_with_cvr() BOOST_NOEXCEPT { - typedef typename boost::detail::save_cvr::type type; - return reinterpret_cast(typeid(type)); + return type_info::construct_with_cvr(); } /// Function, that works exactly like C++ typeid(rtti_val) call, but returns boost::type_index.