Line data Source code
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/container_hash/hash.hpp>
15 : #include <boost/core/typeinfo.hpp>
16 : #include <boost/config.hpp>
17 :
18 : namespace boost {
19 : namespace http_proto {
20 : namespace detail {
21 :
22 : struct type_index_impl {
23 : private:
24 : boost::core::typeinfo const *pdata_ = nullptr;
25 :
26 1109 : std::size_t get_raw_name_length() const noexcept {
27 : // Boost.TypeIndex has a dramatically more sophisticated implementation here
28 : // see if this eventually turns out to matter and if it does, essentially
29 : // just do more copy-paste
30 1109 : return std::strlen(raw_name());
31 : }
32 :
33 1045 : bool equal(type_index_impl const &rhs) const noexcept {
34 1045 : return raw_name() == rhs.raw_name() ||
35 1045 : !std::strcmp(raw_name(), rhs.raw_name());
36 : }
37 :
38 : public:
39 1077 : type_index_impl(boost::core::typeinfo const &type_info) noexcept
40 1077 : : pdata_(&type_info) {}
41 :
42 : type_index_impl(type_index_impl const &) = default;
43 : type_index_impl &operator=(type_index_impl const &) = default;
44 :
45 : ~type_index_impl() = default;
46 :
47 1077 : template <class T> static type_index_impl type_id() noexcept {
48 1077 : return type_index_impl(BOOST_CORE_TYPEID(T));
49 : }
50 :
51 5417 : char const *raw_name() const noexcept { return pdata_->name(); }
52 :
53 1109 : std::size_t hash_code() const noexcept {
54 1109 : return boost::hash_range(raw_name(), raw_name() + get_raw_name_length());
55 : }
56 :
57 1045 : bool operator==(type_index_impl const &rhs) const noexcept {
58 1045 : return equal(rhs);
59 : }
60 :
61 : bool operator!=(type_index_impl const &rhs) const noexcept {
62 : return !equal(rhs);
63 : }
64 : };
65 :
66 : // like std::type_index,
67 : // but without requiring RTTI
68 : using type_index = type_index_impl;
69 :
70 1077 : template <class T> type_index get_type_index() noexcept {
71 1077 : return type_index_impl::type_id<T>();
72 : }
73 :
74 : struct type_index_hasher {
75 1109 : std::size_t operator()(type_index const &tid) const noexcept {
76 1109 : return tid.hash_code();
77 : }
78 : };
79 :
80 1045 : template <class U, class T> U downcast(T *p) {
81 : #ifdef BOOST_NO_RTTI
82 : return static_cast<U>(p);
83 : #else
84 1045 : return dynamic_cast<U>(p);
85 : #endif
86 : }
87 :
88 32 : template <class U, class T> U downcast(T &p) {
89 : #ifdef BOOST_NO_RTTI
90 : return static_cast<U>(p);
91 : #else
92 32 : return dynamic_cast<U>(p);
93 : #endif
94 : }
95 :
96 : } // namespace detail
97 : } // namespace http_proto
98 : } // namespace boost
99 :
100 : #endif
|