Introduce detail/using_smart_holder.h and remove pybindit::memory:: in most places.

This commit is contained in:
Ralf W. Grosse-Kunstleve 2024-07-19 00:23:14 -07:00
parent 583c07bffd
commit 7296c39705
10 changed files with 52 additions and 51 deletions

View File

@ -156,6 +156,7 @@ set(PYBIND11_HEADERS
include/pybind11/detail/smart_holder_poc.h
include/pybind11/detail/type_caster_base.h
include/pybind11/detail/typeid.h
include/pybind11/detail/using_smart_holder.h
include/pybind11/detail/value_and_holder.h
include/pybind11/attr.h
include/pybind11/buffer_info.h

View File

@ -1137,7 +1137,7 @@ struct is_holder_type<base, std::unique_ptr<base, deleter>> : std::true_type {};
#ifdef PYBIND11_HAVE_INTERNALS_WITH_SMART_HOLDER_SUPPORT
template <typename base>
struct is_holder_type<base, pybindit::memory::smart_holder> : std::true_type {};
struct is_holder_type<base, smart_holder> : std::true_type {};
#endif
#ifdef PYBIND11_DISABLE_HANDLE_TYPE_NAME_DEFAULT_IMPLEMENTATION // See PR #4888

View File

@ -10,7 +10,7 @@
#pragma once
#include "class.h"
#include "smart_holder_poc.h"
#include "using_smart_holder.h"
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
@ -156,10 +156,8 @@ void construct(value_and_holder &v_h, Alias<Class> *alias_ptr, bool) {
// holder. This also handles types like std::shared_ptr<T> and std::unique_ptr<T> where T is a
// derived type (through those holder's implicit conversion from derived class holder
// constructors).
template <
typename Class,
detail::enable_if_t<!std::is_same<Holder<Class>, pybindit::memory::smart_holder>::value, int>
= 0>
template <typename Class,
detail::enable_if_t<!std::is_same<Holder<Class>, smart_holder>::value, int> = 0>
void construct(value_and_holder &v_h, Holder<Class> holder, bool need_alias) {
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(need_alias);
auto *ptr = holder_helper<Holder<Class>>::get(holder);
@ -203,23 +201,21 @@ void construct(value_and_holder &v_h, Alias<Class> &&result, bool) {
namespace originally_smart_holder_type_casters_h {
template <typename T, typename D>
pybindit::memory::smart_holder smart_holder_from_unique_ptr(std::unique_ptr<T, D> &&unq_ptr,
bool void_cast_raw_ptr) {
smart_holder smart_holder_from_unique_ptr(std::unique_ptr<T, D> &&unq_ptr,
bool void_cast_raw_ptr) {
void *void_ptr = void_cast_raw_ptr ? static_cast<void *>(unq_ptr.get()) : nullptr;
return pybindit::memory::smart_holder::from_unique_ptr(std::move(unq_ptr), void_ptr);
return smart_holder::from_unique_ptr(std::move(unq_ptr), void_ptr);
}
template <typename T>
pybindit::memory::smart_holder smart_holder_from_shared_ptr(std::shared_ptr<T> shd_ptr) {
return pybindit::memory::smart_holder::from_shared_ptr(shd_ptr);
smart_holder smart_holder_from_shared_ptr(std::shared_ptr<T> shd_ptr) {
return smart_holder::from_shared_ptr(shd_ptr);
}
} // namespace originally_smart_holder_type_casters_h
template <
typename Class,
typename D = std::default_delete<Cpp<Class>>,
detail::enable_if_t<std::is_same<Holder<Class>, pybindit::memory::smart_holder>::value, int>
= 0>
template <typename Class,
typename D = std::default_delete<Cpp<Class>>,
detail::enable_if_t<std::is_same<Holder<Class>, smart_holder>::value, int> = 0>
void construct(value_and_holder &v_h, std::unique_ptr<Cpp<Class>, D> &&unq_ptr, bool need_alias) {
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(need_alias);
auto *ptr = unq_ptr.get();
@ -239,11 +235,9 @@ void construct(value_and_holder &v_h, std::unique_ptr<Cpp<Class>, D> &&unq_ptr,
v_h.type->init_instance(v_h.inst, &smhldr);
}
template <
typename Class,
typename D = std::default_delete<Alias<Class>>,
detail::enable_if_t<std::is_same<Holder<Class>, pybindit::memory::smart_holder>::value, int>
= 0>
template <typename Class,
typename D = std::default_delete<Alias<Class>>,
detail::enable_if_t<std::is_same<Holder<Class>, smart_holder>::value, int> = 0>
void construct(value_and_holder &v_h,
std::unique_ptr<Alias<Class>, D> &&unq_ptr,
bool /*need_alias*/) {
@ -255,10 +249,8 @@ void construct(value_and_holder &v_h,
v_h.type->init_instance(v_h.inst, &smhldr);
}
template <
typename Class,
detail::enable_if_t<std::is_same<Holder<Class>, pybindit::memory::smart_holder>::value, int>
= 0>
template <typename Class,
detail::enable_if_t<std::is_same<Holder<Class>, smart_holder>::value, int> = 0>
void construct(value_and_holder &v_h, std::shared_ptr<Cpp<Class>> &&shd_ptr, bool need_alias) {
PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(need_alias);
auto *ptr = shd_ptr.get();
@ -272,10 +264,8 @@ void construct(value_and_holder &v_h, std::shared_ptr<Cpp<Class>> &&shd_ptr, boo
v_h.type->init_instance(v_h.inst, &smhldr);
}
template <
typename Class,
detail::enable_if_t<std::is_same<Holder<Class>, pybindit::memory::smart_holder>::value, int>
= 0>
template <typename Class,
detail::enable_if_t<std::is_same<Holder<Class>, smart_holder>::value, int> = 0>
void construct(value_and_holder &v_h,
std::shared_ptr<Alias<Class>> &&shd_ptr,
bool /*need_alias*/) {

View File

@ -16,8 +16,8 @@
#include "descr.h"
#include "dynamic_raw_ptr_cast_if_possible.h"
#include "internals.h"
#include "smart_holder_poc.h"
#include "typeid.h"
#include "using_smart_holder.h"
#include "value_and_holder.h"
#include <cstdint>
@ -484,9 +484,7 @@ struct value_and_holder_helper {
return loaded_v_h.vh != nullptr && loaded_v_h.holder_constructed();
}
pybindit::memory::smart_holder &holder() const {
return loaded_v_h.holder<pybindit::memory::smart_holder>();
}
smart_holder &holder() const { return loaded_v_h.holder<smart_holder>(); }
void throw_if_uninitialized_or_disowned_holder(const char *typeid_name) const {
static const std::string missing_value_msg = "Missing value for wrapped C++ type `";
@ -548,7 +546,7 @@ handle smart_holder_from_unique_ptr(std::unique_ptr<T, D> &&src,
if (self_life_support != nullptr) {
value_and_holder &v_h = self_life_support->v_h;
if (v_h.inst != nullptr && v_h.vh != nullptr) {
auto &holder = v_h.holder<pybindit::memory::smart_holder>();
auto &holder = v_h.holder<smart_holder>();
if (!holder.is_disowned) {
pybind11_fail("smart_holder_from_unique_ptr: unexpected "
"smart_holder.is_disowned failure.");
@ -576,8 +574,7 @@ handle smart_holder_from_unique_ptr(std::unique_ptr<T, D> &&src,
// SMART_HOLDER_WIP: IMPROVABLE: Is there a better solution?
src_raw_void_ptr = nullptr;
}
auto smhldr
= pybindit::memory::smart_holder::from_unique_ptr(std::move(src), src_raw_void_ptr);
auto smhldr = smart_holder::from_unique_ptr(std::move(src), src_raw_void_ptr);
tinfo->init_instance(inst_raw_ptr, static_cast<const void *>(&smhldr));
if (policy == return_value_policy::reference_internal) {
@ -639,8 +636,8 @@ handle smart_holder_from_shared_ptr(const std::shared_ptr<T> &src,
void *&valueptr = values_and_holders(inst_raw_ptr).begin()->value_ptr();
valueptr = src_raw_void_ptr;
auto smhldr = pybindit::memory::smart_holder::from_shared_ptr(
std::shared_ptr<void>(src, const_cast<void *>(st.first)));
auto smhldr
= smart_holder::from_shared_ptr(std::shared_ptr<void>(src, const_cast<void *>(st.first)));
tinfo->init_instance(inst_raw_ptr, static_cast<const void *>(&smhldr));
if (policy == return_value_policy::reference_internal) {
@ -710,7 +707,7 @@ inline std::unique_ptr<T, D> unique_with_deleter(T *raw_ptr, std::unique_ptr<D>
template <typename T>
struct load_helper : value_and_holder_helper {
using holder_type = pybindit::memory::smart_holder;
using holder_type = smart_holder;
static std::shared_ptr<T> make_shared_ptr_with_responsible_parent(T *raw_ptr, handle parent) {
return std::shared_ptr<T>(raw_ptr, shared_ptr_parent_life_support(parent.ptr()));

View File

@ -0,0 +1,14 @@
// Copyright (c) 2024 The Pybind Development Team.
// All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
#pragma once
#include "common.h"
#include "smart_holder_poc.h"
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
using pybindit::memory::smart_holder;
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)

View File

@ -13,7 +13,7 @@
#include "detail/class.h"
#include "detail/dynamic_raw_ptr_cast_if_possible.h"
#include "detail/init.h"
#include "detail/smart_holder_poc.h"
#include "detail/using_smart_holder.h"
#include "attr.h"
#include "gil.h"
#include "gil_safe_call_once.h"
@ -1800,7 +1800,7 @@ struct property_cpp_function<
#ifdef PYBIND11_USE_SMART_HOLDER_AS_DEFAULT
// BAKEIN_WIP: Add comment to explain: This is meant for stress-testing only.
template <typename>
using default_holder_type = pybindit::memory::smart_holder;
using default_holder_type = smart_holder;
#else
template <typename T>
using default_holder_type = std::unique_ptr<T>;
@ -1863,7 +1863,7 @@ public:
record.holder_enum_v = detail::holder_enum_t::std_unique_ptr;
} else if (detail::is_instantiation<std::shared_ptr, holder_type>::value) {
record.holder_enum_v = detail::holder_enum_t::std_shared_ptr;
} else if (std::is_same<holder_type, pybindit::memory::smart_holder>::value) {
} else if (std::is_same<holder_type, smart_holder>::value) {
record.holder_enum_v = detail::holder_enum_t::smart_holder;
} else {
record.holder_enum_v = detail::holder_enum_t::custom_holder;
@ -2193,8 +2193,7 @@ private:
/// an optional pointer to an existing holder to use; if not specified and the instance is
/// `.owned`, a new holder will be constructed to manage the value pointer.
template <typename H = holder_type,
detail::enable_if_t<!std::is_same<H, pybindit::memory::smart_holder>::value, int>
= 0>
detail::enable_if_t<!std::is_same<H, smart_holder>::value, int> = 0>
static void init_instance(detail::instance *inst, const void *holder_ptr) {
auto v_h = inst->get_value_and_holder(detail::get_type_info(typeid(type)));
if (!v_h.instance_registered()) {
@ -2230,7 +2229,7 @@ private:
}
template <typename H = holder_type,
detail::enable_if_t<std::is_same<H, pybindit::memory::smart_holder>::value, int> = 0>
detail::enable_if_t<std::is_same<H, smart_holder>::value, int> = 0>
static void init_instance(detail::instance *inst, const void *holder_const_void_ptr) {
// Need for const_cast is a consequence of the type_info::init_instance type:
// void (*init_instance)(instance *, const void *);

View File

@ -16,9 +16,9 @@ PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
// Supports easier switching between py::class_<T> and py::class_<T, py::smart_holder>:
// users can simply replace the `_` in `class_` with `h` or vice versa.
template <typename type_, typename... options>
class classh : public class_<type_, pybindit::memory::smart_holder, options...> {
class classh : public class_<type_, smart_holder, options...> {
public:
using class_<type_, pybindit::memory::smart_holder, options...>::class_;
using class_<type_, smart_holder, options...>::class_;
};
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)

View File

@ -5,7 +5,7 @@
#pragma once
#include "detail/common.h"
#include "detail/smart_holder_poc.h"
#include "detail/using_smart_holder.h"
#include "detail/value_and_holder.h"
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
@ -40,7 +40,7 @@ struct trampoline_self_life_support {
if (value_void_ptr != nullptr) {
PyGILState_STATE threadstate = PyGILState_Ensure();
v_h.value_ptr() = nullptr;
v_h.holder<pybindit::memory::smart_holder>().release_disowned();
v_h.holder<smart_holder>().release_disowned();
detail::deregister_instance(v_h.inst, value_void_ptr, v_h.type);
Py_DECREF((PyObject *) v_h.inst); // Must be after deregister.
PyGILState_Release(threadstate);

View File

@ -62,6 +62,7 @@ detail_headers = {
"include/pybind11/detail/smart_holder_poc.h",
"include/pybind11/detail/type_caster_base.h",
"include/pybind11/detail/typeid.h",
"include/pybind11/detail/using_smart_holder.h",
"include/pybind11/detail/value_and_holder.h",
}

View File

@ -608,8 +608,7 @@ CHECK_NOALIAS(8);
std::TYPE##_ptr<BreaksBase<(N)>>>::value, \
"DoesntBreak" #N " has wrong holder_type!")
#define CHECK_SMART_HOLDER(N) \
static_assert(std::is_same<typename DoesntBreak##N::holder_type, \
pybindit::memory::smart_holder>::value, \
static_assert(std::is_same<typename DoesntBreak##N::holder_type, py::smart_holder>::value, \
"DoesntBreak" #N " has wrong holder_type!")
CHECK_HOLDER(1, unique);
CHECK_HOLDER(2, unique);