diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h index da138d53d..412a6e748 100644 --- a/include/pybind11/cast.h +++ b/include/pybind11/cast.h @@ -1027,9 +1027,10 @@ public: if (typeinfo->default_holder) { sh_load_helper.loaded_v_h = v_h; sh_load_helper.loaded_v_h.type = get_type_info(typeid(type)); + type_caster_generic::load_value(std::move(v_h)); return; } - throw std::runtime_error("BAKEIN_WIP: What is the best behavior here?"); + throw std::runtime_error("BAKEIN_WIP: What is the best behavior here (load_value)?"); } template @@ -1037,11 +1038,29 @@ public: explicit operator std::unique_ptr() { if (typeinfo->default_holder) { - return sh_load_helper.template loaded_as_unique_ptr(); + return sh_load_helper.template loaded_as_unique_ptr(value); } pybind11_fail("Passing std::unique_ptr from Python to C++ requires smart_holder."); } + bool try_implicit_casts(handle src, bool convert) { + for (auto &cast : typeinfo->implicit_casts) { + move_only_holder_caster sub_caster(*cast.first); + if (sub_caster.load(src, convert)) { + value = cast.second(sub_caster.value); + if (typeinfo->default_holder) { + // BAKEIN_WIP: Copy pointer only? + sh_load_helper.loaded_v_h = sub_caster.sh_load_helper.loaded_v_h; + } else { + throw std::runtime_error( + "BAKEIN_WIP: What is the best behavior here (try_implicit_casts)?"); + } + return true; + } + } + return false; + } + static bool try_direct_conversions(handle) { return false; } smart_holder_type_caster_support::load_helper> sh_load_helper; // Const2Mutbl diff --git a/include/pybind11/detail/type_caster_base.h b/include/pybind11/detail/type_caster_base.h index 779bb15a4..5efdf308b 100644 --- a/include/pybind11/detail/type_caster_base.h +++ b/include/pybind11/detail/type_caster_base.h @@ -887,7 +887,8 @@ struct load_helper : value_and_holder_helper { } template - std::unique_ptr loaded_as_unique_ptr(const char *context = "loaded_as_unique_ptr") { + std::unique_ptr loaded_as_unique_ptr(void *raw_void_ptr, + const char *context = "loaded_as_unique_ptr") { if (!have_holder()) { return unique_with_deleter(nullptr, std::unique_ptr()); } @@ -896,17 +897,8 @@ struct load_helper : value_and_holder_helper { holder().ensure_is_not_disowned(context); holder().template ensure_compatible_rtti_uqp_del(context); holder().ensure_use_count_1(context); - auto raw_void_ptr = holder().template as_raw_ptr_unowned(); - void *value_void_ptr = loaded_v_h.value_ptr(); - if (value_void_ptr != raw_void_ptr) { - pybind11_fail("smart_holder_type_casters: loaded_as_unique_ptr failure:" - " value_void_ptr != raw_void_ptr"); - } - - // SMART_HOLDER_WIP: MISSING: Safety checks for type conversions - // (T must be polymorphic or meet certain other conditions). - T *raw_type_ptr = convert_type(raw_void_ptr); + T *raw_type_ptr = static_cast(raw_void_ptr); auto *self_life_support = dynamic_raw_ptr_cast_if_possible(raw_type_ptr); @@ -943,6 +935,7 @@ struct load_helper : value_and_holder_helper { if (self_life_support != nullptr) { self_life_support->activate_life_support(loaded_v_h); } else { + void *value_void_ptr = loaded_v_h.value_ptr(); loaded_v_h.value_ptr() = nullptr; deregister_instance(loaded_v_h.inst, value_void_ptr, loaded_v_h.type); }