[PowerPC][NFC] Cleanup PPCCTRLoopsVerify pass
[llvm-project.git] / libcxx / test / support / test_iterators.h
blobbc07e20fbafe68c6a16734b21ef223614a160909
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 //===----------------------------------------------------------------------===//
9 #ifndef ITERATORS_H
10 #define ITERATORS_H
12 #include <iterator>
13 #include <stdexcept>
14 #include <cstddef>
15 #include <cassert>
17 #include "test_macros.h"
19 #if TEST_STD_VER >= 11
20 #define DELETE_FUNCTION = delete
21 #else
22 #define DELETE_FUNCTION
23 #endif
25 template <class It>
26 class output_iterator
28 It it_;
30 template <class U> friend class output_iterator;
31 public:
32 typedef std::output_iterator_tag iterator_category;
33 typedef void value_type;
34 typedef typename std::iterator_traits<It>::difference_type difference_type;
35 typedef It pointer;
36 typedef typename std::iterator_traits<It>::reference reference;
38 TEST_CONSTEXPR_CXX14 It base() const {return it_;}
40 TEST_CONSTEXPR_CXX14 output_iterator () {}
41 explicit TEST_CONSTEXPR_CXX14 output_iterator(It it) : it_(it) {}
42 template <class U>
43 TEST_CONSTEXPR_CXX14 output_iterator(const output_iterator<U>& u) :it_(u.it_) {}
45 TEST_CONSTEXPR_CXX14 reference operator*() const {return *it_;}
47 TEST_CONSTEXPR_CXX14 output_iterator& operator++() {++it_; return *this;}
48 TEST_CONSTEXPR_CXX14 output_iterator operator++(int)
49 {output_iterator tmp(*this); ++(*this); return tmp;}
51 template <class T>
52 void operator,(T const &) DELETE_FUNCTION;
55 template <class It,
56 class ItTraits = It>
57 class input_iterator
59 typedef std::iterator_traits<ItTraits> Traits;
60 It it_;
62 template <class U, class T> friend class input_iterator;
63 public:
64 typedef std::input_iterator_tag iterator_category;
65 typedef typename Traits::value_type value_type;
66 typedef typename Traits::difference_type difference_type;
67 typedef It pointer;
68 typedef typename Traits::reference reference;
70 TEST_CONSTEXPR_CXX14 It base() const {return it_;}
72 TEST_CONSTEXPR_CXX14 input_iterator() : it_() {}
73 explicit TEST_CONSTEXPR_CXX14 input_iterator(It it) : it_(it) {}
74 template <class U, class T>
75 TEST_CONSTEXPR_CXX14 input_iterator(const input_iterator<U, T>& u) :it_(u.it_) {}
77 TEST_CONSTEXPR_CXX14 reference operator*() const {return *it_;}
78 TEST_CONSTEXPR_CXX14 pointer operator->() const {return it_;}
80 TEST_CONSTEXPR_CXX14 input_iterator& operator++() {++it_; return *this;}
81 TEST_CONSTEXPR_CXX14 input_iterator operator++(int)
82 {input_iterator tmp(*this); ++(*this); return tmp;}
84 friend TEST_CONSTEXPR_CXX14 bool operator==(const input_iterator& x, const input_iterator& y)
85 {return x.it_ == y.it_;}
86 friend TEST_CONSTEXPR_CXX14 bool operator!=(const input_iterator& x, const input_iterator& y)
87 {return !(x == y);}
89 template <class T>
90 void operator,(T const &) DELETE_FUNCTION;
93 template <class T, class TV, class U, class UV>
94 inline
95 bool
96 operator==(const input_iterator<T, TV>& x, const input_iterator<U, UV>& y)
98 return x.base() == y.base();
101 template <class T, class TV, class U, class UV>
102 inline
103 bool
104 operator!=(const input_iterator<T, TV>& x, const input_iterator<U, UV>& y)
106 return !(x == y);
109 template <class It>
110 class forward_iterator
112 It it_;
114 template <class U> friend class forward_iterator;
115 public:
116 typedef std::forward_iterator_tag iterator_category;
117 typedef typename std::iterator_traits<It>::value_type value_type;
118 typedef typename std::iterator_traits<It>::difference_type difference_type;
119 typedef It pointer;
120 typedef typename std::iterator_traits<It>::reference reference;
122 TEST_CONSTEXPR_CXX14 It base() const {return it_;}
124 TEST_CONSTEXPR_CXX14 forward_iterator() : it_() {}
125 explicit TEST_CONSTEXPR_CXX14 forward_iterator(It it) : it_(it) {}
126 template <class U>
127 TEST_CONSTEXPR_CXX14 forward_iterator(const forward_iterator<U>& u) :it_(u.it_) {}
129 TEST_CONSTEXPR_CXX14 reference operator*() const {return *it_;}
130 TEST_CONSTEXPR_CXX14 pointer operator->() const {return it_;}
132 TEST_CONSTEXPR_CXX14 forward_iterator& operator++() {++it_; return *this;}
133 TEST_CONSTEXPR_CXX14 forward_iterator operator++(int)
134 {forward_iterator tmp(*this); ++(*this); return tmp;}
136 friend TEST_CONSTEXPR_CXX14 bool operator==(const forward_iterator& x, const forward_iterator& y)
137 {return x.it_ == y.it_;}
138 friend TEST_CONSTEXPR_CXX14 bool operator!=(const forward_iterator& x, const forward_iterator& y)
139 {return !(x == y);}
141 template <class T>
142 void operator,(T const &) DELETE_FUNCTION;
145 template <class T, class U>
146 inline
147 bool TEST_CONSTEXPR_CXX14
148 operator==(const forward_iterator<T>& x, const forward_iterator<U>& y)
150 return x.base() == y.base();
153 template <class T, class U>
154 inline
155 bool TEST_CONSTEXPR_CXX14
156 operator!=(const forward_iterator<T>& x, const forward_iterator<U>& y)
158 return !(x == y);
161 template <class It>
162 class bidirectional_iterator
164 It it_;
166 template <class U> friend class bidirectional_iterator;
167 public:
168 typedef std::bidirectional_iterator_tag iterator_category;
169 typedef typename std::iterator_traits<It>::value_type value_type;
170 typedef typename std::iterator_traits<It>::difference_type difference_type;
171 typedef It pointer;
172 typedef typename std::iterator_traits<It>::reference reference;
174 TEST_CONSTEXPR_CXX14 It base() const {return it_;}
176 TEST_CONSTEXPR_CXX14 bidirectional_iterator() : it_() {}
177 explicit TEST_CONSTEXPR_CXX14 bidirectional_iterator(It it) : it_(it) {}
178 template <class U>
179 TEST_CONSTEXPR_CXX14 bidirectional_iterator(const bidirectional_iterator<U>& u) :it_(u.it_) {}
181 TEST_CONSTEXPR_CXX14 reference operator*() const {return *it_;}
182 TEST_CONSTEXPR_CXX14 pointer operator->() const {return it_;}
184 TEST_CONSTEXPR_CXX14 bidirectional_iterator& operator++() {++it_; return *this;}
185 TEST_CONSTEXPR_CXX14 bidirectional_iterator operator++(int)
186 {bidirectional_iterator tmp(*this); ++(*this); return tmp;}
188 TEST_CONSTEXPR_CXX14 bidirectional_iterator& operator--() {--it_; return *this;}
189 TEST_CONSTEXPR_CXX14 bidirectional_iterator operator--(int)
190 {bidirectional_iterator tmp(*this); --(*this); return tmp;}
192 template <class T>
193 void operator,(T const &) DELETE_FUNCTION;
196 template <class T, class U>
197 inline
198 bool TEST_CONSTEXPR_CXX14
199 operator==(const bidirectional_iterator<T>& x, const bidirectional_iterator<U>& y)
201 return x.base() == y.base();
204 template <class T, class U>
205 inline
206 bool TEST_CONSTEXPR_CXX14
207 operator!=(const bidirectional_iterator<T>& x, const bidirectional_iterator<U>& y)
209 return !(x == y);
212 template <class It>
213 class random_access_iterator
215 It it_;
217 template <class U> friend class random_access_iterator;
218 public:
219 typedef std::random_access_iterator_tag iterator_category;
220 typedef typename std::iterator_traits<It>::value_type value_type;
221 typedef typename std::iterator_traits<It>::difference_type difference_type;
222 typedef It pointer;
223 typedef typename std::iterator_traits<It>::reference reference;
225 TEST_CONSTEXPR_CXX14 It base() const {return it_;}
227 TEST_CONSTEXPR_CXX14 random_access_iterator() : it_() {}
228 explicit TEST_CONSTEXPR_CXX14 random_access_iterator(It it) : it_(it) {}
229 template <class U>
230 TEST_CONSTEXPR_CXX14 random_access_iterator(const random_access_iterator<U>& u) :it_(u.it_) {}
232 TEST_CONSTEXPR_CXX14 reference operator*() const {return *it_;}
233 TEST_CONSTEXPR_CXX14 pointer operator->() const {return it_;}
235 TEST_CONSTEXPR_CXX14 random_access_iterator& operator++() {++it_; return *this;}
236 TEST_CONSTEXPR_CXX14 random_access_iterator operator++(int)
237 {random_access_iterator tmp(*this); ++(*this); return tmp;}
239 TEST_CONSTEXPR_CXX14 random_access_iterator& operator--() {--it_; return *this;}
240 TEST_CONSTEXPR_CXX14 random_access_iterator operator--(int)
241 {random_access_iterator tmp(*this); --(*this); return tmp;}
243 TEST_CONSTEXPR_CXX14 random_access_iterator& operator+=(difference_type n) {it_ += n; return *this;}
244 TEST_CONSTEXPR_CXX14 random_access_iterator operator+(difference_type n) const
245 {random_access_iterator tmp(*this); tmp += n; return tmp;}
246 friend TEST_CONSTEXPR_CXX14 random_access_iterator operator+(difference_type n, random_access_iterator x)
247 {x += n; return x;}
248 TEST_CONSTEXPR_CXX14 random_access_iterator& operator-=(difference_type n) {return *this += -n;}
249 TEST_CONSTEXPR_CXX14 random_access_iterator operator-(difference_type n) const
250 {random_access_iterator tmp(*this); tmp -= n; return tmp;}
252 TEST_CONSTEXPR_CXX14 reference operator[](difference_type n) const {return it_[n];}
254 template <class T>
255 void operator,(T const &) DELETE_FUNCTION;
258 template <class T, class U>
259 inline
260 bool TEST_CONSTEXPR_CXX14
261 operator==(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
263 return x.base() == y.base();
266 template <class T, class U>
267 inline
268 bool TEST_CONSTEXPR_CXX14
269 operator!=(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
271 return !(x == y);
274 template <class T, class U>
275 inline
276 bool TEST_CONSTEXPR_CXX14
277 operator<(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
279 return x.base() < y.base();
282 template <class T, class U>
283 inline
284 bool TEST_CONSTEXPR_CXX14
285 operator<=(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
287 return !(y < x);
290 template <class T, class U>
291 inline
292 bool TEST_CONSTEXPR_CXX14
293 operator>(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
295 return y < x;
298 template <class T, class U>
299 inline
300 bool TEST_CONSTEXPR_CXX14
301 operator>=(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
303 return !(x < y);
306 template <class T, class U>
307 inline TEST_CONSTEXPR_CXX14
308 typename std::iterator_traits<T>::difference_type
309 operator-(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
311 return x.base() - y.base();
314 template <class Iter>
315 inline TEST_CONSTEXPR_CXX14 Iter base(output_iterator<Iter> i) { return i.base(); }
317 template <class Iter>
318 inline TEST_CONSTEXPR_CXX14 Iter base(input_iterator<Iter> i) { return i.base(); }
320 template <class Iter>
321 inline TEST_CONSTEXPR_CXX14 Iter base(forward_iterator<Iter> i) { return i.base(); }
323 template <class Iter>
324 inline TEST_CONSTEXPR_CXX14 Iter base(bidirectional_iterator<Iter> i) { return i.base(); }
326 template <class Iter>
327 inline TEST_CONSTEXPR_CXX14 Iter base(random_access_iterator<Iter> i) { return i.base(); }
329 template <class Iter> // everything else
330 inline TEST_CONSTEXPR_CXX14 Iter base(Iter i) { return i; }
332 template <typename T>
333 struct ThrowingIterator {
334 typedef std::bidirectional_iterator_tag iterator_category;
335 typedef ptrdiff_t difference_type;
336 typedef const T value_type;
337 typedef const T * pointer;
338 typedef const T & reference;
340 enum ThrowingAction { TAIncrement, TADecrement, TADereference, TAAssignment, TAComparison };
342 // Constructors
343 ThrowingIterator ()
344 : begin_(nullptr), end_(nullptr), current_(nullptr), action_(TADereference), index_(0) {}
345 ThrowingIterator (const T *first, const T *last, size_t index = 0, ThrowingAction action = TADereference)
346 : begin_(first), end_(last), current_(first), action_(action), index_(index) {}
347 ThrowingIterator (const ThrowingIterator &rhs)
348 : begin_(rhs.begin_), end_(rhs.end_), current_(rhs.current_), action_(rhs.action_), index_(rhs.index_) {}
349 ThrowingIterator & operator= (const ThrowingIterator &rhs)
351 if (action_ == TAAssignment)
353 if (index_ == 0)
354 #ifndef TEST_HAS_NO_EXCEPTIONS
355 throw std::runtime_error ("throw from iterator assignment");
356 #else
357 assert(false);
358 #endif
360 else
361 --index_;
363 begin_ = rhs.begin_;
364 end_ = rhs.end_;
365 current_ = rhs.current_;
366 action_ = rhs.action_;
367 index_ = rhs.index_;
368 return *this;
371 // iterator operations
372 reference operator*() const
374 if (action_ == TADereference)
376 if (index_ == 0)
377 #ifndef TEST_HAS_NO_EXCEPTIONS
378 throw std::runtime_error ("throw from iterator dereference");
379 #else
380 assert(false);
381 #endif
382 else
383 --index_;
385 return *current_;
388 ThrowingIterator & operator++()
390 if (action_ == TAIncrement)
392 if (index_ == 0)
393 #ifndef TEST_HAS_NO_EXCEPTIONS
394 throw std::runtime_error ("throw from iterator increment");
395 #else
396 assert(false);
397 #endif
398 else
399 --index_;
401 ++current_;
402 return *this;
405 ThrowingIterator operator++(int)
407 ThrowingIterator temp = *this;
408 ++(*this);
409 return temp;
412 ThrowingIterator & operator--()
414 if (action_ == TADecrement)
416 if (index_ == 0)
417 #ifndef TEST_HAS_NO_EXCEPTIONS
418 throw std::runtime_error ("throw from iterator decrement");
419 #else
420 assert(false);
421 #endif
422 else
423 --index_;
425 --current_;
426 return *this;
429 ThrowingIterator operator--(int) {
430 ThrowingIterator temp = *this;
431 --(*this);
432 return temp;
435 bool operator== (const ThrowingIterator &rhs) const
437 if (action_ == TAComparison)
439 if (index_ == 0)
440 #ifndef TEST_HAS_NO_EXCEPTIONS
441 throw std::runtime_error ("throw from iterator comparison");
442 #else
443 assert(false);
444 #endif
445 else
446 --index_;
448 bool atEndL = current_ == end_;
449 bool atEndR = rhs.current_ == rhs.end_;
450 if (atEndL != atEndR) return false; // one is at the end (or empty), the other is not.
451 if (atEndL) return true; // both are at the end (or empty)
452 return current_ == rhs.current_;
455 private:
456 const T* begin_;
457 const T* end_;
458 const T* current_;
459 ThrowingAction action_;
460 mutable size_t index_;
463 template <typename T>
464 bool operator== (const ThrowingIterator<T>& a, const ThrowingIterator<T>& b)
465 { return a.operator==(b); }
467 template <typename T>
468 bool operator!= (const ThrowingIterator<T>& a, const ThrowingIterator<T>& b)
469 { return !a.operator==(b); }
471 template <typename T>
472 struct NonThrowingIterator {
473 typedef std::bidirectional_iterator_tag iterator_category;
474 typedef ptrdiff_t difference_type;
475 typedef const T value_type;
476 typedef const T * pointer;
477 typedef const T & reference;
479 // Constructors
480 NonThrowingIterator ()
481 : begin_(nullptr), end_(nullptr), current_(nullptr) {}
482 NonThrowingIterator (const T *first, const T* last)
483 : begin_(first), end_(last), current_(first) {}
484 NonThrowingIterator (const NonThrowingIterator &rhs)
485 : begin_(rhs.begin_), end_(rhs.end_), current_(rhs.current_) {}
486 NonThrowingIterator & operator= (const NonThrowingIterator &rhs) TEST_NOEXCEPT
488 begin_ = rhs.begin_;
489 end_ = rhs.end_;
490 current_ = rhs.current_;
491 return *this;
494 // iterator operations
495 reference operator*() const TEST_NOEXCEPT
497 return *current_;
500 NonThrowingIterator & operator++() TEST_NOEXCEPT
502 ++current_;
503 return *this;
506 NonThrowingIterator operator++(int) TEST_NOEXCEPT
508 NonThrowingIterator temp = *this;
509 ++(*this);
510 return temp;
513 NonThrowingIterator & operator--() TEST_NOEXCEPT
515 --current_;
516 return *this;
519 NonThrowingIterator operator--(int) TEST_NOEXCEPT
521 NonThrowingIterator temp = *this;
522 --(*this);
523 return temp;
526 bool operator== (const NonThrowingIterator &rhs) const TEST_NOEXCEPT
528 bool atEndL = current_ == end_;
529 bool atEndR = rhs.current_ == rhs.end_;
530 if (atEndL != atEndR) return false; // one is at the end (or empty), the other is not.
531 if (atEndL) return true; // both are at the end (or empty)
532 return current_ == rhs.current_;
535 private:
536 const T* begin_;
537 const T* end_;
538 const T* current_;
541 template <typename T>
542 bool operator== (const NonThrowingIterator<T>& a, const NonThrowingIterator<T>& b) TEST_NOEXCEPT
543 { return a.operator==(b); }
545 template <typename T>
546 bool operator!= (const NonThrowingIterator<T>& a, const NonThrowingIterator<T>& b) TEST_NOEXCEPT
547 { return !a.operator==(b); }
549 #undef DELETE_FUNCTION
551 #endif // ITERATORS_H