OSDN Git Service

Merge pull request #3532 from sikabane-works/release/3.0.0.87-alpha
[hengbandforosx/hengbandosx.git] / src / util / finalizer.h
1 #pragma once
2
3 #include <concepts>
4 #include <functional>
5 #include <type_traits>
6 #include <utility>
7
8 namespace util {
9
10 /*!
11  * @brief オブジェクトがスコープを抜ける際に、コンストラクタで渡された関数を実行するクラス
12  *
13  * コード例:
14  * @code
15  * void func()
16  * {
17  *     auto finalizer = util::make_finalizer([] { std::cout << "finally" << std::endl; });
18  *     std::cout << "do something" << std::endl;
19  * }
20  * @endcode
21  * この場合、func()が終了する際に"finally"と表示される。
22  *
23  * @param func 実行する関数
24  */
25 template <std::invocable Func>
26 class Finalizer {
27 public:
28     explicit Finalizer(const Func &func) noexcept
29         : func_{ func }
30     {
31     }
32     explicit Finalizer(Func &&func) noexcept
33         : func_{ std::move(func) }
34     {
35     }
36
37     ~Finalizer() noexcept
38     {
39         std::invoke(func_);
40     }
41
42     Finalizer(const Finalizer &) = delete;
43     void operator=(const Finalizer &) = delete;
44     Finalizer(Finalizer &&) = delete;
45     void operator=(Finalizer &&) = delete;
46
47 private:
48     Func func_;
49 };
50
51 /*!
52  * @brief Finalizerオブジェクトを生成するファクトリ関数
53  * @param func Finalizerオブジェクトのコンストラクタに渡す関数
54  */
55 template <typename Func>
56 [[nodiscard]] auto make_finalizer(Func &&func) noexcept
57 {
58     return Finalizer<std::decay_t<Func>>{ std::forward<Func>(func) };
59 }
60
61 }