1 /*
2 Copyright (c) Marshall Clow 2013.
3
4 Distributed under the Boost Software License, Version 1.0. (See accompanying
5 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6
7 For more information, see http://www.boost.org
8 */
9
10 #ifndef ITERATOR_TEST_H
11 #define ITERATOR_TEST_H
12
13 /*
14 A set of iterator adapters for constructing test cases
15 From an iterator (or a pointer), you can make any class of iterator.
16 Assuming you want to degrade the capabilities.
17
18 Modeled closely on work that Howard Hinnant did for libc++.
19 */
20
21 #include <iterator>
22
23 // == Input Iterator ==
24 template <typename It>
25 class input_iterator {
26 public:
27 typedef std::input_iterator_tag iterator_category;
28 typedef typename std::iterator_traits<It>::value_type value_type;
29 typedef typename std::iterator_traits<It>::difference_type difference_type;
30 typedef It pointer;
31 typedef typename std::iterator_traits<It>::reference reference;
32
base() const33 BOOST_CXX14_CONSTEXPR It base() const {return it_;}
34
input_iterator()35 BOOST_CXX14_CONSTEXPR input_iterator() : it_() {}
input_iterator(It it)36 BOOST_CXX14_CONSTEXPR explicit input_iterator(It it) : it_(it) {}
37
38 template <typename U>
input_iterator(const input_iterator<U> & u)39 BOOST_CXX14_CONSTEXPR input_iterator(const input_iterator<U>& u) :it_(u.it_) {}
40
operator *() const41 BOOST_CXX14_CONSTEXPR reference operator*() const {return *it_;}
operator ->() const42 BOOST_CXX14_CONSTEXPR pointer operator->() const {return it_;}
43
operator ++()44 BOOST_CXX14_CONSTEXPR input_iterator& operator++() {++it_; return *this;}
operator ++(int)45 BOOST_CXX14_CONSTEXPR input_iterator operator++(int) {input_iterator tmp(*this); ++(*this); return tmp;}
46
operator ==(const input_iterator & x,const input_iterator & y)47 BOOST_CXX14_CONSTEXPR friend bool operator==(const input_iterator& x, const input_iterator& y)
48 {return x.it_ == y.it_;}
operator !=(const input_iterator & x,const input_iterator & y)49 BOOST_CXX14_CONSTEXPR friend bool operator!=(const input_iterator& x, const input_iterator& y)
50 {return !(x == y);}
51
52 private:
53 It it_;
54 template <typename U> friend class input_iterator;
55 };
56
57 template <typename T, typename U>
58 BOOST_CXX14_CONSTEXPR inline bool
operator ==(const input_iterator<T> & x,const input_iterator<U> & y)59 operator==(const input_iterator<T>& x, const input_iterator<U>& y)
60 {
61 return x.base() == y.base();
62 }
63
64 template <typename T, typename U>
65 BOOST_CXX14_CONSTEXPR inline bool
operator !=(const input_iterator<T> & x,const input_iterator<U> & y)66 operator!=(const input_iterator<T>& x, const input_iterator<U>& y)
67 {
68 return !(x == y);
69 }
70
71
72 // == Forward Iterator ==
73 template <typename It>
74 class forward_iterator {
75 public:
76 typedef std::forward_iterator_tag iterator_category;
77 typedef typename std::iterator_traits<It>::value_type value_type;
78 typedef typename std::iterator_traits<It>::difference_type difference_type;
79 typedef It pointer;
80 typedef typename std::iterator_traits<It>::reference reference;
81
base() const82 BOOST_CXX14_CONSTEXPR It base() const {return it_;}
83
forward_iterator()84 BOOST_CXX14_CONSTEXPR forward_iterator() : it_() {}
forward_iterator(It it)85 BOOST_CXX14_CONSTEXPR explicit forward_iterator(It it) : it_(it) {}
86 template <typename U>
forward_iterator(const forward_iterator<U> & u)87 BOOST_CXX14_CONSTEXPR forward_iterator(const forward_iterator<U>& u) :it_(u.it_) {}
88
operator *() const89 BOOST_CXX14_CONSTEXPR reference operator*() const {return *it_;}
operator ->() const90 BOOST_CXX14_CONSTEXPR pointer operator->() const {return it_;}
91
operator ++()92 BOOST_CXX14_CONSTEXPR forward_iterator& operator++() {++it_; return *this;}
operator ++(int)93 BOOST_CXX14_CONSTEXPR forward_iterator operator++(int) {forward_iterator tmp(*this); ++(*this); return tmp;}
94
operator ==(const forward_iterator & x,const forward_iterator & y)95 BOOST_CXX14_CONSTEXPR friend bool operator==(const forward_iterator& x, const forward_iterator& y)
96 {return x.it_ == y.it_;}
operator !=(const forward_iterator & x,const forward_iterator & y)97 BOOST_CXX14_CONSTEXPR friend bool operator!=(const forward_iterator& x, const forward_iterator& y)
98 {return !(x == y);}
99 private:
100 It it_;
101
102 template <typename U> friend class forward_iterator;
103 };
104
105 template <typename T, typename U>
106 BOOST_CXX14_CONSTEXPR inline bool
operator ==(const forward_iterator<T> & x,const forward_iterator<U> & y)107 operator==(const forward_iterator<T>& x, const forward_iterator<U>& y)
108 {
109 return x.base() == y.base();
110 }
111
112 template <typename T, typename U>
113 BOOST_CXX14_CONSTEXPR inline bool
operator !=(const forward_iterator<T> & x,const forward_iterator<U> & y)114 operator!=(const forward_iterator<T>& x, const forward_iterator<U>& y)
115 {
116 return !(x == y);
117 }
118
119 // == Bidirectional Iterator ==
120 template <typename It>
121 class bidirectional_iterator
122 {
123 public:
124 typedef std::bidirectional_iterator_tag iterator_category;
125 typedef typename std::iterator_traits<It>::value_type value_type;
126 typedef typename std::iterator_traits<It>::difference_type difference_type;
127 typedef It pointer;
128 typedef typename std::iterator_traits<It>::reference reference;
129
base() const130 BOOST_CXX14_CONSTEXPR It base() const {return it_;}
131
bidirectional_iterator()132 BOOST_CXX14_CONSTEXPR bidirectional_iterator() : it_() {}
bidirectional_iterator(It it)133 BOOST_CXX14_CONSTEXPR explicit bidirectional_iterator(It it) : it_(it) {}
134 template <typename U>
bidirectional_iterator(const bidirectional_iterator<U> & u)135 BOOST_CXX14_CONSTEXPR bidirectional_iterator(const bidirectional_iterator<U>& u) :it_(u.it_) {}
136
operator *() const137 BOOST_CXX14_CONSTEXPR reference operator*() const {return *it_;}
operator ->() const138 BOOST_CXX14_CONSTEXPR pointer operator->() const {return it_;}
139
operator ++()140 BOOST_CXX14_CONSTEXPR bidirectional_iterator& operator++() {++it_; return *this;}
operator ++(int)141 BOOST_CXX14_CONSTEXPR bidirectional_iterator operator++(int) {bidirectional_iterator tmp(*this); ++(*this); return tmp;}
142
operator --()143 BOOST_CXX14_CONSTEXPR bidirectional_iterator& operator--() {--it_; return *this;}
operator --(int)144 BOOST_CXX14_CONSTEXPR bidirectional_iterator operator--(int) {bidirectional_iterator tmp(*this); --(*this); return tmp;}
145 private:
146 It it_;
147 template <typename U> friend class bidirectional_iterator;
148 };
149
150 template <typename T, typename U>
151 BOOST_CXX14_CONSTEXPR inline bool
operator ==(const bidirectional_iterator<T> & x,const bidirectional_iterator<U> & y)152 operator==(const bidirectional_iterator<T>& x, const bidirectional_iterator<U>& y)
153 {
154 return x.base() == y.base();
155 }
156
157 template <typename T, typename U>
158 BOOST_CXX14_CONSTEXPR inline bool
operator !=(const bidirectional_iterator<T> & x,const bidirectional_iterator<U> & y)159 operator!=(const bidirectional_iterator<T>& x, const bidirectional_iterator<U>& y)
160 {
161 return !(x == y);
162 }
163
164
165 // == Random Access Iterator ==
166 template <typename It>
167 class random_access_iterator {
168 public:
169 typedef std::random_access_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
base() const175 BOOST_CXX14_CONSTEXPR It base() const {return it_;}
176
random_access_iterator()177 BOOST_CXX14_CONSTEXPR random_access_iterator() : it_() {}
random_access_iterator(It it)178 BOOST_CXX14_CONSTEXPR explicit random_access_iterator(It it) : it_(it) {}
179 template <typename U>
random_access_iterator(const random_access_iterator<U> & u)180 BOOST_CXX14_CONSTEXPR random_access_iterator(const random_access_iterator<U>& u) :it_(u.it_) {}
181
operator *() const182 BOOST_CXX14_CONSTEXPR reference operator*() const {return *it_;}
operator ->() const183 BOOST_CXX14_CONSTEXPR pointer operator->() const {return it_;}
184
operator ++()185 BOOST_CXX14_CONSTEXPR random_access_iterator& operator++() {++it_; return *this;}
operator ++(int)186 BOOST_CXX14_CONSTEXPR random_access_iterator operator++(int) {random_access_iterator tmp(*this); ++(*this); return tmp;}
187
operator --()188 BOOST_CXX14_CONSTEXPR random_access_iterator& operator--() {--it_; return *this;}
operator --(int)189 BOOST_CXX14_CONSTEXPR random_access_iterator operator--(int) {random_access_iterator tmp(*this); --(*this); return tmp;}
190
operator +=(difference_type n)191 BOOST_CXX14_CONSTEXPR random_access_iterator& operator+=(difference_type n) {it_ += n; return *this;}
operator +(difference_type n) const192 BOOST_CXX14_CONSTEXPR random_access_iterator operator+ (difference_type n) const {random_access_iterator tmp(*this); tmp += n; return tmp;}
operator +(difference_type n,random_access_iterator x)193 BOOST_CXX14_CONSTEXPR friend random_access_iterator operator+(difference_type n, random_access_iterator x) {x += n; return x;}
194
operator -=(difference_type n)195 BOOST_CXX14_CONSTEXPR random_access_iterator& operator-=(difference_type n) {return *this += -n;}
operator -(difference_type n) const196 BOOST_CXX14_CONSTEXPR random_access_iterator operator- (difference_type n) const {random_access_iterator tmp(*this); tmp -= n; return tmp;}
197
operator [](difference_type n) const198 BOOST_CXX14_CONSTEXPR reference operator[](difference_type n) const {return it_[n];}
199 private:
200 It it_;
201
202 template <typename U> friend class random_access_iterator;
203 };
204
205 template <typename T, typename U>
206 BOOST_CXX14_CONSTEXPR inline bool
operator ==(const random_access_iterator<T> & x,const random_access_iterator<U> & y)207 operator==(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
208 {
209 return x.base() == y.base();
210 }
211
212 template <typename T, typename U>
213 BOOST_CXX14_CONSTEXPR inline bool
operator !=(const random_access_iterator<T> & x,const random_access_iterator<U> & y)214 operator!=(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
215 {
216 return !(x == y);
217 }
218
219 template <typename T, typename U>
220 BOOST_CXX14_CONSTEXPR inline bool
operator <(const random_access_iterator<T> & x,const random_access_iterator<U> & y)221 operator<(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
222 {
223 return x.base() < y.base();
224 }
225
226 template <typename T, typename U>
227 BOOST_CXX14_CONSTEXPR inline bool
operator <=(const random_access_iterator<T> & x,const random_access_iterator<U> & y)228 operator<=(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
229 {
230 return !(y < x);
231 }
232
233 template <typename T, typename U>
234 BOOST_CXX14_CONSTEXPR inline bool
operator >(const random_access_iterator<T> & x,const random_access_iterator<U> & y)235 operator>(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
236 {
237 return y < x;
238 }
239
240 template <typename T, typename U>
241 BOOST_CXX14_CONSTEXPR inline bool
operator >=(const random_access_iterator<T> & x,const random_access_iterator<U> & y)242 operator>=(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
243 {
244 return !(x < y);
245 }
246
247 template <typename T, typename U>
248 BOOST_CXX14_CONSTEXPR inline typename std::iterator_traits<T>::difference_type
operator -(const random_access_iterator<T> & x,const random_access_iterator<U> & y)249 operator-(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
250 {
251 return x.base() - y.base();
252 }
253
254
255 // == Output Iterator ==
256 template <typename It>
257 class output_iterator {
258 public:
259 typedef std::output_iterator_tag iterator_category;
260 typedef void value_type;
261 typedef typename std::iterator_traits<It>::difference_type difference_type;
262 typedef It pointer;
263 typedef typename std::iterator_traits<It>::reference reference;
264
base() const265 BOOST_CXX14_CONSTEXPR It base() const {return it_;}
266
output_iterator()267 BOOST_CXX14_CONSTEXPR output_iterator () {}
output_iterator(It it)268 BOOST_CXX14_CONSTEXPR explicit output_iterator(It it) : it_(it) {}
269
270 template <typename U>
output_iterator(const output_iterator<U> & u)271 BOOST_CXX14_CONSTEXPR output_iterator(const output_iterator<U>& u) :it_(u.it_) {}
272
operator *() const273 BOOST_CXX14_CONSTEXPR reference operator*() const {return *it_;}
274
operator ++()275 BOOST_CXX14_CONSTEXPR output_iterator& operator++() {++it_; return *this;}
operator ++(int)276 BOOST_CXX14_CONSTEXPR output_iterator operator++(int) {output_iterator tmp(*this); ++(*this); return tmp;}
277
278 private:
279 It it_;
280 template <typename U> friend class output_iterator;
281 };
282
283 // No comparison operators for output iterators
284
285
286 // == Get the base of an iterator; used for comparisons ==
287 template <typename Iter>
base(output_iterator<Iter> i)288 BOOST_CXX14_CONSTEXPR inline Iter base(output_iterator<Iter> i) { return i.base(); }
289
290 template <typename Iter>
base(input_iterator<Iter> i)291 BOOST_CXX14_CONSTEXPR inline Iter base(input_iterator<Iter> i) { return i.base(); }
292
293 template <typename Iter>
base(forward_iterator<Iter> i)294 BOOST_CXX14_CONSTEXPR inline Iter base(forward_iterator<Iter> i) { return i.base(); }
295
296 template <typename Iter>
base(bidirectional_iterator<Iter> i)297 BOOST_CXX14_CONSTEXPR inline Iter base(bidirectional_iterator<Iter> i) { return i.base(); }
298
299 template <typename Iter>
base(random_access_iterator<Iter> i)300 BOOST_CXX14_CONSTEXPR inline Iter base(random_access_iterator<Iter> i) { return i.base(); }
301
302 template <typename Iter> // everything else
base(Iter i)303 BOOST_CXX14_CONSTEXPR inline Iter base(Iter i) { return i; }
304
305 #endif // ITERATORS_H
306