[libc++] Remove operator-> from iterator archetypes that don't need it

operator-> is not a requirement for most iterators, so remove it. To
account for this change, the `common_iterator.operator->` test needs to
be refactored quite a bit -- improve test coverage while we're at it.

Differential Revision: https://reviews.llvm.org/D118400
This commit is contained in:
Louis Dionne 2022-01-27 13:57:49 -05:00
parent c24199e8e8
commit 553ab7a090
3 changed files with 60 additions and 56 deletions

View File

@ -14,71 +14,79 @@
#include <iterator>
#include <cassert>
#include <concepts>
#include "test_iterators.h"
#include "test_macros.h"
#include "types.h"
void test() {
int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8};
// Case 1: http://eel.is/c++draft/iterators.common#common.iter.access-5.1
{
auto check = []<class Iterator>() {
int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8};
Iterator iter(buffer);
using Common = std::common_iterator<Iterator, sentinel_wrapper<Iterator>>;
Common common(iter);
std::same_as<Iterator> auto result = common.operator->();
assert(base(result) == buffer);
Common const ccommon(iter);
std::same_as<Iterator> auto cresult = ccommon.operator->();
assert(base(cresult) == buffer);
};
check.operator()<contiguous_iterator<int*>>();
check.operator()<int*>();
}
// Case 2: http://eel.is/c++draft/iterators.common#common.iter.access-5.2
{
auto iter1 = simple_iterator<int*>(buffer);
auto commonIter1 = std::common_iterator<decltype(iter1), sentinel_type<int*>>(iter1);
const auto commonIter2 = std::common_iterator<decltype(iter1), sentinel_type<int*>>(iter1);
auto check = []<class Iterator>() {
int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8};
Iterator iter(buffer);
using Common = std::common_iterator<Iterator, sentinel_type<int*>>;
assert(commonIter1.operator->() == buffer);
assert(commonIter2.operator->() == buffer);
Common common(iter);
std::same_as<int*> auto result = common.operator->();
assert(result == buffer);
Common const ccommon(iter);
std::same_as<int*> auto cresult = ccommon.operator->();
assert(cresult == buffer);
};
check.operator()<simple_iterator<int*>>();
check.operator()<cpp17_input_iterator<int*>>();
// cpp20_input_iterator can't be used with common_iterator because it's not copyable
check.operator()<forward_iterator<int*>>();
check.operator()<bidirectional_iterator<int*>>();
check.operator()<random_access_iterator<int*>>();
}
// Case 3: http://eel.is/c++draft/iterators.common#common.iter.access-5.3
{
auto iter1 = value_iterator<int*>(buffer);
auto commonIter1 = std::common_iterator<decltype(iter1), sentinel_type<int*>>(iter1);
const auto commonIter2 = std::common_iterator<decltype(iter1), sentinel_type<int*>>(iter1);
auto check = []<class Iterator>() {
int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8};
Iterator iter(buffer);
using Common = std::common_iterator<Iterator, sentinel_type<int*>>;
assert(*commonIter1.operator->().operator->() == 1);
assert(*commonIter2.operator->().operator->() == 1);
}
Common common(iter);
auto proxy = common.operator->();
std::same_as<int const*> auto result = proxy.operator->();
assert(result != buffer); // we copied to a temporary proxy
assert(*result == *buffer);
// Case 3: http://eel.is/c++draft/iterators.common#common.iter.access-5.3
{
auto iter1 = void_plus_plus_iterator<int*>(buffer);
auto commonIter1 = std::common_iterator<decltype(iter1), sentinel_type<int*>>(iter1);
const auto commonIter2 = std::common_iterator<decltype(iter1), sentinel_type<int*>>(iter1);
Common const ccommon(iter);
auto cproxy = ccommon.operator->();
std::same_as<int const*> auto cresult = cproxy.operator->();
assert(cresult != buffer); // we copied to a temporary proxy
assert(*cresult == *buffer);
};
assert(*commonIter1.operator->().operator->() == 1);
assert(*commonIter2.operator->().operator->() == 1);
}
// Case 1: http://eel.is/c++draft/iterators.common#common.iter.access-5.1
{
auto iter1 = cpp17_input_iterator<int*>(buffer);
auto commonIter1 = std::common_iterator<decltype(iter1), sentinel_type<int*>>(iter1);
const auto commonIter2 = std::common_iterator<decltype(iter1), sentinel_type<int*>>(iter1);
assert(base(commonIter1.operator->()) == buffer);
assert(base(commonIter2.operator->()) == buffer);
}
// Case 1: http://eel.is/c++draft/iterators.common#common.iter.access-5.1
{
auto iter1 = forward_iterator<int*>(buffer);
auto commonIter1 = std::common_iterator<decltype(iter1), sentinel_type<int*>>(iter1);
const auto commonIter2 = std::common_iterator<decltype(iter1), sentinel_type<int*>>(iter1);
assert(base(commonIter1.operator->()) == buffer);
assert(base(commonIter2.operator->()) == buffer);
}
// Case 1: http://eel.is/c++draft/iterators.common#common.iter.access-5.1
{
auto iter1 = random_access_iterator<int*>(buffer);
auto commonIter1 = std::common_iterator<decltype(iter1), sentinel_type<int*>>(iter1);
const auto commonIter2 = std::common_iterator<decltype(iter1), sentinel_type<int*>>(iter1);
assert(base(commonIter1.operator->()) == buffer);
assert(base(commonIter2.operator->()) == buffer);
check.operator()<value_iterator<int*>>();
check.operator()<void_plus_plus_iterator<int*>>();
}
}

