зеркало из https://github.com/microsoft/STL.git
LWG-3448 transform_view's sentinel<false> not comparable with iterator<true> (#1458)
Co-authored-by: Stephan T. Lavavej <stl@microsoft.com> Co-authored-by: Casey Carter <cartec69@gmail.com>
This commit is contained in:
Родитель
2aa944beba
Коммит
8516f91a7a
|
@ -1426,26 +1426,19 @@ namespace ranges {
|
|||
|
||||
using _Parent_t = _Maybe_const<_Const, transform_view>;
|
||||
using _Base = _Maybe_const<_Const, _Vw>;
|
||||
template <bool _OtherConst>
|
||||
using _Maybe_const_iter = iterator_t<_Maybe_const<_OtherConst, _Vw>>;
|
||||
|
||||
sentinel_t<_Base> _Last{};
|
||||
|
||||
_NODISCARD constexpr bool _Equal(const _Iterator<_Const>& _It) const
|
||||
noexcept(noexcept(_It._Current == _Last)) {
|
||||
template <bool _OtherConst>
|
||||
_NODISCARD static constexpr const _Maybe_const_iter<_OtherConst>& _Get_current(
|
||||
const _Iterator<_OtherConst>& _It) noexcept {
|
||||
#if _ITERATOR_DEBUG_LEVEL != 0
|
||||
_STL_VERIFY(
|
||||
_It._Parent != nullptr, "cannot compare transform_view sentinel with value-initialized iterator");
|
||||
#endif // _ITERATOR_DEBUG_LEVEL != 0
|
||||
return _It._Current == _Last;
|
||||
}
|
||||
|
||||
_NODISCARD constexpr range_difference_t<_Base> _Distance_to(const _Iterator<_Const>& _It) const
|
||||
noexcept(noexcept(_It._Current - _Last)) {
|
||||
_STL_INTERNAL_STATIC_ASSERT(sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>);
|
||||
#if _ITERATOR_DEBUG_LEVEL != 0
|
||||
_STL_VERIFY(
|
||||
_It._Parent != nullptr, "cannot compare transform_view sentinel with value-initialized iterator");
|
||||
#endif // _ITERATOR_DEBUG_LEVEL != 0
|
||||
return _It._Current - _Last;
|
||||
return _It._Current;
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -1466,22 +1459,30 @@ namespace ranges {
|
|||
return _Last;
|
||||
}
|
||||
|
||||
_NODISCARD friend constexpr bool operator==(const _Iterator<_Const>& _Left,
|
||||
const _Sentinel& _Right) noexcept(noexcept(_Right._Equal(_Left))) /* strengthened */ {
|
||||
return _Right._Equal(_Left);
|
||||
// clang-format off
|
||||
template <bool _OtherConst>
|
||||
requires sentinel_for<sentinel_t<_Base>, _Maybe_const_iter<_OtherConst>>
|
||||
_NODISCARD friend constexpr bool operator==(const _Iterator<_OtherConst>& _Left,
|
||||
const _Sentinel& _Right) noexcept(noexcept(_Get_current(_Left) == _Right._Last)) /* strengthened */ {
|
||||
return _Get_current(_Left) == _Right._Last;
|
||||
}
|
||||
|
||||
_NODISCARD friend constexpr range_difference_t<_Base>
|
||||
operator-(const _Iterator<_Const>& _Left, const _Sentinel& _Right) noexcept(
|
||||
noexcept(_Right._Distance_to(
|
||||
_Left))) /* strengthened */ requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>> {
|
||||
return _Right._Distance_to(_Left);
|
||||
template <bool _OtherConst>
|
||||
requires sized_sentinel_for<sentinel_t<_Base>, _Maybe_const_iter<_OtherConst>>
|
||||
_NODISCARD friend constexpr range_difference_t<_Maybe_const<_OtherConst, _Vw>>
|
||||
operator-(const _Iterator<_OtherConst>& _Left, const _Sentinel& _Right) noexcept(
|
||||
noexcept(_Get_current(_Left) - _Right._Last)) /* strengthened */ {
|
||||
return _Get_current(_Left) - _Right._Last;
|
||||
}
|
||||
_NODISCARD friend constexpr range_difference_t<_Base>
|
||||
operator-(const _Sentinel& _Left, const _Iterator<_Const>& _Right) noexcept(noexcept(_Left._Distance_to(
|
||||
_Right))) /* strengthened */ requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>> {
|
||||
return -_Left._Distance_to(_Right);
|
||||
|
||||
template <bool _OtherConst>
|
||||
requires sized_sentinel_for<sentinel_t<_Base>, _Maybe_const_iter<_OtherConst>>
|
||||
_NODISCARD friend constexpr range_difference_t<_Maybe_const<_OtherConst, _Vw>>
|
||||
operator-(const _Sentinel& _Left, const _Iterator<_OtherConst>& _Right) noexcept(
|
||||
noexcept(_Left._Last - _Get_current(_Right))) /* strengthened */ {
|
||||
return _Left._Last - _Get_current(_Right);
|
||||
}
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
public:
|
||||
|
@ -2836,11 +2837,13 @@ namespace ranges {
|
|||
friend class _Sentinel;
|
||||
|
||||
using _Base = _Maybe_const<_Const, _Vw>;
|
||||
template <bool _OtherConst>
|
||||
using _Maybe_const_iter = iterator_t<_Maybe_const<_OtherConst, _Vw>>;
|
||||
|
||||
sentinel_t<_Base> _Last{};
|
||||
|
||||
template <bool _OtherConst>
|
||||
_NODISCARD static constexpr const iterator_t<_Maybe_const<_OtherConst, _Vw>>& _Get_current(
|
||||
_NODISCARD static constexpr const _Maybe_const_iter<_OtherConst>& _Get_current(
|
||||
const _Iterator<_OtherConst>& _It) noexcept {
|
||||
return _It._Current;
|
||||
}
|
||||
|
@ -2865,7 +2868,7 @@ namespace ranges {
|
|||
|
||||
// clang-format off
|
||||
template <bool _OtherConst>
|
||||
requires sentinel_for<sentinel_t<_Base>, iterator_t<_Maybe_const<_OtherConst, _Vw>>>
|
||||
requires sentinel_for<sentinel_t<_Base>, _Maybe_const_iter<_OtherConst>>
|
||||
_NODISCARD friend constexpr bool operator==(const _Iterator<_OtherConst>& _Left,
|
||||
const _Sentinel& _Right) noexcept(noexcept(_Get_current(_Left) == _Right._Last)) /* strengthened */ {
|
||||
// clang-format on
|
||||
|
@ -2874,7 +2877,7 @@ namespace ranges {
|
|||
|
||||
// clang-format off
|
||||
template <bool _OtherConst>
|
||||
requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Maybe_const<_OtherConst, _Vw>>>
|
||||
requires sized_sentinel_for<sentinel_t<_Base>, _Maybe_const_iter<_OtherConst>>
|
||||
_NODISCARD friend constexpr range_difference_t<_Maybe_const<_OtherConst, _Vw>> operator-(
|
||||
const _Iterator<_OtherConst>& _Left, const _Sentinel& _Right) noexcept(
|
||||
noexcept(_Get_current(_Left) - _Right._Last)) /* strengthened */ {
|
||||
|
@ -2884,7 +2887,7 @@ namespace ranges {
|
|||
|
||||
// clang-format off
|
||||
template <bool _OtherConst>
|
||||
requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Maybe_const<_OtherConst, _Vw>>>
|
||||
requires sized_sentinel_for<sentinel_t<_Base>, _Maybe_const_iter<_OtherConst>>
|
||||
_NODISCARD friend constexpr range_difference_t<_Maybe_const<_OtherConst, _Vw>> operator-(
|
||||
const _Sentinel& _Left, const _Iterator<_OtherConst>& _Right) noexcept(
|
||||
noexcept(_Left._Last - _Get_current(_Right))) /* strengthened */ {
|
||||
|
|
|
@ -241,17 +241,27 @@ constexpr bool test_one(Rng&& rng, Expected&& expected) {
|
|||
STATIC_ASSERT(CanMemberEnd<R>);
|
||||
STATIC_ASSERT(CanEnd<const R&> == (range<const V> && const_invocable));
|
||||
if (!is_empty) {
|
||||
same_as<sentinel_t<R>> auto i = r.end();
|
||||
same_as<sentinel_t<R>> auto s = r.end();
|
||||
static_assert(is_same_v<sentinel_t<R>, iterator_t<R>> == common_range<V>);
|
||||
if constexpr (bidirectional_range<R> && common_range<R>) {
|
||||
assert(*prev(i) == *prev(end(expected)));
|
||||
assert(*prev(s) == *prev(end(expected)));
|
||||
}
|
||||
|
||||
if constexpr (CanEnd<const R&>) {
|
||||
same_as<sentinel_t<const R>> auto i2 = as_const(r).end();
|
||||
same_as<sentinel_t<const R>> auto sc = as_const(r).end();
|
||||
static_assert(is_same_v<sentinel_t<const R>, iterator_t<const R>> == common_range<const V>);
|
||||
if constexpr (bidirectional_range<const R> && common_range<const R>) {
|
||||
assert(*prev(i2) == *prev(end(expected)));
|
||||
assert(*prev(sc) == *prev(end(expected)));
|
||||
}
|
||||
|
||||
if (forward_range<V>) { // intentionally not if constexpr
|
||||
// Compare with const / non-const iterators
|
||||
const same_as<iterator_t<R>> auto i = r.begin();
|
||||
const same_as<iterator_t<const R>> auto ic = as_const(r).begin();
|
||||
assert(s != i);
|
||||
assert(s != ic);
|
||||
assert(sc != i);
|
||||
assert(sc != ic);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -574,27 +584,55 @@ struct iterator_instantiator {
|
|||
const auto first = r.begin();
|
||||
const auto last = r.end();
|
||||
|
||||
const auto const_first = ranges::iterator_t<const R>{first};
|
||||
const auto const_last = ranges::sentinel_t<const R>{last};
|
||||
|
||||
assert(first == first);
|
||||
assert(I{} == I{});
|
||||
STATIC_ASSERT(noexcept(first == first));
|
||||
|
||||
assert(first == const_first);
|
||||
STATIC_ASSERT(noexcept(first == const_first));
|
||||
assert(const_first == first);
|
||||
STATIC_ASSERT(noexcept(const_first == first));
|
||||
|
||||
assert(!(first == last));
|
||||
STATIC_ASSERT(noexcept(first == last));
|
||||
assert(!(last == first));
|
||||
STATIC_ASSERT(noexcept(last == first));
|
||||
|
||||
assert(!(const_first == last));
|
||||
STATIC_ASSERT(noexcept(const_first == last));
|
||||
assert(!(last == const_first));
|
||||
STATIC_ASSERT(noexcept(last == const_first));
|
||||
|
||||
assert(!(first == const_last));
|
||||
STATIC_ASSERT(noexcept(first == const_last));
|
||||
assert(!(const_last == first));
|
||||
STATIC_ASSERT(noexcept(const_last == first));
|
||||
|
||||
assert(!(first != first));
|
||||
assert(!(I{} != I{}));
|
||||
STATIC_ASSERT(noexcept(first != first));
|
||||
|
||||
if constexpr (forward_iterator<Iter>) {
|
||||
const auto final = ranges::next(first, last);
|
||||
const auto final = ranges::next(first, last);
|
||||
const auto const_final = ranges::next(const_first, const_last);
|
||||
assert(!(first == final));
|
||||
assert(first != final);
|
||||
|
||||
assert(last == final);
|
||||
assert(final == last);
|
||||
|
||||
assert(const_last == final);
|
||||
assert(final == const_last);
|
||||
|
||||
assert(last == const_final);
|
||||
assert(const_final == last);
|
||||
|
||||
assert(const_last == const_final);
|
||||
assert(const_final == const_last);
|
||||
|
||||
assert(!(last != final));
|
||||
assert(!(final != last));
|
||||
|
||||
|
@ -611,6 +649,21 @@ struct iterator_instantiator {
|
|||
assert(first - last == -ranges::ssize(mutable_ints));
|
||||
STATIC_ASSERT(noexcept(last - first));
|
||||
STATIC_ASSERT(noexcept(first - last));
|
||||
|
||||
assert(last - const_first == ranges::ssize(mutable_ints));
|
||||
assert(const_first - last == -ranges::ssize(mutable_ints));
|
||||
STATIC_ASSERT(noexcept(last - const_first));
|
||||
STATIC_ASSERT(noexcept(const_first - last));
|
||||
|
||||
assert(const_last - first == ranges::ssize(mutable_ints));
|
||||
assert(first - const_last == -ranges::ssize(mutable_ints));
|
||||
STATIC_ASSERT(noexcept(const_last - first));
|
||||
STATIC_ASSERT(noexcept(first - const_last));
|
||||
|
||||
assert(const_last - const_first == ranges::ssize(mutable_ints));
|
||||
assert(const_first - const_last == -ranges::ssize(mutable_ints));
|
||||
STATIC_ASSERT(noexcept(const_last - const_first));
|
||||
STATIC_ASSERT(noexcept(const_first - const_last));
|
||||
}
|
||||
|
||||
if constexpr (random_access_iterator<Iter>) { // Validate relational operators
|
||||
|
|
Загрузка…
Ссылка в новой задаче