Browse Source

update: using `Layout` instead of `Code`

master
Dnomd343 6 days ago
parent
commit
77d9353b9e
  1. 2
      src/core_ffi/python_ffi/CMakeLists.txt
  2. 6
      src/core_ffi/python_ffi/binder/fast_cal.cc
  3. 4
      src/core_ffi/python_ffi/binder/group.cc
  4. 6
      src/core_ffi/python_ffi/binder/group_union.cc
  5. 33
      src/core_ffi/python_ffi/binder/klsk_code.cc
  6. 12
      src/core_ffi/python_ffi/include/py_ffi/cases.h
  7. 22
      src/core_ffi/python_ffi/include/py_ffi/fast_cal.h
  8. 9
      src/core_ffi/python_ffi/include/py_ffi/group.h
  9. 40
      src/core_ffi/python_ffi/include/py_ffi/layout.h
  10. 10
      src/core_ffi/python_ffi/include/py_ffi/short_code.h
  11. 8
      src/core_ffi/python_ffi/wrapper/cases.cc
  12. 6
      src/core_ffi/python_ffi/wrapper/group_union.cc
  13. 30
      src/core_ffi/python_ffi/wrapper/layout.cc
  14. 12
      src/core_ffi/python_ffi/wrapper/short_code.cc

2
src/core_ffi/python_ffi/CMakeLists.txt

