Android-cuttlefish cvd tool
expected.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 2023 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#pragma once
17
18#include <functional>
19#include <type_traits>
20#include <variant>
21
22namespace gfxstream {
23
24template <typename E>
25class unexpected;
26
27template <class E>
29
30#define ENABLE_IF(...) typename std::enable_if<__VA_ARGS__>::type* = nullptr
31
32template <typename T, typename E>
33class expected {
34 public:
35 constexpr expected() = default;
36 constexpr expected(const expected& rhs) = default;
37 constexpr expected(expected&& rhs) = default;
38
39 template <typename CopyT = T, ENABLE_IF(!std::is_void<CopyT>::value)>
40 constexpr expected(T&& v)
41 : mVariant(std::in_place_index<0>, std::forward<T>(v)) {}
42
43 template <class... Args,
44 ENABLE_IF(std::is_constructible<T, Args&&...>::value)>
45 constexpr expected(std::in_place_t, Args&&... args)
46 : mVariant(std::in_place_index<0>, std::forward<Args>(args)...) {}
47
48 constexpr expected(const unexpected<E>& u)
49 : mVariant(std::in_place_index<1>, u.value()) {}
50
51 template <class OtherE = E,
52 ENABLE_IF(std::is_constructible<E, const OtherE&>::value)>
53 constexpr expected(const unexpected<OtherE>& e)
54 : mVariant(std::in_place_index<1>, e.value()) {}
55
56 constexpr const T* operator->() const { return std::addressof(value()); }
57 constexpr T* operator->() { return std::addressof(value()); }
58 constexpr const T& operator*() const& { return value(); }
59 constexpr T& operator*() & { return value(); }
60 constexpr const T&& operator*() const&& {
61 return std::move(std::get<T>(mVariant));
62 }
63 constexpr T&& operator*() && { return std::move(std::get<T>(mVariant)); }
64
65 constexpr bool has_value() const { return mVariant.index() == 0; }
66 constexpr bool ok() const { return has_value(); }
67
68 template <typename T2 = T, ENABLE_IF(!std::is_void<T>::value)>
69 constexpr const T& value() const& {
70 return std::get<T>(mVariant);
71 }
72 template <typename T2 = T, ENABLE_IF(!std::is_void<T>::value)>
73 constexpr T& value() & {
74 return std::get<T>(mVariant);
75 }
76
77 constexpr const T&& value() const&& {
78 return std::move(std::get<T>(mVariant));
79 }
80 constexpr T&& value() && { return std::move(std::get<T>(mVariant)); }
81
82 constexpr const E& error() const& { return std::get<E>(mVariant); }
83 constexpr E& error() & { return std::get<E>(mVariant); }
84 constexpr const E&& error() const&& {
85 return std::move(std::get<E>(mVariant));
86 }
87 constexpr E&& error() && { return std::move(std::get<E>(mVariant)); }
88
89 template <typename F,
90 typename NewE = std::remove_cv_t<std::invoke_result_t<F, E>>>
91 constexpr expected<T, NewE> transform_error(F&& function) {
92 if (ok()) {
93 if constexpr (std::is_void_v<T>) {
94 return expected<T, NewE>();
95 } else {
96 return expected<T, NewE>(std::in_place, value());
97 }
98 } else {
99 return unexpected(std::invoke(std::forward<F>(function), error()));
100 }
101 }
102
103 private:
104 std::variant<T, E> mVariant;
105};
106
107template <typename E>
109 public:
110 constexpr unexpected(const unexpected&) = default;
111
112 template <typename T>
113 constexpr explicit unexpected(T&& e) : mError(std::forward<T>(e)) {}
114
115 template <class... Args,
116 ENABLE_IF(std::is_constructible<E, Args&&...>::value)>
117 constexpr explicit unexpected(std::in_place_t, Args&&... args)
118 : mError(std::forward<Args>(args)...) {}
119
120 constexpr const E& value() const& noexcept { return mError; }
121 constexpr E& value() & noexcept { return mError; }
122 constexpr const E&& value() const&& noexcept { return std::move(mError); }
123 constexpr E&& value() && noexcept { return std::move(mError); }
124
125 private:
127};
128
129#define GFXSTREAM_EXPECT(x) \
130 ({ \
131 auto local_expected = (x); \
132 if (!local_expected.ok()) { \
133 return gfxstream::unexpected(local_expected.error()); \
134 }; \
135 std::move(local_expected.value()); \
136 })
137
138class Ok {};
139
140} // namespace gfxstream
Definition: expected.h:138
Definition: expected.h:33
constexpr T * operator->()
Definition: expected.h:57
constexpr T && operator*() &&
Definition: expected.h:63
constexpr const T && operator*() const &&
Definition: expected.h:60
std::variant< T, E > mVariant
Definition: expected.h:104
constexpr bool has_value() const
Definition: expected.h:65
constexpr const T & value() const &
Definition: expected.h:69
constexpr expected()=default
constexpr expected(const expected &rhs)=default
constexpr E && error() &&
Definition: expected.h:87
constexpr T & operator*() &
Definition: expected.h:59
constexpr const T & operator*() const &
Definition: expected.h:58
constexpr expected< T, NewE > transform_error(F &&function)
Definition: expected.h:91
constexpr expected(expected &&rhs)=default
constexpr expected(std::in_place_t, Args &&... args)
Definition: expected.h:45
constexpr T & value() &
Definition: expected.h:73
constexpr const T * operator->() const
Definition: expected.h:56
constexpr const T && value() const &&
Definition: expected.h:77
constexpr expected(const unexpected< E > &u)
Definition: expected.h:48
constexpr expected(T &&v)
Definition: expected.h:40
constexpr T && value() &&
Definition: expected.h:80
constexpr E & error() &
Definition: expected.h:83
constexpr expected(const unexpected< OtherE > &e)
Definition: expected.h:53
constexpr const E && error() const &&
Definition: expected.h:84
constexpr bool ok() const
Definition: expected.h:66
constexpr const E & error() const &
Definition: expected.h:82
Definition: expected.h:108
constexpr E && value() &&noexcept
Definition: expected.h:123
constexpr const E && value() const &&noexcept
Definition: expected.h:122
constexpr unexpected(std::in_place_t, Args &&... args)
Definition: expected.h:117
constexpr E & value() &noexcept
Definition: expected.h:121
E mError
Definition: expected.h:126
constexpr const E & value() const &noexcept
Definition: expected.h:120
constexpr unexpected(const unexpected &)=default
constexpr unexpected(T &&e)
Definition: expected.h:113
#define ENABLE_IF(...)
Definition: expected.h:30
Definition: egl.cpp:21
unexpected(E) -> unexpected< E >
std::vector< std::string_view > Args
Definition: incremental.h:28
Definition: logging.h:464