diff --git a/src/core/common_code/common_code.h b/src/core/common_code/common_code.h index 24159e7..9f5c083 100644 --- a/src/core/common_code/common_code.h +++ b/src/core/common_code/common_code.h @@ -201,3 +201,10 @@ static_assert(std::is_trivially_copyable_v); #include "internal/common_code.inl" #include "internal/mirror.inl" #include "internal/check.inl" + +template <> +struct std::hash { + constexpr std::size_t operator()(const klotski::codec::CommonCode &c) const noexcept { + return std::hash{}(c.unwrap()); + } +}; diff --git a/src/core/common_code/internal/common_code.inl b/src/core/common_code/internal/common_code.inl index de55de5..e640153 100644 --- a/src/core/common_code/internal/common_code.inl +++ b/src/core/common_code/internal/common_code.inl @@ -53,6 +53,8 @@ inline ShortCode CommonCode::to_short_code() const { return ShortCode(*this); } +// ----------------------------------------------------------------------------------------- // + inline std::string CommonCode::to_string(const bool shorten) const { if (!shorten) { return string_encode(code_); // with full length @@ -60,8 +62,6 @@ inline std::string CommonCode::to_string(const bool shorten) const { return string_encode_shorten(code_); // without trailing zero } -// ----------------------------------------------------------------------------------------- // - inline std::optional CommonCode::from_string(const std::string_view common_code) { return string_decode(common_code).transform(unsafe_create); } @@ -138,18 +138,3 @@ constexpr auto operator<=>(const CommonCode &lhs, const CommonCode &rhs) { // ----------------------------------------------------------------------------------------- // } // namespace klotski::codec - -// ----------------------------------------------------------------------------------------- // - -namespace std { - -template <> -struct hash { - constexpr std::size_t operator()(const klotski::codec::CommonCode &c) const noexcept { - return std::hash{}(c.unwrap()); - } -}; - -} // namespace std - -// ----------------------------------------------------------------------------------------- // diff --git a/src/core/main.cc b/src/core/main.cc index 8540fa5..e477c84 100644 --- a/src/core/main.cc +++ b/src/core/main.cc @@ -79,6 +79,13 @@ int main() { static_assert(raw_code.to_vertical_mirror() == 0xFFF5E2FCF4DA603); static_assert(raw_code.to_horizontal_mirror() == 0x603EDF5CAFFF5E2); + static_assert(ShortCode::check(4091296)); + constexpr auto short_code = ShortCode::unsafe_create(4091296); + + static_assert(short_code.unwrap() == 4091296); + static_assert(static_cast(short_code) == 4091296); + static_assert(short_code == ShortCode::create(4091296)->unwrap()); + // const auto code = CommonCode::unsafe_create(0x1A9BF0C00).to_raw_code(); // const auto code = CommonCode::unsafe_create(0x4FEA13400).to_raw_code(); // FastCal fc {code}; diff --git a/src/core/raw_code/internal/check.inl b/src/core/raw_code/internal/check.inl index f8a6759..1723913 100644 --- a/src/core/raw_code/internal/check.inl +++ b/src/core/raw_code/internal/check.inl @@ -1,33 +1,9 @@ #pragma once -#ifndef KLSK_NDEBUG -// TODO: only for debug output -> move to other header -#include -#include -#endif - #include "utils/common.h" namespace klotski::codec { -#ifndef KLSK_NDEBUG -inline std::ostream& operator<<(std::ostream &out, const RawCode self) { - constexpr auto char_map = std::to_array({ - '.', // space - '~', '|', // 1x2 | 2x1 - '*', '@', // 1x1 | 2x2 - '?', '?', // unknown - '+', // fill - }); - out << std::format("{:015X}\n", self.code_); - for (int addr = 0; addr < 60; addr += 3) { - out << char_map[(self.code_ >> addr) & 0b111]; - out << &" "[(addr & 0b11) == 0b01] << &"\n"[(addr & 0b11) != 0b01]; - } - return out; -} -#endif - constexpr bool RawCode::check(uint64_t raw_code) { /// MASK_1x1 | MASK_1x2 | MASK_2x1 | MASK_2x2 /// 100 000 000 000 | 000 100 000 000 | 000 000 000 000 | 000 100 000 000 diff --git a/src/core/raw_code/internal/raw_code.inl b/src/core/raw_code/internal/raw_code.inl index 8ae3f1c..80c3075 100644 --- a/src/core/raw_code/internal/raw_code.inl +++ b/src/core/raw_code/internal/raw_code.inl @@ -1,5 +1,7 @@ #pragma once +#include + #include "common_code/common_code.h" namespace klotski::codec { @@ -93,19 +95,28 @@ constexpr auto operator<=>(const RawCode &lhs, const RawCode &rhs) { // ----------------------------------------------------------------------------------------- // -} // namespace klotski::codec - -// ----------------------------------------------------------------------------------------- // - -namespace std { +#ifndef KLSK_NDEBUG +inline std::ostream& operator<<(std::ostream &out, const RawCode self) { + auto show = [code = self.code_](const int offset) { + constexpr auto char_map = std::to_array({ + '.', // space + '~', '|', // 1x2 | 2x1 + '*', '@', // 1x1 | 2x2 + '?', '?', // unknown + '+', // fill + }); + return char_map[(code >> (offset * 3)) & 0b111]; + }; -template <> -struct hash { - constexpr std::size_t operator()(const klotski::codec::RawCode &r) const noexcept { - return std::hash{}(r.unwrap()); + out << std::format("{:015X}\n", self.code_); + for (int offset = 0; offset < 20; offset += 4) { + out << std::format("{} {} {} {}\n", + show(offset), show(offset + 1), show(offset + 2), show(offset + 3)); } -}; - -} // namespace std + return out; +} +#endif // ----------------------------------------------------------------------------------------- // + +} // namespace klotski::codec diff --git a/src/core/raw_code/raw_code.h b/src/core/raw_code/raw_code.h index 6bb82d8..8c5641c 100644 --- a/src/core/raw_code/raw_code.h +++ b/src/core/raw_code/raw_code.h @@ -179,3 +179,10 @@ static_assert(std::is_trivially_copyable_v); #include "internal/convert.inl" #include "internal/mirror.inl" #include "internal/check.inl" + +template <> +struct std::hash { + constexpr std::size_t operator()(const klotski::codec::RawCode &r) const noexcept { + return std::hash{}(r.unwrap()); + } +}; diff --git a/src/core/short_code/internal/short_code.inl b/src/core/short_code/internal/short_code.inl index 8edefdf..827e6bd 100644 --- a/src/core/short_code/internal/short_code.inl +++ b/src/core/short_code/internal/short_code.inl @@ -117,18 +117,3 @@ constexpr auto operator<=>(const ShortCode &lhs, const ShortCode &rhs) { // ----------------------------------------------------------------------------------------- // } // namespace klotski::codec - -// ----------------------------------------------------------------------------------------- // - -namespace std { - -template <> -struct hash { - constexpr std::size_t operator()(const klotski::codec::ShortCode &s) const noexcept { - return std::hash{}(s.unwrap()); - } -}; - -} // namespace std - -// ----------------------------------------------------------------------------------------- // diff --git a/src/core/short_code/short_code.h b/src/core/short_code/short_code.h index 9499291..54bcd48 100644 --- a/src/core/short_code/short_code.h +++ b/src/core/short_code/short_code.h @@ -91,15 +91,15 @@ public: // ------------------------------------------------------------------------------------- // + /// Build the conversion index. + static void speed_up(bool fast_mode); + /// Explicit conversion to u32 code. explicit constexpr operator uint32_t() const; /// Check the validity of the original ShortCode. static constexpr bool check(uint32_t short_code); - /// Build the conversion index for ShortCode. - static void speed_up(bool fast_mode = false); - #ifndef KLSK_NDEBUG /// Output string encoding of ShortCode only for debug. friend std::ostream& operator<<(std::ostream &out, ShortCode self); @@ -195,3 +195,10 @@ static_assert(std::is_trivially_copyable_v); #include "internal/short_code.inl" #include "internal/serialize.inl" #include "internal/convert.inl" + +template <> +struct std::hash { + constexpr std::size_t operator()(const klotski::codec::ShortCode &s) const noexcept { + return std::hash{}(s.unwrap()); + } +};