Browse Source

refactor: project structure of python ffi

master
Dnomd343 4 weeks ago
parent
commit
fe307fd519
  1. 11
      src/core_ffi/CMakeLists.txt
  2. 7
      src/core_ffi/py_ffi/binder.cc
  3. 2
      src/core_ffi/py_ffi/include/py_cases.h
  4. 135
      src/core_ffi/py_ffi/include/py_codec.h
  5. 97
      src/core_ffi/py_ffi/include/py_common_code.h
  6. 24
      src/core_ffi/py_ffi/include/py_exception.h
  7. 2
      src/core_ffi/py_ffi/include/py_group.h
  8. 99
      src/core_ffi/py_ffi/include/py_short_code.h
  9. 38
      src/core_ffi/py_ffi/wrapper/common_codec.cc
  10. 0
      src/core_ffi/py_ffi/wrapper/py_cases.cc
  11. 0
      src/core_ffi/py_ffi/wrapper/py_group.cc
  12. 0
      src/core_ffi/py_ffi/wrapper/py_group_union.cc
  13. 38
      src/core_ffi/py_ffi/wrapper/short_code.cc

11
src/core_ffi/CMakeLists.txt

@ -13,13 +13,14 @@ endif()
if (KLSK_PYTHON_FFI)
pybind11_add_module(klotski_py
py_ffi/binder.cc
py_ffi/codec/short_code.cc
py_ffi/codec/common_codec.cc
py_ffi/py_cases.cc
py_ffi/py_group_union.cc
py_ffi/py_group.cc
py_ffi/wrapper/short_code.cc
py_ffi/wrapper/common_codec.cc
py_ffi/wrapper/py_cases.cc
py_ffi/wrapper/py_group_union.cc
py_ffi/wrapper/py_group.cc
)
target_include_directories(klotski_py PRIVATE py_ffi/include)
target_include_directories(klotski_py PRIVATE py_ffi)
target_link_libraries(klotski_py PRIVATE klotski::core)
set_target_properties(klotski_py PROPERTIES OUTPUT_NAME klotski)
endif()

7
src/core_ffi/py_ffi/binder.cc

@ -3,7 +3,8 @@
#include <pybind11/stl.h>
#include "py_exps.h"
#include "py_codec.h"
#include "py_common_code.h"
#include "py_short_code.h"
#include "py_cases.h"
#include "py_group.h"
@ -38,10 +39,12 @@ void bind_common_code(const py::module_ &m) {
.def(py::self < uint64_t()).def(py::self <= uint64_t())
.def(py::self > uint64_t()).def(py::self >= uint64_t())
.def_property_readonly("str", &PyCommonCode::string)
// .def_property_readonly("str", &PyCommonCode::string)
.def_property_readonly("value", &PyCommonCode::value)
.def_property_readonly("short_code", &PyCommonCode::short_code)
.def("to_string", &PyCommonCode::string, py::arg("shorten") = false)
.def_static("check", static_cast<bool (*)(uint64_t)>(&PyCommonCode::check))
.def_static("check", static_cast<bool (*)(std::string_view)>(&PyCommonCode::check));
}

2
src/core_ffi/py_ffi/include/py_cases.h

