@@ -269,25 +269,22 @@ struct smart_holder_type_caster_class_hooks : smart_holder_type_caster_base_tag
269
269
using holder_type = pybindit::memory::smart_holder;
270
270
271
271
template <typename WrappedType>
272
- static void from_raw_pointer_take_ownership_or_shared_from_this (
273
- holder_type *uninitialized_location, WrappedType *value_ptr, ...) {
274
- new (uninitialized_location)
275
- holder_type (holder_type::from_raw_ptr_take_ownership (value_ptr));
272
+ static bool try_initialization_using_shared_from_this (holder_type *, WrappedType *, ...) {
273
+ return false ;
276
274
}
277
275
278
276
template <typename WrappedType, typename AnyBaseOfWrappedType>
279
- static void from_raw_pointer_take_ownership_or_shared_from_this (
277
+ static bool try_initialization_using_shared_from_this (
280
278
holder_type *uninitialized_location,
281
- WrappedType *value_ptr ,
279
+ WrappedType *value_ptr_w_t ,
282
280
const std::enable_shared_from_this<AnyBaseOfWrappedType> *) {
283
- auto shd_ptr
284
- = std::dynamic_pointer_cast<WrappedType>(detail::try_get_shared_from_this (value_ptr));
285
- if (shd_ptr) {
286
- new (uninitialized_location) holder_type (holder_type::from_shared_ptr (shd_ptr));
287
- } else {
288
- new (uninitialized_location)
289
- holder_type (holder_type::from_shared_ptr (std::shared_ptr<WrappedType>(value_ptr)));
290
- }
281
+ auto shd_ptr = std::dynamic_pointer_cast<WrappedType>(
282
+ detail::try_get_shared_from_this (value_ptr_w_t ));
283
+ if (!shd_ptr)
284
+ return false ;
285
+ // Note: inst->owned ignored.
286
+ new (uninitialized_location) holder_type (holder_type::from_shared_ptr (shd_ptr));
287
+ return true ;
291
288
}
292
289
293
290
template <typename WrappedType, typename AliasType>
@@ -301,21 +298,26 @@ struct smart_holder_type_caster_class_hooks : smart_holder_type_caster_base_tag
301
298
register_instance (inst, v_h.value_ptr (), v_h.type );
302
299
v_h.set_instance_registered ();
303
300
}
301
+ auto uninitialized_location = std::addressof (v_h.holder <holder_type>());
302
+ auto value_ptr_w_t = v_h.value_ptr <WrappedType>();
304
303
if (holder_void_ptr) {
305
304
// Note: inst->owned ignored.
306
305
auto holder_ptr = static_cast <holder_type *>(holder_void_ptr);
307
- new (std::addressof (v_h.holder <holder_type>())) holder_type (std::move (*holder_ptr));
308
- } else if (inst->owned ) {
309
- from_raw_pointer_take_ownership_or_shared_from_this (
310
- std::addressof (v_h.holder <holder_type>()),
311
- v_h.value_ptr <WrappedType>(),
312
- v_h.value_ptr <WrappedType>());
306
+ new (uninitialized_location) holder_type (std::move (*holder_ptr));
313
307
} else {
314
- new (std::addressof (v_h.holder <holder_type>()))
315
- holder_type (holder_type::from_raw_ptr_unowned (v_h.value_ptr <WrappedType>()));
308
+ if (!try_initialization_using_shared_from_this (
309
+ uninitialized_location, value_ptr_w_t , value_ptr_w_t )) {
310
+ if (inst->owned ) {
311
+ new (uninitialized_location)
312
+ holder_type (holder_type::from_raw_ptr_take_ownership (value_ptr_w_t ));
313
+ } else {
314
+ new (uninitialized_location)
315
+ holder_type (holder_type::from_raw_ptr_unowned (value_ptr_w_t ));
316
+ }
317
+ }
316
318
}
317
319
v_h.holder <holder_type>().pointee_depends_on_holder_owner
318
- = dynamic_raw_ptr_cast_if_possible<AliasType>(v_h. value_ptr <WrappedType>() ) != nullptr ;
320
+ = dynamic_raw_ptr_cast_if_possible<AliasType>(value_ptr_w_t ) != nullptr ;
319
321
v_h.set_holder_constructed ();
320
322
}
321
323
@@ -390,6 +392,9 @@ struct smart_holder_type_caster_load {
390
392
shared_ptr_dec_ref_deleter{
391
393
handle ((PyObject *) load_impl.loaded_v_h .inst ).inc_ref ()});
392
394
}
395
+ if (holder ().vptr_is_using_noop_deleter ) {
396
+ throw std::runtime_error (" Non-owning holder (loaded_as_shared_ptr)." );
397
+ }
393
398
std::shared_ptr<void > void_shd_ptr = holder ().template as_shared_ptr <void >();
394
399
return std::shared_ptr<T>(void_shd_ptr, type_raw_ptr);
395
400
}
0 commit comments