xref: /aosp_15_r20/system/libbase/include/android-base/result.h (revision 8f0ba417480079999ba552f1087ae592091b9d02)
1*8f0ba417SAndroid Build Coastguard Worker /*
2*8f0ba417SAndroid Build Coastguard Worker  * Copyright (C) 2017 The Android Open Source Project
3*8f0ba417SAndroid Build Coastguard Worker  *
4*8f0ba417SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*8f0ba417SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*8f0ba417SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*8f0ba417SAndroid Build Coastguard Worker  *
8*8f0ba417SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*8f0ba417SAndroid Build Coastguard Worker  *
10*8f0ba417SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*8f0ba417SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*8f0ba417SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*8f0ba417SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*8f0ba417SAndroid Build Coastguard Worker  * limitations under the License.
15*8f0ba417SAndroid Build Coastguard Worker  */
16*8f0ba417SAndroid Build Coastguard Worker 
17*8f0ba417SAndroid Build Coastguard Worker // Result<T, E> is the type that is used to pass a success value of type T or an error code of type
18*8f0ba417SAndroid Build Coastguard Worker // E, optionally together with an error message. T and E can be any type. If E is omitted it
19*8f0ba417SAndroid Build Coastguard Worker // defaults to int, which is useful when errno(3) is used as the error code.
20*8f0ba417SAndroid Build Coastguard Worker //
21*8f0ba417SAndroid Build Coastguard Worker // Passing a success value or an error value:
22*8f0ba417SAndroid Build Coastguard Worker //
23*8f0ba417SAndroid Build Coastguard Worker // Result<std::string> readFile() {
24*8f0ba417SAndroid Build Coastguard Worker //   std::string content;
25*8f0ba417SAndroid Build Coastguard Worker //   if (base::ReadFileToString("path", &content)) {
26*8f0ba417SAndroid Build Coastguard Worker //     return content; // ok case
27*8f0ba417SAndroid Build Coastguard Worker //   } else {
28*8f0ba417SAndroid Build Coastguard Worker //     return ErrnoError() << "failed to read"; // error case
29*8f0ba417SAndroid Build Coastguard Worker //   }
30*8f0ba417SAndroid Build Coastguard Worker // }
31*8f0ba417SAndroid Build Coastguard Worker //
32*8f0ba417SAndroid Build Coastguard Worker // Checking the result and then unwrapping the value or propagating the error:
33*8f0ba417SAndroid Build Coastguard Worker //
34*8f0ba417SAndroid Build Coastguard Worker // Result<bool> hasAWord() {
35*8f0ba417SAndroid Build Coastguard Worker //   auto content = readFile();
36*8f0ba417SAndroid Build Coastguard Worker //   if (!content.ok()) {
37*8f0ba417SAndroid Build Coastguard Worker //     return Error() << "failed to process: " << content.error();
38*8f0ba417SAndroid Build Coastguard Worker //   }
39*8f0ba417SAndroid Build Coastguard Worker //   return (*content.find("happy") != std::string::npos);
40*8f0ba417SAndroid Build Coastguard Worker // }
41*8f0ba417SAndroid Build Coastguard Worker //
42*8f0ba417SAndroid Build Coastguard Worker // Using custom error code type:
43*8f0ba417SAndroid Build Coastguard Worker //
44*8f0ba417SAndroid Build Coastguard Worker // enum class MyError { A, B }; // assume that this is the error code you already have
45*8f0ba417SAndroid Build Coastguard Worker //
46*8f0ba417SAndroid Build Coastguard Worker // // To use the error code with Result, define a wrapper class that provides the following
47*8f0ba417SAndroid Build Coastguard Worker // operations and use the wrapper class as the second type parameter (E) when instantiating
48*8f0ba417SAndroid Build Coastguard Worker // Result<T, E>
49*8f0ba417SAndroid Build Coastguard Worker //
50*8f0ba417SAndroid Build Coastguard Worker // 1. default constructor
51*8f0ba417SAndroid Build Coastguard Worker // 2. copy constructor / and move constructor if copying is expensive
52*8f0ba417SAndroid Build Coastguard Worker // 3. conversion operator to the error code type
53*8f0ba417SAndroid Build Coastguard Worker // 4. value() function that return the error code value
54*8f0ba417SAndroid Build Coastguard Worker // 5. print() function that gives a string representation of the error ode value
55*8f0ba417SAndroid Build Coastguard Worker //
56*8f0ba417SAndroid Build Coastguard Worker // struct MyErrorWrapper {
57*8f0ba417SAndroid Build Coastguard Worker //   MyError val_;
58*8f0ba417SAndroid Build Coastguard Worker //   MyErrorWrapper() : val_(/* reasonable default value */) {}
59*8f0ba417SAndroid Build Coastguard Worker //   MyErrorWrapper(MyError&& e) : val_(std:forward<MyError>(e)) {}
60*8f0ba417SAndroid Build Coastguard Worker //   operator const MyError&() const { return val_; }
61*8f0ba417SAndroid Build Coastguard Worker //   MyError value() const { return val_; }
62*8f0ba417SAndroid Build Coastguard Worker //   std::string print() const {
63*8f0ba417SAndroid Build Coastguard Worker //     switch(val_) {
64*8f0ba417SAndroid Build Coastguard Worker //       MyError::A: return "A";
65*8f0ba417SAndroid Build Coastguard Worker //       MyError::B: return "B";
66*8f0ba417SAndroid Build Coastguard Worker //     }
67*8f0ba417SAndroid Build Coastguard Worker //   }
68*8f0ba417SAndroid Build Coastguard Worker // };
69*8f0ba417SAndroid Build Coastguard Worker //
70*8f0ba417SAndroid Build Coastguard Worker // #define NewMyError(e) Error<MyErrorWrapper>(MyError::e)
71*8f0ba417SAndroid Build Coastguard Worker //
72*8f0ba417SAndroid Build Coastguard Worker // Result<T, MyError> val = NewMyError(A) << "some message";
73*8f0ba417SAndroid Build Coastguard Worker //
74*8f0ba417SAndroid Build Coastguard Worker // Formatting the error message using fmtlib:
75*8f0ba417SAndroid Build Coastguard Worker //
76*8f0ba417SAndroid Build Coastguard Worker // Errorf("{} errors", num); // equivalent to Error() << num << " errors";
77*8f0ba417SAndroid Build Coastguard Worker // ErrnoErrorf("{} errors", num); // equivalent to ErrnoError() << num << " errors";
78*8f0ba417SAndroid Build Coastguard Worker //
79*8f0ba417SAndroid Build Coastguard Worker // Returning success or failure, but not the value:
80*8f0ba417SAndroid Build Coastguard Worker //
81*8f0ba417SAndroid Build Coastguard Worker // Result<void> doSomething() {
82*8f0ba417SAndroid Build Coastguard Worker //   if (success) return {};
83*8f0ba417SAndroid Build Coastguard Worker //   else return Error() << "error occurred";
84*8f0ba417SAndroid Build Coastguard Worker // }
85*8f0ba417SAndroid Build Coastguard Worker //
86*8f0ba417SAndroid Build Coastguard Worker // Extracting error code:
87*8f0ba417SAndroid Build Coastguard Worker //
88*8f0ba417SAndroid Build Coastguard Worker // Result<T> val = Error(3) << "some error occurred";
89*8f0ba417SAndroid Build Coastguard Worker // assert(3 == val.error().code());
90*8f0ba417SAndroid Build Coastguard Worker //
91*8f0ba417SAndroid Build Coastguard Worker 
92*8f0ba417SAndroid Build Coastguard Worker #pragma once
93*8f0ba417SAndroid Build Coastguard Worker 
94*8f0ba417SAndroid Build Coastguard Worker #include <assert.h>
95*8f0ba417SAndroid Build Coastguard Worker #include <errno.h>
96*8f0ba417SAndroid Build Coastguard Worker #include <string.h>
97*8f0ba417SAndroid Build Coastguard Worker 
98*8f0ba417SAndroid Build Coastguard Worker #include <sstream>
99*8f0ba417SAndroid Build Coastguard Worker #include <string>
100*8f0ba417SAndroid Build Coastguard Worker #include <type_traits>
101*8f0ba417SAndroid Build Coastguard Worker 
102*8f0ba417SAndroid Build Coastguard Worker #include "android-base/errors.h"
103*8f0ba417SAndroid Build Coastguard Worker #include "android-base/expected.h"
104*8f0ba417SAndroid Build Coastguard Worker #include "android-base/format.h"
105*8f0ba417SAndroid Build Coastguard Worker 
106*8f0ba417SAndroid Build Coastguard Worker namespace android {
107*8f0ba417SAndroid Build Coastguard Worker namespace base {
108*8f0ba417SAndroid Build Coastguard Worker 
109*8f0ba417SAndroid Build Coastguard Worker // Errno is a wrapper class for errno(3). Use this type instead of `int` when instantiating
110*8f0ba417SAndroid Build Coastguard Worker // `Result<T, E>` and `Error<E>` template classes. This is required to distinguish errno from other
111*8f0ba417SAndroid Build Coastguard Worker // integer-based error code types like `status_t`.
112*8f0ba417SAndroid Build Coastguard Worker struct Errno {
ErrnoErrno113*8f0ba417SAndroid Build Coastguard Worker   Errno() : val_(0) {}
ErrnoErrno114*8f0ba417SAndroid Build Coastguard Worker   Errno(int e) : val_(e) {}
valueErrno115*8f0ba417SAndroid Build Coastguard Worker   int value() const { return val_; }
116*8f0ba417SAndroid Build Coastguard Worker   operator int() const { return value(); }
printErrno117*8f0ba417SAndroid Build Coastguard Worker   const char* print() const { return strerror(value()); }
118*8f0ba417SAndroid Build Coastguard Worker 
119*8f0ba417SAndroid Build Coastguard Worker   int val_;
120*8f0ba417SAndroid Build Coastguard Worker 
121*8f0ba417SAndroid Build Coastguard Worker   // TODO(b/209929099): remove this conversion operator. This currently is needed to not break
122*8f0ba417SAndroid Build Coastguard Worker   // existing places where error().code() is used to construct enum values.
123*8f0ba417SAndroid Build Coastguard Worker   template <typename E, typename = std::enable_if_t<std::is_enum_v<E>>>
EErrno124*8f0ba417SAndroid Build Coastguard Worker   operator E() const {
125*8f0ba417SAndroid Build Coastguard Worker     return E(val_);
126*8f0ba417SAndroid Build Coastguard Worker   }
127*8f0ba417SAndroid Build Coastguard Worker };
128*8f0ba417SAndroid Build Coastguard Worker 
129*8f0ba417SAndroid Build Coastguard Worker static_assert(std::is_trivially_copyable_v<Errno> == true);
130*8f0ba417SAndroid Build Coastguard Worker 
131*8f0ba417SAndroid Build Coastguard Worker template <typename E = Errno, bool include_message = true>
132*8f0ba417SAndroid Build Coastguard Worker struct ResultError {
133*8f0ba417SAndroid Build Coastguard Worker   template <typename T, typename P, typename = std::enable_if_t<std::is_convertible_v<P, E>>>
ResultErrorResultError134*8f0ba417SAndroid Build Coastguard Worker   ResultError(T&& message, P&& code)
135*8f0ba417SAndroid Build Coastguard Worker       : message_(std::forward<T>(message)), code_(E(std::forward<P>(code))) {}
136*8f0ba417SAndroid Build Coastguard Worker 
137*8f0ba417SAndroid Build Coastguard Worker   ResultError(const ResultError& other) = default;
138*8f0ba417SAndroid Build Coastguard Worker   ResultError(ResultError&& other) = default;
139*8f0ba417SAndroid Build Coastguard Worker   ResultError& operator=(const ResultError& other) = default;
140*8f0ba417SAndroid Build Coastguard Worker   ResultError& operator=(ResultError&& other) = default;
141*8f0ba417SAndroid Build Coastguard Worker 
142*8f0ba417SAndroid Build Coastguard Worker   template <typename T>
143*8f0ba417SAndroid Build Coastguard Worker   // NOLINTNEXTLINE(google-explicit-constructor)
144*8f0ba417SAndroid Build Coastguard Worker   operator android::base::expected<T, ResultError<E>>() && {
145*8f0ba417SAndroid Build Coastguard Worker     return android::base::unexpected(std::move(*this));
146*8f0ba417SAndroid Build Coastguard Worker   }
147*8f0ba417SAndroid Build Coastguard Worker 
148*8f0ba417SAndroid Build Coastguard Worker   template <typename T>
149*8f0ba417SAndroid Build Coastguard Worker   // NOLINTNEXTLINE(google-explicit-constructor)
150*8f0ba417SAndroid Build Coastguard Worker   operator android::base::expected<T, ResultError<E>>() const& {
151*8f0ba417SAndroid Build Coastguard Worker     return android::base::unexpected(*this);
152*8f0ba417SAndroid Build Coastguard Worker   }
153*8f0ba417SAndroid Build Coastguard Worker 
messageResultError154*8f0ba417SAndroid Build Coastguard Worker   const std::string& message() const { return message_; }
codeResultError155*8f0ba417SAndroid Build Coastguard Worker   const E& code() const { return code_; }
156*8f0ba417SAndroid Build Coastguard Worker 
157*8f0ba417SAndroid Build Coastguard Worker  private:
158*8f0ba417SAndroid Build Coastguard Worker   std::string message_;
159*8f0ba417SAndroid Build Coastguard Worker   E code_;
160*8f0ba417SAndroid Build Coastguard Worker };
161*8f0ba417SAndroid Build Coastguard Worker 
162*8f0ba417SAndroid Build Coastguard Worker template <typename E>
format_as(ResultError<E,true> error)163*8f0ba417SAndroid Build Coastguard Worker auto format_as(ResultError<E, true> error) {
164*8f0ba417SAndroid Build Coastguard Worker   return error.message();
165*8f0ba417SAndroid Build Coastguard Worker }
166*8f0ba417SAndroid Build Coastguard Worker 
167*8f0ba417SAndroid Build Coastguard Worker template <typename E>
168*8f0ba417SAndroid Build Coastguard Worker struct ResultError<E, /* include_message */ false> {
169*8f0ba417SAndroid Build Coastguard Worker   template <typename P, typename = std::enable_if_t<std::is_convertible_v<P, E>>>
170*8f0ba417SAndroid Build Coastguard Worker   ResultError(P&& code) : code_(E(std::forward<P>(code))) {}
171*8f0ba417SAndroid Build Coastguard Worker 
172*8f0ba417SAndroid Build Coastguard Worker   template <typename T>
173*8f0ba417SAndroid Build Coastguard Worker   operator android::base::expected<T, ResultError<E, false>>() const {
174*8f0ba417SAndroid Build Coastguard Worker     return android::base::unexpected(ResultError<E, false>(code_));
175*8f0ba417SAndroid Build Coastguard Worker   }
176*8f0ba417SAndroid Build Coastguard Worker 
177*8f0ba417SAndroid Build Coastguard Worker   const E& code() const { return code_; }
178*8f0ba417SAndroid Build Coastguard Worker 
179*8f0ba417SAndroid Build Coastguard Worker  private:
180*8f0ba417SAndroid Build Coastguard Worker   E code_;
181*8f0ba417SAndroid Build Coastguard Worker };
182*8f0ba417SAndroid Build Coastguard Worker 
183*8f0ba417SAndroid Build Coastguard Worker template <typename E>
184*8f0ba417SAndroid Build Coastguard Worker inline bool operator==(const ResultError<E>& lhs, const ResultError<E>& rhs) {
185*8f0ba417SAndroid Build Coastguard Worker   return lhs.message() == rhs.message() && lhs.code() == rhs.code();
186*8f0ba417SAndroid Build Coastguard Worker }
187*8f0ba417SAndroid Build Coastguard Worker 
188*8f0ba417SAndroid Build Coastguard Worker template <typename E>
189*8f0ba417SAndroid Build Coastguard Worker inline bool operator!=(const ResultError<E>& lhs, const ResultError<E>& rhs) {
190*8f0ba417SAndroid Build Coastguard Worker   return !(lhs == rhs);
191*8f0ba417SAndroid Build Coastguard Worker }
192*8f0ba417SAndroid Build Coastguard Worker 
193*8f0ba417SAndroid Build Coastguard Worker template <typename E>
194*8f0ba417SAndroid Build Coastguard Worker inline std::ostream& operator<<(std::ostream& os, const ResultError<E>& t) {
195*8f0ba417SAndroid Build Coastguard Worker   os << t.message();
196*8f0ba417SAndroid Build Coastguard Worker   return os;
197*8f0ba417SAndroid Build Coastguard Worker }
198*8f0ba417SAndroid Build Coastguard Worker 
199*8f0ba417SAndroid Build Coastguard Worker namespace internal {
200*8f0ba417SAndroid Build Coastguard Worker // Stream class that does nothing and is has zero (actually 1) size. It is used instead of
201*8f0ba417SAndroid Build Coastguard Worker // std::stringstream when include_message is false so that we use less on stack.
202*8f0ba417SAndroid Build Coastguard Worker // sizeof(std::stringstream) is 280 on arm64.
203*8f0ba417SAndroid Build Coastguard Worker struct DoNothingStream {
204*8f0ba417SAndroid Build Coastguard Worker   template <typename T>
205*8f0ba417SAndroid Build Coastguard Worker   DoNothingStream& operator<<(T&&) {
206*8f0ba417SAndroid Build Coastguard Worker     return *this;
207*8f0ba417SAndroid Build Coastguard Worker   }
208*8f0ba417SAndroid Build Coastguard Worker 
209*8f0ba417SAndroid Build Coastguard Worker   std::string str() const { return ""; }
210*8f0ba417SAndroid Build Coastguard Worker };
211*8f0ba417SAndroid Build Coastguard Worker }  // namespace internal
212*8f0ba417SAndroid Build Coastguard Worker 
213*8f0ba417SAndroid Build Coastguard Worker template <typename E = Errno, bool include_message = true,
214*8f0ba417SAndroid Build Coastguard Worker           typename = std::enable_if_t<!std::is_same_v<E, int>>>
215*8f0ba417SAndroid Build Coastguard Worker class Error {
216*8f0ba417SAndroid Build Coastguard Worker  public:
217*8f0ba417SAndroid Build Coastguard Worker   Error() : code_(0), has_code_(false) {}
218*8f0ba417SAndroid Build Coastguard Worker   template <typename P, typename = std::enable_if_t<std::is_convertible_v<P, E>>>
219*8f0ba417SAndroid Build Coastguard Worker   // NOLINTNEXTLINE(google-explicit-constructor)
220*8f0ba417SAndroid Build Coastguard Worker   Error(P&& code) : code_(std::forward<P>(code)), has_code_(true) {}
221*8f0ba417SAndroid Build Coastguard Worker 
222*8f0ba417SAndroid Build Coastguard Worker   template <typename T, typename P, typename = std::enable_if_t<std::is_convertible_v<E, P>>>
223*8f0ba417SAndroid Build Coastguard Worker   // NOLINTNEXTLINE(google-explicit-constructor)
224*8f0ba417SAndroid Build Coastguard Worker   operator android::base::expected<T, ResultError<P>>() const {
225*8f0ba417SAndroid Build Coastguard Worker     return android::base::unexpected(ResultError<P>(str(), static_cast<P>(code_)));
226*8f0ba417SAndroid Build Coastguard Worker   }
227*8f0ba417SAndroid Build Coastguard Worker 
228*8f0ba417SAndroid Build Coastguard Worker   template <typename T, typename P, typename = std::enable_if_t<std::is_convertible_v<E, P>>>
229*8f0ba417SAndroid Build Coastguard Worker   // NOLINTNEXTLINE(google-explicit-constructor)
230*8f0ba417SAndroid Build Coastguard Worker   operator android::base::expected<T, ResultError<P, false>>() const {
231*8f0ba417SAndroid Build Coastguard Worker     return android::base::unexpected(ResultError<P, false>(static_cast<P>(code_)));
232*8f0ba417SAndroid Build Coastguard Worker   }
233*8f0ba417SAndroid Build Coastguard Worker 
234*8f0ba417SAndroid Build Coastguard Worker   template <typename T>
235*8f0ba417SAndroid Build Coastguard Worker   Error& operator<<(T&& t) {
236*8f0ba417SAndroid Build Coastguard Worker     static_assert(include_message, "<< not supported when include_message = false");
237*8f0ba417SAndroid Build Coastguard Worker     // NOLINTNEXTLINE(bugprone-suspicious-semicolon)
238*8f0ba417SAndroid Build Coastguard Worker     if constexpr (std::is_same_v<std::remove_cv_t<std::remove_reference_t<T>>, ResultError<E>>) {
239*8f0ba417SAndroid Build Coastguard Worker       if (!has_code_) {
240*8f0ba417SAndroid Build Coastguard Worker         code_ = t.code();
241*8f0ba417SAndroid Build Coastguard Worker       }
242*8f0ba417SAndroid Build Coastguard Worker       return (*this) << t.message();
243*8f0ba417SAndroid Build Coastguard Worker     }
244*8f0ba417SAndroid Build Coastguard Worker     int saved = errno;
245*8f0ba417SAndroid Build Coastguard Worker     ss_ << t;
246*8f0ba417SAndroid Build Coastguard Worker     errno = saved;
247*8f0ba417SAndroid Build Coastguard Worker     return *this;
248*8f0ba417SAndroid Build Coastguard Worker   }
249*8f0ba417SAndroid Build Coastguard Worker 
250*8f0ba417SAndroid Build Coastguard Worker   const std::string str() const {
251*8f0ba417SAndroid Build Coastguard Worker     static_assert(include_message, "str() not supported when include_message = false");
252*8f0ba417SAndroid Build Coastguard Worker     std::string str = ss_.str();
253*8f0ba417SAndroid Build Coastguard Worker     if (has_code_) {
254*8f0ba417SAndroid Build Coastguard Worker       if (str.empty()) {
255*8f0ba417SAndroid Build Coastguard Worker         return code_.print();
256*8f0ba417SAndroid Build Coastguard Worker       }
257*8f0ba417SAndroid Build Coastguard Worker       return std::move(str) + ": " + code_.print();
258*8f0ba417SAndroid Build Coastguard Worker     }
259*8f0ba417SAndroid Build Coastguard Worker     return str;
260*8f0ba417SAndroid Build Coastguard Worker   }
261*8f0ba417SAndroid Build Coastguard Worker 
262*8f0ba417SAndroid Build Coastguard Worker   Error(const Error&) = delete;
263*8f0ba417SAndroid Build Coastguard Worker   Error(Error&&) = delete;
264*8f0ba417SAndroid Build Coastguard Worker   Error& operator=(const Error&) = delete;
265*8f0ba417SAndroid Build Coastguard Worker   Error& operator=(Error&&) = delete;
266*8f0ba417SAndroid Build Coastguard Worker 
267*8f0ba417SAndroid Build Coastguard Worker   template <typename... Args>
268*8f0ba417SAndroid Build Coastguard Worker   friend Error ErrorfImpl(fmt::format_string<Args...> fmt, const Args&... args);
269*8f0ba417SAndroid Build Coastguard Worker 
270*8f0ba417SAndroid Build Coastguard Worker   template <typename... Args>
271*8f0ba417SAndroid Build Coastguard Worker   friend Error ErrnoErrorfImpl(fmt::format_string<Args...> fmt, const Args&... args);
272*8f0ba417SAndroid Build Coastguard Worker 
273*8f0ba417SAndroid Build Coastguard Worker  private:
274*8f0ba417SAndroid Build Coastguard Worker   Error(bool has_code, E code, const std::string& message) : code_(code), has_code_(has_code) {
275*8f0ba417SAndroid Build Coastguard Worker     (*this) << message;
276*8f0ba417SAndroid Build Coastguard Worker   }
277*8f0ba417SAndroid Build Coastguard Worker 
278*8f0ba417SAndroid Build Coastguard Worker   std::conditional_t<include_message, std::stringstream, internal::DoNothingStream> ss_;
279*8f0ba417SAndroid Build Coastguard Worker   E code_;
280*8f0ba417SAndroid Build Coastguard Worker   const bool has_code_;
281*8f0ba417SAndroid Build Coastguard Worker };
282*8f0ba417SAndroid Build Coastguard Worker 
283*8f0ba417SAndroid Build Coastguard Worker inline Error<Errno> ErrnoError() {
284*8f0ba417SAndroid Build Coastguard Worker   return Error<Errno>(Errno{errno});
285*8f0ba417SAndroid Build Coastguard Worker }
286*8f0ba417SAndroid Build Coastguard Worker 
287*8f0ba417SAndroid Build Coastguard Worker template <typename E>
288*8f0ba417SAndroid Build Coastguard Worker inline E ErrorCode(E code) {
289*8f0ba417SAndroid Build Coastguard Worker   return code;
290*8f0ba417SAndroid Build Coastguard Worker }
291*8f0ba417SAndroid Build Coastguard Worker 
292*8f0ba417SAndroid Build Coastguard Worker // Return the error code of the last ResultError object, if any.
293*8f0ba417SAndroid Build Coastguard Worker // Otherwise, return `code` as it is.
294*8f0ba417SAndroid Build Coastguard Worker template <typename T, typename E, typename... Args>
295*8f0ba417SAndroid Build Coastguard Worker inline E ErrorCode(E code, T&& t, const Args&... args) {
296*8f0ba417SAndroid Build Coastguard Worker   if constexpr (std::is_same_v<std::remove_cv_t<std::remove_reference_t<T>>, ResultError<E>>) {
297*8f0ba417SAndroid Build Coastguard Worker     return ErrorCode(t.code(), args...);
298*8f0ba417SAndroid Build Coastguard Worker   }
299*8f0ba417SAndroid Build Coastguard Worker   return ErrorCode(code, args...);
300*8f0ba417SAndroid Build Coastguard Worker }
301*8f0ba417SAndroid Build Coastguard Worker 
302*8f0ba417SAndroid Build Coastguard Worker __attribute__((noinline)) ResultError<Errno> MakeResultErrorWithCode(std::string&& message,
303*8f0ba417SAndroid Build Coastguard Worker                                                                      Errno code);
304*8f0ba417SAndroid Build Coastguard Worker 
305*8f0ba417SAndroid Build Coastguard Worker template <typename... Args>
306*8f0ba417SAndroid Build Coastguard Worker inline ResultError<Errno> ErrorfImpl(fmt::format_string<Args...> fmt, const Args&... args) {
307*8f0ba417SAndroid Build Coastguard Worker   return ResultError(fmt::vformat(fmt.get(), fmt::make_format_args(args...)),
308*8f0ba417SAndroid Build Coastguard Worker                      ErrorCode(Errno{}, args...));
309*8f0ba417SAndroid Build Coastguard Worker }
310*8f0ba417SAndroid Build Coastguard Worker 
311*8f0ba417SAndroid Build Coastguard Worker template <typename... Args>
312*8f0ba417SAndroid Build Coastguard Worker inline ResultError<Errno> ErrnoErrorfImpl(fmt::format_string<Args...> fmt, const Args&... args) {
313*8f0ba417SAndroid Build Coastguard Worker   Errno code{errno};
314*8f0ba417SAndroid Build Coastguard Worker   return MakeResultErrorWithCode(fmt::vformat(fmt.get(), fmt::make_format_args(args...)), code);
315*8f0ba417SAndroid Build Coastguard Worker }
316*8f0ba417SAndroid Build Coastguard Worker 
317*8f0ba417SAndroid Build Coastguard Worker #define Errorf(fmt, ...) android::base::ErrorfImpl(FMT_STRING(fmt), ##__VA_ARGS__)
318*8f0ba417SAndroid Build Coastguard Worker #define ErrnoErrorf(fmt, ...) android::base::ErrnoErrorfImpl(FMT_STRING(fmt), ##__VA_ARGS__)
319*8f0ba417SAndroid Build Coastguard Worker 
320*8f0ba417SAndroid Build Coastguard Worker template <typename T, typename E = Errno, bool include_message = true>
321*8f0ba417SAndroid Build Coastguard Worker using Result = android::base::expected<T, ResultError<E, include_message>>;
322*8f0ba417SAndroid Build Coastguard Worker 
323*8f0ba417SAndroid Build Coastguard Worker // Specialization of android::base::OkOrFail<V> for V = Result<T, E>. See android-base/errors.h
324*8f0ba417SAndroid Build Coastguard Worker // for the contract.
325*8f0ba417SAndroid Build Coastguard Worker 
326*8f0ba417SAndroid Build Coastguard Worker namespace impl {
327*8f0ba417SAndroid Build Coastguard Worker template <typename U>
328*8f0ba417SAndroid Build Coastguard Worker using Code = std::decay_t<decltype(std::declval<U>().error().code())>;
329*8f0ba417SAndroid Build Coastguard Worker 
330*8f0ba417SAndroid Build Coastguard Worker template <typename U>
331*8f0ba417SAndroid Build Coastguard Worker using ErrorType = std::decay_t<decltype(std::declval<U>().error())>;
332*8f0ba417SAndroid Build Coastguard Worker 
333*8f0ba417SAndroid Build Coastguard Worker template <typename U>
334*8f0ba417SAndroid Build Coastguard Worker constexpr bool IsNumeric = std::is_integral_v<U> || std::is_floating_point_v<U> ||
335*8f0ba417SAndroid Build Coastguard Worker                            (std::is_enum_v<U> && std::is_convertible_v<U, size_t>);
336*8f0ba417SAndroid Build Coastguard Worker 
337*8f0ba417SAndroid Build Coastguard Worker // This base class exists to take advantage of shadowing
338*8f0ba417SAndroid Build Coastguard Worker // We include the conversion in this base class so that if the conversion in NumericConversions
339*8f0ba417SAndroid Build Coastguard Worker // overlaps, we (arbitrarily) choose the implementation in NumericConversions due to shadowing.
340*8f0ba417SAndroid Build Coastguard Worker template <typename T>
341*8f0ba417SAndroid Build Coastguard Worker struct ConversionBase {
342*8f0ba417SAndroid Build Coastguard Worker   ErrorType<T> error_;
343*8f0ba417SAndroid Build Coastguard Worker   // T is a expected<U, ErrorType<T>>.
344*8f0ba417SAndroid Build Coastguard Worker   operator T() const& { return unexpected(error_); }
345*8f0ba417SAndroid Build Coastguard Worker   operator T() && { return unexpected(std::move(error_)); }
346*8f0ba417SAndroid Build Coastguard Worker 
347*8f0ba417SAndroid Build Coastguard Worker   operator Code<T>() const { return error_.code(); }
348*8f0ba417SAndroid Build Coastguard Worker };
349*8f0ba417SAndroid Build Coastguard Worker 
350*8f0ba417SAndroid Build Coastguard Worker // User defined conversions can be followed by numeric conversions
351*8f0ba417SAndroid Build Coastguard Worker // Although we template specialize for the exact code type, we need
352*8f0ba417SAndroid Build Coastguard Worker // specializations for conversions to all numeric types to avoid an
353*8f0ba417SAndroid Build Coastguard Worker // ambiguous conversion sequence.
354*8f0ba417SAndroid Build Coastguard Worker template <typename T, typename = void>
355*8f0ba417SAndroid Build Coastguard Worker struct NumericConversions : public ConversionBase<T> {};
356*8f0ba417SAndroid Build Coastguard Worker template <typename T>
357*8f0ba417SAndroid Build Coastguard Worker struct NumericConversions<T,
358*8f0ba417SAndroid Build Coastguard Worker     std::enable_if_t<impl::IsNumeric<impl::Code<T>>>
359*8f0ba417SAndroid Build Coastguard Worker     > : public ConversionBase<T>
360*8f0ba417SAndroid Build Coastguard Worker {
361*8f0ba417SAndroid Build Coastguard Worker #pragma push_macro("SPECIALIZED_CONVERSION")
362*8f0ba417SAndroid Build Coastguard Worker #define SPECIALIZED_CONVERSION(type)                                                  \
363*8f0ba417SAndroid Build Coastguard Worker   operator expected<type, ErrorType<T>>() const& { return unexpected(this->error_); } \
364*8f0ba417SAndroid Build Coastguard Worker   operator expected<type, ErrorType<T>>()&& { return unexpected(std::move(this->error_)); }
365*8f0ba417SAndroid Build Coastguard Worker 
366*8f0ba417SAndroid Build Coastguard Worker   SPECIALIZED_CONVERSION(int)
367*8f0ba417SAndroid Build Coastguard Worker   SPECIALIZED_CONVERSION(short int)
368*8f0ba417SAndroid Build Coastguard Worker   SPECIALIZED_CONVERSION(unsigned short int)
369*8f0ba417SAndroid Build Coastguard Worker   SPECIALIZED_CONVERSION(unsigned int)
370*8f0ba417SAndroid Build Coastguard Worker   SPECIALIZED_CONVERSION(long int)
371*8f0ba417SAndroid Build Coastguard Worker   SPECIALIZED_CONVERSION(unsigned long int)
372*8f0ba417SAndroid Build Coastguard Worker   SPECIALIZED_CONVERSION(long long int)
373*8f0ba417SAndroid Build Coastguard Worker   SPECIALIZED_CONVERSION(unsigned long long int)
374*8f0ba417SAndroid Build Coastguard Worker   SPECIALIZED_CONVERSION(bool)
375*8f0ba417SAndroid Build Coastguard Worker   SPECIALIZED_CONVERSION(char)
376*8f0ba417SAndroid Build Coastguard Worker   SPECIALIZED_CONVERSION(unsigned char)
377*8f0ba417SAndroid Build Coastguard Worker   SPECIALIZED_CONVERSION(signed char)
378*8f0ba417SAndroid Build Coastguard Worker   SPECIALIZED_CONVERSION(wchar_t)
379*8f0ba417SAndroid Build Coastguard Worker   SPECIALIZED_CONVERSION(char16_t)
380*8f0ba417SAndroid Build Coastguard Worker   SPECIALIZED_CONVERSION(char32_t)
381*8f0ba417SAndroid Build Coastguard Worker   SPECIALIZED_CONVERSION(float)
382*8f0ba417SAndroid Build Coastguard Worker   SPECIALIZED_CONVERSION(double)
383*8f0ba417SAndroid Build Coastguard Worker   SPECIALIZED_CONVERSION(long double)
384*8f0ba417SAndroid Build Coastguard Worker 
385*8f0ba417SAndroid Build Coastguard Worker #undef SPECIALIZED_CONVERSION
386*8f0ba417SAndroid Build Coastguard Worker #pragma pop_macro("SPECIALIZED_CONVERSION")
387*8f0ba417SAndroid Build Coastguard Worker   // For debugging purposes
388*8f0ba417SAndroid Build Coastguard Worker   using IsNumericT = std::true_type;
389*8f0ba417SAndroid Build Coastguard Worker };
390*8f0ba417SAndroid Build Coastguard Worker 
391*8f0ba417SAndroid Build Coastguard Worker #ifdef __cpp_concepts
392*8f0ba417SAndroid Build Coastguard Worker template <class U>
393*8f0ba417SAndroid Build Coastguard Worker // Define a concept which **any** type matches to
394*8f0ba417SAndroid Build Coastguard Worker concept Universal = std::is_same_v<U, U>;
395*8f0ba417SAndroid Build Coastguard Worker #endif
396*8f0ba417SAndroid Build Coastguard Worker 
397*8f0ba417SAndroid Build Coastguard Worker // A type that is never used.
398*8f0ba417SAndroid Build Coastguard Worker struct Never {};
399*8f0ba417SAndroid Build Coastguard Worker } // namespace impl
400*8f0ba417SAndroid Build Coastguard Worker 
401*8f0ba417SAndroid Build Coastguard Worker template <typename T, typename E, bool include_message>
402*8f0ba417SAndroid Build Coastguard Worker struct OkOrFail<Result<T, E, include_message>>
403*8f0ba417SAndroid Build Coastguard Worker     : public impl::NumericConversions<Result<T, E, include_message>> {
404*8f0ba417SAndroid Build Coastguard Worker   using V = Result<T, E, include_message>;
405*8f0ba417SAndroid Build Coastguard Worker   using Err = impl::ErrorType<V>;
406*8f0ba417SAndroid Build Coastguard Worker   using C = impl::Code<V>;
407*8f0ba417SAndroid Build Coastguard Worker private:
408*8f0ba417SAndroid Build Coastguard Worker    OkOrFail(Err&& v): impl::NumericConversions<V>{std::move(v)} {}
409*8f0ba417SAndroid Build Coastguard Worker    OkOrFail(const OkOrFail& other) = delete;
410*8f0ba417SAndroid Build Coastguard Worker    OkOrFail(const OkOrFail&& other) = delete;
411*8f0ba417SAndroid Build Coastguard Worker public:
412*8f0ba417SAndroid Build Coastguard Worker   // Checks if V is ok or fail
413*8f0ba417SAndroid Build Coastguard Worker   static bool IsOk(const V& val) { return val.ok(); }
414*8f0ba417SAndroid Build Coastguard Worker 
415*8f0ba417SAndroid Build Coastguard Worker   // Turns V into a success value
416*8f0ba417SAndroid Build Coastguard Worker   static T Unwrap(V&& val) {
417*8f0ba417SAndroid Build Coastguard Worker     if constexpr (std::is_same_v<T, void>) {
418*8f0ba417SAndroid Build Coastguard Worker       assert(IsOk(val));
419*8f0ba417SAndroid Build Coastguard Worker       return;
420*8f0ba417SAndroid Build Coastguard Worker     } else {
421*8f0ba417SAndroid Build Coastguard Worker       return std::move(val.value());
422*8f0ba417SAndroid Build Coastguard Worker     }
423*8f0ba417SAndroid Build Coastguard Worker   }
424*8f0ba417SAndroid Build Coastguard Worker 
425*8f0ba417SAndroid Build Coastguard Worker   // Consumes V when it's a fail value
426*8f0ba417SAndroid Build Coastguard Worker   static OkOrFail<V> Fail(V&& v) {
427*8f0ba417SAndroid Build Coastguard Worker     assert(!IsOk(v));
428*8f0ba417SAndroid Build Coastguard Worker     return OkOrFail<V>{std::move(v.error())};
429*8f0ba417SAndroid Build Coastguard Worker   }
430*8f0ba417SAndroid Build Coastguard Worker 
431*8f0ba417SAndroid Build Coastguard Worker   // We specialize as much as possible to avoid ambiguous conversion with templated expected ctor.
432*8f0ba417SAndroid Build Coastguard Worker   // We don't need this specialization if `C` is numeric because that case is already covered by
433*8f0ba417SAndroid Build Coastguard Worker   // `NumericConversions`.
434*8f0ba417SAndroid Build Coastguard Worker   operator Result<std::conditional_t<impl::IsNumeric<C>, impl::Never, C>, E, include_message>()
435*8f0ba417SAndroid Build Coastguard Worker       const& {
436*8f0ba417SAndroid Build Coastguard Worker     return unexpected(this->error_);
437*8f0ba417SAndroid Build Coastguard Worker   }
438*8f0ba417SAndroid Build Coastguard Worker   operator Result<std::conditional_t<impl::IsNumeric<C>, impl::Never, C>, E, include_message>() && {
439*8f0ba417SAndroid Build Coastguard Worker     return unexpected(std::move(this->error_));
440*8f0ba417SAndroid Build Coastguard Worker   }
441*8f0ba417SAndroid Build Coastguard Worker 
442*8f0ba417SAndroid Build Coastguard Worker #ifdef __cpp_concepts
443*8f0ba417SAndroid Build Coastguard Worker   // The idea here is to match this template method to any type (not simply trivial types).
444*8f0ba417SAndroid Build Coastguard Worker   // The reason for including a constraint is to take advantage of the fact that a constrained
445*8f0ba417SAndroid Build Coastguard Worker   // method always has strictly lower precedence than a non-constrained method in template
446*8f0ba417SAndroid Build Coastguard Worker   // specialization rules (thus avoiding ambiguity). So we use a universally matching constraint to
447*8f0ba417SAndroid Build Coastguard Worker   // mark this function as less preferable (but still accepting of all types).
448*8f0ba417SAndroid Build Coastguard Worker   template <impl::Universal U>
449*8f0ba417SAndroid Build Coastguard Worker   operator Result<U, E, include_message>() const& {
450*8f0ba417SAndroid Build Coastguard Worker     return unexpected(this->error_);
451*8f0ba417SAndroid Build Coastguard Worker   }
452*8f0ba417SAndroid Build Coastguard Worker   template <impl::Universal U>
453*8f0ba417SAndroid Build Coastguard Worker   operator Result<U, E, include_message>() && {
454*8f0ba417SAndroid Build Coastguard Worker     return unexpected(std::move(this->error_));
455*8f0ba417SAndroid Build Coastguard Worker   }
456*8f0ba417SAndroid Build Coastguard Worker #else
457*8f0ba417SAndroid Build Coastguard Worker   template <typename U>
458*8f0ba417SAndroid Build Coastguard Worker   operator Result<U, E, include_message>() const& {
459*8f0ba417SAndroid Build Coastguard Worker     return unexpected(this->error_);
460*8f0ba417SAndroid Build Coastguard Worker   }
461*8f0ba417SAndroid Build Coastguard Worker   template <typename U>
462*8f0ba417SAndroid Build Coastguard Worker   operator Result<U, E, include_message>() && {
463*8f0ba417SAndroid Build Coastguard Worker     return unexpected(std::move(this->error_));
464*8f0ba417SAndroid Build Coastguard Worker   }
465*8f0ba417SAndroid Build Coastguard Worker #endif
466*8f0ba417SAndroid Build Coastguard Worker 
467*8f0ba417SAndroid Build Coastguard Worker   static const std::string& ErrorMessage(const V& val) { return val.error().message(); }
468*8f0ba417SAndroid Build Coastguard Worker };
469*8f0ba417SAndroid Build Coastguard Worker 
470*8f0ba417SAndroid Build Coastguard Worker // Macros for testing the results of functions that return android::base::Result. These also work
471*8f0ba417SAndroid Build Coastguard Worker // with base::android::expected. They assume the user depends on libgmock and includes
472*8f0ba417SAndroid Build Coastguard Worker // gtest/gtest.h. For advanced matchers and customized error messages, see result-gmock.h.
473*8f0ba417SAndroid Build Coastguard Worker 
474*8f0ba417SAndroid Build Coastguard Worker #define ASSERT_RESULT_OK(stmt)                            \
475*8f0ba417SAndroid Build Coastguard Worker   if (const auto& tmp = (stmt); !tmp.ok())                \
476*8f0ba417SAndroid Build Coastguard Worker   FAIL() << "Value of: " << #stmt << "\n"                 \
477*8f0ba417SAndroid Build Coastguard Worker          << "  Actual: " << tmp.error().message() << "\n" \
478*8f0ba417SAndroid Build Coastguard Worker          << "Expected: is ok\n"
479*8f0ba417SAndroid Build Coastguard Worker 
480*8f0ba417SAndroid Build Coastguard Worker #define EXPECT_RESULT_OK(stmt)                                   \
481*8f0ba417SAndroid Build Coastguard Worker   if (const auto& tmp = (stmt); !tmp.ok())                       \
482*8f0ba417SAndroid Build Coastguard Worker   ADD_FAILURE() << "Value of: " << #stmt << "\n"                 \
483*8f0ba417SAndroid Build Coastguard Worker                 << "  Actual: " << tmp.error().message() << "\n" \
484*8f0ba417SAndroid Build Coastguard Worker                 << "Expected: is ok\n"
485*8f0ba417SAndroid Build Coastguard Worker 
486*8f0ba417SAndroid Build Coastguard Worker }  // namespace base
487*8f0ba417SAndroid Build Coastguard Worker }  // namespace android
488