2018-03-08 Richard Biener <rguenther@suse.de>
[official-gcc.git] / libstdc++-v3 / testsuite / util / testsuite_iterators.h
blob74b6b6064f90819dd30bc3a7ba8fa900f422045c
1 // -*- C++ -*-
2 // Iterator Wrappers for the C++ library testsuite.
3 //
4 // Copyright (C) 2004-2018 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 3, 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 COPYING3. If not see
19 // <http://www.gnu.org/licenses/>.
22 // This file provides the following:
24 // input_iterator_wrapper, output_iterator_wrapper
25 // forward_iterator_wrapper, bidirectional_iterator_wrapper and
26 // random_access_wrapper, which attempt to exactly perform the requirements
27 // of these types of iterators. These are constructed from the class
28 // test_container, which is given two pointers to T and an iterator type.
30 #include <testsuite_hooks.h>
31 #include <bits/stl_iterator_base_types.h>
33 #if __cplusplus >= 201103L
34 #include <bits/move.h>
35 #endif
37 #ifndef _TESTSUITE_ITERATORS
38 #define _TESTSUITE_ITERATORS
40 #ifdef DISABLE_ITERATOR_DEBUG
41 #define ITERATOR_VERIFY(x)
42 #else
43 #define ITERATOR_VERIFY(x) VERIFY(x)
44 #endif
46 namespace __gnu_test
48 /**
49 * @brief Simple container for holding two pointers.
51 * Note that input_iterator_wrapper changes first to denote
52 * how the valid range of == , ++, etc. change as the iterators are used.
54 template<typename T>
55 struct BoundsContainer
57 T* first;
58 T* last;
59 BoundsContainer(T* _first, T* _last) : first(_first), last(_last)
60 { }
63 // Simple container for holding state of a set of output iterators.
64 template<typename T>
65 struct OutputContainer : public BoundsContainer<T>
67 T* incrementedto;
68 bool* writtento;
69 OutputContainer(T* _first, T* _last)
70 : BoundsContainer<T>(_first, _last), incrementedto(_first)
72 writtento = new bool[this->last - this->first];
73 for(int i = 0; i < this->last - this->first; i++)
74 writtento[i] = false;
77 ~OutputContainer()
78 { delete[] writtento; }
81 // Produced by output_iterator to allow limited writing to pointer
82 template<class T>
83 class WritableObject
85 T* ptr;
87 public:
88 OutputContainer<T>* SharedInfo;
89 WritableObject(T* ptr_in,OutputContainer<T>* SharedInfo_in):
90 ptr(ptr_in), SharedInfo(SharedInfo_in)
91 { }
93 #if __cplusplus >= 201103L
94 template<class U>
95 void
96 operator=(U&& new_val)
98 ITERATOR_VERIFY(SharedInfo->writtento[ptr - SharedInfo->first] == 0);
99 SharedInfo->writtento[ptr - SharedInfo->first] = 1;
100 *ptr = std::forward<U>(new_val);
102 #else
103 template<class U>
104 void
105 operator=(const U& new_val)
107 ITERATOR_VERIFY(SharedInfo->writtento[ptr - SharedInfo->first] == 0);
108 SharedInfo->writtento[ptr - SharedInfo->first] = 1;
109 *ptr = new_val;
111 #endif
115 * @brief output_iterator wrapper for pointer
117 * This class takes a pointer and wraps it to provide exactly
118 * the requirements of a output_iterator. It should not be
119 * instantiated directly, but generated from a test_container
121 template<class T>
122 struct output_iterator_wrapper
123 : public std::iterator<std::output_iterator_tag, T, std::ptrdiff_t, T*, T&>
125 typedef OutputContainer<T> ContainerType;
126 T* ptr;
127 ContainerType* SharedInfo;
129 output_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in)
130 : ptr(_ptr), SharedInfo(SharedInfo_in)
132 ITERATOR_VERIFY(ptr >= SharedInfo->first && ptr <= SharedInfo->last);
135 output_iterator_wrapper(const output_iterator_wrapper& in)
136 : ptr(in.ptr), SharedInfo(in.SharedInfo)
139 WritableObject<T>
140 operator*() const
142 ITERATOR_VERIFY(ptr < SharedInfo->last);
143 ITERATOR_VERIFY(SharedInfo->writtento[ptr - SharedInfo->first] == false);
144 return WritableObject<T>(ptr, SharedInfo);
147 output_iterator_wrapper&
148 operator=(const output_iterator_wrapper& in)
150 ptr = in.ptr;
151 SharedInfo = in.SharedInfo;
152 return *this;
155 output_iterator_wrapper&
156 operator++()
158 ITERATOR_VERIFY(SharedInfo && ptr < SharedInfo->last);
159 ITERATOR_VERIFY(ptr>=SharedInfo->incrementedto);
160 ptr++;
161 SharedInfo->incrementedto=ptr;
162 return *this;
165 output_iterator_wrapper
166 operator++(int)
168 output_iterator_wrapper<T> tmp = *this;
169 ++*this;
170 return tmp;
173 #if __cplusplus >= 201103L
174 template<typename U>
175 void operator,(const U&) const = delete;
176 #else
177 private:
178 template<typename U>
179 void operator,(const U&) const;
180 #endif
183 #if __cplusplus >= 201103L
184 template<typename T, typename U>
185 void operator,(const T&, const output_iterator_wrapper<U>&) = delete;
186 #endif
189 * @brief input_iterator wrapper for pointer
191 * This class takes a pointer and wraps it to provide exactly
192 * the requirements of a input_iterator. It should not be
193 * instantiated directly, but generated from a test_container
195 template<class T>
196 class input_iterator_wrapper
197 : public std::iterator<std::input_iterator_tag, T, std::ptrdiff_t, T*, T&>
199 protected:
200 input_iterator_wrapper()
203 public:
204 typedef BoundsContainer<T> ContainerType;
205 T* ptr;
206 ContainerType* SharedInfo;
208 input_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in)
209 : ptr(_ptr), SharedInfo(SharedInfo_in)
210 { ITERATOR_VERIFY(ptr >= SharedInfo->first && ptr <= SharedInfo->last); }
212 input_iterator_wrapper(const input_iterator_wrapper& in)
213 : ptr(in.ptr), SharedInfo(in.SharedInfo)
216 bool
217 operator==(const input_iterator_wrapper& in) const
219 ITERATOR_VERIFY(SharedInfo && SharedInfo == in.SharedInfo);
220 ITERATOR_VERIFY(ptr>=SharedInfo->first && in.ptr>=SharedInfo->first);
221 return ptr == in.ptr;
224 bool
225 operator!=(const input_iterator_wrapper& in) const
227 return !(*this == in);
231 operator*() const
233 ITERATOR_VERIFY(SharedInfo && ptr < SharedInfo->last);
234 ITERATOR_VERIFY(ptr >= SharedInfo->first);
235 return *ptr;
239 operator->() const
241 return &**this;
244 input_iterator_wrapper&
245 operator=(const input_iterator_wrapper& in)
247 ptr = in.ptr;
248 SharedInfo = in.SharedInfo;
249 return *this;
252 input_iterator_wrapper&
253 operator++()
255 ITERATOR_VERIFY(SharedInfo && ptr < SharedInfo->last);
256 ITERATOR_VERIFY(ptr>=SharedInfo->first);
257 ptr++;
258 SharedInfo->first=ptr;
259 return *this;
262 void
263 operator++(int)
265 ++*this;
268 #if __cplusplus >= 201103L
269 template<typename U>
270 void operator,(const U&) const = delete;
271 #else
272 private:
273 template<typename U>
274 void operator,(const U&) const;
275 #endif
278 #if __cplusplus >= 201103L
279 template<typename T, typename U>
280 void operator,(const T&, const input_iterator_wrapper<U>&) = delete;
281 #endif
284 * @brief forward_iterator wrapper for pointer
286 * This class takes a pointer and wraps it to provide exactly
287 * the requirements of a forward_iterator. It should not be
288 * instantiated directly, but generated from a test_container
290 template<class T>
291 struct forward_iterator_wrapper : public input_iterator_wrapper<T>
293 typedef BoundsContainer<T> ContainerType;
294 typedef std::forward_iterator_tag iterator_category;
295 forward_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in)
296 : input_iterator_wrapper<T>(_ptr, SharedInfo_in)
299 forward_iterator_wrapper(const forward_iterator_wrapper& in)
300 : input_iterator_wrapper<T>(in)
303 forward_iterator_wrapper()
305 this->ptr = 0;
306 this->SharedInfo = 0;
310 operator*() const
312 ITERATOR_VERIFY(this->SharedInfo && this->ptr < this->SharedInfo->last);
313 return *(this->ptr);
317 operator->() const
318 { return &**this; }
320 forward_iterator_wrapper&
321 operator++()
323 ITERATOR_VERIFY(this->SharedInfo && this->ptr < this->SharedInfo->last);
324 this->ptr++;
325 return *this;
328 forward_iterator_wrapper
329 operator++(int)
331 forward_iterator_wrapper<T> tmp = *this;
332 ++*this;
333 return tmp;
338 * @brief bidirectional_iterator wrapper for pointer
340 * This class takes a pointer and wraps it to provide exactly
341 * the requirements of a forward_iterator. It should not be
342 * instantiated directly, but generated from a test_container
344 template<class T>
345 struct bidirectional_iterator_wrapper : public forward_iterator_wrapper<T>
347 typedef BoundsContainer<T> ContainerType;
348 typedef std::bidirectional_iterator_tag iterator_category;
349 bidirectional_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in)
350 : forward_iterator_wrapper<T>(_ptr, SharedInfo_in)
353 bidirectional_iterator_wrapper(const bidirectional_iterator_wrapper& in)
354 : forward_iterator_wrapper<T>(in)
357 bidirectional_iterator_wrapper(): forward_iterator_wrapper<T>()
360 bidirectional_iterator_wrapper&
361 operator=(const bidirectional_iterator_wrapper& in)
363 this->ptr = in.ptr;
364 this->SharedInfo = in.SharedInfo;
365 return *this;
368 bidirectional_iterator_wrapper&
369 operator++()
371 ITERATOR_VERIFY(this->SharedInfo && this->ptr < this->SharedInfo->last);
372 this->ptr++;
373 return *this;
376 bidirectional_iterator_wrapper
377 operator++(int)
379 bidirectional_iterator_wrapper<T> tmp = *this;
380 ++*this;
381 return tmp;
384 bidirectional_iterator_wrapper&
385 operator--()
387 ITERATOR_VERIFY(this->SharedInfo && this->ptr > this->SharedInfo->first);
388 this->ptr--;
389 return *this;
392 bidirectional_iterator_wrapper
393 operator--(int)
395 bidirectional_iterator_wrapper<T> tmp = *this;
396 --*this;
397 return tmp;
402 * @brief random_access_iterator wrapper for pointer
404 * This class takes a pointer and wraps it to provide exactly
405 * the requirements of a forward_iterator. It should not be
406 * instantiated directly, but generated from a test_container
408 template<class T>
409 struct random_access_iterator_wrapper
410 : public bidirectional_iterator_wrapper<T>
412 typedef BoundsContainer<T> ContainerType;
413 typedef std::random_access_iterator_tag iterator_category;
414 random_access_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in)
415 : bidirectional_iterator_wrapper<T>(_ptr, SharedInfo_in)
418 random_access_iterator_wrapper(const random_access_iterator_wrapper<T>& in)
419 : bidirectional_iterator_wrapper<T>(in)
422 random_access_iterator_wrapper():bidirectional_iterator_wrapper<T>()
425 random_access_iterator_wrapper&
426 operator=(const random_access_iterator_wrapper& in)
428 this->ptr = in.ptr;
429 this->SharedInfo = in.SharedInfo;
430 return *this;
433 random_access_iterator_wrapper&
434 operator++()
436 ITERATOR_VERIFY(this->SharedInfo && this->ptr < this->SharedInfo->last);
437 this->ptr++;
438 return *this;
441 random_access_iterator_wrapper
442 operator++(int)
444 random_access_iterator_wrapper<T> tmp = *this;
445 ++*this;
446 return tmp;
449 random_access_iterator_wrapper&
450 operator--()
452 ITERATOR_VERIFY(this->SharedInfo && this->ptr > this->SharedInfo->first);
453 this->ptr--;
454 return *this;
457 random_access_iterator_wrapper
458 operator--(int)
460 random_access_iterator_wrapper<T> tmp = *this;
461 --*this;
462 return tmp;
465 random_access_iterator_wrapper&
466 operator+=(std::ptrdiff_t n)
468 if(n > 0)
470 ITERATOR_VERIFY(n <= this->SharedInfo->last - this->ptr);
471 this->ptr += n;
473 else
475 ITERATOR_VERIFY(n <= this->ptr - this->SharedInfo->first);
476 this->ptr += n;
478 return *this;
481 random_access_iterator_wrapper&
482 operator-=(std::ptrdiff_t n)
483 { return *this += -n; }
485 random_access_iterator_wrapper
486 operator-(std::ptrdiff_t n) const
488 random_access_iterator_wrapper<T> tmp = *this;
489 return tmp -= n;
492 std::ptrdiff_t
493 operator-(const random_access_iterator_wrapper<T>& in) const
495 ITERATOR_VERIFY(this->SharedInfo == in.SharedInfo);
496 return this->ptr - in.ptr;
500 operator[](std::ptrdiff_t n) const
501 { return *(*this + n); }
503 bool
504 operator<(const random_access_iterator_wrapper<T>& in) const
506 ITERATOR_VERIFY(this->SharedInfo == in.SharedInfo);
507 return this->ptr < in.ptr;
510 bool
511 operator>(const random_access_iterator_wrapper<T>& in) const
513 return in < *this;
516 bool
517 operator>=(const random_access_iterator_wrapper<T>& in) const
519 return !(*this < in);
522 bool
523 operator<=(const random_access_iterator_wrapper<T>& in) const
525 return !(*this > in);
529 template<typename T>
530 random_access_iterator_wrapper<T>
531 operator+(random_access_iterator_wrapper<T> it, std::ptrdiff_t n)
532 { return it += n; }
534 template<typename T>
535 random_access_iterator_wrapper<T>
536 operator+(std::ptrdiff_t n, random_access_iterator_wrapper<T> it)
537 { return it += n; }
541 * @brief A container-type class for holding iterator wrappers
542 * test_container takes two parameters, a class T and an iterator
543 * wrapper templated by T (for example forward_iterator_wrapper<T>.
544 * It takes two pointers representing a range and presents them as
545 * a container of iterators.
547 template <class T, template<class TT> class ItType>
548 struct test_container
550 typename ItType<T>::ContainerType bounds;
551 test_container(T* _first, T* _last) : bounds(_first, _last)
554 #if __cplusplus >= 201103L
555 template<std::size_t N>
556 explicit
557 test_container(T (&arr)[N]) : test_container(arr, arr+N)
559 #endif
561 ItType<T>
562 it(int pos)
564 ITERATOR_VERIFY(pos >= 0 && pos <= (bounds.last - bounds.first));
565 return ItType<T>(bounds.first + pos, &bounds);
568 ItType<T>
569 it(T* pos)
571 ITERATOR_VERIFY(pos >= bounds.first && pos <= bounds.last);
572 return ItType<T>(pos, &bounds);
575 const T&
576 val(int pos)
577 { return (bounds.first)[pos]; }
579 ItType<T>
580 begin()
581 { return it(bounds.first); }
583 ItType<T>
584 end()
585 { return it(bounds.last); }
588 #endif