From 76099d7069250488d3d064fcb33f6d384535c3d6 Mon Sep 17 00:00:00 2001 From: Dnomd343 Date: Sun, 8 Dec 2024 18:37:20 +0800 Subject: [PATCH] update: add constexpr support of ShortCode --- src/core/CMakeLists.txt | 2 +- src/core/short_code/internal/convert.cc | 15 ----------- src/core/short_code/internal/convert.inl | 22 +++++++++++++++ .../internal/{serialize.cc => serialize.inl} | 14 +++++----- src/core/short_code/internal/short_code.inl | 10 +++---- src/core/short_code/short_code.h | 27 ++++++++----------- 6 files changed, 47 insertions(+), 43 deletions(-) create mode 100644 src/core/short_code/internal/convert.inl rename src/core/short_code/internal/{serialize.cc => serialize.inl} (73%) diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index be0c551..c6c4e22 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -19,7 +19,7 @@ set(KLSK_CORE_SRC # raw_code/internal/mirror.cc short_code/internal/convert.cc - short_code/internal/serialize.cc +# short_code/internal/serialize.cc mover/internal/mover.cc diff --git a/src/core/short_code/internal/convert.cc b/src/core/short_code/internal/convert.cc index 7a43ff2..3daa9c7 100644 --- a/src/core/short_code/internal/convert.cc +++ b/src/core/short_code/internal/convert.cc @@ -50,21 +50,6 @@ static uint32_t check_range(uint32_t head, uint32_t range) noexcept { return 0; // pass check } -uint32_t ShortCode::fast_encode(uint64_t common_code) { - auto head = common_code >> 32; - const auto &ranges = (*cases_).ranges(head); // match available ranges - // TODO: try to narrow the scope by prefix - auto target = std::lower_bound(ranges.begin(), ranges.end(), (uint32_t)common_code); - return ALL_CASES_OFFSET[head] + (target - ranges.begin()); -} - -uint64_t ShortCode::fast_decode(uint32_t short_code) { - auto offset = std::upper_bound(ALL_CASES_OFFSET.begin(), ALL_CASES_OFFSET.end(), short_code) - 1; - uint64_t head = offset - ALL_CASES_OFFSET.begin(); - // return (head << 32) | AllCases::instance().fetch()[head][short_code - *offset]; - return (head << 32) | (*cases_).ranges(head)[short_code - *offset]; -} - uint32_t ShortCode::tiny_encode(uint64_t common_code) { uint32_t head = common_code >> 32; uint32_t prefix = (common_code >> 20) & 0xFFF; diff --git a/src/core/short_code/internal/convert.inl b/src/core/short_code/internal/convert.inl new file mode 100644 index 0000000..651300d --- /dev/null +++ b/src/core/short_code/internal/convert.inl @@ -0,0 +1,22 @@ +#pragma once + +#include + +namespace klotski::codec { + +KLSK_INLINE_H uint32_t ShortCode::fast_encode(uint64_t common_code) { + auto head = common_code >> 32; + const auto &ranges = (*cases_).ranges(head); // match available ranges + // TODO: try to narrow the scope by prefix + auto target = std::lower_bound(ranges.begin(), ranges.end(), (uint32_t)common_code); + return cases::ALL_CASES_OFFSET[head] + (target - ranges.begin()); +} + +KLSK_INLINE_H uint64_t ShortCode::fast_decode(uint32_t short_code) { + auto offset = std::upper_bound(cases::ALL_CASES_OFFSET.begin(), cases::ALL_CASES_OFFSET.end(), short_code) - 1; + uint64_t head = offset - cases::ALL_CASES_OFFSET.begin(); + // return (head << 32) | AllCases::instance().fetch()[head][short_code - *offset]; + return (head << 32) | (*cases_).ranges(head)[short_code - *offset]; +} + +} // namespace klotski::codec diff --git a/src/core/short_code/internal/serialize.cc b/src/core/short_code/internal/serialize.inl similarity index 73% rename from src/core/short_code/internal/serialize.cc rename to src/core/short_code/internal/serialize.inl index 5a666c2..51481f4 100644 --- a/src/core/short_code/internal/serialize.cc +++ b/src/core/short_code/internal/serialize.inl @@ -1,13 +1,13 @@ +#pragma once + #include #include "serialize_chars.h" -#include "short_code/short_code.h" -using klotski::codec::ShortCode; -using klotski::cases::ALL_CASES_NUM_; +namespace klotski::codec { -std::string ShortCode::string_encode(uint32_t short_code) { - KLSK_ASSUME(short_code < ALL_CASES_NUM_); +KLSK_INLINE_H std::string ShortCode::string_encode(uint32_t short_code) { + KLSK_ASSUME(short_code < cases::ALL_CASES_NUM_); std::array arr {}; for (auto &c : arr | std::views::reverse) { c = SHORT_CODE_TABLE[short_code & 0b11111]; // table convert @@ -16,7 +16,7 @@ std::string ShortCode::string_encode(uint32_t short_code) { return {arr.begin(), arr.end()}; } -std::optional ShortCode::string_decode(const std::string_view short_code) { +KLSK_INLINE_H std::optional ShortCode::string_decode(const std::string_view short_code) { if (short_code.length() != 5) { return std::nullopt; // invalid string length } @@ -36,3 +36,5 @@ std::optional ShortCode::string_decode(const std::string_view short_co } return code; // apply convert result } + +} // namespace klotski::codec diff --git a/src/core/short_code/internal/short_code.inl b/src/core/short_code/internal/short_code.inl index a4bf6bb..8edefdf 100644 --- a/src/core/short_code/internal/short_code.inl +++ b/src/core/short_code/internal/short_code.inl @@ -15,11 +15,11 @@ inline ShortCode::ShortCode(const CommonCode common_code) { } } -inline ShortCode ShortCode::unsafe_create(const uint32_t short_code) { +constexpr ShortCode ShortCode::unsafe_create(const uint32_t short_code) { return std::bit_cast(short_code); // init directly } -inline std::optional ShortCode::create(const uint32_t short_code) { +constexpr std::optional ShortCode::create(const uint32_t short_code) { if (!check(short_code)) { return std::nullopt; // invalid short code } @@ -28,11 +28,11 @@ inline std::optional ShortCode::create(const uint32_t short_code) { // ----------------------------------------------------------------------------------------- // -inline ShortCode::operator uint32_t() const { +constexpr ShortCode::operator uint32_t() const { return code_; } -inline bool ShortCode::check(const uint32_t short_code) { +constexpr bool ShortCode::check(const uint32_t short_code) { return short_code < SHORT_CODE_LIMIT; // [0, SHORT_CODE_LIMIT) } @@ -55,7 +55,7 @@ inline std::ostream& operator<<(std::ostream &out, const ShortCode self) { // ----------------------------------------------------------------------------------------- // -inline uint32_t ShortCode::unwrap() const { +constexpr uint32_t ShortCode::unwrap() const { return code_; } diff --git a/src/core/short_code/short_code.h b/src/core/short_code/short_code.h index 72ff239..9499291 100644 --- a/src/core/short_code/short_code.h +++ b/src/core/short_code/short_code.h @@ -66,20 +66,13 @@ #include #include "utils/utility.h" -// #include "all_cases/all_cases.h" - -namespace klotski::cases { -class AllCases; -class Ranges; -class RangesUnion; -} // namespace klotski::cases +#include "ranges/ranges_fwd.h" +#include "all_cases/all_cases_fwd.h" +#include "common_code/common_code_fwd.h" namespace klotski::codec { -constexpr uint32_t SHORT_CODE_LIMIT = 29334498; -// constexpr uint32_t SHORT_CODE_LIMIT = cases::ALL_CASES_NUM_; - -class CommonCode; +constexpr uint32_t SHORT_CODE_LIMIT = cases::ALL_CASES_NUM_; class ShortCode { public: @@ -91,18 +84,18 @@ public: explicit ShortCode(CommonCode common_code); /// Create ShortCode without any check. - static ShortCode unsafe_create(uint32_t short_code); + static constexpr ShortCode unsafe_create(uint32_t short_code); /// Create ShortCode with validity check. - static std::optional create(uint32_t short_code); + static constexpr std::optional create(uint32_t short_code); // ------------------------------------------------------------------------------------- // /// Explicit conversion to u32 code. - explicit operator uint32_t() const; + explicit constexpr operator uint32_t() const; /// Check the validity of the original ShortCode. - static bool check(uint32_t short_code); + static constexpr bool check(uint32_t short_code); /// Build the conversion index for ShortCode. static void speed_up(bool fast_mode = false); @@ -115,7 +108,7 @@ public: // ------------------------------------------------------------------------------------- // /// Get the original u32 code. - [[nodiscard]] uint32_t unwrap() const; + [[nodiscard]] constexpr uint32_t unwrap() const; /// Convert ShortCode to string form. [[nodiscard]] std::string to_string() const; @@ -200,3 +193,5 @@ static_assert(std::is_trivially_copyable_v); } // namespace klotski::codec #include "internal/short_code.inl" +#include "internal/serialize.inl" +#include "internal/convert.inl"