From 275aaf977a1c243ba96a2434c967ef3015c89e1a Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Wed, 16 Jun 2021 14:07:18 -0700 Subject: [PATCH] Inserting `const_cast` for `std::get_deleter` return, to keep Ubuntu 20 GCC 6.3.0 happy. --- include/pybind11/detail/smart_holder_poc.h | 40 ++++++++-------------- 1 file changed, 15 insertions(+), 25 deletions(-) diff --git a/include/pybind11/detail/smart_holder_poc.h b/include/pybind11/detail/smart_holder_poc.h index 06df06008..4248ae262 100644 --- a/include/pybind11/detail/smart_holder_poc.h +++ b/include/pybind11/detail/smart_holder_poc.h @@ -59,12 +59,8 @@ namespace memory { struct guarded_operator_call { bool armed_flag; explicit guarded_operator_call(bool armed_flag) : armed_flag{armed_flag} {} - virtual void operator()(void *) = 0; - virtual ~guarded_operator_call() = default; - guarded_operator_call(guarded_operator_call &&) = default; - guarded_operator_call(guarded_operator_call &) = default; - guarded_operator_call &operator=(guarded_operator_call &&) = delete; - guarded_operator_call &operator=(const guarded_operator_call &) = delete; + virtual void operator()(void *) = 0; + virtual ~guarded_operator_call() = default; }; template @@ -214,20 +210,25 @@ struct smart_holder { } } + template + void vptr_reset(T *raw_ptr, const D &del) { + vptr.reset(raw_ptr, del); // Copies del. + // The const_cast is only for certain compilers (Ubuntu 20 GCC 6.3.0 being one). + vptr_del = const_cast(std::get_deleter(vptr)); // Pointer to copy of del. + } + void reset_vptr_deleter_armed_flag(bool armed_flag) const { - auto vptr_del_ptr = std::get_deleter(vptr); - if (vptr_del_ptr == nullptr) { + if (vptr_del == nullptr) { throw std::runtime_error( "smart_holder::reset_vptr_deleter_armed_flag() called in an invalid context."); } - vptr_del_ptr->armed_flag = armed_flag; + vptr_del->armed_flag = armed_flag; } template static smart_holder from_raw_ptr_unowned(T *raw_ptr) { smart_holder hld; - hld.vptr.reset(raw_ptr, guarded_builtin_delete(false)); - hld.vptr_del = std::get_deleter>(hld.vptr); + hld.vptr_reset(raw_ptr, guarded_builtin_delete(false)); hld.vptr_is_using_noop_deleter = true; hld.is_populated = true; return hld; @@ -258,21 +259,12 @@ struct smart_holder { static smart_holder from_raw_ptr_take_ownership(T *raw_ptr) { ensure_pointee_is_destructible("from_raw_ptr_take_ownership"); smart_holder hld; - hld.vptr.reset(raw_ptr, guarded_builtin_delete(true)); - hld.vptr_del = std::get_deleter>(hld.vptr); + hld.vptr_reset(raw_ptr, guarded_builtin_delete(true)); hld.vptr_is_using_builtin_delete = true; hld.is_populated = true; return hld; } - void reset_vptr_deleter_armed_flag(bool armed_flag) { - if (vptr_del == nullptr) { - throw std::runtime_error( - "smart_holder::reset_vptr_deleter_armed_flag() called in an invalid context."); - } - vptr_del->armed_flag = armed_flag; - } - // Caller is responsible for ensuring preconditions (SMART_HOLDER_WIP: details). void disown() { reset_vptr_deleter_armed_flag(false); @@ -318,11 +310,9 @@ struct smart_holder { hld.rtti_uqp_del = &typeid(D); hld.vptr_is_using_builtin_delete = is_std_default_delete(*hld.rtti_uqp_del); if (hld.vptr_is_using_builtin_delete) { - hld.vptr.reset(unq_ptr.get(), guarded_builtin_delete(true)); - hld.vptr_del = std::get_deleter>(hld.vptr); + hld.vptr_reset(unq_ptr.get(), guarded_builtin_delete(true)); } else { - hld.vptr.reset(unq_ptr.get(), guarded_custom_deleter(true)); - hld.vptr_del = std::get_deleter>(hld.vptr); + hld.vptr_reset(unq_ptr.get(), guarded_custom_deleter(true)); } unq_ptr.release(); hld.is_populated = true;