summaryrefslogtreecommitdiff
path: root/asl/hash.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'asl/hash.hpp')
-rw-r--r--asl/hash.hpp276
1 files changed, 138 insertions, 138 deletions
diff --git a/asl/hash.hpp b/asl/hash.hpp
index 2e48a02..9539755 100644
--- a/asl/hash.hpp
+++ b/asl/hash.hpp
@@ -1,138 +1,138 @@
-#pragma once
-
-#include "asl/integers.hpp"
-#include "asl/meta.hpp"
-#include "asl/span.hpp"
-#include "asl/utility.hpp"
-
-namespace asl::city_hash
-{
-
-// Hash function for a byte array.
-uint64_t CityHash64(const char *s, size_t len);
-
-// Hash function for a byte array. For convenience, a 64-bit seed is also
-// hashed into the result.
-uint64_t CityHash64WithSeed(const char *s, size_t len, uint64_t seed);
-
-// Hash function for a byte array. For convenience, two seeds are also
-// hashed into the result.
-uint64_t CityHash64WithSeeds(const char *s, size_t len,
- uint64_t seed0, uint64_t seed1);
-
-// Hash function for a byte array.
-uint128_t CityHash128(const char *s, size_t len);
-
-// Hash function for a byte array. For convenience, a 128-bit seed is also
-// hashed into the result.
-uint128_t CityHash128WithSeed(const char *s, size_t len, uint128_t seed);
-
-// Hash function for a byte array. Most useful in 32-bit binaries.
-uint32_t CityHash32(const char *s, size_t len);
-
-// Hash 128 input bits down to 64 bits of output.
-// This is intended to be a reasonably good hash function.
-constexpr uint64_t Hash128to64(uint64_t high, uint64_t low)
-{
- // Murmur-inspired hashing.
- const uint64_t kMul = 0x9ddfea08eb382d69ULL;
- uint64_t a = (low ^ high) * kMul;
- a ^= (a >> 47);
- uint64_t b = (high ^ a) * kMul;
- b ^= (b >> 47);
- b *= kMul;
- return b;
-}
-
-// Hash 128 input bits down to 64 bits of output.
-// This is intended to be a reasonably good hash function.
-constexpr uint64_t Hash128to64(const uint128_t& x)
-{
- return Hash128to64(x.high, x.low);
-}
-
-} // namespace asl::city_hash
-
-namespace asl
-{
-
-template<typename T, typename H>
-concept hashable_generic = requires(const T& value, H h)
-{
- { AslHashValue(h, value) } -> same_as<H>;
-};
-
-struct HashState
-{
- uint128_t state{};
-
- constexpr HashState() = default;
- explicit constexpr HashState(uint128_t s) : state{s} {}
-
- template<typename T>
- static HashState combine_contiguous(HashState h, span<const T> s)
- {
- if constexpr (uniquely_represented<T>)
- {
- auto bytes = as_bytes(s);
- auto hashed = city_hash::CityHash128WithSeed(
- reinterpret_cast<const char*>(bytes.data()),
- static_cast<size_t>(bytes.size()),
- h.state);
- return HashState{hashed};
- }
- else
- {
- for (const auto& value: s)
- {
- h = AslHashValue(ASL_MOVE(h), value);
- }
- return h;
- }
- }
-
- static constexpr HashState combine(HashState h)
- {
- return h;
- }
-
- template<hashable_generic<HashState> Arg, hashable_generic<HashState>... Remaining>
- static constexpr HashState combine(HashState h, const Arg& arg, const Remaining&... remaining)
- {
- return combine(AslHashValue(ASL_MOVE(h), arg), remaining...);
- }
-};
-
-template<typename T>
-concept hashable = hashable_generic<T, HashState>;
-
-template<typename H, uniquely_represented T>
-constexpr H AslHashValue(H h, const T& value)
-{
- return H::combine_contiguous(ASL_MOVE(h), span<const T>{&value, 1});
-}
-
-template<typename H>
-constexpr H AslHashValue(H h, bool value)
-{
- return AslHashValue(ASL_MOVE(h), value ? 1 : 0);
-}
-
-template<typename H, typename T>
-constexpr void AslHashValue(H h, T*); // Don't hash pointers
-
-template<typename H, hashable T>
-constexpr H AslHashValue(H h, const span<T>& s)
-{
- return H::combine_contiguous(ASL_MOVE(h), span<const T>{s.data(), s.size()});
-}
-
-template<hashable T>
-constexpr uint64_t hash_value(const T& value)
-{
- auto result = AslHashValue(HashState{}, value).state;
- return city_hash::Hash128to64(result);
-}
-
-} // namespace asl
-
+#pragma once
+
+#include "asl/integers.hpp"
+#include "asl/meta.hpp"
+#include "asl/span.hpp"
+#include "asl/utility.hpp"
+
+namespace asl::city_hash
+{
+
+// Hash function for a byte array.
+uint64_t CityHash64(const char *s, size_t len);
+
+// Hash function for a byte array. For convenience, a 64-bit seed is also
+// hashed into the result.
+uint64_t CityHash64WithSeed(const char *s, size_t len, uint64_t seed);
+
+// Hash function for a byte array. For convenience, two seeds are also
+// hashed into the result.
+uint64_t CityHash64WithSeeds(const char *s, size_t len,
+ uint64_t seed0, uint64_t seed1);
+
+// Hash function for a byte array.
+uint128_t CityHash128(const char *s, size_t len);
+
+// Hash function for a byte array. For convenience, a 128-bit seed is also
+// hashed into the result.
+uint128_t CityHash128WithSeed(const char *s, size_t len, uint128_t seed);
+
+// Hash function for a byte array. Most useful in 32-bit binaries.
+uint32_t CityHash32(const char *s, size_t len);
+
+// Hash 128 input bits down to 64 bits of output.
+// This is intended to be a reasonably good hash function.
+constexpr uint64_t Hash128to64(uint64_t high, uint64_t low)
+{
+ // Murmur-inspired hashing.
+ const uint64_t kMul = 0x9ddfea08eb382d69ULL;
+ uint64_t a = (low ^ high) * kMul;
+ a ^= (a >> 47);
+ uint64_t b = (high ^ a) * kMul;
+ b ^= (b >> 47);
+ b *= kMul;
+ return b;
+}
+
+// Hash 128 input bits down to 64 bits of output.
+// This is intended to be a reasonably good hash function.
+constexpr uint64_t Hash128to64(const uint128_t& x)
+{
+ return Hash128to64(x.high, x.low);
+}
+
+} // namespace asl::city_hash
+
+namespace asl
+{
+
+template<typename T, typename H>
+concept hashable_generic = requires(const T& value, H h)
+{
+ { AslHashValue(h, value) } -> same_as<H>;
+};
+
+struct HashState
+{
+ uint128_t state{};
+
+ constexpr HashState() = default;
+ explicit constexpr HashState(uint128_t s) : state{s} {}
+
+ template<typename T>
+ static HashState combine_contiguous(HashState h, span<const T> s)
+ {
+ if constexpr (uniquely_represented<T>)
+ {
+ auto bytes = as_bytes(s);
+ auto hashed = city_hash::CityHash128WithSeed(
+ reinterpret_cast<const char*>(bytes.data()),
+ static_cast<size_t>(bytes.size()),
+ h.state);
+ return HashState{hashed};
+ }
+ else
+ {
+ for (const auto& value: s)
+ {
+ h = AslHashValue(ASL_MOVE(h), value);
+ }
+ return h;
+ }
+ }
+
+ static constexpr HashState combine(HashState h)
+ {
+ return h;
+ }
+
+ template<hashable_generic<HashState> Arg, hashable_generic<HashState>... Remaining>
+ static constexpr HashState combine(HashState h, const Arg& arg, const Remaining&... remaining)
+ {
+ return combine(AslHashValue(ASL_MOVE(h), arg), remaining...);
+ }
+};
+
+template<typename T>
+concept hashable = hashable_generic<T, HashState>;
+
+template<typename H, uniquely_represented T>
+constexpr H AslHashValue(H h, const T& value)
+{
+ return H::combine_contiguous(ASL_MOVE(h), span<const T>{&value, 1});
+}
+
+template<typename H>
+constexpr H AslHashValue(H h, bool value)
+{
+ return AslHashValue(ASL_MOVE(h), value ? 1 : 0);
+}
+
+template<typename H, typename T>
+constexpr void AslHashValue(H h, T*); // Don't hash pointers
+
+template<typename H, hashable T>
+constexpr H AslHashValue(H h, const span<T>& s)
+{
+ return H::combine_contiguous(ASL_MOVE(h), span<const T>{s.data(), s.size()});
+}
+
+template<hashable T>
+constexpr uint64_t hash_value(const T& value)
+{
+ auto result = AslHashValue(HashState{}, value).state;
+ return city_hash::Hash128to64(result);
+}
+
+} // namespace asl
+