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#include <cstddef>
47
48#include "test_macros.h"
49
50struct IterBase {
51 using iterator_category = std::bidirectional_iterator_tag;
52 using value_type = int;
53 using difference_type = std::ptrdiff_t;
54 using pointer = int*;
55 using reference = int&;
56
57 reference operator*() const;
58 pointer operator->() const;
59};
60
61template<class T> concept HasEqual = requires (T t) { t == t; };
62template<class T> concept HasNotEqual = requires (T t) { t != t; };
63template<class T> concept HasLess = requires (T t) { t < t; };
64template<class T> concept HasLessOrEqual = requires (T t) { t <= t; };
65template<class T> concept HasGreater = requires (T t) { t > t; };
66template<class T> concept HasGreaterOrEqual = requires (T t) { t >= t; };
67template<class T> concept HasSpaceship = requires (T t) { t <=> t; };
68
69// operator ==
70
71struct NoEqualityCompIter : IterBase {
72 bool operator!=(NoEqualityCompIter) const;
73 bool operator<(NoEqualityCompIter) const;
74 bool operator>(NoEqualityCompIter) const;
75 bool operator<=(NoEqualityCompIter) const;
76 bool operator>=(NoEqualityCompIter) const;
77};
78
79static_assert( HasEqual<std::reverse_iterator<int*>>);
80static_assert(!HasEqual<std::reverse_iterator<NoEqualityCompIter>>);
81static_assert( HasNotEqual<std::reverse_iterator<NoEqualityCompIter>>);
82static_assert( HasLess<std::reverse_iterator<NoEqualityCompIter>>);
83static_assert( HasLessOrEqual<std::reverse_iterator<NoEqualityCompIter>>);
84static_assert( HasGreater<std::reverse_iterator<NoEqualityCompIter>>);
85static_assert( HasGreaterOrEqual<std::reverse_iterator<NoEqualityCompIter>>);
86
87void Foo() {
88 std::reverse_iterator<NoEqualityCompIter> i;
89 (void)i;
90}
91
92// operator !=
93
94struct NoInequalityCompIter : IterBase {
95 bool operator<(NoInequalityCompIter) const;
96 bool operator>(NoInequalityCompIter) const;
97 bool operator<=(NoInequalityCompIter) const;
98 bool operator>=(NoInequalityCompIter) const;
99};
100
101static_assert( HasNotEqual<std::reverse_iterator<int*>>);
102static_assert(!HasNotEqual<std::reverse_iterator<NoInequalityCompIter>>);
103static_assert(!HasEqual<std::reverse_iterator<NoInequalityCompIter>>);
104static_assert( HasLess<std::reverse_iterator<NoInequalityCompIter>>);
105static_assert( HasLessOrEqual<std::reverse_iterator<NoInequalityCompIter>>);
106static_assert( HasGreater<std::reverse_iterator<NoInequalityCompIter>>);
107static_assert( HasGreaterOrEqual<std::reverse_iterator<NoInequalityCompIter>>);
108
109// operator <
110
111struct NoGreaterCompIter : IterBase {
112 bool operator==(NoGreaterCompIter) const;
113 bool operator!=(NoGreaterCompIter) const;
114 bool operator<(NoGreaterCompIter) const;
115 bool operator<=(NoGreaterCompIter) const;
116 bool operator>=(NoGreaterCompIter) const;
117};
118
119static_assert( HasLess<std::reverse_iterator<int*>>);
120static_assert(!HasLess<std::reverse_iterator<NoGreaterCompIter>>);
121static_assert( HasEqual<std::reverse_iterator<NoGreaterCompIter>>);
122static_assert( HasNotEqual<std::reverse_iterator<NoGreaterCompIter>>);
123static_assert( HasLessOrEqual<std::reverse_iterator<NoGreaterCompIter>>);
124static_assert( HasGreater<std::reverse_iterator<NoGreaterCompIter>>);
125static_assert( HasGreaterOrEqual<std::reverse_iterator<NoGreaterCompIter>>);
126
127// operator >
128
129struct NoLessCompIter : IterBase {
130 bool operator==(NoLessCompIter) const;
131 bool operator!=(NoLessCompIter) const;
132 bool operator>(NoLessCompIter) const;
133 bool operator<=(NoLessCompIter) const;
134 bool operator>=(NoLessCompIter) const;
135};
136
137static_assert( HasGreater<std::reverse_iterator<int*>>);
138static_assert(!HasGreater<std::reverse_iterator<NoLessCompIter>>);
139static_assert( HasEqual<std::reverse_iterator<NoLessCompIter>>);
140static_assert( HasNotEqual<std::reverse_iterator<NoLessCompIter>>);
141static_assert( HasLess<std::reverse_iterator<NoLessCompIter>>);
142static_assert( HasLessOrEqual<std::reverse_iterator<NoLessCompIter>>);
143static_assert( HasGreaterOrEqual<std::reverse_iterator<NoLessCompIter>>);
144
145// operator <=
146
147struct NoGreaterOrEqualCompIter : IterBase {
148 bool operator==(NoGreaterOrEqualCompIter) const;
149 bool operator!=(NoGreaterOrEqualCompIter) const;
150 bool operator<(NoGreaterOrEqualCompIter) const;
151 bool operator>(NoGreaterOrEqualCompIter) const;
152 bool operator<=(NoGreaterOrEqualCompIter) const;
153};
154
155static_assert( HasLessOrEqual<std::reverse_iterator<int*>>);
156static_assert(!HasLessOrEqual<std::reverse_iterator<NoGreaterOrEqualCompIter>>);
157static_assert( HasEqual<std::reverse_iterator<NoGreaterOrEqualCompIter>>);
158static_assert( HasNotEqual<std::reverse_iterator<NoGreaterOrEqualCompIter>>);
159static_assert( HasLess<std::reverse_iterator<NoGreaterOrEqualCompIter>>);
160static_assert( HasGreater<std::reverse_iterator<NoGreaterOrEqualCompIter>>);
161static_assert( HasGreaterOrEqual<std::reverse_iterator<NoGreaterOrEqualCompIter>>);
162
163// operator >=
164
165struct NoLessOrEqualCompIter : IterBase {
166 bool operator==(NoLessOrEqualCompIter) const;
167 bool operator!=(NoLessOrEqualCompIter) const;
168 bool operator<(NoLessOrEqualCompIter) const;
169 bool operator>(NoLessOrEqualCompIter) const;
170 bool operator>=(NoLessOrEqualCompIter) const;
171};
172
173static_assert( HasGreaterOrEqual<std::reverse_iterator<int*>>);
174static_assert(!HasGreaterOrEqual<std::reverse_iterator<NoLessOrEqualCompIter>>);
175static_assert( HasEqual<std::reverse_iterator<NoLessOrEqualCompIter>>);
176static_assert( HasNotEqual<std::reverse_iterator<NoLessOrEqualCompIter>>);
177static_assert( HasLess<std::reverse_iterator<NoLessOrEqualCompIter>>);
178static_assert( HasLessOrEqual<std::reverse_iterator<NoLessOrEqualCompIter>>);
179static_assert( HasGreater<std::reverse_iterator<NoLessOrEqualCompIter>>);
180
181// operator <=>
182
183static_assert( std::three_way_comparable_with<int*, int*>);
184static_assert( HasSpaceship<std::reverse_iterator<int*>>);
185static_assert(!std::three_way_comparable_with<NoEqualityCompIter, NoEqualityCompIter>);
186static_assert(!HasSpaceship<std::reverse_iterator<NoEqualityCompIter>>);
187static_assert(!std::three_way_comparable_with<NoInequalityCompIter, NoInequalityCompIter>);
188static_assert(!HasSpaceship<std::reverse_iterator<NoInequalityCompIter>>);
189static_assert(!std::three_way_comparable_with<NoGreaterCompIter, NoGreaterCompIter>);
190static_assert(!HasSpaceship<std::reverse_iterator<NoGreaterCompIter>>);
191static_assert(!std::three_way_comparable_with<NoLessCompIter, NoLessCompIter>);
192static_assert(!HasSpaceship<std::reverse_iterator<NoLessCompIter>>);
193static_assert(!std::three_way_comparable_with<NoGreaterOrEqualCompIter, NoGreaterOrEqualCompIter>);
194static_assert(!HasSpaceship<std::reverse_iterator<NoGreaterOrEqualCompIter>>);
195static_assert(!std::three_way_comparable_with<NoLessOrEqualCompIter, NoLessOrEqualCompIter>);
196static_assert(!HasSpaceship<std::reverse_iterator<NoLessOrEqualCompIter>>);
197

source code of libcxx/test/std/iterators/predef.iterators/reverse.iterators/reverse.iter.cmp/sfinae.compile.pass.cpp