blob: 8c4fc99b8e44339e37a37ad91837a4b9fa7e7968 [file] [log] [blame]
#pragma once
#include <optional>
#include <utility>
namespace utils
{
template <class F>
struct Ensure
{
Ensure() = default;
template <class U>
Ensure(U&& functor) : functor(std::forward<U>(functor))
{}
Ensure(F functor) : functor(std::move(functor))
{}
Ensure(Ensure&& other) = delete;
Ensure(const Ensure&) = delete;
~Ensure()
{
clear();
}
template <class U>
Ensure& operator=(U&& other)
{
clear();
functor = std::move(other);
return *this;
}
Ensure& operator=(Ensure&& other) = delete;
Ensure& operator=(std::nullptr_t)
{
clear();
return *this;
}
Ensure& operator=(const Ensure&) = delete;
explicit operator bool() const
{
return static_cast<bool>(functor);
}
private:
void clear()
{
if (functor)
{
(*functor)();
functor = std::nullopt;
}
}
std::optional<F> functor;
};
} // namespace utils