Last active
December 1, 2024 23:57
-
-
Save playday3008/004d10dd8af2599b9cb96aba47708170 to your computer and use it in GitHub Desktop.
Defer in C++ (Requires C++20)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #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