https://gcc.gnu.org/g:7c0d1e9f2a2f1d41d9eb755c36c871d92638c4b7
commit r15-4086-g7c0d1e9f2a2f1d41d9eb755c36c871d92638c4b7 Author: Patrick Palka <ppa...@redhat.com> Date: Sat Oct 5 13:48:06 2024 -0400 libstdc++: Implement LWG 3664 changes to ranges::distance libstdc++-v3/ChangeLog: * include/bits/ranges_base.h (__distance_fn::operator()): Adjust iterator/sentinel overloads as per LWG 3664. * testsuite/24_iterators/range_operations/distance.cc: Test LWG 3664 example. Reviewed-by: Jonathan Wakely <jwak...@redhat.com> Diff: --- libstdc++-v3/include/bits/ranges_base.h | 14 +++++++------- .../testsuite/24_iterators/range_operations/distance.cc | 11 +++++++++++ 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/libstdc++-v3/include/bits/ranges_base.h b/libstdc++-v3/include/bits/ranges_base.h index 137c3c98e146..cb2eba1f841a 100644 --- a/libstdc++-v3/include/bits/ranges_base.h +++ b/libstdc++-v3/include/bits/ranges_base.h @@ -947,7 +947,9 @@ namespace ranges struct __distance_fn final { - template<input_or_output_iterator _It, sentinel_for<_It> _Sent> + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 3664. LWG 3392 broke std::ranges::distance(a, a+3) + template<typename _It, sentinel_for<_It> _Sent> requires (!sized_sentinel_for<_Sent, _It>) constexpr iter_difference_t<_It> operator()[[nodiscard]](_It __first, _Sent __last) const @@ -961,13 +963,11 @@ namespace ranges return __n; } - template<input_or_output_iterator _It, sized_sentinel_for<_It> _Sent> + template<typename _It, sized_sentinel_for<decay_t<_It>> _Sent> [[nodiscard]] - constexpr iter_difference_t<_It> - operator()(const _It& __first, const _Sent& __last) const - { - return __last - __first; - } + constexpr iter_difference_t<decay_t<_It>> + operator()(_It&& __first, _Sent __last) const + { return __last - static_cast<const decay_t<_It>&>(__first); } template<range _Range> [[nodiscard]] diff --git a/libstdc++-v3/testsuite/24_iterators/range_operations/distance.cc b/libstdc++-v3/testsuite/24_iterators/range_operations/distance.cc index 9a1d0c3efe83..336956936c22 100644 --- a/libstdc++-v3/testsuite/24_iterators/range_operations/distance.cc +++ b/libstdc++-v3/testsuite/24_iterators/range_operations/distance.cc @@ -144,6 +144,16 @@ test05() VERIFY( std::ranges::distance(c4) == 5 ); } +void +test06() +{ + // LWG 3664 - LWG 3392 broke std::ranges::distance(a, a+3) + int a[] = {1, 2, 3}; + VERIFY( std::ranges::distance(a, a+3) == 3 ); + VERIFY( std::ranges::distance(a, a) == 0 ); + VERIFY( std::ranges::distance(a+3, a) == -3 ); +} + int main() { @@ -152,4 +162,5 @@ main() test03(); test04(); test05(); + test06(); }