* Makefile.in (WERROR_FLAGS): Renamed from WERROR.
[official-gcc.git] / libstdc++-v3 / testsuite / testsuite_iterators.h
blob435bb1d26b581521766af21bdebd6e2f69c38e95
1 // -*- C++ -*-
2 // Iterator Wrappers for the C++ library testsuite.
3 //
4 // Copyright (C) 2004 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 = 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 void
100 operator=(T& new_val)
102 ITERATOR_VERIFY(SharedInfo->writtento[ptr - SharedInfo->first] == 0);
103 SharedInfo->writtento[ptr - SharedInfo->first] = 1;
104 ptr = new_val;
109 * @brief output_iterator wrapper for pointer
111 * This class takes a pointer and wraps it to provide exactly
112 * the requirements of a output_iterator. It should not be
113 * instansiated directly, but generated from a test_container
115 template<class T>
116 struct output_iterator_wrapper: public std::iterator
117 <std::output_iterator_tag, T, ptrdiff_t, T*, T&>
119 typedef OutputContainer<T> ContainerType;
120 T* ptr;
121 ContainerType* SharedInfo;
123 output_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in)
124 :ptr(_ptr), SharedInfo(SharedInfo_in)
126 ITERATOR_VERIFY(ptr >= SharedInfo->first && ptr <= SharedInfo->last);
129 output_iterator_wrapper(const output_iterator_wrapper& in)
130 :ptr(in.ptr), SharedInfo(in.SharedInfo)
133 WritableObject<T>
134 operator*() const
136 ITERATOR_VERIFY(ptr < SharedInfo->last);
137 ITERATOR_VERIFY(SharedInfo->writtento[ptr - SharedInfo->first] == false);
138 return WritableObject<T>(ptr, SharedInfo);
141 output_iterator_wrapper&
142 operator=(const output_iterator_wrapper& in)
144 ptr = in.ptr;
145 SharedInfo = in.SharedInfo;
148 output_iterator_wrapper&
149 operator++()
151 ITERATOR_VERIFY(SharedInfo && ptr < SharedInfo->last);
152 ITERATOR_VERIFY(ptr>=SharedInfo->first);
153 ptr++;
154 SharedInfo->first=ptr;
155 return *this;
158 output_iterator_wrapper
159 operator++(int)
161 output_iterator_wrapper<T> tmp = *this;
162 ++*this;
163 return tmp;
169 * @brief input_iterator wrapper for pointer
171 * This class takes a pointer and wraps it to provide exactly
172 * the requirements of a input_iterator. It should not be
173 * instansiated directly, but generated from a test_container
175 template<class T>
176 class input_iterator_wrapper:public std::iterator
177 <std::input_iterator_tag, T, ptrdiff_t, T*, T&>
179 protected:
180 input_iterator_wrapper()
183 public:
184 typedef BoundsContainer<T> ContainerType;
185 T* ptr;
186 ContainerType* SharedInfo;
188 input_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in)
189 : ptr(_ptr), SharedInfo(SharedInfo_in)
190 { ITERATOR_VERIFY(ptr >= SharedInfo->first && ptr <= SharedInfo->last); }
192 input_iterator_wrapper(const input_iterator_wrapper& in)
193 : ptr(in.ptr), SharedInfo(in.SharedInfo)
196 bool
197 operator==(const input_iterator_wrapper& in) const
199 ITERATOR_VERIFY(SharedInfo != NULL && SharedInfo == in.SharedInfo);
200 ITERATOR_VERIFY(ptr>=SharedInfo->first && in.ptr>=SharedInfo->first);
201 return ptr == in.ptr;
204 bool
205 operator!=(const input_iterator_wrapper& in) const
207 return !(*this == in);
211 operator*() const
213 ITERATOR_VERIFY(SharedInfo && ptr < SharedInfo->last);
214 ITERATOR_VERIFY(ptr >= SharedInfo->first);
215 return *ptr;
219 operator->() const
221 return &**this;
224 input_iterator_wrapper&
225 operator=(const input_iterator_wrapper& in)
227 ptr = in.ptr;
228 SharedInfo = in.SharedInfo;
229 return *this;
232 input_iterator_wrapper&
233 operator++()
235 ITERATOR_VERIFY(SharedInfo && ptr < SharedInfo->last);
236 ITERATOR_VERIFY(ptr>=SharedInfo->first);
237 ptr++;
238 SharedInfo->first=ptr;
239 return *this;
242 void
243 operator++(int)
245 ++*this;
251 * @brief forward_iterator wrapper for pointer
253 * This class takes a pointer and wraps it to provide exactly
254 * the requirements of a forward_iterator. It should not be
255 * instansiated directly, but generated from a test_container
257 template<class T>
258 struct forward_iterator_wrapper:public input_iterator_wrapper<T>
260 typedef BoundsContainer<T> ContainerType;
261 typedef std::forward_iterator_tag iterator_category;
262 forward_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in)
263 :input_iterator_wrapper<T>(_ptr, SharedInfo_in)
266 forward_iterator_wrapper(const forward_iterator_wrapper& in)
267 :input_iterator_wrapper<T>(in)
270 forward_iterator_wrapper()
272 this->ptr = NULL;
273 this->SharedInfo = NULL;
277 operator*() const
279 ITERATOR_VERIFY(this->SharedInfo && this->ptr < this->SharedInfo->last);
280 return *(this->ptr);
284 operator->() const
285 { return &**this; }
287 forward_iterator_wrapper&
288 operator++()
290 ITERATOR_VERIFY(this->SharedInfo && this->ptr < this->SharedInfo->last);
291 this->ptr++;
292 return *this;
295 forward_iterator_wrapper
296 operator++(int)
298 forward_iterator_wrapper<T> tmp = *this;
299 ++*this;
300 return tmp;
305 * @brief bidirectional_iterator wrapper for pointer
307 * This class takes a pointer and wraps it to provide exactly
308 * the requirements of a forward_iterator. It should not be
309 * instansiated directly, but generated from a test_container
311 template<class T>
312 struct bidirectional_iterator_wrapper:public forward_iterator_wrapper<T>
314 typedef BoundsContainer<T> ContainerType;
315 typedef std::bidirectional_iterator_tag iterator_category;
316 bidirectional_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in)
317 :forward_iterator_wrapper<T>(_ptr, SharedInfo_in)
320 bidirectional_iterator_wrapper(const bidirectional_iterator_wrapper& in)
321 :forward_iterator_wrapper<T>(in)
324 bidirectional_iterator_wrapper(): forward_iterator_wrapper<T>()
327 bidirectional_iterator_wrapper&
328 operator=(const bidirectional_iterator_wrapper& in)
330 this->ptr = in.ptr;
331 this->SharedInfo = in.SharedInfo;
332 return *this;
335 bidirectional_iterator_wrapper&
336 operator++()
338 ITERATOR_VERIFY(this->SharedInfo && this->ptr < this->SharedInfo->last);
339 this->ptr++;
340 return *this;
343 bidirectional_iterator_wrapper
344 operator++(int)
346 bidirectional_iterator_wrapper<T> tmp = *this;
347 ++*this;
348 return tmp;
351 bidirectional_iterator_wrapper&
352 operator--()
354 ITERATOR_VERIFY(this->SharedInfo && this->ptr > this->SharedInfo->first);
355 this->ptr--;
356 return *this;
359 bidirectional_iterator_wrapper
360 operator--(int)
362 bidirectional_iterator_wrapper<T> tmp = *this;
363 --*this;
364 return tmp;
369 * @brief random_access_iterator wrapper for pointer
371 * This class takes a pointer and wraps it to provide exactly
372 * the requirements of a forward_iterator. It should not be
373 * instansiated directly, but generated from a test_container
375 template<class T>
376 struct random_access_iterator_wrapper:public bidirectional_iterator_wrapper<T>
378 typedef BoundsContainer<T> ContainerType;
379 typedef std::random_access_iterator_tag iterator_category;
380 random_access_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in)
381 : bidirectional_iterator_wrapper<T>(_ptr, SharedInfo_in)
384 random_access_iterator_wrapper(const random_access_iterator_wrapper<T>& in)
385 : bidirectional_iterator_wrapper<T>(in)
388 random_access_iterator_wrapper():bidirectional_iterator_wrapper<T>()
391 random_access_iterator_wrapper&
392 operator=(const random_access_iterator_wrapper& in)
394 this->ptr = in.ptr;
395 this->SharedInfo = in.SharedInfo;
398 random_access_iterator_wrapper&
399 operator++()
401 ITERATOR_VERIFY(this->SharedInfo && this->ptr < this->SharedInfo->last);
402 this->ptr++;
403 return *this;
406 random_access_iterator_wrapper
407 operator++(int)
409 random_access_iterator_wrapper<T> tmp = *this;
410 ++*this;
411 return tmp;
414 random_access_iterator_wrapper&
415 operator--()
417 ITERATOR_VERIFY(this->SharedInfo && this->ptr > this->SharedInfo->first);
418 this->ptr--;
419 return *this;
422 random_access_iterator_wrapper
423 operator--(int)
425 random_access_iterator_wrapper<T> tmp = *this;
426 ++*this;
427 return tmp;
430 random_access_iterator_wrapper&
431 operator+=(ptrdiff_t n)
433 if(n > 0)
435 ITERATOR_VERIFY(n <= this->SharedInfo->last - this->ptr);
436 this->ptr += n;
438 else
440 ITERATOR_VERIFY(n <= this->ptr - this->SharedInfo->first);
441 this->ptr += n;
443 return *this;
446 random_access_iterator_wrapper
447 operator+(ptrdiff_t n)
449 random_access_iterator_wrapper<T> tmp = *this;
450 return tmp += n;
453 random_access_iterator_wrapper&
454 operator-=(ptrdiff_t n)
455 { return *this += -n; }
457 random_access_iterator_wrapper
458 operator-(ptrdiff_t n)
460 random_access_iterator_wrapper<T> tmp = *this;
461 return tmp -= n;
464 ptrdiff_t
465 operator-(const random_access_iterator_wrapper<T>& in)
467 ITERATOR_VERIFY(this->SharedInfo == in.SharedInfo);
468 return this->ptr - in.ptr;
472 operator[](ptrdiff_t n)
473 { return *(this + n); }
475 bool
476 operator<(const random_access_iterator_wrapper<T>& in) const
478 ITERATOR_VERIFY(this->SharedInfo == in.SharedInfo);
479 return this->ptr < in.ptr;
482 bool
483 operator>(const random_access_iterator_wrapper<T>& in) const
485 return in < *this;
488 bool
489 operator>=(const random_access_iterator_wrapper<T>& in) const
491 return !(*this < in);
494 bool
495 operator<=(const random_access_iterator_wrapper<T>& in) const
497 return !(*this > in);
502 /**
503 * @brief A container-type class for holding iterator wrappers
504 * test_container takes two parameters, a class T and an iterator
505 * wrapper templated by T (for example forward_iterator_wrapper<T>.
506 * It takes two pointers representing a range and presents them as
507 * a container of iterators.
509 template <class T, template<class T> class ItType>
510 struct test_container
512 typename ItType<T>::ContainerType bounds;
513 test_container(T* _first, T* _last):bounds(_first, _last)
516 ItType<T>
517 it(int pos)
519 ITERATOR_VERIFY(pos >= 0 && pos <= (bounds.last - bounds.first));
520 return ItType<T>(bounds.first + pos, &bounds);
523 ItType<T>
524 it(T* pos)
526 ITERATOR_VERIFY(pos >= bounds.first && pos <= bounds.last);
527 return ItType<T>(pos, &bounds);
530 ItType<T>
531 begin()
532 { return it(bounds.first); }
534 ItType<T>
535 end()
536 { return it(bounds.last); }
539 #endif