blob: a54787af1b6327911595ef41fb6808403c0e0b6b [file] [log] [blame]
Marshall Clow354d39c2014-01-16 16:58:45 +00001//===----------------------------------------------------------------------===//
2//
Chandler Carruth57b08b02019-01-19 10:56:40 +00003// 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
Marshall Clow354d39c2014-01-16 16:58:45 +00006//
7//===----------------------------------------------------------------------===//
8
Howard Hinnantc1198c32010-07-16 19:08:36 +00009#ifndef ITERATORS_H
10#define ITERATORS_H
11
12#include <iterator>
Marshall Clow76b4afc2016-01-13 21:54:34 +000013#include <stdexcept>
Eric Fiselier71c425f2016-05-27 23:43:29 +000014#include <cstddef>
Marshall Clow29298662014-09-17 04:09:35 +000015#include <cassert>
Howard Hinnantc1198c32010-07-16 19:08:36 +000016
Marshall Clow76b4afc2016-01-13 21:54:34 +000017#include "test_macros.h"
18
Eric Fiselier8f56ded2017-01-06 20:58:25 +000019#if TEST_STD_VER >= 11
Eric Fiselier847ee132014-10-27 20:26:25 +000020#define DELETE_FUNCTION = delete
21#else
22#define DELETE_FUNCTION
23#endif
24
Howard Hinnantc1198c32010-07-16 19:08:36 +000025template <class It>
Howard Hinnant48b242a2010-08-14 18:14:02 +000026class output_iterator
27{
28 It it_;
29
30 template <class U> friend class output_iterator;
31public:
32 typedef std::output_iterator_tag iterator_category;
Marshall Clow44761002013-01-09 17:20:02 +000033 typedef void value_type;
Howard Hinnant48b242a2010-08-14 18:14:02 +000034 typedef typename std::iterator_traits<It>::difference_type difference_type;
35 typedef It pointer;
36 typedef typename std::iterator_traits<It>::reference reference;
37
38 It base() const {return it_;}
39
Marshall Clowcf1589f2013-01-03 02:29:29 +000040 output_iterator () {}
Howard Hinnant48b242a2010-08-14 18:14:02 +000041 explicit output_iterator(It it) : it_(it) {}
42 template <class U>
43 output_iterator(const output_iterator<U>& u) :it_(u.it_) {}
44
45 reference operator*() const {return *it_;}
46
47 output_iterator& operator++() {++it_; return *this;}
48 output_iterator operator++(int)
49 {output_iterator tmp(*this); ++(*this); return tmp;}
Eric Fiselier910285b2014-10-27 19:28:20 +000050
51 template <class T>
Eric Fiselier847ee132014-10-27 20:26:25 +000052 void operator,(T const &) DELETE_FUNCTION;
Howard Hinnant48b242a2010-08-14 18:14:02 +000053};
54
Eric Fiselier2fc65042016-08-28 21:26:01 +000055template <class It,
56 class ItTraits = It>
Howard Hinnantc1198c32010-07-16 19:08:36 +000057class input_iterator
58{
Eric Fiseliere7154702016-08-28 22:14:37 +000059 typedef std::iterator_traits<ItTraits> Traits;
Howard Hinnantc1198c32010-07-16 19:08:36 +000060 It it_;
61
Eric Fiselier2fc65042016-08-28 21:26:01 +000062 template <class U, class T> friend class input_iterator;
Howard Hinnantc1198c32010-07-16 19:08:36 +000063public:
64 typedef std::input_iterator_tag iterator_category;
Eric Fiselier2fc65042016-08-28 21:26:01 +000065 typedef typename Traits::value_type value_type;
66 typedef typename Traits::difference_type difference_type;
Howard Hinnantc1198c32010-07-16 19:08:36 +000067 typedef It pointer;
Eric Fiselier2fc65042016-08-28 21:26:01 +000068 typedef typename Traits::reference reference;
Howard Hinnantc1198c32010-07-16 19:08:36 +000069
Marshall Clowf51ee632017-05-17 18:51:36 +000070 TEST_CONSTEXPR_CXX14 It base() const {return it_;}
Howard Hinnantc1198c32010-07-16 19:08:36 +000071
Marshall Clowf51ee632017-05-17 18:51:36 +000072 TEST_CONSTEXPR_CXX14 input_iterator() : it_() {}
73 explicit TEST_CONSTEXPR_CXX14 input_iterator(It it) : it_(it) {}
Eric Fiselier2fc65042016-08-28 21:26:01 +000074 template <class U, class T>
Marshall Clowf51ee632017-05-17 18:51:36 +000075 TEST_CONSTEXPR_CXX14 input_iterator(const input_iterator<U, T>& u) :it_(u.it_) {}
Howard Hinnantc1198c32010-07-16 19:08:36 +000076
Marshall Clowf51ee632017-05-17 18:51:36 +000077 TEST_CONSTEXPR_CXX14 reference operator*() const {return *it_;}
78 TEST_CONSTEXPR_CXX14 pointer operator->() const {return it_;}
Howard Hinnantc1198c32010-07-16 19:08:36 +000079
Marshall Clowf51ee632017-05-17 18:51:36 +000080 TEST_CONSTEXPR_CXX14 input_iterator& operator++() {++it_; return *this;}
81 TEST_CONSTEXPR_CXX14 input_iterator operator++(int)
Howard Hinnantc1198c32010-07-16 19:08:36 +000082 {input_iterator tmp(*this); ++(*this); return tmp;}
83
Marshall Clowf51ee632017-05-17 18:51:36 +000084 friend TEST_CONSTEXPR_CXX14 bool operator==(const input_iterator& x, const input_iterator& y)
Howard Hinnantc1198c32010-07-16 19:08:36 +000085 {return x.it_ == y.it_;}
Marshall Clowf51ee632017-05-17 18:51:36 +000086 friend TEST_CONSTEXPR_CXX14 bool operator!=(const input_iterator& x, const input_iterator& y)
Howard Hinnantc1198c32010-07-16 19:08:36 +000087 {return !(x == y);}
Eric Fiselier910285b2014-10-27 19:28:20 +000088
89 template <class T>
Eric Fiselier847ee132014-10-27 20:26:25 +000090 void operator,(T const &) DELETE_FUNCTION;
Howard Hinnantc1198c32010-07-16 19:08:36 +000091};
92
Eric Fiselier2fc65042016-08-28 21:26:01 +000093template <class T, class TV, class U, class UV>
Howard Hinnantc1198c32010-07-16 19:08:36 +000094inline
95bool
Eric Fiselier2fc65042016-08-28 21:26:01 +000096operator==(const input_iterator<T, TV>& x, const input_iterator<U, UV>& y)
Howard Hinnantc1198c32010-07-16 19:08:36 +000097{
98 return x.base() == y.base();
99}
100
Eric Fiselier2fc65042016-08-28 21:26:01 +0000101template <class T, class TV, class U, class UV>
Howard Hinnantc1198c32010-07-16 19:08:36 +0000102inline
103bool
Eric Fiselier2fc65042016-08-28 21:26:01 +0000104operator!=(const input_iterator<T, TV>& x, const input_iterator<U, UV>& y)
Howard Hinnantc1198c32010-07-16 19:08:36 +0000105{
106 return !(x == y);
107}
108
109template <class It>
110class forward_iterator
111{
112 It it_;
113
114 template <class U> friend class forward_iterator;
115public:
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;
121
Marshall Clowf51ee632017-05-17 18:51:36 +0000122 TEST_CONSTEXPR_CXX14 It base() const {return it_;}
Howard Hinnantc1198c32010-07-16 19:08:36 +0000123
Marshall Clowf51ee632017-05-17 18:51:36 +0000124 TEST_CONSTEXPR_CXX14 forward_iterator() : it_() {}
125 explicit TEST_CONSTEXPR_CXX14 forward_iterator(It it) : it_(it) {}
Howard Hinnantc1198c32010-07-16 19:08:36 +0000126 template <class U>
Marshall Clowf51ee632017-05-17 18:51:36 +0000127 TEST_CONSTEXPR_CXX14 forward_iterator(const forward_iterator<U>& u) :it_(u.it_) {}
Howard Hinnantc1198c32010-07-16 19:08:36 +0000128
Marshall Clowf51ee632017-05-17 18:51:36 +0000129 TEST_CONSTEXPR_CXX14 reference operator*() const {return *it_;}
130 TEST_CONSTEXPR_CXX14 pointer operator->() const {return it_;}
Howard Hinnantc1198c32010-07-16 19:08:36 +0000131
Marshall Clowf51ee632017-05-17 18:51:36 +0000132 TEST_CONSTEXPR_CXX14 forward_iterator& operator++() {++it_; return *this;}
133 TEST_CONSTEXPR_CXX14 forward_iterator operator++(int)
Howard Hinnantc1198c32010-07-16 19:08:36 +0000134 {forward_iterator tmp(*this); ++(*this); return tmp;}
135
Marshall Clowf51ee632017-05-17 18:51:36 +0000136 friend TEST_CONSTEXPR_CXX14 bool operator==(const forward_iterator& x, const forward_iterator& y)
Howard Hinnantc1198c32010-07-16 19:08:36 +0000137 {return x.it_ == y.it_;}
Marshall Clowf51ee632017-05-17 18:51:36 +0000138 friend TEST_CONSTEXPR_CXX14 bool operator!=(const forward_iterator& x, const forward_iterator& y)
Howard Hinnantc1198c32010-07-16 19:08:36 +0000139 {return !(x == y);}
Eric Fiselier910285b2014-10-27 19:28:20 +0000140
141 template <class T>
Eric Fiselier847ee132014-10-27 20:26:25 +0000142 void operator,(T const &) DELETE_FUNCTION;
Howard Hinnantc1198c32010-07-16 19:08:36 +0000143};
144
145template <class T, class U>
146inline
Marshall Clowf51ee632017-05-17 18:51:36 +0000147bool TEST_CONSTEXPR_CXX14
Howard Hinnantc1198c32010-07-16 19:08:36 +0000148operator==(const forward_iterator<T>& x, const forward_iterator<U>& y)
149{
150 return x.base() == y.base();
151}
152
153template <class T, class U>
154inline
Marshall Clowf51ee632017-05-17 18:51:36 +0000155bool TEST_CONSTEXPR_CXX14
Howard Hinnantc1198c32010-07-16 19:08:36 +0000156operator!=(const forward_iterator<T>& x, const forward_iterator<U>& y)
157{
158 return !(x == y);
159}
160
161template <class It>
162class bidirectional_iterator
163{
164 It it_;
165
166 template <class U> friend class bidirectional_iterator;
167public:
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;
173
Marshall Clowf51ee632017-05-17 18:51:36 +0000174 TEST_CONSTEXPR_CXX14 It base() const {return it_;}
Howard Hinnantc1198c32010-07-16 19:08:36 +0000175
Marshall Clowf51ee632017-05-17 18:51:36 +0000176 TEST_CONSTEXPR_CXX14 bidirectional_iterator() : it_() {}
177 explicit TEST_CONSTEXPR_CXX14 bidirectional_iterator(It it) : it_(it) {}
Howard Hinnantc1198c32010-07-16 19:08:36 +0000178 template <class U>
Marshall Clowf51ee632017-05-17 18:51:36 +0000179 TEST_CONSTEXPR_CXX14 bidirectional_iterator(const bidirectional_iterator<U>& u) :it_(u.it_) {}
Howard Hinnantc1198c32010-07-16 19:08:36 +0000180
Marshall Clowf51ee632017-05-17 18:51:36 +0000181 TEST_CONSTEXPR_CXX14 reference operator*() const {return *it_;}
182 TEST_CONSTEXPR_CXX14 pointer operator->() const {return it_;}
Howard Hinnantc1198c32010-07-16 19:08:36 +0000183
Marshall Clowf51ee632017-05-17 18:51:36 +0000184 TEST_CONSTEXPR_CXX14 bidirectional_iterator& operator++() {++it_; return *this;}
185 TEST_CONSTEXPR_CXX14 bidirectional_iterator operator++(int)
Howard Hinnantc1198c32010-07-16 19:08:36 +0000186 {bidirectional_iterator tmp(*this); ++(*this); return tmp;}
187
Marshall Clowf51ee632017-05-17 18:51:36 +0000188 TEST_CONSTEXPR_CXX14 bidirectional_iterator& operator--() {--it_; return *this;}
189 TEST_CONSTEXPR_CXX14 bidirectional_iterator operator--(int)
Howard Hinnantc1198c32010-07-16 19:08:36 +0000190 {bidirectional_iterator tmp(*this); --(*this); return tmp;}
Eric Fiselier910285b2014-10-27 19:28:20 +0000191
192 template <class T>
Eric Fiselier847ee132014-10-27 20:26:25 +0000193 void operator,(T const &) DELETE_FUNCTION;
Howard Hinnantc1198c32010-07-16 19:08:36 +0000194};
195
196template <class T, class U>
197inline
Marshall Clowf51ee632017-05-17 18:51:36 +0000198bool TEST_CONSTEXPR_CXX14
Howard Hinnantc1198c32010-07-16 19:08:36 +0000199operator==(const bidirectional_iterator<T>& x, const bidirectional_iterator<U>& y)
200{
201 return x.base() == y.base();
202}
203
204template <class T, class U>
205inline
Marshall Clowf51ee632017-05-17 18:51:36 +0000206bool TEST_CONSTEXPR_CXX14
Howard Hinnantc1198c32010-07-16 19:08:36 +0000207operator!=(const bidirectional_iterator<T>& x, const bidirectional_iterator<U>& y)
208{
209 return !(x == y);
210}
211
212template <class It>
213class random_access_iterator
214{
215 It it_;
216
217 template <class U> friend class random_access_iterator;
218public:
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;
224
Marshall Clowf51ee632017-05-17 18:51:36 +0000225 TEST_CONSTEXPR_CXX14 It base() const {return it_;}
Howard Hinnantc1198c32010-07-16 19:08:36 +0000226
Marshall Clowf51ee632017-05-17 18:51:36 +0000227 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_) {}
Howard Hinnantc1198c32010-07-16 19:08:36 +0000231
Marshall Clowf51ee632017-05-17 18:51:36 +0000232 TEST_CONSTEXPR_CXX14 reference operator*() const {return *it_;}
233 TEST_CONSTEXPR_CXX14 pointer operator->() const {return it_;}
Howard Hinnantc1198c32010-07-16 19:08:36 +0000234
Marshall Clowf51ee632017-05-17 18:51:36 +0000235 TEST_CONSTEXPR_CXX14 random_access_iterator& operator++() {++it_; return *this;}
236 TEST_CONSTEXPR_CXX14 random_access_iterator operator++(int)
Howard Hinnantc1198c32010-07-16 19:08:36 +0000237 {random_access_iterator tmp(*this); ++(*this); return tmp;}
238
Marshall Clowf51ee632017-05-17 18:51:36 +0000239 TEST_CONSTEXPR_CXX14 random_access_iterator& operator--() {--it_; return *this;}
240 TEST_CONSTEXPR_CXX14 random_access_iterator operator--(int)
Howard Hinnantc1198c32010-07-16 19:08:36 +0000241 {random_access_iterator tmp(*this); --(*this); return tmp;}
242
Marshall Clowf51ee632017-05-17 18:51:36 +0000243 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
Howard Hinnantc1198c32010-07-16 19:08:36 +0000245 {random_access_iterator tmp(*this); tmp += n; return tmp;}
Marshall Clowf51ee632017-05-17 18:51:36 +0000246 friend TEST_CONSTEXPR_CXX14 random_access_iterator operator+(difference_type n, random_access_iterator x)
Howard Hinnantc1198c32010-07-16 19:08:36 +0000247 {x += n; return x;}
Marshall Clowf51ee632017-05-17 18:51:36 +0000248 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
Howard Hinnantc1198c32010-07-16 19:08:36 +0000250 {random_access_iterator tmp(*this); tmp -= n; return tmp;}
251
Marshall Clowf51ee632017-05-17 18:51:36 +0000252 TEST_CONSTEXPR_CXX14 reference operator[](difference_type n) const {return it_[n];}
Eric Fiselier910285b2014-10-27 19:28:20 +0000253
254 template <class T>
Eric Fiselier847ee132014-10-27 20:26:25 +0000255 void operator,(T const &) DELETE_FUNCTION;
Howard Hinnantc1198c32010-07-16 19:08:36 +0000256};
257
258template <class T, class U>
259inline
Marshall Clowf51ee632017-05-17 18:51:36 +0000260bool TEST_CONSTEXPR_CXX14
Howard Hinnantc1198c32010-07-16 19:08:36 +0000261operator==(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
262{
263 return x.base() == y.base();
264}
265
266template <class T, class U>
267inline
Marshall Clowf51ee632017-05-17 18:51:36 +0000268bool TEST_CONSTEXPR_CXX14
Howard Hinnantc1198c32010-07-16 19:08:36 +0000269operator!=(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
270{
271 return !(x == y);
272}
273
274template <class T, class U>
275inline
Marshall Clowf51ee632017-05-17 18:51:36 +0000276bool TEST_CONSTEXPR_CXX14
Howard Hinnantc1198c32010-07-16 19:08:36 +0000277operator<(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
278{
279 return x.base() < y.base();
280}
281
282template <class T, class U>
283inline
Marshall Clowf51ee632017-05-17 18:51:36 +0000284bool TEST_CONSTEXPR_CXX14
Howard Hinnantc1198c32010-07-16 19:08:36 +0000285operator<=(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
286{
287 return !(y < x);
288}
289
290template <class T, class U>
291inline
Marshall Clowf51ee632017-05-17 18:51:36 +0000292bool TEST_CONSTEXPR_CXX14
Howard Hinnantc1198c32010-07-16 19:08:36 +0000293operator>(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
294{
295 return y < x;
296}
297
298template <class T, class U>
299inline
Marshall Clowf51ee632017-05-17 18:51:36 +0000300bool TEST_CONSTEXPR_CXX14
Howard Hinnantc1198c32010-07-16 19:08:36 +0000301operator>=(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
302{
303 return !(x < y);
304}
305
306template <class T, class U>
Marshall Clowf51ee632017-05-17 18:51:36 +0000307inline TEST_CONSTEXPR_CXX14
Howard Hinnantc1198c32010-07-16 19:08:36 +0000308typename std::iterator_traits<T>::difference_type
309operator-(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
310{
311 return x.base() - y.base();
312}
313
Marshall Clowf8c2b822013-01-04 18:24:04 +0000314template <class Iter>
Marshall Clowf51ee632017-05-17 18:51:36 +0000315inline TEST_CONSTEXPR_CXX14 Iter base(output_iterator<Iter> i) { return i.base(); }
Marshall Clowf8c2b822013-01-04 18:24:04 +0000316
317template <class Iter>
Marshall Clowf51ee632017-05-17 18:51:36 +0000318inline TEST_CONSTEXPR_CXX14 Iter base(input_iterator<Iter> i) { return i.base(); }
Marshall Clowf8c2b822013-01-04 18:24:04 +0000319
320template <class Iter>
Marshall Clowf51ee632017-05-17 18:51:36 +0000321inline TEST_CONSTEXPR_CXX14 Iter base(forward_iterator<Iter> i) { return i.base(); }
Marshall Clowf8c2b822013-01-04 18:24:04 +0000322
323template <class Iter>
Marshall Clowf51ee632017-05-17 18:51:36 +0000324inline TEST_CONSTEXPR_CXX14 Iter base(bidirectional_iterator<Iter> i) { return i.base(); }
Marshall Clowf8c2b822013-01-04 18:24:04 +0000325
326template <class Iter>
Marshall Clowf51ee632017-05-17 18:51:36 +0000327inline TEST_CONSTEXPR_CXX14 Iter base(random_access_iterator<Iter> i) { return i.base(); }
Marshall Clowf8c2b822013-01-04 18:24:04 +0000328
Howard Hinnante0fe3d22013-07-08 21:06:38 +0000329template <class Iter> // everything else
Marshall Clowf51ee632017-05-17 18:51:36 +0000330inline TEST_CONSTEXPR_CXX14 Iter base(Iter i) { return i; }
Marshall Clowf8c2b822013-01-04 18:24:04 +0000331
Marshall Clow76b4afc2016-01-13 21:54:34 +0000332template <typename T>
333struct 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;
339
Marshall Clow64ca6862016-01-20 03:37:46 +0000340 enum ThrowingAction { TAIncrement, TADecrement, TADereference, TAAssignment, TAComparison };
Marshall Clow76b4afc2016-01-13 21:54:34 +0000341
Marshall Clow64ca6862016-01-20 03:37:46 +0000342// 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)
350 {
351 if (action_ == TAAssignment)
352 {
353 if (index_ == 0)
Marshall Clow9d10d272016-01-20 03:19:15 +0000354#ifndef TEST_HAS_NO_EXCEPTIONS
Marshall Clow64ca6862016-01-20 03:37:46 +0000355 throw std::runtime_error ("throw from iterator assignment");
Marshall Clow9d10d272016-01-20 03:19:15 +0000356#else
Marshall Clow64ca6862016-01-20 03:37:46 +0000357 assert(false);
Marshall Clow9d10d272016-01-20 03:19:15 +0000358#endif
359
Marshall Clow64ca6862016-01-20 03:37:46 +0000360 else
361 --index_;
362 }
363 begin_ = rhs.begin_;
364 end_ = rhs.end_;
365 current_ = rhs.current_;
366 action_ = rhs.action_;
367 index_ = rhs.index_;
368 return *this;
369 }
Marshall Clow76b4afc2016-01-13 21:54:34 +0000370
Marshall Clow64ca6862016-01-20 03:37:46 +0000371// iterator operations
372 reference operator*() const
373 {
374 if (action_ == TADereference)
375 {
376 if (index_ == 0)
Marshall Clow9d10d272016-01-20 03:19:15 +0000377#ifndef TEST_HAS_NO_EXCEPTIONS
Marshall Clow64ca6862016-01-20 03:37:46 +0000378 throw std::runtime_error ("throw from iterator dereference");
Marshall Clow9d10d272016-01-20 03:19:15 +0000379#else
Marshall Clow64ca6862016-01-20 03:37:46 +0000380 assert(false);
Marshall Clow9d10d272016-01-20 03:19:15 +0000381#endif
Marshall Clow64ca6862016-01-20 03:37:46 +0000382 else
383 --index_;
384 }
385 return *current_;
386 }
Marshall Clow76b4afc2016-01-13 21:54:34 +0000387
Marshall Clow64ca6862016-01-20 03:37:46 +0000388 ThrowingIterator & operator++()
389 {
390 if (action_ == TAIncrement)
391 {
392 if (index_ == 0)
Marshall Clow9d10d272016-01-20 03:19:15 +0000393#ifndef TEST_HAS_NO_EXCEPTIONS
Marshall Clow64ca6862016-01-20 03:37:46 +0000394 throw std::runtime_error ("throw from iterator increment");
Marshall Clow9d10d272016-01-20 03:19:15 +0000395#else
Marshall Clow64ca6862016-01-20 03:37:46 +0000396 assert(false);
Marshall Clow9d10d272016-01-20 03:19:15 +0000397#endif
Marshall Clow64ca6862016-01-20 03:37:46 +0000398 else
399 --index_;
400 }
401 ++current_;
402 return *this;
403 }
Eric Fiselierd04c6852016-06-01 21:35:39 +0000404
Marshall Clow64ca6862016-01-20 03:37:46 +0000405 ThrowingIterator operator++(int)
406 {
407 ThrowingIterator temp = *this;
408 ++(*this);
409 return temp;
410 }
Marshall Clow76b4afc2016-01-13 21:54:34 +0000411
Marshall Clow64ca6862016-01-20 03:37:46 +0000412 ThrowingIterator & operator--()
413 {
414 if (action_ == TADecrement)
415 {
416 if (index_ == 0)
Marshall Clow9d10d272016-01-20 03:19:15 +0000417#ifndef TEST_HAS_NO_EXCEPTIONS
Marshall Clow64ca6862016-01-20 03:37:46 +0000418 throw std::runtime_error ("throw from iterator decrement");
Marshall Clow9d10d272016-01-20 03:19:15 +0000419#else
Marshall Clow64ca6862016-01-20 03:37:46 +0000420 assert(false);
Marshall Clow9d10d272016-01-20 03:19:15 +0000421#endif
Marshall Clow64ca6862016-01-20 03:37:46 +0000422 else
423 --index_;
424 }
425 --current_;
426 return *this;
427 }
Marshall Clow76b4afc2016-01-13 21:54:34 +0000428
Marshall Clow64ca6862016-01-20 03:37:46 +0000429 ThrowingIterator operator--(int) {
430 ThrowingIterator temp = *this;
431 --(*this);
432 return temp;
433 }
Marshall Clow76b4afc2016-01-13 21:54:34 +0000434
Marshall Clow64ca6862016-01-20 03:37:46 +0000435 bool operator== (const ThrowingIterator &rhs) const
436 {
437 if (action_ == TAComparison)
438 {
439 if (index_ == 0)
Marshall Clow9d10d272016-01-20 03:19:15 +0000440#ifndef TEST_HAS_NO_EXCEPTIONS
Marshall Clow64ca6862016-01-20 03:37:46 +0000441 throw std::runtime_error ("throw from iterator comparison");
Marshall Clow9d10d272016-01-20 03:19:15 +0000442#else
Marshall Clow64ca6862016-01-20 03:37:46 +0000443 assert(false);
Marshall Clow9d10d272016-01-20 03:19:15 +0000444#endif
Marshall Clow64ca6862016-01-20 03:37:46 +0000445 else
446 --index_;
447 }
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_;
453 }
Marshall Clow76b4afc2016-01-13 21:54:34 +0000454
455private:
Marshall Clow64ca6862016-01-20 03:37:46 +0000456 const T* begin_;
457 const T* end_;
458 const T* current_;
459 ThrowingAction action_;
460 mutable size_t index_;
Marshall Clow76b4afc2016-01-13 21:54:34 +0000461};
462
463template <typename T>
464bool operator== (const ThrowingIterator<T>& a, const ThrowingIterator<T>& b)
Marshall Clow64ca6862016-01-20 03:37:46 +0000465{ return a.operator==(b); }
Marshall Clow76b4afc2016-01-13 21:54:34 +0000466
467template <typename T>
468bool operator!= (const ThrowingIterator<T>& a, const ThrowingIterator<T>& b)
Marshall Clow64ca6862016-01-20 03:37:46 +0000469{ return !a.operator==(b); }
Eric Fiselierd04c6852016-06-01 21:35:39 +0000470
Marshall Clow76b4afc2016-01-13 21:54:34 +0000471template <typename T>
472struct 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;
478
Marshall Clow64ca6862016-01-20 03:37:46 +0000479// 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
487 {
488 begin_ = rhs.begin_;
489 end_ = rhs.end_;
490 current_ = rhs.current_;
491 return *this;
492 }
Marshall Clow76b4afc2016-01-13 21:54:34 +0000493
Marshall Clow64ca6862016-01-20 03:37:46 +0000494// iterator operations
495 reference operator*() const TEST_NOEXCEPT
496 {
497 return *current_;
498 }
Marshall Clow76b4afc2016-01-13 21:54:34 +0000499
Marshall Clow64ca6862016-01-20 03:37:46 +0000500 NonThrowingIterator & operator++() TEST_NOEXCEPT
501 {
502 ++current_;
503 return *this;
504 }
Eric Fiselierd04c6852016-06-01 21:35:39 +0000505
Marshall Clow64ca6862016-01-20 03:37:46 +0000506 NonThrowingIterator operator++(int) TEST_NOEXCEPT
507 {
508 NonThrowingIterator temp = *this;
509 ++(*this);
510 return temp;
511 }
Marshall Clow76b4afc2016-01-13 21:54:34 +0000512
Marshall Clow64ca6862016-01-20 03:37:46 +0000513 NonThrowingIterator & operator--() TEST_NOEXCEPT
514 {
515 --current_;
516 return *this;
517 }
Marshall Clow76b4afc2016-01-13 21:54:34 +0000518
Marshall Clow64ca6862016-01-20 03:37:46 +0000519 NonThrowingIterator operator--(int) TEST_NOEXCEPT
520 {
521 NonThrowingIterator temp = *this;
522 --(*this);
523 return temp;
524 }
Marshall Clow76b4afc2016-01-13 21:54:34 +0000525
Marshall Clow64ca6862016-01-20 03:37:46 +0000526 bool operator== (const NonThrowingIterator &rhs) const TEST_NOEXCEPT
527 {
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_;
533 }
Marshall Clow76b4afc2016-01-13 21:54:34 +0000534
535private:
Marshall Clow64ca6862016-01-20 03:37:46 +0000536 const T* begin_;
537 const T* end_;
538 const T* current_;
Marshall Clow76b4afc2016-01-13 21:54:34 +0000539};
540
541template <typename T>
542bool operator== (const NonThrowingIterator<T>& a, const NonThrowingIterator<T>& b) TEST_NOEXCEPT
Marshall Clow64ca6862016-01-20 03:37:46 +0000543{ return a.operator==(b); }
Marshall Clow76b4afc2016-01-13 21:54:34 +0000544
545template <typename T>
546bool operator!= (const NonThrowingIterator<T>& a, const NonThrowingIterator<T>& b) TEST_NOEXCEPT
Marshall Clow64ca6862016-01-20 03:37:46 +0000547{ return !a.operator==(b); }
Marshall Clow76b4afc2016-01-13 21:54:34 +0000548
Eric Fiselier847ee132014-10-27 20:26:25 +0000549#undef DELETE_FUNCTION
550
Howard Hinnantf36101d2010-08-22 00:45:01 +0000551#endif // ITERATORS_H