From 311246d1a456f4e530ba579de5af32104f5d426a Mon Sep 17 00:00:00 2001 From: Antony Polukhin Date: Sat, 9 Jun 2012 22:01:36 +0400 Subject: [PATCH] * Reduced size of binary in case of template_index usage * Added noexcept modifiers * Added comparison operators for comparison with std::type_info --- boost/type_index.hpp | 199 ++++++++++++++++++++++++++++++------------- 1 file changed, 140 insertions(+), 59 deletions(-) diff --git a/boost/type_index.hpp b/boost/type_index.hpp index 5c88bd7..6931b16 100644 --- a/boost/type_index.hpp +++ b/boost/type_index.hpp @@ -45,58 +45,60 @@ namespace boost { namespace detail { #ifdef _MSC_VER - // sizeof("const char *__cdecl boost::detail::template_info<") - 1 - BOOST_STATIC_CONSTANT(std::size_t, template_info_skip_size_at_begin = 49); + // sizeof("const char *__cdecl boost::detail::ctti<") - 1 + BOOST_STATIC_CONSTANT(std::size_t, ctti_skip_size_at_begin = 40); // sizeof(">::name(void)") - 1 - BOOST_STATIC_CONSTANT(std::size_t, template_info_skip_size_at_end = 13); + BOOST_STATIC_CONSTANT(std::size_t, ctti_skip_size_at_end = 13); #elif defined __clang__ - // sizeof("static const char *boost::detail::template_info<") - 1 - BOOST_STATIC_CONSTANT(std::size_t, template_info_skip_size_at_begin = 48); + // sizeof("static const char *boost::detail::ctti<") - 1 + BOOST_STATIC_CONSTANT(std::size_t, ctti_skip_size_at_begin = 39); // == sizeof(">::name()") - 1 - BOOST_STATIC_CONSTANT(std::size_t, template_info_skip_size_at_end = 9); + BOOST_STATIC_CONSTANT(std::size_t, ctti_skip_size_at_end = 9); #elif defined __GNUC__ - // sizeof("static const char* boost::detail::template_info::name() [with T = ") - 1 - BOOST_STATIC_CONSTANT(std::size_t, template_info_skip_size_at_begin = 69); + // sizeof("static const char* boost::detail::ctti::name() [with T = ") - 1 + BOOST_STATIC_CONSTANT(std::size_t, ctti_skip_size_at_begin = 60); // == sizeof("]") - 1 - BOOST_STATIC_CONSTANT(std::size_t, template_info_skip_size_at_end = 1); + BOOST_STATIC_CONSTANT(std::size_t, ctti_skip_size_at_end = 1); #else // TODO: Code for other platforms - BOOST_STATIC_CONSTANT(std::size_t, template_info_skip_size_at_begin = 0); // skip nothing - BOOST_STATIC_CONSTANT(std::size_t, template_info_skip_size_at_end = 0); // skip nothing + BOOST_STATIC_CONSTANT(std::size_t, ctti_skip_size_at_begin = 0); // skip nothing + BOOST_STATIC_CONSTANT(std::size_t, ctti_skip_size_at_end = 0); // skip nothing #endif - + /// Noncopyable type_info that does not require RTTI + /// CTTI == Compile Time Type Info + /// This name must be as short as posible, to avoid code bloat template - struct template_info { - typedef T template_type; - typedef template_info this_type; + struct ctti { + typedef T template_type; + typedef ctti this_type; /// Retrurns raw name - static const char* name() { - return BOOST_CURRENT_FUNCTION + detail::template_info_skip_size_at_begin; + static const char* name() BOOST_NOEXCEPT { + return BOOST_CURRENT_FUNCTION + detail::ctti_skip_size_at_begin; } /// 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() { - return std::strcmp(this_type::name(), template_info::name_begin()) < 0; + static bool before() BOOST_NOEXCEPT { + return std::strcmp(this_type::name(), ctti::name_begin()) < 0; } /// Returns length of demangled name - static std::size_t name_length() { - return std::strlen(this_type::name()) - detail::template_info_skip_size_at_end; + static std::size_t name_length() BOOST_NOEXCEPT { + return std::strlen(this_type::name()) - detail::ctti_skip_size_at_end; } /// Retrurns user-friendly name - static std::string name_demangled() { + static std::string name_demangled() BOOST_NOEXCEPT { return std::string(this_type::name(), this_type::name_length()); } }; @@ -105,14 +107,14 @@ namespace detail { /// @defgroup template_index_methods template_index class and methods /// @{ -/// Copyable type_info that does not require RTTI and could store const, +/// Copyable type_info that does not require RTTI and could store const, /// volatile and references if constructed via construct_with_cvr() class template_index { private: const char* name_; - + /// @cond - explicit template_index(const char* name) + explicit template_index(const char* name) BOOST_NOEXCEPT : name_(name) {} /// @endcond @@ -132,7 +134,7 @@ public: , "Your EDG-based compiler seems to mistakenly distinguish 'int' from 'signed int', in typeid() expressions."); #endif - return template_index(detail::template_info::name()); + return template_index(detail::ctti::name()); } /// Factory method for constructing template_index instance for type T. @@ -145,58 +147,58 @@ public: , "Your EDG-based compiler seems to mistakenly distinguish 'int' from 'signed int', in typeid() expressions."); #endif - return template_index(detail::template_info::name()); + return template_index(detail::ctti::name()); } /// 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 { + bool before(const template_index& rhs) const BOOST_NOEXCEPT { return std::strcmp(name(), rhs.name()) < 0; } /// Retrurns raw name - const char* name() const { + const char* name() const BOOST_NOEXCEPT { return name_; } /// Retrurns user-friendly name std::string name_demangled() const { - return std::string(name_, std::strlen(name_) - detail::template_info_skip_size_at_end); + return std::string(name_, std::strlen(name_) - detail::ctti_skip_size_at_end); } /// Comparison operator - bool operator == (const template_index& rhs) const { + bool operator == (const template_index& rhs) const BOOST_NOEXCEPT { return !std::strcmp(name_, rhs.name()); } /// Comparison operator - bool operator != (const template_index& rhs) const { + bool operator != (const template_index& rhs) const BOOST_NOEXCEPT { return !!std::strcmp(name_, rhs.name()); } /// Comparison operator - bool operator < (const template_index& rhs) const { + bool operator < (const template_index& rhs) const BOOST_NOEXCEPT { return std::strcmp(name_, rhs.name()) < 0; } /// Comparison operator - bool operator > (const template_index& rhs) const { + bool operator > (const template_index& rhs) const BOOST_NOEXCEPT { return std::strcmp(name_, rhs.name()) > 0; } /// Comparison operator - bool operator <= (const template_index& rhs) const { + bool operator <= (const template_index& rhs) const BOOST_NOEXCEPT { return std::strcmp(name_, rhs.name()) <= 0; } /// Comparison operator - bool operator >= (const template_index& rhs) const { + bool operator >= (const template_index& rhs) const BOOST_NOEXCEPT { return std::strcmp(name_, rhs.name()) >= 0; } /// Function for getting hash value - std::size_t hash_code() const { + std::size_t hash_code() const BOOST_NOEXCEPT { return boost::hash_range(name_, name_ + std::strlen(name_)); } }; @@ -204,14 +206,14 @@ public: /// Method for constructing template_index instance for type T. /// Strips const, volatile and & modifiers from T. template -template_index template_id() { +template_index template_id() BOOST_NOEXCEPT { return template_index::construct(); } /// Factory method for constructing template_index instance for type T. /// Does not strips const, volatile and & modifiers from T. template -template_index template_id_with_cvr() { +template_index template_id_with_cvr() BOOST_NOEXCEPT { return template_index::construct_with_cvr(); } @@ -226,6 +228,9 @@ template_index template_id_with_cvr() { || (defined(__hpux) && defined(__HP_aCC)) \ || (defined(linux) && defined(__INTEL_COMPILER) && defined(__ICC)) # define BOOST_CLASSINFO_COMPARE_BY_NAMES +# define BOOST_CLASSINFO_COMPARISON_NOEXCEPT +#else +# define BOOST_CLASSINFO_COMPARISON_NOEXCEPT BOOST_NOEXCEPT # endif /// @} @@ -235,18 +240,19 @@ template_index template_id_with_cvr() { /// Copyable type_info class that requires RTTI. class type_index { -private: +public: #ifdef BOOST_NO_STD_TYPEINFO - typedef type_info stl_type_index; + typedef type_info stl_type_info; #else - typedef std::type_info stl_type_index; + typedef std::type_info stl_type_info; #endif - const stl_type_index* pinfo_; +private: + const stl_type_info* pinfo_; /// @cond - explicit type_index(const stl_type_index& inf) + explicit type_index(const stl_type_info& inf) BOOST_NOEXCEPT : pinfo_(&inf) {} /// @endcond @@ -259,7 +265,7 @@ public: static type_index construct() { typedef BOOST_DEDUCED_TYPENAME boost::remove_reference::type no_ref_t; 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 @@ -271,7 +277,7 @@ public: /// 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 { + bool before(type_index const& rhs) const BOOST_NOEXCEPT { return !!pinfo_->before(*rhs.pinfo_); } @@ -293,13 +299,13 @@ public: std::string ret(demang); free(demang); return ret; - #else + #else return pinfo_->name(); #endif } /// Comparison operator - bool operator == (type_index const& rhs) const { + bool operator == (type_index const& rhs) const BOOST_CLASSINFO_COMPARISON_NOEXCEPT { #ifdef BOOST_CLASSINFO_COMPARE_BY_NAMES return !std::strcmp(pinfo_->name(), rhs.pinfo_->name()); #else @@ -308,12 +314,12 @@ public: } /// Comparison operator - bool operator != (type_index const& rhs) const { + bool operator != (type_index const& rhs) const BOOST_CLASSINFO_COMPARISON_NOEXCEPT { return !(*this == rhs); } /// Comparison operator - bool operator < (type_index const& rhs) const { + bool operator < (type_index const& rhs) const BOOST_CLASSINFO_COMPARISON_NOEXCEPT { #ifdef BOOST_CLASSINFO_COMPARE_BY_NAMES return std::strcmp(pinfo_->name(), rhs.pinfo_->name()) < 0; #else @@ -322,17 +328,60 @@ public: } /// Comparison operator - bool operator > (type_index const& rhs) const { + bool operator > (type_index const& rhs) const BOOST_CLASSINFO_COMPARISON_NOEXCEPT { return (rhs < *this); } /// Comparison operator - bool operator <= (type_index const& rhs) const { + bool operator <= (type_index const& rhs) const BOOST_CLASSINFO_COMPARISON_NOEXCEPT { return !(*this > rhs); } - /// Comparison operator - bool operator >= (type_index const& rhs) const { + /// Comparison operator + bool operator >= (type_index const& rhs) const BOOST_CLASSINFO_COMPARISON_NOEXCEPT { + return !(*this < rhs); + } + + + /// Comparison operator for native std::type_info + bool operator == (stl_type_info const& rhs) const BOOST_CLASSINFO_COMPARISON_NOEXCEPT { + #ifdef BOOST_CLASSINFO_COMPARE_BY_NAMES + return !std::strcmp(pinfo_->name(), rhs.name()); + #else + return *pinfo_ == rhs; + #endif + } + + /// Comparison operator for native std::type_info + bool operator != (stl_type_info const& rhs) const BOOST_CLASSINFO_COMPARISON_NOEXCEPT { + return !(*this == rhs); + } + + /// Comparison operator for native std::type_info + bool operator < (stl_type_info const& rhs) const BOOST_CLASSINFO_COMPARISON_NOEXCEPT { + #ifdef BOOST_CLASSINFO_COMPARE_BY_NAMES + return std::strcmp(pinfo_->name(), rhs.name()) < 0; + #else + return pinfo_->before(rhs); + #endif + } + + /// Comparison operator for native std::type_info + bool operator > (stl_type_info const& rhs) const BOOST_CLASSINFO_COMPARISON_NOEXCEPT { + #ifdef BOOST_CLASSINFO_COMPARE_BY_NAMES + return std::strcmp(pinfo_->name(), rhs.name()) > 0; + #else + return rhs.before(*pinfo_); + #endif + } + + /// Comparison operator for native std::type_info + bool operator <= (stl_type_info const& rhs) const BOOST_CLASSINFO_COMPARISON_NOEXCEPT { + return !(*this > rhs); + } + + /// Comparison operator for native std::type_info + bool operator >= (stl_type_info const& rhs) const BOOST_CLASSINFO_COMPARISON_NOEXCEPT { return !(*this < rhs); } @@ -342,9 +391,41 @@ public: } }; +/// Comparison operator for native std::type_info +inline bool operator == (type_index::stl_type_info const& lhs, type_index const& rhs) BOOST_CLASSINFO_COMPARISON_NOEXCEPT { + return rhs == lhs; // Operation is comutative +} + +/// Comparison operator for native std::type_info +inline bool operator != (type_index::stl_type_info const& lhs, type_index const& rhs) BOOST_CLASSINFO_COMPARISON_NOEXCEPT { + return rhs != lhs; // Operation is comutative +} + +/// Comparison operator for native std::type_info +inline bool operator < (type_index::stl_type_info const& lhs, type_index const& rhs) BOOST_CLASSINFO_COMPARISON_NOEXCEPT { + return rhs > lhs; +} + +/// Comparison operator for native std::type_info +inline bool operator > (type_index::stl_type_info const& lhs, type_index const& rhs) BOOST_CLASSINFO_COMPARISON_NOEXCEPT { + return rhs < lhs; +} + +/// Comparison operator for native std::type_info +inline bool operator <= (type_index::stl_type_info const& lhs, type_index const& rhs) BOOST_CLASSINFO_COMPARISON_NOEXCEPT { + return rhs >= lhs; +} + +/// Comparison operator for native std::type_info +inline bool operator >= (type_index::stl_type_info const& lhs, type_index const& rhs) BOOST_CLASSINFO_COMPARISON_NOEXCEPT { + return rhs <= lhs; +} + +#undef BOOST_CLASSINFO_COMPARISON_NOEXCEPT + #ifdef BOOST_CLASSINFO_COMPARE_BY_NAMES #undef BOOST_CLASSINFO_COMPARE_BY_NAMES -#endif +#endif /// Function, to get type_index for a type T. /// Strips const, volatile and & modifiers from T. @@ -374,7 +455,7 @@ inline std::basic_ostream& operator<<(std::basic_ostream& operator<<(std::basic_ostream