1 /* sane - Scanner Access Now Easy.
2 
3    Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt>
4 
5    This file is part of the SANE package.
6 
7    This program is free software; you can redistribute it and/or
8    modify it under the terms of the GNU General Public License as
9    published by the Free Software Foundation; either version 2 of the
10    License, or (at your option) any later version.
11 
12    This program is distributed in the hope that it will be useful, but
13    WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15    General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <https://www.gnu.org/licenses/>.
19 */
20 
21 #ifndef BACKEND_GENESYS_STATIC_INIT_H
22 #define BACKEND_GENESYS_STATIC_INIT_H
23 
24 #include <functional>
25 #include <memory>
26 
27 namespace genesys {
28 
29 void add_function_to_run_at_backend_exit(const std::function<void()>& function);
30 
31 // calls functions added via add_function_to_run_at_backend_exit() in reverse order of being
32 // added.
33 void run_functions_at_backend_exit();
34 
35 template<class T>
36 class StaticInit {
37 public:
38     StaticInit() = default;
39     StaticInit(const StaticInit&) = delete;
40     StaticInit& operator=(const StaticInit&) = delete;
41 
42     template<class... Args>
init(Args&& .... args)43     void init(Args&& ... args)
44     {
45         ptr_ = std::unique_ptr<T>(new T(std::forward<Args>(args)...));
46         add_function_to_run_at_backend_exit([this](){ deinit(); });
47     }
48 
deinit()49     void deinit()
50     {
51         ptr_.reset();
52     }
53 
operator ->() const54     const T* operator->() const { return ptr_.get(); }
operator ->()55     T* operator->() { return ptr_.get(); }
operator *() const56     const T& operator*() const { return *ptr_.get(); }
operator *()57     T& operator*() { return *ptr_.get(); }
58 
59 private:
60     std::unique_ptr<T> ptr_;
61 };
62 
63 } // namespace genesys
64 
65 #endif // BACKEND_GENESYS_STATIC_INIT_H
66