Skip to content

Commit

Permalink
Add yk::hash_combine
Browse files Browse the repository at this point in the history
  • Loading branch information
saki7 committed Aug 22, 2024
1 parent 7d1c750 commit d08bec4
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 3 deletions.
8 changes: 6 additions & 2 deletions include/yk/util/hash/hash.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#ifndef YK_UTIL_HASH_HASH_HPP
#define YK_UTIL_HASH_HASH_HPP

#define YK_PP_REQUIRE_SEMICOLON static_assert(true)

#define YK_ADAPT_HASH(ns, type, param, hash_stmt) \
namespace std { \
template <> \
Expand All @@ -15,7 +17,8 @@
{ \
return ::yk::hash_value_for(value); \
} \
} /* ns */
} /* ns */ \
YK_PP_REQUIRE_SEMICOLON

#define YK_PP_EXPAND(...) __VA_ARGS__
#define YK_PP_REMOVE_PAREN(expr) YK_PP_EXPAND expr
Expand All @@ -35,6 +38,7 @@
{ \
return ::yk::hash_value_for(value); \
} \
} /* ns */
} /* ns */ \
YK_PP_REQUIRE_SEMICOLON

#endif // YK_UTIL_HASH_HASH_HPP
20 changes: 20 additions & 0 deletions include/yk/util/hash/hash_combine.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#ifndef YK_UTIL_HASH_HASH_COMBINE_HPP
#define YK_UTIL_HASH_HASH_COMBINE_HPP

#include <boost/container_hash/hash.hpp>

#include <cstddef>

namespace yk {

template <class T, class... Rest>
[[nodiscard]] constexpr std::size_t hash_combine(T const& first_arg, Rest const&... rest) noexcept /* strengthened */
{
std::size_t seed = hash_value(first_arg);
(boost::hash_combine(seed, hash_value(rest)), ...);
return seed;
}

} // namespace yk

#endif // YK_HASH_HASH_COMBINE_HPP
15 changes: 14 additions & 1 deletion test/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "yk/util/forward_like.hpp"
#include "yk/util/hash.hpp"
#include "yk/util/hash/boost.hpp"
#include "yk/util/hash/hash_combine.hpp"
#include "yk/util/pack_indexing.hpp"
#include "yk/util/reverse.hpp"
#include "yk/util/specialization_of.hpp"
Expand Down Expand Up @@ -46,9 +47,14 @@ struct S {
int val;
};

struct MultiS {
int a, b;
};

} // namespace hash_test

YK_ADAPT_HASH_TEMPLATE(hash_test, (S<T, Ts...>), val, { return val.val; }, class T, class... Ts)
YK_ADAPT_HASH_TEMPLATE(hash_test, (S<T, Ts...>), val, { return val.val; }, class T, class... Ts);
YK_ADAPT_HASH(hash_test, MultiS, val, { return yk::hash_combine(val.a, val.b); });

BOOST_AUTO_TEST_SUITE(yk_util)

Expand Down Expand Up @@ -238,6 +244,13 @@ BOOST_AUTO_TEST_CASE(Hash) {
hash_test::S<int, double> s{42};
BOOST_TEST(yk::hash_value_for(s) == yk::hash_value_for(42));
BOOST_TEST(hash_value(s) == yk::hash_value_for(42)); // call hash_value by ADL

{
hash_test::MultiS s{334, 314151765};
std::size_t seed = yk::hash_value_for(s.a);
boost::hash_combine(seed, yk::hash_value_for(s.b));
BOOST_TEST(hash_value(s) == seed);
}
}

BOOST_AUTO_TEST_SUITE_END() // yk_util

0 comments on commit d08bec4

Please sign in to comment.