Skip to content

Commit

Permalink
[libc++] [test] Simplify sentinel_wrapper and sized_sentinel.
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Arthur O'Dwyer committed Dec 16, 2021
1 parent 209ec8e commit 2a04dec
Show file tree
Hide file tree
Showing 8 changed files with 25 additions and 92 deletions.
Expand Up @@ -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));
}
Expand Down
Expand Up @@ -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*>>;

{
Expand Down
18 changes: 2 additions & 16 deletions libcxx/test/std/ranges/range.adaptors/range.common.view/types.h
Expand Up @@ -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>);
Expand All @@ -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>);
Expand Down
Expand Up @@ -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 *>);
}

Expand Down
Expand Up @@ -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;
Expand Down
18 changes: 2 additions & 16 deletions libcxx/test/std/ranges/range.adaptors/range.take/types.h
Expand Up @@ -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>);
Expand All @@ -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>);
Expand Down
Expand Up @@ -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>);
Expand Down
67 changes: 14 additions & 53 deletions libcxx/test/support/test_iterators.h
Expand Up @@ -838,69 +838,30 @@ class stride_counting_iterator {
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
{
Expand Down

0 comments on commit 2a04dec

Please sign in to comment.