summaryrefslogtreecommitdiff
path: root/asl/base/defer.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'asl/base/defer.hpp')
-rw-r--r--asl/base/defer.hpp50
1 files changed, 50 insertions, 0 deletions
diff --git a/asl/base/defer.hpp b/asl/base/defer.hpp
new file mode 100644
index 0000000..b6d52af
--- /dev/null
+++ b/asl/base/defer.hpp
@@ -0,0 +1,50 @@
+#pragma once
+
+#include "asl/base/utility.hpp"
+#include "asl/base/functional.hpp"
+
+namespace asl
+{
+
+// @Todo Add invokable check
+template<typename Callback>
+class DeferCallback
+{
+ Callback m_callback;
+ bool m_moved = false;
+
+public:
+ template<typename T>
+ explicit DeferCallback(T&& callback) : m_callback(ASL_FWD(callback))
+ {
+ }
+
+ ASL_DELETE_COPY(DeferCallback);
+
+ DeferCallback(DeferCallback&& other) :
+ m_callback(ASL_MOVE(other.m_callback)), m_moved(exchange(other.m_moved, true))
+ {
+ }
+
+ DeferCallback& operator=(DeferCallback&&) = delete;
+
+ ~DeferCallback()
+ {
+ if (!m_moved) { invoke(m_callback); }
+ }
+};
+
+struct DeferFactory
+{
+ // @Todo Add invokable check
+ template<typename Callback>
+ DeferCallback<Callback> operator<<(Callback&& callback) const
+ {
+ return DeferCallback<Callback>(ASL_FWD(callback));
+ }
+};
+
+} // namespace asl
+
+#define ASL_DEFER auto ASL_CONCAT(_defer_, __COUNTER__) = ::asl::DeferFactory{} <<
+