diff --git a/src/klotski_core/common_code/common_code.h b/src/klotski_core/common_code/common_code.h index e89ed3a..fbb45ea 100644 --- a/src/klotski_core/common_code/common_code.h +++ b/src/klotski_core/common_code/common_code.h @@ -127,3 +127,11 @@ inline bool operator==(const CommonCode &c1, const CommonCode &c2) noexcept { re inline bool operator!=(const CommonCode &c1, const CommonCode &c2) noexcept { return c1.unwrap() != c2.unwrap(); } } // namespace klotski + +/// In namespace std, let the CommonCode implement the standard hash function. +template<> +struct std::hash { + inline std::size_t operator()(const klotski::CommonCode &common_code) const { + return static_cast(common_code.unwrap()); + } +}; diff --git a/src/klotski_core/raw_code/raw_code.h b/src/klotski_core/raw_code/raw_code.h index 7dbd306..605a912 100644 --- a/src/klotski_core/raw_code/raw_code.h +++ b/src/klotski_core/raw_code/raw_code.h @@ -116,3 +116,11 @@ inline bool operator==(const RawCode &r1, const RawCode &r2) noexcept { return r inline bool operator!=(const RawCode &r1, const RawCode &r2) noexcept { return r1.unwrap() != r2.unwrap(); } } // namespace klotski + +/// In namespace std, let the RawCode implement the standard hash function. +template<> +struct std::hash { + inline std::size_t operator()(const klotski::RawCode &raw_code) const { + return static_cast(raw_code.unwrap()); + } +}; diff --git a/src/klotski_core/short_code/short_code.h b/src/klotski_core/short_code/short_code.h index a8cdba4..8b8b978 100644 --- a/src/klotski_core/short_code/short_code.h +++ b/src/klotski_core/short_code/short_code.h @@ -141,3 +141,11 @@ inline bool operator==(const ShortCode &s1, const ShortCode &s2) noexcept { retu inline bool operator!=(const ShortCode &s1, const ShortCode &s2) noexcept { return s1.unwrap() != s2.unwrap(); } } // namespace klotski + +/// In namespace std, let the ShortCode implement the standard hash function. +template<> +struct std::hash { + inline std::size_t operator()(const klotski::ShortCode &short_code) const { + return static_cast(short_code.unwrap()); + } +}; diff --git a/test/codec/common_code.cc b/test/codec/common_code.cc index d659e5a..acfdf53 100644 --- a/test/codec/common_code.cc +++ b/test/codec/common_code.cc @@ -1,5 +1,6 @@ #include #include +#include #include "all_cases.h" #include "common_code.h" #include "gtest/gtest.h" @@ -22,6 +23,11 @@ static inline void SHOULD_PANIC(const std::function &func) { EXPECT_EQ(panic_flag, true); } +TEST(CommonCode, hash) { + auto tmp = std::unordered_set{ CommonCode(TEST_CODE) }; + EXPECT_EQ(tmp.size(), 1); +} + TEST(CommonCode, validity) { EXPECT_NE(CommonCode::check(0x3'A9'BF'0C'00), true); // invalid 2x2 block EXPECT_NE(CommonCode::check(0x1'D9'BF'0C'00), true); // invalid block range diff --git a/test/codec/raw_code.cc b/test/codec/raw_code.cc index 40c639d..ba721de 100644 --- a/test/codec/raw_code.cc +++ b/test/codec/raw_code.cc @@ -1,4 +1,5 @@ #include +#include #include "raw_code.h" #include "all_cases.h" #include "gtest/gtest.h" @@ -9,6 +10,11 @@ using klotski::CommonCode; const static uint64_t TEST_CODE = 0x0603'EDF5'CAFF'F5E2; +TEST(RawCode, hash) { + auto tmp = std::unordered_set{ RawCode(TEST_CODE) }; + EXPECT_EQ(tmp.size(), 1); +} + TEST(RawCode, validity) { EXPECT_EQ(RawCode::check(0x0A34'182B'3810'2D21), false); // invalid code EXPECT_EQ(RawCode::check(0x8603'EDF5'CAFF'F5E2), false); // high 4-bits not zero diff --git a/test/codec/short_code.cc b/test/codec/short_code.cc index 05932a7..878bc51 100644 --- a/test/codec/short_code.cc +++ b/test/codec/short_code.cc @@ -1,5 +1,6 @@ #include #include +#include #include "all_cases.h" #include "short_code.h" #include "gtest/gtest.h" @@ -22,6 +23,11 @@ static inline void SHOULD_PANIC(const std::function &func) { EXPECT_EQ(panic_flag, true); } +TEST(ShortCode, hash) { + auto tmp = std::unordered_set{ ShortCode(TEST_CODE) }; + EXPECT_EQ(tmp.size(), 1); +} + TEST(ShortCode, validity) { EXPECT_NE(ShortCode::check(-1), true); // out of short code range EXPECT_NE(ShortCode::check(29670987), true); // out of short code range