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 = 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 
Foo()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