On Mon, Mar 16, 2026 at 12:07 PM Jonathan Wakely <[email protected]> wrote:

> On Mon, 16 Mar 2026 at 07:53, Tomasz Kaminski <[email protected]> wrote:
> >
> >
> >
> > On Mon, Mar 16, 2026 at 8:33 AM Jonathan Wakely <[email protected]>
> wrote:
> >>
> >>
> >>
> >> On Thu, 12 Mar 2026, 15:59 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.
> >>
> >>
> >> The tests passed but I forgot to check that Clang allows auto(x) in
> C++20 mode. I'll check they before pushing.
> >
> > clang-22 rejects it (https://godbolt.org/z/bY1Gs8xsj), so we will need
> to do something like, like
> > auto __dfirst = __first;
> > return __last - __difrst;
>
> Actually we might as well just use decay_t<I> exactly as the issue
> resolution shows, because we already instantiated decay_t<I> for the
> constraints:
>
> template<class I, sized_sentinel_for<decay_t<I>> S>
>
> So we aren't optimizing anything by avoiding it in the function body.
>
Good catch, makes sense.

>
>
> >>
> >>
> >>
> >>
> >>>
> >>>  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