Resolving TODOs for from_unique_ptr void_cast_raw_ptr. Adding test to exercise the path through cast. The path through init.h is missing a test that would fail if the flag is incorrect. The plan is to systematically cover all situations (there are many that are not exercised for shared_from_this).

This commit is contained in:
Ralf W. Grosse-Kunstleve
2021-06-24 06:04:34 -07:00
committed by Ralf W. Grosse-Kunstleve
parent a0e19bdc46
commit 146a925e4e
5 changed files with 27 additions and 12 deletions

View File

@@ -182,8 +182,8 @@ void construct(value_and_holder &v_h, std::unique_ptr<Cpp<Class>, D> &&unq_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");
auto smhldr
= type_caster<Cpp<Class>>::template smart_holder_from_unique_ptr(std::move(unq_ptr));
auto smhldr = type_caster<Cpp<Class>>::template smart_holder_from_unique_ptr(
std::move(unq_ptr), Class::has_alias && is_alias<Class>(ptr));
v_h.value_ptr() = ptr;
v_h.type->init_instance(v_h.inst, &smhldr);
}
@@ -197,8 +197,8 @@ void construct(value_and_holder &v_h,
bool /*need_alias*/) {
auto *ptr = unq_ptr.get();
no_nullptr(ptr);
auto smhldr
= type_caster<Alias<Class>>::template smart_holder_from_unique_ptr(std::move(unq_ptr));
auto smhldr = type_caster<Alias<Class>>::template smart_holder_from_unique_ptr(
std::move(unq_ptr), true);
v_h.value_ptr() = ptr;
v_h.type->init_instance(v_h.inst, &smhldr);
}

View File

@@ -40,6 +40,10 @@ Details:
* By choice, the smart_holder is movable but not copyable, to keep the design
simple, and to guard against accidental copying overhead.
* The `void_cast_raw_ptr` option is needed to make the `smart_holder` `vptr`
member invisible to the `shared_from_this` mechanism, in case the lifetime
of a `PyObject` is tied to the pointee.
*/
#pragma once
@@ -51,7 +55,7 @@ Details:
#include <type_traits>
#include <typeinfo>
//#include <iostream>
// #include <iostream>
// inline void to_cout(const std::string &msg) { std::cout << msg << std::endl; }
inline void to_cout(const std::string &) {}

View File

@@ -317,7 +317,7 @@ struct smart_holder_type_caster_class_hooks : smart_holder_type_caster_base_tag
if (inst->owned) {
new (uninitialized_location)
holder_type(holder_type::from_raw_ptr_take_ownership(
value_ptr_w_t, pointee_depends_on_holder_owner));
value_ptr_w_t, /*void_cast_raw_ptr*/ pointee_depends_on_holder_owner));
} else {
new (uninitialized_location)
holder_type(holder_type::from_raw_ptr_unowned(value_ptr_w_t));
@@ -330,9 +330,10 @@ struct smart_holder_type_caster_class_hooks : smart_holder_type_caster_base_tag
}
template <typename T, typename D>
static smart_holder smart_holder_from_unique_ptr(std::unique_ptr<T, D> &&unq_ptr) {
return pybindit::memory::smart_holder::from_unique_ptr(
std::move(unq_ptr), /*TODO pointee_depends_on_holder_owner*/ true);
static smart_holder smart_holder_from_unique_ptr(std::unique_ptr<T, D> &&unq_ptr,
bool void_cast_raw_ptr) {
return pybindit::memory::smart_holder::from_unique_ptr(std::move(unq_ptr),
void_cast_raw_ptr);
}
template <typename T>
@@ -805,8 +806,8 @@ struct smart_holder_type_caster<std::unique_ptr<T, D>> : smart_holder_type_caste
void *&valueptr = values_and_holders(inst_raw_ptr).begin()->value_ptr();
valueptr = src_raw_void_ptr;
auto smhldr = pybindit::memory::smart_holder::from_unique_ptr(
std::move(src), /*TODO pointee_depends_on_holder_owner*/ true);
auto smhldr = pybindit::memory::smart_holder::from_unique_ptr(std::move(src),
/*void_cast_raw_ptr*/ false);
tinfo->init_instance(inst_raw_ptr, static_cast<const void *>(&smhldr));
if (policy == return_value_policy::reference_internal)