Skip to content

Instantly share code, notes, and snippets.

@playday3008
Last active December 1, 2024 23:57
Show Gist options
  • Select an option

  • Save playday3008/004d10dd8af2599b9cb96aba47708170 to your computer and use it in GitHub Desktop.

Select an option

Save playday3008/004d10dd8af2599b9cb96aba47708170 to your computer and use it in GitHub Desktop.
Defer in C++ (Requires C++20)
#pragma once
#include <type_traits>
template <typename Func>
requires std::is_nothrow_invocable_v<Func>
struct DeferAction {
explicit DeferAction(Func a) : act{a} {}
~DeferAction() { act(); }
// Disallow copy and move
DeferAction(const DeferAction&) = delete;
DeferAction& operator=(const DeferAction&) = delete;
DeferAction(DeferAction&&) = delete;
DeferAction& operator=(DeferAction&&) = delete;
private:
Func act;
};
template <typename Func>
requires std::is_nothrow_invocable_v<Func>
DeferAction<Func> defer(Func act) {
return DeferAction<Func>{act};
}
#define DEFER_MERGE(a, b) a##b
#define DEFER_LABEL(a, b) DEFER_MERGE(a, b)
// clang-format off
#define DEFER_UNIQUE_NAME \
DEFER_LABEL( \
_defer_, \
DEFER_LABEL( \
__LINE__, \
DEFER_LABEL( \
_, \
DEFER_LABEL( \
__COUNTER__, \
_ \
) \
) \
) \
) // Will do: _defer_ + __LINE__ + _ + __COUNTER__ + _ -> _defer_41_1_
// clang-format on
#define DEFER(...) const auto DEFER_UNIQUE_NAME = defer(__VA_ARGS__)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment