blob: 0fdb225b2c713d8677e7276bb93b17f769f94884 [file] [log] [blame]
Marshall Clow354d39c2014-01-16 16:58:45 +00001//===----------------------------------------------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Howard Hinnantc1198c32010-07-16 19:08:36 +000010#ifndef ITERATORS_H
11#define ITERATORS_H
12
13#include <iterator>
Marshall Clow76b4afc2016-01-13 21:54:34 +000014#include <stdexcept>
Eric Fiselier71c425f2016-05-27 23:43:29 +000015#include <cstddef>
Marshall Clow29298662014-09-17 04:09:35 +000016#include <cassert>
Howard Hinnantc1198c32010-07-16 19:08:36 +000017
Marshall Clow76b4afc2016-01-13 21:54:34 +000018#include "test_macros.h"
19
Eric Fiselier8f56ded2017-01-06 20:58:25 +000020#if TEST_STD_VER >= 11
Eric Fiselier847ee132014-10-27 20:26:25 +000021#define DELETE_FUNCTION = delete
22#else
23#define DELETE_FUNCTION
24#endif
25
Howard Hinnantc1198c32010-07-16 19:08:36 +000026template <class It>
Howard Hinnant48b242a2010-08-14 18:14:02 +000027class output_iterator
28{
29 It it_;
30
31 template <class U> friend class output_iterator;
32public:
33 typedef std::output_iterator_tag iterator_category;
Marshall Clow44761002013-01-09 17:20:02 +000034 typedef void value_type;
Howard Hinnant48b242a2010-08-14 18:14:02 +000035 typedef typename std::iterator_traits<It>::difference_type difference_type;
36 typedef It pointer;
37 typedef typename std::iterator_traits<It>::reference reference;
38
39 It base() const {return it_;}
40
Marshall Clowcf1589f2013-01-03 02:29:29 +000041 output_iterator () {}
Howard Hinnant48b242a2010-08-14 18:14:02 +000042 explicit output_iterator(It it) : it_(it) {}
43 template <class U>
44 output_iterator(const output_iterator<U>& u) :it_(u.it_) {}
45
46 reference operator*() const {return *it_;}
47
48 output_iterator& operator++() {++it_; return *this;}
49 output_iterator operator++(int)
50 {output_iterator tmp(*this); ++(*this); return tmp;}
Eric Fiselier910285b2014-10-27 19:28:20 +000051
52 template <class T>
Eric Fiselier847ee132014-10-27 20:26:25 +000053 void operator,(T const &) DELETE_FUNCTION;
Howard Hinnant48b242a2010-08-14 18:14:02 +000054};
55
Eric Fiselier2fc65042016-08-28 21:26:01 +000056template <class It,
57 class ItTraits = It>
Howard Hinnantc1198c32010-07-16 19:08:36 +000058class input_iterator
59{
Eric Fiseliere7154702016-08-28 22:14:37 +000060 typedef std::iterator_traits<ItTraits> Traits;
Howard Hinnantc1198c32010-07-16 19:08:36 +000061 It it_;
62
Eric Fiselier2fc65042016-08-28 21:26:01 +000063 template <class U, class T> friend class input_iterator;
Howard Hinnantc1198c32010-07-16 19:08:36 +000064public:
65 typedef std::input_iterator_tag iterator_category;
Eric Fiselier2fc65042016-08-28 21:26:01 +000066 typedef typename Traits::value_type value_type;
67 typedef typename Traits::difference_type difference_type;
Howard Hinnantc1198c32010-07-16 19:08:36 +000068 typedef It pointer;
Eric Fiselier2fc65042016-08-28 21:26:01 +000069 typedef typename Traits::reference reference;
Howard Hinnantc1198c32010-07-16 19:08:36 +000070
Marshall Clowf51ee632017-05-17 18:51:36 +000071 TEST_CONSTEXPR_CXX14 It base() const {return it_;}
Howard Hinnantc1198c32010-07-16 19:08:36 +000072
Marshall Clowf51ee632017-05-17 18:51:36 +000073 TEST_CONSTEXPR_CXX14 input_iterator() : it_() {}
74 explicit TEST_CONSTEXPR_CXX14 input_iterator(It it) : it_(it) {}
Eric Fiselier2fc65042016-08-28 21:26:01 +000075 template <class U, class T>
Marshall Clowf51ee632017-05-17 18:51:36 +000076 TEST_CONSTEXPR_CXX14 input_iterator(const input_iterator<U, T>& u) :it_(u.it_) {}
Howard Hinnantc1198c32010-07-16 19:08:36 +000077
Marshall Clowf51ee632017-05-17 18:51:36 +000078 TEST_CONSTEXPR_CXX14 reference operator*() const {return *it_;}
79 TEST_CONSTEXPR_CXX14 pointer operator->() const {return it_;}
Howard Hinnantc1198c32010-07-16 19:08:36 +000080
Marshall Clowf51ee632017-05-17 18:51:36 +000081 TEST_CONSTEXPR_CXX14 input_iterator& operator++() {++it_; return *this;}
82 TEST_CONSTEXPR_CXX14 input_iterator operator++(int)
Howard Hinnantc1198c32010-07-16 19:08:36 +000083 {input_iterator tmp(*this); ++(*this); return tmp;}
84
Marshall Clowf51ee632017-05-17 18:51:36 +000085 friend TEST_CONSTEXPR_CXX14 bool operator==(const input_iterator& x, const input_iterator& y)
Howard Hinnantc1198c32010-07-16 19:08:36 +000086 {return x.it_ == y.it_;}
Marshall Clowf51ee632017-05-17 18:51:36 +000087 friend TEST_CONSTEXPR_CXX14 bool operator!=(const input_iterator& x, const input_iterator& y)
Howard Hinnantc1198c32010-07-16 19:08:36 +000088 {return !(x == y);}
Eric Fiselier910285b2014-10-27 19:28:20 +000089
90 template <class T>
Eric Fiselier847ee132014-10-27 20:26:25 +000091 void operator,(T const &) DELETE_FUNCTION;
Howard Hinnantc1198c32010-07-16 19:08:36 +000092};
93
Eric Fiselier2fc65042016-08-28 21:26:01 +000094template <class T, class TV, class U, class UV>
Howard Hinnantc1198c32010-07-16 19:08:36 +000095inline
96bool
Eric Fiselier2fc65042016-08-28 21:26:01 +000097operator==(const input_iterator<T, TV>& x, const input_iterator<U, UV>& y)
Howard Hinnantc1198c32010-07-16 19:08:36 +000098{
99 return x.base() == y.base();
100}
101
Eric Fiselier2fc65042016-08-28 21:26:01 +0000102template <class T, class TV, class U, class UV>
Howard Hinnantc1198c32010-07-16 19:08:36 +0000103inline
104bool
Eric Fiselier2fc65042016-08-28 21:26:01 +0000105operator!=(const input_iterator<T, TV>& x, const input_iterator<U, UV>& y)
Howard Hinnantc1198c32010-07-16 19:08:36 +0000106{
107 return !(x == y);
108}
109
110template <class It>
111class forward_iterator
112{
113 It it_;
114
115 template <class U> friend class forward_iterator;
116public:
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;
120 typedef It pointer;
121 typedef typename std::iterator_traits<It>::reference reference;
122
Marshall Clowf51ee632017-05-17 18:51:36 +0000123 TEST_CONSTEXPR_CXX14 It base() const {return it_;}
Howard Hinnantc1198c32010-07-16 19:08:36 +0000124
Marshall Clowf51ee632017-05-17 18:51:36 +0000125 TEST_CONSTEXPR_CXX14 forward_iterator() : it_() {}
126 explicit TEST_CONSTEXPR_CXX14 forward_iterator(It it) : it_(it) {}
Howard Hinnantc1198c32010-07-16 19:08:36 +0000127 template <class U>
Marshall Clowf51ee632017-05-17 18:51:36 +0000128 TEST_CONSTEXPR_CXX14 forward_iterator(const forward_iterator<U>& u) :it_(u.it_) {}
Howard Hinnantc1198c32010-07-16 19:08:36 +0000129
Marshall Clowf51ee632017-05-17 18:51:36 +0000130 TEST_CONSTEXPR_CXX14 reference operator*() const {return *it_;}
131 TEST_CONSTEXPR_CXX14 pointer operator->() const {return it_;}
Howard Hinnantc1198c32010-07-16 19:08:36 +0000132
Marshall Clowf51ee632017-05-17 18:51:36 +0000133 TEST_CONSTEXPR_CXX14 forward_iterator& operator++() {++it_; return *this;}
134 TEST_CONSTEXPR_CXX14 forward_iterator operator++(int)
Howard Hinnantc1198c32010-07-16 19:08:36 +0000135 {forward_iterator tmp(*this); ++(*this); return tmp;}
136
Marshall Clowf51ee632017-05-17 18:51:36 +0000137 friend TEST_CONSTEXPR_CXX14 bool operator==(const forward_iterator& x, const forward_iterator& y)
Howard Hinnantc1198c32010-07-16 19:08:36 +0000138 {return x.it_ == y.it_;}
Marshall Clowf51ee632017-05-17 18:51:36 +0000139 friend TEST_CONSTEXPR_CXX14 bool operator!=(const forward_iterator& x, const forward_iterator& y)
Howard Hinnantc1198c32010-07-16 19:08:36 +0000140 {return !(x == y);}
Eric Fiselier910285b2014-10-27 19:28:20 +0000141
142 template <class T>
Eric Fiselier847ee132014-10-27 20:26:25 +0000143 void operator,(T const &) DELETE_FUNCTION;
Howard Hinnantc1198c32010-07-16 19:08:36 +0000144};
145
146template <class T, class U>
147inline
Marshall Clowf51ee632017-05-17 18:51:36 +0000148bool TEST_CONSTEXPR_CXX14
Howard Hinnantc1198c32010-07-16 19:08:36 +0000149operator==(const forward_iterator<T>& x, const forward_iterator<U>& y)
150{
151 return x.base() == y.base();
152}
153
154template <class T, class U>
155inline
Marshall Clowf51ee632017-05-17 18:51:36 +0000156bool TEST_CONSTEXPR_CXX14
Howard Hinnantc1198c32010-07-16 19:08:36 +0000157operator!=(const forward_iterator<T>& x, const forward_iterator<U>& y)
158{
159 return !(x == y);
160}
161
162template <class It>
163class bidirectional_iterator
164{
165 It it_;
166
167 template <class U> friend class bidirectional_iterator;
168public:
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;
172 typedef It pointer;
173 typedef typename std::iterator_traits<It>::reference reference;
174
Marshall Clowf51ee632017-05-17 18:51:36 +0000175 TEST_CONSTEXPR_CXX14 It base() const {return it_;}
Howard Hinnantc1198c32010-07-16 19:08:36 +0000176
Marshall Clowf51ee632017-05-17 18:51:36 +0000177 TEST_CONSTEXPR_CXX14 bidirectional_iterator() : it_() {}
178 explicit TEST_CONSTEXPR_CXX14 bidirectional_iterator(It it) : it_(it) {}
Howard Hinnantc1198c32010-07-16 19:08:36 +0000179 template <class U>
Marshall Clowf51ee632017-05-17 18:51:36 +0000180 TEST_CONSTEXPR_CXX14 bidirectional_iterator(const bidirectional_iterator<U>& u) :it_(u.it_) {}
Howard Hinnantc1198c32010-07-16 19:08:36 +0000181
Marshall Clowf51ee632017-05-17 18:51:36 +0000182 TEST_CONSTEXPR_CXX14 reference operator*() const {return *it_;}
183 TEST_CONSTEXPR_CXX14 pointer operator->() const {return it_;}
Howard Hinnantc1198c32010-07-16 19:08:36 +0000184
Marshall Clowf51ee632017-05-17 18:51:36 +0000185 TEST_CONSTEXPR_CXX14 bidirectional_iterator& operator++() {++it_; return *this;}
186 TEST_CONSTEXPR_CXX14 bidirectional_iterator operator++(int)
Howard Hinnantc1198c32010-07-16 19:08:36 +0000187 {bidirectional_iterator tmp(*this); ++(*this); return tmp;}
188
Marshall Clowf51ee632017-05-17 18:51:36 +0000189 TEST_CONSTEXPR_CXX14 bidirectional_iterator& operator--() {--it_; return *this;}
190 TEST_CONSTEXPR_CXX14 bidirectional_iterator operator--(int)
Howard Hinnantc1198c32010-07-16 19:08:36 +0000191 {bidirectional_iterator tmp(*this); --(*this); return tmp;}
Eric Fiselier910285b2014-10-27 19:28:20 +0000192
193 template <class T>
Eric Fiselier847ee132014-10-27 20:26:25 +0000194 void operator,(T const &) DELETE_FUNCTION;
Howard Hinnantc1198c32010-07-16 19:08:36 +0000195};
196
197template <class T, class U>
198inline
Marshall Clowf51ee632017-05-17 18:51:36 +0000199bool TEST_CONSTEXPR_CXX14
Howard Hinnantc1198c32010-07-16 19:08:36 +0000200operator==(const bidirectional_iterator<T>& x, const bidirectional_iterator<U>& y)
201{
202 return x.base() == y.base();
203}
204
205template <class T, class U>
206inline
Marshall Clowf51ee632017-05-17 18:51:36 +0000207bool TEST_CONSTEXPR_CXX14
Howard Hinnantc1198c32010-07-16 19:08:36 +0000208operator!=(const bidirectional_iterator<T>& x, const bidirectional_iterator<U>& y)
209{
210 return !(x == y);
211}
212
213template <class It>
214class random_access_iterator
215{
216 It it_;
217
218 template <class U> friend class random_access_iterator;
219public:
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;
223 typedef It pointer;
224 typedef typename std::iterator_traits<It>::reference reference;
225
Marshall Clowf51ee632017-05-17 18:51:36 +0000226 TEST_CONSTEXPR_CXX14 It base() const {return it_;}
Howard Hinnantc1198c32010-07-16 19:08:36 +0000227
Marshall Clowf51ee632017-05-17 18:51:36 +0000228 TEST_CONSTEXPR_CXX14 random_access_iterator() : it_() {}
229 explicit TEST_CONSTEXPR_CXX14 random_access_iterator(It it) : it_(it) {}
230 template <class U>
231 TEST_CONSTEXPR_CXX14 random_access_iterator(const random_access_iterator<U>& u) :it_(u.it_) {}
Howard Hinnantc1198c32010-07-16 19:08:36 +0000232
Marshall Clowf51ee632017-05-17 18:51:36 +0000233 TEST_CONSTEXPR_CXX14 reference operator*() const {return *it_;}
234 TEST_CONSTEXPR_CXX14 pointer operator->() const {return it_;}
Howard Hinnantc1198c32010-07-16 19:08:36 +0000235
Marshall Clowf51ee632017-05-17 18:51:36 +0000236 TEST_CONSTEXPR_CXX14 random_access_iterator& operator++() {++it_; return *this;}
237 TEST_CONSTEXPR_CXX14 random_access_iterator operator++(int)
Howard Hinnantc1198c32010-07-16 19:08:36 +0000238 {random_access_iterator tmp(*this); ++(*this); return tmp;}
239
Marshall Clowf51ee632017-05-17 18:51:36 +0000240 TEST_CONSTEXPR_CXX14 random_access_iterator& operator--() {--it_; return *this;}
241 TEST_CONSTEXPR_CXX14 random_access_iterator operator--(int)
Howard Hinnantc1198c32010-07-16 19:08:36 +0000242 {random_access_iterator tmp(*this); --(*this); return tmp;}
243
Marshall Clowf51ee632017-05-17 18:51:36 +0000244 TEST_CONSTEXPR_CXX14 random_access_iterator& operator+=(difference_type n) {it_ += n; return *this;}
245 TEST_CONSTEXPR_CXX14 random_access_iterator operator+(difference_type n) const
Howard Hinnantc1198c32010-07-16 19:08:36 +0000246 {random_access_iterator tmp(*this); tmp += n; return tmp;}
Marshall Clowf51ee632017-05-17 18:51:36 +0000247 friend TEST_CONSTEXPR_CXX14 random_access_iterator operator+(difference_type n, random_access_iterator x)
Howard Hinnantc1198c32010-07-16 19:08:36 +0000248 {x += n; return x;}
Marshall Clowf51ee632017-05-17 18:51:36 +0000249 TEST_CONSTEXPR_CXX14 random_access_iterator& operator-=(difference_type n) {return *this += -n;}
250 TEST_CONSTEXPR_CXX14 random_access_iterator operator-(difference_type n) const
Howard Hinnantc1198c32010-07-16 19:08:36 +0000251 {random_access_iterator tmp(*this); tmp -= n; return tmp;}
252
Marshall Clowf51ee632017-05-17 18:51:36 +0000253 TEST_CONSTEXPR_CXX14 reference operator[](difference_type n) const {return it_[n];}
Eric Fiselier910285b2014-10-27 19:28:20 +0000254
255 template <class T>
Eric Fiselier847ee132014-10-27 20:26:25 +0000256 void operator,(T const &) DELETE_FUNCTION;
Howard Hinnantc1198c32010-07-16 19:08:36 +0000257};
258
259template <class T, class U>
260inline
Marshall Clowf51ee632017-05-17 18:51:36 +0000261bool TEST_CONSTEXPR_CXX14
Howard Hinnantc1198c32010-07-16 19:08:36 +0000262operator==(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
263{
264 return x.base() == y.base();
265}
266
267template <class T, class U>
268inline
Marshall Clowf51ee632017-05-17 18:51:36 +0000269bool TEST_CONSTEXPR_CXX14
Howard Hinnantc1198c32010-07-16 19:08:36 +0000270operator!=(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
271{
272 return !(x == y);
273}
274
275template <class T, class U>
276inline
Marshall Clowf51ee632017-05-17 18:51:36 +0000277bool TEST_CONSTEXPR_CXX14
Howard Hinnantc1198c32010-07-16 19:08:36 +0000278operator<(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
279{
280 return x.base() < y.base();
281}
282
283template <class T, class U>
284inline
Marshall Clowf51ee632017-05-17 18:51:36 +0000285bool TEST_CONSTEXPR_CXX14
Howard Hinnantc1198c32010-07-16 19:08:36 +0000286operator<=(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
287{
288 return !(y < x);
289}
290
291template <class T, class U>
292inline
Marshall Clowf51ee632017-05-17 18:51:36 +0000293bool TEST_CONSTEXPR_CXX14
Howard Hinnantc1198c32010-07-16 19:08:36 +0000294operator>(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
295{
296 return y < x;
297}
298
299template <class T, class U>
300inline
Marshall Clowf51ee632017-05-17 18:51:36 +0000301bool TEST_CONSTEXPR_CXX14
Howard Hinnantc1198c32010-07-16 19:08:36 +0000302operator>=(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
303{
304 return !(x < y);
305}
306
307template <class T, class U>
Marshall Clowf51ee632017-05-17 18:51:36 +0000308inline TEST_CONSTEXPR_CXX14
Howard Hinnantc1198c32010-07-16 19:08:36 +0000309typename std::iterator_traits<T>::difference_type
310operator-(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
311{
312 return x.base() - y.base();
313}
314
Marshall Clowf8c2b822013-01-04 18:24:04 +0000315template <class Iter>
Marshall Clowf51ee632017-05-17 18:51:36 +0000316inline TEST_CONSTEXPR_CXX14 Iter base(output_iterator<Iter> i) { return i.base(); }
Marshall Clowf8c2b822013-01-04 18:24:04 +0000317
318template <class Iter>
Marshall Clowf51ee632017-05-17 18:51:36 +0000319inline TEST_CONSTEXPR_CXX14 Iter base(input_iterator<Iter> i) { return i.base(); }
Marshall Clowf8c2b822013-01-04 18:24:04 +0000320
321template <class Iter>
Marshall Clowf51ee632017-05-17 18:51:36 +0000322inline TEST_CONSTEXPR_CXX14 Iter base(forward_iterator<Iter> i) { return i.base(); }
Marshall Clowf8c2b822013-01-04 18:24:04 +0000323
324template <class Iter>
Marshall Clowf51ee632017-05-17 18:51:36 +0000325inline TEST_CONSTEXPR_CXX14 Iter base(bidirectional_iterator<Iter> i) { return i.base(); }
Marshall Clowf8c2b822013-01-04 18:24:04 +0000326
327template <class Iter>
Marshall Clowf51ee632017-05-17 18:51:36 +0000328inline TEST_CONSTEXPR_CXX14 Iter base(random_access_iterator<Iter> i) { return i.base(); }
Marshall Clowf8c2b822013-01-04 18:24:04 +0000329
Howard Hinnante0fe3d22013-07-08 21:06:38 +0000330template <class Iter> // everything else
Marshall Clowf51ee632017-05-17 18:51:36 +0000331inline TEST_CONSTEXPR_CXX14 Iter base(Iter i) { return i; }
Marshall Clowf8c2b822013-01-04 18:24:04 +0000332
Marshall Clow76b4afc2016-01-13 21:54:34 +0000333template <typename T>
334struct 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;
340
Marshall Clow64ca6862016-01-20 03:37:46 +0000341 enum ThrowingAction { TAIncrement, TADecrement, TADereference, TAAssignment, TAComparison };
Marshall Clow76b4afc2016-01-13 21:54:34 +0000342
Marshall Clow64ca6862016-01-20 03:37:46 +0000343// Constructors
344 ThrowingIterator ()
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)
351 {
352 if (action_ == TAAssignment)
353 {
354 if (index_ == 0)
Marshall Clow9d10d272016-01-20 03:19:15 +0000355#ifndef TEST_HAS_NO_EXCEPTIONS
Marshall Clow64ca6862016-01-20 03:37:46 +0000356 throw std::runtime_error ("throw from iterator assignment");
Marshall Clow9d10d272016-01-20 03:19:15 +0000357#else
Marshall Clow64ca6862016-01-20 03:37:46 +0000358 assert(false);
Marshall Clow9d10d272016-01-20 03:19:15 +0000359#endif
360
Marshall Clow64ca6862016-01-20 03:37:46 +0000361 else
362 --index_;
363 }
364 begin_ = rhs.begin_;
365 end_ = rhs.end_;
366 current_ = rhs.current_;
367 action_ = rhs.action_;
368 index_ = rhs.index_;
369 return *this;
370 }
Marshall Clow76b4afc2016-01-13 21:54:34 +0000371
Marshall Clow64ca6862016-01-20 03:37:46 +0000372// iterator operations
373 reference operator*() const
374 {
375 if (action_ == TADereference)
376 {
377 if (index_ == 0)
Marshall Clow9d10d272016-01-20 03:19:15 +0000378#ifndef TEST_HAS_NO_EXCEPTIONS
Marshall Clow64ca6862016-01-20 03:37:46 +0000379 throw std::runtime_error ("throw from iterator dereference");
Marshall Clow9d10d272016-01-20 03:19:15 +0000380#else
Marshall Clow64ca6862016-01-20 03:37:46 +0000381 assert(false);
Marshall Clow9d10d272016-01-20 03:19:15 +0000382#endif
Marshall Clow64ca6862016-01-20 03:37:46 +0000383 else
384 --index_;
385 }
386 return *current_;
387 }
Marshall Clow76b4afc2016-01-13 21:54:34 +0000388
Marshall Clow64ca6862016-01-20 03:37:46 +0000389 ThrowingIterator & operator++()
390 {
391 if (action_ == TAIncrement)
392 {
393 if (index_ == 0)
Marshall Clow9d10d272016-01-20 03:19:15 +0000394#ifndef TEST_HAS_NO_EXCEPTIONS
Marshall Clow64ca6862016-01-20 03:37:46 +0000395 throw std::runtime_error ("throw from iterator increment");
Marshall Clow9d10d272016-01-20 03:19:15 +0000396#else
Marshall Clow64ca6862016-01-20 03:37:46 +0000397 assert(false);
Marshall Clow9d10d272016-01-20 03:19:15 +0000398#endif
Marshall Clow64ca6862016-01-20 03:37:46 +0000399 else
400 --index_;
401 }
402 ++current_;
403 return *this;
404 }
Eric Fiselierd04c6852016-06-01 21:35:39 +0000405
Marshall Clow64ca6862016-01-20 03:37:46 +0000406 ThrowingIterator operator++(int)
407 {
408 ThrowingIterator temp = *this;
409 ++(*this);
410 return temp;
411 }
Marshall Clow76b4afc2016-01-13 21:54:34 +0000412
Marshall Clow64ca6862016-01-20 03:37:46 +0000413 ThrowingIterator & operator--()
414 {
415 if (action_ == TADecrement)
416 {
417 if (index_ == 0)
Marshall Clow9d10d272016-01-20 03:19:15 +0000418#ifndef TEST_HAS_NO_EXCEPTIONS
Marshall Clow64ca6862016-01-20 03:37:46 +0000419 throw std::runtime_error ("throw from iterator decrement");
Marshall Clow9d10d272016-01-20 03:19:15 +0000420#else
Marshall Clow64ca6862016-01-20 03:37:46 +0000421 assert(false);
Marshall Clow9d10d272016-01-20 03:19:15 +0000422#endif
Marshall Clow64ca6862016-01-20 03:37:46 +0000423 else
424 --index_;
425 }
426 --current_;
427 return *this;
428 }
Marshall Clow76b4afc2016-01-13 21:54:34 +0000429
Marshall Clow64ca6862016-01-20 03:37:46 +0000430 ThrowingIterator operator--(int) {
431 ThrowingIterator temp = *this;
432 --(*this);
433 return temp;
434 }
Marshall Clow76b4afc2016-01-13 21:54:34 +0000435
Marshall Clow64ca6862016-01-20 03:37:46 +0000436 bool operator== (const ThrowingIterator &rhs) const
437 {
438 if (action_ == TAComparison)
439 {
440 if (index_ == 0)
Marshall Clow9d10d272016-01-20 03:19:15 +0000441#ifndef TEST_HAS_NO_EXCEPTIONS
Marshall Clow64ca6862016-01-20 03:37:46 +0000442 throw std::runtime_error ("throw from iterator comparison");
Marshall Clow9d10d272016-01-20 03:19:15 +0000443#else
Marshall Clow64ca6862016-01-20 03:37:46 +0000444 assert(false);
Marshall Clow9d10d272016-01-20 03:19:15 +0000445#endif
Marshall Clow64ca6862016-01-20 03:37:46 +0000446 else
447 --index_;
448 }
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_;
454 }
Marshall Clow76b4afc2016-01-13 21:54:34 +0000455
456private:
Marshall Clow64ca6862016-01-20 03:37:46 +0000457 const T* begin_;
458 const T* end_;
459 const T* current_;
460 ThrowingAction action_;
461 mutable size_t index_;
Marshall Clow76b4afc2016-01-13 21:54:34 +0000462};
463
464template <typename T>
465bool operator== (const ThrowingIterator<T>& a, const ThrowingIterator<T>& b)
Marshall Clow64ca6862016-01-20 03:37:46 +0000466{ return a.operator==(b); }
Marshall Clow76b4afc2016-01-13 21:54:34 +0000467
468template <typename T>
469bool operator!= (const ThrowingIterator<T>& a, const ThrowingIterator<T>& b)
Marshall Clow64ca6862016-01-20 03:37:46 +0000470{ return !a.operator==(b); }
Eric Fiselierd04c6852016-06-01 21:35:39 +0000471
Marshall Clow76b4afc2016-01-13 21:54:34 +0000472template <typename T>
473struct 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;
479
Marshall Clow64ca6862016-01-20 03:37:46 +0000480// Constructors
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
488 {
489 begin_ = rhs.begin_;
490 end_ = rhs.end_;
491 current_ = rhs.current_;
492 return *this;
493 }
Marshall Clow76b4afc2016-01-13 21:54:34 +0000494
Marshall Clow64ca6862016-01-20 03:37:46 +0000495// iterator operations
496 reference operator*() const TEST_NOEXCEPT
497 {
498 return *current_;
499 }
Marshall Clow76b4afc2016-01-13 21:54:34 +0000500
Marshall Clow64ca6862016-01-20 03:37:46 +0000501 NonThrowingIterator & operator++() TEST_NOEXCEPT
502 {
503 ++current_;
504 return *this;
505 }
Eric Fiselierd04c6852016-06-01 21:35:39 +0000506
Marshall Clow64ca6862016-01-20 03:37:46 +0000507 NonThrowingIterator operator++(int) TEST_NOEXCEPT
508 {
509 NonThrowingIterator temp = *this;
510 ++(*this);
511 return temp;
512 }
Marshall Clow76b4afc2016-01-13 21:54:34 +0000513
Marshall Clow64ca6862016-01-20 03:37:46 +0000514 NonThrowingIterator & operator--() TEST_NOEXCEPT
515 {
516 --current_;
517 return *this;
518 }
Marshall Clow76b4afc2016-01-13 21:54:34 +0000519
Marshall Clow64ca6862016-01-20 03:37:46 +0000520 NonThrowingIterator operator--(int) TEST_NOEXCEPT
521 {
522 NonThrowingIterator temp = *this;
523 --(*this);
524 return temp;
525 }
Marshall Clow76b4afc2016-01-13 21:54:34 +0000526
Marshall Clow64ca6862016-01-20 03:37:46 +0000527 bool operator== (const NonThrowingIterator &rhs) const TEST_NOEXCEPT
528 {
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_;
534 }
Marshall Clow76b4afc2016-01-13 21:54:34 +0000535
536private:
Marshall Clow64ca6862016-01-20 03:37:46 +0000537 const T* begin_;
538 const T* end_;
539 const T* current_;
Marshall Clow76b4afc2016-01-13 21:54:34 +0000540};
541
542template <typename T>
543bool operator== (const NonThrowingIterator<T>& a, const NonThrowingIterator<T>& b) TEST_NOEXCEPT
Marshall Clow64ca6862016-01-20 03:37:46 +0000544{ return a.operator==(b); }
Marshall Clow76b4afc2016-01-13 21:54:34 +0000545
546template <typename T>
547bool operator!= (const NonThrowingIterator<T>& a, const NonThrowingIterator<T>& b) TEST_NOEXCEPT
Marshall Clow64ca6862016-01-20 03:37:46 +0000548{ return !a.operator==(b); }
Marshall Clow76b4afc2016-01-13 21:54:34 +0000549
Eric Fiselier847ee132014-10-27 20:26:25 +0000550#undef DELETE_FUNCTION
551
Howard Hinnantf36101d2010-08-22 00:45:01 +0000552#endif // ITERATORS_H