mirror of
https://github.com/pybind/pybind11.git
synced 2024-12-01 17:37:15 +00:00
Bring in pybind11/detail/class.h, init.h as-is from smart_holder branch (does not build).
This commit is contained in:
parent
33b0b387f1
commit
dfaa49bb21
@ -431,6 +431,8 @@ inline void clear_instance(PyObject *self) {
|
||||
if (instance->owned || v_h.holder_constructed()) {
|
||||
v_h.type->dealloc(v_h);
|
||||
}
|
||||
} else if (v_h.holder_constructed()) {
|
||||
v_h.type->dealloc(v_h); // Disowned instance.
|
||||
}
|
||||
}
|
||||
// Deallocate the value/holder layout internals:
|
||||
|
@ -10,6 +10,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "class.h"
|
||||
#include "smart_holder_sfinae_hooks_only.h"
|
||||
|
||||
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
|
||||
|
||||
@ -128,11 +129,14 @@ void construct(value_and_holder &v_h, Cpp<Class> *ptr, bool need_alias) {
|
||||
// the holder and destruction happens when we leave the C++ scope, and the holder
|
||||
// class gets to handle the destruction however it likes.
|
||||
v_h.value_ptr() = ptr;
|
||||
v_h.set_instance_registered(true); // To prevent init_instance from registering it
|
||||
v_h.type->init_instance(v_h.inst, nullptr); // Set up the holder
|
||||
v_h.set_instance_registered(true); // To prevent init_instance from registering it
|
||||
v_h.set_instance_registered(true); // SHORTCUT To prevent init_instance from registering it
|
||||
// DANGER ZONE BEGIN: exceptions will leave v_h in an invalid state.
|
||||
v_h.type->init_instance(v_h.inst, nullptr); // Set up the holder
|
||||
Holder<Class> temp_holder(std::move(v_h.holder<Holder<Class>>())); // Steal the holder
|
||||
v_h.type->dealloc(v_h); // Destroys the moved-out holder remains, resets value ptr to null
|
||||
v_h.set_instance_registered(false);
|
||||
// DANGER ZONE END.
|
||||
|
||||
construct_alias_from_cpp<Class>(is_alias_constructible<Class>{}, v_h, std::move(*ptr));
|
||||
} else {
|
||||
@ -153,7 +157,9 @@ 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>
|
||||
template <typename Class,
|
||||
detail::enable_if_t<!detail::type_uses_smart_holder_type_caster<Cpp<Class>>::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);
|
||||
@ -195,6 +201,73 @@ void construct(value_and_holder &v_h, Alias<Class> &&result, bool) {
|
||||
v_h.value_ptr() = new Alias<Class>(std::move(result));
|
||||
}
|
||||
|
||||
template <typename Class,
|
||||
typename D = std::default_delete<Cpp<Class>>,
|
||||
detail::enable_if_t<detail::type_uses_smart_holder_type_caster<Cpp<Class>>::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();
|
||||
no_nullptr(ptr);
|
||||
if (Class::has_alias && need_alias && !is_alias<Class>(ptr)) {
|
||||
throw type_error("pybind11::init(): construction failed: returned std::unique_ptr pointee "
|
||||
"is not an alias instance");
|
||||
}
|
||||
// Here and below: if the new object is a trampoline, the shared_from_this mechanism needs
|
||||
// to be prevented from accessing the smart_holder vptr, because it does not keep the
|
||||
// trampoline Python object alive. For types that don't inherit from enable_shared_from_this
|
||||
// it does not matter if void_cast_raw_ptr is true or false, therefore it's not necessary
|
||||
// to also inspect the type.
|
||||
auto smhldr = type_caster<Cpp<Class>>::smart_holder_from_unique_ptr(
|
||||
std::move(unq_ptr), /*void_cast_raw_ptr*/ Class::has_alias && is_alias<Class>(ptr));
|
||||
v_h.value_ptr() = ptr;
|
||||
v_h.type->init_instance(v_h.inst, &smhldr);
|
||||
}
|
||||
|
||||
template <typename Class,
|
||||
typename D = std::default_delete<Alias<Class>>,
|
||||
detail::enable_if_t<detail::type_uses_smart_holder_type_caster<Alias<Class>>::value, int>
|
||||
= 0>
|
||||
void construct(value_and_holder &v_h,
|
||||
std::unique_ptr<Alias<Class>, D> &&unq_ptr,
|
||||
bool /*need_alias*/) {
|
||||
auto *ptr = unq_ptr.get();
|
||||
no_nullptr(ptr);
|
||||
auto smhldr = type_caster<Alias<Class>>::smart_holder_from_unique_ptr(
|
||||
std::move(unq_ptr), /*void_cast_raw_ptr*/ true);
|
||||
v_h.value_ptr() = ptr;
|
||||
v_h.type->init_instance(v_h.inst, &smhldr);
|
||||
}
|
||||
|
||||
template <typename Class,
|
||||
detail::enable_if_t<detail::type_uses_smart_holder_type_caster<Cpp<Class>>::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();
|
||||
no_nullptr(ptr);
|
||||
if (Class::has_alias && need_alias && !is_alias<Class>(ptr)) {
|
||||
throw type_error("pybind11::init(): construction failed: returned std::shared_ptr pointee "
|
||||
"is not an alias instance");
|
||||
}
|
||||
auto smhldr = type_caster<Cpp<Class>>::smart_holder_from_shared_ptr(shd_ptr);
|
||||
v_h.value_ptr() = ptr;
|
||||
v_h.type->init_instance(v_h.inst, &smhldr);
|
||||
}
|
||||
|
||||
template <typename Class,
|
||||
detail::enable_if_t<detail::type_uses_smart_holder_type_caster<Alias<Class>>::value, int>
|
||||
= 0>
|
||||
void construct(value_and_holder &v_h,
|
||||
std::shared_ptr<Alias<Class>> &&shd_ptr,
|
||||
bool /*need_alias*/) {
|
||||
auto *ptr = shd_ptr.get();
|
||||
no_nullptr(ptr);
|
||||
auto smhldr = type_caster<Alias<Class>>::smart_holder_from_shared_ptr(shd_ptr);
|
||||
v_h.value_ptr() = ptr;
|
||||
v_h.type->init_instance(v_h.inst, &smhldr);
|
||||
}
|
||||
|
||||
// Implementing class for py::init<...>()
|
||||
template <typename... Args>
|
||||
struct constructor {
|
||||
|
Loading…
Reference in New Issue
Block a user