Skip to content

Commit 553ab7a

Browse files
committed
[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
1 parent c24199e commit 553ab7a

File tree

3 files changed

+63
-59
lines changed

3 files changed

+63
-59
lines changed

libcxx/test/std/iterators/predef.iterators/iterators.common/arrow.pass.cpp

Lines changed: 60 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -14,71 +14,79 @@
1414

1515
#include <iterator>
1616
#include <cassert>
17+
#include <concepts>
1718

19+
#include "test_iterators.h"
1820
#include "test_macros.h"
1921
#include "types.h"
2022

2123
void test() {
22-
int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8};
23-
24-
// Case 2: http://eel.is/c++draft/iterators.common#common.iter.access-5.2
25-
{
26-
auto iter1 = simple_iterator<int*>(buffer);
27-
auto commonIter1 = std::common_iterator<decltype(iter1), sentinel_type<int*>>(iter1);
28-
const auto commonIter2 = std::common_iterator<decltype(iter1), sentinel_type<int*>>(iter1);
29-
30-
assert(commonIter1.operator->() == buffer);
31-
assert(commonIter2.operator->() == buffer);
32-
}
33-
34-
// Case 3: http://eel.is/c++draft/iterators.common#common.iter.access-5.3
35-
{
36-
auto iter1 = value_iterator<int*>(buffer);
37-
auto commonIter1 = std::common_iterator<decltype(iter1), sentinel_type<int*>>(iter1);
38-
const auto commonIter2 = std::common_iterator<decltype(iter1), sentinel_type<int*>>(iter1);
39-
40-
assert(*commonIter1.operator->().operator->() == 1);
41-
assert(*commonIter2.operator->().operator->() == 1);
42-
}
43-
44-
// Case 3: http://eel.is/c++draft/iterators.common#common.iter.access-5.3
45-
{
46-
auto iter1 = void_plus_plus_iterator<int*>(buffer);
47-
auto commonIter1 = std::common_iterator<decltype(iter1), sentinel_type<int*>>(iter1);
48-
const auto commonIter2 = std::common_iterator<decltype(iter1), sentinel_type<int*>>(iter1);
49-
50-
assert(*commonIter1.operator->().operator->() == 1);
51-
assert(*commonIter2.operator->().operator->() == 1);
52-
}
53-
5424
// Case 1: http://eel.is/c++draft/iterators.common#common.iter.access-5.1
5525
{
56-
auto iter1 = cpp17_input_iterator<int*>(buffer);
57-
auto commonIter1 = std::common_iterator<decltype(iter1), sentinel_type<int*>>(iter1);
58-
const auto commonIter2 = std::common_iterator<decltype(iter1), sentinel_type<int*>>(iter1);
59-
60-
assert(base(commonIter1.operator->()) == buffer);
61-
assert(base(commonIter2.operator->()) == buffer);
26+
auto check = []<class Iterator>() {
27+
int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8};
28+
Iterator iter(buffer);
29+
using Common = std::common_iterator<Iterator, sentinel_wrapper<Iterator>>;
30+
31+
Common common(iter);
32+
std::same_as<Iterator> auto result = common.operator->();
33+
assert(base(result) == buffer);
34+
35+
Common const ccommon(iter);
36+
std::same_as<Iterator> auto cresult = ccommon.operator->();
37+
assert(base(cresult) == buffer);
38+
};
39+
40+
check.operator()<contiguous_iterator<int*>>();
41+
check.operator()<int*>();
6242
}
6343

64-
// Case 1: http://eel.is/c++draft/iterators.common#common.iter.access-5.1
44+
// Case 2: http://eel.is/c++draft/iterators.common#common.iter.access-5.2
6545
{
66-
auto iter1 = forward_iterator<int*>(buffer);
67-
auto commonIter1 = std::common_iterator<decltype(iter1), sentinel_type<int*>>(iter1);
68-
const auto commonIter2 = std::common_iterator<decltype(iter1), sentinel_type<int*>>(iter1);
69-
70-
assert(base(commonIter1.operator->()) == buffer);
71-
assert(base(commonIter2.operator->()) == buffer);
46+
auto check = []<class Iterator>() {
47+
int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8};
48+
Iterator iter(buffer);
49+
using Common = std::common_iterator<Iterator, sentinel_type<int*>>;
50+
51+
Common common(iter);
52+
std::same_as<int*> auto result = common.operator->();
53+
assert(result == buffer);
54+
55+
Common const ccommon(iter);
56+
std::same_as<int*> auto cresult = ccommon.operator->();
57+
assert(cresult == buffer);
58+
};
59+
60+
check.operator()<simple_iterator<int*>>();
61+
check.operator()<cpp17_input_iterator<int*>>();
62+
// cpp20_input_iterator can't be used with common_iterator because it's not copyable
63+
check.operator()<forward_iterator<int*>>();
64+
check.operator()<bidirectional_iterator<int*>>();
65+
check.operator()<random_access_iterator<int*>>();
7266
}
7367

