Fix order and types of members in C++17 insert_return_type structs
[official-gcc.git] / libstdc++-v3 / testsuite / util / testsuite_iterators.h
blob6771ae2cea64391621a945faaad9ce4f8504bb28
1 // -*- C++ -*-
2 // Iterator Wrappers for the C++ library testsuite.
3 //
4 // Copyright (C) 2004-2017 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
184 * @brief input_iterator wrapper for pointer
186 * This class takes a pointer and wraps it to provide exactly
187 * the requirements of a input_iterator. It should not be
188 * instantiated directly, but generated from a test_container
190 template<class T>
191 class input_iterator_wrapper
192 : public std::iterator<std::input_iterator_tag, T, std::ptrdiff_t, T*, T&>
194 protected:
195 input_iterator_wrapper()
198 public:
199 typedef BoundsContainer<T> ContainerType;
200 T* ptr;
201 ContainerType* SharedInfo;
203 input_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in)
204 : ptr(_ptr), SharedInfo(SharedInfo_in)
205 { ITERATOR_VERIFY(ptr >= SharedInfo->first && ptr <= SharedInfo->last); }
207 input_iterator_wrapper(const input_iterator_wrapper& in)
208 : ptr(in.ptr), SharedInfo(in.SharedInfo)
211 bool
212 operator==(const input_iterator_wrapper& in) const
214 ITERATOR_VERIFY(SharedInfo && SharedInfo == in.SharedInfo);
215 ITERATOR_VERIFY(ptr>=SharedInfo->first && in.ptr>=SharedInfo->first);
216 return ptr == in.ptr;
219 bool
220 operator!=(const input_iterator_wrapper& in) const
222 return !(*this == in);
226 operator*() const
228 ITERATOR_VERIFY(SharedInfo && ptr < SharedInfo->last);
229 ITERATOR_VERIFY(ptr >= SharedInfo->first);
230 return *ptr;
234 operator->() const
236 return &**this;
239 input_iterator_wrapper&
240 operator=(const input_iterator_wrapper& in)
242 ptr = in.ptr;
243 SharedInfo = in.SharedInfo;
244 return *this;
247 input_iterator_wrapper&
248 operator++()
250 ITERATOR_VERIFY(SharedInfo && ptr < SharedInfo->last);
251 ITERATOR_VERIFY(ptr>=SharedInfo->first);
252 ptr++;
253 SharedInfo->first=ptr;
254 return *this;
257 void
258 operator++(int)
260 ++*this;
263 #if __cplusplus >= 201103L
264 template<typename U>
265 void operator,(const U&) const = delete;
266 #else
267 private:
268 template<typename U>
269 void operator,(const U&) const;
270 #endif
275 * @brief forward_iterator wrapper for pointer
277 * This class takes a pointer and wraps it to provide exactly
278 * the requirements of a forward_iterator. It should not be
279 * instantiated directly, but generated from a test_container
281 template<class T>
282 struct forward_iterator_wrapper : public input_iterator_wrapper<T>
284 typedef BoundsContainer<T> ContainerType;
285 typedef std::forward_iterator_tag iterator_category;
286 forward_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in)
287 : input_iterator_wrapper<T>(_ptr, SharedInfo_in)
290 forward_iterator_wrapper(const forward_iterator_wrapper& in)
291 : input_iterator_wrapper<T>(in)
294 forward_iterator_wrapper()
296 this->ptr = 0;
297 this->SharedInfo = 0;
301 operator*() const
303 ITERATOR_VERIFY(this->SharedInfo && this->ptr < this->SharedInfo->last);
304 return *(this->ptr);
308 operator->() const
309 { return &**this; }
311 forward_iterator_wrapper&
312 operator++()
314 ITERATOR_VERIFY(this->SharedInfo && this->ptr < this->SharedInfo->last);
315 this->ptr++;
316 return *this;
319 forward_iterator_wrapper
320 operator++(int)
322 forward_iterator_wrapper<T> tmp = *this;
323 ++*this;
324 return tmp;
329 * @brief bidirectional_iterator wrapper for pointer
331 * This class takes a pointer and wraps it to provide exactly
332 * the requirements of a forward_iterator. It should not be
333 * instantiated directly, but generated from a test_container
335 template<class T>
336 struct bidirectional_iterator_wrapper : public forward_iterator_wrapper<T>
338 typedef BoundsContainer<T> ContainerType;
339 typedef std::bidirectional_iterator_tag iterator_category;
340 bidirectional_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in)
341 : forward_iterator_wrapper<T>(_ptr, SharedInfo_in)
344 bidirectional_iterator_wrapper(const bidirectional_iterator_wrapper& in)
345 : forward_iterator_wrapper<T>(in)
348 bidirectional_iterator_wrapper(): forward_iterator_wrapper<T>()
351 bidirectional_iterator_wrapper&
352 operator=(const bidirectional_iterator_wrapper& in)
354 this->ptr = in.ptr;
355 this->SharedInfo = in.SharedInfo;
356 return *this;
359 bidirectional_iterator_wrapper&
360 operator++()
362 ITERATOR_VERIFY(this->SharedInfo && this->ptr < this->SharedInfo->last);
363 this->ptr++;
364 return *this;
367 bidirectional_iterator_wrapper
368 operator++(int)
370 bidirectional_iterator_wrapper<T> tmp = *this;
371 ++*this;
372 return tmp;
375 bidirectional_iterator_wrapper&
376 operator--()
378 ITERATOR_VERIFY(this->SharedInfo && this->ptr > this->SharedInfo->first);
379 this->ptr--;
380 return *this;
383 bidirectional_iterator_wrapper
384 operator--(int)
386 bidirectional_iterator_wrapper<T> tmp = *this;
387 --*this;
388 return tmp;
393 * @brief random_access_iterator wrapper for pointer
395 * This class takes a pointer and wraps it to provide exactly
396 * the requirements of a forward_iterator. It should not be
397 * instantiated directly, but generated from a test_container
399 template<class T>
400 struct random_access_iterator_wrapper
401 : public bidirectional_iterator_wrapper<T>
403 typedef BoundsContainer<T> ContainerType;
404 typedef std::random_access_iterator_tag iterator_category;
405 random_access_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in)
406 : bidirectional_iterator_wrapper<T>(_ptr, SharedInfo_in)
409 random_access_iterator_wrapper(const random_access_iterator_wrapper<T>& in)
410 : bidirectional_iterator_wrapper<T>(in)
413 random_access_iterator_wrapper():bidirectional_iterator_wrapper<T>()
416 random_access_iterator_wrapper&
417 operator=(const random_access_iterator_wrapper& in)
419 this->ptr = in.ptr;
420 this->SharedInfo = in.SharedInfo;
421 return *this;
424 random_access_iterator_wrapper&
425 operator++()
427 ITERATOR_VERIFY(this->SharedInfo && this->ptr < this->SharedInfo->last);
428 this->ptr++;
429 return *this;
432 random_access_iterator_wrapper
433 operator++(int)
435 random_access_iterator_wrapper<T> tmp = *this;
436 ++*this;
437 return tmp;
440 random_access_iterator_wrapper&
441 operator--()
443 ITERATOR_VERIFY(this->SharedInfo && this->ptr > this->SharedInfo->first);
444 this->ptr--;
445 return *this;
448 random_access_iterator_wrapper
449 operator--(int)
451 random_access_iterator_wrapper<T> tmp = *this;
452 --*this;
453 return tmp;
456 random_access_iterator_wrapper&
457 operator+=(std::ptrdiff_t n)
459 if(n > 0)
461 ITERATOR_VERIFY(n <= this->SharedInfo->last - this->ptr);
462 this->ptr += n;
464 else
466 ITERATOR_VERIFY(n <= this->ptr - this->SharedInfo->first);
467 this->ptr += n;
469 return *this;
472 random_access_iterator_wrapper&
473 operator-=(std::ptrdiff_t n)
474 { return *this += -n; }
476 random_access_iterator_wrapper
477 operator-(std::ptrdiff_t n) const
479 random_access_iterator_wrapper<T> tmp = *this;
480 return tmp -= n;
483 std::ptrdiff_t
484 operator-(const random_access_iterator_wrapper<T>& in) const
486 ITERATOR_VERIFY(this->SharedInfo == in.SharedInfo);
487 return this->ptr - in.ptr;
491 operator[](std::ptrdiff_t n) const
492 { return *(*this + n); }
494 bool
495 operator<(const random_access_iterator_wrapper<T>& in) const
497 ITERATOR_VERIFY(this->SharedInfo == in.SharedInfo);
498 return this->ptr < in.ptr;
501 bool
502 operator>(const random_access_iterator_wrapper<T>& in) const
504 return in < *this;
507 bool
508 operator>=(const random_access_iterator_wrapper<T>& in) const
510 return !(*this < in);
513 bool
514 operator<=(const random_access_iterator_wrapper<T>& in) const
516 return !(*this > in);
520 template<typename T>
521 random_access_iterator_wrapper<T>
522 operator+(random_access_iterator_wrapper<T> it, std::ptrdiff_t n)
523 { return it += n; }
525 template<typename T>
526 random_access_iterator_wrapper<T>
527 operator+(std::ptrdiff_t n, random_access_iterator_wrapper<T> it)
528 { return it += n; }
532 * @brief A container-type class for holding iterator wrappers
533 * test_container takes two parameters, a class T and an iterator
534 * wrapper templated by T (for example forward_iterator_wrapper<T>.
535 * It takes two pointers representing a range and presents them as
536 * a container of iterators.
538 template <class T, template<class TT> class ItType>
539 struct test_container
541 typename ItType<T>::ContainerType bounds;
542 test_container(T* _first, T* _last):bounds(_first, _last)
545 #if __cplusplus >= 201103L
546 template<std::size_t N>
547 explicit
548 test_container(T (&arr)[N]) : test_container(arr, arr+N)
550 #endif
552 ItType<T>
553 it(int pos)
555 ITERATOR_VERIFY(pos >= 0 && pos <= (bounds.last - bounds.first));
556 return ItType<T>(bounds.first + pos, &bounds);
559 ItType<T>
560 it(T* pos)
562 ITERATOR_VERIFY(pos >= bounds.first && pos <= bounds.last);
563 return ItType<T>(pos, &bounds);
566 const T&
567 val(int pos)
568 { return (bounds.first)[pos]; }
570 ItType<T>
571 begin()
572 { return it(bounds.first); }
574 ItType<T>
575 end()
576 { return it(bounds.last); }
579 #endif