summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMaxime Coste <frrrwww@gmail.com>2011-09-14 15:36:35 +0000
committerMaxime Coste <frrrwww@gmail.com>2011-09-14 15:36:35 +0000
commit4b38cd3cd0131b2ab276310cc234ab666bd99363 (patch)
treebe269ab870109e1913baf34d59cd59556a86cae7 /src
parenteecc5a184e4a3aacaf2984f2171a58440bebc43c (diff)
utils: add auto_raii helper function
this helper permits to register a resource and cleanup function to keep exception safety with C like resource. For exemple, to be sure that a FILE* will be closed, you can use: auto file = auto_raii(fopen("filename"), fclose); file will auto cast to FILE* when needed, and will call fclose when going out of scope.
Diffstat (limited to 'src')
-rw-r--r--src/utils.hh29
1 files changed, 29 insertions, 0 deletions
diff --git a/src/utils.hh b/src/utils.hh
index d495afeb..5b219b2e 100644
--- a/src/utils.hh
+++ b/src/utils.hh
@@ -39,6 +39,35 @@ bool operator== (const std::unique_ptr<T>& lhs, T* rhs)
return lhs.get() == rhs;
}
+template<typename T, typename F>
+class AutoRaii
+{
+public:
+ AutoRaii(T* resource, F cleanup)
+ : m_resource(resource), m_cleanup(cleanup) {}
+
+ AutoRaii(AutoRaii&& other) : m_resource(other.m_resource),
+ m_cleanup(other.m_cleanup)
+ { other.m_resource = nullptr; }
+
+ AutoRaii(const AutoRaii&) = delete;
+ AutoRaii& operator=(const AutoRaii&) = delete;
+
+ ~AutoRaii() { if (m_resource) m_cleanup(m_resource); }
+
+ operator T*() { return m_resource; }
+
+private:
+ T* m_resource;
+ F m_cleanup;
+};
+
+template<typename T, typename F>
+AutoRaii<T, F> auto_raii(T* resource, F cleanup)
+{
+ return AutoRaii<T, F>(resource, cleanup);
+}
+
}
#endif // utils_hh_INCLUDED