|
13 | 13 | #include "detail/argument_vector.h" |
14 | 14 | #include "detail/common.h" |
15 | 15 | #include "detail/descr.h" |
| 16 | +#include "detail/holder_caster_foreign_helpers.h" |
16 | 17 | #include "detail/native_enum_data.h" |
17 | 18 | #include "detail/type_caster_base.h" |
18 | 19 | #include "detail/typeid.h" |
@@ -907,6 +908,10 @@ struct copyable_holder_caster : public type_caster_base<type> { |
907 | 908 | } |
908 | 909 | } |
909 | 910 |
|
| 911 | + bool set_foreign_holder(handle src) { |
| 912 | + return holder_caster_foreign_helpers::set_foreign_holder(src, (type *) value, &holder); |
| 913 | + } |
| 914 | + |
910 | 915 | void load_value(value_and_holder &&v_h) { |
911 | 916 | if (v_h.holder_constructed()) { |
912 | 917 | value = v_h.value_ptr(); |
@@ -977,22 +982,22 @@ struct copyable_holder_caster< |
977 | 982 | } |
978 | 983 |
|
979 | 984 | explicit operator std::shared_ptr<type> *() { |
980 | | - if (typeinfo->holder_enum_v == detail::holder_enum_t::smart_holder) { |
| 985 | + if (sh_load_helper.was_populated) { |
981 | 986 | pybind11_fail("Passing `std::shared_ptr<T> *` from Python to C++ is not supported " |
982 | 987 | "(inherently unsafe)."); |
983 | 988 | } |
984 | 989 | return std::addressof(shared_ptr_storage); |
985 | 990 | } |
986 | 991 |
|
987 | 992 | explicit operator std::shared_ptr<type> &() { |
988 | | - if (typeinfo->holder_enum_v == detail::holder_enum_t::smart_holder) { |
| 993 | + if (sh_load_helper.was_populated) { |
989 | 994 | shared_ptr_storage = sh_load_helper.load_as_shared_ptr(typeinfo, value); |
990 | 995 | } |
991 | 996 | return shared_ptr_storage; |
992 | 997 | } |
993 | 998 |
|
994 | 999 | std::weak_ptr<type> potentially_slicing_weak_ptr() { |
995 | | - if (typeinfo->holder_enum_v == detail::holder_enum_t::smart_holder) { |
| 1000 | + if (sh_load_helper.was_populated) { |
996 | 1001 | // Reusing shared_ptr code to minimize code complexity. |
997 | 1002 | shared_ptr_storage |
998 | 1003 | = sh_load_helper.load_as_shared_ptr(typeinfo, |
@@ -1041,6 +1046,11 @@ struct copyable_holder_caster< |
1041 | 1046 | } |
1042 | 1047 | } |
1043 | 1048 |
|
| 1049 | + bool set_foreign_holder(handle src) { |
| 1050 | + return holder_caster_foreign_helpers::set_foreign_holder( |
| 1051 | + src, (type *) value, &shared_ptr_storage); |
| 1052 | + } |
| 1053 | + |
1044 | 1054 | void load_value(value_and_holder &&v_h) { |
1045 | 1055 | if (typeinfo->holder_enum_v == detail::holder_enum_t::smart_holder) { |
1046 | 1056 | sh_load_helper.loaded_v_h = v_h; |
@@ -1078,6 +1088,7 @@ struct copyable_holder_caster< |
1078 | 1088 | value = cast.second(sub_caster.value); |
1079 | 1089 | if (typeinfo->holder_enum_v == detail::holder_enum_t::smart_holder) { |
1080 | 1090 | sh_load_helper.loaded_v_h = sub_caster.sh_load_helper.loaded_v_h; |
| 1091 | + sh_load_helper.was_populated = true; |
1081 | 1092 | } else { |
1082 | 1093 | shared_ptr_storage |
1083 | 1094 | = std::shared_ptr<type>(sub_caster.shared_ptr_storage, (type *) value); |
@@ -1224,6 +1235,12 @@ struct move_only_holder_caster< |
1224 | 1235 | return false; |
1225 | 1236 | } |
1226 | 1237 |
|
| 1238 | + bool set_foreign_holder(handle) { |
| 1239 | + throw cast_error("Foreign instance cannot be converted to std::unique_ptr " |
| 1240 | + "because we don't know how to make it relinquish " |
| 1241 | + "ownership"); |
| 1242 | + } |
| 1243 | + |
1227 | 1244 | void load_value(value_and_holder &&v_h) { |
1228 | 1245 | if (typeinfo->holder_enum_v == detail::holder_enum_t::smart_holder) { |
1229 | 1246 | sh_load_helper.loaded_v_h = v_h; |
@@ -1282,6 +1299,7 @@ struct move_only_holder_caster< |
1282 | 1299 | value = cast.second(sub_caster.value); |
1283 | 1300 | if (typeinfo->holder_enum_v == detail::holder_enum_t::smart_holder) { |
1284 | 1301 | sh_load_helper.loaded_v_h = sub_caster.sh_load_helper.loaded_v_h; |
| 1302 | + sh_load_helper.was_populated = true; |
1285 | 1303 | } else { |
1286 | 1304 | pybind11_fail("Expected to be UNREACHABLE: " __FILE__ |
1287 | 1305 | ":" PYBIND11_TOSTRING(__LINE__)); |
|
0 commit comments