Introduce struct custom_deleter to ensure the deleter is moved as desired (the lambda function only captures a reference, which can become dangling).

This commit is contained in:
Ralf W. Grosse-Kunstleve 2023-09-21 21:15:45 -07:00
parent 435d3864a1
commit 17098eb760

View File

@ -68,8 +68,6 @@ static constexpr bool type_has_shared_from_this(const std::enable_shared_from_th
return true; return true;
} }
struct smart_holder;
struct guarded_delete { struct guarded_delete {
std::weak_ptr<void> released_ptr; // Trick to keep the smart_holder memory footprint small. std::weak_ptr<void> released_ptr; // Trick to keep the smart_holder memory footprint small.
std::function<void(void *)> del_fun; // Rare case. std::function<void(void *)> del_fun; // Rare case.
@ -110,10 +108,16 @@ guarded_delete make_guarded_builtin_delete(bool armed_flag) {
return guarded_delete(builtin_delete_if_destructible<T>, armed_flag); return guarded_delete(builtin_delete_if_destructible<T>, armed_flag);
} }
template <typename T, typename D>
struct custom_deleter {
D deleter;
custom_deleter(D &&deleter) : deleter{std::move(deleter)} {}
void operator()(void *raw_ptr) { deleter(static_cast<T *>(raw_ptr)); }
};
template <typename T, typename D> template <typename T, typename D>
guarded_delete make_guarded_custom_deleter(D &&uqp_del, bool armed_flag) { guarded_delete make_guarded_custom_deleter(D &&uqp_del, bool armed_flag) {
return guarded_delete(std::function<void(void *)>( return guarded_delete(std::function<void(void *)>(custom_deleter<T, D>(std::move(uqp_del))),
[&uqp_del](void *raw_ptr) { uqp_del(static_cast<T *>(raw_ptr)); }),
armed_flag); armed_flag);
} }