@ -8,7 +8,7 @@
#include "ranges/ranges.h"
#include "py_codec.h"
#include "py_common_code.h"
namespace klotski::ffi {

135
src/core_ffi/py_ffi/include/py_codec.h

@ -1,135 +0,0 @@
#pragma once
#include "short_code/short_code.h"
#include "common_code/common_code.h"
namespace klotski::ffi {
using codec::ShortCode;
using codec::CommonCode;
class PyCommonCode;
// ----------------------------------------------------------------------------------------- //
class PyShortCode {
public:
explicit PyShortCode(uint32_t code);
explicit PyShortCode(PyCommonCode code);
explicit PyShortCode(std::string_view code);
/// Get original value.
[[nodiscard]] uint32_t value() const;
/// Convert ShortCode to CommonCode.
[[nodiscard]] PyCommonCode common_code() const;
/// Verify ShortCode in u32 form.
static bool check(uint32_t code);
/// Verify ShortCode in string form.
static bool check(std::string_view code);
/// Build conversion index for ShortCode.
static void speed_up(bool fast_mode);
/// Wrapper of `__str__` method in Python.
static std::string str(PyShortCode code);
/// Wrapper of `__repr__` method in Python.
static std::string repr(PyShortCode code);
private:
ShortCode code_;
};
// ----------------------------------------------------------------------------------------- //
constexpr auto operator==(const PyShortCode &lhs, const uint32_t rhs) {
return lhs.value() == rhs;
}
constexpr auto operator<=>(const PyShortCode &lhs, const uint32_t rhs) {
return lhs.value() <=> rhs;
}
constexpr auto operator==(const PyShortCode &lhs, const PyShortCode &rhs) {
return lhs.value() == rhs.value();
}
constexpr auto operator<=>(const PyShortCode &lhs, const PyShortCode &rhs) {
return lhs.value() <=> rhs.value();
}
// ----------------------------------------------------------------------------------------- //
class PyCommonCode {
public:
explicit PyCommonCode(uint64_t code);
explicit PyCommonCode(PyShortCode code);
explicit PyCommonCode(std::string_view code);
/// Get original value.
[[nodiscard]] uint64_t value() const;
/// Convert as shorten string form.
[[nodiscard]] std::string string() const;
/// Convert CommonCode to ShortCode.
[[nodiscard]] PyShortCode short_code() const;
/// Verify CommonCode in u64 form.
static bool check(uint64_t code);
/// Verify CommonCode in string form.
static bool check(std::string_view code);
/// Wrapper of `__str__` method in Python.
static std::string str(PyCommonCode code);
/// Wrapper of `__repr__` method in Python.
static std::string repr(PyCommonCode code);
private:
CommonCode code_;
};
// ----------------------------------------------------------------------------------------- //
constexpr auto operator==(const PyCommonCode &lhs, const uint64_t rhs) {
return lhs.value() == rhs;
}
constexpr auto operator<=>(const PyCommonCode &lhs, const uint64_t rhs) {
return lhs.value() <=> rhs;
}
constexpr auto operator==(const PyCommonCode &lhs, const PyCommonCode &rhs) {
return lhs.value() == rhs.value();
}
constexpr auto operator<=>(const PyCommonCode &lhs, const PyCommonCode &rhs) {
return lhs.value() <=> rhs.value();
}
// ----------------------------------------------------------------------------------------- //
} // namespace klotski::ffi
// ----------------------------------------------------------------------------------------- //
template<>
struct std::hash<klotski::ffi::PyShortCode> {
size_t operator()(const klotski::ffi::PyShortCode &short_code) const noexcept {
return std::hash<uint32_t>()(short_code.value());
}
};
template<>
struct std::hash<klotski::ffi::PyCommonCode> {
size_t operator()(const klotski::ffi::PyCommonCode &common_code) const noexcept {
return std::hash<uint64_t>()(common_code.value());
}
};
// ----------------------------------------------------------------------------------------- //

97
src/core_ffi/py_ffi/include/py_common_code.h

@ -0,0 +1,97 @@
/// Klotski Engine Python FFI by Dnomd343 @2024
#pragma once
#include "py_short_code.h"
#include "common_code/common_code.h"
namespace klotski::ffi {
using codec::CommonCode;
class PyShortCode;
class PyCommonCode {
public:
PyCommonCode() = delete;
// ------------------------------------------------------------------------------------- //
/// Construct from origin u64 value.
explicit PyCommonCode(uint64_t code);
/// Construct from origin string form.
explicit PyCommonCode(std::string_view code);
/// Construct from PyShortCode object.
explicit PyCommonCode(PyShortCode code) noexcept;
// ------------------------------------------------------------------------------------- //
/// Verify CommonCode in u64 form.
static bool check(uint64_t code) noexcept;
/// Verify CommonCode in string form.
static bool check(std::string_view code) noexcept;
// ------------------------------------------------------------------------------------- //
/// Get original value.
[[nodiscard]] uint64_t value() const noexcept;
/// Convert CommonCode as ShortCode.
[[nodiscard]] PyShortCode short_code() const noexcept;
/// Convert CommonCode as string form.
[[nodiscard]] std::string string(bool shorten) const noexcept;
// ------------------------------------------------------------------------------------- //
/// Wrapper of `__str__` method in Python.
static std::string str(PyCommonCode code) noexcept;
/// Wrapper of `__repr__` method in Python.
static std::string repr(PyCommonCode code) noexcept;
// ------------------------------------------------------------------------------------- //
private:
CommonCode code_;
};
// ----------------------------------------------------------------------------------------- //
constexpr auto operator==(const PyCommonCode &lhs, const uint64_t rhs) {
return lhs.value() == rhs;
}
constexpr auto operator<=>(const PyCommonCode &lhs, const uint64_t rhs) {
return lhs.value() <=> rhs;
}
constexpr auto operator==(const PyCommonCode &lhs, const PyCommonCode &rhs) {
return lhs.value() == rhs.value();
}
constexpr auto operator<=>(const PyCommonCode &lhs, const PyCommonCode &rhs) {
return lhs.value() <=> rhs.value();
}
// ----------------------------------------------------------------------------------------- //
} // namespace klotski::ffi
// ----------------------------------------------------------------------------------------- //
namespace std {
template<>
struct std::hash<klotski::ffi::PyCommonCode> {
size_t operator()(const klotski::ffi::PyCommonCode &common_code) const noexcept {
return std::hash<uint64_t>{}(common_code.value());
}
};
} // namespace std
// ----------------------------------------------------------------------------------------- //

24
src/core_ffi/py_ffi/include/py_exception.h

@ -0,0 +1,24 @@
/// Klotski Engine Python FFI by Dnomd343 @2024
#pragma once
#include <string>
#include <exception>
namespace klotski::ffi {
class PyExc_CodecError final : std::exception {
public:
explicit PyExc_CodecError(const std::string_view &msg) : msg_(msg) {}
~PyExc_CodecError() override = default;
[[nodiscard]] const char* what() const noexcept override {
return msg_.c_str();
}
private:
std::string msg_;
};
} // namespace klotski::ffi

2
src/core_ffi/py_ffi/include/py_group.h

@ -9,7 +9,7 @@
#include "py_cases.h"
#include "py_codec.h"
#include "py_common_code.h"
namespace klotski::ffi {

99
src/core_ffi/py_ffi/include/py_short_code.h

@ -0,0 +1,99 @@
/// Klotski Engine Python FFI by Dnomd343 @2024
#pragma once
#include "py_common_code.h"
#include "short_code/short_code.h"
namespace klotski::ffi {
using codec::ShortCode;
class PyCommonCode;
class PyShortCode {
public:
PyShortCode() = delete;
// ------------------------------------------------------------------------------------- //
/// Construct from origin u32 value.
explicit PyShortCode(uint32_t code);
/// Construct from origin string form.
explicit PyShortCode(std::string_view code);
/// Construct from PyCommonCode object.
explicit PyShortCode(PyCommonCode code) noexcept;
// ------------------------------------------------------------------------------------- //
/// Verify ShortCode in u32 form.
static bool check(uint32_t code) noexcept;
/// Verify ShortCode in string form.
static bool check(std::string_view code) noexcept;
// ------------------------------------------------------------------------------------- //
/// Get original value.
[[nodiscard]] uint32_t value() const noexcept;
/// Convert ShortCode as CommonCode.
[[nodiscard]] PyCommonCode common_code() const noexcept;
// ------------------------------------------------------------------------------------- //
/// Wrapper of `__str__` method in Python.
static std::string str(PyShortCode code) noexcept;
/// Wrapper of `__repr__` method in Python.
static std::string repr(PyShortCode code) noexcept;
// ------------------------------------------------------------------------------------- //
/// Build conversion index for ShortCode.
static void speed_up(bool fast_mode) { // TODO: move to `SpeedUp`
ShortCode::speed_up(fast_mode);
}
private:
ShortCode code_;
};
// ----------------------------------------------------------------------------------------- //
constexpr auto operator==(const PyShortCode &lhs, const uint32_t rhs) {
return lhs.value() == rhs;
}
constexpr auto operator<=>(const PyShortCode &lhs, const uint32_t rhs) {
return lhs.value() <=> rhs;
}
constexpr auto operator==(const PyShortCode &lhs, const PyShortCode &rhs) {
return lhs.value() == rhs.value();
}
constexpr auto operator<=>(const PyShortCode &lhs, const PyShortCode &rhs) {
return lhs.value() <=> rhs.value();
}
// ----------------------------------------------------------------------------------------- //
} // namespace klotski::ffi
// ----------------------------------------------------------------------------------------- //
namespace std {
template<>
struct std::hash<klotski::ffi::PyShortCode> {
size_t operator()(const klotski::ffi::PyShortCode &short_code) const noexcept {
return std::hash<uint32_t>{}(short_code.value());
}
};
}
// ----------------------------------------------------------------------------------------- //

38
src/core_ffi/py_ffi/codec/common_codec.cc → src/core_ffi/py_ffi/wrapper/common_codec.cc

@ -1,53 +1,47 @@
#include <format>
#include "py_exps.h"
#include "py_codec.h"
#include "include/py_exception.h"
#include "include/py_common_code.h"
using klotski::ffi::PyCodecExp;
using klotski::ffi::PyShortCode;
using klotski::ffi::PyCommonCode;
using klotski::codec::ShortCode;
using klotski::codec::CommonCode;
using namespace klotski::ffi;
// ----------------------------------------------------------------------------------------- //
uint64_t PyCommonCode::value() const {
uint64_t PyCommonCode::value() const noexcept {
return code_.unwrap();
}
std::string PyCommonCode::string() const {
return code_.to_string(true);
std::string PyCommonCode::string(bool shorten) const noexcept {
return code_.to_string(shorten);
}
PyShortCode PyCommonCode::short_code() const {
PyShortCode PyCommonCode::short_code() const noexcept {
return std::bit_cast<PyShortCode>(code_.to_short_code());
}
// ----------------------------------------------------------------------------------------- //
bool PyCommonCode::check(const uint64_t code) {
bool PyCommonCode::check(const uint64_t code) noexcept {
return CommonCode::check(code);
}
bool PyCommonCode::check(const std::string_view code) {
bool PyCommonCode::check(const std::string_view code) noexcept {
return CommonCode::from_string(code).has_value();
}
// ----------------------------------------------------------------------------------------- //
std::string PyCommonCode::str(const PyCommonCode code) {
std::string PyCommonCode::str(const PyCommonCode code) noexcept {
return code.code_.to_string();
}
std::string PyCommonCode::repr(const PyCommonCode code) {
std::string PyCommonCode::repr(const PyCommonCode code) noexcept {
return std::format("<klotski.CommonCode 0x{}>", str(code));
}
// ----------------------------------------------------------------------------------------- //
static CommonCode convert(const PyShortCode code) {
static CommonCode convert(const PyShortCode code) noexcept {
return std::bit_cast<ShortCode>(code).to_common_code();
}
@ -55,20 +49,18 @@ static CommonCode convert(const uint64_t code) {
if (CommonCode::check(code)) {
return CommonCode::unsafe_create(code);
}
throw PyCodecExp(std::format("invalid common code -> {}", code));
throw PyExc_CodecError(std::format("invalid common code -> {}", code));
}
static CommonCode convert(const std::string_view code) {
if (const auto str = CommonCode::from_string(code)) {
return str.value();
}
throw PyCodecExp(std::format("invalid common code -> `{}`", code));
throw PyExc_CodecError(std::format("invalid common code -> `{}`", code));
}
PyCommonCode::PyCommonCode(const uint64_t code) : code_(convert(code)) {}
PyCommonCode::PyCommonCode(const PyShortCode code) : code_(convert(code)) {}
PyCommonCode::PyCommonCode(const std::string_view code) : code_(convert(code)) {}
PyCommonCode::PyCommonCode(const PyShortCode code) noexcept : code_(convert(code)) {}
// ----------------------------------------------------------------------------------------- //

0
src/core_ffi/py_ffi/py_cases.cc → src/core_ffi/py_ffi/wrapper/py_cases.cc

0
src/core_ffi/py_ffi/py_group.cc → src/core_ffi/py_ffi/wrapper/py_group.cc

0
src/core_ffi/py_ffi/py_group_union.cc → src/core_ffi/py_ffi/wrapper/py_group_union.cc

38
src/core_ffi/py_ffi/codec/short_code.cc → src/core_ffi/py_ffi/wrapper/short_code.cc

@ -1,53 +1,43 @@
#include <format>
#include "py_exps.h"
#include "py_codec.h"
#include "include/py_exception.h"
#include "include/py_short_code.h"
using klotski::ffi::PyCodecExp;
using klotski::ffi::PyShortCode;
using klotski::ffi::PyCommonCode;
using klotski::codec::ShortCode;
using klotski::codec::CommonCode;
using namespace klotski::ffi;
// ----------------------------------------------------------------------------------------- //
uint32_t PyShortCode::value() const {
uint32_t PyShortCode::value() const noexcept {
return code_.unwrap();
}
PyCommonCode PyShortCode::common_code() const {
PyCommonCode PyShortCode::common_code() const noexcept {
return std::bit_cast<PyCommonCode>(code_.to_common_code());
}
// ----------------------------------------------------------------------------------------- //
bool PyShortCode::check(const uint32_t code) {
bool PyShortCode::check(const uint32_t code) noexcept {
return ShortCode::check(code);
}
bool PyShortCode::check(const std::string_view code) {
bool PyShortCode::check(const std::string_view code) noexcept {
return ShortCode::from_string(code).has_value();
}
void PyShortCode::speed_up(const bool fast_mode) {
ShortCode::speed_up(fast_mode);
}
// ----------------------------------------------------------------------------------------- //
std::string PyShortCode::str(const PyShortCode code) {
std::string PyShortCode::str(const PyShortCode code) noexcept {
return code.code_.to_string();
}
std::string PyShortCode::repr(const PyShortCode code) {
std::string PyShortCode::repr(const PyShortCode code) noexcept {
return std::format("<klotski.ShortCode {} @{}>", code.value(), str(code));
}
// ----------------------------------------------------------------------------------------- //
static ShortCode convert(const PyCommonCode code) {
static ShortCode convert(const PyCommonCode code) noexcept {
return std::bit_cast<CommonCode>(code).to_short_code();
}
@ -55,20 +45,18 @@ static ShortCode convert(const uint32_t code) {
if (ShortCode::check(code)) {
return ShortCode::unsafe_create(code);
}
throw PyCodecExp(std::format("invalid short code -> {}", code));
throw PyExc_CodecError(std::format("invalid short code -> {}", code));
}
static ShortCode convert(const std::string_view code) {
if (const auto str = ShortCode::from_string(code)) {
return str.value();
}
throw PyCodecExp(std::format("invalid short code -> `{}`", code));
throw PyExc_CodecError(std::format("invalid short code -> `{}`", code));
}
PyShortCode::PyShortCode(const uint32_t code) : code_(convert(code)) {}
PyShortCode::PyShortCode(const PyCommonCode code) : code_(convert(code)) {}
PyShortCode::PyShortCode(const std::string_view code) : code_(convert(code)) {}
PyShortCode::PyShortCode(const PyCommonCode code) noexcept : code_(convert(code)) {}
// ----------------------------------------------------------------------------------------- //
Loading…
Cancel
Save