aboutsummaryrefslogtreecommitdiff
path: root/source/ScopeGuard.hpp
diff options
context:
space:
mode:
authorrtk0c <[email protected]>2022-04-06 20:52:51 -0700
committerrtk0c <[email protected]>2022-04-06 20:52:51 -0700
commitf163e8f37123e651ea80b690793845b31ddb8639 (patch)
treee2c9f14d600f073533c9d01cfb90c4d60938127c /source/ScopeGuard.hpp
parent11edae3fbf770695d1b263712ca4f3a40bdd70e3 (diff)
Changeset: 2 Work on moving infrastruture to this project
Diffstat (limited to 'source/ScopeGuard.hpp')
-rw-r--r--source/ScopeGuard.hpp53
1 files changed, 53 insertions, 0 deletions
diff --git a/source/ScopeGuard.hpp b/source/ScopeGuard.hpp
new file mode 100644
index 0000000..b4a1749
--- /dev/null
+++ b/source/ScopeGuard.hpp
@@ -0,0 +1,53 @@
+#pragma once
+
+#include "Macros.hpp"
+
+#include <utility>
+
+template <class TCleanupFunc>
+class ScopeGuard {
+private:
+ TCleanupFunc mFunc;
+ bool mDismissed = false;
+
+public:
+ /// Specifically left this implicit so that constructs like
+ /// \code
+ /// ScopeGuard sg = [&]() { res.Cleanup(); };
+ /// \endcode
+ /// would work. It is highly discourage and unlikely that one would want to use ScopeGuard as a function
+ /// parameter, so the normal argument that implicit conversion are harmful doesn't really apply here.
+ // Deliberately not explicit to allow usages like: ScopeGuard var = lambda;
+ ScopeGuard(TCleanupFunc&& function) noexcept
+ : mFunc{ std::move(function) } {
+ }
+
+ ~ScopeGuard() noexcept {
+ if (!mDismissed) {
+ mFunc();
+ }
+ }
+
+ ScopeGuard(const ScopeGuard&) = delete;
+ ScopeGuard& operator=(const ScopeGuard&) = delete;
+
+ ScopeGuard(ScopeGuard&& that) noexcept
+ : mFunc{ std::move(that.mFunc) } {
+ that.Cancel();
+ }
+
+ ScopeGuard& operator=(ScopeGuard&& that) noexcept {
+ if (!mDismissed) {
+ mFunc();
+ }
+ this->mFunc = std::move(that.mFunc);
+ this->cancelled = std::exchange(that.cancelled, true);
+ }
+
+ void Dismiss() noexcept {
+ mDismissed = true;
+ }
+};
+
+#define SCOPE_GUARD(name) ScopeGuard name = [&]()
+#define DEFER ScopeGuard UNIQUE_NAME(scopeGuard) = [&]()