mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 11:30:18 +00:00
commit
0c1bd532f8
@ -81,9 +81,13 @@ inline bool isinstance(const handle& obj, const handle& type) {
|
|||||||
|
|
||||||
inline int64_t hash(const handle& obj) { return vm->py_hash(obj.ptr()); }
|
inline int64_t hash(const handle& obj) { return vm->py_hash(obj.ptr()); }
|
||||||
|
|
||||||
|
namespace impl {
|
||||||
|
|
||||||
template <typename T, typename SFINAE = void>
|
template <typename T, typename SFINAE = void>
|
||||||
struct type_caster;
|
struct type_caster;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
handle cast(T&& value, return_value_policy policy, handle parent) {
|
handle cast(T&& value, return_value_policy policy, handle parent) {
|
||||||
// decay_t can resolve c-array type, but remove_cv_ref_t can't.
|
// decay_t can resolve c-array type, but remove_cv_ref_t can't.
|
||||||
@ -107,7 +111,7 @@ handle cast(T&& value, return_value_policy policy, handle parent) {
|
|||||||
: return_value_policy::move;
|
: return_value_policy::move;
|
||||||
}
|
}
|
||||||
|
|
||||||
return type_caster<underlying_type>::cast(std::forward<T>(value), policy, parent);
|
return impl::type_caster<underlying_type>::cast(std::forward<T>(value), policy, parent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,7 +119,7 @@ template <typename T>
|
|||||||
T cast(const handle& obj, bool convert) {
|
T cast(const handle& obj, bool convert) {
|
||||||
assert(obj.ptr() != nullptr);
|
assert(obj.ptr() != nullptr);
|
||||||
|
|
||||||
type_caster<T> caster = {};
|
impl::type_caster<T> caster = {};
|
||||||
|
|
||||||
if(caster.load(obj, convert)) {
|
if(caster.load(obj, convert)) {
|
||||||
return caster.value;
|
return caster.value;
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#include "instance.h"
|
#include "instance.h"
|
||||||
#include "accessor.h"
|
#include "accessor.h"
|
||||||
|
|
||||||
namespace pybind11 {
|
namespace pybind11::impl {
|
||||||
|
|
||||||
using pkpy::is_floating_point_v;
|
using pkpy::is_floating_point_v;
|
||||||
using pkpy::is_integral_v;
|
using pkpy::is_integral_v;
|
||||||
|
@ -169,15 +169,15 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum_& value(const char* name, T value) {
|
enum_& value(const char* name, T value) {
|
||||||
handle var = type_caster<T>::cast(value, return_value_policy::copy);
|
handle var = pybind11::cast(value, return_value_policy::copy);
|
||||||
this->m_ptr->attr().set(name, var.ptr());
|
setattr(*this, name, var);
|
||||||
m_values.emplace_back(name, var);
|
m_values.emplace_back(name, var);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum_& export_values() {
|
enum_& export_values() {
|
||||||
for(auto& [name, value]: m_values) {
|
for(auto& [name, value]: m_values) {
|
||||||
Base::m_scope.ptr()->attr().set(name, value.ptr());
|
setattr(Base::m_scope, name, value);
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -176,7 +176,7 @@ public:
|
|||||||
template <typename Fn, std::size_t... Is, typename... Args>
|
template <typename Fn, std::size_t... Is, typename... Args>
|
||||||
handle invoke(Fn&& fn,
|
handle invoke(Fn&& fn,
|
||||||
std::index_sequence<Is...>,
|
std::index_sequence<Is...>,
|
||||||
std::tuple<type_caster<Args>...>& casters,
|
std::tuple<impl::type_caster<Args>...>& casters,
|
||||||
return_value_policy policy,
|
return_value_policy policy,
|
||||||
handle parent) {
|
handle parent) {
|
||||||
using underlying_type = std::decay_t<Fn>;
|
using underlying_type = std::decay_t<Fn>;
|
||||||
@ -361,10 +361,10 @@ struct template_parser<Callable, std::tuple<Extras...>, std::tuple<Args...>, std
|
|||||||
|
|
||||||
// resolve keyword arguments
|
// resolve keyword arguments
|
||||||
const auto n = vm->s_data._sp - view.end();
|
const auto n = vm->s_data._sp - view.end();
|
||||||
std::size_t index = 0;
|
int index = 0;
|
||||||
|
|
||||||
if constexpr(named_argc > 0) {
|
if constexpr(named_argc > 0) {
|
||||||
std::size_t arg_index = 0;
|
int arg_index = 0;
|
||||||
auto& arguments = *record.arguments;
|
auto& arguments = *record.arguments;
|
||||||
|
|
||||||
while(arg_index < named_argc && index < n) {
|
while(arg_index < named_argc && index < n) {
|
||||||
@ -403,7 +403,7 @@ struct template_parser<Callable, std::tuple<Extras...>, std::tuple<Args...>, std
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ok, all the arguments are valid, call the function
|
// ok, all the arguments are valid, call the function
|
||||||
std::tuple<type_caster<Args>...> casters;
|
std::tuple<impl::type_caster<Args>...> casters;
|
||||||
|
|
||||||
// check type compatibility
|
// check type compatibility
|
||||||
if(((std::get<Is>(casters).load(stack[Is], convert)) && ...)) {
|
if(((std::get<Is>(casters).load(stack[Is], convert)) && ...)) {
|
||||||
@ -489,14 +489,14 @@ pkpy::PyVar setter_wrapper(pkpy::VM* vm, pkpy::ArgsView view) {
|
|||||||
|
|
||||||
if constexpr(std::is_member_object_pointer_v<Setter>) {
|
if constexpr(std::is_member_object_pointer_v<Setter>) {
|
||||||
// specialize for pointer to data member
|
// specialize for pointer to data member
|
||||||
type_caster<member_type_t<Setter>> caster;
|
impl::type_caster<member_type_t<Setter>> caster;
|
||||||
if(caster.load(view[1], true)) {
|
if(caster.load(view[1], true)) {
|
||||||
self.*setter = caster.value;
|
self.*setter = caster.value;
|
||||||
return vm->None;
|
return vm->None;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// specialize for pointer to member function
|
// specialize for pointer to member function
|
||||||
type_caster<std::tuple_element_t<1, callable_args_t<Setter>>> caster;
|
impl::type_caster<std::tuple_element_t<1, callable_args_t<Setter>>> caster;
|
||||||
if(caster.load(view[1], true)) {
|
if(caster.load(view[1], true)) {
|
||||||
(self.*setter)(caster.value);
|
(self.*setter)(caster.value);
|
||||||
return vm->None;
|
return vm->None;
|
||||||
@ -507,7 +507,7 @@ pkpy::PyVar setter_wrapper(pkpy::VM* vm, pkpy::ArgsView view) {
|
|||||||
using Self = remove_cvref_t<std::tuple_element_t<0, callable_args_t<Setter>>>;
|
using Self = remove_cvref_t<std::tuple_element_t<0, callable_args_t<Setter>>>;
|
||||||
auto& self = handle(view[0])._as<instance>()._as<Self>();
|
auto& self = handle(view[0])._as<instance>()._as<Self>();
|
||||||
|
|
||||||
type_caster<std::tuple_element_t<1, callable_args_t<Setter>>> caster;
|
impl::type_caster<std::tuple_element_t<1, callable_args_t<Setter>>> caster;
|
||||||
if(caster.load(view[1], true)) {
|
if(caster.load(view[1], true)) {
|
||||||
setter(self, caster.value);
|
setter(self, caster.value);
|
||||||
return vm->None;
|
return vm->None;
|
||||||
|
@ -37,7 +37,7 @@ class handle;
|
|||||||
class object;
|
class object;
|
||||||
class iterator;
|
class iterator;
|
||||||
class str;
|
class str;
|
||||||
class arg;
|
struct arg;
|
||||||
struct args_proxy;
|
struct args_proxy;
|
||||||
struct kwargs_proxy;
|
struct kwargs_proxy;
|
||||||
|
|
||||||
@ -210,12 +210,7 @@ constexpr inline bool is_pyobject_v = std::is_base_of_v<object, T>;
|
|||||||
#if PK_VERSION_MAJOR == 2
|
#if PK_VERSION_MAJOR == 2
|
||||||
using error_already_set = pkpy::TopLevelException;
|
using error_already_set = pkpy::TopLevelException;
|
||||||
#else
|
#else
|
||||||
class error_already_set : std::exception {
|
using error_already_set = pkpy::Exception;
|
||||||
public:
|
|
||||||
error_already_set() = default;
|
|
||||||
|
|
||||||
const char* what() const noexcept override { return "An error occurred while calling a Python function."; }
|
|
||||||
};
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
inline void setattr(const handle& obj, const handle& name, const handle& value);
|
inline void setattr(const handle& obj, const handle& name, const handle& value);
|
||||||
|
@ -19,8 +19,10 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
module_ def_submodule(const char* name, const char* doc = nullptr) {
|
module_ def_submodule(const char* name, const char* doc = nullptr) {
|
||||||
auto package = this->package()._as<pkpy::Str>() + "." + this->name()._as<pkpy::Str>();
|
// TODO: resolve package
|
||||||
auto m = vm->new_module(name, package);
|
//auto package = this->package()._as<pkpy::Str>() + "." + this->name()._as<pkpy::Str>();
|
||||||
|
auto fname = this->name()._as<pkpy::Str>() + "." + name;
|
||||||
|
auto m = vm->new_module(fname, "");
|
||||||
setattr(*this, name, m);
|
setattr(*this, name, m);
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
@ -69,15 +69,19 @@ public:
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
decltype(auto) _as() const {
|
decltype(auto) _as() const {
|
||||||
static_assert(!std::is_reference_v<T>, "T must not be a reference type.");
|
static_assert(!std::is_reference_v<T>, "T must not be a reference type.");
|
||||||
#if PK_VERSION_MAJOR == 2
|
if constexpr(std::is_same_v<T, empty>) {
|
||||||
if constexpr(pkpy::is_sso_v<T>) {
|
return empty();
|
||||||
return pkpy::_py_cast<T>(vm, ptr());
|
|
||||||
} else {
|
} else {
|
||||||
return ptr().template obj_get<T>();
|
#if PK_VERSION_MAJOR == 2
|
||||||
}
|
if constexpr(pkpy::is_sso_v<T>) {
|
||||||
|
return pkpy::_py_cast<T>(vm, ptr());
|
||||||
|
} else {
|
||||||
|
return ptr().template obj_get<T>();
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
return (((pkpy::Py_<T>*)ptr())->_value);
|
return (((pkpy::Py_<T>*)ptr())->_value);
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -25,9 +25,9 @@ struct function_traits {
|
|||||||
static_assert(dependent_false<Fn>, "unsupported function type");
|
static_assert(dependent_false<Fn>, "unsupported function type");
|
||||||
};
|
};
|
||||||
|
|
||||||
#define PYBIND11_FUNCTION_TRAITS_SPECIALIZE(qualifiers) \
|
#define PYBIND11_FUNCTION_TRAITS_SPECIALIZE(...) \
|
||||||
template <typename R, typename... Args> \
|
template <typename R, typename... Args> \
|
||||||
struct function_traits<R(Args...) qualifiers> { \
|
struct function_traits<R(Args...) __VA_ARGS__> { \
|
||||||
using return_type = R; \
|
using return_type = R; \
|
||||||
using args_type = std::tuple<Args...>; \
|
using args_type = std::tuple<Args...>; \
|
||||||
constexpr static std::size_t args_count = sizeof...(Args); \
|
constexpr static std::size_t args_count = sizeof...(Args); \
|
||||||
@ -167,4 +167,32 @@ constexpr auto type_name() {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename... Args>
|
||||||
|
struct overload_cast_t {
|
||||||
|
template <typename Return>
|
||||||
|
constexpr auto operator() (Return (*pf)(Args...)) const noexcept -> decltype(pf) {
|
||||||
|
return pf;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Return, typename Class>
|
||||||
|
constexpr auto operator() (Return (Class::*pmf)(Args...), std::false_type = {}) const noexcept -> decltype(pmf) {
|
||||||
|
return pmf;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Return, typename Class>
|
||||||
|
constexpr auto operator() (Return (Class::*pmf)(Args...) const, std::true_type) const noexcept -> decltype(pmf) {
|
||||||
|
return pmf;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Syntax sugar for resolving overloaded function pointers:
|
||||||
|
/// - regular: static_cast<Return (Class::*)(Arg0, Arg1, Arg2)>(&Class::func)
|
||||||
|
/// - sweet: overload_cast<Arg0, Arg1, Arg2>(&Class::func)
|
||||||
|
template <typename... Args>
|
||||||
|
constexpr inline overload_cast_t<Args...> overload_cast;
|
||||||
|
|
||||||
|
/// Const member function selector for overload_cast
|
||||||
|
/// - regular: static_cast<Return (Class::*)(Arg) const>(&Class::func)
|
||||||
|
/// - sweet: overload_cast<Arg>(&Class::func, const_)
|
||||||
|
constexpr static auto const_ = std::true_type{};
|
||||||
} // namespace pybind11
|
} // namespace pybind11
|
||||||
|
@ -385,11 +385,11 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
class args : public tuple {
|
class args : public tuple {
|
||||||
PYBIND11_TYPE_IMPLEMENT(tuple, struct empty, vm->tp_tuple);
|
PYBIND11_TYPE_IMPLEMENT(tuple, pybind11::empty, vm->tp_tuple);
|
||||||
};
|
};
|
||||||
|
|
||||||
class kwargs : public dict {
|
class kwargs : public dict {
|
||||||
PYBIND11_TYPE_IMPLEMENT(dict, struct empty, vm->tp_dict);
|
PYBIND11_TYPE_IMPLEMENT(dict, pybind11::empty, vm->tp_dict);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace pybind11
|
} // namespace pybind11
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
namespace pybind11 {
|
namespace pybind11::impl {
|
||||||
|
|
||||||
template <typename T, std::size_t N>
|
template <typename T, std::size_t N>
|
||||||
struct type_caster<std::array<T, N>> {
|
struct type_caster<std::array<T, N>> {
|
||||||
@ -140,5 +140,5 @@ struct type_caster<T, std::enable_if_t<is_py_map_like_v<T>>> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace pybind11
|
} // namespace pybind11::impl
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user