EnTT  3.9.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 "../config/config.h"
7 #include "fwd.hpp"
8 
9 namespace entt {
10 
16 namespace internal {
17 
18 template<typename>
19 struct fnv1a_traits;
20 
21 template<>
22 struct fnv1a_traits<std::uint32_t> {
23  using type = std::uint32_t;
24  static constexpr std::uint32_t offset = 2166136261;
25  static constexpr std::uint32_t prime = 16777619;
26 };
27 
28 template<>
29 struct fnv1a_traits<std::uint64_t> {
30  using type = std::uint64_t;
31  static constexpr std::uint64_t offset = 14695981039346656037ull;
32  static constexpr std::uint64_t prime = 1099511628211ull;
33 };
34 
35 } // namespace internal
36 
57 template<typename Char>
59  using hs_traits = internal::fnv1a_traits<id_type>;
60 
61  struct const_wrapper {
62  // non-explicit constructor on purpose
63  constexpr const_wrapper(const Char *curr) ENTT_NOEXCEPT: str{curr} {}
64  const Char *str;
65  };
66 
67  // Fowler–Noll–Vo hash function v. 1a - the good
68  [[nodiscard]] static constexpr id_type helper(const Char *curr) ENTT_NOEXCEPT {
69  auto value = hs_traits::offset;
70 
71  while(*curr != 0) {
72  value = (value ^ static_cast<hs_traits::type>(*(curr++))) * hs_traits::prime;
73  }
74 
75  return value;
76  }
77 
78 public:
80  using value_type = Char;
82  using hash_type = id_type;
83 
90  [[nodiscard]] static constexpr hash_type value(const value_type *str, std::size_t size) ENTT_NOEXCEPT {
91  id_type partial{hs_traits::offset};
92  while(size--) { partial = (partial ^ (str++)[0]) * hs_traits::prime; }
93  return partial;
94  }
95 
111  template<std::size_t N>
112  [[nodiscard]] static constexpr hash_type value(const value_type (&str)[N]) ENTT_NOEXCEPT {
113  return helper(str);
114  }
115 
121  [[nodiscard]] static hash_type value(const_wrapper wrapper) ENTT_NOEXCEPT {
122  return helper(wrapper.str);
123  }
124 
126  constexpr basic_hashed_string() ENTT_NOEXCEPT
127  : str{nullptr},
128  hash{} {}
129 
144  template<std::size_t N>
145  constexpr basic_hashed_string(const value_type (&curr)[N]) ENTT_NOEXCEPT
146  : str{curr},
147  hash{helper(curr)} {}
148 
158  explicit constexpr basic_hashed_string(const_wrapper wrapper) ENTT_NOEXCEPT
159  : str{wrapper.str},
160  hash{helper(wrapper.str)} {}
161 
166  [[nodiscard]] constexpr const value_type *data() const ENTT_NOEXCEPT {
167  return str;
168  }
169 
174  [[nodiscard]] constexpr hash_type value() const ENTT_NOEXCEPT {
175  return hash;
176  }
177 
179  [[nodiscard]] constexpr operator const value_type *() const ENTT_NOEXCEPT {
180  return data();
181  }
182 
187  [[nodiscard]] constexpr operator hash_type() const ENTT_NOEXCEPT {
188  return value();
189  }
190 
191 private:
192  const value_type *str;
193  hash_type hash;
194 };
195 
206 template<typename Char, std::size_t N>
208 
216 template<typename Char>
217 [[nodiscard]] constexpr bool operator==(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) ENTT_NOEXCEPT {
218  return lhs.value() == rhs.value();
219 }
220 
228 template<typename Char>
229 [[nodiscard]] constexpr bool operator!=(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) ENTT_NOEXCEPT {
230  return !(lhs == rhs);
231 }
232 
240 template<typename Char>
241 [[nodiscard]] constexpr bool operator<(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) ENTT_NOEXCEPT {
242  return lhs.value() < rhs.value();
243 }
244 
253 template<typename Char>
254 [[nodiscard]] constexpr bool operator<=(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) ENTT_NOEXCEPT {
255  return !(rhs < lhs);
256 }
257 
266 template<typename Char>
267 [[nodiscard]] constexpr bool operator>(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) ENTT_NOEXCEPT {
268  return rhs < lhs;
269 }
270 
279 template<typename Char>
280 [[nodiscard]] constexpr bool operator>=(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) ENTT_NOEXCEPT {
281  return !(lhs < rhs);
282 }
283 
286 
289 
290 inline namespace literals {
291 
297 [[nodiscard]] constexpr entt::hashed_string operator"" _hs(const char *str, std::size_t) ENTT_NOEXCEPT {
298  return entt::hashed_string{str};
299 }
300 
306 [[nodiscard]] constexpr entt::hashed_wstring operator"" _hws(const wchar_t *str, std::size_t) ENTT_NOEXCEPT {
307  return entt::hashed_wstring{str};
308 }
309 
310 } // namespace literals
311 
312 } // namespace entt
313 
314 #endif
Zero overhead unique identifier.
constexpr basic_hashed_string(const value_type(&curr)[N])
Constructs a hashed string from an array of const characters.
id_type hash_type
Unsigned integer type.
constexpr const value_type * data() const
Returns the human-readable representation of a hashed string.
static hash_type value(const_wrapper wrapper)
Returns directly the numeric representation of a string.
constexpr hash_type value() const
Returns the numeric representation of a hashed string.
constexpr basic_hashed_string(const_wrapper wrapper)
Explicit constructor on purpose to avoid constructing a hashed string directly from a const value_typ...
static constexpr hash_type value(const value_type(&str)[N])
Returns directly the numeric representation of a string.
constexpr basic_hashed_string()
Constructs an empty hashed string.
static constexpr hash_type value(const value_type *str, std::size_t size)
Returns directly the numeric representation of a string view.
Char value_type
Character type.
EnTT default namespace.
constexpr bool operator==(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs)
Compares two hashed strings.
std::uint32_t id_type
Alias declaration for type identifiers.
Definition: fwd.hpp:13
constexpr bool operator<=(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs)
Compares two hashed strings.
constexpr bool operator>=(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs)
Compares two hashed strings.
constexpr bool operator<(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs)
Compares two hashed strings.
basic_hashed_string(const Char(&str)[N]) -> basic_hashed_string< Char >
Deduction guide.
bool operator!=(const basic_any< Len, Align > &lhs, const basic_any< Len, Align > &rhs)
Checks if two wrappers differ in their content.
Definition: any.hpp:406
constexpr bool operator>(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs)
Compares two hashed strings.