A couple more enhancements based on feedback by @laramiel.

This commit is contained in:
Ralf W. Grosse-Kunstleve 2021-06-25 07:42:32 -07:00 committed by Ralf W. Grosse-Kunstleve
parent 64716cc14c
commit 9fce2956bc
1 changed files with 15 additions and 13 deletions

View File

@ -277,11 +277,16 @@ struct smart_holder_type_caster_class_hooks : smart_holder_type_caster_base_tag
return false; return false;
} }
template <typename WrappedType, typename AnyBaseOfWrappedType> // Adopting existing approach used by type_caster_base, although it leads to somewhat fuzzy
// ownership semantics: if we deteced via shared_from_this that a shared_ptr exists already, it
// is reused, irrespective of the return_value_policy in effect.
// "SomeBaseOfWrappedType" is needed because std::enable_shared_from_this is not necessarily a
// direct base of WrappedType.
template <typename WrappedType, typename SomeBaseOfWrappedType>
static bool try_initialization_using_shared_from_this( static bool try_initialization_using_shared_from_this(
holder_type *uninitialized_location, holder_type *uninitialized_location,
WrappedType *value_ptr_w_t, WrappedType *value_ptr_w_t,
const std::enable_shared_from_this<AnyBaseOfWrappedType> *) { const std::enable_shared_from_this<SomeBaseOfWrappedType> *) {
auto shd_ptr = std::dynamic_pointer_cast<WrappedType>( auto shd_ptr = std::dynamic_pointer_cast<WrappedType>(
detail::try_get_shared_from_this(value_ptr_w_t)); detail::try_get_shared_from_this(value_ptr_w_t));
if (!shd_ptr) if (!shd_ptr)
@ -310,19 +315,16 @@ struct smart_holder_type_caster_class_hooks : smart_holder_type_caster_base_tag
// Note: inst->owned ignored. // Note: inst->owned ignored.
auto holder_ptr = static_cast<holder_type *>(holder_void_ptr); auto holder_ptr = static_cast<holder_type *>(holder_void_ptr);
new (uninitialized_location) holder_type(std::move(*holder_ptr)); new (uninitialized_location) holder_type(std::move(*holder_ptr));
} else { } else if (!try_initialization_using_shared_from_this(
if (!try_initialization_using_shared_from_this(
uninitialized_location, value_ptr_w_t, value_ptr_w_t)) { uninitialized_location, value_ptr_w_t, value_ptr_w_t)) {
if (inst->owned) { if (inst->owned) {
new (uninitialized_location) new (uninitialized_location) holder_type(holder_type::from_raw_ptr_take_ownership(
holder_type(holder_type::from_raw_ptr_take_ownership(
value_ptr_w_t, /*void_cast_raw_ptr*/ pointee_depends_on_holder_owner)); value_ptr_w_t, /*void_cast_raw_ptr*/ pointee_depends_on_holder_owner));
} else { } else {
new (uninitialized_location) new (uninitialized_location)
holder_type(holder_type::from_raw_ptr_unowned(value_ptr_w_t)); holder_type(holder_type::from_raw_ptr_unowned(value_ptr_w_t));
} }
} }
}
v_h.holder<holder_type>().pointee_depends_on_holder_owner v_h.holder<holder_type>().pointee_depends_on_holder_owner
= pointee_depends_on_holder_owner; = pointee_depends_on_holder_owner;
v_h.set_holder_constructed(); v_h.set_holder_constructed();