74-
// Case 1: http://eel.is/c++draft/iterators.common#common.iter.access-5.1
68+
// Case 3: http://eel.is/c++draft/iterators.common#common.iter.access-5.3
7569
{
76-
auto iter1 = random_access_iterator<int*>(buffer);
77-
auto commonIter1 = std::common_iterator<decltype(iter1), sentinel_type<int*>>(iter1);
78-
const auto commonIter2 = std::common_iterator<decltype(iter1), sentinel_type<int*>>(iter1);
79-
80-
assert(base(commonIter1.operator->()) == buffer);
81-
assert(base(commonIter2.operator->()) == buffer);
70+
auto check = []<class Iterator>() {
71+
int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8};
72+
Iterator iter(buffer);
73+
using Common = std::common_iterator<Iterator, sentinel_type<int*>>;
74+
75+
Common common(iter);
76+
auto proxy = common.operator->();
77+
std::same_as<int const*> auto result = proxy.operator->();
78+
assert(result != buffer); // we copied to a temporary proxy
79+
assert(*result == *buffer);
80+
81+
Common const ccommon(iter);
82+
auto cproxy = ccommon.operator->();
83+
std::same_as<int const*> auto cresult = cproxy.operator->();
84+
assert(cresult != buffer); // we copied to a temporary proxy
85+
assert(*cresult == *buffer);
86+
};
87+
88+
check.operator()<value_iterator<int*>>();
89+
check.operator()<void_plus_plus_iterator<int*>>();
8290
}
8391
}
8492

libcxx/test/std/iterators/predef.iterators/iterators.common/iterator_traits.compile.pass.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ void test() {
9191
static_assert(std::same_as<IterTraits::iterator_category, std::input_iterator_tag>);
9292
static_assert(std::same_as<IterTraits::value_type, int>);
9393
static_assert(std::same_as<IterTraits::difference_type, std::ptrdiff_t>);
94-
static_assert(std::same_as<IterTraits::pointer, const Iter&>);
94+
static_assert(std::same_as<IterTraits::pointer, int*>);
9595
static_assert(std::same_as<IterTraits::reference, int&>);
9696
}
9797
{
@@ -103,7 +103,7 @@ void test() {
103103
static_assert(std::same_as<IterTraits::iterator_category, std::forward_iterator_tag>);
104104
static_assert(std::same_as<IterTraits::value_type, int>);
105105
static_assert(std::same_as<IterTraits::difference_type, std::ptrdiff_t>);
106-
static_assert(std::same_as<IterTraits::pointer, const Iter&>);
106+
static_assert(std::same_as<IterTraits::pointer, int*>);
107107
static_assert(std::same_as<IterTraits::reference, int&>);
108108
}
109109
{
@@ -115,7 +115,7 @@ void test() {
115115
static_assert(std::same_as<IterTraits::iterator_category, std::forward_iterator_tag>);
116116
static_assert(std::same_as<IterTraits::value_type, int>);
117117
static_assert(std::same_as<IterTraits::difference_type, std::ptrdiff_t>);
118-
static_assert(std::same_as<IterTraits::pointer, const Iter&>);
118+
static_assert(std::same_as<IterTraits::pointer, int*>);
119119
static_assert(std::same_as<IterTraits::reference, int&>);
120120
}
121121

libcxx/test/support/test_iterators.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@ class cpp17_input_iterator
7171
TEST_CONSTEXPR cpp17_input_iterator(const cpp17_input_iterator<U, T>& u) : it_(u.it_) {}
7272

7373
TEST_CONSTEXPR reference operator*() const {return *it_;}
74-
TEST_CONSTEXPR pointer operator->() const {return it_;}
7574

7675
TEST_CONSTEXPR_CXX14 cpp17_input_iterator& operator++() {++it_; return *this;}
7776
TEST_CONSTEXPR_CXX14 cpp17_input_iterator operator++(int) {return cpp17_input_iterator(it_++);}
@@ -107,7 +106,6 @@ class forward_iterator
107106
TEST_CONSTEXPR forward_iterator(const forward_iterator<U>& u) : it_(u.it_) {}
108107

109108
TEST_CONSTEXPR reference operator*() const {return *it_;}
110-
TEST_CONSTEXPR pointer operator->() const {return it_;}
111109

112110
TEST_CONSTEXPR_CXX14 forward_iterator& operator++() {++it_; return *this;}
113111
TEST_CONSTEXPR_CXX14 forward_iterator operator++(int) {return forward_iterator(it_++);}
@@ -140,7 +138,6 @@ class bidirectional_iterator
140138
TEST_CONSTEXPR bidirectional_iterator(const bidirectional_iterator<U>& u) : it_(u.it_) {}
141139

142140
TEST_CONSTEXPR reference operator*() const {return *it_;}
143-
TEST_CONSTEXPR pointer operator->() const {return it_;}
144141

145142
TEST_CONSTEXPR_CXX14 bidirectional_iterator& operator++() {++it_; return *this;}
146143
TEST_CONSTEXPR_CXX14 bidirectional_iterator& operator--() {--it_; return *this;}
@@ -175,7 +172,6 @@ class random_access_iterator
175172
TEST_CONSTEXPR random_access_iterator(const random_access_iterator<U>& u) : it_(u.it_) {}
176173

177174
TEST_CONSTEXPR_CXX14 reference operator*() const {return *it_;}
178-
TEST_CONSTEXPR_CXX14 pointer operator->() const {return it_;}
179175
TEST_CONSTEXPR_CXX14 reference operator[](difference_type n) const {return it_[n];}
180176

181177
TEST_CONSTEXPR_CXX14 random_access_iterator& operator++() {++it_; return *this;}

0 commit comments

Comments
 (0)