Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 25 additions & 13 deletions stl/inc/ranges
Original file line number Diff line number Diff line change
Expand Up @@ -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{};

Expand All @@ -1540,25 +1543,34 @@ 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;
}

using _Prevent_inheriting_unwrap = _Sentinel;

// 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);
Expand Down Expand Up @@ -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>>>;
Expand Down Expand Up @@ -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);
Expand Down
18 changes: 14 additions & 4 deletions tests/std/tests/P0896R4_views_take/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
}
Expand Down