On Thu, 27 Feb 2025, Jonathan Wakely wrote:

> The standard requires that we reject attempts to create a ranges::to
> adaptor for cv-qualified types and non-class types. Currently we only
> diagnose it once the adaptor is used in a pipeline.
> 
> This adds static assertions to diagnose it immediately.
> 
> libstdc++-v3/ChangeLog:
> 
>       PR libstdc++/112803
>       * include/std/ranges (ranges::to): Add static assertions to
>       enforce Mandates conditions.
>       * testsuite/std/ranges/conv/112803.cc: New test.

LGTM

> ---
> 
> Tested x86_64-linux.
> 
>  libstdc++-v3/include/std/ranges               |  3 +++
>  .../testsuite/std/ranges/conv/112803.cc       | 20 +++++++++++++++++++
>  2 files changed, 23 insertions(+)
>  create mode 100644 libstdc++-v3/testsuite/std/ranges/conv/112803.cc
> 
> diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges
> index 6c65722b687..c0b1134ab32 100644
> --- a/libstdc++-v3/include/std/ranges
> +++ b/libstdc++-v3/include/std/ranges
> @@ -9569,6 +9569,9 @@ namespace __detail
>      constexpr auto
>      to [[nodiscard]] (_Args&&... __args)
>      {
> +      static_assert(!is_const_v<_Cont> && !is_volatile_v<_Cont>);
> +      static_assert(is_class_v<_Cont>);
> +
>        using __detail::_To;
>        using views::__adaptor::_Partial;
>        return _Partial<_To<_Cont>, decay_t<_Args>...>{0, 
> std::forward<_Args>(__args)...};
> diff --git a/libstdc++-v3/testsuite/std/ranges/conv/112803.cc 
> b/libstdc++-v3/testsuite/std/ranges/conv/112803.cc
> new file mode 100644
> index 00000000000..0a73b0200b0
> --- /dev/null
> +++ b/libstdc++-v3/testsuite/std/ranges/conv/112803.cc
> @@ -0,0 +1,20 @@
> +// { dg-do compile { target c++23 } }
> +
> +// Bug 112803 - <ranges>: to(Args&&... args) is missing Mandates
> +
> +#include <ranges>
> +
> +void
> +test()
> +{
> +  struct C { };
> +
> +  (void) std::ranges::to<int>(); // { dg-error "here" }
> +  (void) std::ranges::to<C*>(); // { dg-error "here" }
> +  (void) std::ranges::to<C&>(); // { dg-error "here" }
> +  (void) std::ranges::to<const C>(); // { dg-error "here" }
> +  (void) std::ranges::to<volatile C>(); // { dg-error "here" }
> +  (void) std::ranges::to<const volatile C>(); // { dg-error "here" }
> +}
> +
> +// { dg-error "static assertion failed" "" { target *-*-* } 0 }
> -- 
> 2.48.1
> 
> 

Reply via email to