On Tue, Mar 25, 2025 at 1:43 PM Jonathan Wakely <jwak...@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 > >