[gcc r14-11999] libstdc++: Implement LWG4222 'expected' constructor from a single value missing a constraint
Jonathan Wakely
redi@gcc.gnu.org
Thu Sep 4 12:28:39 GMT 2025
https://gcc.gnu.org/g:2d0ed37e2e816861780a0c0922dd888c77ad6fee
commit r14-11999-g2d0ed37e2e816861780a0c0922dd888c77ad6fee
Author: Yihan Wang <yronglin777@gmail.com>
Date: Sat Aug 16 16:43:05 2025 +0800
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>
(cherry picked from commit 589f3cd1831446485a6c602578177f5d9794d936)
Diff:
---
libstdc++-v3/include/std/expected | 1 +
libstdc++-v3/testsuite/20_util/expected/lwg4222.cc | 39 ++++++++++++++++++++++
2 files changed, 40 insertions(+)
diff --git a/libstdc++-v3/include/std/expected b/libstdc++-v3/include/std/expected
index 2594cfe131c0..b0a5423f1935 100644
--- a/libstdc++-v3/include/std/expected
+++ b/libstdc++-v3/include/std/expected
@@ -471,6 +471,7 @@ namespace __expected
template<typename _Up = _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 000000000000..5c107792456b
--- /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;
+}
More information about the Libstdc++-cvs
mailing list