1 //===----------------------------------------------------------------------===//
3 // 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
7 //===----------------------------------------------------------------------===//
17 #include "test_macros.h"
19 #if TEST_STD_VER >= 11
20 #define DELETE_FUNCTION = delete
22 #define DELETE_FUNCTION
30 template <class U
> friend class output_iterator
;
32 typedef std::output_iterator_tag iterator_category
;
33 typedef void value_type
;
34 typedef typename
std::iterator_traits
<It
>::difference_type difference_type
;
36 typedef typename
std::iterator_traits
<It
>::reference reference
;
38 TEST_CONSTEXPR_CXX14 It
base() const {return it_
;}
40 TEST_CONSTEXPR_CXX14
output_iterator () {}
41 explicit TEST_CONSTEXPR_CXX14
output_iterator(It it
) : it_(it
) {}
43 TEST_CONSTEXPR_CXX14
output_iterator(const output_iterator
<U
>& u
) :it_(u
.it_
) {}
45 TEST_CONSTEXPR_CXX14 reference
operator*() const {return *it_
;}
47 TEST_CONSTEXPR_CXX14 output_iterator
& operator++() {++it_
; return *this;}
48 TEST_CONSTEXPR_CXX14 output_iterator
operator++(int)
49 {output_iterator
tmp(*this); ++(*this); return tmp
;}
52 void operator,(T
const &) DELETE_FUNCTION
;
59 typedef std::iterator_traits
<ItTraits
> Traits
;
62 template <class U
, class T
> friend class input_iterator
;
64 typedef std::input_iterator_tag iterator_category
;
65 typedef typename
Traits::value_type value_type
;
66 typedef typename
Traits::difference_type difference_type
;
68 typedef typename
Traits::reference reference
;
70 TEST_CONSTEXPR_CXX14 It
base() const {return it_
;}
72 TEST_CONSTEXPR_CXX14
input_iterator() : it_() {}
73 explicit TEST_CONSTEXPR_CXX14
input_iterator(It it
) : it_(it
) {}
74 template <class U
, class T
>
75 TEST_CONSTEXPR_CXX14
input_iterator(const input_iterator
<U
, T
>& u
) :it_(u
.it_
) {}
77 TEST_CONSTEXPR_CXX14 reference
operator*() const {return *it_
;}
78 TEST_CONSTEXPR_CXX14 pointer
operator->() const {return it_
;}
80 TEST_CONSTEXPR_CXX14 input_iterator
& operator++() {++it_
; return *this;}
81 TEST_CONSTEXPR_CXX14 input_iterator
operator++(int)
82 {input_iterator
tmp(*this); ++(*this); return tmp
;}
84 friend TEST_CONSTEXPR_CXX14
bool operator==(const input_iterator
& x
, const input_iterator
& y
)
85 {return x
.it_
== y
.it_
;}
86 friend TEST_CONSTEXPR_CXX14
bool operator!=(const input_iterator
& x
, const input_iterator
& y
)
90 void operator,(T
const &) DELETE_FUNCTION
;
93 template <class T
, class TV
, class U
, class UV
>
96 operator==(const input_iterator
<T
, TV
>& x
, const input_iterator
<U
, UV
>& y
)
98 return x
.base() == y
.base();
101 template <class T
, class TV
, class U
, class UV
>
104 operator!=(const input_iterator
<T
, TV
>& x
, const input_iterator
<U
, UV
>& y
)
110 class forward_iterator
114 template <class U
> friend class forward_iterator
;
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
;
120 typedef typename
std::iterator_traits
<It
>::reference reference
;
122 TEST_CONSTEXPR_CXX14 It
base() const {return it_
;}
124 TEST_CONSTEXPR_CXX14
forward_iterator() : it_() {}
125 explicit TEST_CONSTEXPR_CXX14
forward_iterator(It it
) : it_(it
) {}
127 TEST_CONSTEXPR_CXX14
forward_iterator(const forward_iterator
<U
>& u
) :it_(u
.it_
) {}
129 TEST_CONSTEXPR_CXX14 reference
operator*() const {return *it_
;}
130 TEST_CONSTEXPR_CXX14 pointer
operator->() const {return it_
;}
132 TEST_CONSTEXPR_CXX14 forward_iterator
& operator++() {++it_
; return *this;}
133 TEST_CONSTEXPR_CXX14 forward_iterator
operator++(int)
134 {forward_iterator
tmp(*this); ++(*this); return tmp
;}
136 friend TEST_CONSTEXPR_CXX14
bool operator==(const forward_iterator
& x
, const forward_iterator
& y
)
137 {return x
.it_
== y
.it_
;}
138 friend TEST_CONSTEXPR_CXX14
bool operator!=(const forward_iterator
& x
, const forward_iterator
& y
)
142 void operator,(T
const &) DELETE_FUNCTION
;
145 template <class T
, class U
>
147 bool TEST_CONSTEXPR_CXX14
148 operator==(const forward_iterator
<T
>& x
, const forward_iterator
<U
>& y
)
150 return x
.base() == y
.base();
153 template <class T
, class U
>
155 bool TEST_CONSTEXPR_CXX14
156 operator!=(const forward_iterator
<T
>& x
, const forward_iterator
<U
>& y
)
162 class bidirectional_iterator
166 template <class U
> friend class bidirectional_iterator
;
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
;
172 typedef typename
std::iterator_traits
<It
>::reference reference
;
174 TEST_CONSTEXPR_CXX14 It
base() const {return it_
;}
176 TEST_CONSTEXPR_CXX14
bidirectional_iterator() : it_() {}
177 explicit TEST_CONSTEXPR_CXX14
bidirectional_iterator(It it
) : it_(it
) {}
179 TEST_CONSTEXPR_CXX14
bidirectional_iterator(const bidirectional_iterator
<U
>& u
) :it_(u
.it_
) {}
181 TEST_CONSTEXPR_CXX14 reference
operator*() const {return *it_
;}
182 TEST_CONSTEXPR_CXX14 pointer
operator->() const {return it_
;}
184 TEST_CONSTEXPR_CXX14 bidirectional_iterator
& operator++() {++it_
; return *this;}
185 TEST_CONSTEXPR_CXX14 bidirectional_iterator
operator++(int)
186 {bidirectional_iterator
tmp(*this); ++(*this); return tmp
;}
188 TEST_CONSTEXPR_CXX14 bidirectional_iterator
& operator--() {--it_
; return *this;}
189 TEST_CONSTEXPR_CXX14 bidirectional_iterator
operator--(int)
190 {bidirectional_iterator
tmp(*this); --(*this); return tmp
;}
193 void operator,(T
const &) DELETE_FUNCTION
;
196 template <class T
, class U
>
198 bool TEST_CONSTEXPR_CXX14
199 operator==(const bidirectional_iterator
<T
>& x
, const bidirectional_iterator
<U
>& y
)
201 return x
.base() == y
.base();
204 template <class T
, class U
>
206 bool TEST_CONSTEXPR_CXX14
207 operator!=(const bidirectional_iterator
<T
>& x
, const bidirectional_iterator
<U
>& y
)
213 class random_access_iterator
217 template <class U
> friend class random_access_iterator
;
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
;
223 typedef typename
std::iterator_traits
<It
>::reference reference
;
225 TEST_CONSTEXPR_CXX14 It
base() const {return it_
;}
227 TEST_CONSTEXPR_CXX14
random_access_iterator() : it_() {}
228 explicit TEST_CONSTEXPR_CXX14
random_access_iterator(It it
) : it_(it
) {}
230 TEST_CONSTEXPR_CXX14
random_access_iterator(const random_access_iterator
<U
>& u
) :it_(u
.it_
) {}
232 TEST_CONSTEXPR_CXX14 reference
operator*() const {return *it_
;}
233 TEST_CONSTEXPR_CXX14 pointer
operator->() const {return it_
;}
235 TEST_CONSTEXPR_CXX14 random_access_iterator
& operator++() {++it_
; return *this;}
236 TEST_CONSTEXPR_CXX14 random_access_iterator
operator++(int)
237 {random_access_iterator
tmp(*this); ++(*this); return tmp
;}
239 TEST_CONSTEXPR_CXX14 random_access_iterator
& operator--() {--it_
; return *this;}
240 TEST_CONSTEXPR_CXX14 random_access_iterator
operator--(int)
241 {random_access_iterator
tmp(*this); --(*this); return tmp
;}
243 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
245 {random_access_iterator
tmp(*this); tmp
+= n
; return tmp
;}
246 friend TEST_CONSTEXPR_CXX14 random_access_iterator
operator+(difference_type n
, random_access_iterator x
)
248 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
250 {random_access_iterator
tmp(*this); tmp
-= n
; return tmp
;}
252 TEST_CONSTEXPR_CXX14 reference
operator[](difference_type n
) const {return it_
[n
];}
255 void operator,(T
const &) DELETE_FUNCTION
;
258 template <class T
, class U
>
260 bool TEST_CONSTEXPR_CXX14
261 operator==(const random_access_iterator
<T
>& x
, const random_access_iterator
<U
>& y
)
263 return x
.base() == y
.base();
266 template <class T
, class U
>
268 bool TEST_CONSTEXPR_CXX14
269 operator!=(const random_access_iterator
<T
>& x
, const random_access_iterator
<U
>& y
)
274 template <class T
, class U
>
276 bool TEST_CONSTEXPR_CXX14
277 operator<(const random_access_iterator
<T
>& x
, const random_access_iterator
<U
>& y
)
279 return x
.base() < y
.base();
282 template <class T
, class U
>
284 bool TEST_CONSTEXPR_CXX14
285 operator<=(const random_access_iterator
<T
>& x
, const random_access_iterator
<U
>& y
)
290 template <class T
, class U
>
292 bool TEST_CONSTEXPR_CXX14
293 operator>(const random_access_iterator
<T
>& x
, const random_access_iterator
<U
>& y
)
298 template <class T
, class U
>
300 bool TEST_CONSTEXPR_CXX14
301 operator>=(const random_access_iterator
<T
>& x
, const random_access_iterator
<U
>& y
)
306 template <class T
, class U
>
307 inline TEST_CONSTEXPR_CXX14
308 typename
std::iterator_traits
<T
>::difference_type
309 operator-(const random_access_iterator
<T
>& x
, const random_access_iterator
<U
>& y
)
311 return x
.base() - y
.base();
314 template <class Iter
>
315 inline TEST_CONSTEXPR_CXX14 Iter
base(output_iterator
<Iter
> i
) { return i
.base(); }
317 template <class Iter
>
318 inline TEST_CONSTEXPR_CXX14 Iter
base(input_iterator
<Iter
> i
) { return i
.base(); }
320 template <class Iter
>
321 inline TEST_CONSTEXPR_CXX14 Iter
base(forward_iterator
<Iter
> i
) { return i
.base(); }
323 template <class Iter
>
324 inline TEST_CONSTEXPR_CXX14 Iter
base(bidirectional_iterator
<Iter
> i
) { return i
.base(); }
326 template <class Iter
>
327 inline TEST_CONSTEXPR_CXX14 Iter
base(random_access_iterator
<Iter
> i
) { return i
.base(); }
329 template <class Iter
> // everything else
330 inline TEST_CONSTEXPR_CXX14 Iter
base(Iter i
) { return i
; }
332 template <typename T
>
333 struct 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
;
340 enum ThrowingAction
{ TAIncrement
, TADecrement
, TADereference
, TAAssignment
, TAComparison
};
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
)
351 if (action_
== TAAssignment
)
354 #ifndef TEST_HAS_NO_EXCEPTIONS
355 throw std::runtime_error ("throw from iterator assignment");
365 current_
= rhs
.current_
;
366 action_
= rhs
.action_
;
371 // iterator operations
372 reference
operator*() const
374 if (action_
== TADereference
)
377 #ifndef TEST_HAS_NO_EXCEPTIONS
378 throw std::runtime_error ("throw from iterator dereference");
388 ThrowingIterator
& operator++()
390 if (action_
== TAIncrement
)
393 #ifndef TEST_HAS_NO_EXCEPTIONS
394 throw std::runtime_error ("throw from iterator increment");
405 ThrowingIterator
operator++(int)
407 ThrowingIterator temp
= *this;
412 ThrowingIterator
& operator--()
414 if (action_
== TADecrement
)
417 #ifndef TEST_HAS_NO_EXCEPTIONS
418 throw std::runtime_error ("throw from iterator decrement");
429 ThrowingIterator
operator--(int) {
430 ThrowingIterator temp
= *this;
435 bool operator== (const ThrowingIterator
&rhs
) const
437 if (action_
== TAComparison
)
440 #ifndef TEST_HAS_NO_EXCEPTIONS
441 throw std::runtime_error ("throw from iterator comparison");
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_
;
459 ThrowingAction action_
;
460 mutable size_t index_
;
463 template <typename T
>
464 bool operator== (const ThrowingIterator
<T
>& a
, const ThrowingIterator
<T
>& b
)
465 { return a
.operator==(b
); }
467 template <typename T
>
468 bool operator!= (const ThrowingIterator
<T
>& a
, const ThrowingIterator
<T
>& b
)
469 { return !a
.operator==(b
); }
471 template <typename T
>
472 struct 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
;
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
490 current_
= rhs
.current_
;
494 // iterator operations
495 reference
operator*() const TEST_NOEXCEPT
500 NonThrowingIterator
& operator++() TEST_NOEXCEPT
506 NonThrowingIterator
operator++(int) TEST_NOEXCEPT
508 NonThrowingIterator temp
= *this;
513 NonThrowingIterator
& operator--() TEST_NOEXCEPT
519 NonThrowingIterator
operator--(int) TEST_NOEXCEPT
521 NonThrowingIterator temp
= *this;
526 bool operator== (const NonThrowingIterator
&rhs
) const TEST_NOEXCEPT
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_
;
541 template <typename T
>
542 bool operator== (const NonThrowingIterator
<T
>& a
, const NonThrowingIterator
<T
>& b
) TEST_NOEXCEPT
543 { return a
.operator==(b
); }
545 template <typename T
>
546 bool operator!= (const NonThrowingIterator
<T
>& a
, const NonThrowingIterator
<T
>& b
) TEST_NOEXCEPT
547 { return !a
.operator==(b
); }
549 #undef DELETE_FUNCTION
551 #endif // ITERATORS_H