Merge reload-branch up to revision 101000
[official-gcc.git] / libstdc++-v3 / testsuite / testsuite_iterators.h
blob1a6a295ee975e2b963197f9091b08d1278d940a9
1 // -*- C++ -*-
2 // Iterator Wrappers for the C++ library testsuite.
3 //
4 // Copyright (C) 2004, 2005 Free Software Foundation, Inc.
5 //
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)
10 // any later version.
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,
20 // USA.
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>
40 #include <iterator>
42 #ifndef _TESTSUITE_ITERATORS
43 #define _TESTSUITE_ITERATORS
45 #ifdef DISABLE_ITERATOR_DEBUG
46 #define ITERATOR_VERIFY(x)
47 #else
48 #define ITERATOR_VERIFY(x) VERIFY(x)
49 #endif
51 namespace __gnu_test
53 /**
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.
59 template<typename T>
60 struct BoundsContainer
62 T* first;
63 T* last;
64 BoundsContainer(T* _first, T* _last)
65 : first(_first), last(_last)
66 { }
69 // Simple container for holding state of a set of output iterators.
70 template<typename T>
71 struct OutputContainer : public BoundsContainer<T>
73 T* incrementedto;
74 bool* writtento;
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++)
80 writtento[i] = false;
83 ~OutputContainer()
84 { delete[] writtento; }
87 // Produced by output_iterator to allow limited writing to pointer
88 template<class T>
89 class WritableObject
91 T* ptr;
93 public:
94 OutputContainer<T>* SharedInfo;
95 WritableObject(T* ptr_in,OutputContainer<T>* SharedInfo_in):
96 ptr(ptr_in), SharedInfo(SharedInfo_in)
97 { }
99 template<class U>
100 void
101 operator=(const U& new_val)
103 ITERATOR_VERIFY(SharedInfo->writtento[ptr - SharedInfo->first] == 0);
104 SharedInfo->writtento[ptr - SharedInfo->first] = 1;
105 *ptr = new_val;
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
116 template<class T>
117 struct output_iterator_wrapper: public std::iterator
118 <std::output_iterator_tag, T, ptrdiff_t, T*, T&>
120 typedef OutputContainer<T> ContainerType;
121 T* ptr;
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)
134 WritableObject<T>
135 operator*() const
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)
145 ptr = in.ptr;
146 SharedInfo = in.SharedInfo;
149 output_iterator_wrapper&
150 operator++()
152 ITERATOR_VERIFY(SharedInfo && ptr < SharedInfo->last);
153 ITERATOR_VERIFY(ptr>=SharedInfo->incrementedto);
154 ptr++;
155 SharedInfo->incrementedto=ptr;
156 return *this;
159 output_iterator_wrapper
160 operator++(int)
162 output_iterator_wrapper<T> tmp = *this;
163 ++*this;
164 return tmp;
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
176 template<class T>
177 class input_iterator_wrapper:public std::iterator
178 <std::input_iterator_tag, T, ptrdiff_t, T*, T&>
180 protected:
181 input_iterator_wrapper()
184 public:
185 typedef BoundsContainer<T> ContainerType;
186 T* ptr;
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)
197 bool
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;
205 bool
206 operator!=(const input_iterator_wrapper& in) const
208 return !(*this == in);
212 operator*() const
214 ITERATOR_VERIFY(SharedInfo && ptr < SharedInfo->last);
215 ITERATOR_VERIFY(ptr >= SharedInfo->first);
216 return *ptr;
220 operator->() const
222 return &**this;
225 input_iterator_wrapper&
226 operator=(const input_iterator_wrapper& in)
228 ptr = in.ptr;
229 SharedInfo = in.SharedInfo;
230 return *this;
233 input_iterator_wrapper&
234 operator++()
236 ITERATOR_VERIFY(SharedInfo && ptr < SharedInfo->last);
237 ITERATOR_VERIFY(ptr>=SharedInfo->first);
238 ptr++;
239 SharedInfo->first=ptr;
240 return *this;
243 void
244 operator++(int)
246 ++*this;
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
258 template<class T>
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()
273 this->ptr = NULL;
274 this->SharedInfo = NULL;
278 operator*() const
280 ITERATOR_VERIFY(this->SharedInfo && this->ptr < this->SharedInfo->last);
281 return *(this->ptr);
285 operator->() const
286 { return &**this; }
288 forward_iterator_wrapper&
289 operator++()
291 ITERATOR_VERIFY(this->SharedInfo && this->ptr < this->SharedInfo->last);
292 this->ptr++;
293 return *this;
296 forward_iterator_wrapper
297 operator++(int)
299 forward_iterator_wrapper<T> tmp = *this;
300 ++*this;
301 return tmp;
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
312 template<class T>
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)
331 this->ptr = in.ptr;
332 this->SharedInfo = in.SharedInfo;
333 return *this;
336 bidirectional_iterator_wrapper&
337 operator++()
339 ITERATOR_VERIFY(this->SharedInfo && this->ptr < this->SharedInfo->last);
340 this->ptr++;
341 return *this;
344 bidirectional_iterator_wrapper
345 operator++(int)
347 bidirectional_iterator_wrapper<T> tmp = *this;
348 ++*this;
349 return tmp;
352 bidirectional_iterator_wrapper&
353 operator--()
355 ITERATOR_VERIFY(this->SharedInfo && this->ptr > this->SharedInfo->first);
356 this->ptr--;
357 return *this;
360 bidirectional_iterator_wrapper
361 operator--(int)
363 bidirectional_iterator_wrapper<T> tmp = *this;
364 --*this;
365 return tmp;
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
376 template<class T>
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)
395 this->ptr = in.ptr;
396 this->SharedInfo = in.SharedInfo;
399 random_access_iterator_wrapper&
400 operator++()
402 ITERATOR_VERIFY(this->SharedInfo && this->ptr < this->SharedInfo->last);
403 this->ptr++;
404 return *this;
407 random_access_iterator_wrapper
408 operator++(int)
410 random_access_iterator_wrapper<T> tmp = *this;
411 ++*this;
412 return tmp;
415 random_access_iterator_wrapper&
416 operator--()
418 ITERATOR_VERIFY(this->SharedInfo && this->ptr > this->SharedInfo->first);
419 this->ptr--;
420 return *this;
423 random_access_iterator_wrapper
424 operator--(int)
426 random_access_iterator_wrapper<T> tmp = *this;
427 --*this;
428 return tmp;
431 random_access_iterator_wrapper&
432 operator+=(ptrdiff_t n)
434 if(n > 0)
436 ITERATOR_VERIFY(n <= this->SharedInfo->last - this->ptr);
437 this->ptr += n;
439 else
441 ITERATOR_VERIFY(n <= this->ptr - this->SharedInfo->first);
442 this->ptr += n;
444 return *this;
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;
455 return tmp -= n;
458 ptrdiff_t
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); }
469 bool
470 operator<(const random_access_iterator_wrapper<T>& in) const
472 ITERATOR_VERIFY(this->SharedInfo == in.SharedInfo);
473 return this->ptr < in.ptr;
476 bool
477 operator>(const random_access_iterator_wrapper<T>& in) const
479 return in < *this;
482 bool
483 operator>=(const random_access_iterator_wrapper<T>& in) const
485 return !(*this < in);
488 bool
489 operator<=(const random_access_iterator_wrapper<T>& in) const
491 return !(*this > in);
495 template<typename T>
496 random_access_iterator_wrapper<T>
497 operator+(random_access_iterator_wrapper<T> it, ptrdiff_t n)
498 { return it += n; }
500 template<typename T>
501 random_access_iterator_wrapper<T>
502 operator+(ptrdiff_t n, random_access_iterator_wrapper<T> it)
503 { return it += n; }
506 /**
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)
520 ItType<T>
521 it(int pos)
523 ITERATOR_VERIFY(pos >= 0 && pos <= (bounds.last - bounds.first));
524 return ItType<T>(bounds.first + pos, &bounds);
527 ItType<T>
528 it(T* pos)
530 ITERATOR_VERIFY(pos >= bounds.first && pos <= bounds.last);
531 return ItType<T>(pos, &bounds);
534 ItType<T>
535 begin()
536 { return it(bounds.first); }
538 ItType<T>
539 end()
540 { return it(bounds.last); }
543 #endif