2 // Iterator Wrappers for the C++ library testsuite.
4 // Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010
5 // Free Software Foundation, Inc.
7 // This file is part of the GNU ISO C++ Library. This library is free
8 // software; you can redistribute it and/or modify it under the
9 // terms of the GNU General Public License as published by the
10 // Free Software Foundation; either version 3, or (at your option)
13 // This library is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU General Public License for more details.
18 // You should have received a copy of the GNU General Public License along
19 // with this library; see the file COPYING3. If not see
20 // <http://www.gnu.org/licenses/>.
23 // This file provides the following:
25 // input_iterator_wrapper, output_iterator_wrapper
26 // forward_iterator_wrapper, bidirectional_iterator_wrapper and
27 // random_access_wrapper, which attempt to exactly perform the requirements
28 // of these types of iterators. These are constructed from the class
29 // test_container, which is given two pointers to T and an iterator type.
31 #include <testsuite_hooks.h>
32 #include <bits/stl_iterator_base_types.h>
34 #ifdef __GXX_EXPERIMENTAL_CXX0X__
35 #include <bits/move.h>
38 #ifndef _TESTSUITE_ITERATORS
39 #define _TESTSUITE_ITERATORS
41 #ifdef DISABLE_ITERATOR_DEBUG
42 #define ITERATOR_VERIFY(x)
44 #define ITERATOR_VERIFY(x) VERIFY(x)
50 * @brief Simple container for holding two pointers.
52 * Note that input_iterator_wrapper changes first to denote
53 * how the valid range of == , ++, etc. change as the iterators are used.
56 struct BoundsContainer
60 BoundsContainer(T
* _first
, T
* _last
) : first(_first
), last(_last
)
64 // Simple container for holding state of a set of output iterators.
66 struct OutputContainer
: public BoundsContainer
<T
>
70 OutputContainer(T
* _first
, T
* _last
)
71 : BoundsContainer
<T
>(_first
, _last
), incrementedto(_first
)
73 writtento
= new bool[this->last
- this->first
];
74 for(int i
= 0; i
< this->last
- this->first
; i
++)
79 { delete[] writtento
; }
82 // Produced by output_iterator to allow limited writing to pointer
89 OutputContainer
<T
>* SharedInfo
;
90 WritableObject(T
* ptr_in
,OutputContainer
<T
>* SharedInfo_in
):
91 ptr(ptr_in
), SharedInfo(SharedInfo_in
)
94 #ifdef __GXX_EXPERIMENTAL_CXX0X__
97 operator=(U
&& new_val
)
99 ITERATOR_VERIFY(SharedInfo
->writtento
[ptr
- SharedInfo
->first
] == 0);
100 SharedInfo
->writtento
[ptr
- SharedInfo
->first
] = 1;
101 *ptr
= std::forward
<U
>(new_val
);
106 operator=(const U
& new_val
)
108 ITERATOR_VERIFY(SharedInfo
->writtento
[ptr
- SharedInfo
->first
] == 0);
109 SharedInfo
->writtento
[ptr
- SharedInfo
->first
] = 1;
116 * @brief output_iterator wrapper for pointer
118 * This class takes a pointer and wraps it to provide exactly
119 * the requirements of a output_iterator. It should not be
120 * instansiated directly, but generated from a test_container
123 struct output_iterator_wrapper
124 : public std::iterator
<std::output_iterator_tag
, T
, std::ptrdiff_t, T
*, T
&>
126 typedef OutputContainer
<T
> ContainerType
;
128 ContainerType
* SharedInfo
;
130 output_iterator_wrapper(T
* _ptr
, ContainerType
* SharedInfo_in
)
131 : ptr(_ptr
), SharedInfo(SharedInfo_in
)
133 ITERATOR_VERIFY(ptr
>= SharedInfo
->first
&& ptr
<= SharedInfo
->last
);
136 output_iterator_wrapper(const output_iterator_wrapper
& in
)
137 : ptr(in
.ptr
), SharedInfo(in
.SharedInfo
)
143 ITERATOR_VERIFY(ptr
< SharedInfo
->last
);
144 ITERATOR_VERIFY(SharedInfo
->writtento
[ptr
- SharedInfo
->first
] == false);
145 return WritableObject
<T
>(ptr
, SharedInfo
);
148 output_iterator_wrapper
&
149 operator=(const output_iterator_wrapper
& in
)
152 SharedInfo
= in
.SharedInfo
;
156 output_iterator_wrapper
&
159 ITERATOR_VERIFY(SharedInfo
&& ptr
< SharedInfo
->last
);
160 ITERATOR_VERIFY(ptr
>=SharedInfo
->incrementedto
);
162 SharedInfo
->incrementedto
=ptr
;
166 output_iterator_wrapper
169 output_iterator_wrapper
<T
> tmp
= *this;
177 * @brief input_iterator wrapper for pointer
179 * This class takes a pointer and wraps it to provide exactly
180 * the requirements of a input_iterator. It should not be
181 * instansiated directly, but generated from a test_container
184 class input_iterator_wrapper
185 : public std::iterator
<std::input_iterator_tag
, T
, std::ptrdiff_t, T
*, T
&>
188 input_iterator_wrapper()
192 typedef BoundsContainer
<T
> ContainerType
;
194 ContainerType
* SharedInfo
;
196 input_iterator_wrapper(T
* _ptr
, ContainerType
* SharedInfo_in
)
197 : ptr(_ptr
), SharedInfo(SharedInfo_in
)
198 { ITERATOR_VERIFY(ptr
>= SharedInfo
->first
&& ptr
<= SharedInfo
->last
); }
200 input_iterator_wrapper(const input_iterator_wrapper
& in
)
201 : ptr(in
.ptr
), SharedInfo(in
.SharedInfo
)
205 operator==(const input_iterator_wrapper
& in
) const
207 ITERATOR_VERIFY(SharedInfo
&& SharedInfo
== in
.SharedInfo
);
208 ITERATOR_VERIFY(ptr
>=SharedInfo
->first
&& in
.ptr
>=SharedInfo
->first
);
209 return ptr
== in
.ptr
;
213 operator!=(const input_iterator_wrapper
& in
) const
215 return !(*this == in
);
221 ITERATOR_VERIFY(SharedInfo
&& ptr
< SharedInfo
->last
);
222 ITERATOR_VERIFY(ptr
>= SharedInfo
->first
);
232 input_iterator_wrapper
&
233 operator=(const input_iterator_wrapper
& in
)
236 SharedInfo
= in
.SharedInfo
;
240 input_iterator_wrapper
&
243 ITERATOR_VERIFY(SharedInfo
&& ptr
< SharedInfo
->last
);
244 ITERATOR_VERIFY(ptr
>=SharedInfo
->first
);
246 SharedInfo
->first
=ptr
;
259 * @brief forward_iterator wrapper for pointer
261 * This class takes a pointer and wraps it to provide exactly
262 * the requirements of a forward_iterator. It should not be
263 * instansiated directly, but generated from a test_container
266 struct forward_iterator_wrapper
: public input_iterator_wrapper
<T
>
268 typedef BoundsContainer
<T
> ContainerType
;
269 typedef std::forward_iterator_tag iterator_category
;
270 forward_iterator_wrapper(T
* _ptr
, ContainerType
* SharedInfo_in
)
271 : input_iterator_wrapper
<T
>(_ptr
, SharedInfo_in
)
274 forward_iterator_wrapper(const forward_iterator_wrapper
& in
)
275 : input_iterator_wrapper
<T
>(in
)
278 forward_iterator_wrapper()
281 this->SharedInfo
= 0;
287 ITERATOR_VERIFY(this->SharedInfo
&& this->ptr
< this->SharedInfo
->last
);
295 forward_iterator_wrapper
&
298 ITERATOR_VERIFY(this->SharedInfo
&& this->ptr
< this->SharedInfo
->last
);
303 forward_iterator_wrapper
306 forward_iterator_wrapper
<T
> tmp
= *this;
313 * @brief bidirectional_iterator wrapper for pointer
315 * This class takes a pointer and wraps it to provide exactly
316 * the requirements of a forward_iterator. It should not be
317 * instansiated directly, but generated from a test_container
320 struct bidirectional_iterator_wrapper
: public forward_iterator_wrapper
<T
>
322 typedef BoundsContainer
<T
> ContainerType
;
323 typedef std::bidirectional_iterator_tag iterator_category
;
324 bidirectional_iterator_wrapper(T
* _ptr
, ContainerType
* SharedInfo_in
)
325 : forward_iterator_wrapper
<T
>(_ptr
, SharedInfo_in
)
328 bidirectional_iterator_wrapper(const bidirectional_iterator_wrapper
& in
)
329 : forward_iterator_wrapper
<T
>(in
)
332 bidirectional_iterator_wrapper(): forward_iterator_wrapper
<T
>()
335 bidirectional_iterator_wrapper
&
336 operator=(const bidirectional_iterator_wrapper
& in
)
339 this->SharedInfo
= in
.SharedInfo
;
343 bidirectional_iterator_wrapper
&
346 ITERATOR_VERIFY(this->SharedInfo
&& this->ptr
< this->SharedInfo
->last
);
351 bidirectional_iterator_wrapper
354 bidirectional_iterator_wrapper
<T
> tmp
= *this;
359 bidirectional_iterator_wrapper
&
362 ITERATOR_VERIFY(this->SharedInfo
&& this->ptr
> this->SharedInfo
->first
);
367 bidirectional_iterator_wrapper
370 bidirectional_iterator_wrapper
<T
> tmp
= *this;
377 * @brief random_access_iterator wrapper for pointer
379 * This class takes a pointer and wraps it to provide exactly
380 * the requirements of a forward_iterator. It should not be
381 * instansiated directly, but generated from a test_container
384 struct random_access_iterator_wrapper
385 : public bidirectional_iterator_wrapper
<T
>
387 typedef BoundsContainer
<T
> ContainerType
;
388 typedef std::random_access_iterator_tag iterator_category
;
389 random_access_iterator_wrapper(T
* _ptr
, ContainerType
* SharedInfo_in
)
390 : bidirectional_iterator_wrapper
<T
>(_ptr
, SharedInfo_in
)
393 random_access_iterator_wrapper(const random_access_iterator_wrapper
<T
>& in
)
394 : bidirectional_iterator_wrapper
<T
>(in
)
397 random_access_iterator_wrapper():bidirectional_iterator_wrapper
<T
>()
400 random_access_iterator_wrapper
&
401 operator=(const random_access_iterator_wrapper
& in
)
404 this->SharedInfo
= in
.SharedInfo
;
408 random_access_iterator_wrapper
&
411 ITERATOR_VERIFY(this->SharedInfo
&& this->ptr
< this->SharedInfo
->last
);
416 random_access_iterator_wrapper
419 random_access_iterator_wrapper
<T
> tmp
= *this;
424 random_access_iterator_wrapper
&
427 ITERATOR_VERIFY(this->SharedInfo
&& this->ptr
> this->SharedInfo
->first
);
432 random_access_iterator_wrapper
435 random_access_iterator_wrapper
<T
> tmp
= *this;
440 random_access_iterator_wrapper
&
441 operator+=(std::ptrdiff_t n
)
445 ITERATOR_VERIFY(n
<= this->SharedInfo
->last
- this->ptr
);
450 ITERATOR_VERIFY(n
<= this->ptr
- this->SharedInfo
->first
);
456 random_access_iterator_wrapper
&
457 operator-=(std::ptrdiff_t n
)
458 { return *this += -n
; }
460 random_access_iterator_wrapper
461 operator-(std::ptrdiff_t n
) const
463 random_access_iterator_wrapper
<T
> tmp
= *this;
468 operator-(const random_access_iterator_wrapper
<T
>& in
) const
470 ITERATOR_VERIFY(this->SharedInfo
== in
.SharedInfo
);
471 return this->ptr
- in
.ptr
;
475 operator[](std::ptrdiff_t n
) const
476 { return *(*this + n
); }
479 operator<(const random_access_iterator_wrapper
<T
>& in
) const
481 ITERATOR_VERIFY(this->SharedInfo
== in
.SharedInfo
);
482 return this->ptr
< in
.ptr
;
486 operator>(const random_access_iterator_wrapper
<T
>& in
) const
492 operator>=(const random_access_iterator_wrapper
<T
>& in
) const
494 return !(*this < in
);
498 operator<=(const random_access_iterator_wrapper
<T
>& in
) const
500 return !(*this > in
);
505 random_access_iterator_wrapper
<T
>
506 operator+(random_access_iterator_wrapper
<T
> it
, std::ptrdiff_t n
)
510 random_access_iterator_wrapper
<T
>
511 operator+(std::ptrdiff_t n
, random_access_iterator_wrapper
<T
> it
)
516 * @brief A container-type class for holding iterator wrappers
517 * test_container takes two parameters, a class T and an iterator
518 * wrapper templated by T (for example forward_iterator_wrapper<T>.
519 * It takes two pointers representing a range and presents them as
520 * a container of iterators.
522 template <class T
, template<class T
> class ItType
>
523 struct test_container
525 typename ItType
<T
>::ContainerType bounds
;
526 test_container(T
* _first
, T
* _last
):bounds(_first
, _last
)
532 ITERATOR_VERIFY(pos
>= 0 && pos
<= (bounds
.last
- bounds
.first
));
533 return ItType
<T
>(bounds
.first
+ pos
, &bounds
);
539 ITERATOR_VERIFY(pos
>= bounds
.first
&& pos
<= bounds
.last
);
540 return ItType
<T
>(pos
, &bounds
);
545 { return it(bounds
.first
); }
549 { return it(bounds
.last
); }