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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
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;
150 output_iterator_wrapper&
153 ITERATOR_VERIFY(SharedInfo && ptr < SharedInfo->last);
154 ITERATOR_VERIFY(ptr>=SharedInfo->incrementedto);
156 SharedInfo->incrementedto=ptr;
160 output_iterator_wrapper
163 output_iterator_wrapper<T> tmp = *this;
171 * @brief input_iterator wrapper for pointer
173 * This class takes a pointer and wraps it to provide exactly
174 * the requirements of a input_iterator. It should not be
175 * instansiated directly, but generated from a test_container
178 class input_iterator_wrapper:public std::iterator
179 <std::input_iterator_tag, T, ptrdiff_t, T*, T&>
182 input_iterator_wrapper()
186 typedef BoundsContainer<T> ContainerType;
188 ContainerType* SharedInfo;
190 input_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in)
191 : ptr(_ptr), SharedInfo(SharedInfo_in)
192 { ITERATOR_VERIFY(ptr >= SharedInfo->first && ptr <= SharedInfo->last); }
194 input_iterator_wrapper(const input_iterator_wrapper& in)
195 : ptr(in.ptr), SharedInfo(in.SharedInfo)
199 operator==(const input_iterator_wrapper& in) const
201 ITERATOR_VERIFY(SharedInfo != NULL && SharedInfo == in.SharedInfo);
202 ITERATOR_VERIFY(ptr>=SharedInfo->first && in.ptr>=SharedInfo->first);
203 return ptr == in.ptr;
207 operator!=(const input_iterator_wrapper& in) const
209 return !(*this == in);
215 ITERATOR_VERIFY(SharedInfo && ptr < SharedInfo->last);
216 ITERATOR_VERIFY(ptr >= SharedInfo->first);
226 input_iterator_wrapper&
227 operator=(const input_iterator_wrapper& in)
230 SharedInfo = in.SharedInfo;
234 input_iterator_wrapper&
237 ITERATOR_VERIFY(SharedInfo && ptr < SharedInfo->last);
238 ITERATOR_VERIFY(ptr>=SharedInfo->first);
240 SharedInfo->first=ptr;
253 * @brief forward_iterator wrapper for pointer
255 * This class takes a pointer and wraps it to provide exactly
256 * the requirements of a forward_iterator. It should not be
257 * instansiated directly, but generated from a test_container
260 struct forward_iterator_wrapper:public input_iterator_wrapper<T>
262 typedef BoundsContainer<T> ContainerType;
263 typedef std::forward_iterator_tag iterator_category;
264 forward_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in)
265 :input_iterator_wrapper<T>(_ptr, SharedInfo_in)
268 forward_iterator_wrapper(const forward_iterator_wrapper& in)
269 :input_iterator_wrapper<T>(in)
272 forward_iterator_wrapper()
275 this->SharedInfo = NULL;
281 ITERATOR_VERIFY(this->SharedInfo && this->ptr < this->SharedInfo->last);
289 forward_iterator_wrapper&
292 ITERATOR_VERIFY(this->SharedInfo && this->ptr < this->SharedInfo->last);
297 forward_iterator_wrapper
300 forward_iterator_wrapper<T> tmp = *this;
307 * @brief bidirectional_iterator wrapper for pointer
309 * This class takes a pointer and wraps it to provide exactly
310 * the requirements of a forward_iterator. It should not be
311 * instansiated directly, but generated from a test_container
314 struct bidirectional_iterator_wrapper:public forward_iterator_wrapper<T>
316 typedef BoundsContainer<T> ContainerType;
317 typedef std::bidirectional_iterator_tag iterator_category;
318 bidirectional_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in)
319 :forward_iterator_wrapper<T>(_ptr, SharedInfo_in)
322 bidirectional_iterator_wrapper(const bidirectional_iterator_wrapper& in)
323 :forward_iterator_wrapper<T>(in)
326 bidirectional_iterator_wrapper(): forward_iterator_wrapper<T>()
329 bidirectional_iterator_wrapper&
330 operator=(const bidirectional_iterator_wrapper& in)
333 this->SharedInfo = in.SharedInfo;
337 bidirectional_iterator_wrapper&
340 ITERATOR_VERIFY(this->SharedInfo && this->ptr < this->SharedInfo->last);
345 bidirectional_iterator_wrapper
348 bidirectional_iterator_wrapper<T> tmp = *this;
353 bidirectional_iterator_wrapper&
356 ITERATOR_VERIFY(this->SharedInfo && this->ptr > this->SharedInfo->first);
361 bidirectional_iterator_wrapper
364 bidirectional_iterator_wrapper<T> tmp = *this;
371 * @brief random_access_iterator wrapper for pointer
373 * This class takes a pointer and wraps it to provide exactly
374 * the requirements of a forward_iterator. It should not be
375 * instansiated directly, but generated from a test_container
378 struct random_access_iterator_wrapper:public bidirectional_iterator_wrapper<T>
380 typedef BoundsContainer<T> ContainerType;
381 typedef std::random_access_iterator_tag iterator_category;
382 random_access_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in)
383 : bidirectional_iterator_wrapper<T>(_ptr, SharedInfo_in)
386 random_access_iterator_wrapper(const random_access_iterator_wrapper<T>& in)
387 : bidirectional_iterator_wrapper<T>(in)
390 random_access_iterator_wrapper():bidirectional_iterator_wrapper<T>()
393 random_access_iterator_wrapper&
394 operator=(const random_access_iterator_wrapper& in)
397 this->SharedInfo = in.SharedInfo;
401 random_access_iterator_wrapper&
404 ITERATOR_VERIFY(this->SharedInfo && this->ptr < this->SharedInfo->last);
409 random_access_iterator_wrapper
412 random_access_iterator_wrapper<T> tmp = *this;
417 random_access_iterator_wrapper&
420 ITERATOR_VERIFY(this->SharedInfo && this->ptr > this->SharedInfo->first);
425 random_access_iterator_wrapper
428 random_access_iterator_wrapper<T> tmp = *this;
433 random_access_iterator_wrapper&
434 operator+=(ptrdiff_t n)
438 ITERATOR_VERIFY(n <= this->SharedInfo->last - this->ptr);
443 ITERATOR_VERIFY(n <= this->ptr - this->SharedInfo->first);
449 random_access_iterator_wrapper&
450 operator-=(ptrdiff_t n)
451 { return *this += -n; }
453 random_access_iterator_wrapper
454 operator-(ptrdiff_t n) const
456 random_access_iterator_wrapper<T> tmp = *this;
461 operator-(const random_access_iterator_wrapper<T>& in) const
463 ITERATOR_VERIFY(this->SharedInfo == in.SharedInfo);
464 return this->ptr - in.ptr;
468 operator[](ptrdiff_t n) const
469 { return *(*this + n); }
472 operator<(const random_access_iterator_wrapper<T>& in) const
474 ITERATOR_VERIFY(this->SharedInfo == in.SharedInfo);
475 return this->ptr < in.ptr;
479 operator>(const random_access_iterator_wrapper<T>& in) const
485 operator>=(const random_access_iterator_wrapper<T>& in) const
487 return !(*this < in);
491 operator<=(const random_access_iterator_wrapper<T>& in) const
493 return !(*this > in);
498 random_access_iterator_wrapper<T>
499 operator+(random_access_iterator_wrapper<T> it, ptrdiff_t n)
503 random_access_iterator_wrapper<T>
504 operator+(ptrdiff_t n, random_access_iterator_wrapper<T> it)
509 * @brief A container-type class for holding iterator wrappers
510 * test_container takes two parameters, a class T and an iterator
511 * wrapper templated by T (for example forward_iterator_wrapper<T>.
512 * It takes two pointers representing a range and presents them as
513 * a container of iterators.
515 template <class T, template<class T> class ItType>
516 struct test_container
518 typename ItType<T>::ContainerType bounds;
519 test_container(T* _first, T* _last):bounds(_first, _last)
525 ITERATOR_VERIFY(pos >= 0 && pos <= (bounds.last - bounds.first));
526 return ItType<T>(bounds.first + pos, &bounds);
532 ITERATOR_VERIFY(pos >= bounds.first && pos <= bounds.last);
533 return ItType<T>(pos, &bounds);
538 { return it(bounds.first); }
542 { return it(bounds.last); }