@ -13,7 +13,7 @@ set(KLSK_PYTHON_FFI_SRC
binder/fast_cal.cc
wrapper/short_code.cc
wrapper/common_codec.cc
wrapper/layout.cc
wrapper/cases.cc
wrapper/group_union.cc
wrapper/group.cc

6
src/core_ffi/python_ffi/binder/fast_cal.cc

@ -5,20 +5,20 @@
#include "py_ffi/cases.h"
#include "py_ffi/group.h"
#include "py_ffi/short_code.h"
#include "py_ffi/common_code.h"
#include "py_ffi/layout.h"
#include "py_ffi/fast_cal.h"
using klotski::ffi::PyCases;
using klotski::ffi::PyCasesIter;
using klotski::ffi::PyShortCode;
using klotski::ffi::PyCommonCode;
using klotski::ffi::PyLayout;
using klotski::ffi::PyGroupUnion;
using klotski::ffi::PyGroup;
using klotski::ffi::PyFastCal;
void bind_fast_cal(const py::module_ &m) {
py::class_<PyFastCal>(m, "FastCal")
.def(py::init<PyCommonCode>())
.def(py::init<PyLayout>())
.def("solve", &PyFastCal::solve)
.def("exports", &PyFastCal::exports)
.def("build_all", &PyFastCal::build_all)

4
src/core_ffi/python_ffi/binder/group.cc

@ -3,13 +3,13 @@
#include "py_ffi/cases.h"
#include "py_ffi/group.h"
#include "py_ffi/short_code.h"
#include "py_ffi/common_code.h"
#include "py_ffi/layout.h"
#include "py_ffi/fast_cal.h"
using klotski::ffi::PyCases;
using klotski::ffi::PyCasesIter;
using klotski::ffi::PyShortCode;
using klotski::ffi::PyCommonCode;
using klotski::ffi::PyLayout;
using klotski::ffi::PyGroupUnion;
using klotski::ffi::PyGroup;
using klotski::ffi::PyFastCal;

6
src/core_ffi/python_ffi/binder/group_union.cc

@ -3,13 +3,13 @@
#include "py_ffi/cases.h"
#include "py_ffi/group.h"
#include "py_ffi/short_code.h"
#include "py_ffi/common_code.h"
#include "py_ffi/layout.h"
#include "py_ffi/fast_cal.h"
using klotski::ffi::PyCases;
using klotski::ffi::PyCasesIter;
using klotski::ffi::PyShortCode;
using klotski::ffi::PyCommonCode;
using klotski::ffi::PyLayout;
using klotski::ffi::PyGroupUnion;
using klotski::ffi::PyGroup;
using klotski::ffi::PyFastCal;
@ -20,7 +20,7 @@ void bind_group_union(const py::module_ &m) {
py::class_<PyGroupUnion>(m, "GroupUnion")
.def(py::init<uint8_t>())
.def(py::init<PyShortCode>())
.def(py::init<PyCommonCode>())
.def(py::init<PyLayout>())
// .def(py::hash(py::self))
// .def(py::self == py::self)

33
src/core_ffi/python_ffi/binder/klsk_code.cc

@ -1,14 +1,15 @@
#include <pybind11/stl.h>
#include <pybind11/operators.h>
#include "binder.h"
#include "py_ffi/layout.h"
#include "py_ffi/short_code.h"
#include "py_ffi/common_code.h"
using klotski::ffi::PyLayout;
using klotski::ffi::PyShortCode;
using klotski::ffi::PyCommonCode;
static void bind_common_code(const py::module_ &mod) {
py::class_<PyCommonCode>(mod, "Code")
static void bind_layout(const py::module_ &mod) {
py::class_<PyLayout>(mod, "Layout")
.def(py::init<uint64_t>())
.def(py::init<PyShortCode>())
.def(py::init<std::string_view>())
@ -21,27 +22,27 @@ static void bind_common_code(const py::module_ &mod) {
.def(py::self > uint64_t()).def(py::self >= uint64_t())
.def(py::hash(py::self))
.def("__str__", &PyCommonCode::str)
.def("__int__", &PyCommonCode::value)
.def("__repr__", &PyCommonCode::repr)
.def("__str__", &PyLayout::str)
.def("__int__", &PyLayout::value)
.def("__repr__", &PyLayout::repr)
.def("next_cases", &PyCommonCode::next_cases)
.def("next_cases", &PyLayout::next_cases)
// TODO: add fast_cal / fast_cal_multi / ...
.def("to_short_code", &PyCommonCode::short_code)
.def("to_string", &PyCommonCode::string, py::arg("shorten") = false)
.def("to_short_code", &PyLayout::short_code)
.def("to_string", &PyLayout::string, py::arg("shorten") = false)
.def_property_readonly("value", &PyCommonCode::value)
.def_property_readonly("value", &PyLayout::value)
// TODO: add n_1x1 / n_1x2 / n_2x1 / ...
.def_static("check", py::overload_cast<uint64_t>(&PyCommonCode::check))
.def_static("check", py::overload_cast<std::string_view>(&PyCommonCode::check));
.def_static("check", py::overload_cast<uint64_t>(&PyLayout::check))
.def_static("check", py::overload_cast<std::string_view>(&PyLayout::check));
}
static void bind_short_code(const py::module_ &mod) {
py::class_<PyShortCode>(mod, "ShortCode")
.def(py::init<uint32_t>())
.def(py::init<PyCommonCode>())
.def(py::init<PyLayout>())
.def(py::init<std::string_view>())
.def(py::self == py::self)
@ -58,7 +59,7 @@ static void bind_short_code(const py::module_ &mod) {
.def_property_readonly("value", &PyShortCode::value)
.def("to_common_code", &PyShortCode::common_code)
.def("to_layout", &PyShortCode::layout)
.def_static("check", py::overload_cast<uint32_t>(&PyShortCode::check))
.def_static("check", py::overload_cast<std::string_view>(&PyShortCode::check))
@ -67,6 +68,6 @@ static void bind_short_code(const py::module_ &mod) {
}
void bind_klsk_code(const py::module_ &mod) {
bind_layout(mod);
bind_short_code(mod);
bind_common_code(mod);
}

12
src/core_ffi/python_ffi/include/py_ffi/cases.h

@ -5,7 +5,7 @@
#include <variant>
#include <ranges/ranges.h>
#include "py_ffi/common_code.h"
#include "py_ffi/layout.h"
namespace klotski::ffi {
@ -17,7 +17,7 @@ public:
explicit PyCasesIter(const RangesUnion &data) noexcept;
/// Get the next CommonCode or throw `stop_iteration` exception.
PyCommonCode next();
PyLayout next();
private:
size_t index_ {0};
@ -25,12 +25,12 @@ private:
const RangesUnion &data_;
};
// TODO: add `copy` and `pickle` support
class PyCases {
public:
PyCases() = delete;
// TODO: add pickle support
// ------------------------------------------------------------------------------------- //
/// Constructing from r-value.
@ -48,7 +48,9 @@ public:
[[nodiscard]] PyCasesIter iter() const noexcept;
/// Get the CommonCode of the specified index.
[[nodiscard]] PyCommonCode at(int32_t index) const;
[[nodiscard]] PyLayout at(int32_t index) const;
// TODO: add `contain` interface
// ------------------------------------------------------------------------------------- //

22
src/core_ffi/python_ffi/include/py_ffi/fast_cal.h

@ -4,7 +4,7 @@
#include <fast_cal/fast_cal.h>
#include "py_ffi/common_code.h"
#include "py_ffi/layout.h"
namespace klotski::ffi {
@ -12,14 +12,14 @@ using fast_cal::FastCal;
class PyFastCal {
public:
explicit PyFastCal(PyCommonCode code)
explicit PyFastCal(PyLayout code)
: fast_cal_(FastCal(std::bit_cast<codec::CommonCode>(code).to_raw_code())) {}
// TODO: export solution path directly
std::optional<PyCommonCode> solve() {
std::optional<PyLayout> solve() {
auto tmp = fast_cal_.solve();
if (tmp.has_value()) {
return std::bit_cast<PyCommonCode>(tmp.value().to_common_code());
return std::bit_cast<PyLayout>(tmp.value().to_common_code());
}
return std::nullopt;
}
@ -30,24 +30,24 @@ public:
fast_cal_.build_all();
}
[[nodiscard]] std::vector<PyCommonCode> backtrack(PyCommonCode code) const {
std::vector<PyCommonCode> path;
[[nodiscard]] std::vector<PyLayout> backtrack(PyLayout code) const {
std::vector<PyLayout> path;
for (auto x : fast_cal_.backtrack(std::bit_cast<codec::CommonCode>(code).to_raw_code())) {
path.emplace_back(std::bit_cast<PyCommonCode>(x.to_common_code()));
path.emplace_back(std::bit_cast<PyLayout>(x.to_common_code()));
}
return path;
}
[[nodiscard]] std::vector<std::vector<PyCommonCode>> exports() const {
std::vector<std::vector<PyCommonCode>> result;
[[nodiscard]] std::vector<std::vector<PyLayout>> exports() const {
std::vector<std::vector<PyLayout>> result;
const auto data = fast_cal_.exports();
result.reserve(data.size());
for (const auto &layer_raw : data) {
std::vector<PyCommonCode> layer;
std::vector<PyLayout> layer;
layer.reserve(layer_raw.size());
for (auto x : layer_raw) {
layer.emplace_back(std::bit_cast<PyCommonCode>(x.to_common_code()));
layer.emplace_back(std::bit_cast<PyLayout>(x.to_common_code()));
}
result.emplace_back(layer);
}

9
src/core_ffi/python_ffi/include/py_ffi/group.h

@ -7,7 +7,8 @@
#include <group/group.h>
#include "py_ffi/cases.h"
#include "py_ffi/common_code.h"
#include "py_ffi/layout.h"
#include "py_ffi/short_code.h"
namespace klotski::ffi {
@ -44,9 +45,9 @@ private:
class PyGroupUnion {
public:
PyGroupUnion(uint8_t type_id);
PyGroupUnion(PyShortCode short_code);
PyGroupUnion(PyCommonCode common_code);
explicit PyGroupUnion(uint8_t type_id);
explicit PyGroupUnion(PyLayout layout);
explicit PyGroupUnion(PyShortCode short_code);
[[nodiscard]] uint32_t value() const;

40
src/core_ffi/python_ffi/include/py_ffi/common_code.h → src/core_ffi/python_ffi/include/py_ffi/layout.h

@ -7,24 +7,24 @@
#include "py_ffi/short_code.h"
// TODO: maybe using `PyLayout` instead of `PyCommonCode`
// TODO: add `copy` and `pickle` support
namespace klotski::ffi {
class PyCommonCode {
class PyLayout {
public:
PyCommonCode() = delete;
PyLayout() = delete;
// ------------------------------------------------------------------------------------- //
/// Construct from origin u64 value.
explicit PyCommonCode(uint64_t code);
explicit PyLayout(uint64_t code);
/// Construct from origin string form.
explicit PyCommonCode(std::string_view code);
explicit PyLayout(std::string_view code);
/// Construct from PyShortCode object.
explicit PyCommonCode(PyShortCode code) noexcept;
explicit PyLayout(PyShortCode code) noexcept;
// ------------------------------------------------------------------------------------- //
@ -39,23 +39,23 @@ public:
/// Get original value.
[[nodiscard]] uint64_t value() const noexcept;
/// Convert CommonCode as ShortCode.
/// Convert Layout as ShortCode.
[[nodiscard]] PyShortCode short_code() const noexcept;
/// Convert CommonCode as string form.
/// Convert Layout as string form.
[[nodiscard]] std::string string(bool shorten) const noexcept;
// ------------------------------------------------------------------------------------- //
/// Wrapper of `__str__` method in Python.
static std::string str(PyCommonCode code) noexcept;
static std::string str(PyLayout code) noexcept;
/// Wrapper of `__repr__` method in Python.
static std::string repr(PyCommonCode code) noexcept;
static std::string repr(PyLayout code) noexcept;
// ------------------------------------------------------------------------------------- //
[[nodiscard]] std::vector<PyCommonCode> next_cases() const noexcept;
[[nodiscard]] std::vector<PyLayout> next_cases() const noexcept;
// ------------------------------------------------------------------------------------- //
@ -63,24 +63,24 @@ private:
codec::CommonCode code_;
};
static_assert(std::is_trivially_copyable_v<PyCommonCode>);
static_assert(sizeof(PyCommonCode) == sizeof(codec::CommonCode));
static_assert(std::is_trivially_copyable_v<PyLayout>);
static_assert(sizeof(PyLayout) == sizeof(codec::CommonCode));
// ----------------------------------------------------------------------------------------- //
constexpr auto operator==(const PyCommonCode &lhs, const uint64_t rhs) {
constexpr auto operator==(const PyLayout &lhs, const uint64_t rhs) {
return lhs.value() == rhs;
}
constexpr auto operator<=>(const PyCommonCode &lhs, const uint64_t rhs) {
constexpr auto operator<=>(const PyLayout &lhs, const uint64_t rhs) {
return lhs.value() <=> rhs;
}
constexpr auto operator==(const PyCommonCode &lhs, const PyCommonCode &rhs) {
constexpr auto operator==(const PyLayout &lhs, const PyLayout &rhs) {
return lhs.value() == rhs.value();
}
constexpr auto operator<=>(const PyCommonCode &lhs, const PyCommonCode &rhs) {
constexpr auto operator<=>(const PyLayout &lhs, const PyLayout &rhs) {
return lhs.value() <=> rhs.value();
}
@ -89,8 +89,8 @@ constexpr auto operator<=>(const PyCommonCode &lhs, const PyCommonCode &rhs) {
} // namespace klotski::ffi
template <>
struct std::hash<klotski::ffi::PyCommonCode> {
size_t operator()(const klotski::ffi::PyCommonCode &code) const noexcept {
return std::hash<uint64_t>{}(code.value());
struct std::hash<klotski::ffi::PyLayout> {
size_t operator()(const klotski::ffi::PyLayout &layout) const noexcept {
return std::hash<uint64_t>{}(layout.value());
}
};

10
src/core_ffi/python_ffi/include/py_ffi/short_code.h

@ -6,7 +6,7 @@
namespace klotski::ffi {
class PyCommonCode;
class PyLayout;
class PyShortCode {
public:
@ -20,8 +20,8 @@ public:
/// Construct from origin string form.
explicit PyShortCode(std::string_view code);
/// Construct from PyCommonCode object.
explicit PyShortCode(PyCommonCode code) noexcept;
/// Construct from PyLayout object.
explicit PyShortCode(PyLayout code) noexcept;
// ------------------------------------------------------------------------------------- //
@ -36,8 +36,8 @@ public:
/// Get original value.
[[nodiscard]] uint32_t value() const noexcept;
/// Convert ShortCode as CommonCode.
[[nodiscard]] PyCommonCode common_code() const noexcept;
/// Convert ShortCode as Layout.
[[nodiscard]] PyLayout layout() const noexcept;
// ------------------------------------------------------------------------------------- //

8
src/core_ffi/python_ffi/wrapper/cases.cc

@ -12,10 +12,10 @@ using klotski::cases::AllCases;
PyCasesIter::PyCasesIter(const RangesUnion &data) noexcept : data_(data) {}
PyCommonCode PyCasesIter::next() {
PyLayout PyCasesIter::next() {
while (head_ < 16) {
if (const auto &ranges = data_.ranges(head_); index_ < ranges.size()) {
return std::bit_cast<PyCommonCode>((head_ << 32) | ranges[index_++]);
return std::bit_cast<PyLayout>((head_ << 32) | ranges[index_++]);
}
index_ = 0, ++head_;
}
@ -32,13 +32,13 @@ PyCasesIter PyCases::iter() const noexcept {
return PyCasesIter(data_ref());
}
PyCommonCode PyCases::at(const int32_t index) const {
PyLayout PyCases::at(const int32_t index) const {
const auto size_ = static_cast<int32_t>(size());
if (index >= size_ || index < -size_) {
throw py::index_error("cases index out of range");
}
const auto code = data_ref()[index < 0 ? index + size_ : index];
return std::bit_cast<PyCommonCode>(code);
return std::bit_cast<PyLayout>(code);
}
// ----------------------------------------------------------------------------------------- //

6
src/core_ffi/python_ffi/wrapper/group_union.cc

@ -11,7 +11,7 @@ using klotski::ffi::PyGroupUnion;
static klotski::group::GroupUnion convert(uint8_t type_id) {
auto group_union = klotski::group::GroupUnion::create(type_id);
if (!group_union.has_value()) {
throw PyExc_GroupError(std::format("invalid type id -> {}", type_id));
throw PyExc_GroupError(std::format("invalid type id: {}", type_id));
}
return group_union.value();
}
@ -22,8 +22,8 @@ PyGroupUnion::PyGroupUnion(const uint8_t type_id) :
PyGroupUnion::PyGroupUnion(const PyShortCode short_code) :
group_union_(GroupUnion::from_short_code(std::bit_cast<ShortCode>(short_code))) {}
PyGroupUnion::PyGroupUnion(const PyCommonCode common_code) :
group_union_(GroupUnion::from_common_code(std::bit_cast<CommonCode>(common_code))) {}
PyGroupUnion::PyGroupUnion(const PyLayout layout) :
group_union_(GroupUnion::from_common_code(std::bit_cast<CommonCode>(layout))) {}
uint32_t PyGroupUnion::value() const {
return group_union_.unwrap();

30
src/core_ffi/python_ffi/wrapper/common_codec.cc → src/core_ffi/python_ffi/wrapper/layout.cc

@ -1,7 +1,7 @@
#include <format>
#include "exception.h"
#include "py_ffi/common_code.h"
#include "py_ffi/layout.h"
using namespace klotski::ffi;
using klotski::codec::ShortCode;
@ -9,34 +9,34 @@ using klotski::codec::CommonCode;
// ----------------------------------------------------------------------------------------- //
uint64_t PyCommonCode::value() const noexcept {
uint64_t PyLayout::value() const noexcept {
return code_.unwrap();
}
std::string PyCommonCode::string(const bool shorten) const noexcept {
std::string PyLayout::string(const bool shorten) const noexcept {
return code_.to_string(shorten);
}
PyShortCode PyCommonCode::short_code() const noexcept {
PyShortCode PyLayout::short_code() const noexcept {
return std::bit_cast<PyShortCode>(code_.to_short_code());
}
// ----------------------------------------------------------------------------------------- //
bool PyCommonCode::check(const uint64_t code) noexcept {
bool PyLayout::check(const uint64_t code) noexcept {
return CommonCode::check(code);
}
bool PyCommonCode::check(const std::string_view code) noexcept {
bool PyLayout::check(const std::string_view code) noexcept {
return CommonCode::from_string(code).has_value();
}
// ----------------------------------------------------------------------------------------- //
[[nodiscard]] std::vector<PyCommonCode> PyCommonCode::next_cases() const noexcept {
std::vector<PyCommonCode> cases;
[[nodiscard]] std::vector<PyLayout> PyLayout::next_cases() const noexcept {
std::vector<PyLayout> cases;
auto mover = mover::MaskMover([&cases](const codec::RawCode code, uint64_t) {
cases.emplace_back(std::bit_cast<PyCommonCode>(code.to_common_code()));
cases.emplace_back(std::bit_cast<PyLayout>(code.to_common_code()));
});
mover.next_cases(code_.to_raw_code(), 0);
return cases;
@ -44,12 +44,12 @@ bool PyCommonCode::check(const std::string_view code) noexcept {
// ----------------------------------------------------------------------------------------- //
std::string PyCommonCode::str(const PyCommonCode code) noexcept {
std::string PyLayout::str(const PyLayout code) noexcept {
return code.code_.to_string();
}
std::string PyCommonCode::repr(const PyCommonCode code) noexcept {
return std::format("<klotski.Code 0x{}>", str(code));
std::string PyLayout::repr(const PyLayout code) noexcept {
return std::format("<klotski.Layout 0x{}>", str(code));
}
// ----------------------------------------------------------------------------------------- //
@ -72,8 +72,8 @@ static CommonCode convert(const std::string_view code) {
throw PyExc_CodecError(std::format("invalid code: `{}`", code));
}
PyCommonCode::PyCommonCode(const uint64_t code) : code_(convert(code)) {}
PyCommonCode::PyCommonCode(const std::string_view code) : code_(convert(code)) {}
PyCommonCode::PyCommonCode(const PyShortCode code) noexcept : code_(convert(code)) {}
PyLayout::PyLayout(const uint64_t code) : code_(convert(code)) {}
PyLayout::PyLayout(const std::string_view code) : code_(convert(code)) {}
PyLayout::PyLayout(const PyShortCode code) noexcept : code_(convert(code)) {}
// ----------------------------------------------------------------------------------------- //

12
src/core_ffi/python_ffi/wrapper/short_code.cc

@ -1,8 +1,8 @@
#include <format>
#include "exception.h"
#include "py_ffi/layout.h"
#include "py_ffi/short_code.h"
#include "py_ffi/common_code.h"
using namespace klotski::ffi;
using klotski::codec::ShortCode;
@ -14,8 +14,8 @@ uint32_t PyShortCode::value() const noexcept {
return code_.unwrap();
}
PyCommonCode PyShortCode::common_code() const noexcept {
return std::bit_cast<PyCommonCode>(code_.to_common_code());
PyLayout PyShortCode::layout() const noexcept {
return std::bit_cast<PyLayout>(code_.to_common_code());
}
// ----------------------------------------------------------------------------------------- //
@ -40,8 +40,8 @@ std::string PyShortCode::repr(const PyShortCode code) noexcept {
// ----------------------------------------------------------------------------------------- //
static ShortCode convert(const PyCommonCode code) noexcept {
return std::bit_cast<CommonCode>(code).to_short_code();
static ShortCode convert(const PyLayout layout) noexcept {
return std::bit_cast<CommonCode>(layout).to_short_code();
}
static ShortCode convert(const uint32_t code) {
@ -60,6 +60,6 @@ static ShortCode convert(const std::string_view code) {
PyShortCode::PyShortCode(const uint32_t code) : code_(convert(code)) {}
PyShortCode::PyShortCode(const std::string_view code) : code_(convert(code)) {}
PyShortCode::PyShortCode(const PyCommonCode code) noexcept : code_(convert(code)) {}
PyShortCode::PyShortCode(const PyLayout code) noexcept : code_(convert(code)) {}
// ----------------------------------------------------------------------------------------- //

Loading…
Cancel
Save