tmp/tmpyfpmqy5s/{from.md → to.md}
RENAMED
|
@@ -21,11 +21,11 @@ namespace std {
|
|
| 21 |
template<class U, class G>
|
| 22 |
constexpr explicit(see below) expected(const expected<U, G>&);
|
| 23 |
template<class U, class G>
|
| 24 |
constexpr explicit(see below) expected(expected<U, G>&&);
|
| 25 |
|
| 26 |
-
template<class U = T>
|
| 27 |
constexpr explicit(see below) expected(U&& v);
|
| 28 |
|
| 29 |
template<class G>
|
| 30 |
constexpr explicit(see below) expected(const unexpected<G>&);
|
| 31 |
template<class G>
|
|
@@ -44,11 +44,11 @@ namespace std {
|
|
| 44 |
constexpr ~expected();
|
| 45 |
|
| 46 |
// [expected.object.assign], assignment
|
| 47 |
constexpr expected& operator=(const expected&);
|
| 48 |
constexpr expected& operator=(expected&&) noexcept(see below);
|
| 49 |
-
template<class U = T> constexpr expected& operator=(U&&);
|
| 50 |
template<class G>
|
| 51 |
constexpr expected& operator=(const unexpected<G>&);
|
| 52 |
template<class G>
|
| 53 |
constexpr expected& operator=(unexpected<G>&&);
|
| 54 |
|
|
@@ -68,20 +68,20 @@ namespace std {
|
|
| 68 |
constexpr T& operator*() & noexcept;
|
| 69 |
constexpr const T&& operator*() const && noexcept;
|
| 70 |
constexpr T&& operator*() && noexcept;
|
| 71 |
constexpr explicit operator bool() const noexcept;
|
| 72 |
constexpr bool has_value() const noexcept;
|
| 73 |
-
constexpr const T& value() const &;
|
| 74 |
-
constexpr T& value() &;
|
| 75 |
-
constexpr const T&& value() const &&;
|
| 76 |
-
constexpr T&& value() &&;
|
| 77 |
constexpr const E& error() const & noexcept;
|
| 78 |
constexpr E& error() & noexcept;
|
| 79 |
constexpr const E&& error() const && noexcept;
|
| 80 |
constexpr E&& error() && noexcept;
|
| 81 |
-
template<class U> constexpr T value_or(U&&) const &;
|
| 82 |
-
template<class U> constexpr T value_or(U&&) &&;
|
| 83 |
template<class G = E> constexpr E error_or(G&&) const &;
|
| 84 |
template<class G = E> constexpr E error_or(G&&) &&;
|
| 85 |
|
| 86 |
// [expected.object.monadic], monadic operations
|
| 87 |
template<class F> constexpr auto and_then(F&& f) &;
|
|
@@ -118,15 +118,13 @@ namespace std {
|
|
| 118 |
};
|
| 119 |
}
|
| 120 |
```
|
| 121 |
|
| 122 |
Any object of type `expected<T, E>` either contains a value of type `T`
|
| 123 |
-
or a value of type `E` within
|
| 124 |
-
|
| 125 |
-
|
| 126 |
-
indicates whether the `expected<T, E>` object contains an object of type
|
| 127 |
-
`T`.
|
| 128 |
|
| 129 |
A type `T` is a *valid value type for `expected`*, if `remove_cv_t<T>`
|
| 130 |
is `void` or a complete non-array object type that is not `in_place_t`,
|
| 131 |
`unexpect_t`, or a specialization of `unexpected`. A program which
|
| 132 |
instantiates class template `expected<T, E>` with an argument `T` that
|
|
@@ -242,18 +240,19 @@ with `std::forward<GF>(rhs.error())`.
|
|
| 242 |
|
| 243 |
*Remarks:* The expression inside `explicit` is equivalent to
|
| 244 |
`!is_convertible_v<UF, T> || !is_convertible_v<GF, E>`.
|
| 245 |
|
| 246 |
``` cpp
|
| 247 |
-
template<class U = T>
|
| 248 |
constexpr explicit(!is_convertible_v<U, T>) expected(U&& v);
|
| 249 |
```
|
| 250 |
|
| 251 |
*Constraints:*
|
| 252 |
|
| 253 |
- `is_same_v<remove_cvref_t<U>, in_place_t>` is `false`; and
|
| 254 |
-
- `is_same_v<
|
|
|
|
| 255 |
- `remove_cvref_t<U>` is not a specialization of `unexpected`; and
|
| 256 |
- `is_constructible_v<T, U>` is `true`; and
|
| 257 |
- if `T` is cv `bool`, `remove_cvref_t<U>` is not a specialization of
|
| 258 |
`expected`.
|
| 259 |
|
|
@@ -353,11 +352,12 @@ destroys *unex*.
|
|
| 353 |
`is_trivially_destructible_v<E>` is `true`, then this destructor is a
|
| 354 |
trivial destructor.
|
| 355 |
|
| 356 |
#### Assignment <a id="expected.object.assign">[[expected.object.assign]]</a>
|
| 357 |
|
| 358 |
-
This subclause makes use of the following exposition-only function
|
|
|
|
| 359 |
|
| 360 |
``` cpp
|
| 361 |
template<class T, class U, class... Args>
|
| 362 |
constexpr void reinit-expected(T& newval, U& oldval, Args&&... args) { // exposition only
|
| 363 |
if constexpr (is_nothrow_constructible_v<T, Args...>) {
|
|
@@ -450,11 +450,11 @@ Then, if no exception was thrown, equivalent to:
|
|
| 450 |
is_nothrow_move_assignable_v<T> && is_nothrow_move_constructible_v<T> &&
|
| 451 |
is_nothrow_move_assignable_v<E> && is_nothrow_move_constructible_v<E>
|
| 452 |
```
|
| 453 |
|
| 454 |
``` cpp
|
| 455 |
-
template<class U = T>
|
| 456 |
constexpr expected& operator=(U&& v);
|
| 457 |
```
|
| 458 |
|
| 459 |
*Constraints:*
|
| 460 |
|
|
@@ -566,12 +566,12 @@ constexpr void swap(expected& rhs) noexcept(see below);
|
|
| 566 |
|
| 567 |
| \topline | `this->has_value()` | `!this->has_value()` |
|
| 568 |
| -------- | ------------------- | -------------------- |
|
| 569 |
|
| 570 |
|
| 571 |
-
For the case where `rhs.
|
| 572 |
-
`true`, equivalent to:
|
| 573 |
|
| 574 |
``` cpp
|
| 575 |
if constexpr (is_nothrow_move_constructible_v<E>) {
|
| 576 |
E tmp(std::move(rhs.unex));
|
| 577 |
destroy_at(addressof(rhs.unex));
|
|
@@ -619,29 +619,29 @@ friend constexpr void swap(expected& x, expected& y) noexcept(noexcept(x.swap(y)
|
|
| 619 |
``` cpp
|
| 620 |
constexpr const T* operator->() const noexcept;
|
| 621 |
constexpr T* operator->() noexcept;
|
| 622 |
```
|
| 623 |
|
| 624 |
-
|
| 625 |
|
| 626 |
*Returns:* `addressof(`*`val`*`)`.
|
| 627 |
|
| 628 |
``` cpp
|
| 629 |
constexpr const T& operator*() const & noexcept;
|
| 630 |
constexpr T& operator*() & noexcept;
|
| 631 |
```
|
| 632 |
|
| 633 |
-
|
| 634 |
|
| 635 |
*Returns:* *val*.
|
| 636 |
|
| 637 |
``` cpp
|
| 638 |
constexpr T&& operator*() && noexcept;
|
| 639 |
constexpr const T&& operator*() const && noexcept;
|
| 640 |
```
|
| 641 |
|
| 642 |
-
|
| 643 |
|
| 644 |
*Returns:* `std::move(`*`val`*`)`.
|
| 645 |
|
| 646 |
``` cpp
|
| 647 |
constexpr explicit operator bool() const noexcept;
|
|
@@ -678,34 +678,34 @@ constexpr const T&& value() const &&;
|
|
| 678 |
``` cpp
|
| 679 |
constexpr const E& error() const & noexcept;
|
| 680 |
constexpr E& error() & noexcept;
|
| 681 |
```
|
| 682 |
|
| 683 |
-
|
| 684 |
|
| 685 |
*Returns:* *unex*.
|
| 686 |
|
| 687 |
``` cpp
|
| 688 |
constexpr E&& error() && noexcept;
|
| 689 |
constexpr const E&& error() const && noexcept;
|
| 690 |
```
|
| 691 |
|
| 692 |
-
|
| 693 |
|
| 694 |
*Returns:* `std::move(`*`unex`*`)`.
|
| 695 |
|
| 696 |
``` cpp
|
| 697 |
-
template<class U> constexpr T value_or(U&& v) const &;
|
| 698 |
```
|
| 699 |
|
| 700 |
*Mandates:* `is_copy_constructible_v<T>` is `true` and
|
| 701 |
`is_convertible_v<U, T>` is `true`.
|
| 702 |
|
| 703 |
*Returns:* `has_value() ? **this : static_cast<T>(std::forward<U>(v))`.
|
| 704 |
|
| 705 |
``` cpp
|
| 706 |
-
template<class U> constexpr T value_or(U&& v) &&;
|
| 707 |
```
|
| 708 |
|
| 709 |
*Mandates:* `is_move_constructible_v<T>` is `true` and
|
| 710 |
`is_convertible_v<U, T>` is `true`.
|
| 711 |
|
|
@@ -737,45 +737,45 @@ template<class G = E> constexpr E error_or(G&& e) &&;
|
|
| 737 |
``` cpp
|
| 738 |
template<class F> constexpr auto and_then(F&& f) &;
|
| 739 |
template<class F> constexpr auto and_then(F&& f) const &;
|
| 740 |
```
|
| 741 |
|
| 742 |
-
Let `U` be `remove_cvref_t<invoke_result_t<F, decltype(
|
| 743 |
|
| 744 |
*Constraints:* `is_constructible_v<E, decltype(error())>` is `true`.
|
| 745 |
|
| 746 |
*Mandates:* `U` is a specialization of `expected` and
|
| 747 |
-
`is_same_v<U::error_type, E>` is `true`.
|
| 748 |
|
| 749 |
*Effects:* Equivalent to:
|
| 750 |
|
| 751 |
``` cpp
|
| 752 |
if (has_value())
|
| 753 |
-
return invoke(std::forward<F>(f),
|
| 754 |
else
|
| 755 |
return U(unexpect, error());
|
| 756 |
```
|
| 757 |
|
| 758 |
``` cpp
|
| 759 |
template<class F> constexpr auto and_then(F&& f) &&;
|
| 760 |
template<class F> constexpr auto and_then(F&& f) const &&;
|
| 761 |
```
|
| 762 |
|
| 763 |
Let `U` be
|
| 764 |
-
`remove_cvref_t<invoke_result_t<F, decltype(std::move(
|
| 765 |
|
| 766 |
*Constraints:* `is_constructible_v<E, decltype(std::move(error()))>` is
|
| 767 |
`true`.
|
| 768 |
|
| 769 |
*Mandates:* `U` is a specialization of `expected` and
|
| 770 |
-
`is_same_v<U::error_type, E>` is `true`.
|
| 771 |
|
| 772 |
*Effects:* Equivalent to:
|
| 773 |
|
| 774 |
``` cpp
|
| 775 |
if (has_value())
|
| 776 |
-
return invoke(std::forward<F>(f), std::move(
|
| 777 |
else
|
| 778 |
return U(unexpect, std::move(error()));
|
| 779 |
```
|
| 780 |
|
| 781 |
``` cpp
|
|
@@ -783,20 +783,20 @@ template<class F> constexpr auto or_else(F&& f) &;
|
|
| 783 |
template<class F> constexpr auto or_else(F&& f) const &;
|
| 784 |
```
|
| 785 |
|
| 786 |
Let `G` be `remove_cvref_t<invoke_result_t<F, decltype(error())>>`.
|
| 787 |
|
| 788 |
-
*Constraints:* `is_constructible_v<T, decltype(
|
| 789 |
|
| 790 |
*Mandates:* `G` is a specialization of `expected` and
|
| 791 |
-
`is_same_v<G::value_type, T>` is `true`.
|
| 792 |
|
| 793 |
*Effects:* Equivalent to:
|
| 794 |
|
| 795 |
``` cpp
|
| 796 |
if (has_value())
|
| 797 |
-
return G(in_place,
|
| 798 |
else
|
| 799 |
return invoke(std::forward<F>(f), error());
|
| 800 |
```
|
| 801 |
|
| 802 |
``` cpp
|
|
@@ -805,39 +805,39 @@ template<class F> constexpr auto or_else(F&& f) const &&;
|
|
| 805 |
```
|
| 806 |
|
| 807 |
Let `G` be
|
| 808 |
`remove_cvref_t<invoke_result_t<F, decltype(std::move(error()))>>`.
|
| 809 |
|
| 810 |
-
*Constraints:* `is_constructible_v<T, decltype(std::move(
|
| 811 |
-
`true`.
|
| 812 |
|
| 813 |
*Mandates:* `G` is a specialization of `expected` and
|
| 814 |
-
`is_same_v<G::value_type, T>` is `true`.
|
| 815 |
|
| 816 |
*Effects:* Equivalent to:
|
| 817 |
|
| 818 |
``` cpp
|
| 819 |
if (has_value())
|
| 820 |
-
return G(in_place, std::move(
|
| 821 |
else
|
| 822 |
return invoke(std::forward<F>(f), std::move(error()));
|
| 823 |
```
|
| 824 |
|
| 825 |
``` cpp
|
| 826 |
template<class F> constexpr auto transform(F&& f) &;
|
| 827 |
template<class F> constexpr auto transform(F&& f) const &;
|
| 828 |
```
|
| 829 |
|
| 830 |
-
Let `U` be `remove_cv_t<invoke_result_t<F, decltype(
|
| 831 |
|
| 832 |
*Constraints:* `is_constructible_v<E, decltype(error())>` is `true`.
|
| 833 |
|
| 834 |
*Mandates:* `U` is a valid value type for `expected`. If `is_void_v<U>`
|
| 835 |
is `false`, the declaration
|
| 836 |
|
| 837 |
``` cpp
|
| 838 |
-
U u(invoke(std::forward<F>(f),
|
| 839 |
```
|
| 840 |
|
| 841 |
is well-formed.
|
| 842 |
|
| 843 |
*Effects:*
|
|
@@ -845,53 +845,54 @@ is well-formed.
|
|
| 845 |
- If `has_value()` is `false`, returns
|
| 846 |
`expected<U, E>(unexpect, error())`.
|
| 847 |
- Otherwise, if `is_void_v<U>` is `false`, returns an `expected<U, E>`
|
| 848 |
object whose *has_val* member is `true` and *val* member is
|
| 849 |
direct-non-list-initialized with
|
| 850 |
-
`invoke(std::forward<F>(f),
|
| 851 |
-
- Otherwise, evaluates `invoke(std::forward<F>(f),
|
| 852 |
returns `expected<U, E>()`.
|
| 853 |
|
| 854 |
``` cpp
|
| 855 |
template<class F> constexpr auto transform(F&& f) &&;
|
| 856 |
template<class F> constexpr auto transform(F&& f) const &&;
|
| 857 |
```
|
| 858 |
|
| 859 |
Let `U` be
|
| 860 |
-
`remove_cv_t<invoke_result_t<F, decltype(std::move(
|
| 861 |
|
| 862 |
*Constraints:* `is_constructible_v<E, decltype(std::move(error()))>` is
|
| 863 |
`true`.
|
| 864 |
|
| 865 |
*Mandates:* `U` is a valid value type for `expected`. If `is_void_v<U>`
|
| 866 |
is `false`, the declaration
|
| 867 |
|
| 868 |
``` cpp
|
| 869 |
-
U u(invoke(std::forward<F>(f), std::move(
|
| 870 |
```
|
| 871 |
|
| 872 |
-
is well-formed
|
| 873 |
|
| 874 |
*Effects:*
|
| 875 |
|
| 876 |
- If `has_value()` is `false`, returns
|
| 877 |
`expected<U, E>(unexpect, std::move(error()))`.
|
| 878 |
- Otherwise, if `is_void_v<U>` is `false`, returns an `expected<U, E>`
|
| 879 |
object whose *has_val* member is `true` and *val* member is
|
| 880 |
direct-non-list-initialized with
|
| 881 |
-
`invoke(std::forward<F>(f), std::move(
|
| 882 |
-
- Otherwise, evaluates
|
| 883 |
-
|
|
|
|
| 884 |
|
| 885 |
``` cpp
|
| 886 |
template<class F> constexpr auto transform_error(F&& f) &;
|
| 887 |
template<class F> constexpr auto transform_error(F&& f) const &;
|
| 888 |
```
|
| 889 |
|
| 890 |
Let `G` be `remove_cv_t<invoke_result_t<F, decltype(error())>>`.
|
| 891 |
|
| 892 |
-
*Constraints:* `is_constructible_v<T, decltype(
|
| 893 |
|
| 894 |
*Mandates:* `G` is a valid template argument for `unexpected`
|
| 895 |
[[expected.un.general]] and the declaration
|
| 896 |
|
| 897 |
``` cpp
|
|
@@ -899,11 +900,11 @@ G g(invoke(std::forward<F>(f), error()));
|
|
| 899 |
```
|
| 900 |
|
| 901 |
is well-formed.
|
| 902 |
|
| 903 |
*Returns:* If `has_value()` is `true`,
|
| 904 |
-
`expected<T, G>(in_place,
|
| 905 |
object whose *has_val* member is `false` and *unex* member is
|
| 906 |
direct-non-list-initialized with `invoke(std::forward<F>(f), error())`.
|
| 907 |
|
| 908 |
``` cpp
|
| 909 |
template<class F> constexpr auto transform_error(F&& f) &&;
|
|
@@ -911,12 +912,12 @@ template<class F> constexpr auto transform_error(F&& f) const &&;
|
|
| 911 |
```
|
| 912 |
|
| 913 |
Let `G` be
|
| 914 |
`remove_cv_t<invoke_result_t<F, decltype(std::move(error()))>>`.
|
| 915 |
|
| 916 |
-
*Constraints:* `is_constructible_v<T, decltype(std::move(
|
| 917 |
-
`true`.
|
| 918 |
|
| 919 |
*Mandates:* `G` is a valid template argument for `unexpected`
|
| 920 |
[[expected.un.general]] and the declaration
|
| 921 |
|
| 922 |
``` cpp
|
|
@@ -924,11 +925,11 @@ G g(invoke(std::forward<F>(f), std::move(error())));
|
|
| 924 |
```
|
| 925 |
|
| 926 |
is well-formed.
|
| 927 |
|
| 928 |
*Returns:* If `has_value()` is `true`,
|
| 929 |
-
`expected<T, G>(in_place, std::move(
|
| 930 |
`expected<T, G>` object whose *has_val* member is `false` and *unex*
|
| 931 |
member is direct-non-list-initialized with
|
| 932 |
`invoke(std::forward<F>(f), std::move(error()))`.
|
| 933 |
|
| 934 |
#### Equality operators <a id="expected.object.eq">[[expected.object.eq]]</a>
|
|
@@ -936,33 +937,34 @@ member is direct-non-list-initialized with
|
|
| 936 |
``` cpp
|
| 937 |
template<class T2, class E2> requires (!is_void_v<T2>)
|
| 938 |
friend constexpr bool operator==(const expected& x, const expected<T2, E2>& y);
|
| 939 |
```
|
| 940 |
|
| 941 |
-
*
|
| 942 |
-
well-formed and their results are convertible to `bool`.
|
| 943 |
|
| 944 |
*Returns:* If `x.has_value()` does not equal `y.has_value()`, `false`;
|
| 945 |
otherwise if `x.has_value()` is `true`, `*x == *y`; otherwise
|
| 946 |
`x.error() == y.error()`.
|
| 947 |
|
| 948 |
``` cpp
|
| 949 |
template<class T2> friend constexpr bool operator==(const expected& x, const T2& v);
|
| 950 |
```
|
| 951 |
|
| 952 |
-
*
|
| 953 |
-
|
|
|
|
| 954 |
|
| 955 |
[*Note 1*: `T` need not be *Cpp17EqualityComparable*. — *end note*]
|
| 956 |
|
| 957 |
*Returns:* `x.has_value() && static_cast<bool>(*x == v)`.
|
| 958 |
|
| 959 |
``` cpp
|
| 960 |
template<class E2> friend constexpr bool operator==(const expected& x, const unexpected<E2>& e);
|
| 961 |
```
|
| 962 |
|
| 963 |
-
*
|
| 964 |
-
its result is convertible to `bool`.
|
| 965 |
|
| 966 |
*Returns:*
|
| 967 |
`!x.has_value() && static_cast<bool>(x.error() == e.error())`.
|
| 968 |
|
|
|
|
| 21 |
template<class U, class G>
|
| 22 |
constexpr explicit(see below) expected(const expected<U, G>&);
|
| 23 |
template<class U, class G>
|
| 24 |
constexpr explicit(see below) expected(expected<U, G>&&);
|
| 25 |
|
| 26 |
+
template<class U = remove_cv_t<T>>
|
| 27 |
constexpr explicit(see below) expected(U&& v);
|
| 28 |
|
| 29 |
template<class G>
|
| 30 |
constexpr explicit(see below) expected(const unexpected<G>&);
|
| 31 |
template<class G>
|
|
|
|
| 44 |
constexpr ~expected();
|
| 45 |
|
| 46 |
// [expected.object.assign], assignment
|
| 47 |
constexpr expected& operator=(const expected&);
|
| 48 |
constexpr expected& operator=(expected&&) noexcept(see below);
|
| 49 |
+
template<class U = remove_cv_t<T>> constexpr expected& operator=(U&&);
|
| 50 |
template<class G>
|
| 51 |
constexpr expected& operator=(const unexpected<G>&);
|
| 52 |
template<class G>
|
| 53 |
constexpr expected& operator=(unexpected<G>&&);
|
| 54 |
|
|
|
|
| 68 |
constexpr T& operator*() & noexcept;
|
| 69 |
constexpr const T&& operator*() const && noexcept;
|
| 70 |
constexpr T&& operator*() && noexcept;
|
| 71 |
constexpr explicit operator bool() const noexcept;
|
| 72 |
constexpr bool has_value() const noexcept;
|
| 73 |
+
constexpr const T& value() const &; // freestanding-deleted
|
| 74 |
+
constexpr T& value() &; // freestanding-deleted
|
| 75 |
+
constexpr const T&& value() const &&; // freestanding-deleted
|
| 76 |
+
constexpr T&& value() &&; // freestanding-deleted
|
| 77 |
constexpr const E& error() const & noexcept;
|
| 78 |
constexpr E& error() & noexcept;
|
| 79 |
constexpr const E&& error() const && noexcept;
|
| 80 |
constexpr E&& error() && noexcept;
|
| 81 |
+
template<class U = remove_cv_t<T>> constexpr T value_or(U&&) const &;
|
| 82 |
+
template<class U = remove_cv_t<T>> constexpr T value_or(U&&) &&;
|
| 83 |
template<class G = E> constexpr E error_or(G&&) const &;
|
| 84 |
template<class G = E> constexpr E error_or(G&&) &&;
|
| 85 |
|
| 86 |
// [expected.object.monadic], monadic operations
|
| 87 |
template<class F> constexpr auto and_then(F&& f) &;
|
|
|
|
| 118 |
};
|
| 119 |
}
|
| 120 |
```
|
| 121 |
|
| 122 |
Any object of type `expected<T, E>` either contains a value of type `T`
|
| 123 |
+
or a value of type `E` nested within [[intro.object]] it. Member
|
| 124 |
+
*`has_val`* indicates whether the `expected<T, E>` object contains an
|
| 125 |
+
object of type `T`.
|
|
|
|
|
|
|
| 126 |
|
| 127 |
A type `T` is a *valid value type for `expected`*, if `remove_cv_t<T>`
|
| 128 |
is `void` or a complete non-array object type that is not `in_place_t`,
|
| 129 |
`unexpect_t`, or a specialization of `unexpected`. A program which
|
| 130 |
instantiates class template `expected<T, E>` with an argument `T` that
|
|
|
|
| 240 |
|
| 241 |
*Remarks:* The expression inside `explicit` is equivalent to
|
| 242 |
`!is_convertible_v<UF, T> || !is_convertible_v<GF, E>`.
|
| 243 |
|
| 244 |
``` cpp
|
| 245 |
+
template<class U = remove_cv_t<T>>
|
| 246 |
constexpr explicit(!is_convertible_v<U, T>) expected(U&& v);
|
| 247 |
```
|
| 248 |
|
| 249 |
*Constraints:*
|
| 250 |
|
| 251 |
- `is_same_v<remove_cvref_t<U>, in_place_t>` is `false`; and
|
| 252 |
+
- `is_same_v<remove_cvref_t<U>, expected>` is `false`; and
|
| 253 |
+
- `is_same_v<remove_cvref_t<U>, unexpect_t>` is `false`; and
|
| 254 |
- `remove_cvref_t<U>` is not a specialization of `unexpected`; and
|
| 255 |
- `is_constructible_v<T, U>` is `true`; and
|
| 256 |
- if `T` is cv `bool`, `remove_cvref_t<U>` is not a specialization of
|
| 257 |
`expected`.
|
| 258 |
|
|
|
|
| 352 |
`is_trivially_destructible_v<E>` is `true`, then this destructor is a
|
| 353 |
trivial destructor.
|
| 354 |
|
| 355 |
#### Assignment <a id="expected.object.assign">[[expected.object.assign]]</a>
|
| 356 |
|
| 357 |
+
This subclause makes use of the following exposition-only function
|
| 358 |
+
template:
|
| 359 |
|
| 360 |
``` cpp
|
| 361 |
template<class T, class U, class... Args>
|
| 362 |
constexpr void reinit-expected(T& newval, U& oldval, Args&&... args) { // exposition only
|
| 363 |
if constexpr (is_nothrow_constructible_v<T, Args...>) {
|
|
|
|
| 450 |
is_nothrow_move_assignable_v<T> && is_nothrow_move_constructible_v<T> &&
|
| 451 |
is_nothrow_move_assignable_v<E> && is_nothrow_move_constructible_v<E>
|
| 452 |
```
|
| 453 |
|
| 454 |
``` cpp
|
| 455 |
+
template<class U = remove_cv_t<T>>
|
| 456 |
constexpr expected& operator=(U&& v);
|
| 457 |
```
|
| 458 |
|
| 459 |
*Constraints:*
|
| 460 |
|
|
|
|
| 566 |
|
| 567 |
| \topline | `this->has_value()` | `!this->has_value()` |
|
| 568 |
| -------- | ------------------- | -------------------- |
|
| 569 |
|
| 570 |
|
| 571 |
+
For the case where `rhs.has_value()` is `false` and `this->has_value()`
|
| 572 |
+
is `true`, equivalent to:
|
| 573 |
|
| 574 |
``` cpp
|
| 575 |
if constexpr (is_nothrow_move_constructible_v<E>) {
|
| 576 |
E tmp(std::move(rhs.unex));
|
| 577 |
destroy_at(addressof(rhs.unex));
|
|
|
|
| 619 |
``` cpp
|
| 620 |
constexpr const T* operator->() const noexcept;
|
| 621 |
constexpr T* operator->() noexcept;
|
| 622 |
```
|
| 623 |
|
| 624 |
+
`has_value()` is `true`.
|
| 625 |
|
| 626 |
*Returns:* `addressof(`*`val`*`)`.
|
| 627 |
|
| 628 |
``` cpp
|
| 629 |
constexpr const T& operator*() const & noexcept;
|
| 630 |
constexpr T& operator*() & noexcept;
|
| 631 |
```
|
| 632 |
|
| 633 |
+
`has_value()` is `true`.
|
| 634 |
|
| 635 |
*Returns:* *val*.
|
| 636 |
|
| 637 |
``` cpp
|
| 638 |
constexpr T&& operator*() && noexcept;
|
| 639 |
constexpr const T&& operator*() const && noexcept;
|
| 640 |
```
|
| 641 |
|
| 642 |
+
`has_value()` is `true`.
|
| 643 |
|
| 644 |
*Returns:* `std::move(`*`val`*`)`.
|
| 645 |
|
| 646 |
``` cpp
|
| 647 |
constexpr explicit operator bool() const noexcept;
|
|
|
|
| 678 |
``` cpp
|
| 679 |
constexpr const E& error() const & noexcept;
|
| 680 |
constexpr E& error() & noexcept;
|
| 681 |
```
|
| 682 |
|
| 683 |
+
`has_value()` is `false`.
|
| 684 |
|
| 685 |
*Returns:* *unex*.
|
| 686 |
|
| 687 |
``` cpp
|
| 688 |
constexpr E&& error() && noexcept;
|
| 689 |
constexpr const E&& error() const && noexcept;
|
| 690 |
```
|
| 691 |
|
| 692 |
+
`has_value()` is `false`.
|
| 693 |
|
| 694 |
*Returns:* `std::move(`*`unex`*`)`.
|
| 695 |
|
| 696 |
``` cpp
|
| 697 |
+
template<class U = remove_cv_t<T>> constexpr T value_or(U&& v) const &;
|
| 698 |
```
|
| 699 |
|
| 700 |
*Mandates:* `is_copy_constructible_v<T>` is `true` and
|
| 701 |
`is_convertible_v<U, T>` is `true`.
|
| 702 |
|
| 703 |
*Returns:* `has_value() ? **this : static_cast<T>(std::forward<U>(v))`.
|
| 704 |
|
| 705 |
``` cpp
|
| 706 |
+
template<class U = remove_cv_t<T>> constexpr T value_or(U&& v) &&;
|
| 707 |
```
|
| 708 |
|
| 709 |
*Mandates:* `is_move_constructible_v<T>` is `true` and
|
| 710 |
`is_convertible_v<U, T>` is `true`.
|
| 711 |
|
|
|
|
| 737 |
``` cpp
|
| 738 |
template<class F> constexpr auto and_then(F&& f) &;
|
| 739 |
template<class F> constexpr auto and_then(F&& f) const &;
|
| 740 |
```
|
| 741 |
|
| 742 |
+
Let `U` be `remove_cvref_t<invoke_result_t<F, decltype((`*`val`*`))>>`.
|
| 743 |
|
| 744 |
*Constraints:* `is_constructible_v<E, decltype(error())>` is `true`.
|
| 745 |
|
| 746 |
*Mandates:* `U` is a specialization of `expected` and
|
| 747 |
+
`is_same_v<typename U::error_type, E>` is `true`.
|
| 748 |
|
| 749 |
*Effects:* Equivalent to:
|
| 750 |
|
| 751 |
``` cpp
|
| 752 |
if (has_value())
|
| 753 |
+
return invoke(std::forward<F>(f), val);
|
| 754 |
else
|
| 755 |
return U(unexpect, error());
|
| 756 |
```
|
| 757 |
|
| 758 |
``` cpp
|
| 759 |
template<class F> constexpr auto and_then(F&& f) &&;
|
| 760 |
template<class F> constexpr auto and_then(F&& f) const &&;
|
| 761 |
```
|
| 762 |
|
| 763 |
Let `U` be
|
| 764 |
+
`remove_cvref_t<invoke_result_t<F, decltype(std::move(`*`val`*`))>>`.
|
| 765 |
|
| 766 |
*Constraints:* `is_constructible_v<E, decltype(std::move(error()))>` is
|
| 767 |
`true`.
|
| 768 |
|
| 769 |
*Mandates:* `U` is a specialization of `expected` and
|
| 770 |
+
`is_same_v<typename U::error_type, E>` is `true`.
|
| 771 |
|
| 772 |
*Effects:* Equivalent to:
|
| 773 |
|
| 774 |
``` cpp
|
| 775 |
if (has_value())
|
| 776 |
+
return invoke(std::forward<F>(f), std::move(val));
|
| 777 |
else
|
| 778 |
return U(unexpect, std::move(error()));
|
| 779 |
```
|
| 780 |
|
| 781 |
``` cpp
|
|
|
|
| 783 |
template<class F> constexpr auto or_else(F&& f) const &;
|
| 784 |
```
|
| 785 |
|
| 786 |
Let `G` be `remove_cvref_t<invoke_result_t<F, decltype(error())>>`.
|
| 787 |
|
| 788 |
+
*Constraints:* `is_constructible_v<T, decltype((`*`val`*`))>` is `true`.
|
| 789 |
|
| 790 |
*Mandates:* `G` is a specialization of `expected` and
|
| 791 |
+
`is_same_v<typename G::value_type, T>` is `true`.
|
| 792 |
|
| 793 |
*Effects:* Equivalent to:
|
| 794 |
|
| 795 |
``` cpp
|
| 796 |
if (has_value())
|
| 797 |
+
return G(in_place, val);
|
| 798 |
else
|
| 799 |
return invoke(std::forward<F>(f), error());
|
| 800 |
```
|
| 801 |
|
| 802 |
``` cpp
|
|
|
|
| 805 |
```
|
| 806 |
|
| 807 |
Let `G` be
|
| 808 |
`remove_cvref_t<invoke_result_t<F, decltype(std::move(error()))>>`.
|
| 809 |
|
| 810 |
+
*Constraints:* `is_constructible_v<T, decltype(std::move(`*`val`*`))>`
|
| 811 |
+
is `true`.
|
| 812 |
|
| 813 |
*Mandates:* `G` is a specialization of `expected` and
|
| 814 |
+
`is_same_v<typename G::value_type, T>` is `true`.
|
| 815 |
|
| 816 |
*Effects:* Equivalent to:
|
| 817 |
|
| 818 |
``` cpp
|
| 819 |
if (has_value())
|
| 820 |
+
return G(in_place, std::move(val));
|
| 821 |
else
|
| 822 |
return invoke(std::forward<F>(f), std::move(error()));
|
| 823 |
```
|
| 824 |
|
| 825 |
``` cpp
|
| 826 |
template<class F> constexpr auto transform(F&& f) &;
|
| 827 |
template<class F> constexpr auto transform(F&& f) const &;
|
| 828 |
```
|
| 829 |
|
| 830 |
+
Let `U` be `remove_cv_t<invoke_result_t<F, decltype((`*`val`*`))>>`.
|
| 831 |
|
| 832 |
*Constraints:* `is_constructible_v<E, decltype(error())>` is `true`.
|
| 833 |
|
| 834 |
*Mandates:* `U` is a valid value type for `expected`. If `is_void_v<U>`
|
| 835 |
is `false`, the declaration
|
| 836 |
|
| 837 |
``` cpp
|
| 838 |
+
U u(invoke(std::forward<F>(f), val));
|
| 839 |
```
|
| 840 |
|
| 841 |
is well-formed.
|
| 842 |
|
| 843 |
*Effects:*
|
|
|
|
| 845 |
- If `has_value()` is `false`, returns
|
| 846 |
`expected<U, E>(unexpect, error())`.
|
| 847 |
- Otherwise, if `is_void_v<U>` is `false`, returns an `expected<U, E>`
|
| 848 |
object whose *has_val* member is `true` and *val* member is
|
| 849 |
direct-non-list-initialized with
|
| 850 |
+
`invoke(std::forward<F>(f), `*`val`*`)`.
|
| 851 |
+
- Otherwise, evaluates `invoke(std::forward<F>(f), `*`val`*`)` and then
|
| 852 |
returns `expected<U, E>()`.
|
| 853 |
|
| 854 |
``` cpp
|
| 855 |
template<class F> constexpr auto transform(F&& f) &&;
|
| 856 |
template<class F> constexpr auto transform(F&& f) const &&;
|
| 857 |
```
|
| 858 |
|
| 859 |
Let `U` be
|
| 860 |
+
`remove_cv_t<invoke_result_t<F, decltype(std::move(`*`val`*`))>>`.
|
| 861 |
|
| 862 |
*Constraints:* `is_constructible_v<E, decltype(std::move(error()))>` is
|
| 863 |
`true`.
|
| 864 |
|
| 865 |
*Mandates:* `U` is a valid value type for `expected`. If `is_void_v<U>`
|
| 866 |
is `false`, the declaration
|
| 867 |
|
| 868 |
``` cpp
|
| 869 |
+
U u(invoke(std::forward<F>(f), std::move(val)));
|
| 870 |
```
|
| 871 |
|
| 872 |
+
is well-formed.
|
| 873 |
|
| 874 |
*Effects:*
|
| 875 |
|
| 876 |
- If `has_value()` is `false`, returns
|
| 877 |
`expected<U, E>(unexpect, std::move(error()))`.
|
| 878 |
- Otherwise, if `is_void_v<U>` is `false`, returns an `expected<U, E>`
|
| 879 |
object whose *has_val* member is `true` and *val* member is
|
| 880 |
direct-non-list-initialized with
|
| 881 |
+
`invoke(std::forward<F>(f), std::move(`*`val`*`))`.
|
| 882 |
+
- Otherwise, evaluates
|
| 883 |
+
`invoke(std::forward<F>(f), std::move(`*`val`*`))` and then returns
|
| 884 |
+
`expected<U, E>()`.
|
| 885 |
|
| 886 |
``` cpp
|
| 887 |
template<class F> constexpr auto transform_error(F&& f) &;
|
| 888 |
template<class F> constexpr auto transform_error(F&& f) const &;
|
| 889 |
```
|
| 890 |
|
| 891 |
Let `G` be `remove_cv_t<invoke_result_t<F, decltype(error())>>`.
|
| 892 |
|
| 893 |
+
*Constraints:* `is_constructible_v<T, decltype((`*`val`*`))>` is `true`.
|
| 894 |
|
| 895 |
*Mandates:* `G` is a valid template argument for `unexpected`
|
| 896 |
[[expected.un.general]] and the declaration
|
| 897 |
|
| 898 |
``` cpp
|
|
|
|
| 900 |
```
|
| 901 |
|
| 902 |
is well-formed.
|
| 903 |
|
| 904 |
*Returns:* If `has_value()` is `true`,
|
| 905 |
+
`expected<T, G>(in_place, `*`val`*`)`; otherwise, an `expected<T, G>`
|
| 906 |
object whose *has_val* member is `false` and *unex* member is
|
| 907 |
direct-non-list-initialized with `invoke(std::forward<F>(f), error())`.
|
| 908 |
|
| 909 |
``` cpp
|
| 910 |
template<class F> constexpr auto transform_error(F&& f) &&;
|
|
|
|
| 912 |
```
|
| 913 |
|
| 914 |
Let `G` be
|
| 915 |
`remove_cv_t<invoke_result_t<F, decltype(std::move(error()))>>`.
|
| 916 |
|
| 917 |
+
*Constraints:* `is_constructible_v<T, decltype(std::move(`*`val`*`))>`
|
| 918 |
+
is `true`.
|
| 919 |
|
| 920 |
*Mandates:* `G` is a valid template argument for `unexpected`
|
| 921 |
[[expected.un.general]] and the declaration
|
| 922 |
|
| 923 |
``` cpp
|
|
|
|
| 925 |
```
|
| 926 |
|
| 927 |
is well-formed.
|
| 928 |
|
| 929 |
*Returns:* If `has_value()` is `true`,
|
| 930 |
+
`expected<T, G>(in_place, std::move(`*`val`*`))`; otherwise, an
|
| 931 |
`expected<T, G>` object whose *has_val* member is `false` and *unex*
|
| 932 |
member is direct-non-list-initialized with
|
| 933 |
`invoke(std::forward<F>(f), std::move(error()))`.
|
| 934 |
|
| 935 |
#### Equality operators <a id="expected.object.eq">[[expected.object.eq]]</a>
|
|
|
|
| 937 |
``` cpp
|
| 938 |
template<class T2, class E2> requires (!is_void_v<T2>)
|
| 939 |
friend constexpr bool operator==(const expected& x, const expected<T2, E2>& y);
|
| 940 |
```
|
| 941 |
|
| 942 |
+
*Constraints:* The expressions `*x == *y` and `x.error() == y.error()`
|
| 943 |
+
are well-formed and their results are convertible to `bool`.
|
| 944 |
|
| 945 |
*Returns:* If `x.has_value()` does not equal `y.has_value()`, `false`;
|
| 946 |
otherwise if `x.has_value()` is `true`, `*x == *y`; otherwise
|
| 947 |
`x.error() == y.error()`.
|
| 948 |
|
| 949 |
``` cpp
|
| 950 |
template<class T2> friend constexpr bool operator==(const expected& x, const T2& v);
|
| 951 |
```
|
| 952 |
|
| 953 |
+
*Constraints:* `T2` is not a specialization of `expected`. The
|
| 954 |
+
expression `*x == v` is well-formed and its result is convertible to
|
| 955 |
+
`bool`.
|
| 956 |
|
| 957 |
[*Note 1*: `T` need not be *Cpp17EqualityComparable*. — *end note*]
|
| 958 |
|
| 959 |
*Returns:* `x.has_value() && static_cast<bool>(*x == v)`.
|
| 960 |
|
| 961 |
``` cpp
|
| 962 |
template<class E2> friend constexpr bool operator==(const expected& x, const unexpected<E2>& e);
|
| 963 |
```
|
| 964 |
|
| 965 |
+
*Constraints:* The expression `x.error() == e.error()` is well-formed
|
| 966 |
+
and its result is convertible to `bool`.
|
| 967 |
|
| 968 |
*Returns:*
|
| 969 |
`!x.has_value() && static_cast<bool>(x.error() == e.error())`.
|
| 970 |
|