LCOV - code coverage report
Current view: top level - boost/capy/detail - type_id.hpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 100.0 % 2 2
Test Date: 2026-01-30 23:43:15 Functions: 100.0 % 16 16

            Line data    Source code
       1              : //
       2              : // Copyright (c) 2023 Vinnie Falco (vinnie.falco@gmail.com)
       3              : //
       4              : // Distributed under the Boost Software License, Version 1.0. (See accompanying
       5              : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
       6              : //
       7              : // Official repository: https://github.com/cppalliance/capy
       8              : //
       9              : 
      10              : #ifndef BOOST_CAPY_DETAIL_TYPE_ID_HPP
      11              : #define BOOST_CAPY_DETAIL_TYPE_ID_HPP
      12              : 
      13              : #include <boost/capy/detail/config.hpp>
      14              : 
      15              : #if BOOST_CAPY_NO_RTTI
      16              : 
      17              : //------------------------------------------------
      18              : // Custom implementation (no RTTI)
      19              : //------------------------------------------------
      20              : 
      21              : #include <compare>
      22              : #include <cstddef>
      23              : #include <cstdint>
      24              : #include <string_view>
      25              : #include <type_traits>
      26              : 
      27              : namespace boost {
      28              : namespace capy {
      29              : namespace detail {
      30              : 
      31              : template<typename T>
      32              : constexpr std::string_view
      33              : type_name_impl() noexcept
      34              : {
      35              :     constexpr auto strlen_ce = [](char const* s) constexpr noexcept {
      36              :         std::size_t n = 0;
      37              :         while(s[n] != '\0')
      38              :             ++n;
      39              :         return n;
      40              :     };
      41              : 
      42              :     constexpr auto find = [](char const* s, std::size_t len, char c) constexpr noexcept {
      43              :         for(std::size_t i = 0; i < len; ++i)
      44              :             if(s[i] == c)
      45              :                 return i;
      46              :         return len;
      47              :     };
      48              : 
      49              :     constexpr auto rfind = [](char const* s, std::size_t len, char c) constexpr noexcept {
      50              :         for(std::size_t i = len; i > 0; --i)
      51              :             if(s[i - 1] == c)
      52              :                 return i - 1;
      53              :         return len;
      54              :     };
      55              : 
      56              : #if defined(__clang__)
      57              :     constexpr char const* s = __PRETTY_FUNCTION__;
      58              :     constexpr std::size_t len = strlen_ce(s);
      59              :     constexpr std::size_t start = find(s, len, '=') + 2;
      60              :     constexpr std::size_t end = rfind(s, len, ']');
      61              :     return {s + start, end - start};
      62              : 
      63              : #elif defined(__GNUC__)
      64              :     constexpr char const* s = __PRETTY_FUNCTION__;
      65              :     constexpr std::size_t len = strlen_ce(s);
      66              :     constexpr std::size_t start = find(s, len, '=') + 2;
      67              :     constexpr std::size_t end = rfind(s, len, ']');
      68              :     return {s + start, end - start};
      69              : 
      70              : #elif defined(_MSC_VER)
      71              :     constexpr char const* s = __FUNCSIG__;
      72              :     constexpr std::size_t len = strlen_ce(s);
      73              :     constexpr std::size_t start = find(s, len, '<') + 1;
      74              :     constexpr std::size_t end = rfind(s, len, '>');
      75              :     return {s + start, end - start};
      76              : 
      77              : #else
      78              :     return "unknown";
      79              : #endif
      80              : }
      81              : 
      82              : template<typename T>
      83              : inline constexpr std::string_view type_name = type_name_impl<T>();
      84              : 
      85              : class type_info
      86              : {
      87              :     void const* id_;
      88              :     std::string_view name_;
      89              : 
      90              :     constexpr explicit
      91              :     type_info(void const* id, std::string_view name) noexcept
      92              :         : id_(id)
      93              :         , name_(name)
      94              :     {
      95              :     }
      96              : 
      97              :     template<typename T>
      98              :     friend struct type_id_impl;
      99              : 
     100              : public:
     101              :     type_info(type_info const&) = default;
     102              :     type_info& operator=(type_info const&) = default;
     103              : 
     104              :     constexpr std::string_view
     105              :     name() const noexcept
     106              :     {
     107              :         return name_;
     108              :     }
     109              : 
     110              :     constexpr bool
     111              :     operator==(type_info const& rhs) const noexcept
     112              :     {
     113              :         return id_ == rhs.id_;
     114              :     }
     115              : 
     116              :     constexpr bool
     117              :     operator!=(type_info const& rhs) const noexcept
     118              :     {
     119              :         return id_ != rhs.id_;
     120              :     }
     121              : 
     122              :     constexpr bool
     123              :     before(type_info const& rhs) const noexcept
     124              :     {
     125              :         return id_ < rhs.id_;
     126              :     }
     127              : 
     128              :     std::uintptr_t
     129              :     hash_code() const noexcept
     130              :     {
     131              :         return reinterpret_cast<std::uintptr_t>(id_);
     132              :     }
     133              : };
     134              : 
     135              : template<typename T>
     136              : struct type_id_impl
     137              : {
     138              :     inline static constexpr char tag{};
     139              :     inline static constexpr type_info value{&tag, type_name<T>};
     140              : };
     141              : 
     142              : /// Returns type_info for type T (ignores top-level cv-qualifiers)
     143              : template<typename T>
     144              : inline constexpr type_info const&
     145              : type_id() noexcept
     146              : {
     147              :     return type_id_impl<std::remove_cv_t<T>>::value;
     148              : }
     149              : 
     150              : class type_index
     151              : {
     152              :     type_info const* info_;
     153              : 
     154              : public:
     155              :     constexpr
     156              :     type_index(type_info const& info) noexcept
     157              :         : info_(&info)
     158              :     {
     159              :     }
     160              : 
     161              :     constexpr std::string_view
     162              :     name() const noexcept
     163              :     {
     164              :         return info_->name();
     165              :     }
     166              : 
     167              :     std::uintptr_t
     168              :     hash_code() const noexcept
     169              :     {
     170              :         return reinterpret_cast<std::uintptr_t>(info_);
     171              :     }
     172              : 
     173              :     constexpr bool
     174              :     operator==(type_index const& rhs) const noexcept = default;
     175              : 
     176              :     constexpr std::strong_ordering
     177              :     operator<=>(type_index const& rhs) const noexcept = default;
     178              : };
     179              : 
     180              : } // detail
     181              : } // capy
     182              : } // boost
     183              : 
     184              : template<>
     185              : struct std::hash<boost::capy::detail::type_index>
     186              : {
     187              :     std::size_t
     188              :     operator()(boost::capy::detail::type_index const& ti) const noexcept
     189              :     {
     190              :         return ti.hash_code();
     191              :     }
     192              : };
     193              : 
     194              : #else // BOOST_CAPY_NO_RTTI
     195              : 
     196              : //------------------------------------------------
     197              : // Standard RTTI implementation
     198              : //------------------------------------------------
     199              : 
     200              : #include <typeinfo>
     201              : #include <typeindex>
     202              : 
     203              : namespace boost {
     204              : namespace capy {
     205              : namespace detail {
     206              : 
     207              : using type_info = std::type_info;
     208              : using type_index = std::type_index;
     209              : 
     210              : /// Returns type_info for type T
     211              : template<typename T>
     212              : inline type_info const&
     213          222 : type_id() noexcept
     214              : {
     215          222 :     return typeid(T);
     216              : }
     217              : 
     218              : } // detail
     219              : } // capy
     220              : } // boost
     221              : 
     222              : #endif // BOOST_CAPY_NO_RTTI
     223              : 
     224              : #endif
        

Generated by: LCOV version 2.3