`ranges::distance` fails to emulate the Standard's two overload presentation (#2987)

Co-authored-by: Nicole Mazzuca <mazzucan@outlook.com>
Co-authored-by: Stephan T. Lavavej <stl@nuwen.net>
This commit is contained in:
Casey Carter 2022-08-26 17:21:59 -07:00 коммит произвёл GitHub
Родитель 04e304b147
Коммит 7cdd700459
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
2 изменённых файлов: 14 добавлений и 18 удалений

Просмотреть файл

@ -2569,16 +2569,19 @@ namespace ranges {
public:
using _Not_quite_object::_Not_quite_object;
template <class _It, sentinel_for<decay_t<_It>> _Se>
_NODISCARD constexpr iter_difference_t<decay_t<_It>> operator()(_It&& _Raw_first, _Se _Last) const
noexcept(_Nothrow_dist<_It, _Se>) /* strengthened */ {
if constexpr (sized_sentinel_for<_Se, decay_t<_It>>) {
return _Last - static_cast<const decay_t<_It>&>(_Raw_first); // Per LWG-3664
} else {
auto _First = _STD forward<_It>(_Raw_first);
_Adl_verify_range(_First, _Last);
return _Distance_unchecked(_Get_unwrapped(_STD move(_First)), _Get_unwrapped(_STD move(_Last)));
}
template <class _It, sentinel_for<_It> _Se>
requires(!sized_sentinel_for<_Se, _It>)
_NODISCARD constexpr iter_difference_t<_It> operator()(_It _First, _Se _Last) const
noexcept(noexcept(_Distance_unchecked(_Get_unwrapped(_STD move(_First)),
_Get_unwrapped(_STD move(_Last))))) /* strengthened */ { // Per LWG-3664
_Adl_verify_range(_First, _Last);
return _Distance_unchecked(_Get_unwrapped(_STD move(_First)), _Get_unwrapped(_STD move(_Last)));
}
template <class _It, sized_sentinel_for<decay_t<_It>> _Se>
_NODISCARD constexpr iter_difference_t<decay_t<_It>> operator()(_It&& _First, const _Se _Last) const
noexcept(noexcept(_Last - static_cast<const decay_t<_It>&>(_First))) /* strengthened */ { // Per LWG-3664
return _Last - static_cast<const decay_t<_It>&>(_First);
}
template <range _Rng>
@ -2592,13 +2595,6 @@ namespace ranges {
}
private:
template <class _It, class _Se>
static constexpr bool _Nothrow_dist = false;
template <class _It, sized_sentinel_for<decay_t<_It>> _Se>
static constexpr bool _Nothrow_dist<_It, _Se> = noexcept(
_STD declval<_Se&>() - _STD declval<const decay_t<_It>&>());
template <class _It, class _Se>
_NODISCARD static constexpr iter_difference_t<_It> _Distance_unchecked(_It _First, const _Se _Last) noexcept(
noexcept(++_First != _Last)) {

Просмотреть файл

@ -2959,7 +2959,7 @@ namespace iter_ops {
trace t{};
I first{t};
same_as<iter_difference_t<I>> auto const result = distance(move(first), default_sentinel);
STATIC_ASSERT(!noexcept(distance(move(first), default_sentinel))); // No conditional noexcept
STATIC_ASSERT(noexcept(distance(move(first), default_sentinel)));
assert(result == sentinel_position);
assert((t == trace{.compares_ = sentinel_position + 1, .increments_ = sentinel_position}));
}