blob: 8c4fc99b8e44339e37a37ad91837a4b9fa7e7968 [file] [log] [blame]
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +01001#pragma once
2
3#include <optional>
4#include <utility>
5
6namespace utils
7{
8
9template <class F>
10struct Ensure
11{
12 Ensure() = default;
13
14 template <class U>
15 Ensure(U&& functor) : functor(std::forward<U>(functor))
16 {}
17
18 Ensure(F functor) : functor(std::move(functor))
19 {}
20
Szymon Dompkebcf045a2022-09-16 15:23:30 +020021 Ensure(Ensure&& other) = delete;
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +010022 Ensure(const Ensure&) = delete;
23
24 ~Ensure()
25 {
26 clear();
27 }
28
29 template <class U>
30 Ensure& operator=(U&& other)
31 {
32 clear();
33 functor = std::move(other);
34 return *this;
35 }
36
Szymon Dompkebcf045a2022-09-16 15:23:30 +020037 Ensure& operator=(Ensure&& other) = delete;
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +010038
39 Ensure& operator=(std::nullptr_t)
40 {
41 clear();
42 return *this;
43 }
44
45 Ensure& operator=(const Ensure&) = delete;
46
Krzysztof Grobelny973b4bb2022-04-25 17:07:27 +020047 explicit operator bool() const
48 {
49 return static_cast<bool>(functor);
50 }
51
Krzysztof Grobelnyf7ea2992022-01-27 11:04:58 +010052 private:
53 void clear()
54 {
55 if (functor)
56 {
57 (*functor)();
58 functor = std::nullopt;
59 }
60 }
61
62 std::optional<F> functor;
63};
64
65} // namespace utils