@@ -605,7 +605,7 @@ class optional {
605605 * @return T
606606 */
607607 template <class U = std::remove_cv_t <T>>
608- constexpr T value_or (U&& u) const &;
608+ constexpr std:: remove_cv_t <T> value_or (U&& u) const &;
609609 /* *
610610 * @brief Returns the contained value if there is one, otherwise returns `u`.
611611 *
@@ -614,7 +614,7 @@ class optional {
614614 * @return T
615615 */
616616 template <class U = std::remove_cv_t <T>>
617- constexpr T value_or (U&& u) &&;
617+ constexpr std:: remove_cv_t <T> value_or (U&& u) &&;
618618
619619 // \ref{optional.monadic}, monadic operations
620620
@@ -1105,17 +1105,25 @@ inline constexpr T&& optional<T>::value() && {
11051105// / Returns the contained value if there is one, otherwise returns `u`
11061106template <class T >
11071107template <class U >
1108- inline constexpr T optional<T>::value_or(U&& u) const & {
1109- static_assert (std::is_copy_constructible_v<T> && std::is_convertible_v<U&&, T>);
1110- return has_value () ? value () : static_cast <T>(std::forward<U>(u));
1108+ inline constexpr std::remove_cv_t <T> optional<T>::value_or(U&& u) const & {
1109+ using X = std::remove_cv_t <T>;
1110+ static_assert (std::is_convertible_v<const T&, X>, " Must be able to convert const T& to remove_cv_t<T>" );
1111+ static_assert (std::is_convertible_v<U, X>, " Must be able to convert u to remove_cv_t<T>" );
1112+ if (has_value ())
1113+ return value_;
1114+ return std::forward<U>(u);
11111115}
11121116
11131117template <class T >
11141118template <class U >
1115- inline constexpr T optional<T>::value_or(U&& u) && {
1116- static_assert (std::is_move_constructible_v<T>);
1117- static_assert (std::is_convertible_v<decltype (u), T>, " Must be able to convert u to T" );
1118- return has_value () ? std::move (value ()) : static_cast <T>(std::forward<U>(u));
1119+ inline constexpr std::remove_cv_t <T> optional<T>::value_or(U&& u) && {
1120+ using X = std::remove_cv_t <T>;
1121+ static_assert (std::is_convertible_v<T, X>, " Must be able to convert T to remove_cv_t<T>" );
1122+ static_assert (std::is_convertible_v<U, X>, " Must be able to convert u to remove_cv_t<T>" );
1123+ if (has_value ()) {
1124+ return std::move (value_);
1125+ }
1126+ return std::forward<U>(u);
11191127}
11201128
11211129// 22.5.3.8 Monadic operations[optional.monadic]
@@ -1819,7 +1827,7 @@ class optional<T&> {
18191827 * @return std::remove_cv_t<T>
18201828 */
18211829 template <class U = std::remove_cv_t <T>>
1822- requires (std::is_object_v<T> && !std::is_array_v<T>)
1830+ requires (std::is_object_v<T> && !std::is_array_v<T>)
18231831 constexpr std::decay_t <T> value_or (U&& u) const ;
18241832
18251833 // \ref{optionalref.monadic}, monadic operations
@@ -2007,16 +2015,23 @@ constexpr bool optional<T&>::has_value() const noexcept {
20072015
20082016template <class T >
20092017constexpr T& optional<T&>::value() const {
2010- return has_value () ? *value_ : throw bad_optional_access ();
2018+ if (has_value ()) {
2019+ return *value_;
2020+ }
2021+ throw bad_optional_access ();
20112022}
20122023
20132024template <class T >
20142025template <class U >
2015- requires (std::is_object_v<T> && !std::is_array_v<T>)
2026+ requires (std::is_object_v<T> && !std::is_array_v<T>)
20162027constexpr std::decay_t <T> optional<T&>::value_or(U&& u) const {
2017- static_assert (std::is_constructible_v<std::remove_cv_t <T>, T&>, " T must be constructible from a T&" );
2018- static_assert (std::is_convertible_v<U, std::remove_cv_t <T>>, " Must be able to convert u to T" );
2019- return has_value () ? *value_ : static_cast <std::remove_cv_t <T>>(std::forward<U>(u));
2028+ using X = std::remove_cv_t <T>;
2029+ static_assert (std::is_convertible_v<T&, X>, " remove_cv_t<T> must be constructible from a T&" );
2030+ static_assert (std::is_convertible_v<U, X>, " Must be able to convert u to remove_cv_t<T>" );
2031+ if (has_value ()) {
2032+ return *value_;
2033+ }
2034+ return std::forward<U>(u);
20202035}
20212036
20222037// \rSec3[optionalref.monadic]{Monadic operations}
0 commit comments