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