From 48f7e22d9cc93989173afe2550fcc2f082c61773 Mon Sep 17 00:00:00 2001 From: Steven Le Rouzic Date: Mon, 6 Jan 2025 00:33:50 +0100 Subject: Start work on hashing --- asl/hash.hpp | 45 +++++++++++++++++++++++++++++++++++++++++++-- asl/meta.hpp | 7 +++++++ asl/tests/meta_tests.cpp | 4 ++++ 3 files changed, 54 insertions(+), 2 deletions(-) (limited to 'asl') diff --git a/asl/hash.hpp b/asl/hash.hpp index 6190e8f..5eb64f6 100644 --- a/asl/hash.hpp +++ b/asl/hash.hpp @@ -1,12 +1,12 @@ #pragma once #include "asl/integers.hpp" +#include "asl/meta.hpp" +#include "asl/utility.hpp" namespace asl::city_hash { -// All CityHash stuff below this point - // Hash function for a byte array. uint64_t CityHash64(const char *s, size_t len); @@ -51,3 +51,44 @@ constexpr uint64_t Hash128to64(const uint128_t& x) } } // namespace asl::city_hash + +namespace asl +{ + +template +concept hashable_generic = requires(const T& value, H h) +{ + { AslHashValue(h, value) } -> same_as; +}; + +struct HashState +{ + uint128_t state{}; + + constexpr HashState() = default; + explicit constexpr HashState(uint128_t s) : state{s} {} + + static constexpr HashState combine(HashState h) + { + return h; + } + + template Arg, hashable_generic... Remaining> + static constexpr HashState combine(HashState h, const Arg& arg, const Remaining&... remaining) + { + return combine(AslHashValue(h, arg), remaining...); + } +}; + +template +concept hashable = hashable_generic; + +template +constexpr H AslHashValue(H h, const T& value) +{ + auto hashed = city_hash::CityHash128WithSeed(reinterpret_cast(&value), size_of, h.state); + return HashState{hashed}; +} + +} // namespace asl + diff --git a/asl/meta.hpp b/asl/meta.hpp index 84616f4..c353b0f 100644 --- a/asl/meta.hpp +++ b/asl/meta.hpp @@ -189,6 +189,13 @@ template<> struct _is_integer_helper : true_type {}; template concept is_integer = _is_integer_helper>::value; +template struct is_uniquely_represented : false_type {}; +template struct is_uniquely_represented : true_type {}; +template<> struct is_uniquely_represented : true_type {}; +template<> struct is_uniquely_represented : true_type {}; + +template concept uniquely_represented = is_uniquely_represented::value; + template concept equality_comparable_with = requires (const un_cvref_t& a, const un_cvref_t& b) { diff --git a/asl/tests/meta_tests.cpp b/asl/tests/meta_tests.cpp index 24e9754..4fedd71 100644 --- a/asl/tests/meta_tests.cpp +++ b/asl/tests/meta_tests.cpp @@ -232,3 +232,7 @@ static_assert(asl::is_floating_point); static_assert(!asl::is_floating_point); static_assert(!asl::is_floating_point); static_assert(!asl::is_floating_point); + +static_assert(asl::uniquely_represented); +static_assert(asl::uniquely_represented); +static_assert(!asl::uniquely_represented); -- cgit