xref: /llvm-project/libcxx/test/std/iterators/predef.iterators/iterators.common/types.h (revision 5f26d8636f506b487962cd2a9b0e32940e93fa9b)
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 #ifndef TEST_STD_RANGES_ITERATORS_PREDEF_ITERATORS_ITERATORS_COMMON_TYPES_H
10 #define TEST_STD_RANGES_ITERATORS_PREDEF_ITERATORS_ITERATORS_COMMON_TYPES_H
11 
12 #include "test_macros.h"
13 #include "test_iterators.h"
14 
15 template <class>
16 class assignable_iterator;
17 
18 template <class It>
19 class simple_iterator
20 {
21     It it_;
22 
23 public:
24     typedef          std::input_iterator_tag                   iterator_category;
25     typedef typename std::iterator_traits<It>::value_type      value_type;
26     typedef typename std::iterator_traits<It>::difference_type difference_type;
27     typedef It                                                 pointer;
28     typedef typename std::iterator_traits<It>::reference       reference;
29 
base(const simple_iterator & i)30     friend constexpr It base(const simple_iterator& i) {return i.it_;}
31 
32     simple_iterator() = default;
simple_iterator(It it)33     explicit constexpr simple_iterator(It it) : it_(it) {}
34 
35     constexpr reference operator*() const {return *it_;}
36 
37     constexpr simple_iterator& operator++() {++it_; return *this;}
38     constexpr simple_iterator operator++(int)
39         {simple_iterator tmp(*this); ++(*this); return tmp;}
40 };
41 
42 template <class It>
43 class value_iterator
44 {
45     It it_;
46 
47 public:
48     typedef          std::input_iterator_tag                   iterator_category;
49     typedef typename std::iterator_traits<It>::value_type      value_type;
50     typedef typename std::iterator_traits<It>::difference_type difference_type;
51     typedef It                                                 pointer;
52     typedef typename std::iterator_traits<It>::reference       reference;
53 
base(const value_iterator & i)54     friend constexpr It base(const value_iterator& i) {return i.it_;}
55 
56     value_iterator() = default;
value_iterator(It it)57     explicit constexpr value_iterator(It it) : it_(it) {}
58 
59     constexpr value_type operator*() const {return std::move(*it_);}
60 
61     constexpr value_iterator& operator++() {++it_; return *this;}
62     constexpr value_iterator operator++(int)
63         {value_iterator tmp(*this); ++(*this); return tmp;}
64 };
65 
66 template <class It>
67 class void_plus_plus_iterator
68 {
69     It it_;
70 
71 public:
72     typedef          std::input_iterator_tag                   iterator_category;
73     typedef typename std::iterator_traits<It>::value_type      value_type;
74     typedef typename std::iterator_traits<It>::difference_type difference_type;
75     typedef It                                                 pointer;
76     typedef typename std::iterator_traits<It>::reference       reference;
77 
base(const void_plus_plus_iterator & i)78     friend constexpr It base(const void_plus_plus_iterator& i) {return i.it_;}
79 
80     void_plus_plus_iterator() = default;
void_plus_plus_iterator(It it)81     explicit constexpr void_plus_plus_iterator(It it) : it_(it) {}
82 
83     constexpr value_type operator*() const {return std::move(*it_);}
84 
85     constexpr void_plus_plus_iterator& operator++() {++it_; return *this;}
86     constexpr void operator++(int) {++(*this);}
87 };
88 
89 // Not referenceable, constructible, and not move constructible.
90 template <class It>
91 class value_type_not_move_constructible_iterator
92 {
93     It it_;
94 
95 public:
96     template<class T>
97     struct hold {
98       T value_;
holdhold99       hold(T v) : value_(v) {}
100       hold(const hold&) = delete;
101       hold(hold&&) = delete;
102     };
103 
104     typedef          std::input_iterator_tag                   iterator_category;
105     typedef typename std::iterator_traits<It>::value_type      underlying_value_type;
106     typedef hold<underlying_value_type>                        value_type;
107     typedef typename std::iterator_traits<It>::difference_type difference_type;
108     typedef It                                                 pointer;
109     typedef typename std::iterator_traits<It>::reference       reference;
110 
base(const value_type_not_move_constructible_iterator & i)111     friend constexpr It base(const value_type_not_move_constructible_iterator& i) {return i.it_;}
112 
113     value_type_not_move_constructible_iterator() = default;
value_type_not_move_constructible_iterator(It it)114     explicit constexpr value_type_not_move_constructible_iterator(It it) : it_(it) {}
115 
116     constexpr underlying_value_type operator*() const {return std::move(*it_);}
117 
118     constexpr value_type_not_move_constructible_iterator& operator++() {++it_; return *this;}
119     constexpr void operator++(int) {++(*this);}
120 };
121 
122 template <class It>
123 class comparable_iterator
124 {
125     It it_;
126 
127 public:
128     typedef          std::input_iterator_tag                   iterator_category;
129     typedef typename std::iterator_traits<It>::value_type      value_type;
130     typedef typename std::iterator_traits<It>::difference_type difference_type;
131     typedef It                                                 pointer;
132     typedef typename std::iterator_traits<It>::reference       reference;
133 
base(const comparable_iterator & i)134     friend constexpr It base(const comparable_iterator& i) {return i.it_;}
135 
136     comparable_iterator() = default;
comparable_iterator(It it)137     explicit constexpr comparable_iterator(It it) : it_(it) {}
138 
139     constexpr reference operator*() const {return *it_;}
140 
141     constexpr comparable_iterator& operator++() {++it_; return *this;}
142     constexpr comparable_iterator operator++(int)
143         {comparable_iterator tmp(*this); ++(*this); return tmp;}
144 
145     friend constexpr bool operator==(const comparable_iterator& lhs, const simple_iterator<It>& rhs) {
146       return base(lhs) == base(rhs);
147     }
148     friend constexpr bool operator==(const simple_iterator<It>& lhs, const comparable_iterator& rhs) {
149       return base(lhs) == base(rhs);
150     }
151 
152     friend constexpr auto operator-(const comparable_iterator& lhs, const simple_iterator<It>& rhs) {
153       return base(lhs) - base(rhs);
154     }
155     friend constexpr auto operator-(const simple_iterator<It>& lhs, const comparable_iterator& rhs) {
156       return base(lhs) - base(rhs);
157     }
158 };
159 
160 template<class T>
161 struct sentinel_type {
162   T base_;
163 
164   template<class U>
165   friend constexpr bool operator==(const sentinel_type& lhs, const U& rhs) { return lhs.base_ == base(rhs); }
166   template<class U>
167   friend constexpr bool operator==(const U& lhs, const sentinel_type& rhs) { return base(lhs) == rhs.base_; }
168 };
169 
170 template<class T>
171 struct sized_sentinel_type {
172   T base_;
173 
174   template<class U>
175   friend constexpr bool operator==(const sized_sentinel_type& lhs, const U& rhs) { return lhs.base_ - base(rhs); }
176   template<class U>
177   friend constexpr bool operator==(const U& lhs, const sized_sentinel_type& rhs) { return base(lhs) - rhs.base_; }
178   template<class U>
179   friend constexpr auto operator- (const sized_sentinel_type& lhs, const U& rhs) { return lhs.base_ - base(rhs); }
180   template<class U>
181   friend constexpr auto operator- (const U& lhs, const sized_sentinel_type& rhs) { return base(lhs) - rhs.base_; }
182 };
183 
184 template <class It>
185 class assignable_iterator
186 {
187     It it_;
188 
189 public:
190     typedef          std::input_iterator_tag                   iterator_category;
191     typedef typename std::iterator_traits<It>::value_type      value_type;
192     typedef typename std::iterator_traits<It>::difference_type difference_type;
193     typedef It                                                 pointer;
194     typedef typename std::iterator_traits<It>::reference       reference;
195 
base(const assignable_iterator & i)196     friend constexpr It base(const assignable_iterator& i) {return i.it_;}
197 
198     assignable_iterator() = default;
assignable_iterator(It it)199     explicit constexpr assignable_iterator(It it) : it_(it) {}
200 
assignable_iterator(const forward_iterator<It> & it)201     assignable_iterator(const forward_iterator<It>& it) : it_(base(it)) {}
assignable_iterator(const sentinel_type<It> & it)202     assignable_iterator(const sentinel_type<It>& it) : it_(base(it)) {}
203 
204     constexpr reference operator*() const {return *it_;}
205 
206     constexpr assignable_iterator& operator++() {++it_; return *this;}
207     constexpr assignable_iterator operator++(int)
208         {assignable_iterator tmp(*this); ++(*this); return tmp;}
209 
210     assignable_iterator& operator=(const forward_iterator<It> &other) {
211       it_ = base(other);
212       return *this;
213     }
214 
215     assignable_iterator& operator=(const sentinel_type<It> &other) {
216       it_ = base(other);
217       return *this;
218     }
219 };
220 
221 #ifndef TEST_HAS_NO_EXCEPTIONS
222 template<class T>
223 struct sentinel_throws_on_convert {
224   T base_;
225 
226   template<class U>
227   friend constexpr bool operator==(const sentinel_throws_on_convert& lhs, const U& rhs) { return lhs.base_ == base(rhs); }
228   template<class U>
229   friend constexpr bool operator==(const U& lhs, const sentinel_throws_on_convert& rhs) { return base(lhs) == rhs.base_; }
230 
231   operator sentinel_type<int*>() const { throw 42; }
232 };
233 
234 template <class It>
235 class maybe_valueless_iterator
236 {
237     It it_;
238 
239 public:
240     typedef          std::input_iterator_tag                   iterator_category;
241     typedef typename std::iterator_traits<It>::value_type      value_type;
242     typedef typename std::iterator_traits<It>::difference_type difference_type;
243     typedef It                                                 pointer;
244     typedef typename std::iterator_traits<It>::reference       reference;
245 
base(const maybe_valueless_iterator & i)246     friend constexpr It base(const maybe_valueless_iterator& i) {return i.it_;}
247 
248     maybe_valueless_iterator() = default;
maybe_valueless_iterator(It it)249     explicit constexpr maybe_valueless_iterator(It it) : it_(it) {}
250 
maybe_valueless_iterator(const forward_iterator<It> & it)251     maybe_valueless_iterator(const forward_iterator<It>& it) : it_(base(it)) {}
252 
253     constexpr reference operator*() const {return *it_;}
254 
255     constexpr maybe_valueless_iterator& operator++() {++it_; return *this;}
256     constexpr maybe_valueless_iterator operator++(int)
257         {maybe_valueless_iterator tmp(*this); ++(*this); return tmp;}
258 
259     maybe_valueless_iterator& operator=(const forward_iterator<It> &other) {
260       it_ = base(other);
261       return *this;
262     }
263 };
264 #endif // TEST_HAS_NO_EXCEPTIONS
265 
266 #endif // TEST_STD_RANGES_ITERATORS_PREDEF_ITERATORS_ITERATORS_COMMON_TYPES_H
267