1 | //===----------------------------------------------------------------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | // UNSUPPORTED: c++03, c++11, c++14, c++17 |
10 | |
11 | // <iterator> |
12 | // |
13 | // reverse_iterator |
14 | // |
15 | // template <class Iterator1, class Iterator2> |
16 | // constexpr bool // constexpr in C++17 |
17 | // operator==(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y); |
18 | // |
19 | // template <class Iterator1, class Iterator2> |
20 | // constexpr bool // constexpr in C++17 |
21 | // operator!=(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y); |
22 | // |
23 | // template <class Iterator1, class Iterator2> |
24 | // constexpr bool // constexpr in C++17 |
25 | // operator<(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y); |
26 | // |
27 | // template <class Iterator1, class Iterator2> |
28 | // constexpr bool // constexpr in C++17 |
29 | // operator>(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y); |
30 | // |
31 | // template <class Iterator1, class Iterator2> |
32 | // constexpr bool // constexpr in C++17 |
33 | // operator<=(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y); |
34 | // |
35 | // template <class Iterator1, class Iterator2> |
36 | // constexpr bool // constexpr in C++17 |
37 | // operator>=(const reverse_iterator<Iterator1>& x, const reverse_iterator<Iterator2>& y); |
38 | // |
39 | // template<class Iterator1, three_way_comparable_with<Iterator1> Iterator2> |
40 | // constexpr compare_three_way_result_t<Iterator1, Iterator2> |
41 | // operator<=>(const reverse_iterator<Iterator1>& x, |
42 | // const reverse_iterator<Iterator2>& y); |
43 | |
44 | #include <iterator> |
45 | #include <cassert> |
46 | |
47 | #include "test_macros.h" |
48 | |
49 | struct IterBase { |
50 | using iterator_category = std::bidirectional_iterator_tag; |
51 | using value_type = int; |
52 | using difference_type = std::ptrdiff_t; |
53 | using pointer = int*; |
54 | using reference = int&; |
55 | |
56 | reference operator*() const; |
57 | pointer operator->() const; |
58 | }; |
59 | |
60 | template<class T> concept HasEqual = requires (T t) { t == t; }; |
61 | template<class T> concept HasNotEqual = requires (T t) { t != t; }; |
62 | template<class T> concept HasLess = requires (T t) { t < t; }; |
63 | template<class T> concept HasLessOrEqual = requires (T t) { t <= t; }; |
64 | template<class T> concept HasGreater = requires (T t) { t > t; }; |
65 | template<class T> concept HasGreaterOrEqual = requires (T t) { t >= t; }; |
66 | template<class T> concept HasSpaceship = requires (T t) { t <=> t; }; |
67 | |
68 | // operator == |
69 | |
70 | struct NoEqualityCompIter : IterBase { |
71 | bool operator!=(NoEqualityCompIter) const; |
72 | bool operator<(NoEqualityCompIter) const; |
73 | bool operator>(NoEqualityCompIter) const; |
74 | bool operator<=(NoEqualityCompIter) const; |
75 | bool operator>=(NoEqualityCompIter) const; |
76 | }; |
77 | |
78 | static_assert( HasEqual<std::reverse_iterator<int*>>); |
79 | static_assert(!HasEqual<std::reverse_iterator<NoEqualityCompIter>>); |
80 | static_assert( HasNotEqual<std::reverse_iterator<NoEqualityCompIter>>); |
81 | static_assert( HasLess<std::reverse_iterator<NoEqualityCompIter>>); |
82 | static_assert( HasLessOrEqual<std::reverse_iterator<NoEqualityCompIter>>); |
83 | static_assert( HasGreater<std::reverse_iterator<NoEqualityCompIter>>); |
84 | static_assert( HasGreaterOrEqual<std::reverse_iterator<NoEqualityCompIter>>); |
85 | |
86 | void Foo() { |
87 | std::reverse_iterator<NoEqualityCompIter> i; |
88 | (void)i; |
89 | } |
90 | |
91 | // operator != |
92 | |
93 | struct NoInequalityCompIter : IterBase { |
94 | bool operator<(NoInequalityCompIter) const; |
95 | bool operator>(NoInequalityCompIter) const; |
96 | bool operator<=(NoInequalityCompIter) const; |
97 | bool operator>=(NoInequalityCompIter) const; |
98 | }; |
99 | |
100 | static_assert( HasNotEqual<std::reverse_iterator<int*>>); |
101 | static_assert(!HasNotEqual<std::reverse_iterator<NoInequalityCompIter>>); |
102 | static_assert(!HasEqual<std::reverse_iterator<NoInequalityCompIter>>); |
103 | static_assert( HasLess<std::reverse_iterator<NoInequalityCompIter>>); |
104 | static_assert( HasLessOrEqual<std::reverse_iterator<NoInequalityCompIter>>); |
105 | static_assert( HasGreater<std::reverse_iterator<NoInequalityCompIter>>); |
106 | static_assert( HasGreaterOrEqual<std::reverse_iterator<NoInequalityCompIter>>); |
107 | |
108 | // operator < |
109 | |
110 | struct NoGreaterCompIter : IterBase { |
111 | bool operator==(NoGreaterCompIter) const; |
112 | bool operator!=(NoGreaterCompIter) const; |
113 | bool operator<(NoGreaterCompIter) const; |
114 | bool operator<=(NoGreaterCompIter) const; |
115 | bool operator>=(NoGreaterCompIter) const; |
116 | }; |
117 | |
118 | static_assert( HasLess<std::reverse_iterator<int*>>); |
119 | static_assert(!HasLess<std::reverse_iterator<NoGreaterCompIter>>); |
120 | static_assert( HasEqual<std::reverse_iterator<NoGreaterCompIter>>); |
121 | static_assert( HasNotEqual<std::reverse_iterator<NoGreaterCompIter>>); |
122 | static_assert( HasLessOrEqual<std::reverse_iterator<NoGreaterCompIter>>); |
123 | static_assert( HasGreater<std::reverse_iterator<NoGreaterCompIter>>); |
124 | static_assert( HasGreaterOrEqual<std::reverse_iterator<NoGreaterCompIter>>); |
125 | |
126 | // operator > |
127 | |
128 | struct NoLessCompIter : IterBase { |
129 | bool operator==(NoLessCompIter) const; |
130 | bool operator!=(NoLessCompIter) const; |
131 | bool operator>(NoLessCompIter) const; |
132 | bool operator<=(NoLessCompIter) const; |
133 | bool operator>=(NoLessCompIter) const; |
134 | }; |
135 | |
136 | static_assert( HasGreater<std::reverse_iterator<int*>>); |
137 | static_assert(!HasGreater<std::reverse_iterator<NoLessCompIter>>); |
138 | static_assert( HasEqual<std::reverse_iterator<NoLessCompIter>>); |
139 | static_assert( HasNotEqual<std::reverse_iterator<NoLessCompIter>>); |
140 | static_assert( HasLess<std::reverse_iterator<NoLessCompIter>>); |
141 | static_assert( HasLessOrEqual<std::reverse_iterator<NoLessCompIter>>); |
142 | static_assert( HasGreaterOrEqual<std::reverse_iterator<NoLessCompIter>>); |
143 | |
144 | // operator <= |
145 | |
146 | struct NoGreaterOrEqualCompIter : IterBase { |
147 | bool operator==(NoGreaterOrEqualCompIter) const; |
148 | bool operator!=(NoGreaterOrEqualCompIter) const; |
149 | bool operator<(NoGreaterOrEqualCompIter) const; |
150 | bool operator>(NoGreaterOrEqualCompIter) const; |
151 | bool operator<=(NoGreaterOrEqualCompIter) const; |
152 | }; |
153 | |
154 | static_assert( HasLessOrEqual<std::reverse_iterator<int*>>); |
155 | static_assert(!HasLessOrEqual<std::reverse_iterator<NoGreaterOrEqualCompIter>>); |
156 | static_assert( HasEqual<std::reverse_iterator<NoGreaterOrEqualCompIter>>); |
157 | static_assert( HasNotEqual<std::reverse_iterator<NoGreaterOrEqualCompIter>>); |
158 | static_assert( HasLess<std::reverse_iterator<NoGreaterOrEqualCompIter>>); |
159 | static_assert( HasGreater<std::reverse_iterator<NoGreaterOrEqualCompIter>>); |
160 | static_assert( HasGreaterOrEqual<std::reverse_iterator<NoGreaterOrEqualCompIter>>); |
161 | |
162 | // operator >= |
163 | |
164 | struct NoLessOrEqualCompIter : IterBase { |
165 | bool operator==(NoLessOrEqualCompIter) const; |
166 | bool operator!=(NoLessOrEqualCompIter) const; |
167 | bool operator<(NoLessOrEqualCompIter) const; |
168 | bool operator>(NoLessOrEqualCompIter) const; |
169 | bool operator>=(NoLessOrEqualCompIter) const; |
170 | }; |
171 | |
172 | static_assert( HasGreaterOrEqual<std::reverse_iterator<int*>>); |
173 | static_assert(!HasGreaterOrEqual<std::reverse_iterator<NoLessOrEqualCompIter>>); |
174 | static_assert( HasEqual<std::reverse_iterator<NoLessOrEqualCompIter>>); |
175 | static_assert( HasNotEqual<std::reverse_iterator<NoLessOrEqualCompIter>>); |
176 | static_assert( HasLess<std::reverse_iterator<NoLessOrEqualCompIter>>); |
177 | static_assert( HasLessOrEqual<std::reverse_iterator<NoLessOrEqualCompIter>>); |
178 | static_assert( HasGreater<std::reverse_iterator<NoLessOrEqualCompIter>>); |
179 | |
180 | // operator <=> |
181 | |
182 | static_assert( std::three_way_comparable_with<int*, int*>); |
183 | static_assert( HasSpaceship<std::reverse_iterator<int*>>); |
184 | static_assert(!std::three_way_comparable_with<NoEqualityCompIter, NoEqualityCompIter>); |
185 | static_assert(!HasSpaceship<std::reverse_iterator<NoEqualityCompIter>>); |
186 | static_assert(!std::three_way_comparable_with<NoInequalityCompIter, NoInequalityCompIter>); |
187 | static_assert(!HasSpaceship<std::reverse_iterator<NoInequalityCompIter>>); |
188 | static_assert(!std::three_way_comparable_with<NoGreaterCompIter, NoGreaterCompIter>); |
189 | static_assert(!HasSpaceship<std::reverse_iterator<NoGreaterCompIter>>); |
190 | static_assert(!std::three_way_comparable_with<NoLessCompIter, NoLessCompIter>); |
191 | static_assert(!HasSpaceship<std::reverse_iterator<NoLessCompIter>>); |
192 | static_assert(!std::three_way_comparable_with<NoGreaterOrEqualCompIter, NoGreaterOrEqualCompIter>); |
193 | static_assert(!HasSpaceship<std::reverse_iterator<NoGreaterOrEqualCompIter>>); |
194 | static_assert(!std::three_way_comparable_with<NoLessOrEqualCompIter, NoLessOrEqualCompIter>); |
195 | static_assert(!HasSpaceship<std::reverse_iterator<NoLessOrEqualCompIter>>); |
196 | |