OSDN Git Service

Add NIOS2 support. Code from SourceyG++.
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / testsuite / util / testsuite_iterators.h
1 // -*- C++ -*-
2 // Iterator Wrappers for the C++ library testsuite. 
3 //
4 // Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009
5 // Free Software Foundation, Inc.
6 //
7 // This file is part of the GNU ISO C++ Library.  This library is free
8 // software; you can redistribute it and/or modify it under the
9 // terms of the GNU General Public License as published by the
10 // Free Software Foundation; either version 3, or (at your option)
11 // any later version.
12 //
13 // This library is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License along
19 // with this library; see the file COPYING3.  If not see
20 // <http://www.gnu.org/licenses/>.
21 //
22
23 // This file provides the following:
24 //
25 // input_iterator_wrapper, output_iterator_wrapper
26 // forward_iterator_wrapper, bidirectional_iterator_wrapper and
27 // random_access_wrapper, which attempt to exactly perform the requirements
28 // of these types of iterators. These are constructed from the class
29 // test_container, which is given two pointers to T and an iterator type.
30
31 #include <testsuite_hooks.h>
32 #include <bits/stl_iterator_base_types.h>
33 #include <bits/move.h>
34
35 #ifndef _TESTSUITE_ITERATORS
36 #define _TESTSUITE_ITERATORS
37
38 #ifdef DISABLE_ITERATOR_DEBUG
39 #define ITERATOR_VERIFY(x)
40 #else
41 #define ITERATOR_VERIFY(x) VERIFY(x)
42 #endif
43
44 namespace __gnu_test
45 {
46   /**
47    * @brief Simple container for holding two pointers.
48    *
49    * Note that input_iterator_wrapper changes first to denote
50    * how the valid range of == , ++, etc. change as the iterators are used.
51    */
52   template<typename T>
53     struct BoundsContainer
54     {
55       T* first;
56       T* last;
57       BoundsContainer(T* _first, T* _last) : first(_first), last(_last)
58       { }
59     };
60
61   // Simple container for holding state of a set of output iterators.
62   template<typename T>
63     struct OutputContainer : public BoundsContainer<T>
64     {
65       T* incrementedto;
66       bool* writtento;
67       OutputContainer(T* _first, T* _last)
68       : BoundsContainer<T>(_first, _last), incrementedto(_first)
69       {
70         writtento = new bool[this->last - this->first];
71         for(int i = 0; i < this->last - this->first; i++)
72           writtento[i] = false;
73       }
74
75       ~OutputContainer()
76       { delete[] writtento; }
77     };
78
79   // Produced by output_iterator to allow limited writing to pointer
80   template<class T>
81     class WritableObject
82     {
83       T* ptr;
84
85     public:
86       OutputContainer<T>* SharedInfo;
87       WritableObject(T* ptr_in,OutputContainer<T>* SharedInfo_in):
88         ptr(ptr_in), SharedInfo(SharedInfo_in)
89       { }
90
91 #ifdef __GXX_EXPERIMENTAL_CXX0X__
92       template<class U>
93       void
94       operator=(U&& new_val)
95       {
96         ITERATOR_VERIFY(SharedInfo->writtento[ptr - SharedInfo->first] == 0);
97         SharedInfo->writtento[ptr - SharedInfo->first] = 1;
98         *ptr = std::forward<U>(new_val);
99       }
100 #else
101       template<class U>
102       void
103       operator=(const U& new_val)
104       {
105         ITERATOR_VERIFY(SharedInfo->writtento[ptr - SharedInfo->first] == 0);
106         SharedInfo->writtento[ptr - SharedInfo->first] = 1;
107         *ptr = new_val;
108       }
109 #endif
110     };
111
112   /**
113    * @brief output_iterator wrapper for pointer
114    * 
115    * This class takes a pointer and wraps it to provide exactly
116    * the requirements of a output_iterator. It should not be
117    * instansiated directly, but generated from a test_container
118    */
119   template<class T>
120   struct output_iterator_wrapper
121   : public std::iterator<std::output_iterator_tag, T, ptrdiff_t, T*, T&>
122   {
123     typedef OutputContainer<T> ContainerType;
124     T* ptr;
125     ContainerType* SharedInfo;
126
127     output_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in)
128     : ptr(_ptr), SharedInfo(SharedInfo_in)
129     {
130       ITERATOR_VERIFY(ptr >= SharedInfo->first && ptr <= SharedInfo->last);
131     }
132     
133     output_iterator_wrapper(const output_iterator_wrapper& in)
134     : ptr(in.ptr), SharedInfo(in.SharedInfo)
135     { }
136
137     WritableObject<T>
138     operator*() const
139     {
140       ITERATOR_VERIFY(ptr < SharedInfo->last);
141       ITERATOR_VERIFY(SharedInfo->writtento[ptr - SharedInfo->first] == false);
142       return WritableObject<T>(ptr, SharedInfo);
143     }
144     
145     output_iterator_wrapper&
146     operator=(const output_iterator_wrapper& in) 
147     {
148       ptr = in.ptr;
149       SharedInfo = in.SharedInfo;
150       return *this;
151     }
152
153     output_iterator_wrapper&
154     operator++()
155     {
156       ITERATOR_VERIFY(SharedInfo && ptr < SharedInfo->last);
157       ITERATOR_VERIFY(ptr>=SharedInfo->incrementedto);
158       ptr++;
159       SharedInfo->incrementedto=ptr;
160       return *this;
161     }
162
163     output_iterator_wrapper
164     operator++(int)
165     {
166       output_iterator_wrapper<T> tmp = *this;
167       ++*this;
168       return tmp;
169     }
170
171   };
172
173   /**
174    * @brief input_iterator wrapper for pointer
175    * 
176    * This class takes a pointer and wraps it to provide exactly
177    * the requirements of a input_iterator. It should not be
178    * instansiated directly, but generated from a test_container
179    */
180   template<class T>
181   class input_iterator_wrapper
182   : public std::iterator<std::input_iterator_tag, T, ptrdiff_t, T*, T&>
183   {
184   protected:
185     input_iterator_wrapper()
186     { }
187
188   public:
189     typedef BoundsContainer<T> ContainerType;
190     T* ptr;
191     ContainerType* SharedInfo;
192
193     input_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in)
194     : ptr(_ptr), SharedInfo(SharedInfo_in)
195     { ITERATOR_VERIFY(ptr >= SharedInfo->first && ptr <= SharedInfo->last); }
196     
197     input_iterator_wrapper(const input_iterator_wrapper& in)
198     : ptr(in.ptr), SharedInfo(in.SharedInfo)
199     { }
200
201     bool
202     operator==(const input_iterator_wrapper& in) const
203     {
204       ITERATOR_VERIFY(SharedInfo != NULL && SharedInfo == in.SharedInfo);
205       ITERATOR_VERIFY(ptr>=SharedInfo->first && in.ptr>=SharedInfo->first);
206       return ptr == in.ptr;
207     }
208
209     bool
210     operator!=(const input_iterator_wrapper& in) const
211     {
212       return !(*this == in);
213     }
214
215     T&
216     operator*() const
217     {
218       ITERATOR_VERIFY(SharedInfo && ptr < SharedInfo->last);
219       ITERATOR_VERIFY(ptr >= SharedInfo->first);
220       return *ptr;
221     }
222
223     T*
224     operator->() const
225     {
226       return &**this;
227     }
228
229     input_iterator_wrapper&
230     operator=(const input_iterator_wrapper& in)
231     {
232       ptr = in.ptr;
233       SharedInfo = in.SharedInfo;
234       return *this;
235     }
236
237     input_iterator_wrapper&
238     operator++()
239     {
240       ITERATOR_VERIFY(SharedInfo && ptr < SharedInfo->last);
241       ITERATOR_VERIFY(ptr>=SharedInfo->first);
242       ptr++;
243       SharedInfo->first=ptr;
244       return *this;
245     }
246
247     void
248     operator++(int)
249     {
250       ++*this;
251     }
252   };
253
254
255   /**
256    * @brief forward_iterator wrapper for pointer
257    * 
258    * This class takes a pointer and wraps it to provide exactly
259    * the requirements of a forward_iterator. It should not be
260    * instansiated directly, but generated from a test_container
261    */
262   template<class T>
263   struct forward_iterator_wrapper : public input_iterator_wrapper<T>
264   {
265     typedef BoundsContainer<T> ContainerType;
266     typedef std::forward_iterator_tag iterator_category;
267     forward_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in)
268     : input_iterator_wrapper<T>(_ptr, SharedInfo_in)
269     { }
270     
271     forward_iterator_wrapper(const forward_iterator_wrapper& in)
272     : input_iterator_wrapper<T>(in)
273     { }
274
275     forward_iterator_wrapper()
276     {
277       this->ptr = NULL;
278       this->SharedInfo = NULL;
279     }
280
281     T&
282     operator*() const
283     {
284       ITERATOR_VERIFY(this->SharedInfo && this->ptr < this->SharedInfo->last);
285       return *(this->ptr);
286     }
287
288     T*
289     operator->() const
290     { return &**this; }
291
292     forward_iterator_wrapper&
293     operator++()
294     {
295       ITERATOR_VERIFY(this->SharedInfo && this->ptr < this->SharedInfo->last);
296       this->ptr++;
297       return *this;
298     }
299
300     forward_iterator_wrapper
301     operator++(int)
302     {
303       forward_iterator_wrapper<T> tmp = *this;
304       ++*this;
305       return tmp;
306     }
307    };
308
309   /**
310    * @brief bidirectional_iterator wrapper for pointer
311    * 
312    * This class takes a pointer and wraps it to provide exactly
313    * the requirements of a forward_iterator. It should not be
314    * instansiated directly, but generated from a test_container
315    */
316   template<class T>
317   struct bidirectional_iterator_wrapper : public forward_iterator_wrapper<T>
318   {
319     typedef BoundsContainer<T> ContainerType;
320     typedef std::bidirectional_iterator_tag iterator_category;
321     bidirectional_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in)
322     : forward_iterator_wrapper<T>(_ptr, SharedInfo_in)
323     { }
324
325     bidirectional_iterator_wrapper(const bidirectional_iterator_wrapper& in)
326     : forward_iterator_wrapper<T>(in)
327     { }
328
329     bidirectional_iterator_wrapper(): forward_iterator_wrapper<T>()
330     { }
331
332     bidirectional_iterator_wrapper&
333     operator=(const bidirectional_iterator_wrapper& in)
334     {
335       this->ptr = in.ptr;
336       this->SharedInfo = in.SharedInfo;
337       return *this;
338     }
339    
340     bidirectional_iterator_wrapper&
341     operator++()
342     {
343       ITERATOR_VERIFY(this->SharedInfo && this->ptr < this->SharedInfo->last);
344       this->ptr++;
345       return *this;
346     }
347
348     bidirectional_iterator_wrapper
349     operator++(int)
350     {
351       bidirectional_iterator_wrapper<T> tmp = *this;
352       ++*this;
353       return tmp;
354     }
355
356     bidirectional_iterator_wrapper& 
357     operator--()
358     {
359       ITERATOR_VERIFY(this->SharedInfo && this->ptr > this->SharedInfo->first);
360       this->ptr--;
361       return *this;
362     }
363
364     bidirectional_iterator_wrapper
365     operator--(int)
366     { 
367       bidirectional_iterator_wrapper<T> tmp = *this;
368       --*this;
369       return tmp;
370     }
371    };
372
373   /**
374    * @brief random_access_iterator wrapper for pointer
375    * 
376    * This class takes a pointer and wraps it to provide exactly
377    * the requirements of a forward_iterator. It should not be
378    * instansiated directly, but generated from a test_container
379    */
380   template<class T>
381   struct random_access_iterator_wrapper 
382   : public bidirectional_iterator_wrapper<T>
383   {
384     typedef BoundsContainer<T> ContainerType;
385     typedef std::random_access_iterator_tag iterator_category;
386     random_access_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in)
387     : bidirectional_iterator_wrapper<T>(_ptr, SharedInfo_in)
388     { }
389
390     random_access_iterator_wrapper(const random_access_iterator_wrapper<T>& in)
391     : bidirectional_iterator_wrapper<T>(in)
392     { }
393
394     random_access_iterator_wrapper():bidirectional_iterator_wrapper<T>()
395     { }
396
397     random_access_iterator_wrapper&
398     operator=(const random_access_iterator_wrapper& in)
399     {
400       this->ptr = in.ptr;
401       this->SharedInfo = in.SharedInfo;
402       return *this;
403     }
404
405     random_access_iterator_wrapper&
406     operator++()
407     {
408       ITERATOR_VERIFY(this->SharedInfo && this->ptr < this->SharedInfo->last);
409       this->ptr++;
410       return *this;
411     }
412
413     random_access_iterator_wrapper
414     operator++(int)
415     {
416       random_access_iterator_wrapper<T> tmp = *this;
417       ++*this;
418       return tmp;
419     }
420
421     random_access_iterator_wrapper&
422     operator--()
423     {
424       ITERATOR_VERIFY(this->SharedInfo && this->ptr > this->SharedInfo->first);
425       this->ptr--;
426       return *this;
427     }
428
429     random_access_iterator_wrapper
430     operator--(int)
431     {
432       random_access_iterator_wrapper<T> tmp = *this;
433       --*this;
434       return tmp;
435     }
436
437     random_access_iterator_wrapper&
438     operator+=(ptrdiff_t n)
439     {
440       if(n > 0)
441         {
442           ITERATOR_VERIFY(n <= this->SharedInfo->last - this->ptr);
443           this->ptr += n;
444         }
445       else
446         {
447           ITERATOR_VERIFY(n <= this->ptr - this->SharedInfo->first);
448           this->ptr += n;
449         }
450       return *this;
451     }
452
453     random_access_iterator_wrapper&
454     operator-=(ptrdiff_t n)
455     { return *this += -n; }
456
457     random_access_iterator_wrapper
458     operator-(ptrdiff_t n) const
459     {
460       random_access_iterator_wrapper<T> tmp = *this;
461       return tmp -= n;
462     }
463
464     ptrdiff_t
465     operator-(const random_access_iterator_wrapper<T>& in) const
466     {
467       ITERATOR_VERIFY(this->SharedInfo == in.SharedInfo);
468       return this->ptr - in.ptr;
469     }
470
471     T&
472     operator[](ptrdiff_t n) const
473     { return *(*this + n); }
474
475     bool
476     operator<(const random_access_iterator_wrapper<T>& in) const
477     {
478       ITERATOR_VERIFY(this->SharedInfo == in.SharedInfo);
479       return this->ptr < in.ptr;
480     }
481
482     bool
483     operator>(const random_access_iterator_wrapper<T>& in) const
484     {
485       return in < *this;
486     }
487
488     bool
489     operator>=(const random_access_iterator_wrapper<T>& in) const
490     {
491       return !(*this < in);
492     }
493
494     bool 
495     operator<=(const random_access_iterator_wrapper<T>& in) const
496     {
497       return !(*this > in);
498     }
499    };
500
501   template<typename T>
502     random_access_iterator_wrapper<T>
503     operator+(random_access_iterator_wrapper<T> it, ptrdiff_t n)
504     { return it += n; }
505
506   template<typename T>
507     random_access_iterator_wrapper<T>
508     operator+(ptrdiff_t n, random_access_iterator_wrapper<T> it) 
509     { return it += n; }
510
511
512   /** 
513    * @brief A container-type class for holding iterator wrappers
514    * test_container takes two parameters, a class T and an iterator
515    * wrapper templated by T (for example forward_iterator_wrapper<T>.
516    * It takes two pointers representing a range and presents them as 
517    * a container of iterators.
518    */
519   template <class T, template<class T> class ItType>
520   struct test_container
521   {
522     typename ItType<T>::ContainerType bounds;
523     test_container(T* _first, T* _last):bounds(_first, _last)
524     { }
525
526     ItType<T>
527     it(int pos)
528     {
529       ITERATOR_VERIFY(pos >= 0 && pos <= (bounds.last - bounds.first));
530       return ItType<T>(bounds.first + pos, &bounds);
531     }
532
533     ItType<T>
534     it(T* pos)
535     {
536       ITERATOR_VERIFY(pos >= bounds.first && pos <= bounds.last);
537       return ItType<T>(pos, &bounds);
538     }
539
540     ItType<T>
541     begin()
542     { return it(bounds.first); }
543
544     ItType<T>
545     end()
546     { return it(bounds.last); }
547    };
548 }
549 #endif