[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