From Jason Turner

[expected.expected]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpyfpmqy5s/{from.md → to.md} +62 -60
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 its own storage. Implementations are not
124
- permitted to use additional storage, such as dynamic memory, to allocate
125
- the object of type `T` or the object of type `E`. Member *`has_val`*
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<expected, remove_cvref_t<U>>` is `false`; and
 
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.value()` is `false` and `this->has_value()` is
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
- *Preconditions:* `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
- *Preconditions:* `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
- *Preconditions:* `has_value()` is `true`.
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
- *Preconditions:* `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
- *Preconditions:* `has_value()` is `false`.
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(value())>>`.
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), value());
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(value()))>>`.
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(value()));
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(value())>` is `true`.
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, value());
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(value()))>` is
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(value()));
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(value())>>`.
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), value()));
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), value())`.
851
- - Otherwise, evaluates `invoke(std::forward<F>(f), value())` 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(value()))>>`.
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(value())));
870
  ```
871
 
872
- is well-formed for some invented variable `u`.
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(value()))`.
882
- - Otherwise, evaluates `invoke(std::forward<F>(f), std::move(value()))`
883
- and then returns `expected<U, E>()`.
 
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(value())>` is `true`.
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, value())`; otherwise, an `expected<T, G>`
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(value()))>` is
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(value()))`; otherwise, an
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
- *Mandates:* The expressions `*x == *y` and `x.error() == y.error()` are
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
- *Mandates:* The expression `*x == v` is well-formed and its result is
953
- convertible to `bool`.
 
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
- *Mandates:* The expression `x.error() == e.error()` is well-formed and
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