libstdc++: ranges::find needs explicit conversion to size_t [PR115799]
For an integer-class type we need to use an explicit conversion to size_t. libstdc++-v3/ChangeLog: PR libstdc++/115799 * include/bits/ranges_util.h (__find_fn): Make conversion from difference type ti size_t explicit. * testsuite/25_algorithms/find/bytes.cc: Check ranges::find with __gnu_test::test_contiguous_range. * testsuite/std/ranges/range.cc: Adjust expected difference_type for __gnu_test::test_contiguous_range. * testsuite/util/testsuite_iterators.h (contiguous_iterator_wrapper): Use __max_diff_type as difference type. (test_range::sentinel, test_sized_range_sized_sent::sentinel): Ensure that operator- returns difference_type.
This commit is contained in:
parent
aae535f3a8
commit
cda469a59e
4 changed files with 48 additions and 12 deletions
|
@ -506,9 +506,10 @@ namespace ranges
|
|||
if (static_cast<_Vt>(__value) == __value) [[likely]]
|
||||
if (__n > 0)
|
||||
{
|
||||
const size_t __nu = static_cast<size_t>(__n);
|
||||
const int __ival = static_cast<int>(__value);
|
||||
const void* __p0 = std::to_address(__first);
|
||||
if (auto __p1 = __builtin_memchr(__p0, __ival, __n))
|
||||
if (auto __p1 = __builtin_memchr(__p0, __ival, __nu))
|
||||
__n = (const char*)__p1 - (const char*)__p0;
|
||||
}
|
||||
return __first + __n;
|
||||
|
|
|
@ -114,9 +114,19 @@ test_non_characters()
|
|||
#endif
|
||||
}
|
||||
|
||||
#if __cpp_lib_ranges
|
||||
void
|
||||
test_pr115799c0(__gnu_test::test_contiguous_range<char> r)
|
||||
{
|
||||
// Non-common range with integer-class type as difference_type.
|
||||
(void) std::ranges::find(r, 'a');
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
test_pr115799c2(__gnu_test::input_iterator_wrapper<char> i)
|
||||
{
|
||||
// Non-contiguous range of character type.
|
||||
(void) std::find(i, i, 'a');
|
||||
}
|
||||
|
||||
|
|
|
@ -56,6 +56,7 @@ static_assert( std::ranges::range<test_output_sized_range<int>&> );
|
|||
using std::same_as;
|
||||
|
||||
using C = test_contiguous_range<char>;
|
||||
using R = test_random_access_range<char>;
|
||||
using I = test_input_range<char>;
|
||||
using O = test_output_range<char>;
|
||||
|
||||
|
@ -69,7 +70,9 @@ static_assert( same_as<std::ranges::sentinel_t<C>,
|
|||
static_assert( same_as<std::ranges::sentinel_t<O>,
|
||||
decltype(std::declval<O&>().end())> );
|
||||
|
||||
static_assert( same_as<std::ranges::range_difference_t<C>,
|
||||
static_assert( ! same_as<std::ranges::range_difference_t<C>,
|
||||
std::ptrdiff_t> ); // __detail::__max_diff_type
|
||||
static_assert( same_as<std::ranges::range_difference_t<R>,
|
||||
std::ptrdiff_t> );
|
||||
static_assert( same_as<std::ranges::range_difference_t<O>,
|
||||
std::ptrdiff_t> );
|
||||
|
|
|
@ -34,6 +34,10 @@
|
|||
#include <bits/move.h>
|
||||
#endif
|
||||
|
||||
#if __cplusplus > 201703L
|
||||
#include <bits/max_size_type.h>
|
||||
#endif
|
||||
|
||||
#ifndef _TESTSUITE_ITERATORS
|
||||
#define _TESTSUITE_ITERATORS
|
||||
|
||||
|
@ -675,6 +679,9 @@ namespace __gnu_test
|
|||
|
||||
using iterator_concept = std::contiguous_iterator_tag;
|
||||
|
||||
// Use an integer-class type to try and break the library code.
|
||||
using difference_type = std::ranges::__detail::__max_diff_type;
|
||||
|
||||
contiguous_iterator_wrapper&
|
||||
operator++()
|
||||
{
|
||||
|
@ -706,27 +713,42 @@ namespace __gnu_test
|
|||
}
|
||||
|
||||
contiguous_iterator_wrapper&
|
||||
operator+=(std::ptrdiff_t n)
|
||||
operator+=(difference_type n)
|
||||
{
|
||||
random_access_iterator_wrapper<T>::operator+=(n);
|
||||
auto d = static_cast<std::ptrdiff_t>(n);
|
||||
random_access_iterator_wrapper<T>::operator+=(d);
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend contiguous_iterator_wrapper
|
||||
operator+(contiguous_iterator_wrapper iter, std::ptrdiff_t n)
|
||||
operator+(contiguous_iterator_wrapper iter, difference_type n)
|
||||
{ return iter += n; }
|
||||
|
||||
friend contiguous_iterator_wrapper
|
||||
operator+(std::ptrdiff_t n, contiguous_iterator_wrapper iter)
|
||||
operator+(difference_type n, contiguous_iterator_wrapper iter)
|
||||
{ return iter += n; }
|
||||
|
||||
contiguous_iterator_wrapper&
|
||||
operator-=(std::ptrdiff_t n)
|
||||
operator-=(difference_type n)
|
||||
{ return *this += -n; }
|
||||
|
||||
friend contiguous_iterator_wrapper
|
||||
operator-(contiguous_iterator_wrapper iter, std::ptrdiff_t n)
|
||||
operator-(contiguous_iterator_wrapper iter, difference_type n)
|
||||
{ return iter -= n; }
|
||||
|
||||
friend difference_type
|
||||
operator-(contiguous_iterator_wrapper l, contiguous_iterator_wrapper r)
|
||||
{
|
||||
const random_access_iterator_wrapper<T>& lbase = l;
|
||||
const random_access_iterator_wrapper<T>& rbase = r;
|
||||
return static_cast<difference_type>(lbase - rbase);
|
||||
}
|
||||
|
||||
decltype(auto) operator[](difference_type n) const
|
||||
{
|
||||
auto d = static_cast<std::ptrdiff_t>(n);
|
||||
return random_access_iterator_wrapper<T>::operator[](d);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
|
@ -788,11 +810,11 @@ namespace __gnu_test
|
|||
|
||||
friend auto operator-(const sentinel& s, const I& i) noexcept
|
||||
requires std::random_access_iterator<I>
|
||||
{ return s.end - i.ptr; }
|
||||
{ return std::iter_difference_t<I>(s.end - i.ptr); }
|
||||
|
||||
friend auto operator-(const I& i, const sentinel& s) noexcept
|
||||
requires std::random_access_iterator<I>
|
||||
{ return i.ptr - s.end; }
|
||||
{ return std::iter_difference_t<I>(i.ptr - s.end); }
|
||||
};
|
||||
|
||||
protected:
|
||||
|
@ -890,11 +912,11 @@ namespace __gnu_test
|
|||
|
||||
friend std::iter_difference_t<I>
|
||||
operator-(const sentinel& s, const I& i) noexcept
|
||||
{ return s.end - i.ptr; }
|
||||
{ return std::iter_difference_t<I>(s.end - i.ptr); }
|
||||
|
||||
friend std::iter_difference_t<I>
|
||||
operator-(const I& i, const sentinel& s) noexcept
|
||||
{ return i.ptr - s.end; }
|
||||
{ return std::iter_difference_t<I>(i.ptr - s.end); }
|
||||
};
|
||||
|
||||
auto end() &
|
||||
|
|
Loading…
Add table
Reference in a new issue