diff --git a/include/pybind11/internal/builtins.h b/include/pybind11/internal/builtins.h index aa616ca9..084376cb 100644 --- a/include/pybind11/internal/builtins.h +++ b/include/pybind11/internal/builtins.h @@ -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()); } +namespace impl { + template struct type_caster; +} + template handle cast(T&& value, return_value_policy policy, handle parent) { // 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 type_caster::cast(std::forward(value), policy, parent); + return impl::type_caster::cast(std::forward(value), policy, parent); } } @@ -115,7 +119,7 @@ template T cast(const handle& obj, bool convert) { assert(obj.ptr() != nullptr); - type_caster caster = {}; + impl::type_caster caster = {}; if(caster.load(obj, convert)) { return caster.value; diff --git a/include/pybind11/internal/cast.h b/include/pybind11/internal/cast.h index acc0897a..526c5a26 100644 --- a/include/pybind11/internal/cast.h +++ b/include/pybind11/internal/cast.h @@ -2,7 +2,7 @@ #include "instance.h" #include "accessor.h" -namespace pybind11 { +namespace pybind11::impl { using pkpy::is_floating_point_v; using pkpy::is_integral_v; diff --git a/include/pybind11/internal/class.h b/include/pybind11/internal/class.h index 70d850d4..dd4e01e8 100644 --- a/include/pybind11/internal/class.h +++ b/include/pybind11/internal/class.h @@ -169,15 +169,15 @@ public: } enum_& value(const char* name, T value) { - handle var = type_caster::cast(value, return_value_policy::copy); - this->m_ptr->attr().set(name, var.ptr()); + handle var = pybind11::cast(value, return_value_policy::copy); + setattr(*this, name, var); m_values.emplace_back(name, var); return *this; } enum_& export_values() { for(auto& [name, value]: m_values) { - Base::m_scope.ptr()->attr().set(name, value.ptr()); + setattr(Base::m_scope, name, value); } return *this; } diff --git a/include/pybind11/internal/cpp_function.h b/include/pybind11/internal/cpp_function.h index fa7a4364..f12e5b02 100644 --- a/include/pybind11/internal/cpp_function.h +++ b/include/pybind11/internal/cpp_function.h @@ -176,7 +176,7 @@ public: template handle invoke(Fn&& fn, std::index_sequence, - std::tuple...>& casters, + std::tuple...>& casters, return_value_policy policy, handle parent) { using underlying_type = std::decay_t; @@ -361,10 +361,10 @@ struct template_parser, std::tuple, std // resolve keyword arguments const auto n = vm->s_data._sp - view.end(); - std::size_t index = 0; + int index = 0; if constexpr(named_argc > 0) { - std::size_t arg_index = 0; + int arg_index = 0; auto& arguments = *record.arguments; while(arg_index < named_argc && index < n) { @@ -403,7 +403,7 @@ struct template_parser, std::tuple, std } // ok, all the arguments are valid, call the function - std::tuple...> casters; + std::tuple...> casters; // check type compatibility if(((std::get(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) { // specialize for pointer to data member - type_caster> caster; + impl::type_caster> caster; if(caster.load(view[1], true)) { self.*setter = caster.value; return vm->None; } } else { // specialize for pointer to member function - type_caster>> caster; + impl::type_caster>> caster; if(caster.load(view[1], true)) { (self.*setter)(caster.value); return vm->None; @@ -507,7 +507,7 @@ pkpy::PyVar setter_wrapper(pkpy::VM* vm, pkpy::ArgsView view) { using Self = remove_cvref_t>>; auto& self = handle(view[0])._as()._as(); - type_caster>> caster; + impl::type_caster>> caster; if(caster.load(view[1], true)) { setter(self, caster.value); return vm->None; diff --git a/include/pybind11/internal/kernel.h b/include/pybind11/internal/kernel.h index bb117712..55d33f45 100644 --- a/include/pybind11/internal/kernel.h +++ b/include/pybind11/internal/kernel.h @@ -37,7 +37,7 @@ class handle; class object; class iterator; class str; -class arg; +struct arg; struct args_proxy; struct kwargs_proxy; @@ -210,12 +210,7 @@ constexpr inline bool is_pyobject_v = std::is_base_of_v; #if PK_VERSION_MAJOR == 2 using error_already_set = pkpy::TopLevelException; #else -class error_already_set : std::exception { -public: - error_already_set() = default; - - const char* what() const noexcept override { return "An error occurred while calling a Python function."; } -}; +using error_already_set = pkpy::Exception; #endif inline void setattr(const handle& obj, const handle& name, const handle& value); diff --git a/include/pybind11/internal/module.h b/include/pybind11/internal/module.h index 420b11fc..6eef55e2 100644 --- a/include/pybind11/internal/module.h +++ b/include/pybind11/internal/module.h @@ -19,8 +19,10 @@ public: } module_ def_submodule(const char* name, const char* doc = nullptr) { - auto package = this->package()._as() + "." + this->name()._as(); - auto m = vm->new_module(name, package); + // TODO: resolve package + //auto package = this->package()._as() + "." + this->name()._as(); + auto fname = this->name()._as() + "." + name; + auto m = vm->new_module(fname, ""); setattr(*this, name, m); return m; } diff --git a/include/pybind11/internal/object.h b/include/pybind11/internal/object.h index ef1ffe15..007ccf9b 100644 --- a/include/pybind11/internal/object.h +++ b/include/pybind11/internal/object.h @@ -69,15 +69,19 @@ public: template decltype(auto) _as() const { static_assert(!std::is_reference_v, "T must not be a reference type."); -#if PK_VERSION_MAJOR == 2 - if constexpr(pkpy::is_sso_v) { - return pkpy::_py_cast(vm, ptr()); + if constexpr(std::is_same_v) { + return empty(); } else { - return ptr().template obj_get(); - } +#if PK_VERSION_MAJOR == 2 + if constexpr(pkpy::is_sso_v) { + return pkpy::_py_cast(vm, ptr()); + } else { + return ptr().template obj_get(); + } #else - return (((pkpy::Py_*)ptr())->_value); + return (((pkpy::Py_*)ptr())->_value); #endif + } } }; diff --git a/include/pybind11/internal/type_traits.h b/include/pybind11/internal/type_traits.h index 1bb17172..d24374bb 100644 --- a/include/pybind11/internal/type_traits.h +++ b/include/pybind11/internal/type_traits.h @@ -25,9 +25,9 @@ struct function_traits { static_assert(dependent_false, "unsupported function type"); }; -#define PYBIND11_FUNCTION_TRAITS_SPECIALIZE(qualifiers) \ +#define PYBIND11_FUNCTION_TRAITS_SPECIALIZE(...) \ template \ - struct function_traits { \ + struct function_traits { \ using return_type = R; \ using args_type = std::tuple; \ constexpr static std::size_t args_count = sizeof...(Args); \ @@ -167,4 +167,32 @@ constexpr auto type_name() { #endif } +template +struct overload_cast_t { + template + constexpr auto operator() (Return (*pf)(Args...)) const noexcept -> decltype(pf) { + return pf; + } + + template + constexpr auto operator() (Return (Class::*pmf)(Args...), std::false_type = {}) const noexcept -> decltype(pmf) { + return pmf; + } + + template + 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(&Class::func) +/// - sweet: overload_cast(&Class::func) +template +constexpr inline overload_cast_t overload_cast; + +/// Const member function selector for overload_cast +/// - regular: static_cast(&Class::func) +/// - sweet: overload_cast(&Class::func, const_) +constexpr static auto const_ = std::true_type{}; } // namespace pybind11 diff --git a/include/pybind11/internal/types.h b/include/pybind11/internal/types.h index 1c079ca4..92a2dd37 100644 --- a/include/pybind11/internal/types.h +++ b/include/pybind11/internal/types.h @@ -385,11 +385,11 @@ public: }; 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 { - PYBIND11_TYPE_IMPLEMENT(dict, struct empty, vm->tp_dict); + PYBIND11_TYPE_IMPLEMENT(dict, pybind11::empty, vm->tp_dict); }; } // namespace pybind11 diff --git a/include/pybind11/stl.h b/include/pybind11/stl.h index 10e8e976..92c6667f 100644 --- a/include/pybind11/stl.h +++ b/include/pybind11/stl.h @@ -9,7 +9,7 @@ #include #include -namespace pybind11 { +namespace pybind11::impl { template struct type_caster> { @@ -140,5 +140,5 @@ struct type_caster>> { } }; -} // namespace pybind11 +} // namespace pybind11::impl