2 // Iterator Wrappers for the C++ library testsuite.
4 // Copyright (C) 2004, 2005 Free Software Foundation, Inc.
6 // This file is part of the GNU ISO C++ Library. This library is free
7 // software; you can redistribute it and/or modify it under the
8 // terms of the GNU General Public License as published by the
9 // Free Software Foundation; either version 2, or (at your option)
12 // This library is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
17 // You should have received a copy of the GNU General Public License along
18 // with this library; see the file COPYING. If not, write to the Free
19 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
22 // As a special exception, you may use this file as part of a free software
23 // library without restriction. Specifically, if other files instantiate
24 // templates or use macros or inline functions from this file, or you compile
25 // this file and link it with other files to produce an executable, this
26 // file does not by itself cause the resulting executable to be covered by
27 // the GNU General Public License. This exception does not however
28 // invalidate any other reasons why the executable file might be covered by
29 // the GNU General Public License.
31 // This file provides the following:
33 // input_iterator_wrapper, output_iterator_wrapper
34 // forward_iterator_wrapper, bidirectional_iterator_wrapper and
35 // random_access_wrapper, which attempt to exactly perform the requirements
36 // of these types of iterators. These are constructed from the class
37 // test_container, which is given two pointers to T and an iterator type.
39 #include <testsuite_hooks.h>
42 #ifndef _TESTSUITE_ITERATORS
43 #define _TESTSUITE_ITERATORS
45 #ifdef DISABLE_ITERATOR_DEBUG
46 #define ITERATOR_VERIFY(x)
48 #define ITERATOR_VERIFY(x) VERIFY(x)
54 * @brief Simple container for holding two pointers.
56 * Note that input_iterator_wrapper changes first to denote
57 * how the valid range of == , ++, etc. change as the iterators are used.
60 struct BoundsContainer
64 BoundsContainer(T
* _first
, T
* _last
)
65 : first(_first
), last(_last
)
69 // Simple container for holding state of a set of output iterators.
71 struct OutputContainer
: public BoundsContainer
<T
>
75 OutputContainer(T
* _first
, T
* _last
)
76 : BoundsContainer
<T
>(_first
, _last
), incrementedto(_first
)
78 writtento
= new bool[this->last
- this->first
];
79 for(int i
= 0; i
< this->last
- this->first
; i
++)
84 { delete[] writtento
; }
87 // Produced by output_iterator to allow limited writing to pointer
94 OutputContainer
<T
>* SharedInfo
;
95 WritableObject(T
* ptr_in
,OutputContainer
<T
>* SharedInfo_in
):
96 ptr(ptr_in
), SharedInfo(SharedInfo_in
)
101 operator=(const U
& new_val
)
103 ITERATOR_VERIFY(SharedInfo
->writtento
[ptr
- SharedInfo
->first
] == 0);
104 SharedInfo
->writtento
[ptr
- SharedInfo
->first
] = 1;
110 * @brief output_iterator wrapper for pointer
112 * This class takes a pointer and wraps it to provide exactly
113 * the requirements of a output_iterator. It should not be
114 * instansiated directly, but generated from a test_container
117 struct output_iterator_wrapper
: public std::iterator
118 <std::output_iterator_tag
, T
, ptrdiff_t, T
*, T
&>
120 typedef OutputContainer
<T
> ContainerType
;
122 ContainerType
* SharedInfo
;
124 output_iterator_wrapper(T
* _ptr
, ContainerType
* SharedInfo_in
)
125 :ptr(_ptr
), SharedInfo(SharedInfo_in
)
127 ITERATOR_VERIFY(ptr
>= SharedInfo
->first
&& ptr
<= SharedInfo
->last
);
130 output_iterator_wrapper(const output_iterator_wrapper
& in
)
131 :ptr(in
.ptr
), SharedInfo(in
.SharedInfo
)
137 ITERATOR_VERIFY(ptr
< SharedInfo
->last
);
138 ITERATOR_VERIFY(SharedInfo
->writtento
[ptr
- SharedInfo
->first
] == false);
139 return WritableObject
<T
>(ptr
, SharedInfo
);
142 output_iterator_wrapper
&
143 operator=(const output_iterator_wrapper
& in
)
146 SharedInfo
= in
.SharedInfo
;
149 output_iterator_wrapper
&
152 ITERATOR_VERIFY(SharedInfo
&& ptr
< SharedInfo
->last
);
153 ITERATOR_VERIFY(ptr
>=SharedInfo
->incrementedto
);
155 SharedInfo
->incrementedto
=ptr
;
159 output_iterator_wrapper
162 output_iterator_wrapper
<T
> tmp
= *this;
170 * @brief input_iterator wrapper for pointer
172 * This class takes a pointer and wraps it to provide exactly
173 * the requirements of a input_iterator. It should not be
174 * instansiated directly, but generated from a test_container
177 class input_iterator_wrapper
:public std::iterator
178 <std::input_iterator_tag
, T
, ptrdiff_t, T
*, T
&>
181 input_iterator_wrapper()
185 typedef BoundsContainer
<T
> ContainerType
;
187 ContainerType
* SharedInfo
;
189 input_iterator_wrapper(T
* _ptr
, ContainerType
* SharedInfo_in
)
190 : ptr(_ptr
), SharedInfo(SharedInfo_in
)
191 { ITERATOR_VERIFY(ptr
>= SharedInfo
->first
&& ptr
<= SharedInfo
->last
); }
193 input_iterator_wrapper(const input_iterator_wrapper
& in
)
194 : ptr(in
.ptr
), SharedInfo(in
.SharedInfo
)
198 operator==(const input_iterator_wrapper
& in
) const
200 ITERATOR_VERIFY(SharedInfo
!= NULL
&& SharedInfo
== in
.SharedInfo
);
201 ITERATOR_VERIFY(ptr
>=SharedInfo
->first
&& in
.ptr
>=SharedInfo
->first
);
202 return ptr
== in
.ptr
;
206 operator!=(const input_iterator_wrapper
& in
) const
208 return !(*this == in
);
214 ITERATOR_VERIFY(SharedInfo
&& ptr
< SharedInfo
->last
);
215 ITERATOR_VERIFY(ptr
>= SharedInfo
->first
);
225 input_iterator_wrapper
&
226 operator=(const input_iterator_wrapper
& in
)
229 SharedInfo
= in
.SharedInfo
;
233 input_iterator_wrapper
&
236 ITERATOR_VERIFY(SharedInfo
&& ptr
< SharedInfo
->last
);
237 ITERATOR_VERIFY(ptr
>=SharedInfo
->first
);
239 SharedInfo
->first
=ptr
;
252 * @brief forward_iterator wrapper for pointer
254 * This class takes a pointer and wraps it to provide exactly
255 * the requirements of a forward_iterator. It should not be
256 * instansiated directly, but generated from a test_container
259 struct forward_iterator_wrapper
:public input_iterator_wrapper
<T
>
261 typedef BoundsContainer
<T
> ContainerType
;
262 typedef std::forward_iterator_tag iterator_category
;
263 forward_iterator_wrapper(T
* _ptr
, ContainerType
* SharedInfo_in
)
264 :input_iterator_wrapper
<T
>(_ptr
, SharedInfo_in
)
267 forward_iterator_wrapper(const forward_iterator_wrapper
& in
)
268 :input_iterator_wrapper
<T
>(in
)
271 forward_iterator_wrapper()
274 this->SharedInfo
= NULL
;
280 ITERATOR_VERIFY(this->SharedInfo
&& this->ptr
< this->SharedInfo
->last
);
288 forward_iterator_wrapper
&
291 ITERATOR_VERIFY(this->SharedInfo
&& this->ptr
< this->SharedInfo
->last
);
296 forward_iterator_wrapper
299 forward_iterator_wrapper
<T
> tmp
= *this;
306 * @brief bidirectional_iterator wrapper for pointer
308 * This class takes a pointer and wraps it to provide exactly
309 * the requirements of a forward_iterator. It should not be
310 * instansiated directly, but generated from a test_container
313 struct bidirectional_iterator_wrapper
:public forward_iterator_wrapper
<T
>
315 typedef BoundsContainer
<T
> ContainerType
;
316 typedef std::bidirectional_iterator_tag iterator_category
;
317 bidirectional_iterator_wrapper(T
* _ptr
, ContainerType
* SharedInfo_in
)
318 :forward_iterator_wrapper
<T
>(_ptr
, SharedInfo_in
)
321 bidirectional_iterator_wrapper(const bidirectional_iterator_wrapper
& in
)
322 :forward_iterator_wrapper
<T
>(in
)
325 bidirectional_iterator_wrapper(): forward_iterator_wrapper
<T
>()
328 bidirectional_iterator_wrapper
&
329 operator=(const bidirectional_iterator_wrapper
& in
)
332 this->SharedInfo
= in
.SharedInfo
;
336 bidirectional_iterator_wrapper
&
339 ITERATOR_VERIFY(this->SharedInfo
&& this->ptr
< this->SharedInfo
->last
);
344 bidirectional_iterator_wrapper
347 bidirectional_iterator_wrapper
<T
> tmp
= *this;
352 bidirectional_iterator_wrapper
&
355 ITERATOR_VERIFY(this->SharedInfo
&& this->ptr
> this->SharedInfo
->first
);
360 bidirectional_iterator_wrapper
363 bidirectional_iterator_wrapper
<T
> tmp
= *this;
370 * @brief random_access_iterator wrapper for pointer
372 * This class takes a pointer and wraps it to provide exactly
373 * the requirements of a forward_iterator. It should not be
374 * instansiated directly, but generated from a test_container
377 struct random_access_iterator_wrapper
:public bidirectional_iterator_wrapper
<T
>
379 typedef BoundsContainer
<T
> ContainerType
;
380 typedef std::random_access_iterator_tag iterator_category
;
381 random_access_iterator_wrapper(T
* _ptr
, ContainerType
* SharedInfo_in
)
382 : bidirectional_iterator_wrapper
<T
>(_ptr
, SharedInfo_in
)
385 random_access_iterator_wrapper(const random_access_iterator_wrapper
<T
>& in
)
386 : bidirectional_iterator_wrapper
<T
>(in
)
389 random_access_iterator_wrapper():bidirectional_iterator_wrapper
<T
>()
392 random_access_iterator_wrapper
&
393 operator=(const random_access_iterator_wrapper
& in
)
396 this->SharedInfo
= in
.SharedInfo
;
399 random_access_iterator_wrapper
&
402 ITERATOR_VERIFY(this->SharedInfo
&& this->ptr
< this->SharedInfo
->last
);
407 random_access_iterator_wrapper
410 random_access_iterator_wrapper
<T
> tmp
= *this;
415 random_access_iterator_wrapper
&
418 ITERATOR_VERIFY(this->SharedInfo
&& this->ptr
> this->SharedInfo
->first
);
423 random_access_iterator_wrapper
426 random_access_iterator_wrapper
<T
> tmp
= *this;
431 random_access_iterator_wrapper
&
432 operator+=(ptrdiff_t n
)
436 ITERATOR_VERIFY(n
<= this->SharedInfo
->last
- this->ptr
);
441 ITERATOR_VERIFY(n
<= this->ptr
- this->SharedInfo
->first
);
447 random_access_iterator_wrapper
&
448 operator-=(ptrdiff_t n
)
449 { return *this += -n
; }
451 random_access_iterator_wrapper
452 operator-(ptrdiff_t n
) const
454 random_access_iterator_wrapper
<T
> tmp
= *this;
459 operator-(const random_access_iterator_wrapper
<T
>& in
) const
461 ITERATOR_VERIFY(this->SharedInfo
== in
.SharedInfo
);
462 return this->ptr
- in
.ptr
;
466 operator[](ptrdiff_t n
) const
467 { return *(*this + n
); }
470 operator<(const random_access_iterator_wrapper
<T
>& in
) const
472 ITERATOR_VERIFY(this->SharedInfo
== in
.SharedInfo
);
473 return this->ptr
< in
.ptr
;
477 operator>(const random_access_iterator_wrapper
<T
>& in
) const
483 operator>=(const random_access_iterator_wrapper
<T
>& in
) const
485 return !(*this < in
);
489 operator<=(const random_access_iterator_wrapper
<T
>& in
) const
491 return !(*this > in
);
496 random_access_iterator_wrapper
<T
>
497 operator+(random_access_iterator_wrapper
<T
> it
, ptrdiff_t n
)
501 random_access_iterator_wrapper
<T
>
502 operator+(ptrdiff_t n
, random_access_iterator_wrapper
<T
> it
)
507 * @brief A container-type class for holding iterator wrappers
508 * test_container takes two parameters, a class T and an iterator
509 * wrapper templated by T (for example forward_iterator_wrapper<T>.
510 * It takes two pointers representing a range and presents them as
511 * a container of iterators.
513 template <class T
, template<class T
> class ItType
>
514 struct test_container
516 typename ItType
<T
>::ContainerType bounds
;
517 test_container(T
* _first
, T
* _last
):bounds(_first
, _last
)
523 ITERATOR_VERIFY(pos
>= 0 && pos
<= (bounds
.last
- bounds
.first
));
524 return ItType
<T
>(bounds
.first
+ pos
, &bounds
);
530 ITERATOR_VERIFY(pos
>= bounds
.first
&& pos
<= bounds
.last
);
531 return ItType
<T
>(pos
, &bounds
);
536 { return it(bounds
.first
); }
540 { return it(bounds
.last
); }