When ref_ptr<T,Policy>::new_reference() is specialized for 'PyObject'
(i.e. gdbpy_ref<>), it currently requires the argument type to be exactly
'PyObject *'. As a result, pointers to subclasses of 'PyObject' must be
explicitly cast before being passed, making call sites unnecessarily
verbose.
This patch makes ref_ptr<T,Policy>::new_reference() a template method
that accepts both T and subclasses of T, performing the cast to 'T *'
internally when needed. This removes redundant casts at call sites
without changing behavior.
Approved-By: Tom Tromey <tom@tromey.com>
block_object *result = (block_object *) htab_find_with_hash (table, block,
hash);
if (result != nullptr)
- return gdbpy_ref<>::new_reference ((PyObject *) result);
+ return gdbpy_ref<>::new_reference (result);
result = PyObject_New (block_object, &block_object_type);
if (result == nullptr)
for (const thread_map_t::value_type &entry : *inf_obj->threads)
{
- auto thr = gdbpy_ref<>::new_reference ((PyObject *) entry.second.get ());
+ gdbpy_ref<> thr = entry.second;
if (PyTuple_SetItem (tuple.get (), i++, thr.release ()) < 0)
return nullptr;
}
}
/* Acquire a new reference and return a ref_ptr that owns it. */
- static ref_ptr<T, Policy> new_reference (T *obj)
+ template <class TObj>
+ static ref_ptr<T, Policy> new_reference (TObj *obj)
{
Policy::incref (obj);
+ if constexpr (std::is_base_of<T, TObj>::value)
+ return ref_ptr<T, Policy> (static_cast<T *> (obj));
return ref_ptr<T, Policy> (obj);
}