@@ -201,12 +201,16 @@ concept enable_forward_value = !std::is_same_v<std::decay_t<U>, optional<T>> &&
201201 !std::is_same_v<std::decay_t <U>, in_place_t > && std::is_constructible_v<T, U&&>;
202202
203203template <class T , class U , class Other >
204- concept enable_from_other =
205- !std::is_same_v<T, U> && std::is_constructible_v<T, Other> && !std::is_constructible_v<T, optional<U>&> &&
206- !std::is_constructible_v<T, optional<U>&&> && !std::is_constructible_v<T, const optional<U>&> &&
207- !std::is_constructible_v<T, const optional<U>&&> && !std::is_convertible_v<optional<U>&, T> &&
208- !std::is_convertible_v<optional<U>&&, T> && !std::is_convertible_v<const optional<U>&, T> &&
209- !std::is_convertible_v<const optional<U>&&, T>;
204+ concept enable_from_other = !std::is_same_v<T, U> && //
205+ std::is_constructible_v<T, Other> && //
206+ !std::is_constructible_v<T, optional<U>&> && //
207+ !std::is_constructible_v<T, optional<U>&&> && //
208+ !std::is_constructible_v<T, const optional<U>&> && //
209+ !std::is_constructible_v<T, const optional<U>&&> && //
210+ !std::is_convertible_v<optional<U>&, T> && //
211+ !std::is_convertible_v<optional<U>&&, T> && //
212+ !std::is_convertible_v<const optional<U>&, T> && //
213+ !std::is_convertible_v<const optional<U>&&, T>;
210214
211215template <class T , class U >
212216concept enable_assign_forward = !std::is_same_v<optional<T>, std::decay_t <U>> &&
@@ -279,12 +283,12 @@ class optional {
279283 requires(!std::is_reference_v<U> && detail::enable_from_other<T, U, const U&>);
280284
281285 template <class U >
282- constexpr explicit (!std::is_convertible_v<U, T>) optional(optional<U>& & rhs)
283- requires(! std::is_reference_v<U> && detail::enable_from_other<T, U, U && >);
286+ constexpr explicit (!std::is_convertible_v<U, T>) optional(const optional<U>& rhs)
287+ requires(std::is_reference_v<U> && detail::enable_from_other<T, U, U>);
284288
285289 template <class U >
286- constexpr explicit (!std::is_convertible_v<U& , T>) optional(const optional<U&> & rhs)
287- requires(detail::enable_from_other<T, U& , U&>);
290+ constexpr explicit (!std::is_convertible_v<U, T>) optional(optional<U>& & rhs)
291+ requires(!std::is_reference_v<U> && detail::enable_from_other<T, U, U & &>);
288292
289293 // \ref{optional.dtor}, destructor
290294 constexpr ~optional ()
@@ -324,12 +328,12 @@ class optional {
324328 requires (!std::is_reference_v<U> && detail::enable_assign_from_other<T, U, const U&>);
325329
326330 template <class U >
327- constexpr optional& operator =(optional<U>& & rhs)
328- requires (! std::is_reference_v<U> && detail::enable_assign_from_other<T, U, U>);
331+ constexpr optional& operator =(const optional<U>& rhs)
332+ requires (std::is_reference_v<U> && detail::enable_assign_from_other<T, U, U>);
329333
330334 template <class U >
331- constexpr optional& operator =(const optional<U&> & rhs)
332- requires (detail::enable_assign_from_other<T, U& , U& >);
335+ constexpr optional& operator =(optional<U>& & rhs)
336+ requires (!std::is_reference_v<U> && detail::enable_assign_from_other<T, U, U>);
333337
334338 template <class ... Args>
335339 constexpr T& emplace (Args&&... args);
@@ -358,9 +362,9 @@ class optional {
358362 constexpr T& value () &;
359363 constexpr const T& value () const &;
360364 constexpr T&& value() &&;
361- template <class U >
365+ template <class U = std:: remove_cv_t <T> >
362366 constexpr T value_or (U&& u) const &;
363- template <class U >
367+ template <class U = std:: remove_cv_t <T> >
364368 constexpr T value_or (U&& u) &&;
365369
366370 // \ref{optional.monadic}, monadic operations
@@ -456,7 +460,7 @@ inline constexpr optional<T>::optional(in_place_t, std::initializer_list<U> il,
456460template <class T >
457461template <class U >
458462inline constexpr optional<T>::optional(U&& u)
459- requires detail::enable_forward_value<T, U> // && std::is_convertible_v<U&&, T>
463+ requires detail::enable_forward_value<T, U>
460464 : optional(in_place, std::forward<U>(u)) {}
461465
462466// / Converting copy constructor.
@@ -470,24 +474,25 @@ inline constexpr optional<T>::optional(const optional<U>& rhs)
470474 }
471475}
472476
473- // / Converting move constructor.
477+ // / Converting copy constructor for U&
474478template <class T >
475479template <class U >
476- inline constexpr optional<T>::optional(optional<U>& & rhs)
477- requires (! std::is_reference_v<U> && detail::enable_from_other<T, U, U && >)
480+ inline constexpr optional<T>::optional(const optional<U>& rhs)
481+ requires (std::is_reference_v<U> && detail::enable_from_other<T, U, U>)
478482{
479483 if (rhs.has_value ()) {
480- construct (std::move ( *rhs) );
484+ construct (*rhs);
481485 }
482486}
483487
488+ // / Converting move constructor.
484489template <class T >
485490template <class U >
486- inline constexpr optional<T>::optional(const optional<U&> & rhs)
487- requires (detail::enable_from_other<T, U& , U&>)
491+ inline constexpr optional<T>::optional(optional<U>& & rhs)
492+ requires (!std::is_reference_v<U> && detail::enable_from_other<T, U, U & &>)
488493{
489494 if (rhs.has_value ()) {
490- construct (*rhs);
495+ construct (std::move ( *rhs) );
491496 }
492497}
493498
@@ -578,45 +583,45 @@ inline constexpr optional<T>& optional<T>::operator=(const optional<U>& rhs)
578583 return *this ;
579584}
580585
581- // / Converting move assignment operator.
582- // /
583- // / Moves the value from `rhs` if there is one. Otherwise resets the stored
584- // / value in `*this`.
585586template <class T >
586587template <class U >
587- inline constexpr optional<T>& optional<T>::operator =(optional<U>& & rhs)
588- requires (! std::is_reference_v<U> && detail::enable_assign_from_other<T, U, U>)
588+ inline constexpr optional<T>& optional<T>::operator =(const optional<U>& rhs)
589+ requires (std::is_reference_v<U> && detail::enable_assign_from_other<T, U, U>)
589590{
590591 if (has_value ()) {
591592 if (rhs.has_value ()) {
592- value_ = std::move ( *rhs) ;
593+ value_ = *rhs;
593594 } else {
594595 hard_reset ();
595596 }
596597 }
597598
598599 else if (rhs.has_value ()) {
599- construct (std::move ( *rhs) );
600+ construct (*rhs);
600601 }
601602
602603 return *this ;
603604}
604605
606+ // / Converting move assignment operator.
607+ // /
608+ // / Moves the value from `rhs` if there is one. Otherwise resets the stored
609+ // / value in `*this`.
605610template <class T >
606611template <class U >
607- inline constexpr optional<T>& optional<T>::operator =(const optional<U&> & rhs)
608- requires (detail::enable_assign_from_other<T, U& , U& >)
612+ inline constexpr optional<T>& optional<T>::operator =(optional<U>& & rhs)
613+ requires (!std::is_reference_v<U> && detail::enable_assign_from_other<T, U, U>)
609614{
610615 if (has_value ()) {
611616 if (rhs.has_value ()) {
612- value_ = *rhs;
617+ value_ = std::move ( *rhs) ;
613618 } else {
614619 hard_reset ();
615620 }
616621 }
617622
618623 else if (rhs.has_value ()) {
619- construct (*rhs);
624+ construct (std::move ( *rhs) );
620625 }
621626
622627 return *this ;
0 commit comments