diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index e81a413..89afe80 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -9,7 +9,6 @@ set(KLOTSKI_CORE_SRC common_code/internal/common_code.cc common_code/internal/serialize.cc - common_code/internal/sundry.cc raw_code/internal/raw_code.cc raw_code/internal/convert.cc diff --git a/src/core/common_code/common_code.h b/src/core/common_code/common_code.h index 4a935fa..46afcca 100644 --- a/src/core/common_code/common_code.h +++ b/src/core/common_code/common_code.h @@ -72,15 +72,32 @@ class CommonCode { public: // ------------------------------------------------------------------------------------- // + CommonCode() = delete; + + /// Construct CommonCode from RawCode. + explicit CommonCode(RawCode raw_code); + + /// Construct CommonCode from ShortCode. + explicit CommonCode(ShortCode short_code); + + /// Create CommonCode without any check. + static CommonCode unsafe_create(uint64_t common_code); + + /// Create CommonCode with validity check. + static std::optional create(uint64_t common_code); + + // ------------------------------------------------------------------------------------- // + /// Explicit conversion to u64 code. explicit operator uint64_t() const; /// Check the validity of the original CommonCode. static bool check(uint64_t common_code); - // TODO: add macro check here +#ifndef KLSK_NDEBUG /// Output string encoding of CommonCode only for debug. friend std::ostream& operator<<(std::ostream &out, CommonCode self); +#endif // ------------------------------------------------------------------------------------- // @@ -98,22 +115,6 @@ public: // ------------------------------------------------------------------------------------- // - CommonCode() = delete; - - /// Construct CommonCode from RawCode. - explicit CommonCode(RawCode raw_code); - - /// Construct CommonCode from ShortCode. - explicit CommonCode(ShortCode short_code); - - /// Create CommonCode without any check. - static CommonCode unsafe_create(uint64_t common_code); - - /// Create CommonCode with validity check. - static std::optional create(uint64_t common_code); - - // ------------------------------------------------------------------------------------- // - /// Create CommonCode from string form. static std::optional from_string(const std::string &common_code); @@ -138,7 +139,7 @@ public: // ------------------------------------------------------------------------------------- // - /// Compare CommonCode with u64 values. + /// Compare CommonCode with u64 value. friend constexpr auto operator==(const CommonCode &lhs, uint64_t rhs); friend constexpr auto operator<=>(const CommonCode &lhs, uint64_t rhs); @@ -153,13 +154,13 @@ private: // ------------------------------------------------------------------------------------- // - /// Serialize CommonCode into a 9-bit length string. + /// Serialize CommonCode into 9-bit length string. static std::string string_encode(uint64_t common_code); - /// Serialize CommonCode into a variable-length string, removing the trailing zero. + /// Serialize CommonCode into a variable-length string without trailing zero. static std::string string_encode_shorten(uint64_t common_code); - /// Deserialize CommonCode from string and return std::nullopt on error. + /// Deserialize CommonCode from string and return nullopt on error. static std::optional string_decode(const std::string &common_code); // ------------------------------------------------------------------------------------- // diff --git a/src/core/common_code/internal/common_code.cc b/src/core/common_code/internal/common_code.cc index e6e477d..24af763 100644 --- a/src/core/common_code/internal/common_code.cc +++ b/src/core/common_code/internal/common_code.cc @@ -1,9 +1,9 @@ -#include "utility.h" -#include "common_code.h" +#include "utils/utility.h" +#include "common_code/common_code.h" -namespace klotski::codec { +using klotski::codec::CommonCode; -bool CommonCode::check(uint64_t common_code) { +bool CommonCode::check(const uint64_t common_code) { // TODO: optimization of synchronizing all_cases. /// M_1x1 | M_1x2 | M_2x1 | M_2x2 @@ -16,7 +16,7 @@ bool CommonCode::check(uint64_t common_code) { constexpr uint32_t M_2x2 = 0b110011; /// 2x2 address check (high 32-bit) - uint32_t head = common_code >> 32; + const uint32_t head = common_code >> 32; if (head >= 16 || (head & 0b11) == 0b11) { // check 2x2 block address return false; // invalid common code } @@ -56,5 +56,3 @@ bool CommonCode::check(uint64_t common_code) { } } } - -} // namespace klotski::codec diff --git a/src/core/common_code/internal/common_code.inl b/src/core/common_code/internal/common_code.inl index b7907e1..784a44f 100644 --- a/src/core/common_code/internal/common_code.inl +++ b/src/core/common_code/internal/common_code.inl @@ -2,68 +2,121 @@ #include +#include "raw_code/raw_code.h" +#include "short_code/short_code.h" + namespace klotski::codec { // ------------------------------------------------------------------------------------- // -inline uint64_t CommonCode::unwrap() const { - return code_; +inline CommonCode::CommonCode(const RawCode raw_code) { + code_ = raw_code.to_common_code().code_; +} + +inline CommonCode::CommonCode(const ShortCode short_code) { + code_ = short_code.to_common_code().code_; } +inline CommonCode CommonCode::unsafe_create(const uint64_t common_code) { + return std::bit_cast(common_code); // init directly +} + +inline std::optional CommonCode::create(const uint64_t common_code) { + if (!check(common_code)) { + return std::nullopt; // invalid common code + } + return unsafe_create(common_code); +} + +// ------------------------------------------------------------------------------------- // + inline CommonCode::operator uint64_t() const { return code_; } +#ifndef KLSK_NDEBUG inline std::ostream& operator<<(std::ostream &out, const CommonCode self) { out << CommonCode::string_encode(self.code_); return out; } +#endif // ------------------------------------------------------------------------------------- // -constexpr auto operator==(const CommonCode &lhs, const uint64_t rhs) { - return lhs.code_ == rhs; +inline uint64_t CommonCode::unwrap() const { + return code_; } -constexpr auto operator<=>(const CommonCode &lhs, const uint64_t rhs) { - return lhs.code_ <=> rhs; +inline RawCode CommonCode::to_raw_code() const { + return RawCode(*this); } -constexpr auto operator==(const CommonCode &lhs, const CommonCode &rhs) { - return lhs.code_ == rhs.code_; +inline ShortCode CommonCode::to_short_code() const { + return ShortCode(*this); } -constexpr auto operator<=>(const CommonCode &lhs, const CommonCode &rhs) { - return lhs.code_ <=> rhs.code_; +inline std::string CommonCode::to_string(const bool shorten) const { + if (!shorten) { + return string_encode(code_); // with full length + } + return string_encode_shorten(code_); // without trailing zero } // ------------------------------------------------------------------------------------- // -inline CommonCode CommonCode::unsafe_create(const uint64_t common_code) { - return std::bit_cast(common_code); // init directly +inline std::optional CommonCode::from_string(const std::string &common_code) { + return string_decode(common_code).transform(unsafe_create); } -inline std::optional CommonCode::create(const uint64_t common_code) { - if (!check(common_code)) { - return std::nullopt; // invalid common code - } - return unsafe_create(common_code); +// ------------------------------------------------------------------------------------- // + +inline CommonCode CommonCode::from_raw_code(const RawCode raw_code) { + return raw_code.to_common_code(); +} + +inline std::optional CommonCode::from_raw_code(const uint64_t raw_code) { + const auto convert = [](const RawCode code) { + return code.to_common_code(); + }; + return RawCode::create(raw_code).transform(convert); } // ------------------------------------------------------------------------------------- // -inline std::string CommonCode::to_string(const bool shorten) const { - if (!shorten) { - return string_encode(code_); // with full length - } - return string_encode_shorten(code_); // without trailing zero +inline CommonCode CommonCode::from_short_code(const ShortCode short_code) { + return short_code.to_common_code(); } -inline std::optional CommonCode::from_string(const std::string &common_code) { - auto construct = [](const uint64_t code) { - return unsafe_create(code); +inline std::optional CommonCode::from_short_code(const uint32_t short_code) { + const auto convert = [](const ShortCode code) { + return code.to_common_code(); + }; + return ShortCode::create(short_code).transform(convert); +} + +inline std::optional CommonCode::from_short_code(const std::string &short_code) { + const auto convert = [](const ShortCode code) { + return code.to_common_code(); }; - return string_decode(common_code).transform(construct); + return ShortCode::from_string(short_code).transform(convert); +} + +// ------------------------------------------------------------------------------------- // + +constexpr auto operator==(const CommonCode &lhs, const uint64_t rhs) { + return lhs.code_ == rhs; +} + +constexpr auto operator<=>(const CommonCode &lhs, const uint64_t rhs) { + return lhs.code_ <=> rhs; +} + +constexpr auto operator==(const CommonCode &lhs, const CommonCode &rhs) { + return lhs.code_ == rhs.code_; +} + +constexpr auto operator<=>(const CommonCode &lhs, const CommonCode &rhs) { + return lhs.code_ <=> rhs.code_; } // ------------------------------------------------------------------------------------- // diff --git a/src/core/common_code/internal/serialize.cc b/src/core/common_code/internal/serialize.cc index e7911fc..e6cd562 100644 --- a/src/core/common_code/internal/serialize.cc +++ b/src/core/common_code/internal/serialize.cc @@ -1,9 +1,9 @@ -#include "common_code.h" +#include "common_code/common_code.h" namespace klotski::codec { /// Convert a single hexadecimal digit to a character. -inline static char to_hex_char(uint64_t hex_bit) { +static char to_hex_char(const uint64_t hex_bit) { if (hex_bit < 0xA) { return char(hex_bit + '0'); } diff --git a/src/core/common_code/internal/sundry.cc b/src/core/common_code/internal/sundry.cc deleted file mode 100644 index e30bba1..0000000 --- a/src/core/common_code/internal/sundry.cc +++ /dev/null @@ -1,61 +0,0 @@ -#include "raw_code.h" -#include "short_code.h" -#include "common_code.h" - -// TODO: move to inline header - -namespace klotski::codec { - -// ----------------------------------------------------------------------------------------- // - -CommonCode::CommonCode(RawCode raw_code) { - code_ = raw_code.to_common_code().code_; -} - -CommonCode::CommonCode(ShortCode short_code) { - code_ = short_code.to_common_code().code_; -} - -// ----------------------------------------------------------------------------------------- // - -RawCode CommonCode::to_raw_code() const { - return RawCode(*this); -} - -ShortCode CommonCode::to_short_code() const { - return ShortCode(*this); -} - -// ----------------------------------------------------------------------------------------- // - -CommonCode CommonCode::from_raw_code(RawCode raw_code) { - return raw_code.to_common_code(); -} - -std::optional CommonCode::from_raw_code(uint64_t raw_code) { - return RawCode::create(raw_code).transform([](auto raw_code) { - return raw_code.to_common_code(); - }); -} - -// ----------------------------------------------------------------------------------------- // - -CommonCode CommonCode::from_short_code(ShortCode short_code) { - return short_code.to_common_code(); -} - -std::optional CommonCode::from_short_code(uint32_t short_code) { - return ShortCode::create(short_code).transform([](auto short_code) { - return short_code.to_common_code(); - }); -} - -std::optional CommonCode::from_short_code(const std::string &short_code) { - return ShortCode::from_string(short_code).transform([](auto short_code) { - return short_code.to_common_code(); - }); -} - -// ----------------------------------------------------------------------------------------- // - -} // namespace klotski::codec