Skip to content

Commit 707940e

Browse files
committed
Factoring out find_existing_python_instance().
1 parent b0a8957 commit 707940e

File tree

1 file changed

+25
-26
lines changed

1 file changed

+25
-26
lines changed

tests/test_classh_wip.cpp

Lines changed: 25 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,20 @@ namespace detail {
5454

5555
using namespace pybind11_tests::classh_wip;
5656

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+
5771
template <typename T>
5872
struct smart_holder_type_caster_load {
5973
using holder_type = pybindit::memory::smart_holder;
@@ -172,13 +186,9 @@ struct type_caster<mpty> : smart_holder_type_caster_load<mpty> {
172186
if (src == nullptr)
173187
return none().release();
174188

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;
182192

183193
auto inst = reinterpret_steal<object>(make_new_instance(tinfo->type));
184194
auto wrapper = reinterpret_cast<instance *>(inst.ptr());
@@ -270,16 +280,11 @@ struct type_caster<std::shared_ptr<mpty>> : smart_holder_type_caster_load<mpty>
270280

271281
void *src_raw_void_ptr = static_cast<void *>(src_raw_ptr);
272282
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;
283288

284289
object inst = reinterpret_steal<object>(make_new_instance(tinfo->type));
285290
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>
338343

339344
void *src_raw_void_ptr = static_cast<void *>(src_raw_ptr);
340345
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.");
350349

351350
object inst = reinterpret_steal<object>(make_new_instance(tinfo->type));
352351
instance *inst_raw_ptr = reinterpret_cast<instance *>(inst.ptr());

0 commit comments

Comments
 (0)