[smart_holder] test_class_sh_mi_thunks (started from PR #4374) (#4380)

* Content of PR #4374 applied on top of smart_holder branch.

* More tests, with USE_SH switch. [ci skip]

* Use `std::dynamic_pointer_cast<Base0>` [ci skip]

* All tests pass when using `m.make_derived_as_base0_raw_ptr()`, with `USE_SH` defined or not defined. [ci skip]

* WIP

* Debug LOOOK & one-line bug fix:

```diff
-        auto smhldr = pybindit::memory::smart_holder::from_shared_ptr(src);
+        auto smhldr = pybindit::memory::smart_holder::from_shared_ptr(std::shared_ptr<void>(src, const_cast<void *>(st.first)));
```

* Remove all print LOOOK and clang-format the fix.

* Resolve clang-tidy errors.

* Systematic test matrix.

* Bug fix in `smart_holder_type_caster<std::unique_ptr<T, D>>::cast()`

* Rename: test_mi_debug -> test_class_sh_mi_thunks

* Add `test_ptrdiff_derived_base0()`

* Miscellaneous polishing (naming, comments). No functional changes.

* Improve test_class_sh_mi_thunks.py implementation. No change in test coverage.

* Resolve clang-tidy error.
This commit is contained in:
Ralf W. Grosse-Kunstleve
2022-12-12 19:55:16 -08:00
committed by GitHub
parent 53b80b4312
commit 4766065e5c
5 changed files with 175 additions and 12 deletions

View File

@@ -301,7 +301,7 @@ struct smart_holder {
template <typename T, typename D>
static smart_holder from_unique_ptr(std::unique_ptr<T, D> &&unq_ptr,
bool void_cast_raw_ptr = false) {
void *void_ptr = nullptr) {
smart_holder hld;
hld.rtti_uqp_del = &typeid(D);
hld.vptr_is_using_builtin_delete = is_std_default_delete<T>(*hld.rtti_uqp_del);
@@ -311,8 +311,8 @@ struct smart_holder {
} else {
gd = make_guarded_custom_deleter<T, D>(true);
}
if (void_cast_raw_ptr) {
hld.vptr.reset(static_cast<void *>(unq_ptr.get()), std::move(gd));
if (void_ptr != nullptr) {
hld.vptr.reset(void_ptr, std::move(gd));
} else {
hld.vptr.reset(unq_ptr.get(), std::move(gd));
}

View File

@@ -386,8 +386,8 @@ 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,
bool void_cast_raw_ptr) {
return pybindit::memory::smart_holder::from_unique_ptr(std::move(unq_ptr),
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);
}
template <typename T>
@@ -836,7 +836,8 @@ struct smart_holder_type_caster<std::shared_ptr<T>> : smart_holder_type_caster_l
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(src);
auto smhldr = pybindit::memory::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) {
@@ -890,17 +891,16 @@ struct smart_holder_type_caster<std::unique_ptr<T, D>> : smart_holder_type_caste
return none().release();
}
auto src_raw_ptr = src.get();
auto st = type_caster_base<T>::src_and_type(src_raw_ptr);
auto st = type_caster_base<T>::src_and_type(src.get());
if (st.second == nullptr) {
return handle(); // no type info: error will be set already
}
void *src_raw_void_ptr = static_cast<void *>(src_raw_ptr);
void *src_raw_void_ptr = const_cast<void *>(st.first);
const detail::type_info *tinfo = st.second;
if (handle existing_inst = find_registered_python_instance(src_raw_void_ptr, tinfo)) {
auto *self_life_support
= dynamic_raw_ptr_cast_if_possible<trampoline_self_life_support>(src_raw_ptr);
= dynamic_raw_ptr_cast_if_possible<trampoline_self_life_support>(src.get());
if (self_life_support != nullptr) {
value_and_holder &v_h = self_life_support->v_h;
if (v_h.inst != nullptr && v_h.vh != nullptr) {
@@ -926,8 +926,14 @@ 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),
/*void_cast_raw_ptr*/ false);
if (static_cast<void *>(src.get()) == src_raw_void_ptr) {
// This is a multiple-inheritance situation that is incompatible with the current
// shared_from_this handling (see PR #3023).
// 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);
tinfo->init_instance(inst_raw_ptr, static_cast<const void *>(&smhldr));
if (policy == return_value_policy::reference_internal) {