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