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.


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