On Thu, Mar 12, 2026 at 4:59 PM Jonathan Wakely <[email protected]> wrote:

> This implements LWG 4242 which was approved in Sofia 2025.
>
> Replace the use of the std::decay_t trait with the C++23 auto(x)
> feature, which avoids instantiating the class template.
>
> libstdc++-v3/ChangeLog:
>
>         * include/bits/ranges_base.h (distance(It&&, Sent)): Decay
>         arrays to pointers, as per LWG 4242.
>         * testsuite/24_iterators/range_operations/lwg4242.cc: New test.
> ---
>
> Lightly tested on x86_64-linux so far, full tests running now.
>
LGTM

>
>  libstdc++-v3/include/bits/ranges_base.h       | 12 ++++++++++-
>  .../24_iterators/range_operations/lwg4242.cc  | 21 +++++++++++++++++++
>  2 files changed, 32 insertions(+), 1 deletion(-)
>  create mode 100644
> libstdc++-v3/testsuite/24_iterators/range_operations/lwg4242.cc
>
> diff --git a/libstdc++-v3/include/bits/ranges_base.h
> b/libstdc++-v3/include/bits/ranges_base.h
> index 6cfa6fb6afe6..609e29175f06 100644
> --- a/libstdc++-v3/include/bits/ranges_base.h
> +++ b/libstdc++-v3/include/bits/ranges_base.h
> @@ -989,7 +989,17 @@ namespace ranges
>        [[nodiscard, __gnu__::__always_inline__]]
>        constexpr iter_difference_t<decay_t<_It>>
>        operator()(_It&& __first, _Sent __last) const
> -      { return __last - static_cast<const decay_t<_It>&>(__first); }
> +      {
> +       // GLIBCXX_RESOLVE_LIB_DEFECTS
> +       // 4242. ranges::distance does not work with volatile iterators
> +       if constexpr (!is_array_v<remove_reference_t<_It>>)
> +         return __last - __first;
> +       else
> +#pragma GCC diagnostic push
> +#pragma GCC diagnostic ignored "-Wc++23-extensions" // auto(x)
> +         return __last - auto(__first);
> +#pragma GCC diagnostic pop
> +      }
>
>      template<range _Range>
>        [[nodiscard, __gnu__::__always_inline__]]
> diff --git
> a/libstdc++-v3/testsuite/24_iterators/range_operations/lwg4242.cc
> b/libstdc++-v3/testsuite/24_iterators/range_operations/lwg4242.cc
> new file mode 100644
> index 000000000000..ec03be42cbab
> --- /dev/null
> +++ b/libstdc++-v3/testsuite/24_iterators/range_operations/lwg4242.cc
> @@ -0,0 +1,21 @@
> +// { dg-do run { target c++20 } }
> +
> +// LWG 4242. ranges::distance does not work with volatile iterators
> +
> +#include <iterator>
> +#include <testsuite_hooks.h>
> +
> +void
> +test_lwg4242()
> +{
> +  int arr[] = {1, 2, 3};
> +  int* volatile ptr = arr;
> +  auto d1 = std::distance(ptr, arr + 3);
> +  auto d2 = std::ranges::distance(ptr, arr + 3);
> +  VERIFY( d1 == d2 );
> +}
> +
> +int main()
> +{
> +  test_lwg4242();
> +}
> --
> 2.53.0
>
>

Reply via email to