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.
This commit is contained in:
Ralf W. Grosse-Kunstleve 2023-09-18 20:14:35 -07:00
parent f14846dab3
commit 24bf40bb3e

View File

@ -72,13 +72,22 @@ 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; std::function<void(void *)> del_fun; // Rare case.
void (*del_ptr)(void *); // Common case.
bool use_del_fun;
bool armed_flag; bool armed_flag;
guarded_delete(std::function<void(void *)> &&del_fun, bool armed_flag) guarded_delete(std::function<void(void *)> &&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 { void operator()(void *raw_ptr) const {
if (armed_flag) { if (armed_flag) {
if (use_del_fun) {
del_fun(raw_ptr); del_fun(raw_ptr);
} else {
del_ptr(raw_ptr);
}
} }
} }
}; };