Implement resolution of LWG-3449 for take_view (#1457)

Co-authored-by: Casey Carter <cacarter@microsoft.com>
Co-authored-by: Stephan T. Lavavej <stl@microsoft.com>
This commit is contained in:
Michael Schellenberger Costa 2020-12-17 01:19:18 +01:00 коммит произвёл GitHub
Родитель 4bee6b7b75
Коммит d01fd4b73b
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
2 изменённых файлов: 39 добавлений и 17 удалений

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

@ -1515,9 +1515,12 @@ namespace ranges {
template <bool, bool>
friend class _Sentinel;
using _Base_Ty = _Maybe_const<_Const, _Vw>;
using _Base_sentinel = _Maybe_wrapped<_Wrapped, sentinel_t<_Base_Ty>>;
using _Counted_Iter = counted_iterator<_Maybe_wrapped<_Wrapped, iterator_t<_Base_Ty>>>;
using _Base_t = _Maybe_const<_Const, _Vw>;
using _Base_sentinel = _Maybe_wrapped<_Wrapped, sentinel_t<_Base_t>>;
template <bool _OtherConst>
using _Base_iterator = _Maybe_wrapped<_Wrapped, iterator_t<_Maybe_const<_OtherConst, _Vw>>>;
template <bool _OtherConst>
using _Counted_iter = counted_iterator<_Base_iterator<_OtherConst>>;
_Base_sentinel _Last{};
@ -1540,7 +1543,16 @@ namespace ranges {
return _Last;
}
_NODISCARD friend constexpr bool operator==(const _Counted_Iter& _Left, const _Sentinel& _Right) {
_NODISCARD friend constexpr bool operator==(const _Counted_iter<_Const>& _Left, const _Sentinel& _Right) {
return _Left.count() == 0 || _Left.base() == _Right._Last;
}
// clang-format off
template <bool _OtherConst = _Const>
requires sentinel_for<_Base_sentinel, _Base_iterator<_OtherConst>>
_NODISCARD friend constexpr bool operator==(
const _Counted_iter<_OtherConst>& _Left, const _Sentinel& _Right) {
// clang-format on
return _Left.count() == 0 || _Left.base() == _Right._Last;
}
@ -1548,17 +1560,17 @@ namespace ranges {
// clang-format off
_NODISCARD constexpr auto _Unwrapped() const&
requires _Wrapped && _Unwrappable_v<const iterator_t<_Base_Ty>&> {
requires _Wrapped && _Unwrappable_v<const iterator_t<_Base_t>&> {
// clang-format on
return _Sentinel<_Const, false>{_Get_unwrapped(_Last)};
}
// clang-format off
_NODISCARD constexpr auto _Unwrapped() && requires _Wrapped && _Unwrappable_v<iterator_t<_Base_Ty>> {
_NODISCARD constexpr auto _Unwrapped() && requires _Wrapped && _Unwrappable_v<iterator_t<_Base_t>> {
// clang-format on
return _Sentinel<_Const, false>{_Get_unwrapped(_STD move(_Last))};
}
static constexpr bool _Unwrap_when_unverified = _Do_unwrap_when_unverified_v<iterator_t<_Base_Ty>>;
static constexpr bool _Unwrap_when_unverified = _Do_unwrap_when_unverified_v<iterator_t<_Base_t>>;
constexpr void _Seek_to(const _Sentinel<_Const, false>& _That) requires _Wrapped {
_Seek_wrapped(_Last, _That._Last);
@ -1753,9 +1765,9 @@ namespace ranges {
template <bool, bool>
friend class _Sentinel;
using _Base_Ty = _Maybe_const<_Const, _Vw>;
using _Base_iterator = _Maybe_wrapped<_Wrapped, iterator_t<_Base_Ty>>;
using _Base_sentinel = _Maybe_wrapped<_Wrapped, sentinel_t<_Base_Ty>>;
using _Base_t = _Maybe_const<_Const, _Vw>;
using _Base_iterator = _Maybe_wrapped<_Wrapped, iterator_t<_Base_t>>;
using _Base_sentinel = _Maybe_wrapped<_Wrapped, sentinel_t<_Base_t>>;
template <bool _OtherConst>
using _Maybe_const_iter = _Maybe_wrapped<_Wrapped, iterator_t<_Maybe_const<_OtherConst, _Vw>>>;
@ -1799,17 +1811,17 @@ namespace ranges {
// clang-format off
_NODISCARD constexpr auto _Unwrapped() const&
requires _Wrapped && _Unwrappable_v<const iterator_t<_Base_Ty>&> {
requires _Wrapped && _Unwrappable_v<const iterator_t<_Base_t>&> {
// clang-format on
return _Sentinel<_Const, false>{_Get_unwrapped(_Last), _Pred};
}
// clang-format off
_NODISCARD constexpr auto _Unwrapped() && requires _Wrapped && _Unwrappable_v<iterator_t<_Base_Ty>> {
_NODISCARD constexpr auto _Unwrapped() && requires _Wrapped && _Unwrappable_v<iterator_t<_Base_t>> {
// clang-format on
return _Sentinel<_Const, false>{_Get_unwrapped(_STD move(_Last)), _Pred};
}
static constexpr bool _Unwrap_when_unverified = _Do_unwrap_when_unverified_v<iterator_t<_Base_Ty>>;
static constexpr bool _Unwrap_when_unverified = _Do_unwrap_when_unverified_v<iterator_t<_Base_t>>;
constexpr void _Seek_to(const _Sentinel<_Const, false>& _That) requires _Wrapped {
_Seek_wrapped(_Last, _That._Last);

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

@ -282,15 +282,25 @@ constexpr bool test_one(Rng&& rng, Expected&& expected) {
}
STATIC_ASSERT(CanEnd<const R&> == range<const V>);
if (!is_empty) {
same_as<sentinel_t<R>> auto i = r.end();
same_as<sentinel_t<R>> auto s = r.end();
if constexpr (bidirectional_range<R> && common_range<R>) {
assert(*prev(i) == *prev(end(expected)));
assert(*prev(s) == *prev(end(expected)));
}
if constexpr (range<const V>) {
same_as<sentinel_t<const R>> auto i2 = as_const(r).end();
same_as<sentinel_t<const R>> auto sc = as_const(r).end();
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);
}
}
}