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 <jwakely@redhat.com>
This commit is contained in:
Patrick Palka 2024-10-05 13:48:06 -04:00
parent a8e6360765
commit 7c0d1e9f2a
2 changed files with 18 additions and 7 deletions

View file

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

View file

@ -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();
}