Skip to content

Instantly share code, notes, and snippets.

@shawnfeng0
Last active June 12, 2023 07:41
Show Gist options
  • Save shawnfeng0/301f035a5df5743cfdc61451d37c76c3 to your computer and use it in GitHub Desktop.
Save shawnfeng0/301f035a5df5743cfdc61451d37c76c3 to your computer and use it in GitHub Desktop.
#pragma once
#include <tuple>
#include <type_traits>
template <typename... DestroyFuncs>
class DestroyGuard {
public:
~DestroyGuard() {
call_all_destroy_callbacks(
std::make_index_sequence<sizeof...(DestroyFuncs)>{});
}
// Dismiss the AutoDestroy object, so that it will not call destroy func
void dismiss() { dismissed_ = true; }
template <typename... DestroyFuncs_>
friend auto DestroyGuardCreate(DestroyFuncs_ &&...destroy_callbacks)
-> DestroyGuard<std::decay_t<DestroyFuncs_>...>;
private:
explicit DestroyGuard(DestroyFuncs... destroy_callbacks)
: destroy_callbacks_(std::make_tuple(destroy_callbacks...)) {}
template <std::size_t... Is>
void call_all_destroy_callbacks(std::index_sequence<Is...>) {
if (dismissed_) return;
int dummy[] = {0, ((void)std::get<Is>(destroy_callbacks_)(), 0)...};
(void)dummy;
}
private:
bool dismissed_ = false;
std::tuple<DestroyFuncs...> destroy_callbacks_;
};
template <typename... DestroyFuncs>
auto DestroyGuardCreate(DestroyFuncs &&...destroy_callbacks)
-> DestroyGuard<std::decay_t<DestroyFuncs>...> {
return DestroyGuard<std::decay_t<DestroyFuncs>...>(
std::forward<DestroyFuncs>(destroy_callbacks)...);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment