1 //===----------------------------------------------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
18 #include "test_macros.h"
20 #ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS
21 #define DELETE_FUNCTION = delete
23 #define DELETE_FUNCTION
31 template <class U> friend class output_iterator;
33 typedef std::output_iterator_tag iterator_category;
34 typedef void value_type;
35 typedef typename std::iterator_traits<It>::difference_type difference_type;
37 typedef typename std::iterator_traits<It>::reference reference;
39 It base() const {return it_;}
42 explicit output_iterator(It it) : it_(it) {}
44 output_iterator(const output_iterator<U>& u) :it_(u.it_) {}
46 reference operator*() const {return *it_;}
48 output_iterator& operator++() {++it_; return *this;}
49 output_iterator operator++(int)
50 {output_iterator tmp(*this); ++(*this); return tmp;}
53 void operator,(T const &) DELETE_FUNCTION;
60 typedef std::iterator_traits<ItTraits> Traits;
63 template <class U, class T> friend class input_iterator;
65 typedef std::input_iterator_tag iterator_category;
66 typedef typename Traits::value_type value_type;
67 typedef typename Traits::difference_type difference_type;
69 typedef typename Traits::reference reference;
71 It base() const {return it_;}
73 input_iterator() : it_() {}
74 explicit input_iterator(It it) : it_(it) {}
75 template <class U, class T>
76 input_iterator(const input_iterator<U, T>& u) :it_(u.it_) {}
78 reference operator*() const {return *it_;}
79 pointer operator->() const {return it_;}
81 input_iterator& operator++() {++it_; return *this;}
82 input_iterator operator++(int)
83 {input_iterator tmp(*this); ++(*this); return tmp;}
85 friend bool operator==(const input_iterator& x, const input_iterator& y)
86 {return x.it_ == y.it_;}
87 friend bool operator!=(const input_iterator& x, const input_iterator& y)
91 void operator,(T const &) DELETE_FUNCTION;
94 template <class T, class TV, class U, class UV>
97 operator==(const input_iterator<T, TV>& x, const input_iterator<U, UV>& y)
99 return x.base() == y.base();
102 template <class T, class TV, class U, class UV>
105 operator!=(const input_iterator<T, TV>& x, const input_iterator<U, UV>& y)
111 class forward_iterator
115 template <class U> friend class forward_iterator;
117 typedef std::forward_iterator_tag iterator_category;
118 typedef typename std::iterator_traits<It>::value_type value_type;
119 typedef typename std::iterator_traits<It>::difference_type difference_type;
121 typedef typename std::iterator_traits<It>::reference reference;
123 It base() const {return it_;}
125 forward_iterator() : it_() {}
126 explicit forward_iterator(It it) : it_(it) {}
128 forward_iterator(const forward_iterator<U>& u) :it_(u.it_) {}
130 reference operator*() const {return *it_;}
131 pointer operator->() const {return it_;}
133 forward_iterator& operator++() {++it_; return *this;}
134 forward_iterator operator++(int)
135 {forward_iterator tmp(*this); ++(*this); return tmp;}
137 friend bool operator==(const forward_iterator& x, const forward_iterator& y)
138 {return x.it_ == y.it_;}
139 friend bool operator!=(const forward_iterator& x, const forward_iterator& y)
143 void operator,(T const &) DELETE_FUNCTION;
146 template <class T, class U>
149 operator==(const forward_iterator<T>& x, const forward_iterator<U>& y)
151 return x.base() == y.base();
154 template <class T, class U>
157 operator!=(const forward_iterator<T>& x, const forward_iterator<U>& y)
163 class bidirectional_iterator
167 template <class U> friend class bidirectional_iterator;
169 typedef std::bidirectional_iterator_tag iterator_category;
170 typedef typename std::iterator_traits<It>::value_type value_type;
171 typedef typename std::iterator_traits<It>::difference_type difference_type;
173 typedef typename std::iterator_traits<It>::reference reference;
175 It base() const {return it_;}
177 bidirectional_iterator() : it_() {}
178 explicit bidirectional_iterator(It it) : it_(it) {}
180 bidirectional_iterator(const bidirectional_iterator<U>& u) :it_(u.it_) {}
182 reference operator*() const {return *it_;}
183 pointer operator->() const {return it_;}
185 bidirectional_iterator& operator++() {++it_; return *this;}
186 bidirectional_iterator operator++(int)
187 {bidirectional_iterator tmp(*this); ++(*this); return tmp;}
189 bidirectional_iterator& operator--() {--it_; return *this;}
190 bidirectional_iterator operator--(int)
191 {bidirectional_iterator tmp(*this); --(*this); return tmp;}
194 void operator,(T const &) DELETE_FUNCTION;
197 template <class T, class U>
200 operator==(const bidirectional_iterator<T>& x, const bidirectional_iterator<U>& y)
202 return x.base() == y.base();
205 template <class T, class U>
208 operator!=(const bidirectional_iterator<T>& x, const bidirectional_iterator<U>& y)
214 class random_access_iterator
218 template <class U> friend class random_access_iterator;
220 typedef std::random_access_iterator_tag iterator_category;
221 typedef typename std::iterator_traits<It>::value_type value_type;
222 typedef typename std::iterator_traits<It>::difference_type difference_type;
224 typedef typename std::iterator_traits<It>::reference reference;
226 It base() const {return it_;}
228 random_access_iterator() : it_() {}
229 explicit random_access_iterator(It it) : it_(it) {}
231 random_access_iterator(const random_access_iterator<U>& u) :it_(u.it_) {}
233 reference operator*() const {return *it_;}
234 pointer operator->() const {return it_;}
236 random_access_iterator& operator++() {++it_; return *this;}
237 random_access_iterator operator++(int)
238 {random_access_iterator tmp(*this); ++(*this); return tmp;}
240 random_access_iterator& operator--() {--it_; return *this;}
241 random_access_iterator operator--(int)
242 {random_access_iterator tmp(*this); --(*this); return tmp;}
244 random_access_iterator& operator+=(difference_type n) {it_ += n; return *this;}
245 random_access_iterator operator+(difference_type n) const
246 {random_access_iterator tmp(*this); tmp += n; return tmp;}
247 friend random_access_iterator operator+(difference_type n, random_access_iterator x)
249 random_access_iterator& operator-=(difference_type n) {return *this += -n;}
250 random_access_iterator operator-(difference_type n) const
251 {random_access_iterator tmp(*this); tmp -= n; return tmp;}
253 reference operator[](difference_type n) const {return it_[n];}
256 void operator,(T const &) DELETE_FUNCTION;
259 template <class T, class U>
262 operator==(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
264 return x.base() == y.base();
267 template <class T, class U>
270 operator!=(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
275 template <class T, class U>
278 operator<(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
280 return x.base() < y.base();
283 template <class T, class U>
286 operator<=(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
291 template <class T, class U>
294 operator>(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
299 template <class T, class U>
302 operator>=(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
307 template <class T, class U>
309 typename std::iterator_traits<T>::difference_type
310 operator-(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
312 return x.base() - y.base();
315 template <class Iter>
316 inline Iter base(output_iterator<Iter> i) { return i.base(); }
318 template <class Iter>
319 inline Iter base(input_iterator<Iter> i) { return i.base(); }
321 template <class Iter>
322 inline Iter base(forward_iterator<Iter> i) { return i.base(); }
324 template <class Iter>
325 inline Iter base(bidirectional_iterator<Iter> i) { return i.base(); }
327 template <class Iter>
328 inline Iter base(random_access_iterator<Iter> i) { return i.base(); }
330 template <class Iter> // everything else
331 inline Iter base(Iter i) { return i; }
333 template <typename T>
334 struct ThrowingIterator {
335 typedef std::bidirectional_iterator_tag iterator_category;
336 typedef ptrdiff_t difference_type;
337 typedef const T value_type;
338 typedef const T * pointer;
339 typedef const T & reference;
341 enum ThrowingAction { TAIncrement, TADecrement, TADereference, TAAssignment, TAComparison };
345 : begin_(nullptr), end_(nullptr), current_(nullptr), action_(TADereference), index_(0) {}
346 ThrowingIterator (const T *first, const T *last, size_t index = 0, ThrowingAction action = TADereference)
347 : begin_(first), end_(last), current_(first), action_(action), index_(index) {}
348 ThrowingIterator (const ThrowingIterator &rhs)
349 : begin_(rhs.begin_), end_(rhs.end_), current_(rhs.current_), action_(rhs.action_), index_(rhs.index_) {}
350 ThrowingIterator & operator= (const ThrowingIterator &rhs)
352 if (action_ == TAAssignment)
355 #ifndef TEST_HAS_NO_EXCEPTIONS
356 throw std::runtime_error ("throw from iterator assignment");
366 current_ = rhs.current_;
367 action_ = rhs.action_;
372 // iterator operations
373 reference operator*() const
375 if (action_ == TADereference)
378 #ifndef TEST_HAS_NO_EXCEPTIONS
379 throw std::runtime_error ("throw from iterator dereference");
389 ThrowingIterator & operator++()
391 if (action_ == TAIncrement)
394 #ifndef TEST_HAS_NO_EXCEPTIONS
395 throw std::runtime_error ("throw from iterator increment");
406 ThrowingIterator operator++(int)
408 ThrowingIterator temp = *this;
413 ThrowingIterator & operator--()
415 if (action_ == TADecrement)
418 #ifndef TEST_HAS_NO_EXCEPTIONS
419 throw std::runtime_error ("throw from iterator decrement");
430 ThrowingIterator operator--(int) {
431 ThrowingIterator temp = *this;
436 bool operator== (const ThrowingIterator &rhs) const
438 if (action_ == TAComparison)
441 #ifndef TEST_HAS_NO_EXCEPTIONS
442 throw std::runtime_error ("throw from iterator comparison");
449 bool atEndL = current_ == end_;
450 bool atEndR = rhs.current_ == rhs.end_;
451 if (atEndL != atEndR) return false; // one is at the end (or empty), the other is not.
452 if (atEndL) return true; // both are at the end (or empty)
453 return current_ == rhs.current_;
460 ThrowingAction action_;
461 mutable size_t index_;
464 template <typename T>
465 bool operator== (const ThrowingIterator<T>& a, const ThrowingIterator<T>& b)
466 { return a.operator==(b); }
468 template <typename T>
469 bool operator!= (const ThrowingIterator<T>& a, const ThrowingIterator<T>& b)
470 { return !a.operator==(b); }
472 template <typename T>
473 struct NonThrowingIterator {
474 typedef std::bidirectional_iterator_tag iterator_category;
475 typedef ptrdiff_t difference_type;
476 typedef const T value_type;
477 typedef const T * pointer;
478 typedef const T & reference;
481 NonThrowingIterator ()
482 : begin_(nullptr), end_(nullptr), current_(nullptr) {}
483 NonThrowingIterator (const T *first, const T* last)
484 : begin_(first), end_(last), current_(first) {}
485 NonThrowingIterator (const NonThrowingIterator &rhs)
486 : begin_(rhs.begin_), end_(rhs.end_), current_(rhs.current_) {}
487 NonThrowingIterator & operator= (const NonThrowingIterator &rhs) TEST_NOEXCEPT
491 current_ = rhs.current_;
495 // iterator operations
496 reference operator*() const TEST_NOEXCEPT
501 NonThrowingIterator & operator++() TEST_NOEXCEPT
507 NonThrowingIterator operator++(int) TEST_NOEXCEPT
509 NonThrowingIterator temp = *this;
514 NonThrowingIterator & operator--() TEST_NOEXCEPT
520 NonThrowingIterator operator--(int) TEST_NOEXCEPT
522 NonThrowingIterator temp = *this;
527 bool operator== (const NonThrowingIterator &rhs) const TEST_NOEXCEPT
529 bool atEndL = current_ == end_;
530 bool atEndR = rhs.current_ == rhs.end_;
531 if (atEndL != atEndR) return false; // one is at the end (or empty), the other is not.
532 if (atEndL) return true; // both are at the end (or empty)
533 return current_ == rhs.current_;
542 template <typename T>
543 bool operator== (const NonThrowingIterator<T>& a, const NonThrowingIterator<T>& b) TEST_NOEXCEPT
544 { return a.operator==(b); }
546 template <typename T>
547 bool operator!= (const NonThrowingIterator<T>& a, const NonThrowingIterator<T>& b) TEST_NOEXCEPT
548 { return !a.operator==(b); }
550 #undef DELETE_FUNCTION
552 #endif // ITERATORS_H