aboutsummaryrefslogtreecommitdiff
path: root/src/frontend/duckstation/scoped_guard.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/frontend/duckstation/scoped_guard.h')
-rw-r--r--src/frontend/duckstation/scoped_guard.h34
1 files changed, 34 insertions, 0 deletions
diff --git a/src/frontend/duckstation/scoped_guard.h b/src/frontend/duckstation/scoped_guard.h
new file mode 100644
index 0000000..89f35d9
--- /dev/null
+++ b/src/frontend/duckstation/scoped_guard.h
@@ -0,0 +1,34 @@
+#pragma once
+#include <optional>
+#include <utility>
+
+/// ScopedGuard provides an object which runs a function (usually a lambda) when
+/// it goes out of scope. This can be useful for releasing resources or handles
+/// which do not normally have C++ types to automatically release.
+template<typename T>
+class ScopedGuard final
+{
+public:
+ ALWAYS_INLINE ScopedGuard(T&& func) : m_func(std::forward<T>(func)) {}
+ ALWAYS_INLINE ScopedGuard(ScopedGuard&& other) : m_func(std::move(other.m_func)) { other.m_func = nullptr; }
+ ALWAYS_INLINE ~ScopedGuard() { Invoke(); }
+
+ ScopedGuard(const ScopedGuard&) = delete;
+ void operator=(const ScopedGuard&) = delete;
+
+ /// Prevents the function from being invoked when we go out of scope.
+ ALWAYS_INLINE void Cancel() { m_func.reset(); }
+
+ /// Explicitly fires the function.
+ ALWAYS_INLINE void Invoke()
+ {
+ if (!m_func.has_value())
+ return;
+
+ m_func.value()();
+ m_func.reset();
+ }
+
+private:
+ std::optional<T> m_func;
+};