[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@gmail.com>
This commit is contained in:
yronglin 2025-08-10 01:11:20 +08:00 committed by GitHub
parent 870aa979c4
commit 24b772769f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 14 additions and 2 deletions

View File

@ -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)","","",""

1 Issue # Issue Name Meeting Status First released version Notes
132 `LWG4200 <https://wg21.link/LWG4200>`__ The ``operation_state`` concept can be simplified 2025-06 (Sofia)
133 `LWG4201 <https://wg21.link/LWG4201>`__ ``with-await-transform::await_transform`` should not use a deduced return type 2025-06 (Sofia)
134 `LWG4217 <https://wg21.link/LWG4217>`__ Clarify ``mdspan`` layout mapping requirements for ``rank == 0`` 2025-06 (Sofia)
135 `LWG4222 <https://wg21.link/LWG4222>`__ ``expected`` constructor from a single value missing a constraint 2025-06 (Sofia) |Complete| 22
136 `LWG4224 <https://wg21.link/LWG4224>`__ Philox engines should be freestanding 2025-06 (Sofia)
137 `LWG4227 <https://wg21.link/LWG4227>`__ Missing ``noexcept`` operator in [exec.when.all] 2025-06 (Sofia)
138 `LWG4231 <https://wg21.link/LWG4231>`__ ``datapar::chunk<N>`` should use ``simd-size-type`` instead of ``size_t`` 2025-06 (Sofia)

View File

@ -557,7 +557,8 @@ public:
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

View File

@ -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>&>);