diff options
author | Yihan Wang <yronglin777@gmail.com> | 2025-08-16 16:43:05 +0800 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2025-09-03 19:12:15 +0100 |
commit | 589f3cd1831446485a6c602578177f5d9794d936 (patch) | |
tree | fe745bbdd7e549359a73b301d1df4d6d20000304 | |
parent | b790606e492d33e0cdb8159e38cb148d3526071b (diff) | |
download | gcc-589f3cd1831446485a6c602578177f5d9794d936.zip gcc-589f3cd1831446485a6c602578177f5d9794d936.tar.gz gcc-589f3cd1831446485a6c602578177f5d9794d936.tar.bz2 |
libstdc++: Implement LWG4222 'expected' constructor from a single value missing a constraint
libstdc++-v3/ChangeLog:
* include/std/expected (expected(U&&)): Add missing constraint
as per LWG 4222.
* testsuite/20_util/expected/lwg4222.cc: New test.
Signed-off-by: Yihan Wang <yronglin777@gmail.com>
-rw-r--r-- | libstdc++-v3/include/std/expected | 1 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/20_util/expected/lwg4222.cc | 39 |
2 files changed, 40 insertions, 0 deletions
diff --git a/libstdc++-v3/include/std/expected b/libstdc++-v3/include/std/expected index 60f1565..4eaaab6 100644 --- a/libstdc++-v3/include/std/expected +++ b/libstdc++-v3/include/std/expected @@ -474,6 +474,7 @@ namespace __expected template<typename _Up = remove_cv_t<_Tp>> requires (!is_same_v<remove_cvref_t<_Up>, expected>) && (!is_same_v<remove_cvref_t<_Up>, in_place_t>) + && (!is_same_v<remove_cvref_t<_Up>, unexpect_t>) && is_constructible_v<_Tp, _Up> && (!__expected::__is_unexpected<remove_cvref_t<_Up>>) && __expected::__not_constructing_bool_from_expected<_Tp, _Up> diff --git a/libstdc++-v3/testsuite/20_util/expected/lwg4222.cc b/libstdc++-v3/testsuite/20_util/expected/lwg4222.cc new file mode 100644 index 0000000..5c10779 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/expected/lwg4222.cc @@ -0,0 +1,39 @@ +// { dg-do run { target c++23 } } + +// LWG 4222. 'expected' constructor from a single value missing a constraint + +#include <expected> +#include <type_traits> +#include <testsuite_hooks.h> + +struct T { + explicit T(auto) {} +}; +struct E { + E(int) {} +}; + +struct V { + explicit constexpr V(std::unexpect_t) {} +}; + +static_assert(!std::is_constructible_v<std::expected<T, E>, std::unexpect_t>); +static_assert(!std::is_constructible_v<std::expected<T, E>, std::unexpect_t &>); +static_assert(!std::is_constructible_v<std::expected<T, E>, std::unexpect_t &&>); +static_assert(!std::is_constructible_v<std::expected<T, E>, const std::unexpect_t>); +static_assert(!std::is_constructible_v<std::expected<T, E>, const std::unexpect_t &>); +static_assert(!std::is_constructible_v<std::expected<T, E>, const std::unexpect_t &&>); + +constexpr bool test() { + std::expected<V, int> e1(std::in_place, std::unexpect); + VERIFY( e1.has_value() ); + std::expected<int, V> e2(std::unexpect, std::unexpect); + VERIFY( !e2.has_value() ); + return true; +} + +int main() { + test(); + static_assert(test()); + return 0; +} |