View File

@ -91,7 +91,7 @@ void test() {
static_assert(std::same_as<IterTraits::iterator_category, std::input_iterator_tag>);
static_assert(std::same_as<IterTraits::value_type, int>);
static_assert(std::same_as<IterTraits::difference_type, std::ptrdiff_t>);
static_assert(std::same_as<IterTraits::pointer, const Iter&>);
static_assert(std::same_as<IterTraits::pointer, int*>);
static_assert(std::same_as<IterTraits::reference, int&>);
}
{
@ -103,7 +103,7 @@ void test() {
static_assert(std::same_as<IterTraits::iterator_category, std::forward_iterator_tag>);
static_assert(std::same_as<IterTraits::value_type, int>);
static_assert(std::same_as<IterTraits::difference_type, std::ptrdiff_t>);
static_assert(std::same_as<IterTraits::pointer, const Iter&>);
static_assert(std::same_as<IterTraits::pointer, int*>);
static_assert(std::same_as<IterTraits::reference, int&>);
}
{
@ -115,7 +115,7 @@ void test() {
static_assert(std::same_as<IterTraits::iterator_category, std::forward_iterator_tag>);
static_assert(std::same_as<IterTraits::value_type, int>);
static_assert(std::same_as<IterTraits::difference_type, std::ptrdiff_t>);
static_assert(std::same_as<IterTraits::pointer, const Iter&>);
static_assert(std::same_as<IterTraits::pointer, int*>);
static_assert(std::same_as<IterTraits::reference, int&>);
}

View File

@ -71,7 +71,6 @@ public:
TEST_CONSTEXPR cpp17_input_iterator(const cpp17_input_iterator<U, T>& u) : it_(u.it_) {}
TEST_CONSTEXPR reference operator*() const {return *it_;}
TEST_CONSTEXPR pointer operator->() const {return it_;}
TEST_CONSTEXPR_CXX14 cpp17_input_iterator& operator++() {++it_; return *this;}
TEST_CONSTEXPR_CXX14 cpp17_input_iterator operator++(int) {return cpp17_input_iterator(it_++);}
@ -107,7 +106,6 @@ public:
TEST_CONSTEXPR forward_iterator(const forward_iterator<U>& u) : it_(u.it_) {}
TEST_CONSTEXPR reference operator*() const {return *it_;}
TEST_CONSTEXPR pointer operator->() const {return it_;}
TEST_CONSTEXPR_CXX14 forward_iterator& operator++() {++it_; return *this;}
TEST_CONSTEXPR_CXX14 forward_iterator operator++(int) {return forward_iterator(it_++);}
@ -140,7 +138,6 @@ public:
TEST_CONSTEXPR bidirectional_iterator(const bidirectional_iterator<U>& u) : it_(u.it_) {}
TEST_CONSTEXPR reference operator*() const {return *it_;}
TEST_CONSTEXPR pointer operator->() const {return it_;}
TEST_CONSTEXPR_CXX14 bidirectional_iterator& operator++() {++it_; return *this;}
TEST_CONSTEXPR_CXX14 bidirectional_iterator& operator--() {--it_; return *this;}
@ -175,7 +172,6 @@ public:
TEST_CONSTEXPR random_access_iterator(const random_access_iterator<U>& u) : it_(u.it_) {}
TEST_CONSTEXPR_CXX14 reference operator*() const {return *it_;}
TEST_CONSTEXPR_CXX14 pointer operator->() const {return it_;}
TEST_CONSTEXPR_CXX14 reference operator[](difference_type n) const {return it_[n];}
TEST_CONSTEXPR_CXX14 random_access_iterator& operator++() {++it_; return *this;}