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