LCOV - code coverage report
Current view: top level - capy/detail - type_id.hpp (source / functions) Coverage Total Hit
Test: coverage_remapped.info Lines: 100.0 % 2 2
Test Date: 2026-02-17 18:14:47 Functions: 100.0 % 19 19

           TLA  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 constexpr type_info const&
     213 HIT         252 : type_id() noexcept
     214                 : {
     215             252 :     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