EnTT 3.13.0
Loading...
Searching...
No Matches
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
11namespace internal {
12
13template<typename>
14struct fnv1a_traits;
15
16template<>
17struct fnv1a_traits<std::uint32_t> {
18 using type = std::uint32_t;
19 static constexpr std::uint32_t offset = 2166136261;
20 static constexpr std::uint32_t prime = 16777619;
21};
22
23template<>
24struct fnv1a_traits<std::uint64_t> {
25 using type = std::uint64_t;
26 static constexpr std::uint64_t offset = 14695981039346656037ull;
27 static constexpr std::uint64_t prime = 1099511628211ull;
28};
29
30template<typename Char>
32 using value_type = Char;
33 using size_type = std::size_t;
34 using hash_type = id_type;
35
36 const value_type *repr;
37 size_type length;
38 hash_type hash;
39};
40
41} // namespace internal
59template<typename Char>
60class basic_hashed_string: internal::basic_hashed_string<Char> {
61 using base_type = internal::basic_hashed_string<Char>;
62 using traits_type = internal::fnv1a_traits<id_type>;
63
64 struct const_wrapper {
65 // non-explicit constructor on purpose
66 constexpr const_wrapper(const Char *str) noexcept
67 : repr{str} {}
68
69 const Char *repr;
70 };
71
72 // Fowler–Noll–Vo hash function v. 1a - the good
73 [[nodiscard]] static constexpr auto helper(const Char *str) noexcept {
74 base_type base{str, 0u, traits_type::offset};
75
76 for(; str[base.length]; ++base.length) {
77 base.hash = (base.hash ^ static_cast<traits_type::type>(str[base.length])) * traits_type::prime;
78 }
79
80 return base;
81 }
82
83 // Fowler–Noll–Vo hash function v. 1a - the good
84 [[nodiscard]] static constexpr auto helper(const Char *str, const std::size_t len) noexcept {
85 base_type base{str, len, traits_type::offset};
86
87 for(size_type pos{}; pos < len; ++pos) {
88 base.hash = (base.hash ^ static_cast<traits_type::type>(str[pos])) * traits_type::prime;
89 }
90
91 return base;
92 }
93
94public:
96 using value_type = typename base_type::value_type;
98 using size_type = typename base_type::size_type;
100 using hash_type = typename base_type::hash_type;
101
108 [[nodiscard]] static constexpr hash_type value(const value_type *str, const size_type len) noexcept {
109 return basic_hashed_string{str, len};
110 }
111
118 template<std::size_t N>
119 [[nodiscard]] static constexpr hash_type value(const value_type (&str)[N]) noexcept {
120 return basic_hashed_string{str};
121 }
122
128 [[nodiscard]] static constexpr hash_type value(const_wrapper wrapper) noexcept {
129 return basic_hashed_string{wrapper};
130 }
131
133 constexpr basic_hashed_string() noexcept
134 : base_type{} {}
135
141 constexpr basic_hashed_string(const value_type *str, const size_type len) noexcept
142 : base_type{helper(str, len)} {}
143
149 template<std::size_t N>
150 constexpr basic_hashed_string(const value_type (&str)[N]) noexcept
151 : base_type{helper(str)} {}
152
162 explicit constexpr basic_hashed_string(const_wrapper wrapper) noexcept
163 : base_type{helper(wrapper.repr)} {}
164
169 [[nodiscard]] constexpr size_type size() const noexcept {
170 return base_type::length; // NOLINT
171 }
172
177 [[nodiscard]] constexpr const value_type *data() const noexcept {
178 return base_type::repr;
179 }
180
185 [[nodiscard]] constexpr hash_type value() const noexcept {
186 return base_type::hash;
187 }
188
190 [[nodiscard]] constexpr operator const value_type *() const noexcept {
191 return data();
192 }
193
198 [[nodiscard]] constexpr operator hash_type() const noexcept {
199 return value();
200 }
201};
202
209template<typename Char>
210basic_hashed_string(const Char *str, const std::size_t len) -> basic_hashed_string<Char>;
211
218template<typename Char, std::size_t N>
220
228template<typename Char>
229[[nodiscard]] constexpr bool operator==(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) noexcept {
230 return lhs.value() == rhs.value();
231}
232
240template<typename Char>
241[[nodiscard]] constexpr bool operator!=(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) noexcept {
242 return !(lhs == rhs);
243}
244
252template<typename Char>
253[[nodiscard]] constexpr bool operator<(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) noexcept {
254 return lhs.value() < rhs.value();
255}
256
265template<typename Char>
266[[nodiscard]] constexpr bool operator<=(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) noexcept {
267 return !(rhs < lhs);
268}
269
278template<typename Char>
279[[nodiscard]] constexpr bool operator>(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) noexcept {
280 return rhs < lhs;
281}
282
291template<typename Char>
292[[nodiscard]] constexpr bool operator>=(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) noexcept {
293 return !(lhs < rhs);
294}
295
298
301
302inline namespace literals {
303
309[[nodiscard]] constexpr hashed_string operator"" _hs(const char *str, std::size_t) noexcept {
310 return hashed_string{str};
311}
312
318[[nodiscard]] constexpr hashed_wstring operator"" _hws(const wchar_t *str, std::size_t) noexcept {
319 return hashed_wstring{str};
320}
321
322} // namespace literals
323
324} // namespace entt
325
326#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.