mirror of
https://github.com/pocketpy/pocketpy
synced 2025-11-06 03:30:18 +00:00
some fix.
This commit is contained in:
parent
c6e24c69a2
commit
75811061b1
57
.github/workflows/pybind11.yml
vendored
57
.github/workflows/pybind11.yml
vendored
@ -2,11 +2,15 @@ name: CMake Build and Test
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- pkpy-v2
|
||||
paths-ignore:
|
||||
- "docs/**"
|
||||
- "web/**"
|
||||
- "**.md"
|
||||
pull_request:
|
||||
branches:
|
||||
- pkpy-v2
|
||||
paths-ignore:
|
||||
- "docs/**"
|
||||
- "web/**"
|
||||
- "**.md"
|
||||
|
||||
jobs:
|
||||
build_linux:
|
||||
@ -14,7 +18,7 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
|
||||
- name: Set up GCC
|
||||
run: |
|
||||
sudo apt-get update
|
||||
@ -23,18 +27,11 @@ jobs:
|
||||
- name: Set up CMake
|
||||
uses: jwlawson/actions-setup-cmake@v1.10
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
git submodule update --init --recursive
|
||||
git clone https://github.com/google/googletest.git
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
cmake -B build -DENABLE_TEST=ON
|
||||
cmake --build build --config Release --parallel
|
||||
|
||||
- name: Test
|
||||
run: |
|
||||
cd include/pybind11/tests
|
||||
cmake -B build
|
||||
cmake --build build --config Release --parallel
|
||||
build/pybind11_test
|
||||
|
||||
build_win:
|
||||
@ -42,25 +39,18 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
|
||||
- name: Set up MSVC
|
||||
uses: ilammy/msvc-dev-cmd@v1
|
||||
|
||||
- name: Set up CMake
|
||||
uses: jwlawson/actions-setup-cmake@v1.10
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
git submodule update --init --recursive
|
||||
git clone https://github.com/google/googletest.git
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
cmake -B build -DENABLE_TEST=ON
|
||||
cmake --build build --config Release --parallel
|
||||
|
||||
- name: Test
|
||||
run: |
|
||||
cd include\pybind11\tests
|
||||
cmake -B build
|
||||
cmake --build build --config Release --parallel
|
||||
build\Release\pybind11_test.exe
|
||||
|
||||
build_mac:
|
||||
@ -68,7 +58,7 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
|
||||
- name: Set up Clang
|
||||
run: |
|
||||
brew install llvm
|
||||
@ -78,16 +68,9 @@ jobs:
|
||||
- name: Set up CMake
|
||||
uses: jwlawson/actions-setup-cmake@v1.10
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
git submodule update --init --recursive
|
||||
git clone https://github.com/google/googletest.git
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
cmake -B build -DENABLE_TEST=ON
|
||||
cmake --build build --config Release --parallel
|
||||
|
||||
- name: Test
|
||||
run: |
|
||||
cd include/pybind11/tests
|
||||
cmake -B build -DENABLE_TEST=ON
|
||||
cmake --build build --config Release --parallel
|
||||
build/pybind11_test
|
||||
|
||||
@ -79,7 +79,7 @@ struct type_caster<T, std::enable_if_t<is_integer_v<T>>> {
|
||||
|
||||
bool load(handle src, bool) {
|
||||
if(isinstance<int_>(src)) {
|
||||
data = py_toint(src.ptr());
|
||||
data = static_cast<T>(py_toint(src.ptr()));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "module.h"
|
||||
#include "type_traits.h"
|
||||
|
||||
namespace pkbind {
|
||||
|
||||
@ -38,7 +39,8 @@ public:
|
||||
[[maybe_unused]] auto kwargs = py_offset(stack, 2);
|
||||
|
||||
auto info = &type_info::of<T>();
|
||||
int slot = (type_list<Args...>::template count<dynamic_attr> ? -1 : 0);
|
||||
int slot = ((std::is_same_v<dynamic_attr, Args> || ...) ? -1 : 0);
|
||||
std::cout << "<< " << slot << "\n";
|
||||
void* data = py_newobject(retv, steal<type>(cls).index(), slot, sizeof(instance));
|
||||
new (data) instance{instance::Flag::Own, operator new (info->size), info};
|
||||
return true;
|
||||
@ -82,8 +84,9 @@ public:
|
||||
constexpr bool is_first_base_of_v = std::is_base_of_v<first, T> || std::is_same_v<first, T>;
|
||||
|
||||
if constexpr(!is_first_base_of_v) {
|
||||
static_assert(is_first_base_of_v,
|
||||
"If you want to bind member function, the first argument must be the base class");
|
||||
static_assert(
|
||||
is_first_base_of_v,
|
||||
"If you want to bind member function, the first argument must be the base class");
|
||||
} else {
|
||||
impl::bind_function<true, false>(*this, name, std::forward<Fn>(f), extra...);
|
||||
}
|
||||
@ -108,7 +111,8 @@ public:
|
||||
template <typename MP, typename... Extras>
|
||||
class_& def_readwrite(const char* name, MP mp, const Extras&... extras) {
|
||||
if constexpr(!std::is_member_object_pointer_v<MP>) {
|
||||
static_assert(std::is_member_object_pointer_v<MP>, "def_readwrite only supports pointer to data member");
|
||||
static_assert(std::is_member_object_pointer_v<MP>,
|
||||
"def_readwrite only supports pointer to data member");
|
||||
} else {
|
||||
impl::bind_property(
|
||||
*this,
|
||||
@ -127,7 +131,8 @@ public:
|
||||
template <typename MP, typename... Extras>
|
||||
class_& def_readonly(const char* name, MP mp, const Extras&... extras) {
|
||||
if constexpr(!std::is_member_object_pointer_v<MP>) {
|
||||
static_assert(std::is_member_object_pointer_v<MP>, "def_readonly only supports pointer to data member");
|
||||
static_assert(std::is_member_object_pointer_v<MP>,
|
||||
"def_readonly only supports pointer to data member");
|
||||
} else {
|
||||
impl::bind_property(
|
||||
*this,
|
||||
@ -143,7 +148,11 @@ public:
|
||||
|
||||
template <typename Getter, typename Setter, typename... Extras>
|
||||
class_& def_property(const char* name, Getter&& g, Setter&& s, const Extras&... extras) {
|
||||
impl::bind_property(*this, name, std::forward<Getter>(g), std::forward<Setter>(s), extras...);
|
||||
impl::bind_property(*this,
|
||||
name,
|
||||
std::forward<Getter>(g),
|
||||
std::forward<Setter>(s),
|
||||
extras...);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
@ -147,8 +147,8 @@ public:
|
||||
using Callable = std::decay_t<Fn>;
|
||||
|
||||
if constexpr(std::is_trivially_copyable_v<Callable> && sizeof(Callable) <= sizeof(buffer)) {
|
||||
// if the callable object is trivially copyable and the size is less than 16 bytes, store it in the
|
||||
// buffer
|
||||
// if the callable object is trivially copyable and the size is less than 16 bytes,
|
||||
// store it in the buffer
|
||||
new (buffer) auto(std::forward<Fn>(f));
|
||||
destructor = [](function_record* self) {
|
||||
reinterpret_cast<Callable*>(self->buffer)->~Callable();
|
||||
@ -178,18 +178,10 @@ public:
|
||||
function_record& operator= (function_record&&) = delete;
|
||||
|
||||
~function_record() {
|
||||
if(destructor) {
|
||||
destructor(this);
|
||||
}
|
||||
if(arguments) {
|
||||
delete arguments;
|
||||
}
|
||||
if(next) {
|
||||
delete next;
|
||||
}
|
||||
if(signature) {
|
||||
delete[] signature;
|
||||
}
|
||||
if(destructor) { destructor(this); }
|
||||
if(arguments) { delete arguments; }
|
||||
if(next) { delete next; }
|
||||
if(signature) { delete[] signature; }
|
||||
}
|
||||
|
||||
void append(function_record* record) {
|
||||
@ -220,9 +212,7 @@ public:
|
||||
bool has_self = argc == 3;
|
||||
std::vector<handle> args;
|
||||
handle self = py_offset(stack.ptr(), 0);
|
||||
if(has_self) {
|
||||
args.push_back(self);
|
||||
}
|
||||
if(has_self) { args.push_back(self); }
|
||||
|
||||
auto tuple = py_offset(stack.ptr(), 0 + has_self);
|
||||
for(int i = 0; i < py_tuple_len(tuple); ++i) {
|
||||
@ -239,9 +229,7 @@ public:
|
||||
// foreach function record and call the function with not convert
|
||||
while(p != nullptr) {
|
||||
auto result = p->wrapper(*p, args, kwargs, false, self);
|
||||
if(result) {
|
||||
return;
|
||||
}
|
||||
if(result) { return; }
|
||||
p = p->next;
|
||||
}
|
||||
|
||||
@ -249,9 +237,7 @@ public:
|
||||
// foreach function record and call the function with convert
|
||||
while(p != nullptr) {
|
||||
auto result = p->wrapper(*p, args, kwargs, true, self);
|
||||
if(result) {
|
||||
return;
|
||||
}
|
||||
if(result) { return; }
|
||||
p = p->next;
|
||||
}
|
||||
|
||||
@ -299,14 +285,16 @@ void invoke(Fn&& fn,
|
||||
};
|
||||
|
||||
if constexpr(!is_void) {
|
||||
py_assign(py_retval(), pkbind::cast(unpack(std::get<Is>(casters).value()...), policy, parent).ptr());
|
||||
py_assign(py_retval(),
|
||||
pkbind::cast(unpack(std::get<Is>(casters).value()...), policy, parent).ptr());
|
||||
} else {
|
||||
unpack(std::get<Is>(casters).value()...);
|
||||
py_newnone(py_retval());
|
||||
}
|
||||
} else {
|
||||
if constexpr(!is_void) {
|
||||
py_assign(py_retval(), pkbind::cast(fn(std::get<Is>(casters).value()...), policy, parent).ptr());
|
||||
py_assign(py_retval(),
|
||||
pkbind::cast(fn(std::get<Is>(casters).value()...), policy, parent).ptr());
|
||||
} else {
|
||||
fn(std::get<Is>(casters).value()...);
|
||||
py_newnone(py_retval());
|
||||
@ -315,7 +303,10 @@ void invoke(Fn&& fn,
|
||||
}
|
||||
|
||||
template <typename Callable, typename... Extras, typename... Args, std::size_t... Is>
|
||||
struct template_parser<Callable, std::tuple<Extras...>, std::tuple<Args...>, std::index_sequence<Is...>> {
|
||||
struct template_parser<Callable,
|
||||
std::tuple<Extras...>,
|
||||
std::tuple<Args...>,
|
||||
std::index_sequence<Is...>> {
|
||||
using types = type_list<Args...>;
|
||||
|
||||
/// count of the Callable parameters.
|
||||
@ -333,7 +324,8 @@ struct template_parser<Callable, std::tuple<Extras...>, std::tuple<Args...>, std
|
||||
|
||||
// FIXME: temporarily, args and kwargs must be at the end of the arguments list
|
||||
/// if have py::kwargs, it must be at the end of the arguments list.
|
||||
static_assert(kwargs_count == 0 || kwargs_pos == argc - 1, "py::kwargs must be the last parameter");
|
||||
static_assert(kwargs_count == 0 || kwargs_pos == argc - 1,
|
||||
"py::kwargs must be the last parameter");
|
||||
/// if have py::args, it must be before py::kwargs or at the end of the arguments list.
|
||||
static_assert(args_count == 0 || args_pos == kwargs_pos - 1 || args_pos == argc - 1,
|
||||
"py::args must be before py::kwargs or at the end of the parameter list");
|
||||
@ -348,14 +340,18 @@ struct template_parser<Callable, std::tuple<Extras...>, std::tuple<Args...>, std
|
||||
|
||||
constexpr inline static auto policy_pos = extras::template find<pkbind::return_value_policy>;
|
||||
|
||||
constexpr inline static auto last_arg_without_default_pos = types::template find_last<pkbind::arg>;
|
||||
constexpr inline static auto first_arg_with_default_pos = types::template find<pkbind::arg_with_default>;
|
||||
static_assert(last_arg_without_default_pos < first_arg_with_default_pos || first_arg_with_default_pos == -1,
|
||||
constexpr inline static auto last_arg_without_default_pos =
|
||||
types::template find_last<pkbind::arg>;
|
||||
constexpr inline static auto first_arg_with_default_pos =
|
||||
types::template find<pkbind::arg_with_default>;
|
||||
static_assert(last_arg_without_default_pos < first_arg_with_default_pos ||
|
||||
first_arg_with_default_pos == -1,
|
||||
"parameter with default value must be after parameter without default value");
|
||||
|
||||
/// count of named parameters(explicit with name).
|
||||
constexpr inline static auto named_only_argc = extras::template count<pkbind::arg>;
|
||||
constexpr inline static auto named_default_argc = extras::template count<pkbind::arg_with_default>;
|
||||
constexpr inline static auto named_default_argc =
|
||||
extras::template count<pkbind::arg_with_default>;
|
||||
constexpr inline static auto named_argc = named_only_argc + named_default_argc;
|
||||
|
||||
/// count of normal parameters(which are not py::args or py::kwargs).
|
||||
@ -368,9 +364,7 @@ struct template_parser<Callable, std::tuple<Extras...>, std::tuple<Args...>, std
|
||||
static void initialize(function_record& record, const Extras&... extras) {
|
||||
auto extras_tuple = std::make_tuple(extras...);
|
||||
constexpr static bool has_named_args = (named_argc > 0);
|
||||
if constexpr(policy_pos != -1) {
|
||||
record.policy = std::get<policy_pos>(extras_tuple);
|
||||
}
|
||||
if constexpr(policy_pos != -1) { record.policy = std::get<policy_pos>(extras_tuple); }
|
||||
|
||||
// TODO: set others
|
||||
|
||||
@ -410,15 +404,15 @@ struct template_parser<Callable, std::tuple<Extras...>, std::tuple<Args...>, std
|
||||
sig += type_info::of<T>().name;
|
||||
if(!record.arguments->defaults[index].empty()) {
|
||||
sig += " = ";
|
||||
sig += record.arguments->defaults[index].attr("__repr__")().cast<std::string_view>();
|
||||
sig += record.arguments->defaults[index]
|
||||
.attr("__repr__")()
|
||||
.cast<std::string_view>();
|
||||
}
|
||||
} else {
|
||||
sig += "_: ";
|
||||
sig += type_info::of<T>().name;
|
||||
}
|
||||
if(index + 1 < argc) {
|
||||
sig += ", ";
|
||||
}
|
||||
if(index + 1 < argc) { sig += ", "; }
|
||||
index++;
|
||||
};
|
||||
(append(type_identity<Args>{}), ...);
|
||||
@ -430,8 +424,8 @@ struct template_parser<Callable, std::tuple<Extras...>, std::tuple<Args...>, std
|
||||
}
|
||||
}
|
||||
|
||||
/// try to call a C++ function(store in function_record) with the arguments which are from Python.
|
||||
/// if success, return true, otherwise return false.
|
||||
/// try to call a C++ function(store in function_record) with the arguments which are from
|
||||
/// Python. if success, return true, otherwise return false.
|
||||
static bool call(function_record& record,
|
||||
std::vector<handle>& args,
|
||||
std::vector<std::pair<handle, handle>>& kwargs,
|
||||
@ -451,9 +445,7 @@ struct template_parser<Callable, std::tuple<Extras...>, std::tuple<Args...>, std
|
||||
|
||||
// load arguments from call arguments
|
||||
if(args.size() > normal_argc) {
|
||||
if constexpr(args_pos == -1) {
|
||||
return false;
|
||||
}
|
||||
if constexpr(args_pos == -1) { return false; }
|
||||
}
|
||||
|
||||
for(std::size_t i = 0; i < std::min(normal_argc, (int)args.size()); ++i) {
|
||||
@ -463,9 +455,10 @@ struct template_parser<Callable, std::tuple<Extras...>, std::tuple<Args...>, std
|
||||
object repack_args;
|
||||
// pack the args
|
||||
if constexpr(args_pos != -1) {
|
||||
const auto n = args.size() > normal_argc ? args.size() - normal_argc : 0;
|
||||
const auto n =
|
||||
static_cast<int>(args.size() > normal_argc ? args.size() - normal_argc : 0);
|
||||
auto pack = tuple(n);
|
||||
for(std::size_t i = 0; i < n; ++i) {
|
||||
for(int i = 0; i < n; ++i) {
|
||||
pack[i] = args[normal_argc + i];
|
||||
}
|
||||
repack_args = std::move(pack);
|
||||
@ -500,16 +493,18 @@ struct template_parser<Callable, std::tuple<Extras...>, std::tuple<Args...>, std
|
||||
|
||||
// check if all the arguments are valid
|
||||
for(std::size_t i = 0; i < argc; ++i) {
|
||||
if(!stack[i]) {
|
||||
return false;
|
||||
}
|
||||
if(!stack[i]) { return false; }
|
||||
}
|
||||
|
||||
// ok, all the arguments are valid, call the function
|
||||
std::tuple<type_caster<Args>...> casters;
|
||||
|
||||
if(((std::get<Is>(casters).load(stack[Is], convert)) && ...)) {
|
||||
invoke(record.as<Callable>(), std::index_sequence<Is...>{}, casters, record.policy, parent);
|
||||
invoke(record.as<Callable>(),
|
||||
std::index_sequence<Is...>{},
|
||||
casters,
|
||||
record.policy,
|
||||
parent);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -533,15 +528,14 @@ class cpp_function : public function {
|
||||
static bool is_function_record(handle h) {
|
||||
if(isinstance<function>(h)) {
|
||||
auto slot = py_getslot(h.ptr(), 0);
|
||||
if(slot) {
|
||||
return py_typeof(slot) == m_type;
|
||||
}
|
||||
if(slot) { return py_typeof(slot) == m_type; }
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Fn, typename... Extras>
|
||||
cpp_function(bool is_method, const char* name, Fn&& fn, const Extras&... extras) : function(alloc_t{}) {
|
||||
cpp_function(bool is_method, const char* name, Fn&& fn, const Extras&... extras) :
|
||||
function(alloc_t{}) {
|
||||
// bind the function
|
||||
std::string sig = name;
|
||||
sig += is_method ? "(self, *args, **kwargs)" : "(*args, **kwargs)";
|
||||
@ -562,13 +556,9 @@ class cpp_function : public function {
|
||||
py_exception(tp_IndexError, e.what());
|
||||
} catch(std::range_error& e) {
|
||||
py_exception(tp_ValueError, e.what());
|
||||
} catch(stop_iteration& e) {
|
||||
StopIteration();
|
||||
} catch(index_error& e) {
|
||||
} catch(stop_iteration&) { StopIteration(); } catch(index_error& e) {
|
||||
py_exception(tp_IndexError, e.what());
|
||||
} catch(key_error& e) {
|
||||
py_exception(tp_KeyError, e.what());
|
||||
} catch(value_error& e) {
|
||||
} catch(key_error& e) { py_exception(tp_KeyError, e.what()); } catch(value_error& e) {
|
||||
py_exception(tp_ValueError, e.what());
|
||||
} catch(type_error& e) {
|
||||
py_exception(tp_TypeError, e.what());
|
||||
@ -576,9 +566,7 @@ class cpp_function : public function {
|
||||
py_exception(tp_ImportError, e.what());
|
||||
} catch(attribute_error& e) {
|
||||
py_exception(tp_AttributeError, e.what());
|
||||
} catch(std::exception& e) {
|
||||
py_exception(tp_RuntimeError, e.what());
|
||||
}
|
||||
} catch(std::exception& e) { py_exception(tp_RuntimeError, e.what()); }
|
||||
return false;
|
||||
};
|
||||
py_newfunction(m_ptr, sig.c_str(), call, nullptr, 1);
|
||||
@ -590,7 +578,8 @@ class cpp_function : public function {
|
||||
}
|
||||
|
||||
template <typename Fn, typename... Extras>
|
||||
cpp_function(Fn&& fn, const Extras&... extras) : cpp_function("lambda", std::forward<Fn>(fn), extras...) {}
|
||||
cpp_function(Fn&& fn, const Extras&... extras) :
|
||||
cpp_function("lambda", std::forward<Fn>(fn), extras...) {}
|
||||
};
|
||||
|
||||
class property : public object {
|
||||
@ -620,7 +609,8 @@ namespace impl {
|
||||
|
||||
template <bool is_method, bool is_static, typename Fn, typename... Extras>
|
||||
void bind_function(handle obj, const char* name_, Fn&& fn, const Extras&... extras) {
|
||||
constexpr bool has_named_args = ((std::is_same_v<Extras, arg> || std::is_same_v<Extras, arg_with_default>) || ...);
|
||||
constexpr bool has_named_args =
|
||||
((std::is_same_v<Extras, arg> || std::is_same_v<Extras, arg_with_default>) || ...);
|
||||
auto name = py_name(name_);
|
||||
auto func = py_getdict(obj.ptr(), name);
|
||||
|
||||
@ -634,23 +624,33 @@ void bind_function(handle obj, const char* name_, Fn&& fn, const Extras&... extr
|
||||
}
|
||||
} else {
|
||||
if constexpr(is_static) {
|
||||
py_setdict(obj.ptr(),
|
||||
name,
|
||||
staticmethod(cpp_function(is_method, name_, std::forward<Fn>(fn), extras...).ptr()).ptr());
|
||||
py_setdict(
|
||||
obj.ptr(),
|
||||
name,
|
||||
staticmethod(cpp_function(is_method, name_, std::forward<Fn>(fn), extras...).ptr())
|
||||
.ptr());
|
||||
} else {
|
||||
if constexpr(has_named_args && is_method) {
|
||||
py_setdict(
|
||||
obj.ptr(),
|
||||
name,
|
||||
cpp_function(is_method, name_, std::forward<Fn>(fn), arg("self"), extras...)
|
||||
.ptr());
|
||||
} else {
|
||||
py_setdict(obj.ptr(),
|
||||
name,
|
||||
cpp_function(is_method, name_, std::forward<Fn>(fn), arg("self"), extras...).ptr());
|
||||
} else {
|
||||
py_setdict(obj.ptr(), name, cpp_function(is_method, name_, std::forward<Fn>(fn), extras...).ptr());
|
||||
cpp_function(is_method, name_, std::forward<Fn>(fn), extras...).ptr());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Getter, typename Setter, typename... Extras>
|
||||
void bind_property(handle obj, const char* name, Getter&& getter_, Setter&& setter_, const Extras&... extras) {
|
||||
void bind_property(handle obj,
|
||||
const char* name,
|
||||
Getter&& getter_,
|
||||
Setter&& setter_,
|
||||
const Extras&... extras) {
|
||||
if constexpr(std::is_same_v<std::decay_t<Setter>, std::nullptr_t>) {
|
||||
cpp_function getter(true,
|
||||
name,
|
||||
|
||||
@ -120,7 +120,7 @@ public:
|
||||
|
||||
name(const char* data, int size) : data(py_namev({data, size})) {}
|
||||
|
||||
name(std::string_view str) : name(str.data(), str.size()) {}
|
||||
name(std::string_view str) : name(str.data(), static_cast<int>(str.size())) {}
|
||||
|
||||
name(handle h);
|
||||
|
||||
@ -198,9 +198,7 @@ public:
|
||||
object() = default;
|
||||
|
||||
object(const object& other) : handle(other), m_index(other.m_index) {
|
||||
if(other.in_pool()) {
|
||||
object_pool::inc_ref(other);
|
||||
}
|
||||
if(other.in_pool()) { object_pool::inc_ref(other); }
|
||||
}
|
||||
|
||||
object(object&& other) : handle(other), m_index(other.m_index) {
|
||||
@ -210,12 +208,8 @@ public:
|
||||
|
||||
object& operator= (const object& other) {
|
||||
if(this != &other) {
|
||||
if(in_pool()) {
|
||||
object_pool::dec_ref(*this);
|
||||
}
|
||||
if(other.in_pool()) {
|
||||
object_pool::inc_ref(other);
|
||||
}
|
||||
if(in_pool()) { object_pool::dec_ref(*this); }
|
||||
if(other.in_pool()) { object_pool::inc_ref(other); }
|
||||
m_ptr = other.m_ptr;
|
||||
m_index = other.m_index;
|
||||
}
|
||||
@ -224,9 +218,7 @@ public:
|
||||
|
||||
object& operator= (object&& other) {
|
||||
if(this != &other) {
|
||||
if(in_pool()) {
|
||||
object_pool::dec_ref(*this);
|
||||
}
|
||||
if(in_pool()) { object_pool::dec_ref(*this); }
|
||||
m_ptr = other.m_ptr;
|
||||
m_index = other.m_index;
|
||||
other.m_ptr = nullptr;
|
||||
@ -236,9 +228,7 @@ public:
|
||||
}
|
||||
|
||||
~object() {
|
||||
if(in_pool()) {
|
||||
object_pool::dec_ref(*this);
|
||||
}
|
||||
if(in_pool()) { object_pool::dec_ref(*this); }
|
||||
}
|
||||
|
||||
bool is_singleton() const { return m_ptr && m_index == -1; }
|
||||
|
||||
@ -4,22 +4,24 @@
|
||||
|
||||
namespace pkbind {
|
||||
|
||||
#define PKBIND_TYPE_IMPL(parent, child, expr) \
|
||||
\
|
||||
private: \
|
||||
friend class type; \
|
||||
static auto type_or_check() { return expr; } \
|
||||
\
|
||||
public: \
|
||||
using parent::parent; \
|
||||
using parent::operator=; \
|
||||
child(const object& o) : parent(type::isinstance<child>(o) ? o : type::of<child>()(o)) {} \
|
||||
child(object&& o) : parent(type::isinstance<child>(o) ? std::move(o) : type::of<child>()(std::move(o))) {}
|
||||
#define PKBIND_TYPE_IMPL(parent, child, expr) \
|
||||
\
|
||||
private: \
|
||||
friend class type; \
|
||||
static auto type_or_check() { return expr; } \
|
||||
\
|
||||
public: \
|
||||
using parent::parent; \
|
||||
using parent::operator=; \
|
||||
child(const object& o) : parent(type::isinstance<child>(o) ? o : type::of<child>()(o)) {} \
|
||||
child(object&& o) : \
|
||||
parent(type::isinstance<child>(o) ? std::move(o) : type::of<child>()(std::move(o))) {}
|
||||
|
||||
class type : public object {
|
||||
protected:
|
||||
template <typename T>
|
||||
constexpr inline static bool is_check_v = std::is_invocable_r_v<bool, decltype(T::type_or_check()), handle>;
|
||||
constexpr inline static bool is_check_v =
|
||||
std::is_invocable_r_v<bool, decltype(T::type_or_check()), handle>;
|
||||
|
||||
static auto type_or_check() { return tp_type; }
|
||||
|
||||
@ -108,7 +110,9 @@ public:
|
||||
|
||||
object operator* () const { return m_value; }
|
||||
|
||||
friend bool operator== (const iterator& lhs, const iterator& rhs) { return lhs.m_value.ptr() == rhs.m_value.ptr(); }
|
||||
friend bool operator== (const iterator& lhs, const iterator& rhs) {
|
||||
return lhs.m_value.ptr() == rhs.m_value.ptr();
|
||||
}
|
||||
|
||||
friend bool operator!= (const iterator& lhs, const iterator& rhs) { return !(lhs == rhs); }
|
||||
|
||||
@ -134,7 +138,7 @@ class str : public object {
|
||||
|
||||
str(const char* data, int size) : object(alloc_t{}) { py_newstrn(m_ptr, data, size); }
|
||||
|
||||
str(const char* data) : str(data, strlen(data)) {}
|
||||
str(const char* data) : str(data, static_cast<int>(strlen(data))) {}
|
||||
|
||||
str(std::string_view s) : str(s.data(), static_cast<int>(s.size())) {}
|
||||
|
||||
@ -147,7 +151,7 @@ class tuple : public object {
|
||||
|
||||
tuple(int size) : object(alloc_t{}) { py_newtuple(m_ptr, size); }
|
||||
|
||||
tuple(std::initializer_list<handle> args) : tuple(args.size()) {
|
||||
tuple(std::initializer_list<handle> args) : tuple(static_cast<int>(args.size())) {
|
||||
int index = 0;
|
||||
for(auto& arg: args) {
|
||||
py_tuple_setitem(m_ptr, index++, arg.ptr());
|
||||
@ -194,7 +198,7 @@ class list : public object {
|
||||
|
||||
list(int size) : object(alloc_t{}) { py_newlistn(m_ptr, size); }
|
||||
|
||||
list(std::initializer_list<handle> args) : list(args.size()) {
|
||||
list(std::initializer_list<handle> args) : list(static_cast<int>(args.size())) {
|
||||
int index = 0;
|
||||
for(auto& arg: args) {
|
||||
py_list_setitem(m_ptr, index++, arg.ptr());
|
||||
@ -338,9 +342,7 @@ class capsule : public object {
|
||||
static void register_() {
|
||||
m_type = py_newtype("capsule", tp_object, nullptr, [](void* data) {
|
||||
auto impl = static_cast<capsule_impl*>(data);
|
||||
if(impl->data && impl->destructor) {
|
||||
impl->destructor(impl->data);
|
||||
}
|
||||
if(impl->data && impl->destructor) { impl->destructor(impl->data); }
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -30,7 +30,7 @@ struct type_caster<std::array<T, N>> {
|
||||
|
||||
if(list.size() != N) { return false; }
|
||||
|
||||
for(std::size_t i = 0; i < N; ++i) {
|
||||
for(int i = 0; i < N; ++i) {
|
||||
type_caster<T> caster;
|
||||
if(!caster.load(list[i], convert)) { return false; }
|
||||
data[i] = std::move(caster.value());
|
||||
@ -139,7 +139,8 @@ struct type_caster<T, std::enable_if_t<is_py_map_like_v<T>>> {
|
||||
static object cast(U&& src, return_value_policy policy, handle parent) {
|
||||
auto dict = pkbind::dict();
|
||||
for(auto&& [key, value]: src) {
|
||||
dict[pkbind::cast(std::move(key), policy, parent)] = pkbind::cast(std::move(value), policy, parent);
|
||||
dict[pkbind::cast(std::move(key), policy, parent)] =
|
||||
pkbind::cast(std::move(value), policy, parent);
|
||||
}
|
||||
return dict;
|
||||
}
|
||||
@ -167,4 +168,3 @@ struct type_caster<T, std::enable_if_t<is_py_map_like_v<T>>> {
|
||||
};
|
||||
|
||||
} // namespace pkbind
|
||||
|
||||
|
||||
@ -351,7 +351,7 @@ TEST_F(PYBIND11_TEST, lambda) {
|
||||
size_t c;
|
||||
size_t d;
|
||||
|
||||
int operator() (int x, int y) { return x + y + a + b + c + d; }
|
||||
size_t operator() (size_t x, size_t y) { return x + y + a + b + c + d; }
|
||||
|
||||
~NotSmall() { destructor_calls++; }
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user