EnTT 3.11.0
hashed_string.hpp
1#ifndef ENTT_CORE_HASHED_STRING_HPP
2#define ENTT_CORE_HASHED_STRING_HPP
3
4#include <cstddef>
5#include <cstdint>
6#include "fwd.hpp"
7
8namespace entt {
9
15namespace internal {
16
17template<typename>
18struct fnv1a_traits;
19
20template<>
21struct fnv1a_traits<std::uint32_t> {
22 using type = std::uint32_t;
23 static constexpr std::uint32_t offset = 2166136261;
24 static constexpr std::uint32_t prime = 16777619;
25};
26
27template<>
28struct fnv1a_traits<std::uint64_t> {
29 using type = std::uint64_t;
30 static constexpr std::uint64_t offset = 14695981039346656037ull;
31 static constexpr std::uint64_t prime = 1099511628211ull;
32};
33
34template<typename Char>
36 using value_type = Char;
37 using size_type = std::size_t;
38 using hash_type = id_type;
39
40 const value_type *repr;
41 size_type length;
42 hash_type hash;
43};
44
45} // namespace internal
46
67template<typename Char>
68class basic_hashed_string: internal::basic_hashed_string<Char> {
69 using base_type = internal::basic_hashed_string<Char>;
70 using hs_traits = internal::fnv1a_traits<id_type>;
71
72 struct const_wrapper {
73 // non-explicit constructor on purpose
74 constexpr const_wrapper(const Char *str) noexcept
75 : repr{str} {}
76
77 const Char *repr;
78 };
79
80 // Fowler–Noll–Vo hash function v. 1a - the good
81 [[nodiscard]] static constexpr auto helper(const Char *str) noexcept {
82 base_type base{str, 0u, hs_traits::offset};
83
84 for(; str[base.length]; ++base.length) {
85 base.hash = (base.hash ^ static_cast<hs_traits::type>(str[base.length])) * hs_traits::prime;
86 }
87
88 return base;
89 }
90
91 // Fowler–Noll–Vo hash function v. 1a - the good
92 [[nodiscard]] static constexpr auto helper(const Char *str, const std::size_t len) noexcept {
93 base_type base{str, len, hs_traits::offset};
94
95 for(size_type pos{}; pos < len; ++pos) {
96 base.hash = (base.hash ^ static_cast<hs_traits::type>(str[pos])) * hs_traits::prime;
97 }
98
99 return base;
100 }
101
102public:
104 using value_type = typename base_type::value_type;
106 using size_type = typename base_type::size_type;
108 using hash_type = typename base_type::hash_type;
109
116 [[nodiscard]] static constexpr hash_type value(const value_type *str, const size_type len) noexcept {
117 return basic_hashed_string{str, len};
118 }
119
126 template<std::size_t N>
127 [[nodiscard]] static constexpr hash_type value(const value_type (&str)[N]) noexcept {
128 return basic_hashed_string{str};
129 }
130
136 [[nodiscard]] static constexpr hash_type value(const_wrapper wrapper) noexcept {
137 return basic_hashed_string{wrapper};
138 }
139
141 constexpr basic_hashed_string() noexcept
142 : base_type{} {}
143
149 constexpr basic_hashed_string(const value_type *str, const size_type len) noexcept
150 : base_type{helper(str, len)} {}
151
157 template<std::size_t N>
158 constexpr basic_hashed_string(const value_type (&str)[N]) noexcept
159 : base_type{helper(str)} {}
160
170 explicit constexpr basic_hashed_string(const_wrapper wrapper) noexcept
171 : base_type{helper(wrapper.repr)} {}
172
177 [[nodiscard]] constexpr size_type size() const noexcept {
178 return base_type::length;
179 }
180
185 [[nodiscard]] constexpr const value_type *data() const noexcept {
186 return base_type::repr;
187 }
188
193 [[nodiscard]] constexpr hash_type value() const noexcept {
194 return base_type::hash;
195 }
196
198 [[nodiscard]] constexpr operator const value_type *() const noexcept {
199 return data();
200 }
201
206 [[nodiscard]] constexpr operator hash_type() const noexcept {
207 return value();
208 }
209};
210
217template<typename Char>
218basic_hashed_string(const Char *str, const std::size_t len) -> basic_hashed_string<Char>;
219
226template<typename Char, std::size_t N>
228
236template<typename Char>
237[[nodiscard]] constexpr bool operator==(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) noexcept {
238 return lhs.value() == rhs.value();
239}
240
248template<typename Char>
249[[nodiscard]] constexpr bool operator!=(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) noexcept {
250 return !(lhs == rhs);
251}
252
260template<typename Char>
261[[nodiscard]] constexpr bool operator<(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) noexcept {
262 return lhs.value() < rhs.value();
263}
264
273template<typename Char>
274[[nodiscard]] constexpr bool operator<=(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) noexcept {
275 return !(rhs < lhs);
276}
277
286template<typename Char>
287[[nodiscard]] constexpr bool operator>(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) noexcept {
288 return rhs < lhs;
289}
290
299template<typename Char>
300[[nodiscard]] constexpr bool operator>=(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) noexcept {
301 return !(lhs < rhs);
302}
303
306
309
310inline namespace literals {
311
317[[nodiscard]] constexpr hashed_string operator"" _hs(const char *str, std::size_t) noexcept {
318 return hashed_string{str};
319}
320
326[[nodiscard]] constexpr hashed_wstring operator"" _hws(const wchar_t *str, std::size_t) noexcept {
327 return hashed_wstring{str};
328}
329
330} // namespace literals
331
332} // namespace entt
333
334#endif
Zero overhead unique identifier.
typename base_type::value_type value_type
Character type.
constexpr const value_type * data() const noexcept
Returns the human-readable representation of a hashed string.
constexpr hash_type value() const noexcept
Returns the numeric representation of a hashed string.
typename base_type::size_type size_type
Unsigned integer type.
static constexpr hash_type value(const value_type(&str)[N]) noexcept
Returns directly the numeric representation of a string.
static constexpr hash_type value(const_wrapper wrapper) noexcept
Returns directly the numeric representation of a string.
typename base_type::hash_type hash_type
Unsigned integer type.
constexpr basic_hashed_string(const value_type *str, const size_type len) noexcept
Constructs a hashed string from a string view.
constexpr basic_hashed_string(const value_type(&str)[N]) noexcept
Constructs a hashed string from an array of const characters.
constexpr size_type size() const noexcept
Returns the size a hashed string.
constexpr basic_hashed_string() noexcept
Constructs an empty hashed string.
static constexpr hash_type value(const value_type *str, const size_type len) noexcept
Returns directly the numeric representation of a string view.
constexpr basic_hashed_string(const_wrapper wrapper) noexcept
Explicit constructor on purpose to avoid constructing a hashed string directly from a const value_typ...
EnTT default namespace.
Definition: dense_map.hpp:21
std::uint32_t id_type
Alias declaration for type identifiers.
Definition: fwd.hpp:13
basic_hashed_string(const Char *str, const std::size_t len) -> basic_hashed_string< Char >
Deduction guide.
constexpr bool operator<=(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs) noexcept
Compares two hashed strings.
constexpr bool operator<(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs) noexcept
Compares two hashed strings.
constexpr bool operator!=(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs) noexcept
Compares two hashed strings.
constexpr bool operator>=(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs) noexcept
Compares two hashed strings.
constexpr bool operator>(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs) noexcept
Compares two hashed strings.
constexpr bool operator==(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs) noexcept
Compares two hashed strings.