tetl 0.1.0
Embedded Template Library
Loading...
Searching...
No Matches
expected.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: BSL-1.0
2
3#ifndef TETL_EXPECTED_EXPECTED_HPP
4#define TETL_EXPECTED_EXPECTED_HPP
5
20#include <etl/_utility/move.hpp>
22
23namespace etl {
24
26template <typename T, typename E>
27struct expected {
28 using value_type = T;
29 using error_type = E;
31
32 template <typename U>
34
35 constexpr explicit expected() noexcept(is_nothrow_default_constructible_v<T>)
37 : _u()
38 {
39 }
40
41 template <typename... Args>
42 requires is_constructible_v<T, Args...>
43 constexpr explicit expected(in_place_t /*tag*/, Args&&... args) noexcept(is_nothrow_constructible_v<T, Args...>)
44 : _u(in_place_index<0>, etl::forward<Args>(args)...)
45 {
46 }
47
48 template <typename... Args>
49 requires is_constructible_v<E, Args...>
50 constexpr explicit expected(unexpect_t /*tag*/, Args&&... args) noexcept(is_nothrow_constructible_v<E, Args...>)
51 : _u(in_place_index<1>, etl::forward<Args>(args)...)
52 {
53 }
54
55 [[nodiscard]] constexpr explicit operator bool() const noexcept { return has_value(); }
56
57 [[nodiscard]] constexpr auto has_value() const noexcept -> bool { return _u.index() == 0; }
58
59 [[nodiscard]] constexpr auto operator->() const noexcept -> T const* { return etl::get_if<0>(&_u); }
60
61 [[nodiscard]] constexpr auto operator->() noexcept -> T* { return etl::get_if<0>(&_u); }
62
63 [[nodiscard]] constexpr auto operator*() const& noexcept -> T const&
64 {
66 return _u[index_v<0>];
67 }
68
69 [[nodiscard]] constexpr auto operator*() & noexcept -> T&
70 {
72 return _u[index_v<0>];
73 }
74
75 [[nodiscard]] constexpr auto operator*() const&& noexcept -> T const&&
76 {
78 return etl::move(_u[index_v<0>]);
79 }
80
81 [[nodiscard]] constexpr auto operator*() && noexcept -> T&&
82 {
84 return etl::move(_u[index_v<0>]);
85 }
86
87 [[nodiscard]] constexpr auto error() & -> E&
88 {
90 return _u[index_v<1>];
91 }
92
93 [[nodiscard]] constexpr auto error() const& -> E const&
94 {
96 return _u[index_v<1>];
97 }
98
99 [[nodiscard]] constexpr auto error() && -> E&&
100 {
102 return etl::move(_u[index_v<1>]);
103 }
104
105 [[nodiscard]] constexpr auto error() const&& -> E const&&
106 {
108 return etl::move(_u[index_v<1>]);
109 }
110
111 template <typename... Args>
112 requires is_nothrow_constructible_v<T, Args...>
113 constexpr auto emplace(Args&&... args) noexcept -> T&
114 {
115 _u.template emplace<0>(etl::forward<Args>(args)...);
116 return **this;
117 }
118
119 template <typename U>
120 [[nodiscard]] constexpr auto value_or(U&& fallback) const& -> T
121 {
122 return static_cast<bool>(*this) ? **this : static_cast<T>(etl::forward<U>(fallback));
123 }
124
125 template <typename U>
126 [[nodiscard]] constexpr auto value_or(U&& fallback) && -> T
127 {
128 return static_cast<bool>(*this) ? etl::move(**this) : static_cast<T>(etl::forward<U>(fallback));
129 }
130
131 template <typename F>
132 [[nodiscard]] constexpr auto and_then(F&& f) & requires(is_constructible_v<E, decltype(error())>)
133 {
134 if (has_value()) { return etl::invoke(etl::forward<F>(f), **this); }
135 using U = remove_cvref_t<invoke_result_t<F, decltype(**this)>>;
136 return U(unexpect, error());
137 }
138
139 template <typename F>
140 [[nodiscard]] constexpr auto and_then(F&& f) && requires(is_constructible_v<E, decltype(error())>)
141 {
142 if (has_value()) { return etl::invoke(etl::forward<F>(f), **this); }
143 using U = remove_cvref_t<invoke_result_t<F, decltype(**this)>>;
144 return U(unexpect, error());
145 }
146
147 template <typename F>
148 [[nodiscard]] constexpr auto and_then(F&& f) const&
149 requires(is_constructible_v<E, decltype(etl::move(error()))>)
150 {
151 if (has_value()) {
152 return etl::invoke(etl::forward<F>(f), etl::move(**this));
153 }
154 using U = remove_cvref_t<invoke_result_t<F, decltype(etl::move(**this))>>;
155 return U(unexpect, etl::move(error()));
156 }
157
158 template <typename F>
159 [[nodiscard]] constexpr auto and_then(F&& f) const&&
160 requires(is_constructible_v<E, decltype(etl::move(error()))>)
161 {
162 if (has_value()) {
163 return etl::invoke(etl::forward<F>(f), etl::move(**this));
164 }
165 using U = remove_cvref_t<invoke_result_t<F, decltype(etl::move(**this))>>;
166 return U(unexpect, etl::move(error()));
167 }
168
169 template <typename F>
170 [[nodiscard]] constexpr auto or_else(F&& f) & requires(is_constructible_v<T, decltype(**this)>)
171 {
172 using G = remove_cvref_t<invoke_result_t<F, decltype(error())>>;
173 if (has_value()) { return G(etl::in_place, **this); }
174 return etl::invoke(etl::forward<F>(f), error());
175 }
176
177 template <typename F>
178 [[nodiscard]] constexpr auto or_else(F&& f) && requires(is_constructible_v<T, decltype(**this)>)
179 {
180 using G = remove_cvref_t<invoke_result_t<F, decltype(error())>>;
181 if (has_value()) { return G(etl::in_place, **this); }
182 return etl::invoke(etl::forward<F>(f), error());
183 }
184
185 template <typename F>
186 [[nodiscard]] constexpr auto or_else(F&& f) const&
187 requires(is_constructible_v<T, decltype(etl::move(**this))>)
188 {
189 using G = remove_cvref_t<invoke_result_t<F, decltype(etl::move(error()))>>;
190 if (has_value()) {
191 return G(etl::in_place, etl::move(**this));
192 }
194 }
195
196 template <typename F>
197 [[nodiscard]] constexpr auto or_else(F&& f) const&&
198 requires(is_constructible_v<T, decltype(etl::move(**this))>)
199 {
200 using G = remove_cvref_t<invoke_result_t<F, decltype(etl::move(error()))>>;
201 if (has_value()) {
202 return G(etl::in_place, etl::move(**this));
203 }
205 }
206
207private:
209};
210
211} // namespace etl
212
213#endif // TETL_EXPECTED_EXPECTED_HPP
#define TETL_PRECONDITION(...)
Definition check.hpp:16
constexpr auto move(InputIt first, InputIt last, OutputIt destination) -> OutputIt
Moves the elements in the range [first, last), to another range beginning at destination,...
Definition move.hpp:26
Definition adjacent_find.hpp:8
constexpr bool is_constructible_v
Definition is_constructible.hpp:24
remove_cv_t< remove_reference_t< T > > remove_cvref_t
Definition remove_cvref.hpp:23
constexpr bool is_nothrow_default_constructible_v
Definition is_nothrow_default_constructible.hpp:26
constexpr auto index_v
Definition index_constant.hpp:15
constexpr bool is_default_constructible_v
Definition is_default_constructible.hpp:26
constexpr auto invoke(F &&f, Args &&... args) -> invoke_result_t< F, Args... >
Definition invoke.hpp:45
constexpr bool is_nothrow_constructible_v
Definition is_nothrow_constructible.hpp:50
constexpr auto get_if(variant< Types... > *pv) noexcept -> add_pointer_t< T >
constexpr auto forward(remove_reference_t< T > &param) noexcept -> T &&
Forwards lvalues as either lvalues or as rvalues, depending on T. When t is a forwarding reference (a...
Definition forward.hpp:18
Definition expected.hpp:27
constexpr auto operator*() &noexcept -> T &
Definition expected.hpp:69
constexpr auto and_then(F &&f) &
Definition expected.hpp:132
constexpr auto or_else(F &&f) const &&
Definition expected.hpp:197
constexpr expected() noexcept(is_nothrow_default_constructible_v< T >)
Definition expected.hpp:35
etl::unexpected< E > unexpected_type
Definition expected.hpp:30
constexpr auto emplace(Args &&... args) noexcept -> T &
Definition expected.hpp:113
E error_type
Definition expected.hpp:29
constexpr auto operator->() const noexcept -> T const *
Definition expected.hpp:59
constexpr auto error() &&-> E &&
Definition expected.hpp:99
constexpr auto operator*() &&noexcept -> T &&
Definition expected.hpp:81
constexpr auto error() &-> E &
Definition expected.hpp:87
constexpr auto and_then(F &&f) &&
Definition expected.hpp:140
constexpr expected(unexpect_t, Args &&... args) noexcept(is_nothrow_constructible_v< E, Args... >)
Definition expected.hpp:50
constexpr auto and_then(F &&f) const &
Definition expected.hpp:148
constexpr auto or_else(F &&f) &&
Definition expected.hpp:178
constexpr auto value_or(U &&fallback) &&-> T
Definition expected.hpp:126
constexpr expected(in_place_t, Args &&... args) noexcept(is_nothrow_constructible_v< T, Args... >)
Definition expected.hpp:43
constexpr auto error() const &&-> E const &&
Definition expected.hpp:105
constexpr auto or_else(F &&f) const &
Definition expected.hpp:186
constexpr auto operator->() noexcept -> T *
Definition expected.hpp:61
constexpr auto error() const &-> E const &
Definition expected.hpp:93
constexpr auto operator*() const &noexcept -> T const &
Definition expected.hpp:63
constexpr auto operator*() const &&noexcept -> T const &&
Definition expected.hpp:75
constexpr auto has_value() const noexcept -> bool
Definition expected.hpp:57
constexpr auto or_else(F &&f) &
Definition expected.hpp:170
constexpr auto and_then(F &&f) const &&
Definition expected.hpp:159
etl::expected< U, error_type > rebind
Definition expected.hpp:33
T value_type
Definition expected.hpp:28
constexpr auto value_or(U &&fallback) const &-> T
Definition expected.hpp:120
Disambiguation tags that can be passed to the constructors of optional, variant, and any to indicate ...
Definition in_place.hpp:20
Definition unexpect.hpp:9
Definition unexpected.hpp:20
Definition variant.hpp:98