20#include <initializer_list>
53template<
class T,
class E>
73#define _ENABLE_IF(...) \
74 , std::enable_if_t<(__VA_ARGS__)>* = nullptr
78#ifdef NODISCARD_EXPECTED
79#define _NODISCARD_ [[nodiscard]]
85template<
class T,
class E>
101 std::is_constructible_v<T, const U&> &&
102 std::is_constructible_v<E, const G&> &&
111 !(!std::is_convertible_v<const U&, T> ||
112 !std::is_convertible_v<const G&, E>)
121 std::is_constructible_v<T, const U&> &&
122 std::is_constructible_v<E, const G&> &&
131 (!std::is_convertible_v<const U&, T> ||
132 !std::is_convertible_v<const G&, E>)
140 std::is_constructible_v<T, const U&> &&
141 std::is_constructible_v<E, const G&> &&
150 !(!std::is_convertible_v<const U&, T> ||
151 !std::is_convertible_v<const G&, E>)
155 if (rhs.has_value()) var_ = std::move(rhs.value());
156 else var_ =
unexpected(std::move(rhs.error()));
160 std::is_constructible_v<T, const U&> &&
161 std::is_constructible_v<E, const G&> &&
170 (!std::is_convertible_v<const U&, T> ||
171 !std::is_convertible_v<const G&, E>)
174 if (rhs.has_value()) var_ = std::move(rhs.value());
175 else var_ =
unexpected(std::move(rhs.error()));
179 std::is_constructible_v<T, U&&> &&
180 !std::is_same_v<std::remove_cv_t<std::remove_reference_t<U>>, std::in_place_t> &&
181 !std::is_same_v<
expected<T, E>, std::remove_cv_t<std::remove_reference_t<U>>> &&
182 !std::is_same_v<
unexpected<E>, std::remove_cv_t<std::remove_reference_t<U>>> &&
183 std::is_convertible_v<U&&, T>
189 std::is_constructible_v<T, U&&> &&
190 !std::is_same_v<std::remove_cv_t<std::remove_reference_t<U>>, std::in_place_t> &&
191 !std::is_same_v<
expected<T, E>, std::remove_cv_t<std::remove_reference_t<U>>> &&
192 !std::is_same_v<
unexpected<E>, std::remove_cv_t<std::remove_reference_t<U>>> &&
193 !std::is_convertible_v<U&&, T>
196 constexpr explicit expected(U&& v) : var_(
std::in_place_index<0>, T(
std::forward<U>(v))) {}
199 std::is_constructible_v<E, const G&> &&
200 std::is_convertible_v<const G&, E>
204 : var_(
std::in_place_index<1>, e.value()) {}
207 std::is_constructible_v<E, const G&> &&
208 !std::is_convertible_v<const G&, E>
211 : var_(
std::in_place_index<1>, E(e.value())) {}
214 std::is_constructible_v<E, G&&> &&
215 std::is_convertible_v<G&&, E>
219 : var_(
std::in_place_index<1>,
std::move(e.value())) {}
222 std::is_constructible_v<E, G&&> &&
223 !std::is_convertible_v<G&&, E>
226 : var_(
std::in_place_index<1>, E(
std::move(e.value()))) {}
229 std::is_constructible_v<T, Args&&...>
232 : var_(
std::in_place_index<0>,
std::forward<
Args>(args)...) {}
235 std::is_constructible_v<T, std::initializer_list<U>&,
Args...>
237 constexpr explicit expected(std::in_place_t, std::initializer_list<U> il,
Args&&... args)
238 : var_(
std::in_place_index<0>, il,
std::forward<
Args>(args)...) {}
241 std::is_constructible_v<E, Args...>
247 std::is_constructible_v<E, std::initializer_list<U>&,
Args...>
266 std::is_nothrow_move_assignable_v<T>&& std::is_nothrow_move_assignable_v<E>) =
default;
269 !std::is_void_v<T> &&
270 !std::is_same_v<
expected<T, E>, std::remove_cv_t<std::remove_reference_t<U>>> &&
271 !std::conjunction_v<std::is_scalar<T>, std::is_same<T, std::decay_t<U>>> &&
272 std::is_constructible_v<T, U> && std::is_assignable_v<T&, U> &&
273 std::is_nothrow_move_constructible_v<E>)>
275 var_ = T(std::forward<U>(rhs));
279 template<
class G = E>
286 std::is_nothrow_move_constructible_v<G> &&
287 std::is_move_assignable_v<G>
290 var_ = std::move(rhs);
296 std::is_nothrow_constructible_v<T, Args...>
299 expected(std::in_place, std::forward<Args>(args)...).
swap(*
this);
304 std::is_nothrow_constructible_v<T, std::initializer_list<U>&,
Args...>
307 expected(std::in_place, il, std::forward<Args>(args)...).
swap(*
this);
312 template<
typename U = T,
typename = std::enable_if_t<(
313 std::is_swappable_v<U> &&
314 std::is_swappable_v<E> &&
315 (std::is_move_constructible_v<U> ||
316 std::is_move_constructible_v<E>))>>
318 std::is_nothrow_move_constructible_v<T> &&
319 std::is_nothrow_swappable_v<T> &&
320 std::is_nothrow_move_constructible_v<E> &&
321 std::is_nothrow_swappable_v<E>) {
326 constexpr const T*
operator->()
const {
return std::addressof(value()); }
327 constexpr T*
operator->() {
return std::addressof(value()); }
328 constexpr const T&
operator*() const& {
return value(); }
330 constexpr const T&&
operator*() const&& {
return std::move(std::get<T>(var_)); }
331 constexpr T&&
operator*() && {
return std::move(std::get<T>(var_)); }
333 constexpr bool has_value() const noexcept {
return var_.index() == 0; }
334 constexpr bool ok() const noexcept {
return has_value(); }
336 constexpr const T&
value() const& {
return std::get<T>(var_); }
337 constexpr T&
value() & {
return std::get<T>(var_); }
338 constexpr const T&&
value() const&& {
return std::move(std::get<T>(var_)); }
339 constexpr T&&
value() && {
return std::move(std::get<T>(var_)); }
341 constexpr const E&
error() const& {
return std::get<unexpected_type>(var_).value(); }
342 constexpr E&
error() & {
return std::get<unexpected_type>(var_).value(); }
343 constexpr const E&&
error() const&& {
return std::move(std::get<unexpected_type>(var_)).value(); }
344 constexpr E&&
error() && {
return std::move(std::get<unexpected_type>(var_)).value(); }
347 std::is_copy_constructible_v<T> &&
348 std::is_convertible_v<U, T>
351 if (has_value())
return value();
352 else return static_cast<T
>(std::forward<U>(v));
356 std::is_move_constructible_v<T> &&
357 std::is_convertible_v<U, T>
360 if (has_value())
return std::move(value());
361 else return static_cast<T
>(std::forward<U>(v));
365 template<
class T1,
class E1,
class T2,
class E2>
367 template<
class T1,
class E1,
class T2,
class E2>
371 template<
class T1,
class E1,
class E2>
373 template<
class T1,
class E1,
class E2>
375 template<
class T1,
class E1,
class E2>
377 template<
class T1,
class E1,
class E2>
381 template<
class T1,
class E1>
385 std::variant<value_type, unexpected_type>
var_;
388template<
class T1,
class E1,
class T2,
class E2>
395template<
class T1,
class E1,
class T2,
class E2>
401template<
class T1,
class E1,
class E2>
405template<
class T1,
class E1,
class E2>
409template<
class T1,
class E1,
class E2>
413template<
class T1,
class E1,
class E2>
418template<
class T1,
class E1>
437 std::is_convertible_v<const G&, E>
446 !std::is_convertible_v<const G&, E>
454 std::is_convertible_v<const G&&, E>
458 if (!rhs.has_value()) var_ =
unexpected(std::move(rhs.error()));
463 !std::is_convertible_v<const G&&, E>
466 if (!rhs.has_value()) var_ =
unexpected(std::move(rhs.error()));
470 std::is_constructible_v<E, const G&> &&
471 std::is_convertible_v<const G&, E>
475 : var_(
std::in_place_index<1>, e.value()) {}
478 std::is_constructible_v<E, const G&> &&
479 !std::is_convertible_v<const G&, E>
482 : var_(
std::in_place_index<1>, E(e.value())) {}
485 std::is_constructible_v<E, G&&> &&
486 std::is_convertible_v<G&&, E>
490 : var_(
std::in_place_index<1>,
std::move(e.value())) {}
493 std::is_constructible_v<E, G&&> &&
494 !std::is_convertible_v<G&&, E>
497 : var_(
std::in_place_index<1>, E(
std::move(e.value()))) {}
505 std::is_constructible_v<E, Args...>
511 std::is_constructible_v<E, std::initializer_list<U>&,
Args...>
531 template<
class G = E>
538 std::is_nothrow_move_constructible_v<G> &&
539 std::is_move_assignable_v<G>
542 var_ = std::move(rhs);
548 var_ = std::monostate();
552 template<
typename = std::enable_if_t<
553 std::is_swappable_v<E>>
555 void swap(
expected& rhs)
noexcept(std::is_nothrow_move_constructible_v<E>) {
560 constexpr bool has_value() const noexcept {
return var_.index() == 0; }
561 constexpr bool ok() const noexcept {
return has_value(); }
563 constexpr void value() const& {
if (!has_value()) std::get<0>(var_); }
565 constexpr const E&
error() const& {
return std::get<unexpected_type>(var_).value(); }
566 constexpr E&
error() & {
return std::get<unexpected_type>(var_).value(); }
567 constexpr const E&&
error() const&& {
return std::move(std::get<unexpected_type>(var_)).value(); }
568 constexpr E&&
error() && {
return std::move(std::get<unexpected_type>(var_)).value(); }
571 template<
class E1,
class E2>
575 template<
class T1,
class E1>
579 std::variant<std::monostate, unexpected_type>
var_;
582template<
class E1,
class E2>
589template<
class T1,
class E1,
class E2>
596template<
class E1,
class T2,
class E2>
611 std::is_constructible_v<E, Err> &&
612 !
std::is_same_v<
std::remove_cv_t<
std::remove_reference_t<E>>,
std::in_place_t> &&
618 std::is_constructible_v<E, std::initializer_list<U>&,
Args...>
620 constexpr explicit unexpected(std::in_place_t, std::initializer_list<U> il,
Args&&... args)
624 std::is_constructible_v<E, Err> &&
633 std::is_convertible_v<Err, E>
640 std::is_constructible_v<E, Err> &&
649 !std::is_convertible_v<Err, E>
655 std::is_constructible_v<E, Err> &&
664 std::is_convertible_v<Err, E>
671 std::is_constructible_v<E, Err> &&
680 !std::is_convertible_v<Err, E>
689 template<class Err = E>
694 template<
class Err = E>
696 val_ = std::forward<E>(rhs.value());
701 constexpr const E&
value() const& noexcept {
return val_; }
703 constexpr const E&&
value() const&& noexcept {
return std::move(
val_); }
704 constexpr E&&
value() &&
noexcept {
return std::move(
val_); }
710 template<
class E1,
class E2>
711 friend constexpr bool
713 template<
class E1,
class E2>
714 friend constexpr bool
724template<
class E1,
class E2>
730template<
class E1,
class E2>
Definition: expected.h:62
expected & operator=(const expected &rhs)=default
constexpr expected(expected< U, G > &&rhs)
Definition: expected.h:457
expected & operator=(const unexpected< G > &rhs)
Definition: expected.h:532
void emplace()
Definition: expected.h:547
constexpr expected(unexpect_t, std::initializer_list< U > il, Args &&... args)
Definition: expected.h:513
constexpr bool has_value() const noexcept
Definition: expected.h:560
constexpr expected(expected &&rhs) noexcept=default
expected & operator=(unexpected< G > &&rhs)
Definition: expected.h:541
std::variant< std::monostate, unexpected_type > var_
Definition: expected.h:579
constexpr const E & error() const &
Definition: expected.h:565
constexpr bool ok() const noexcept
Definition: expected.h:561
constexpr expected(const expected< U, G > &rhs)
Definition: expected.h:440
E error_type
Definition: expected.h:427
constexpr expected(const expected &rhs)=default
constexpr void value() const &
Definition: expected.h:563
constexpr E & error() &
Definition: expected.h:566
constexpr expected(const unexpected< G > &e)
Definition: expected.h:474
constexpr expected(unexpect_t, Args &&... args)
Definition: expected.h:507
expected & operator=(expected &&rhs) noexcept(std::is_nothrow_move_assignable_v< E >)=default
constexpr E && error() &&
Definition: expected.h:568
constexpr expected()=default
void swap(expected &rhs) noexcept(std::is_nothrow_move_constructible_v< E >)
Definition: expected.h:555
constexpr expected(unexpected< G > &&e)
Definition: expected.h:489
constexpr expected(std::in_place_t, Args &&...)
Definition: expected.h:502
constexpr const E && error() const &&
Definition: expected.h:567
void value_type
Definition: expected.h:426
Definition: expected.h:86
constexpr const T && operator*() const &&
Definition: expected.h:330
E error_type
Definition: expected.h:89
constexpr E & error() &
Definition: expected.h:342
expected & operator=(const unexpected< G > &rhs)
Definition: expected.h:280
friend constexpr bool operator==(const expected< T1, E1 > &x, const expected< T2, E2 > &y)
Definition: expected.h:389
constexpr expected(unexpect_t, std::initializer_list< U > il, Args &&... args)
Definition: expected.h:249
friend constexpr bool operator!=(const expected< T1, E1 > &, const unexpected< E2 > &)
Definition: expected.h:410
constexpr expected(std::in_place_t, Args &&... args)
Definition: expected.h:231
constexpr const E & error() const &
Definition: expected.h:341
expected & operator=(expected &&rhs) noexcept(std::is_nothrow_move_assignable_v< T > &&std::is_nothrow_move_assignable_v< E >)=default
constexpr T value_or(U &&v) &&
Definition: expected.h:359
constexpr T && operator*() &&
Definition: expected.h:331
constexpr expected(const unexpected< G > &e)
Definition: expected.h:203
constexpr const T & operator*() const &
Definition: expected.h:328
constexpr T && value() &&
Definition: expected.h:339
constexpr const E && error() const &&
Definition: expected.h:343
friend constexpr bool operator==(const unexpected< E2 > &, const expected< T1, E1 > &)
Definition: expected.h:406
T & emplace(std::initializer_list< U > il, Args &&... args)
Definition: expected.h:306
friend constexpr bool operator!=(const expected< T1, E1 > &x, const expected< T2, E2 > &y)
Definition: expected.h:396
constexpr bool has_value() const noexcept
Definition: expected.h:333
constexpr expected()=default
T & emplace(Args &&... args)
Definition: expected.h:298
friend void swap(expected< T1, E1 > &x, expected< T1, E1 > &y) noexcept(noexcept(x.swap(y)))
Definition: expected.h:419
friend constexpr bool operator==(const expected< T1, E1 > &, const unexpected< E2 > &)
Definition: expected.h:402
friend constexpr bool operator!=(const unexpected< E2 > &, const expected< T1, E1 > &)
Definition: expected.h:414
constexpr expected(std::in_place_t, std::initializer_list< U > il, Args &&... args)
Definition: expected.h:237
constexpr expected(const expected &rhs)=default
expected & operator=(U &&rhs)
Definition: expected.h:274
constexpr const T && value() const &&
Definition: expected.h:338
constexpr const T & value() const &
Definition: expected.h:336
std::variant< value_type, unexpected_type > var_
Definition: expected.h:385
constexpr expected(expected &&rhs) noexcept=default
constexpr T & operator*() &
Definition: expected.h:329
constexpr bool ok() const noexcept
Definition: expected.h:334
constexpr expected(const expected< U, G > &rhs)
Definition: expected.h:115
constexpr T * operator->()
Definition: expected.h:327
constexpr T & value() &
Definition: expected.h:337
expected & operator=(unexpected< G > &&rhs)
Definition: expected.h:289
constexpr expected(unexpected< G > &&e)
Definition: expected.h:218
constexpr expected(expected< U, G > &&rhs)
Definition: expected.h:154
constexpr const T * operator->() const
Definition: expected.h:326
expected & operator=(const expected &rhs)=default
T value_type
Definition: expected.h:88
void swap(expected &rhs) noexcept(std::is_nothrow_move_constructible_v< T > &&std::is_nothrow_swappable_v< T > &&std::is_nothrow_move_constructible_v< E > &&std::is_nothrow_swappable_v< E >)
Definition: expected.h:317
constexpr E && error() &&
Definition: expected.h:344
constexpr expected(unexpect_t, Args &&... args)
Definition: expected.h:243
constexpr T value_or(U &&v) const &
Definition: expected.h:350
constexpr expected(U &&v)
Definition: expected.h:186
Definition: expected.h:604
constexpr unexpected(unexpected< Err > &&rhs)
Definition: expected.h:667
constexpr const E && value() const &&noexcept
Definition: expected.h:703
constexpr const E & value() const &noexcept
Definition: expected.h:701
constexpr unexpected(const unexpected< Err > &rhs)
Definition: expected.h:636
void swap(unexpected &other) noexcept(std::is_nothrow_swappable_v< E >)
Definition: expected.h:706
constexpr unexpected & operator=(unexpected< Err > &&rhs)
Definition: expected.h:695
E val_
Definition: expected.h:721
friend constexpr bool operator!=(const unexpected< E1 > &e1, const unexpected< E2 > &e2)
Definition: expected.h:732
constexpr E && value() &&noexcept
Definition: expected.h:704
constexpr unexpected(std::in_place_t, std::initializer_list< U > il, Args &&... args)
Definition: expected.h:620
constexpr unexpected(const unexpected &)=default
constexpr unexpected & operator=(unexpected &&) noexcept(std::is_nothrow_move_assignable_v< E >)=default
constexpr unexpected & operator=(const unexpected &)=default
friend constexpr bool operator==(const unexpected< E1 > &e1, const unexpected< E2 > &e2)
Definition: expected.h:726
constexpr E & value() &noexcept
Definition: expected.h:702
constexpr unexpected(unexpected &&) noexcept(std::is_nothrow_move_constructible_v< E >)=default
#define _ENABLE_IF(...)
Definition: expected.h:73
#define _NODISCARD_
Definition: expected.h:81
void swap(unexpected< E1 > &x, unexpected< E1 > &y) noexcept(noexcept(x.swap(y)))
Definition: expected.h:737
constexpr unexpect_t unexpect
Definition: expected.h:70
void swap(expected< T1, E1 > &x, expected< T1, E1 > &y) noexcept(noexcept(x.swap(y)))
Definition: expected.h:419
constexpr bool operator==(const expected< T1, E1 > &x, const expected< T2, E2 > &y)
Definition: expected.h:389
constexpr bool operator!=(const expected< T1, E1 > &x, const expected< T2, E2 > &y)
Definition: expected.h:396
unexpected(E) -> unexpected< E >
std::vector< std::string_view > Args
Definition: incremental.h:28
Definition: logging.h:464
Definition: expected.h:67