diff options
Diffstat (limited to 'src/brussel.common/ScopedResource.hpp')
-rw-r--r-- | src/brussel.common/ScopedResource.hpp | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/src/brussel.common/ScopedResource.hpp b/src/brussel.common/ScopedResource.hpp new file mode 100644 index 0000000..b4098eb --- /dev/null +++ b/src/brussel.common/ScopedResource.hpp @@ -0,0 +1,54 @@ +#pragma once + +#include <type_traits> + +/// std::unique_ptr, but for non-pointer resources +template <typename T, typename TDeleter, T kNullValue = T()> + requires std::is_trivial_v<T> && std::equality_comparable<T> +class ScopedResource { +private: + T mValue; + +public: + ScopedResource() + : mValue{ kNullValue } {} + explicit ScopedResource(T t) + : mValue{ std::move(t) } {} + + ScopedResource(const ScopedResource& that) = delete; + ScopedResource& operator=(const ScopedResource& that) = delete; + + ScopedResource(ScopedResource&& that) noexcept + : mValue(that.mValue) {} + ScopedResource& operator=(ScopedResource&& that) noexcept { + if (this == &that) + return *this; + TDeleter::DeleteObject(mValue); + mValue = that.mValue; + that.mValue = kNullValue; + return *this; + } + + ScopedResource& operator=(T newValue) { + TDeleter::DeleteObject(mValue); + mValue = newValue; + return *this; + } + + ~ScopedResource() { + TDeleter::DeleteObject(mValue); + } + + explicit operator bool() const { + return mValue != kNullValue; + } + + const T& get() const { return mValue; } + T& get() { return mValue; } + + T release() { + T tmp = mValue; + mValue = kNullValue; + return tmp; + } +}; |