LCOV - code coverage report
Current view: top level - usr/include/boost/type_index - stl_type_index.hpp (source / functions) Hit Total Coverage
Test: ROSE Lines: 5 5 100.0 %
Date: 2022-12-08 13:48:47 Functions: 0 0 -
Legend: Lines: hit not hit

          Line data    Source code
       1             : //
       2             : // Copyright (c) 2013-2019 Antony Polukhin.
       3             : //
       4             : //
       5             : // Distributed under the Boost Software License, Version 1.0. (See accompanying
       6             : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
       7             : //
       8             : 
       9             : #ifndef BOOST_TYPE_INDEX_STL_TYPE_INDEX_HPP
      10             : #define BOOST_TYPE_INDEX_STL_TYPE_INDEX_HPP
      11             : 
      12             : /// \file stl_type_index.hpp
      13             : /// \brief Contains boost::typeindex::stl_type_index class.
      14             : ///
      15             : /// boost::typeindex::stl_type_index class can be used as a drop-in replacement 
      16             : /// for std::type_index.
      17             : ///
      18             : /// It is used in situations when RTTI is enabled or typeid() method is available.
      19             : /// When typeid() is disabled or BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY macro
      20             : /// is defined boost::typeindex::ctti is usually used instead of boost::typeindex::stl_type_index.
      21             : 
      22             : #include <boost/type_index/type_index_facade.hpp>
      23             : 
      24             : // MSVC is capable of calling typeid(T) even when RTTI is off
      25             : #if defined(BOOST_NO_RTTI) && !defined(BOOST_MSVC)
      26             : #error "File boost/type_index/stl_type_index.ipp is not usable when typeid() is not available."
      27             : #endif
      28             : 
      29             : #include <typeinfo>
      30             : #include <cstring>                                  // std::strcmp, std::strlen, std::strstr
      31             : #include <stdexcept>
      32             : #include <boost/static_assert.hpp>
      33             : #include <boost/throw_exception.hpp>
      34             : #include <boost/core/demangle.hpp>
      35             : #include <boost/type_traits/conditional.hpp>
      36             : #include <boost/type_traits/is_const.hpp>
      37             : #include <boost/type_traits/is_reference.hpp>
      38             : #include <boost/type_traits/is_volatile.hpp>
      39             : #include <boost/type_traits/remove_cv.hpp>
      40             : #include <boost/type_traits/remove_reference.hpp>
      41             : 
      42             : #if (defined(_MSC_VER) && _MSC_VER > 1600) \
      43             :     || (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ > 5 && defined(__GXX_EXPERIMENTAL_CXX0X__)) \
      44             :     || (defined(__GNUC__) && __GNUC__ > 4 && __cplusplus >= 201103)
      45             : #   define BOOST_TYPE_INDEX_STD_TYPE_INDEX_HAS_HASH_CODE
      46             : #else
      47             : #   include <boost/container_hash/hash.hpp>
      48             : #endif
      49             : 
      50             : #if (defined(__EDG_VERSION__) && __EDG_VERSION__ < 245) \
      51             :         || (defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 744)
      52             : #   include <boost/type_traits/is_signed.hpp>
      53             : #   include <boost/type_traits/make_signed.hpp>
      54             : #   include <boost/type_traits/type_identity.hpp>
      55             : #endif
      56             : 
      57             : #ifdef BOOST_HAS_PRAGMA_ONCE
      58             : # pragma once
      59             : #endif
      60             : 
      61             : namespace boost { namespace typeindex {
      62             : 
      63             : /// \class stl_type_index
      64             : /// This class is a wrapper around std::type_info, that workarounds issues and provides
      65             : /// much more rich interface. \b For \b description \b of \b functions \b see type_index_facade.
      66             : ///
      67             : /// This class requires typeid() to work. For cases when RTTI is disabled see ctti_type_index.
      68             : class stl_type_index
      69             :     : public type_index_facade<
      70             :         stl_type_index, 
      71             :         #ifdef BOOST_NO_STD_TYPEINFO
      72             :             type_info
      73             :         #else
      74             :             std::type_info
      75             :         #endif
      76             :     > 
      77             : {
      78             : public:
      79             : #ifdef BOOST_NO_STD_TYPEINFO
      80             :     typedef type_info type_info_t;
      81             : #else
      82             :     typedef std::type_info type_info_t;
      83             : #endif
      84             : 
      85             : private:
      86             :     const type_info_t* data_;
      87             : 
      88             : public:
      89             :     inline stl_type_index() BOOST_NOEXCEPT
      90             :         : data_(&typeid(void))
      91             :     {}
      92             : 
      93          16 :     inline stl_type_index(const type_info_t& data) BOOST_NOEXCEPT
      94             :         : data_(&data)
      95             :     {}
      96             : 
      97             :     inline const type_info_t&  type_info() const BOOST_NOEXCEPT;
      98             : 
      99             :     inline const char*  raw_name() const BOOST_NOEXCEPT;
     100             :     inline const char*  name() const BOOST_NOEXCEPT;
     101             :     inline std::string  pretty_name() const;
     102             : 
     103             :     inline std::size_t  hash_code() const BOOST_NOEXCEPT;
     104             :     inline bool         equal(const stl_type_index& rhs) const BOOST_NOEXCEPT;
     105             :     inline bool         before(const stl_type_index& rhs) const BOOST_NOEXCEPT;
     106             : 
     107             :     template <class T>
     108             :     inline static stl_type_index type_id() BOOST_NOEXCEPT;
     109             : 
     110             :     template <class T>
     111             :     inline static stl_type_index type_id_with_cvr() BOOST_NOEXCEPT;
     112             : 
     113             :     template <class T>
     114             :     inline static stl_type_index type_id_runtime(const T& value) BOOST_NOEXCEPT;
     115             : };
     116             : 
     117          16 : inline const stl_type_index::type_info_t& stl_type_index::type_info() const BOOST_NOEXCEPT {
     118          16 :     return *data_;
     119             : }
     120             : 
     121             : 
     122             : inline const char* stl_type_index::raw_name() const BOOST_NOEXCEPT {
     123             : #ifdef _MSC_VER
     124             :     return data_->raw_name();
     125             : #else
     126             :     return data_->name();
     127             : #endif
     128             : }
     129             : 
     130             : inline const char* stl_type_index::name() const BOOST_NOEXCEPT {
     131             :     return data_->name();
     132             : }
     133             : 
     134             : inline std::string stl_type_index::pretty_name() const {
     135             :     static const char cvr_saver_name[] = "boost::typeindex::detail::cvr_saver<";
     136             :     static BOOST_CONSTEXPR_OR_CONST std::string::size_type cvr_saver_name_len = sizeof(cvr_saver_name) - 1;
     137             : 
     138             :     // In case of MSVC demangle() is a no-op, and name() already returns demangled name.
     139             :     // In case of GCC and Clang (on non-Windows systems) name() returns mangled name and demangle() undecorates it.
     140             :     const boost::core::scoped_demangled_name demangled_name(data_->name());
     141             : 
     142             :     const char* begin = demangled_name.get();
     143             :     if (!begin) {
     144             :         boost::throw_exception(std::runtime_error("Type name demangling failed"));
     145             :     }
     146             : 
     147             :     const std::string::size_type len = std::strlen(begin);
     148             :     const char* end = begin + len;
     149             : 
     150             :     if (len > cvr_saver_name_len) {
     151             :         const char* b = std::strstr(begin, cvr_saver_name);
     152             :         if (b) {
     153             :             b += cvr_saver_name_len;
     154             : 
     155             :             // Trim leading spaces
     156             :             while (*b == ' ') {         // the string is zero terminated, we won't exceed the buffer size
     157             :                 ++ b;
     158             :             }
     159             : 
     160             :             // Skip the closing angle bracket
     161             :             const char* e = end - 1;
     162             :             while (e > b && *e != '>') {
     163             :                 -- e;
     164             :             }
     165             : 
     166             :             // Trim trailing spaces
     167             :             while (e > b && *(e - 1) == ' ') {
     168             :                 -- e;
     169             :             }
     170             : 
     171             :             if (b < e) {
     172             :                 // Parsing seems to have succeeded, the type name is not empty
     173             :                 begin = b;
     174             :                 end = e;
     175             :             }
     176             :         }
     177             :     }
     178             : 
     179             :     return std::string(begin, end);
     180             : }
     181             : 
     182             : 
     183             : inline std::size_t stl_type_index::hash_code() const BOOST_NOEXCEPT {
     184             : #ifdef BOOST_TYPE_INDEX_STD_TYPE_INDEX_HAS_HASH_CODE
     185             :     return data_->hash_code();
     186             : #else
     187             :     return boost::hash_range(raw_name(), raw_name() + std::strlen(raw_name()));
     188             : #endif
     189             : }
     190             : 
     191             : 
     192             : /// @cond
     193             : 
     194             : // for this compiler at least, cross-shared-library type_info
     195             : // comparisons don't work, so we are using typeid(x).name() instead.
     196             : # if (defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5))) \
     197             :     || defined(_AIX) \
     198             :     || (defined(__sgi) && defined(__host_mips)) \
     199             :     || (defined(__hpux) && defined(__HP_aCC)) \
     200             :     || (defined(linux) && defined(__INTEL_COMPILER) && defined(__ICC))
     201             : #  define BOOST_TYPE_INDEX_CLASSINFO_COMPARE_BY_NAMES
     202             : # endif
     203             : 
     204             : /// @endcond
     205             : 
     206             : inline bool stl_type_index::equal(const stl_type_index& rhs) const BOOST_NOEXCEPT {
     207             : #ifdef BOOST_TYPE_INDEX_CLASSINFO_COMPARE_BY_NAMES
     208             :     return raw_name() == rhs.raw_name() || !std::strcmp(raw_name(), rhs.raw_name());
     209             : #else
     210             :     return !!(*data_ == *rhs.data_);
     211             : #endif
     212             : }
     213             : 
     214             : inline bool stl_type_index::before(const stl_type_index& rhs) const BOOST_NOEXCEPT {
     215             : #ifdef BOOST_TYPE_INDEX_CLASSINFO_COMPARE_BY_NAMES
     216             :     return raw_name() != rhs.raw_name() && std::strcmp(raw_name(), rhs.raw_name()) < 0;
     217             : #else
     218             :     return !!data_->before(*rhs.data_);
     219             : #endif
     220             : }
     221             : 
     222             : #undef BOOST_TYPE_INDEX_CLASSINFO_COMPARE_BY_NAMES
     223             : 
     224             : 
     225             : template <class T>
     226          32 : inline stl_type_index stl_type_index::type_id() BOOST_NOEXCEPT {
     227             :     typedef BOOST_DEDUCED_TYPENAME boost::remove_reference<T>::type no_ref_t;
     228             :     typedef BOOST_DEDUCED_TYPENAME boost::remove_cv<no_ref_t>::type no_cvr_prefinal_t;
     229             : 
     230             :     #  if (defined(__EDG_VERSION__) && __EDG_VERSION__ < 245) \
     231             :         || (defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 744)
     232             : 
     233             :         // Old EDG-based compilers seem to mistakenly distinguish 'integral' from 'signed integral'
     234             :         // in typeid() expressions. Full template specialization for 'integral' fixes that issue:
     235             :         typedef BOOST_DEDUCED_TYPENAME boost::conditional<
     236             :             boost::is_signed<no_cvr_prefinal_t>::value,
     237             :             boost::make_signed<no_cvr_prefinal_t>,
     238             :             boost::type_identity<no_cvr_prefinal_t>
     239             :         >::type no_cvr_prefinal_lazy_t;
     240             : 
     241             :         typedef BOOST_DEDUCED_TYPENAME no_cvr_prefinal_t::type no_cvr_t;
     242             :     #else
     243             :         typedef no_cvr_prefinal_t no_cvr_t;
     244             :     #endif
     245             : 
     246          33 :     return typeid(no_cvr_t);
     247             : }
     248             : 
     249             : namespace detail {
     250             :     template <class T> class cvr_saver{};
     251             : }
     252             : 
     253             : template <class T>
     254             : inline stl_type_index stl_type_index::type_id_with_cvr() BOOST_NOEXCEPT {
     255             :     typedef BOOST_DEDUCED_TYPENAME boost::conditional<
     256             :         boost::is_reference<T>::value ||  boost::is_const<T>::value || boost::is_volatile<T>::value,
     257             :         detail::cvr_saver<T>,
     258             :         T
     259             :     >::type type;
     260             : 
     261             :     return typeid(type);
     262             : }
     263             : 
     264             : 
     265             : template <class T>
     266             : inline stl_type_index stl_type_index::type_id_runtime(const T& value) BOOST_NOEXCEPT {
     267             : #ifdef BOOST_NO_RTTI
     268             :     return value.boost_type_index_type_id_runtime_();
     269             : #else
     270             :     return typeid(value);
     271             : #endif
     272             : }
     273             : 
     274             : }} // namespace boost::typeindex
     275             : 
     276             : #undef BOOST_TYPE_INDEX_STD_TYPE_INDEX_HAS_HASH_CODE
     277             : 
     278             : #endif // BOOST_TYPE_INDEX_STL_TYPE_INDEX_HPP

Generated by: LCOV version 1.14