Browse Source

update: using inline impl

master
Dnomd343 9 months ago
parent
commit
0750c50b60
  1. 48
      src/core/common_code/common_code.h
  2. 56
      src/core/common_code/inline_impl.h
  3. 48
      src/core/main.cc
  4. 70
      src/core/raw_code/inline_impl.h
  5. 42
      src/core/raw_code/mirror.cc
  6. 54
      src/core/raw_code/raw_code.h
  7. 81
      src/core/short_code/convert.cc
  8. 56
      src/core/short_code/inline_impl.h
  9. 18
      src/core/short_code/offset/all_cases_offset.h
  10. 25
      src/core/short_code/offset/basic.h
  11. 13
      src/core/short_code/offset/range_prefix.h
  12. 8
      src/core/short_code/serialize.cc
  13. 28
      src/core/short_code/serialize_chars.h
  14. 22
      src/core/short_code/short_code.cc
  15. 48
      src/core/short_code/short_code.h
  16. 66
      src/core/short_code/sundry.cc

48
src/core/common_code/common_code.h

@ -101,51 +101,7 @@ private:
static std::optional<uint64_t> string_decode(const std::string &common_code) noexcept;
};
/// CommonCode compare implements.
inline bool operator==(uint64_t c1, CommonCode c2) noexcept {
return c1 == c2.unwrap();
}
inline bool operator==(CommonCode c1, CommonCode c2) noexcept {
return c1.unwrap() == c2.unwrap();
}
inline bool operator<(CommonCode c1, CommonCode c2) noexcept {
return c1.unwrap() < c2.unwrap();
}
inline bool operator>(CommonCode c1, CommonCode c2) noexcept {
return c1.unwrap() > c2.unwrap();
}
/// Get the original 64-bit code.
inline uint64_t CommonCode::unwrap() const noexcept {
return code_;
}
/// Implicit conversion to 64-bit code.
inline CommonCode::operator uint64_t() const noexcept {
return code_;
}
/// CommonCode create without any check.
inline CommonCode CommonCode::unsafe_create(uint64_t common_code) noexcept {
return *reinterpret_cast<CommonCode*>(&common_code); // init directly
}
/// CommonCode create with valid check.
inline std::optional<CommonCode> CommonCode::create(uint64_t common_code) noexcept {
if (!CommonCode::check(common_code)) {
return std::nullopt;
}
return CommonCode::unsafe_create(common_code);
}
/// Output string encoding of CommonCode.
inline std::ostream& operator<<(std::ostream &out, CommonCode self) {
out << CommonCode::string_encode(self.code_);
return out;
}
} // namespace codec
} // namespace klotski
#include "inline_impl.h"

56
src/core/common_code/inline_impl.h

@ -0,0 +1,56 @@
#pragma once
namespace klotski {
namespace codec {
/// Get the original 64-bit code.
inline uint64_t CommonCode::unwrap() const noexcept {
return code_;
}
/// Implicit conversion to 64-bit code.
inline CommonCode::operator uint64_t() const noexcept {
return code_;
}
/// Equality comparison between CommonCode and numbers.
inline bool operator==(CommonCode c1, uint64_t c2) noexcept {
return c1.unwrap() == c2;
}
/// CommonCode equal comparison implement.
inline bool operator==(CommonCode c1, CommonCode c2) noexcept {
return c1.unwrap() == c2.unwrap();
}
/// CommonCode less than comparison implement.
inline bool operator<(CommonCode c1, CommonCode c2) noexcept {
return c1.unwrap() < c2.unwrap();
}
/// CommonCode greater than comparison implement.
inline bool operator>(CommonCode c1, CommonCode c2) noexcept {
return c1.unwrap() > c2.unwrap();
}
/// CommonCode create without any check.
inline CommonCode CommonCode::unsafe_create(uint64_t common_code) noexcept {
return *reinterpret_cast<CommonCode*>(&common_code); // init directly
}
/// CommonCode create with valid check.
inline std::optional<CommonCode> CommonCode::create(uint64_t common_code) noexcept {
if (!CommonCode::check(common_code)) {
return std::nullopt; // invalid common code
}
return CommonCode::unsafe_create(common_code);
}
/// Output string encoding of CommonCode.
inline std::ostream& operator<<(std::ostream &out, CommonCode self) {
out << CommonCode::string_encode(self.code_);
return out;
}
} // namespace codec
} // namespace klotski

