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 856 : 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 856 : return std::strlen(raw_name()); 31 : } 32 : 33 792 : bool equal(type_index_impl const &rhs) const noexcept { 34 792 : return raw_name() == rhs.raw_name() || 35 792 : !std::strcmp(raw_name(), rhs.raw_name()); 36 : } 37 : 38 : public: 39 824 : type_index_impl(boost::core::typeinfo const &type_info) noexcept 40 824 : : 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 824 : template <class T> static type_index_impl type_id() noexcept { 48 824 : return type_index_impl(BOOST_CORE_TYPEID(T)); 49 : } 50 : 51 4152 : char const *raw_name() const noexcept { return pdata_->name(); } 52 : 53 856 : std::size_t hash_code() const noexcept { 54 856 : return boost::hash_range(raw_name(), raw_name() + get_raw_name_length()); 55 : } 56 : 57 792 : bool operator==(type_index_impl const &rhs) const noexcept { 58 792 : 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 824 : template <class T> type_index get_type_index() noexcept { 71 824 : return type_index_impl::type_id<T>(); 72 : } 73 : 74 : struct type_index_hasher { 75 856 : std::size_t operator()(type_index const &tid) const noexcept { 76 856 : return tid.hash_code(); 77 : } 78 : }; 79 : 80 792 : template <class U, class T> U downcast(T *p) { 81 : #ifdef BOOST_NO_RTTI 82 : return static_cast<U>(p); 83 : #else 84 792 : 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