[libc++] [test] Simplify sentinel_wrapper and sized_sentinel.

Remove `s.base()`; every test that wants to get the base of a "test sentinel"
should use the ADL `base(s)` from now on.

Differential Revision: https://reviews.llvm.org/D115766
This commit is contained in:
Arthur O'Dwyer 2021-10-06 21:23:13 -04:00
parent 209ec8e2ee
commit 2a04decc4a
8 changed files with 25 additions and 92 deletions

View File

@ -66,14 +66,14 @@ int main(int, char**) {
{
SizedForwardView view{buf, buf + 8};
std::ranges::common_view<SizedForwardView> common(view);
using CommonIter = std::common_iterator<ForwardIter, sentinel_wrapper<ForwardIter>>;
using CommonIter = std::common_iterator<ForwardIter, sized_sentinel<ForwardIter>>;
std::same_as<CommonIter> auto begin = common.begin();
assert(begin == std::ranges::begin(view));
}
{
SizedForwardView view{buf, buf + 8};
std::ranges::common_view<SizedForwardView> const common(view);
using CommonIter = std::common_iterator<ForwardIter, sentinel_wrapper<ForwardIter>>;
using CommonIter = std::common_iterator<ForwardIter, sized_sentinel<ForwardIter>>;
std::same_as<CommonIter> auto begin = common.begin();
assert(begin == std::ranges::begin(view));
}

View File

@ -51,7 +51,7 @@ int main(int, char**) {
{
int buf[8] = {1, 2, 3, 4, 5, 6, 7, 8};
using CommonForwardIter = std::common_iterator<ForwardIter, sentinel_wrapper<ForwardIter>>;
using CommonForwardIter = std::common_iterator<ForwardIter, sized_sentinel<ForwardIter>>;
using CommonIntIter = std::common_iterator<int*, sentinel_wrapper<int*>>;
{

View File

@ -52,15 +52,8 @@ struct SizedForwardView : std::ranges::view_base {
int* end_;
constexpr explicit SizedForwardView(int* b, int* e) : begin_(b), end_(e) { }
constexpr auto begin() const { return forward_iterator<int*>(begin_); }
constexpr auto end() const { return sentinel_wrapper<forward_iterator<int*>>(forward_iterator<int*>(end_)); }
constexpr auto end() const { return sized_sentinel<forward_iterator<int*>>(forward_iterator<int*>(end_)); }
};
// Required to make SizedForwardView a sized view.
constexpr auto operator-(sentinel_wrapper<ForwardIter> sent, ForwardIter iter) {
return sent.base().base() - iter.base();
}
constexpr auto operator-(ForwardIter iter, sentinel_wrapper<ForwardIter> sent) {
return iter.base() - sent.base().base();
}
static_assert(std::ranges::view<SizedForwardView>);
static_assert(std::ranges::forward_range<SizedForwardView>);
static_assert(std::ranges::sized_range<SizedForwardView>);
@ -71,15 +64,8 @@ struct SizedRandomAccessView : std::ranges::view_base {
int* end_;
constexpr explicit SizedRandomAccessView(int* b, int* e) : begin_(b), end_(e) { }
constexpr auto begin() const { return random_access_iterator<int*>(begin_); }
constexpr auto end() const { return sentinel_wrapper<random_access_iterator<int*>>(random_access_iterator<int*>(end_)); }
constexpr auto end() const { return sized_sentinel<random_access_iterator<int*>>(random_access_iterator<int*>(end_)); }
};
// Required to make SizedRandomAccessView a sized view.
constexpr auto operator-(sentinel_wrapper<RandomAccessIter> sent, RandomAccessIter iter) {
return sent.base().base() - iter.base();
}
constexpr auto operator-(RandomAccessIter iter, sentinel_wrapper<RandomAccessIter> sent) {
return iter.base() - sent.base().base();
}
static_assert(std::ranges::view<SizedRandomAccessView>);
static_assert(std::ranges::random_access_range<SizedRandomAccessView>);
static_assert(std::ranges::sized_range<SizedRandomAccessView>);

View File

@ -28,13 +28,13 @@ constexpr bool test() {
{
const std::ranges::take_view<MoveOnlyView> tv(MoveOnlyView{buffer}, 4);
assert(tv.end().base().base() == sw.base());
assert(base(tv.end().base()) == base(sw));
ASSERT_SAME_TYPE(decltype(tv.end().base()), sentinel_wrapper<int *>);
}
{
std::ranges::take_view<MoveOnlyView> tv(MoveOnlyView{buffer}, 4);
assert(tv.end().base().base() == sw.base());
assert(base(tv.end().base()) == base(sw));
ASSERT_SAME_TYPE(decltype(tv.end().base()), sentinel_wrapper<int *>);
}

View File

@ -47,7 +47,7 @@ constexpr bool test() {
auto sw = sentinel_wrapper<int *>(buffer + 6);
using Sent = decltype(tv.end());
Sent sent = Sent(sw);
assert(sent.base().base() == sw.base());
assert(base(sent.base()) == base(sw));
}
return true;

View File

@ -37,15 +37,8 @@ struct SizedForwardView : std::ranges::view_base {
int *ptr_;
constexpr explicit SizedForwardView(int* ptr) : ptr_(ptr) {}
constexpr auto begin() const { return ForwardIter(ptr_); }
constexpr auto end() const { return sentinel_wrapper<ForwardIter>(ForwardIter(ptr_ + 8)); }
constexpr auto end() const { return sized_sentinel<ForwardIter>(ForwardIter(ptr_ + 8)); }
};
// Required to make SizedForwardView a sized view.
constexpr auto operator-(sentinel_wrapper<ForwardIter> sent, ForwardIter iter) {
return sent.base().base() - iter.base();
}
constexpr auto operator-(ForwardIter iter, sentinel_wrapper<ForwardIter> sent) {
return iter.base() - sent.base().base();
}
static_assert(std::ranges::view<SizedForwardView>);
static_assert(std::ranges::forward_range<SizedForwardView>);
static_assert(std::ranges::sized_range<SizedForwardView>);
@ -55,15 +48,8 @@ struct SizedRandomAccessView : std::ranges::view_base {
int *ptr_;
constexpr explicit SizedRandomAccessView(int* ptr) : ptr_(ptr) {}
constexpr auto begin() const { return RandomAccessIter(ptr_); }
constexpr auto end() const { return sentinel_wrapper<RandomAccessIter>(RandomAccessIter(ptr_ + 8)); }
constexpr auto end() const { return sized_sentinel<RandomAccessIter>(RandomAccessIter(ptr_ + 8)); }
};
// Required to make SizedRandomAccessView a sized view.
constexpr auto operator-(sentinel_wrapper<RandomAccessIter> sent, RandomAccessIter iter) {
return sent.base().base() - iter.base();
}
constexpr auto operator-(RandomAccessIter iter, sentinel_wrapper<RandomAccessIter> sent) {
return iter.base() - sent.base().base();
}
static_assert(std::ranges::view<SizedRandomAccessView>);
static_assert(std::ranges::random_access_range<SizedRandomAccessView>);
static_assert(std::ranges::sized_range<SizedRandomAccessView>);

View File

@ -122,7 +122,7 @@ static_assert(!std::ranges::contiguous_range<SizedButNotContiguousRange>);
static_assert(std::ranges::sized_range<SizedButNotContiguousRange>);
static_assert(!std::is_constructible_v<std::string_view, SizedButNotContiguousRange>);
using ContiguousButNotSizedRange = std::ranges::subrange<contiguous_iterator<char*>, sentinel_wrapper<char*>, std::ranges::subrange_kind::unsized>;
using ContiguousButNotSizedRange = std::ranges::subrange<contiguous_iterator<char*>, sentinel_wrapper<contiguous_iterator<char*>>, std::ranges::subrange_kind::unsized>;
static_assert(std::ranges::contiguous_range<ContiguousButNotSizedRange>);
static_assert(!std::ranges::sized_range<ContiguousButNotSizedRange>);
static_assert(!std::is_constructible_v<std::string_view, ContiguousButNotSizedRange>);

View File

@ -838,69 +838,30 @@ private:
difference_type stride_displacement_ = 0;
};
template<class T, class U>
concept sentinel_for_base = requires(U const& u) {
u.base();
requires std::input_or_output_iterator<std::remove_cvref_t<decltype(u.base())>>;
requires std::equality_comparable_with<T, decltype(u.base())>;
};
template <std::input_or_output_iterator I>
template <class It>
class sentinel_wrapper {
public:
sentinel_wrapper() = default;
constexpr explicit sentinel_wrapper(I base) : base_(std::move(base)) {}
constexpr bool operator==(const I& other) const requires std::equality_comparable<I> {
return base_ == other;
}
constexpr const I& base() const& { return base_; }
constexpr I base() && { return std::move(base_); }
template<std::input_or_output_iterator I2>
requires sentinel_for_base<I, I2>
constexpr bool operator==(const I2& other) const {
return base_ == other.base();
}
explicit sentinel_wrapper() = default;
constexpr explicit sentinel_wrapper(const It& it) : base_(base(it)) {}
constexpr bool operator==(const It& other) const { return base_ == base(other); }
friend constexpr It base(const sentinel_wrapper& s) { return It(s.base_); }
private:
I base_ = I();
decltype(base(std::declval<It>())) base_;
};
template <std::input_or_output_iterator I>
template <class It>
class sized_sentinel {
public:
sized_sentinel() = default;
constexpr explicit sized_sentinel(I base) : base_(std::move(base)) {}
constexpr bool operator==(const I& other) const requires std::equality_comparable<I> {
return base_ == other;
}
constexpr const I& base() const& { return base_; }
constexpr I base() && { return std::move(base_); }
template<std::input_or_output_iterator I2>
requires sentinel_for_base<I, I2>
constexpr bool operator==(const I2& other) const {
return base_ == other.base();
}
explicit sized_sentinel() = default;
constexpr explicit sized_sentinel(const It& it) : base_(base(it)) {}
constexpr bool operator==(const It& other) const { return base_ == base(other); }
friend constexpr auto operator-(const sized_sentinel& s, const It& i) { return s.base_ - base(i); }
friend constexpr auto operator-(const It& i, const sized_sentinel& s) { return base(i) - s.base_; }
friend constexpr It base(const sized_sentinel& s) { return It(s.base_); }
private:
I base_ = I();
decltype(base(std::declval<It>())) base_;
};
template <std::input_or_output_iterator I>
constexpr auto operator-(sized_sentinel<I> sent, std::input_or_output_iterator auto iter) {
return sent.base() - iter;
}
template <std::input_or_output_iterator I>
constexpr auto operator-(std::input_or_output_iterator auto iter, sized_sentinel<I> sent) {
return iter - sent.base();
}
template <class It>
class three_way_contiguous_iterator
{