• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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