@@ -54,6 +54,20 @@ namespace detail {
54
54
55
55
using namespace pybind11_tests ::classh_wip;
56
56
57
+ inline std::pair<bool , handle> find_existing_python_instance (void *src_void_ptr,
58
+ const detail::type_info *tinfo) {
59
+ // Loop copied from type_caster_generic::cast.
60
+ // IMPROVEABLE: Factor out of type_caster_generic::cast.
61
+ auto it_instances = get_internals ().registered_instances .equal_range (src_void_ptr);
62
+ for (auto it_i = it_instances.first ; it_i != it_instances.second ; ++it_i) {
63
+ for (auto instance_type : detail::all_type_info (Py_TYPE (it_i->second ))) {
64
+ if (instance_type && same_type (*instance_type->cpptype , *tinfo->cpptype ))
65
+ return std::make_pair (true , handle ((PyObject *) it_i->second ).inc_ref ());
66
+ }
67
+ }
68
+ return std::make_pair (false , handle ());
69
+ }
70
+
57
71
template <typename T>
58
72
struct smart_holder_type_caster_load {
59
73
using holder_type = pybindit::memory::smart_holder;
@@ -172,13 +186,9 @@ struct type_caster<mpty> : smart_holder_type_caster_load<mpty> {
172
186
if (src == nullptr )
173
187
return none ().release ();
174
188
175
- auto it_instances = get_internals ().registered_instances .equal_range (src);
176
- for (auto it_i = it_instances.first ; it_i != it_instances.second ; ++it_i) {
177
- for (auto instance_type : detail::all_type_info (Py_TYPE (it_i->second ))) {
178
- if (instance_type && same_type (*instance_type->cpptype , *tinfo->cpptype ))
179
- return handle ((PyObject *) it_i->second ).inc_ref ();
180
- }
181
- }
189
+ auto existing_inst = find_existing_python_instance (src, tinfo);
190
+ if (existing_inst.first )
191
+ return existing_inst.second ;
182
192
183
193
auto inst = reinterpret_steal<object>(make_new_instance (tinfo->type ));
184
194
auto wrapper = reinterpret_cast <instance *>(inst.ptr ());
@@ -270,16 +280,11 @@ struct type_caster<std::shared_ptr<mpty>> : smart_holder_type_caster_load<mpty>
270
280
271
281
void *src_raw_void_ptr = static_cast <void *>(src_raw_ptr);
272
282
const detail::type_info *tinfo = st.second ;
273
- auto it_instances = get_internals ().registered_instances .equal_range (src_raw_void_ptr);
274
- // Loop copied from type_caster_generic::cast.
275
- for (auto it_i = it_instances.first ; it_i != it_instances.second ; ++it_i) {
276
- for (auto instance_type : detail::all_type_info (Py_TYPE (it_i->second ))) {
277
- if (instance_type && same_type (*instance_type->cpptype , *tinfo->cpptype ))
278
- // MISSING: Enforcement of consistency with existing smart_holder.
279
- // MISSING: keep_alive.
280
- return handle ((PyObject *) it_i->second ).inc_ref ();
281
- }
282
- }
283
+ auto existing_inst = find_existing_python_instance (src_raw_void_ptr, tinfo);
284
+ if (existing_inst.first )
285
+ // MISSING: Enforcement of consistency with existing smart_holder.
286
+ // MISSING: keep_alive.
287
+ return existing_inst.second ;
283
288
284
289
object inst = reinterpret_steal<object>(make_new_instance (tinfo->type ));
285
290
instance *inst_raw_ptr = reinterpret_cast <instance *>(inst.ptr ());
@@ -338,15 +343,9 @@ struct type_caster<std::unique_ptr<mpty>> : smart_holder_type_caster_load<mpty>
338
343
339
344
void *src_raw_void_ptr = static_cast <void *>(src_raw_ptr);
340
345
const detail::type_info *tinfo = st.second ;
341
- auto it_instances = get_internals ().registered_instances .equal_range (src_raw_void_ptr);
342
- // Loop copied from type_caster_generic::cast.
343
- for (auto it_i = it_instances.first ; it_i != it_instances.second ; ++it_i) {
344
- for (auto instance_type : detail::all_type_info (Py_TYPE (it_i->second ))) {
345
- if (instance_type && same_type (*instance_type->cpptype , *tinfo->cpptype ))
346
- throw cast_error (
347
- " Invalid unique_ptr: another instance owns this pointer already." );
348
- }
349
- }
346
+ auto existing_inst = find_existing_python_instance (src_raw_void_ptr, tinfo);
347
+ if (existing_inst.first )
348
+ throw cast_error (" Invalid unique_ptr: another instance owns this pointer already." );
350
349
351
350
object inst = reinterpret_steal<object>(make_new_instance (tinfo->type ));
352
351
instance *inst_raw_ptr = reinterpret_cast <instance *>(inst.ptr ());
0 commit comments