diff options
| author | Maxime Coste <frrrwww@gmail.com> | 2011-09-14 15:36:35 +0000 |
|---|---|---|
| committer | Maxime Coste <frrrwww@gmail.com> | 2011-09-14 15:36:35 +0000 |
| commit | 4b38cd3cd0131b2ab276310cc234ab666bd99363 (patch) | |
| tree | be269ab870109e1913baf34d59cd59556a86cae7 /src | |
| parent | eecc5a184e4a3aacaf2984f2171a58440bebc43c (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.hh | 29 |
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 |
