EnTT  3.10.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 template<typename Char>
36 struct basic_hashed_string {
37  using value_type = Char;
38  using size_type = std::size_t;
39  using hash_type = id_type;
40 
41  const value_type *repr;
42  size_type length;
43  hash_type hash;
44 };
45 
46 } // namespace internal
47 
68 template<typename Char>
69 class basic_hashed_string: internal::basic_hashed_string<Char> {
70  using base_type = internal::basic_hashed_string<Char>;
71  using hs_traits = internal::fnv1a_traits<id_type>;
72 
73  struct const_wrapper {
74  // non-explicit constructor on purpose
75  constexpr const_wrapper(const Char *str) ENTT_NOEXCEPT: repr{str} {}
76  const Char *repr;
77  };
78 
79  // Fowler–Noll–Vo hash function v. 1a - the good
80  [[nodiscard]] static constexpr auto helper(const Char *str) ENTT_NOEXCEPT {
81  base_type base{str, 0u, hs_traits::offset};
82 
83  for(; str[base.length]; ++base.length) {
84  base.hash = (base.hash ^ static_cast<hs_traits::type>(str[base.length])) * hs_traits::prime;
85  }
86 
87  return base;
88  }
89 
90  // Fowler–Noll–Vo hash function v. 1a - the good
91  [[nodiscard]] static constexpr auto helper(const Char *str, const std::size_t len) ENTT_NOEXCEPT {
92  base_type base{str, len, hs_traits::offset};
93 
94  for(size_type pos{}; pos < len; ++pos) {
95  base.hash = (base.hash ^ static_cast<hs_traits::type>(str[pos])) * hs_traits::prime;
96  }
97 
98  return base;
99  }
100 
101 public:
103  using value_type = typename base_type::value_type;
105  using size_type = typename base_type::size_type;
107  using hash_type = typename base_type::hash_type;
108 
115  [[nodiscard]] static constexpr hash_type value(const value_type *str, const size_type len) ENTT_NOEXCEPT {
116  return basic_hashed_string{str, len};
117  }
118 
125  template<std::size_t N>
126  [[nodiscard]] static constexpr hash_type value(const value_type (&str)[N]) ENTT_NOEXCEPT {
127  return basic_hashed_string{str};
128  }
129 
135  [[nodiscard]] static constexpr hash_type value(const_wrapper wrapper) ENTT_NOEXCEPT {
136  return basic_hashed_string{wrapper};
137  }
138 
140  constexpr basic_hashed_string() ENTT_NOEXCEPT
141  : base_type{} {}
142 
148  constexpr basic_hashed_string(const value_type *str, const size_type len) ENTT_NOEXCEPT
149  : base_type{helper(str, len)} {}
150 
156  template<std::size_t N>
157  constexpr basic_hashed_string(const value_type (&str)[N]) ENTT_NOEXCEPT
158  : base_type{helper(str)} {}
159 
169  explicit constexpr basic_hashed_string(const_wrapper wrapper) ENTT_NOEXCEPT
170  : base_type{helper(wrapper.repr)} {}
171 
176  [[nodiscard]] constexpr size_type size() const ENTT_NOEXCEPT {
177  return base_type::length;
178  }
179 
184  [[nodiscard]] constexpr const value_type *data() const ENTT_NOEXCEPT {
185  return base_type::repr;
186  }
187 
192  [[nodiscard]] constexpr hash_type value() const ENTT_NOEXCEPT {
193  return base_type::hash;
194  }
195 
197  [[nodiscard]] constexpr operator const value_type *() const ENTT_NOEXCEPT {
198  return data();
199  }
200 
205  [[nodiscard]] constexpr operator hash_type() const ENTT_NOEXCEPT {
206  return value();
207  }
208 };
209 
216 template<typename Char>
217 basic_hashed_string(const Char *str, const std::size_t len) -> basic_hashed_string<Char>;
218 
225 template<typename Char, std::size_t N>
227 
235 template<typename Char>
236 [[nodiscard]] constexpr bool operator==(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) ENTT_NOEXCEPT {
237  return lhs.value() == rhs.value();
238 }
239 
247 template<typename Char>
248 [[nodiscard]] constexpr bool operator!=(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) ENTT_NOEXCEPT {
249  return !(lhs == rhs);
250 }
251 
259 template<typename Char>
260 [[nodiscard]] constexpr bool operator<(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) ENTT_NOEXCEPT {
261  return lhs.value() < rhs.value();
262 }
263 
272 template<typename Char>
273 [[nodiscard]] constexpr bool operator<=(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) ENTT_NOEXCEPT {
274  return !(rhs < lhs);
275 }
276 
285 template<typename Char>
286 [[nodiscard]] constexpr bool operator>(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) ENTT_NOEXCEPT {
287  return rhs < lhs;
288 }
289 
298 template<typename Char>
299 [[nodiscard]] constexpr bool operator>=(const basic_hashed_string<Char> &lhs, const basic_hashed_string<Char> &rhs) ENTT_NOEXCEPT {
300  return !(lhs < rhs);
301 }
302 
305 
308 
309 inline namespace literals {
310 
316 [[nodiscard]] constexpr hashed_string operator"" _hs(const char *str, std::size_t) ENTT_NOEXCEPT {
317  return hashed_string{str};
318 }
319 
325 [[nodiscard]] constexpr hashed_wstring operator"" _hws(const wchar_t *str, std::size_t) ENTT_NOEXCEPT {
326  return hashed_wstring{str};
327 }
328 
329 } // namespace literals
330 
331 } // namespace entt
332 
333 #endif
Zero overhead unique identifier.
typename base_type::value_type value_type
Character type.
constexpr const value_type * data() const
Returns the human-readable representation of a hashed string.
static constexpr 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.
typename base_type::size_type size_type
Unsigned integer type.
static constexpr hash_type value(const value_type *str, const size_type len)
Returns directly the numeric representation of a string view.
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 size_type size() const
Returns the size a hashed string.
typename base_type::hash_type hash_type
Unsigned integer type.
constexpr basic_hashed_string(const value_type *str, const size_type len)
Constructs a hashed string from a string view.
constexpr basic_hashed_string()
Constructs an empty hashed string.
constexpr basic_hashed_string(const value_type(&str)[N])
Constructs a hashed string from an array of const characters.
EnTT default namespace.
Definition: dense_map.hpp:22
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:14
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)
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.
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:402
constexpr bool operator>(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs)
Compares two hashed strings.