]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
libstdc++: Allow std::ranges::to to create unions
authorJonathan Wakely <jwakely@redhat.com>
Tue, 25 Mar 2025 00:27:52 +0000 (00:27 +0000)
committerJonathan Wakely <redi@gcc.gnu.org>
Wed, 26 Mar 2025 14:41:23 +0000 (14:41 +0000)
LWG 4229 points out that the std::ranges::to wording refers to class
types, but I added an assertion using std::is_class_v which only allows
non-union class types. LWG consensus is that unions should be allowed,
so this additionally uses std::is_union_v.

libstdc++-v3/ChangeLog:

* include/std/ranges (ranges::to): Allow unions as well as
non-union class types.
* testsuite/std/ranges/conv/lwg4229.cc: New test.

Reviewed-by: Tomasz KamiƄski <tkaminsk@redhat.com>
(cherry picked from commit 479a0a8644e5efa0470f032be21ca7749968af42)

libstdc++-v3/include/std/ranges
libstdc++-v3/testsuite/std/ranges/conv/lwg4229.cc [new file with mode: 0644]

index ede042c54fc4d248c7329db550aae5b09906d2c1..fdfecf3527fed6d0dac20103c6f2df61ed8c3c0c 100644 (file)
@@ -9388,7 +9388,7 @@ namespace __detail
     to [[nodiscard]] (_Rg&& __r, _Args&&... __args)
     {
       static_assert(!is_const_v<_Cont> && !is_volatile_v<_Cont>);
-      static_assert(is_class_v<_Cont>);
+      static_assert(is_class_v<_Cont> || is_union_v<_Cont>);
 
       if constexpr (__detail::__toable<_Cont, _Rg>)
        {
@@ -9547,7 +9547,7 @@ namespace __detail
     to [[nodiscard]] (_Args&&... __args)
     {
       static_assert(!is_const_v<_Cont> && !is_volatile_v<_Cont>);
-      static_assert(is_class_v<_Cont>);
+      static_assert(is_class_v<_Cont> || is_union_v<_Cont>);
 
       using __detail::_To;
       using views::__adaptor::_Partial;
diff --git a/libstdc++-v3/testsuite/std/ranges/conv/lwg4229.cc b/libstdc++-v3/testsuite/std/ranges/conv/lwg4229.cc
new file mode 100644 (file)
index 0000000..780ed1f
--- /dev/null
@@ -0,0 +1,18 @@
+// { dg-do compile { target c++23 } }
+
+// LWG 4229 std::ranges::to with union return type
+
+#include <ranges>
+
+union U
+{
+  template<std::ranges::input_range R> U(std::from_range_t, R&&) { }
+
+  int i;
+};
+
+void
+test_lwg4229(std::ranges::subrange<int*> r)
+{
+  U u = std::ranges::to<U>(r);
+}