48
src/core/main.cc

@ -1,34 +1,29 @@
#include <iostream>
#include "raw_code.h"
#include "all_cases.h"
#include "short_code.h"
#include "common_code.h"
#include "all_cases/all_cases.h"
using klotski::cases::AllCases;
using klotski::cases::BasicRanges;
using klotski::codec::RawCode;
using klotski::codec::ShortCode;
using klotski::codec::CommonCode;
int main() {
// std::cout << (int)'0' << std::endl;
// std::cout << (int)'A' << std::endl;
// std::cout << CommonCode::string_encode(0x1A9BF0C00, false) << std::endl;
// std::cout << CommonCode::string_encode(0x0'10'00'00'00, false) << std::endl;
// return 0;
// AllCases::instance().build();
BasicRanges::instance().build();
// printf("%09llX\n", CommonCode::string_decode("1A9BF0C").value());
// return 0;
// std::vector<uint64_t> common_codes;
// common_codes.reserve(klotski::cases::ALL_CASES_NUM_);
// BasicRanges::Instance().Build();
AllCases::Instance().Build();
std::vector<uint64_t> common_codes;
common_codes.reserve(klotski::cases::ALL_CASES_NUM_);
for (uint64_t head = 0; head < 15; ++head) {
for (auto range : AllCases::Instance().Fetch()[head]) {
common_codes.emplace_back(head << 32 | range);
}
}
// for (uint64_t head = 0; head < 15; ++head) {
// for (auto range : AllCases::instance().fetch()[head]) {
// common_codes.emplace_back(head << 32 | range);
// }
// }
// std::vector<std::string> common_codes_str;
// common_codes_str.reserve(klotski::cases::ALL_CASES_NUM_);
@ -50,19 +45,12 @@ int main() {
// CommonCode::string_decode(common_code_str);
// }
// BasicRanges::Instance().Build();
// AllCases::Instance().Build();
// AllCases::Instance().BuildParallel([](auto f) {f();});
// AllCases::Instance().BuildParallelAsync([](auto f) {f();}, []() {});
// BasicRanges::instance().build();
// AllCases::instance().build();
// AllCases::instance().build_parallel([](auto f) {f();});
// AllCases::instance().build_parallel_async([](auto f) {f();}, []() {});
std::cerr << ((clock() - start) * 1000 / CLOCKS_PER_SEC) << "ms" << std::endl;
// for (uint64_t head = 0; head < 15; ++head) {
// for (auto range : AllCases::Instance().Fetch()[head]) {
// printf("%09llX\n", head << 32 | range);
// }
// }
return 0;
}

70
src/core/raw_code/inline_impl.h

@ -0,0 +1,70 @@
#pragma once
namespace klotski {
namespace codec {
/// Get the original 64-bit code.
inline uint64_t RawCode::unwrap() const noexcept {
return code_;
}
/// Implicit conversion to 64-bit code.
inline RawCode::operator uint64_t() const noexcept {
return code_;
}
/// Equality comparison between RawCode and numbers.
inline bool operator==(RawCode r1, uint64_t r2) noexcept {
return r1.unwrap() == r2;
}
/// RawCode equal comparison implement.
inline bool operator==(RawCode r1, RawCode r2) noexcept {
return r1.unwrap() == r2.unwrap();
}
/// RawCode create without any check.
inline RawCode RawCode::unsafe_create(uint64_t raw_code) noexcept {
return *reinterpret_cast<RawCode*>(&raw_code); // init directly
}
/// RawCode create with valid check.
inline std::optional<RawCode> RawCode::create(uint64_t raw_code) noexcept {
if (!RawCode::check(raw_code)) {
return std::nullopt; // invalid raw code
}
return RawCode::unsafe_create(raw_code);
}
/// Calculate vertically symmetrical case.
inline RawCode RawCode::to_vertical_mirror() const noexcept {
return RawCode::unsafe_create(get_vertical_mirror(code_));
}
/// Calculate horizontally symmetrical case.
inline RawCode RawCode::to_horizontal_mirror() const noexcept {
return RawCode::unsafe_create(get_horizontal_mirror(code_));
}
/// Determine whether the case is vertically symmetrical.
inline bool RawCode::is_vertical_mirror() const noexcept {
return check_vertical_mirror(code_);
}
/// Determine whether the case is horizontally symmetrical.
inline bool RawCode::is_horizontal_mirror() const noexcept {
return check_horizontal_mirror(code_);
}
/// Determine whether two cases are vertically symmetrical to each other.
inline bool RawCode::is_vertical_mirror(RawCode raw_code) const noexcept {
return raw_code.code_ == get_vertical_mirror(code_);
}
/// Determine whether two cases are horizontally symmetrical to each other.
inline bool RawCode::is_horizontal_mirror(RawCode raw_code) const noexcept {
return raw_code.code_ == get_horizontal_mirror(code_);
}
} // namespace codec
} // namespace klotski

42
src/core/raw_code/mirror.cc

@ -4,35 +4,7 @@
namespace klotski {
namespace codec {
/// ----------------------------- Mirror Convert ------------------------------
RawCode RawCode::to_vertical_mirror() const noexcept {
return RawCode::unsafe_create(get_vertical_mirror(code_));
}
RawCode RawCode::to_horizontal_mirror() const noexcept {
return RawCode::unsafe_create(get_horizontal_mirror(code_));
}
/// ------------------------------ Mirror Check -------------------------------
bool RawCode::is_vertical_mirror() const noexcept {
return check_vertical_mirror(code_);
}
bool RawCode::is_horizontal_mirror() const noexcept {
return check_horizontal_mirror(code_);
}
bool RawCode::is_vertical_mirror(RawCode raw_code) const noexcept {
return raw_code.unwrap() == get_vertical_mirror(code_);
}
bool RawCode::is_horizontal_mirror(RawCode raw_code) const noexcept {
return raw_code.unwrap() == get_horizontal_mirror(code_);
}
/// ----------------------------- Basic Functions -----------------------------
// ----------------------------------------------------------------------------------------- //
/// MASK_MIRROR_H1 | MASK_MIRROR_H2
/// 111 000 000 000 | 000 111 000 000
@ -55,7 +27,9 @@ constexpr uint64_t MASK_MIRROR_V1 = 0x0'000'000'000'000'FFF;
constexpr uint64_t MASK_MIRROR_V2 = 0x0'000'000'000'FFF'000;
constexpr uint64_t MASK_MIRROR_V3 = 0x0'000'000'FFF'000'000;
inline void vertical_fill(uint64_t &raw_code) {
// ----------------------------------------------------------------------------------------- //
inline static void vertical_fill(uint64_t &raw_code) {
uint64_t mask = 0;
for (int addr = 0; addr < 60; addr += 3) { // traverse every 3-bit
switch ((raw_code >> addr) & 0b111) {
@ -76,7 +50,7 @@ inline void vertical_fill(uint64_t &raw_code) {
}
}
inline void horizontal_fill(uint64_t &raw_code) {
inline static void horizontal_fill(uint64_t &raw_code) {
for (int addr = 0; addr < 60; addr += 3) { // traverse every 3-bit
switch ((raw_code >> addr) & 0b111) {
case BLOCK_1x2:
@ -91,7 +65,7 @@ inline void horizontal_fill(uint64_t &raw_code) {
}
}
inline void vertical_clear(uint64_t &raw_code) {
inline static void vertical_clear(uint64_t &raw_code) {
for (int addr = 0; addr < 60; addr += 3) { // traverse every 3-bit
switch ((raw_code >> addr) & 0b111) {
case BLOCK_2x1:
@ -101,7 +75,7 @@ inline void vertical_clear(uint64_t &raw_code) {
}
}
inline void horizontal_clear(uint64_t &raw_code) {
inline static void horizontal_clear(uint64_t &raw_code) {
for (int addr = 0; addr < 60; addr += 3) { // traverse every 3-bit
switch ((raw_code >> addr) & 0b111) {
case BLOCK_1x2:
@ -111,6 +85,8 @@ inline void horizontal_clear(uint64_t &raw_code) {
}
}
// ----------------------------------------------------------------------------------------- //
uint64_t RawCode::get_vertical_mirror(uint64_t raw_code) noexcept {
vertical_fill(raw_code);
raw_code = (raw_code & MASK_MIRROR_V3)

54
src/core/raw_code/raw_code.h

@ -95,53 +95,23 @@ private:
static uint64_t extract(uint64_t common_code) noexcept;
public:
RawCode to_vertical_mirror() const noexcept;
RawCode to_horizontal_mirror() const noexcept;
[[nodiscard]] RawCode to_vertical_mirror() const noexcept;
[[nodiscard]] RawCode to_horizontal_mirror() const noexcept;
bool is_vertical_mirror() const noexcept;
bool is_horizontal_mirror() const noexcept;
bool is_vertical_mirror(RawCode raw_code) const noexcept;
bool is_horizontal_mirror(RawCode raw_code) const noexcept;
[[nodiscard]] bool is_vertical_mirror() const noexcept;
[[nodiscard]] bool is_horizontal_mirror() const noexcept;
[[nodiscard]] bool is_vertical_mirror(RawCode raw_code) const noexcept;
[[nodiscard]] bool is_horizontal_mirror(RawCode raw_code) const noexcept;
private:
static inline bool check_vertical_mirror(uint64_t raw_code) noexcept;
static inline bool check_horizontal_mirror(uint64_t raw_code) noexcept;
static bool check_vertical_mirror(uint64_t raw_code) noexcept;
static bool check_horizontal_mirror(uint64_t raw_code) noexcept;
static inline uint64_t get_vertical_mirror(uint64_t raw_code) noexcept;
static inline uint64_t get_horizontal_mirror(uint64_t raw_code) noexcept;
static uint64_t get_vertical_mirror(uint64_t raw_code) noexcept;
static uint64_t get_horizontal_mirror(uint64_t raw_code) noexcept;
};
/// RawCode compare implements.
inline bool operator==(uint64_t r1, RawCode r2) noexcept {
return r1 == r2.unwrap();
}
inline bool operator==(RawCode r1, RawCode r2) noexcept {
return r1.unwrap() == r2.unwrap();
}
/// Get the original 64-bit code.
inline uint64_t RawCode::unwrap() const noexcept {
return code_;
}
/// Implicit conversion to 64-bit code.
inline RawCode::operator uint64_t() const noexcept {
return code_;
}
/// RawCode create without any check.
inline RawCode RawCode::unsafe_create(uint64_t raw_code) noexcept {
return *reinterpret_cast<RawCode*>(&raw_code); // init directly
}
/// RawCode create with valid check.
inline std::optional<RawCode> RawCode::create(uint64_t raw_code) noexcept {
if (!RawCode::check(raw_code)) {
return std::nullopt;
}
return RawCode::unsafe_create(raw_code);
}
} // namespace codec
} // namespace klotski
#include "inline_impl.h"

81
src/core/short_code/convert.cc

@ -1,76 +1,31 @@
#include <algorithm>
#include "common.h"
#include "short_code.h"
#include "common_code.h"
#include "all_cases.h"
#include "offset/all_cases_offset.h"
#include "offset/basic_ranges_offset.h"
#include "offset/range_prefix_offset.h"
namespace klotski {
namespace codec {
#include "offset/basic.h"
#include "offset/range_prefix.h"
using klotski::cases::AllCases;
using klotski::cases::BasicRanges;
/// ------------------------- ShortCode to CommonCode -------------------------
//CommonCode ShortCode::to_common_code() const noexcept {
// if (ShortCode::mode() == ShortCode::NORMAL) {
// return CommonCode::unsafe_create(tiny_decode(code_)); // normal mode
// }
// return CommonCode::unsafe_create(fast_decode(code_)); // fast mode
//}
/// ------------------------- ShortCode to CommonCode -------------------------
ShortCode::ShortCode(CommonCode common_code) noexcept {
// if (ShortCode::mode() == ShortCode::NORMAL) {
// code_ = tiny_encode(common_code.unwrap()); // normal mode
// } else {
code_ = fast_encode(common_code.unwrap()); // fast mode
// }
}
//ShortCode ShortCode::from_common_code(uint64_t common_code) {
// return ShortCode(CommonCode(common_code));
//}
using klotski::codec::offset::ALL_CASES_OFFSET;
using klotski::codec::offset::BASIC_RANGES_OFFSET;
using klotski::codec::offset::RANGE_PREFIX_OFFSET;
ShortCode ShortCode::from_common_code(CommonCode common_code) noexcept {
return ShortCode(std::forward<CommonCode>(common_code));
}
//ShortCode ShortCode::from_common_code(std::string &&common_code) {
// return ShortCode(std::forward<CommonCode>(
// CommonCode(std::forward<std::string>(common_code))
// ));
//}
//ShortCode ShortCode::from_common_code(const CommonCode &common_code) noexcept {
// return ShortCode(common_code);
//}
//ShortCode ShortCode::from_common_code(const std::string &common_code) {
// return ShortCode(CommonCode(common_code));
//}
/// ----------------------------- Basic Functions -----------------------------
namespace klotski {
namespace codec {
/// NOTE: ensure that input common code is valid!
uint32_t ShortCode::fast_encode(uint64_t common_code) noexcept { // common code --> short code
auto head = common_code >> 32; // head index
const auto &ranges = AllCases::instance().fetch()[head]; // available ranges
auto offset = std::lower_bound(ranges.begin(), ranges.end(), (uint32_t)common_code) - ranges.begin();
return ALL_CASES_OFFSET[head] + offset; // release short code
/// Convert CommonCode to ShortCode based on AllCases data.
uint32_t ShortCode::fast_encode(uint64_t common_code) noexcept {
auto head = common_code >> 32;
auto &ranges = AllCases::instance().fetch()[head]; // match available ranges
auto target = std::lower_bound(ranges.begin(), ranges.end(), (uint32_t)common_code);
return ALL_CASES_OFFSET[head] + (target - ranges.begin());
}
/// NOTE: ensure that input short code is valid!
uint64_t ShortCode::fast_decode(uint32_t short_code) noexcept { // short code --> common code
auto offset = std::upper_bound( // using binary search
ALL_CASES_OFFSET, ALL_CASES_OFFSET + 16, short_code
) - 1;
uint64_t head = offset - ALL_CASES_OFFSET; // head index
return (head << 32) | AllCases::instance().fetch()[head][short_code - *offset]; // release common code
/// Convert ShortCode to CommonCode based on AllCases data.
uint64_t ShortCode::fast_decode(uint32_t short_code) noexcept {
auto offset = std::upper_bound(ALL_CASES_OFFSET, ALL_CASES_OFFSET + 16, short_code) - 1;
uint64_t head = offset - ALL_CASES_OFFSET;
return (head << 32) | AllCases::instance().fetch()[head][short_code - *offset];
}
/// NOTE: ensure that input common code is valid!

56
src/core/short_code/inline_impl.h

@ -0,0 +1,56 @@
#pragma once
namespace klotski {
namespace codec {
/// Get the original 32-bit code.
inline uint32_t ShortCode::unwrap() const noexcept {
return code_;
}
/// Implicit conversion to 32-bit code.
inline ShortCode::operator uint32_t() const noexcept {
return code_;
}
/// Equality comparison between ShortCode and numbers.
inline bool operator==(ShortCode s1, uint32_t s2) noexcept {
return s1.unwrap() == s2;
}
/// ShortCode equal comparison implement.
inline bool operator==(ShortCode s1, ShortCode s2) noexcept {
return s1.unwrap() == s2.unwrap();
}
/// ShortCode less than comparison implement.
inline bool operator<(ShortCode s1, ShortCode s2) noexcept {
return s1.unwrap() < s2.unwrap();
}
/// ShortCode greater than comparison implement.
inline bool operator>(ShortCode s1, ShortCode s2) noexcept {
return s1.unwrap() > s2.unwrap();
}
/// ShortCode create without any check.
inline ShortCode ShortCode::unsafe_create(uint32_t short_code) noexcept {
return *reinterpret_cast<ShortCode*>(&short_code); // init directly
}
/// ShortCode create with valid check.
inline std::optional<ShortCode> ShortCode::create(uint32_t short_code) noexcept {
if (!ShortCode::check(short_code)) {
return std::nullopt; // invalid short code
}
return ShortCode::unsafe_create(short_code);
}
/// Output string encoding of ShortCode.
inline std::ostream& operator<<(std::ostream &out, ShortCode self) {
out << ShortCode::string_encode(self.code_);
return out;
}
} // namespace codec
} // namespace klotski

18
src/core/short_code/offset/all_cases_offset.h

@ -1,18 +0,0 @@
#pragma once
/// This is the head index, the offset (0 ~ 29334498) in all cases is obtained
/// according to the `head` (0 ~ 15). In other words, the short code range can be
/// obtained according to the position of the 2x2 block.
#include <cstdint>
namespace klotski {
const uint32_t ALL_CASES_OFFSET[16] = {
0, 2942906, 5203298, 8146204,
8146204, 10468254, 12345199, 14667249,
14667249, 16989299, 18866244, 21188294,
21188294, 24131200, 26391592, 29334498,
};
} // namespace klotski

25
src/core/short_code/offset/basic_ranges_offset.h → src/core/short_code/offset/basic.h

@ -1,13 +1,28 @@
#pragma once
/// This is the index for basic ranges, and its position (0 ~ 7311920) in all
/// basic ranges is located according to the first 12-bit (0 ~ 4095) of the
/// 32-bit `range`.
#include <cstdint>
namespace klotski {
namespace codec {
namespace offset {
/// This is the head index, the offset [0, 29334498) in all cases is obtained
/// according to the `head` (0 ~ 15). In other words, the short code range can
/// be obtained according to the position of the 2x2 block.
// TODO: using std::array
const uint32_t ALL_CASES_OFFSET[16] = {
0, 2942906, 5203298, 8146204,
8146204, 10468254, 12345199, 14667249,
14667249, 16989299, 18866244, 21188294,
21188294, 24131200, 26391592, 29334498,
};
/// This is the index for basic ranges, and its position (0 ~ 7311920) in all
/// basic ranges is located according to the first 12-bit (0 ~ 4095) within the
/// 32-bit `range`.
// TODO: using std::array
const uint32_t BASIC_RANGES_OFFSET[4096] = {
0, 18272, 24960, 31648, 49920, 56608, 59056, 61504,
68192, 74880, 77328, 79776, 86464, 104736, 111424, 118112,
@ -523,4 +538,6 @@ const uint32_t BASIC_RANGES_OFFSET[4096] = {
7253514, 7259861, 7261646, 7263431, 7268677, 7286266, 7291512, 7296758,
};
} // namespace offset
} // namespace codec
} // namespace klotski

13
src/core/short_code/offset/range_prefix_offset.h → src/core/short_code/offset/range_prefix.h

@ -1,14 +1,17 @@
#pragma once
/// This is the index for the range prefix. Given the `head` and the first
/// 12-bit (0 ~ 4095) of the `range`, you can get the positions of all cases
/// in the current `head`. That is, according to the position of 2x2 block
/// and the `range`, the short code range is obtained.
/// This is the index for the range prefix. Given the case `head` and the first
/// 12-bit (0 ~ 4095) of the `range`, you can get the positions of all cases in
/// the current `head`. That is, according to the position of 2x2 block and the
/// `range`, the short code range is obtained.
#include <cstdint>
namespace klotski {
namespace codec {
namespace offset {
// TODO: using std::array
const uint32_t RANGE_PREFIX_OFFSET[16][4096] = {{
#include "range_prefix/offset_0x0.inc"
}, {
@ -43,4 +46,6 @@ const uint32_t RANGE_PREFIX_OFFSET[16][4096] = {{
/// --------------- 0xF ---------------
}};
} // namespace offset
} // namespace codec
} // namespace klotski

8
src/core/short_code/serialize.cc

@ -4,14 +4,6 @@
namespace klotski {
namespace codec {
/// --------------------------- ShortCode to String ---------------------------
std::string ShortCode::to_string() const noexcept { // encode as 5-bits string
return string_encode(code_);
}
/// ----------------------------- Basic Functions -----------------------------
std::string ShortCode::string_encode(uint32_t short_code) noexcept { // encode as 5-bits string
char result[6]; // short code length 5
result[5] = '\0'; // string ending flag

28
src/core/short_code/serialize_chars.h

@ -1,19 +1,19 @@
#pragma once
/// ShortCode Convert Table
/// -------------------------------------------------
/// | 00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 |
/// | `1` | `2` | `3` | `4` | `5` | `6` | `7` | `8` |
/// |-----------------------------------------------|
/// | 08 | 09 | 10 | 11 | 12 | 13 | 14 | 15 |
/// | `9` | `A` | `B` | `C` | `D` | `E` | `F` | `G` |
/// |-----------------------------------------------|
/// | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
/// | `H` | `J` | `K` | `M` | `N` | `P` | `Q` | `R` |
/// |-----------------------------------------------|
/// | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
/// | `S` | `T` | `U` | `V` | `W` | `X` | `Y` | `Z` |
/// -------------------------------------------------
/// ShortCode Convert Table ///
/// ------------------------------------------------- ///
/// | 00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | ///
/// | `1` | `2` | `3` | `4` | `5` | `6` | `7` | `8` | ///
/// |-----------------------------------------------| ///
/// | 08 | 09 | 10 | 11 | 12 | 13 | 14 | 15 | ///
/// | `9` | `A` | `B` | `C` | `D` | `E` | `F` | `G` | ///
/// |-----------------------------------------------| ///
/// | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | ///
/// | `H` | `J` | `K` | `M` | `N` | `P` | `Q` | `R` | ///
/// |-----------------------------------------------| ///
/// | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | ///
/// | `S` | `T` | `U` | `V` | `W` | `X` | `Y` | `Z` | ///
/// ------------------------------------------------- ///
#include <cstdint>

22
src/core/short_code/short_code.cc

@ -1,23 +1,25 @@
#include "all_cases.h"
#include "short_code.h"
using klotski::cases::AllCases;
using klotski::cases::BasicRanges;
namespace klotski {
namespace codec {
/// Check the validity of the original ShortCode.
bool ShortCode::check(uint32_t short_code) noexcept {
return short_code < SHORT_CODE_LIMIT; // 0 ~ (SHORT_CODE_LIMIT - 1)
}
//ShortCode::Mode ShortCode::mode() { // ensure speed up enabled and return current mode
// if (fast_mode_available_) {
// return ShortCode::FAST; // fast mode already enabled
// }
// if (normal_mode_available_) {
// return ShortCode::NORMAL; // normal mode already enabled
// }
// speed_up(ShortCode::Mode::NORMAL); // uninitialized -> enable normal mode
// return ShortCode::Mode::NORMAL;
//}
void ShortCode::speed_up(bool fast_mode) noexcept {
if (fast_mode) {
AllCases::instance().build();
} else {
BasicRanges::instance().build();
}
// FIXME: setting up `fast_available_`
}
//void ShortCode::speed_up(ShortCode::Mode mode) {
// if (fast_mode_available_) {

48
src/core/short_code/short_code.h

@ -118,51 +118,7 @@ private:
static std::optional<uint32_t> string_decode(const std::string &short_code) noexcept;
};
/// ShortCode compare implements.
inline bool operator==(uint32_t s1, ShortCode s2) noexcept {
return s1 == s2.unwrap();
}
inline bool operator==(ShortCode s1, ShortCode s2) noexcept {
return s1.unwrap() == s2.unwrap();
}
inline bool operator<(ShortCode s1, ShortCode s2) noexcept {
return s1.unwrap() < s2.unwrap();
}
inline bool operator>(ShortCode s1, ShortCode s2) noexcept {
return s1.unwrap() > s2.unwrap();
}
/// Get the original 32-bit code.
inline uint32_t ShortCode::unwrap() const noexcept {
return code_;
}
/// Implicit conversion to 32-bit code.
inline ShortCode::operator uint32_t() const noexcept {
return code_;
}
/// ShortCode create without any check.
inline ShortCode ShortCode::unsafe_create(uint32_t short_code) noexcept {
return *reinterpret_cast<ShortCode*>(&short_code); // init directly
}
/// ShortCode create with valid check.
inline std::optional<ShortCode> ShortCode::create(uint32_t short_code) noexcept {
if (!ShortCode::check(short_code)) {
return std::nullopt;
}
return ShortCode::unsafe_create(short_code);
}
/// Output string encoding of ShortCode.
inline std::ostream& operator<<(std::ostream &out, ShortCode self) {
out << ShortCode::string_encode(self.code_);
return out;
}
} // namespace codec
} // namespace klotski
#include "inline_impl.h"

66
src/core/short_code/sundry.cc

@ -4,20 +4,74 @@
namespace klotski {
namespace codec {
// FIXME: just for compile
// ----------------------------------------------------------------------------------------- //
ShortCode::ShortCode(CommonCode common_code) noexcept {
// if (fast_available_) {
code_ = fast_encode(common_code.unwrap());
// } else {
// code_ = tiny_encode(common_code.unwrap());
// }
}
// ----------------------------------------------------------------------------------------- //
std::string ShortCode::to_string() const noexcept {
return string_encode(code_);
}
CommonCode ShortCode::to_common_code() const noexcept {
return CommonCode::unsafe_create(0);
// if (fast_available_) {
return CommonCode::unsafe_create(fast_decode(code_));
// }
// return CommonCode::unsafe_create(tiny_decode(code_));
}
// FIXME: just for compile
// ----------------------------------------------------------------------------------------- //
std::optional<ShortCode> ShortCode::from_string(std::string &&short_code) noexcept {
return std::nullopt;
return ShortCode::from_string(short_code);
}
// FIXME: just for compile
std::optional<ShortCode> ShortCode::from_string(const std::string &short_code) noexcept {
return std::nullopt;
auto code = ShortCode::string_decode(short_code);
if (!code.has_value()) {
return std::nullopt; // invalid string
}
return ShortCode::unsafe_create(code.value());
}
// ----------------------------------------------------------------------------------------- //
ShortCode ShortCode::from_common_code(CommonCode common_code) noexcept {
return common_code.to_short_code();
}
std::optional<ShortCode> ShortCode::from_common_code(uint64_t common_code) noexcept {
auto code = CommonCode::create(common_code);
if (!code.has_value()) {
return std::nullopt; // invalid common code
}
return code->to_short_code();
}
std::optional<ShortCode> ShortCode::from_common_code(std::string &&common_code) noexcept {
auto code = CommonCode::from_string(std::move(common_code));
if (!code.has_value()) {
return std::nullopt; // invalid common code
}
return code->to_short_code();
}
std::optional<ShortCode> ShortCode::from_common_code(const std::string &common_code) noexcept {
auto code = CommonCode::from_string(common_code);
if (!code.has_value()) {
return std::nullopt; // invalid common code
}
return code->to_short_code();
}
// ----------------------------------------------------------------------------------------- //
} // namespace codec
} // namespace klotski

Loading…
Cancel
Save