diff --git a/src/klotski/common_code/common_code.cc b/src/klotski/common_code/common_code.cc index 1a733f0..573a783 100644 --- a/src/klotski/common_code/common_code.cc +++ b/src/klotski/common_code/common_code.cc @@ -2,47 +2,59 @@ #include "common.h" #include "common_code.h" -using klotski::CommonCode; +namespace std { + template<> + struct hash { + std::size_t operator()(const klotski::CommonCode &c) const { + return std::hash()(c.unwrap()); + } + }; -uint64_t CommonCode::unwrap() const { - return code; // raw uint64_t code + template<> + struct equal_to { + bool operator()(const klotski::CommonCode &c1, const klotski::CommonCode &c2) const { + return c1.unwrap() == c2.unwrap(); + } + }; } -bool CommonCode::valid() const { - return CommonCode::check(code); -} +namespace klotski { + bool CommonCode::operator==(const CommonCode &common_code) const { + return this->code == common_code.code; + } -CommonCode CommonCode::create(uint64_t common_code) { - return CommonCode(common_code); // create from uint64_t + std::ostream& operator<<(std::ostream &out, const CommonCode &self) { + char str[10]; + sprintf(str, "%09lX", self.code); + out << str; + return out; + } } -CommonCode CommonCode::unsafe_create(uint64_t common_code) { // create without check - auto common = CommonCode(); // init directly - common.code = common_code; - return common; -} +namespace klotski { + bool CommonCode::valid() const { + return CommonCode::check(code); + } -CommonCode::CommonCode(uint64_t common_code) { - if (!CommonCode::check(common_code)) { // check input common code - throw std::invalid_argument("invalid common code"); + CommonCode CommonCode::create(uint64_t common_code) { + return CommonCode(common_code); // create from uint64_t } - code = common_code; -} -bool CommonCode::operator==(const CommonCode &common_code) const { - return this->code == common_code.code; -} + CommonCode CommonCode::unsafe_create(uint64_t common_code) { // create without check + auto tmp = CommonCode(); // init directly + tmp.code = common_code; + return tmp; + } -namespace klotski { - std::ostream &operator<<(std::ostream &out, const CommonCode &self) { - char str[10]; - sprintf(str, "%09lX", self.code); - out << str; - return out; + CommonCode::CommonCode(uint64_t common_code) { + if (!CommonCode::check(common_code)) { // check input common code + throw std::invalid_argument("invalid common code"); + } + code = common_code; } } -bool CommonCode::check(uint64_t common_code) { // whether common code is valid +bool klotski::CommonCode::check(uint64_t common_code) { // whether common code is valid /// M_1x1 M_1x2 M_2x1 M_2x2 /// 1 0 0 0 1 1 0 0 1 0 0 0 1 1 0 0 /// 0 0 0 0 0 0 0 0 1 0 0 0 1 1 0 0 diff --git a/src/klotski/common_code/common_code.h b/src/klotski/common_code/common_code.h index 9c7cb84..bfb415a 100644 --- a/src/klotski/common_code/common_code.h +++ b/src/klotski/common_code/common_code.h @@ -13,19 +13,19 @@ namespace klotski { class CommonCode { public: - bool valid() const; + inline bool valid() const; static bool check(uint64_t common_code); /// Operators of CommonCode - explicit operator uint64_t() const { return code; } + constexpr operator uint64_t() const { return code; } bool operator==(const CommonCode &common_code) const; friend std::ostream& operator<<(std::ostream &out, const CommonCode &self); /// Export functions - uint64_t unwrap() const; RawCode to_raw_code() const; ShortCode to_short_code() const; std::string to_string(bool shorten = false) const; + constexpr uint64_t unwrap() const { return code; } /// CommonCode constructors explicit CommonCode(uint64_t common_code); diff --git a/src/klotski/raw_code/raw_code.cc b/src/klotski/raw_code/raw_code.cc index 9fb015e..fbb4ef2 100644 --- a/src/klotski/raw_code/raw_code.cc +++ b/src/klotski/raw_code/raw_code.cc @@ -2,43 +2,32 @@ #include "common.h" #include "raw_code.h" -using klotski::RawCode; - -uint64_t RawCode::unwrap() const { - return code; // raw uint64_t code -} - -bool RawCode::valid() const { - return RawCode::check(code); -} - -RawCode RawCode::create(uint64_t raw_code) { - return RawCode(raw_code); -} +namespace std { + template<> + struct hash { + std::size_t operator()(const klotski::RawCode &c) const { + return std::hash()(c.unwrap()); + } + }; -RawCode RawCode::unsafe_create(uint64_t raw_code) { // create without check - auto raw = RawCode(); // init directly - raw.code = raw_code; - return raw; + template<> + struct equal_to { + bool operator()(const klotski::RawCode &c1, const klotski::RawCode &c2) const { + return c1.unwrap() == c2.unwrap(); + } + }; } -RawCode::RawCode(uint64_t raw_code) { - if (!RawCode::check(raw_code)) { // check input raw code - throw std::invalid_argument("invalid raw code"); +namespace klotski { + bool RawCode::operator==(const RawCode &raw_code) const { + return this->code == raw_code.code; } - code = raw_code; -} - -bool RawCode::operator==(const RawCode &raw_code) const { - return this->code == raw_code.code; -} -namespace klotski { - std::ostream &operator<<(std::ostream &out, const RawCode &self) { + std::ostream& operator<<(std::ostream &out, const RawCode &self) { char code[16]; char dump_map[] = { - /// 0x0 1x2 2x1 1x1 2x2 b101 b110 fill - '.', '~', '|', '*', '@', '?', '?', '+' + /// 0x0 1x2 2x1 1x1 2x2 b101 b110 fill + '.', '~', '|', '*', '@', '?', '?', '+' }; sprintf(code, "%015lX", self.code); // code length -> 15 out << code << '\n'; @@ -50,7 +39,30 @@ namespace klotski { } } -bool RawCode::check(uint64_t raw_code) { // check whether raw code is valid +namespace klotski { + bool RawCode::valid() const { + return RawCode::check(code); + } + + RawCode RawCode::create(uint64_t raw_code) { + return RawCode(raw_code); + } + + RawCode RawCode::unsafe_create(uint64_t raw_code) { // create without check + auto tmp = RawCode(); // init directly + tmp.code = raw_code; + return tmp; + } + + RawCode::RawCode(uint64_t raw_code) { + if (!RawCode::check(raw_code)) { // check input raw code + throw std::invalid_argument("invalid raw code"); + } + code = raw_code; + } +} + +bool klotski::RawCode::check(uint64_t raw_code) { // check whether raw code is valid /// MASK_1x2 MASK_2x1 MASK_2x2 /// 000 100 000 000 000 000 000 000 000 100 000 000 /// 000 000 000 000 100 000 000 000 100 100 000 000 diff --git a/src/klotski/raw_code/raw_code.h b/src/klotski/raw_code/raw_code.h index 67b1ead..9502c9a 100644 --- a/src/klotski/raw_code/raw_code.h +++ b/src/klotski/raw_code/raw_code.h @@ -45,17 +45,17 @@ namespace klotski { class RawCode { public: - bool valid() const; + inline bool valid() const; static bool check(uint64_t raw_code); /// Operators of RawCode bool operator==(const RawCode &raw_code) const; - explicit operator uint64_t() const { return code; } + constexpr operator uint64_t() const { return code; } friend std::ostream& operator<<(std::ostream &out, const RawCode &self); /// Export functions - uint64_t unwrap() const; CommonCode to_common_code() const; + constexpr uint64_t unwrap() const { return code; } /// RawCode constructors explicit RawCode(uint64_t raw_code); diff --git a/src/klotski/short_code/short_code.cc b/src/klotski/short_code/short_code.cc index 2db9273..8389945 100644 --- a/src/klotski/short_code/short_code.cc +++ b/src/klotski/short_code/short_code.cc @@ -1,42 +1,62 @@ #include "all_cases.h" #include "short_code.h" -using klotski::ShortCode; +namespace std { + template<> + struct hash { + std::size_t operator()(const klotski::ShortCode &c) const { + return std::hash()(c.unwrap()); + } + }; -uint32_t ShortCode::unwrap() const { - return code; // raw uint32_t code + template<> + struct equal_to { + bool operator()(const klotski::ShortCode &c1, const klotski::ShortCode &c2) const { + return c1.unwrap() == c2.unwrap(); + } + }; } -bool ShortCode::valid() const { - return ShortCode::check(code); -} +namespace klotski { + bool ShortCode::operator==(const ShortCode &short_code) const { + return this->code == short_code.code; + } -ShortCode ShortCode::create(uint32_t short_code) { - return ShortCode(short_code); + std::ostream &operator<<(std::ostream &out, const ShortCode &self) { + out << self.to_string() << "(" << self.code << ")"; // short code info + return out; + } } -ShortCode::ShortCode(uint32_t short_code) { - if (!ShortCode::check(short_code)) { // check input short code - throw std::invalid_argument("invalid short code"); +namespace klotski { + bool ShortCode::valid() const { + return ShortCode::check(code); } - code = short_code; -} -bool ShortCode::check(uint32_t short_code) { - return short_code < SHORT_CODE_LIMIT; // 0 ~ (SHORT_CODE_LIMIT - 1) -} + ShortCode ShortCode::create(uint32_t short_code) { + return ShortCode(short_code); + } -bool ShortCode::operator==(const ShortCode &short_code) const { - return this->code == short_code.code; -} + ShortCode ShortCode::unsafe_create(uint32_t short_code) { // create without check + auto tmp = ShortCode(); // init directly + tmp.code = short_code; + return tmp; + } -namespace klotski { - std::ostream &operator<<(std::ostream &out, const ShortCode &self) { - out << self.to_string() << "(" << self.code << ")"; // short code info - return out; + ShortCode::ShortCode(uint32_t short_code) { + if (!ShortCode::check(short_code)) { // check input short code + throw std::invalid_argument("invalid short code"); + } + code = short_code; } } +bool klotski::ShortCode::check(uint32_t short_code) { + return short_code < SHORT_CODE_LIMIT; // 0 ~ (SHORT_CODE_LIMIT - 1) +} + +using klotski::ShortCode; + bool ShortCode::fast_mode_available = false; bool ShortCode::normal_mode_available = false; diff --git a/src/klotski/short_code/short_code.h b/src/klotski/short_code/short_code.h index 9014e49..44ba4cd 100644 --- a/src/klotski/short_code/short_code.h +++ b/src/klotski/short_code/short_code.h @@ -13,19 +13,19 @@ namespace klotski { public: enum Mode {NORMAL, FAST}; - bool valid() const; + inline bool valid() const; static void speed_up(enum Mode mode); static bool check(uint32_t short_code); /// Operators of ShortCode - explicit operator uint32_t() const { return code; } + constexpr operator uint32_t() const { return code; } bool operator==(const ShortCode &short_code) const; friend std::ostream& operator<<(std::ostream &out, const ShortCode &self); /// Export functions - uint32_t unwrap() const; std::string to_string() const; CommonCode to_common_code() const; + constexpr uint32_t unwrap() const { return code; } /// ShortCode constructors explicit ShortCode(uint32_t short_code); @@ -38,6 +38,7 @@ namespace klotski { /// Rust-style initialization static ShortCode create(uint32_t short_code); + static ShortCode unsafe_create(uint32_t short_code); static ShortCode from_string(const std::string &short_code); static ShortCode from_common_code(uint64_t common_code); @@ -50,6 +51,7 @@ namespace klotski { static bool normal_mode_available; static const uint32_t SHORT_CODE_LIMIT = 29334498; + ShortCode() = default; // unsafe initialize static enum Mode mode(); static uint64_t fast_decode(uint32_t short_code); static uint32_t fast_encode(uint64_t common_code);