10USERVER_NAMESPACE_BEGIN
16class bad_expected_access :
public std::exception {
18 using std::exception::exception;
20 explicit bad_expected_access(
const std::string& message)
24 const char* what()
const noexcept override {
return message_.c_str(); }
33 unexpected(
const E& error);
34 unexpected(E&& error);
36 template <
class... Args>
37 unexpected(Args&&... args);
39 template <
class U,
class... Args>
40 unexpected(std::initializer_list<U> il, Args&&... args);
43 const E& error()
const noexcept;
50unexpected(E) -> unexpected<E>;
55template <
class S,
class E>
56class [[nodiscard]] expected {
59 expected(
const S& success);
60 expected(S&& success);
61 expected(
const unexpected<E>& error);
62 expected(unexpected<E>&& error);
64 template <
class G,
typename = std::enable_if_t<std::is_convertible_v<G, E>>>
65 expected(
const unexpected<G>& error);
67 template <
class G,
typename = std::enable_if_t<std::is_convertible_v<G, E>>>
68 expected(unexpected<G>&& error);
71 bool has_value()
const noexcept;
74 explicit operator
bool()
const noexcept;
85 const S& value()
const&;
93 const E& error()
const;
96 std::variant<S, unexpected<E>> data_;
100class [[nodiscard]] expected<
void, E> {
102 constexpr expected()
noexcept;
103 expected(
const unexpected<E>& error);
104 expected(unexpected<E>&& error);
106 template <
class G,
typename = std::enable_if_t<std::is_convertible_v<G, E>>>
107 expected(
const unexpected<G>& error);
109 template <
class G,
typename = std::enable_if_t<std::is_convertible_v<G, E>>>
110 expected(unexpected<G>&& error);
112 bool has_value()
const noexcept;
113 explicit operator
bool()
const noexcept;
117 const E& error()
const;
120 std::variant<std::monostate, unexpected<E>> data_;
124unexpected<E>::unexpected(
const E& error)
129unexpected<E>::unexpected(E&& error)
130 : value_{std::forward<E>(error)}
134template <
class... Args>
135unexpected<E>::unexpected(Args&&... args)
136 : value_(std::forward<Args>(args)...)
140template <
class U,
class... Args>
141unexpected<E>::unexpected(std::initializer_list<U> il, Args&&... args)
142 : value_(il, std::forward<Args>(args)...)
146E& unexpected<E>::error()
noexcept {
151const E& unexpected<E>::error()
const noexcept {
155template <
class S,
class E>
156constexpr expected<S, E>::expected()
157 : data_(std::in_place_index<0>)
160template <
class S,
class E>
161expected<S, E>::expected(
const S& success)
165template <
class S,
class E>
166expected<S, E>::expected(S&& success)
167 : data_(std::forward<S>(success))
170template <
class S,
class E>
171expected<S, E>::expected(
const unexpected<E>& error)
172 : data_(error.error())
175template <
class S,
class E>
176expected<S, E>::expected(unexpected<E>&& error)
177 : data_(std::forward<unexpected<E>>(error.error()))
180template <
class S,
class E>
181template <
class G,
typename>
182expected<S, E>::expected(
const unexpected<G>& error)
183 : data_(utils::unexpected<E>(std::forward<G>(error.error())))
186template <
class S,
class E>
187template <
class G,
typename>
188expected<S, E>::expected(unexpected<G>&& error)
189 : data_(utils::unexpected<E>(std::forward<G>(error.error())))
192template <
class S,
class E>
193bool expected<S, E>::has_value()
const noexcept {
194 return std::holds_alternative<S>(data_);
197template <
class S,
class E>
198expected<S, E>::operator
bool()
const noexcept {
202template <
class S,
class E>
203S& expected<S, E>::value() & {
204 S* result = std::get_if<S>(&data_);
205 if (result ==
nullptr) {
206 throw bad_expected_access(
"Trying to get undefined value from utils::expected");
211template <
class S,
class E>
212S&& expected<S, E>::value() && {
213 return std::move(value());
216template <
class S,
class E>
217const S& expected<S, E>::value()
const& {
218 const S* result = std::get_if<S>(&data_);
219 if (result ==
nullptr) {
220 throw bad_expected_access(
"Trying to get undefined value from utils::expected");
225template <
class S,
class E>
226E& expected<S, E>::error() {
227 auto* result = std::get_if<unexpected<E>>(&data_);
228 if (result ==
nullptr) {
229 throw bad_expected_access(
"Trying to get undefined error value from utils::expected");
231 return result->error();
234template <
class S,
class E>
235const E& expected<S, E>::error()
const {
236 const auto* result = std::get_if<unexpected<E>>(&data_);
237 if (result ==
nullptr) {
238 throw bad_expected_access(
"Trying to get undefined error value from utils::expected");
240 return result->error();
244constexpr expected<
void, E>::expected()
noexcept: data_(std::in_place_index<0>) {}
247expected<
void, E>::expected(
const unexpected<E>& error)
248 : data_(error.error())
252expected<
void, E>::expected(unexpected<E>&& error)
253 : data_(std::forward<unexpected<E>>(error.error()))
257template <
class G,
typename>
258expected<
void, E>::expected(
const unexpected<G>& error)
259 : data_(utils::unexpected<E>(std::forward<G>(error.error())))
263template <
class G,
typename>
264expected<
void, E>::expected(unexpected<G>&& error)
265 : data_(utils::unexpected<E>(std::forward<G>(error.error())))
269bool expected<
void, E>::has_value()
const noexcept {
270 return data_.index() == 0;
274expected<
void, E>::operator
bool()
const noexcept {
279void expected<
void, E>::value()
const {
281 throw bad_expected_access(
"Trying to get undefined value from utils::expected");
286E& expected<
void, E>::error() {
287 auto* result = std::get_if<unexpected<E>>(&data_);
288 if (result ==
nullptr) {
289 throw bad_expected_access(
"Trying to get undefined error value from utils::expected");
291 return result->error();
295const E& expected<
void, E>::error()
const {
296 const auto* result = std::get_if<unexpected<E>>(&data_);
297 if (result ==
nullptr) {
298 throw bad_expected_access(
"Trying to get undefined error value from utils::expected");
300 return result->error();