diff mbox series

libstdc++: Allow std::ranges::to to create unions

Message ID 20250325124138.207138-1-jwakely@redhat.com
State New
Headers show
Series libstdc++: Allow std::ranges::to to create unions | expand

Commit Message

Jonathan Wakely March 25, 2025, 12:35 p.m. UTC
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.
---

Tested x86_64-linux.

 libstdc++-v3/include/std/ranges                |  4 ++--
 .../testsuite/std/ranges/conv/lwg4229.cc       | 18 ++++++++++++++++++
 2 files changed, 20 insertions(+), 2 deletions(-)
 create mode 100644 libstdc++-v3/testsuite/std/ranges/conv/lwg4229.cc

Comments

Tomasz Kaminski March 25, 2025, 4 p.m. UTC | #1
On Tue, Mar 25, 2025 at 1:43 PM Jonathan Wakely <jwakely@redhat.com> wrote:

> 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.
> ---
>
> Tested x86_64-linux.
>
LGTM. I still do not have any real case for using ranges::to with unions,
but consensus seems to be to allow them.

>
>  libstdc++-v3/include/std/ranges                |  4 ++--
>  .../testsuite/std/ranges/conv/lwg4229.cc       | 18 ++++++++++++++++++
>  2 files changed, 20 insertions(+), 2 deletions(-)
>  create mode 100644 libstdc++-v3/testsuite/std/ranges/conv/lwg4229.cc
>
> diff --git a/libstdc++-v3/include/std/ranges
> b/libstdc++-v3/include/std/ranges
> index 34c6f113e21..7a339c51368 100644
> --- a/libstdc++-v3/include/std/ranges
> +++ b/libstdc++-v3/include/std/ranges
> @@ -9421,7 +9421,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>)
>         {
> @@ -9580,7 +9580,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
> index 00000000000..780ed1fd932
> --- /dev/null
> +++ b/libstdc++-v3/testsuite/std/ranges/conv/lwg4229.cc
> @@ -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);
> +}
> --
> 2.49.0
>
>
diff mbox series

Patch

diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges
index 34c6f113e21..7a339c51368 100644
--- a/libstdc++-v3/include/std/ranges
+++ b/libstdc++-v3/include/std/ranges
@@ -9421,7 +9421,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>)
 	{
@@ -9580,7 +9580,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
index 00000000000..780ed1fd932
--- /dev/null
+++ b/libstdc++-v3/testsuite/std/ranges/conv/lwg4229.cc
@@ -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);
+}