From 24bf40bb3eca2ec74871156ffc1bdcc61de80b26 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Mon, 18 Sep 2023 20:14:35 -0700 Subject: [PATCH] Specialize the simple common case. Using a `union` is complicated: https://en.cppreference.com/w/cpp/language/union > If members of a union are classes with user-defined constructors and destructors, to switch the active member, explicit destructor and placement new are generally needed: Using `std::variant` increases compile-time overhead. It is currently unclear how much these effects matter in practice: optimization left for later. --- include/pybind11/detail/smart_holder_poc.h | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/include/pybind11/detail/smart_holder_poc.h b/include/pybind11/detail/smart_holder_poc.h index d0140d6dc..2b333b0ee 100644 --- a/include/pybind11/detail/smart_holder_poc.h +++ b/include/pybind11/detail/smart_holder_poc.h @@ -71,14 +71,23 @@ static constexpr bool type_has_shared_from_this(const std::enable_shared_from_th struct smart_holder; struct guarded_delete { - std::weak_ptr released_ptr; // Trick to keep the smart_holder memory footprint small. - std::function del_fun; + std::weak_ptr released_ptr; // Trick to keep the smart_holder memory footprint small. + std::function del_fun; // Rare case. + void (*del_ptr)(void *); // Common case. + bool use_del_fun; bool armed_flag; guarded_delete(std::function &&del_fun, bool armed_flag) - : del_fun{std::move(del_fun)}, armed_flag{armed_flag} {} + : del_fun{std::move(del_fun)}, del_ptr{nullptr}, use_del_fun{true}, + armed_flag{armed_flag} {} + guarded_delete(void (*del_ptr)(void *), bool armed_flag) + : del_ptr{del_ptr}, use_del_fun{false}, armed_flag{armed_flag} {} void operator()(void *raw_ptr) const { if (armed_flag) { - del_fun(raw_ptr); + if (use_del_fun) { + del_fun(raw_ptr); + } else { + del_ptr(raw_ptr); + } } } };