Skip to content

Commit a6c47cc

Browse files
committed
Fix smart_holder multiple inheritance tests
The original pybind11 holder supported multiple inheritance by recursively creating type casters until it finds one for the source type, then converting each value in turn to the next type via typeinfo->implicit_cast The smart_holder only stored the last implicit_cast, which was incorrect. This commit changes it to create a list of implicit_cast functions that are appended to during the recursive type caster creation, and when the time comes to cast to the destination type, it calls all of them in the correct order.
1 parent 152bb10 commit a6c47cc

File tree

1 file changed

+9
-5
lines changed

1 file changed

+9
-5
lines changed

include/pybind11/detail/smart_holder_type_casters.h

+9-5
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,9 @@ class modified_type_caster_generic_load_impl {
9090
}
9191
loaded_v_h = sub_caster.loaded_v_h;
9292
loaded_v_h_cpptype = cast.first;
93-
implicit_cast = cast.second;
93+
// the sub_caster is being discarded, so steal its vector
94+
implicit_casts = std::move(sub_caster.implicit_casts);
95+
implicit_casts.emplace_back(cast.second);
9496
return true;
9597
}
9698
}
@@ -149,7 +151,7 @@ class modified_type_caster_generic_load_impl {
149151
}
150152
loaded_v_h = foreign_loader->loaded_v_h;
151153
loaded_v_h_cpptype = foreign_loader->loaded_v_h_cpptype;
152-
implicit_cast = foreign_loader->implicit_cast;
154+
implicit_casts = foreign_loader->implicit_casts; // SMART_HOLDER_WIP: should this be a copy or move?
153155
return true;
154156
}
155157
return false;
@@ -251,7 +253,7 @@ class modified_type_caster_generic_load_impl {
251253
const std::type_info *cpptype = nullptr;
252254
void *unowned_void_ptr_from_direct_conversion = nullptr;
253255
const std::type_info *loaded_v_h_cpptype = nullptr;
254-
void *(*implicit_cast)(void *) = nullptr;
256+
std::vector<void *(*)(void *)> implicit_casts;
255257
value_and_holder loaded_v_h;
256258
bool reinterpret_cast_deemed_ok = false;
257259
// Magic number intentionally hard-coded, to guard against class_ holder mixups.
@@ -521,8 +523,10 @@ struct smart_holder_type_caster_load {
521523

522524
T *convert_type(void *void_ptr) const {
523525
if (void_ptr != nullptr && load_impl.loaded_v_h_cpptype != nullptr
524-
&& !load_impl.reinterpret_cast_deemed_ok && load_impl.implicit_cast != nullptr) {
525-
void_ptr = load_impl.implicit_cast(void_ptr);
526+
&& !load_impl.reinterpret_cast_deemed_ok && !load_impl.implicit_casts.empty()) {
527+
for (auto implicit_cast: load_impl.implicit_casts) {
528+
void_ptr = implicit_cast(void_ptr);
529+
}
526530
}
527531
return static_cast<T *>(void_ptr);
528532
}

0 commit comments

Comments
 (0)