GCC Code Coverage Report


Directory: libs/http_proto/
File: boost/http_proto/detail/type_index.hpp
Date: 2024-07-18 19:38:55
Exec Total Coverage
Lines: 26 29 89.7%
Functions: 19 20 95.0%
Branches: 4 10 40.0%

Line Branch Exec Source
1 //
2 // Copyright (c) 2023 Christian Mazakas
3 // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
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 // Official repository: https://github.com/cppalliance/http_proto
9 //
10
11 #ifndef BOOST_HTTP_PROTO_DETAIL_TYPE_INDEX_HPP
12 #define BOOST_HTTP_PROTO_DETAIL_TYPE_INDEX_HPP
13
14 #include <boost/config.hpp>
15 #include <boost/assert/source_location.hpp>
16 #include <boost/container_hash/hash.hpp>
17 #include <boost/core/typeinfo.hpp>
18 #include <boost/throw_exception.hpp>
19
20 namespace boost {
21 namespace http_proto {
22 namespace detail {
23
24 struct type_index_impl
25 {
26 private:
27 boost::core::typeinfo const *pdata_ = nullptr;
28
29 std::size_t
30 1216 get_raw_name_length() const noexcept
31 {
32 // Boost.TypeIndex has a dramatically more sophisticated implementation here
33 // see if this eventually turns out to matter and if it does, essentially
34 // just do more copy-paste
35 1216 return std::strlen(raw_name());
36 }
37
38 bool
39 1095 equal(type_index_impl const &rhs) const noexcept
40 {
41
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 1095 times.
1095 return raw_name() == rhs.raw_name() ||
42
0/2
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1095 !std::strcmp(raw_name(), rhs.raw_name());
43 }
44
45 public:
46 1155 type_index_impl(
47 boost::core::typeinfo const &type_info) noexcept
48 1155 : pdata_(&type_info) {}
49
50 type_index_impl(type_index_impl const &) = default;
51 type_index_impl& operator=(
52 type_index_impl const &) = default;
53
54 ~type_index_impl() = default;
55
56 template <class T>
57 static
58 type_index_impl
59 2233 type_id() noexcept
60 {
61 2233 return type_index_impl(BOOST_CORE_TYPEID(T));
62 }
63
64 char const*
65 5838 raw_name() const noexcept
66 {
67 5838 return pdata_->name();
68 }
69
70 std::size_t
71 1216 hash_code() const noexcept
72 {
73 1216 return boost::hash_range(
74 2432 raw_name(), raw_name() + get_raw_name_length());
75 }
76
77 bool
78 1095 operator==(type_index_impl const &rhs) const noexcept
79 {
80 1095 return equal(rhs);
81 }
82
83 bool
84 operator!=(type_index_impl const &rhs) const noexcept
85 {
86 return !equal(rhs);
87 }
88 };
89
90 // like std::type_index,
91 // but without requiring RTTI
92 using type_index = type_index_impl;
93
94 template <class T>
95 type_index
96 2233 get_type_index() noexcept
97 {
98 2233 return type_index_impl::type_id<T>();
99 }
100
101 struct type_index_hasher
102 {
103 std::size_t
104 1216 operator()(type_index const &tid) const noexcept
105 {
106 1216 return tid.hash_code();
107 }
108 };
109
110 BOOST_NOINLINE BOOST_NORETURN
111 inline
112 void
113 throw_bad_cast(boost::source_location const& loc = {})
114 {
115 boost::throw_exception(std::bad_cast(), loc);
116 }
117
118 template <class U, class T>
119 U
120 2140 downcast(T *p)
121 {
122 #ifdef BOOST_NO_RTTI
123 return static_cast<U>(p);
124 #else
125
1/2
✓ Branch 0 taken 1095 times.
✗ Branch 1 not taken.
2140 auto q = dynamic_cast<U>(p);
126
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1095 times.
2140 if(! q )
127 throw_bad_cast();
128 2140 return q;
129 #endif
130 }
131
132 template <class U, class T>
133 U
134 60 downcast(T &p)
135 {
136 #ifdef BOOST_NO_RTTI
137 return static_cast<U>(p);
138 #else
139
1/2
✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
60 return dynamic_cast<U>(p);
140 #endif
141 }
142
143 } // namespace detail
144 } // namespace http_proto
145 } // namespace boost
146
147 #endif
148