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