[libcxx-commits] [libcxx] 24b7727 - [libc++] Implement LWG4222 'expected' constructor from a single value missing a constraint (#152676)

via libcxx-commits libcxx-commits at lists.llvm.org
Sat Aug 9 10:11:24 PDT 2025


Author: yronglin
Date: 2025-08-10T01:11:20+08:00
New Revision: 24b772769f47f2c884ffab64a24444da9968094f

URL: https://github.com/llvm/llvm-project/commit/24b772769f47f2c884ffab64a24444da9968094f
DIFF: https://github.com/llvm/llvm-project/commit/24b772769f47f2c884ffab64a24444da9968094f.diff

LOG: [libc++] Implement LWG4222 'expected' constructor from a single value missing a constraint (#152676)

Implement [LWG4222](https://wg21.link/LWG4222).
Closes https://github.com/llvm/llvm-project/issues/148208

Signed-off-by: yronglin <yronglin777 at gmail.com>

Added: 
    

Modified: 
    libcxx/docs/Status/Cxx2cIssues.csv
    libcxx/include/__expected/expected.h
    libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.u.pass.cpp

Removed: 
    


################################################################################
diff  --git a/libcxx/docs/Status/Cxx2cIssues.csv b/libcxx/docs/Status/Cxx2cIssues.csv
index c6225127a74b9..5460664369793 100644
--- a/libcxx/docs/Status/Cxx2cIssues.csv
+++ b/libcxx/docs/Status/Cxx2cIssues.csv
@@ -132,7 +132,7 @@
 "`LWG4200 <https://wg21.link/LWG4200>`__","The ``operation_state`` concept can be simplified","2025-06 (Sofia)","","",""
 "`LWG4201 <https://wg21.link/LWG4201>`__","``with-await-transform::await_transform`` should not use a deduced return type","2025-06 (Sofia)","","",""
 "`LWG4217 <https://wg21.link/LWG4217>`__","Clarify ``mdspan`` layout mapping requirements for ``rank == 0``","2025-06 (Sofia)","","",""
-"`LWG4222 <https://wg21.link/LWG4222>`__","``expected`` constructor from a single value missing a constraint","2025-06 (Sofia)","","",""
+"`LWG4222 <https://wg21.link/LWG4222>`__","``expected`` constructor from a single value missing a constraint","2025-06 (Sofia)","|Complete|","22",""
 "`LWG4224 <https://wg21.link/LWG4224>`__","Philox engines should be freestanding","2025-06 (Sofia)","","",""
 "`LWG4227 <https://wg21.link/LWG4227>`__","Missing ``noexcept`` operator in [exec.when.all]","2025-06 (Sofia)","","",""
 "`LWG4231 <https://wg21.link/LWG4231>`__","``datapar::chunk<N>`` should use ``simd-size-type`` instead of ``size_t``","2025-06 (Sofia)","","",""

diff  --git a/libcxx/include/__expected/expected.h b/libcxx/include/__expected/expected.h
index 0f446b870723b..38a34121040f6 100644
--- a/libcxx/include/__expected/expected.h
+++ b/libcxx/include/__expected/expected.h
@@ -557,7 +557,8 @@ class expected : private __expected_base<_Tp, _Err> {
 
   template <class _Up = _Tp>
     requires(!is_same_v<remove_cvref_t<_Up>, in_place_t> && !is_same_v<expected, remove_cvref_t<_Up>> &&
-             is_constructible_v<_Tp, _Up> && !__is_std_unexpected<remove_cvref_t<_Up>>::value &&
+             !is_same_v<remove_cvref_t<_Up>, unexpect_t> && is_constructible_v<_Tp, _Up> &&
+             !__is_std_unexpected<remove_cvref_t<_Up>>::value &&
              (!is_same_v<remove_cv_t<_Tp>, bool> || !__is_std_expected<remove_cvref_t<_Up>>::value))
   _LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_Up, _Tp>)
       expected(_Up&& __u) noexcept(is_nothrow_constructible_v<_Tp, _Up>) // strengthened

diff  --git a/libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.u.pass.cpp b/libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.u.pass.cpp
index fa9f5a115ccf5..13c0da27bc533 100644
--- a/libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.u.pass.cpp
+++ b/libcxx/test/std/utilities/expected/expected.expected/ctor/ctor.u.pass.cpp
@@ -14,6 +14,7 @@
 // Constraints:
 // - is_same_v<remove_cvref_t<U>, in_place_t> is false; and
 // - is_same_v<expected, remove_cvref_t<U>> is false; and
+// - is_same_v<remove_cvref_t<U>, unexpect_t> is false; and
 // - remove_cvref_t<U> is not a specialization of unexpected; and
 // - is_constructible_v<T, U> is true.
 //
@@ -46,6 +47,16 @@ static_assert(!std::is_constructible_v<std::expected<FromJustInplace, int>, std:
 // Note that result is true because it is covered by the constructors that take expected
 static_assert(std::is_constructible_v<std::expected<int, int>, std::expected<int, int>&>);
 
+struct T {
+  explicit T(auto) {}
+};
+struct E {
+  E(int) {}
+};
+
+// is_same_v<remove_cvref_t<U>, unexpect_t> is false;
+static_assert(!std::is_constructible_v<std::expected<T, E>, std::unexpect_t>);
+
 // remove_cvref_t<U> is a specialization of unexpected
 // Note that result is true because it is covered by the constructors that take unexpected
 static_assert(std::is_constructible_v<std::expected<int, int>, std::unexpected<int>&>);


        


More information about the libcxx-commits mailing list