1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #ifndef SCOPE_GUARD_H
16 #define SCOPE_GUARD_H
17 
18 #include <utility>
19 
20 namespace OHOS {
21 namespace IntellVoiceUtils {
22 template <typename Func>
23 class ScopeGuard {
24 public:
ScopeGuard(Func && f)25     explicit ScopeGuard(Func &&f) : func_(std::forward<Func>(f)), active_(true)
26     {
27     }
28 
ScopeGuard(ScopeGuard && rhs)29     ScopeGuard(ScopeGuard &&rhs) : func_(std::move(rhs.func_)), active_(rhs.active_)
30     {
31         rhs.Disable();
32     }
33 
~ScopeGuard()34     ~ScopeGuard()
35     {
36         if (active_) {
37             func_();
38         }
39     }
40 
Disable()41     void Disable()
42     {
43         active_ = false;
44     }
45 
Active()46     bool Active() const
47     {
48         return active_;
49     }
50 
EarlyExit()51     void EarlyExit()
52     {
53         if (active_) {
54             func_();
55         }
56         active_ = false;
57     }
58 private:
59     Func func_;
60     bool active_;
61     ScopeGuard() = delete;
62     ScopeGuard(const ScopeGuard &) = delete;
63     ScopeGuard &operator=(const ScopeGuard &) = delete;
64     ScopeGuard &operator=(ScopeGuard &&) = delete;
65 };
66 
67 // tag dispatch
68 struct ScopeGuardOnExit {};
69 
70 template <typename Func>
71 inline ScopeGuard<Func> operator+(ScopeGuardOnExit, Func &&fn)
72 {
73     return ScopeGuard<Func>(std::forward<Func>(fn));
74 }
75 }
76 }
77 
78 /*
79   * ScopeGuard ensure the specified function which is created by ON_SCOPE_EXIT is executed no matter how the current
80   * scope exit.
81   * when use ON_SCOPE_EXIT macro, the format is:
82   * ON_SCOPE_EXIT {
83   * your code
84   * };
85 */
86 #define ON_SCOPE_EXIT \
87     auto __onScopeGuardExit__ = OHOS::IntellVoiceUtils::ScopeGuardOnExit() + [&]()
88 
89 #define CANCEL_SCOPE_EXIT \
90     (__onScopeGuardExit__.Disable())
91 
92 #define EARLY_SCOPE_EXIT \
93     (__onScopeGuardExit__.EarlyExit())
94 
95 #define ON_SCOPE_EXIT_WITH_NAME(variable_name) \
96     auto variable_name = OHOS::IntellVoiceUtils::ScopeGuardOnExit() + [&]()
97 
98 #endif
99