@@ -824,19 +824,7 @@ struct copy_assign_base<T, E, true, false> : move_ctor_base<T, E> {
824824 noexcept (std::is_nothrow_copy_constructible_v<T> &&
825825 std::is_nothrow_copy_assignable_v<T> &&
826826 std::is_nothrow_copy_constructible_v<E> &&
827- std::is_nothrow_copy_assignable_v<E>) {
828- if (this ->m_has_val && rhs.m_has_val ) {
829- this ->m_val = rhs.m_val ;
830- } else if (this ->m_has_val ) {
831- expected_detail::reinit_expected (this ->m_unexpect , this ->m_val , rhs.m_unexpect );
832- } else if (rhs.m_has_val ) {
833- expected_detail::reinit_expected (this ->m_val , this ->m_unexpect , rhs.m_val );
834- } else {
835- this ->m_unexpect = rhs.m_unexpect ;
836- }
837- this ->m_has_val = rhs.m_has_val ;
838- return *this ;
839- }
827+ std::is_nothrow_copy_assignable_v<E>);
840828
841829 copy_assign_base& operator =(copy_assign_base&& rhs) = default ;
842830};
@@ -851,24 +839,49 @@ struct copy_assign_base<void, E, true, false> : move_ctor_base<void, E> {
851839 copy_assign_base (copy_assign_base&& rhs) = default ;
852840
853841 constexpr copy_assign_base& operator =(const copy_assign_base& rhs) noexcept (
854- std::is_nothrow_copy_constructible_v<E> && std::is_nothrow_copy_assignable_v<E>) {
855- if (this ->m_has_val && rhs.m_has_val ) {
856- // no-op
857- } else if (this ->m_has_val ) {
858- std::construct_at (std::addressof (this ->m_unexpect ), rhs.m_unexpect );
859- this ->m_has_val = false ;
860- } else if (rhs.m_has_val ) {
861- this ->m_unexpect .~E ();
862- this ->m_has_val = true ;
863- } else {
864- this ->m_unexpect = rhs.m_unexpect ;
865- }
866- return *this ;
867- }
842+ std::is_nothrow_copy_constructible_v<E> && std::is_nothrow_copy_assignable_v<E>);
868843
869844 copy_assign_base& operator =(copy_assign_base&& rhs) = default ;
870845};
871846
847+ template <class T , class E >
848+ constexpr copy_assign_base<T, E, true , false >& copy_assign_base<T, E, true , false >::
849+ operator =(const copy_assign_base<T, E, true , false >& rhs) noexcept (
850+ std::is_nothrow_copy_constructible_v<T> && std::is_nothrow_copy_assignable_v<T> &&
851+ std::is_nothrow_copy_constructible_v<E> && std::is_nothrow_copy_assignable_v<E>) {
852+ if (this ->m_has_val && rhs.m_has_val ) {
853+ this ->m_val = rhs.m_val ;
854+ } else if (this ->m_has_val ) {
855+ expected_detail::reinit_expected (this ->m_unexpect , this ->m_val , rhs.m_unexpect );
856+ } else if (rhs.m_has_val ) {
857+ expected_detail::reinit_expected (this ->m_val , this ->m_unexpect , rhs.m_val );
858+ } else {
859+ this ->m_unexpect = rhs.m_unexpect ;
860+ }
861+ this ->m_has_val = rhs.m_has_val ;
862+ return *this ;
863+ }
864+
865+ template <class E >
866+ constexpr copy_assign_base<void , E, true , false >&
867+ copy_assign_base<void , E, true , false >::operator =(
868+ const copy_assign_base<void , E, true , false >&
869+ rhs) noexcept (std::is_nothrow_copy_constructible_v<E> &&
870+ std::is_nothrow_copy_assignable_v<E>) {
871+ if (this ->m_has_val && rhs.m_has_val ) {
872+ // no-op
873+ } else if (this ->m_has_val ) {
874+ std::construct_at (std::addressof (this ->m_unexpect ), rhs.m_unexpect );
875+ this ->m_has_val = false ;
876+ } else if (rhs.m_has_val ) {
877+ this ->m_unexpect .~E ();
878+ this ->m_has_val = true ;
879+ } else {
880+ this ->m_unexpect = rhs.m_unexpect ;
881+ }
882+ return *this ;
883+ }
884+
872885template <class T , class E >
873886inline constexpr bool is_expected_move_assignable_v =
874887 is_move_assignable_or_void_v<T> && is_move_constructible_or_void_v<T> &&
0 commit comments