@@ -595,7 +595,7 @@ class optional {
595595 * @return T
596596 */
597597 template <class U = std::remove_cv_t <T>>
598- constexpr T value_or (U&& u) const &;
598+ constexpr std:: remove_cv_t <T> value_or (U&& u) const &;
599599 /* *
600600 * @brief Returns the contained value if there is one, otherwise returns `u`.
601601 *
@@ -604,7 +604,7 @@ class optional {
604604 * @return T
605605 */
606606 template <class U = std::remove_cv_t <T>>
607- constexpr T value_or (U&& u) &&;
607+ constexpr std:: remove_cv_t <T> value_or (U&& u) &&;
608608
609609 // \ref{optional.monadic}, monadic operations
610610
@@ -1095,17 +1095,25 @@ inline constexpr T&& optional<T>::value() && {
10951095// / Returns the contained value if there is one, otherwise returns `u`
10961096template <class T >
10971097template <class U >
1098- inline constexpr T optional<T>::value_or(U&& u) const & {
1099- static_assert (std::is_copy_constructible_v<T> && std::is_convertible_v<U&&, T>);
1100- return has_value () ? value () : static_cast <T>(std::forward<U>(u));
1098+ inline constexpr std::remove_cv_t <T> optional<T>::value_or(U&& u) const & {
1099+ using X = std::remove_cv_t <T>;
1100+ static_assert (std::is_convertible_v<const T&, X>, " Must be able to convert const T& to remove_cv_t<T>" );
1101+ static_assert (std::is_convertible_v<U, X>, " Must be able to convert u to remove_cv_t<T>" );
1102+ if (has_value ())
1103+ return value_;
1104+ return std::forward<U>(u);
11011105}
11021106
11031107template <class T >
11041108template <class U >
1105- inline constexpr T optional<T>::value_or(U&& u) && {
1106- static_assert (std::is_move_constructible_v<T>);
1107- static_assert (std::is_convertible_v<decltype (u), T>, " Must be able to convert u to T" );
1108- return has_value () ? std::move (value ()) : static_cast <T>(std::forward<U>(u));
1109+ inline constexpr std::remove_cv_t <T> optional<T>::value_or(U&& u) && {
1110+ using X = std::remove_cv_t <T>;
1111+ static_assert (std::is_convertible_v<T, X>, " Must be able to convert T to remove_cv_t<T>" );
1112+ static_assert (std::is_convertible_v<U, X>, " Must be able to convert u to remove_cv_t<T>" );
1113+ if (has_value ()) {
1114+ return std::move (value_);
1115+ }
1116+ return std::forward<U>(u);
11091117}
11101118
11111119// 22.5.3.8 Monadic operations[optional.monadic]
@@ -1986,15 +1994,22 @@ constexpr bool optional<T&>::has_value() const noexcept {
19861994
19871995template <class T >
19881996constexpr T& optional<T&>::value() const {
1989- return has_value () ? *value_ : throw bad_optional_access ();
1997+ if (has_value ()) {
1998+ return *value_;
1999+ }
2000+ throw bad_optional_access ();
19902001}
19912002
19922003template <class T >
19932004template <class U >
19942005constexpr std::remove_cv_t <T> optional<T&>::value_or(U&& u) const {
1995- static_assert (std::is_constructible_v<std::remove_cv_t <T>, T&>, " T must be constructible from a T&" );
1996- static_assert (std::is_convertible_v<U, std::remove_cv_t <T>>, " Must be able to convert u to T" );
1997- return has_value () ? *value_ : static_cast <std::remove_cv_t <T>>(std::forward<U>(u));
2006+ using X = std::remove_cv_t <T>;
2007+ static_assert (std::is_convertible_v<T&, X>, " remove_cv_t<T> must be constructible from a T&" );
2008+ static_assert (std::is_convertible_v<U, X>, " Must be able to convert u to remove_cv_t<T>" );
2009+ if (has_value ()) {
2010+ return *value_;
2011+ }
2012+ return std::forward<U>(u);
19982013}
19992014
20002015// \rSec3[optionalref.monadic]{Monadic operations}
0 commit comments