• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 
16 #ifndef ANI_UTIL_COMMON_H
17 #define ANI_UTIL_COMMON_H
18 
19 #include <exception>
20 #include <memory>
21 #include <type_traits>
22 #include <utility>
23 #include <variant>
24 
25 template <typename T, typename E>
26 class expected {
27 private:
28     std::variant<T, E> data_;
29     bool has_value_;
30 
31 public:
expected(const T & value)32     expected(const T &value) : data_(value), has_value_(true) {}
33 
expected(T && value)34     expected(T &&value) : data_(std::move(value)), has_value_(true) {}
35 
expected(const E & error)36     expected(const E &error) : data_(error), has_value_(false) {}
37 
expected(E && error)38     expected(E &&error) : data_(std::move(error)), has_value_(false) {}
39 
has_value()40     bool has_value() const noexcept
41     {
42         return has_value_;
43     }
44 
45     explicit operator bool() const noexcept
46     {
47         return has_value();
48     }
49 
value()50     T &value() &
51     {
52         if (!has_value()) {
53             std::terminate();
54         }
55         return std::get<T>(data_);
56     }
57 
value()58     const T &value() const &
59     {
60         if (!has_value()) {
61             std::terminate();
62         }
63         return std::get<T>(data_);
64     }
65 
value()66     T &&value() &&
67     {
68         if (!has_value()) {
69             std::terminate();
70         }
71         return std::get<T>(std::move(data_));
72     }
73 
error()74     E &error() &
75     {
76         if (has_value()) {
77             std::terminate();
78         }
79         return std::get<E>(data_);
80     }
81 
error()82     const E &error() const &
83     {
84         if (has_value()) {
85             std::terminate();
86         }
87         return std::get<E>(data_);
88     }
89 
error()90     E &&error() &&
91     {
92         if (has_value()) {
93             std::terminate();
94         }
95         return std::get<E>(std::move(data_));
96     }
97 
98     T &operator*() &
99     {
100         return value();
101     }
102 
103     const T &operator*() const &
104     {
105         return value();
106     }
107 
108     T &&operator*() &&
109     {
110         return std::move(*this).value();
111     }
112 
113     T *operator->()
114     {
115         return &value();
116     }
117 
118     const T *operator->() const
119     {
120         return &value();
121     }
122 
123     template <typename U>
value_or(U && default_value)124     T value_or(U &&default_value) const &
125     {
126         return has_value() ? value() : static_cast<T>(std::forward<U>(default_value));
127     }
128 
129     template <typename U>
value_or(U && default_value)130     T value_or(U &&default_value) &&
131     {
132         return has_value() ? std::move(*this).value() : static_cast<T>(std::forward<U>(default_value));
133     }
134 };
135 
136 template <typename F>
137 class FinalAction {
138 public:
FinalAction(F func)139     explicit FinalAction(F func) : func_(std::move(func)) {}
140 
noexcept(noexcept (func_ ()))141     ~FinalAction() noexcept(noexcept(func_()))
142     {
143         if (!dismissed_) {
144             func_();
145         }
146     }
147 
148     FinalAction(const FinalAction &) = delete;
149     FinalAction &operator=(const FinalAction &) = delete;
150 
FinalAction(FinalAction && other)151     FinalAction(FinalAction &&other) noexcept : func_(std::move(other.func_)), dismissed_(other.dismissed_)
152     {
153         other.dismissed_ = true;
154     }
155 
dismiss()156     void dismiss() noexcept
157     {
158         dismissed_ = true;
159     }
160 
161 private:
162     F func_;
163     bool dismissed_ = false;
164 };
165 
166 template <typename F>
finally(F && func)167 inline FinalAction<F> finally(F &&func)
168 {
169     return FinalAction<F>(std::forward<F>(func));
170 }
171 
172 #endif
173