Merge -r 127928:132243 from trunk
[official-gcc.git] / libstdc++-v3 / testsuite / util / testsuite_iterators.h
blob7a1241961373c38fca7026dd1bfe101b0cba460c
1 // -*- C++ -*-
2 // Iterator Wrappers for the C++ library testsuite.
3 //
4 // Copyright (C) 2004, 2005, 2006, 2007 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
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 <bits/stl_iterator_base_types.h>
41 #include <bits/stl_move.h>
43 #ifndef _TESTSUITE_ITERATORS
44 #define _TESTSUITE_ITERATORS
46 #ifdef DISABLE_ITERATOR_DEBUG
47 #define ITERATOR_VERIFY(x)
48 #else
49 #define ITERATOR_VERIFY(x) VERIFY(x)
50 #endif
52 namespace __gnu_test
54 /**
55 * @brief Simple container for holding two pointers.
57 * Note that input_iterator_wrapper changes first to denote
58 * how the valid range of == , ++, etc. change as the iterators are used.
60 template<typename T>
61 struct BoundsContainer
63 T* first;
64 T* last;
65 BoundsContainer(T* _first, T* _last) : 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;
108 #ifdef __GXX_EXPERIMENTAL_CXX0X__
109 template<class U>
110 void
111 operator=(U&& new_val)
113 ITERATOR_VERIFY(SharedInfo->writtento[ptr - SharedInfo->first] == 0);
114 SharedInfo->writtento[ptr - SharedInfo->first] = 1;
115 *ptr = std::move(new_val);
117 #endif
121 * @brief output_iterator wrapper for pointer
123 * This class takes a pointer and wraps it to provide exactly
124 * the requirements of a output_iterator. It should not be
125 * instansiated directly, but generated from a test_container
127 template<class T>
128 struct output_iterator_wrapper
129 : public std::iterator<std::output_iterator_tag, T, ptrdiff_t, T*, T&>
131 typedef OutputContainer<T> ContainerType;
132 T* ptr;
133 ContainerType* SharedInfo;
135 output_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in)
136 : ptr(_ptr), SharedInfo(SharedInfo_in)
138 ITERATOR_VERIFY(ptr >= SharedInfo->first && ptr <= SharedInfo->last);
141 output_iterator_wrapper(const output_iterator_wrapper& in)
142 : ptr(in.ptr), SharedInfo(in.SharedInfo)
145 WritableObject<T>
146 operator*() const
148 ITERATOR_VERIFY(ptr < SharedInfo->last);
149 ITERATOR_VERIFY(SharedInfo->writtento[ptr - SharedInfo->first] == false);
150 return WritableObject<T>(ptr, SharedInfo);
153 output_iterator_wrapper&
154 operator=(const output_iterator_wrapper& in)
156 ptr = in.ptr;
157 SharedInfo = in.SharedInfo;
158 return *this;
161 output_iterator_wrapper&
162 operator++()
164 ITERATOR_VERIFY(SharedInfo && ptr < SharedInfo->last);
165 ITERATOR_VERIFY(ptr>=SharedInfo->incrementedto);
166 ptr++;
167 SharedInfo->incrementedto=ptr;
168 return *this;
171 output_iterator_wrapper
172 operator++(int)
174 output_iterator_wrapper<T> tmp = *this;
175 ++*this;
176 return tmp;
182 * @brief input_iterator wrapper for pointer
184 * This class takes a pointer and wraps it to provide exactly
185 * the requirements of a input_iterator. It should not be
186 * instansiated directly, but generated from a test_container
188 template<class T>
189 class input_iterator_wrapper
190 : public std::iterator<std::input_iterator_tag, T, ptrdiff_t, T*, T&>
192 protected:
193 input_iterator_wrapper()
196 public:
197 typedef BoundsContainer<T> ContainerType;
198 T* ptr;
199 ContainerType* SharedInfo;
201 input_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in)
202 : ptr(_ptr), SharedInfo(SharedInfo_in)
203 { ITERATOR_VERIFY(ptr >= SharedInfo->first && ptr <= SharedInfo->last); }
205 input_iterator_wrapper(const input_iterator_wrapper& in)
206 : ptr(in.ptr), SharedInfo(in.SharedInfo)
209 bool
210 operator==(const input_iterator_wrapper& in) const
212 ITERATOR_VERIFY(SharedInfo != NULL && SharedInfo == in.SharedInfo);
213 ITERATOR_VERIFY(ptr>=SharedInfo->first && in.ptr>=SharedInfo->first);
214 return ptr == in.ptr;
217 bool
218 operator!=(const input_iterator_wrapper& in) const
220 return !(*this == in);
224 operator*() const
226 ITERATOR_VERIFY(SharedInfo && ptr < SharedInfo->last);
227 ITERATOR_VERIFY(ptr >= SharedInfo->first);
228 return *ptr;
232 operator->() const
234 return &**this;
237 input_iterator_wrapper&
238 operator=(const input_iterator_wrapper& in)
240 ptr = in.ptr;
241 SharedInfo = in.SharedInfo;
242 return *this;
245 input_iterator_wrapper&
246 operator++()
248 ITERATOR_VERIFY(SharedInfo && ptr < SharedInfo->last);
249 ITERATOR_VERIFY(ptr>=SharedInfo->first);
250 ptr++;
251 SharedInfo->first=ptr;
252 return *this;
255 void
256 operator++(int)
258 ++*this;
264 * @brief forward_iterator wrapper for pointer
266 * This class takes a pointer and wraps it to provide exactly
267 * the requirements of a forward_iterator. It should not be
268 * instansiated directly, but generated from a test_container
270 template<class T>
271 struct forward_iterator_wrapper : public input_iterator_wrapper<T>
273 typedef BoundsContainer<T> ContainerType;
274 typedef std::forward_iterator_tag iterator_category;
275 forward_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in)
276 : input_iterator_wrapper<T>(_ptr, SharedInfo_in)
279 forward_iterator_wrapper(const forward_iterator_wrapper& in)
280 : input_iterator_wrapper<T>(in)
283 forward_iterator_wrapper()
285 this->ptr = NULL;
286 this->SharedInfo = NULL;
290 operator*() const
292 ITERATOR_VERIFY(this->SharedInfo && this->ptr < this->SharedInfo->last);
293 return *(this->ptr);
297 operator->() const
298 { return &**this; }
300 forward_iterator_wrapper&
301 operator++()
303 ITERATOR_VERIFY(this->SharedInfo && this->ptr < this->SharedInfo->last);
304 this->ptr++;
305 return *this;
308 forward_iterator_wrapper
309 operator++(int)
311 forward_iterator_wrapper<T> tmp = *this;
312 ++*this;
313 return tmp;
318 * @brief bidirectional_iterator wrapper for pointer
320 * This class takes a pointer and wraps it to provide exactly
321 * the requirements of a forward_iterator. It should not be
322 * instansiated directly, but generated from a test_container
324 template<class T>
325 struct bidirectional_iterator_wrapper : public forward_iterator_wrapper<T>
327 typedef BoundsContainer<T> ContainerType;
328 typedef std::bidirectional_iterator_tag iterator_category;
329 bidirectional_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in)
330 : forward_iterator_wrapper<T>(_ptr, SharedInfo_in)
333 bidirectional_iterator_wrapper(const bidirectional_iterator_wrapper& in)
334 : forward_iterator_wrapper<T>(in)
337 bidirectional_iterator_wrapper(): forward_iterator_wrapper<T>()
340 bidirectional_iterator_wrapper&
341 operator=(const bidirectional_iterator_wrapper& in)
343 this->ptr = in.ptr;
344 this->SharedInfo = in.SharedInfo;
345 return *this;
348 bidirectional_iterator_wrapper&
349 operator++()
351 ITERATOR_VERIFY(this->SharedInfo && this->ptr < this->SharedInfo->last);
352 this->ptr++;
353 return *this;
356 bidirectional_iterator_wrapper
357 operator++(int)
359 bidirectional_iterator_wrapper<T> tmp = *this;
360 ++*this;
361 return tmp;
364 bidirectional_iterator_wrapper&
365 operator--()
367 ITERATOR_VERIFY(this->SharedInfo && this->ptr > this->SharedInfo->first);
368 this->ptr--;
369 return *this;
372 bidirectional_iterator_wrapper
373 operator--(int)
375 bidirectional_iterator_wrapper<T> tmp = *this;
376 --*this;
377 return tmp;
382 * @brief random_access_iterator wrapper for pointer
384 * This class takes a pointer and wraps it to provide exactly
385 * the requirements of a forward_iterator. It should not be
386 * instansiated directly, but generated from a test_container
388 template<class T>
389 struct random_access_iterator_wrapper
390 : public bidirectional_iterator_wrapper<T>
392 typedef BoundsContainer<T> ContainerType;
393 typedef std::random_access_iterator_tag iterator_category;
394 random_access_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in)
395 : bidirectional_iterator_wrapper<T>(_ptr, SharedInfo_in)
398 random_access_iterator_wrapper(const random_access_iterator_wrapper<T>& in)
399 : bidirectional_iterator_wrapper<T>(in)
402 random_access_iterator_wrapper():bidirectional_iterator_wrapper<T>()
405 random_access_iterator_wrapper&
406 operator=(const random_access_iterator_wrapper& in)
408 this->ptr = in.ptr;
409 this->SharedInfo = in.SharedInfo;
410 return *this;
413 random_access_iterator_wrapper&
414 operator++()
416 ITERATOR_VERIFY(this->SharedInfo && this->ptr < this->SharedInfo->last);
417 this->ptr++;
418 return *this;
421 random_access_iterator_wrapper
422 operator++(int)
424 random_access_iterator_wrapper<T> tmp = *this;
425 ++*this;
426 return tmp;
429 random_access_iterator_wrapper&
430 operator--()
432 ITERATOR_VERIFY(this->SharedInfo && this->ptr > this->SharedInfo->first);
433 this->ptr--;
434 return *this;
437 random_access_iterator_wrapper
438 operator--(int)
440 random_access_iterator_wrapper<T> tmp = *this;
441 --*this;
442 return tmp;
445 random_access_iterator_wrapper&
446 operator+=(ptrdiff_t n)
448 if(n > 0)
450 ITERATOR_VERIFY(n <= this->SharedInfo->last - this->ptr);
451 this->ptr += n;
453 else
455 ITERATOR_VERIFY(n <= this->ptr - this->SharedInfo->first);
456 this->ptr += n;
458 return *this;
461 random_access_iterator_wrapper&
462 operator-=(ptrdiff_t n)
463 { return *this += -n; }
465 random_access_iterator_wrapper
466 operator-(ptrdiff_t n) const
468 random_access_iterator_wrapper<T> tmp = *this;
469 return tmp -= n;
472 ptrdiff_t
473 operator-(const random_access_iterator_wrapper<T>& in) const
475 ITERATOR_VERIFY(this->SharedInfo == in.SharedInfo);
476 return this->ptr - in.ptr;
480 operator[](ptrdiff_t n) const
481 { return *(*this + n); }
483 bool
484 operator<(const random_access_iterator_wrapper<T>& in) const
486 ITERATOR_VERIFY(this->SharedInfo == in.SharedInfo);
487 return this->ptr < in.ptr;
490 bool
491 operator>(const random_access_iterator_wrapper<T>& in) const
493 return in < *this;
496 bool
497 operator>=(const random_access_iterator_wrapper<T>& in) const
499 return !(*this < in);
502 bool
503 operator<=(const random_access_iterator_wrapper<T>& in) const
505 return !(*this > in);
509 template<typename T>
510 random_access_iterator_wrapper<T>
511 operator+(random_access_iterator_wrapper<T> it, ptrdiff_t n)
512 { return it += n; }
514 template<typename T>
515 random_access_iterator_wrapper<T>
516 operator+(ptrdiff_t n, random_access_iterator_wrapper<T> it)
517 { return it += n; }
520 /**
521 * @brief A container-type class for holding iterator wrappers
522 * test_container takes two parameters, a class T and an iterator
523 * wrapper templated by T (for example forward_iterator_wrapper<T>.
524 * It takes two pointers representing a range and presents them as
525 * a container of iterators.
527 template <class T, template<class T> class ItType>
528 struct test_container
530 typename ItType<T>::ContainerType bounds;
531 test_container(T* _first, T* _last):bounds(_first, _last)
534 ItType<T>
535 it(int pos)
537 ITERATOR_VERIFY(pos >= 0 && pos <= (bounds.last - bounds.first));
538 return ItType<T>(bounds.first + pos, &bounds);
541 ItType<T>
542 it(T* pos)
544 ITERATOR_VERIFY(pos >= bounds.first && pos <= bounds.last);
545 return ItType<T>(pos, &bounds);
548 ItType<T>
549 begin()
550 { return it(bounds.first); }
552 ItType<T>
553 end()
554 { return it(bounds.last); }
557 #endif