]> gcc.gnu.org Git - gcc.git/blame - libstdc++-v3/testsuite/util/testsuite_iterators.h
libstdc++: Improve comment about testsuite utilities
[gcc.git] / libstdc++-v3 / testsuite / util / testsuite_iterators.h
CommitLineData
278d4cc4 1// -*- C++ -*-
f92ab29f 2// Iterator Wrappers for the C++ library testsuite.
278d4cc4 3//
8d9254fc 4// Copyright (C) 2004-2020 Free Software Foundation, Inc.
278d4cc4
CJ
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
748086b7 9// Free Software Foundation; either version 3, or (at your option)
278d4cc4
CJ
10// any later version.
11//
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.
16//
17// You should have received a copy of the GNU General Public License along
748086b7
JJ
18// with this library; see the file COPYING3. If not see
19// <http://www.gnu.org/licenses/>.
278d4cc4 20//
278d4cc4
CJ
21
22// This file provides the following:
23//
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.
29
30#include <testsuite_hooks.h>
acb8a4ef 31#include <bits/stl_iterator_base_types.h>
cb2168c9 32
734f5023 33#if __cplusplus >= 201103L
ca0f8fd1 34#include <bits/move.h>
cb2168c9 35#endif
278d4cc4
CJ
36
37#ifndef _TESTSUITE_ITERATORS
38#define _TESTSUITE_ITERATORS
39
40#ifdef DISABLE_ITERATOR_DEBUG
41#define ITERATOR_VERIFY(x)
42#else
43#define ITERATOR_VERIFY(x) VERIFY(x)
44#endif
45
46namespace __gnu_test
47{
48 /**
49 * @brief Simple container for holding two pointers.
50 *
51 * Note that input_iterator_wrapper changes first to denote
52 * how the valid range of == , ++, etc. change as the iterators are used.
53 */
54 template<typename T>
55 struct BoundsContainer
56 {
57 T* first;
58 T* last;
9921ac3d 59
65be6ddd 60 BoundsContainer(T* _first, T* _last) : first(_first), last(_last)
278d4cc4 61 { }
9921ac3d
JW
62
63 std::size_t size() const { return last - first; }
278d4cc4
CJ
64 };
65
66 // Simple container for holding state of a set of output iterators.
67 template<typename T>
68 struct OutputContainer : public BoundsContainer<T>
69 {
70 T* incrementedto;
71 bool* writtento;
9921ac3d 72
278d4cc4 73 OutputContainer(T* _first, T* _last)
9921ac3d
JW
74 : BoundsContainer<T>(_first, _last), incrementedto(_first),
75 writtento(new bool[this->size()]())
76 { }
278d4cc4
CJ
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;
9921ac3d
JW
90
91 WritableObject(T* ptr_in, OutputContainer<T>* SharedInfo_in):
278d4cc4
CJ
92 ptr(ptr_in), SharedInfo(SharedInfo_in)
93 { }
94
734f5023 95#if __cplusplus >= 201103L
561e7a36 96 template<class U>
9921ac3d 97 typename std::enable_if<std::is_assignable<T&, U>::value>::type
328b52d6 98 operator=(U&& new_val) const
278d4cc4
CJ
99 {
100 ITERATOR_VERIFY(SharedInfo->writtento[ptr - SharedInfo->first] == 0);
101 SharedInfo->writtento[ptr - SharedInfo->first] = 1;
01bbe151 102 *ptr = std::forward<U>(new_val);
278d4cc4 103 }
01bbe151 104#else
3c167a8b
PC
105 template<class U>
106 void
01bbe151 107 operator=(const U& new_val)
3c167a8b
PC
108 {
109 ITERATOR_VERIFY(SharedInfo->writtento[ptr - SharedInfo->first] == 0);
110 SharedInfo->writtento[ptr - SharedInfo->first] = 1;
01bbe151 111 *ptr = new_val;
3c167a8b
PC
112 }
113#endif
278d4cc4
CJ
114 };
115
116 /**
117 * @brief output_iterator wrapper for pointer
f92ab29f 118 *
278d4cc4
CJ
119 * This class takes a pointer and wraps it to provide exactly
120 * the requirements of a output_iterator. It should not be
f7fbb003 121 * instantiated directly, but generated from a test_container
278d4cc4
CJ
122 */
123 template<class T>
65be6ddd 124 struct output_iterator_wrapper
445877a9 125 : public std::iterator<std::output_iterator_tag, T, std::ptrdiff_t, T*, T&>
278d4cc4
CJ
126 {
127 typedef OutputContainer<T> ContainerType;
128 T* ptr;
129 ContainerType* SharedInfo;
130
131 output_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in)
65be6ddd 132 : ptr(_ptr), SharedInfo(SharedInfo_in)
278d4cc4
CJ
133 {
134 ITERATOR_VERIFY(ptr >= SharedInfo->first && ptr <= SharedInfo->last);
135 }
f92ab29f 136
0a70fb87
JW
137#if __cplusplus >= 201103L
138 output_iterator_wrapper() = delete;
139
140 output_iterator_wrapper(const output_iterator_wrapper&) = default;
141
142 output_iterator_wrapper&
143 operator=(const output_iterator_wrapper&) = default;
144#endif
278d4cc4
CJ
145
146 WritableObject<T>
147 operator*() const
148 {
149 ITERATOR_VERIFY(ptr < SharedInfo->last);
150 ITERATOR_VERIFY(SharedInfo->writtento[ptr - SharedInfo->first] == false);
151 return WritableObject<T>(ptr, SharedInfo);
152 }
f92ab29f 153
278d4cc4
CJ
154 output_iterator_wrapper&
155 operator++()
156 {
157 ITERATOR_VERIFY(SharedInfo && ptr < SharedInfo->last);
561e7a36 158 ITERATOR_VERIFY(ptr>=SharedInfo->incrementedto);
278d4cc4 159 ptr++;
561e7a36 160 SharedInfo->incrementedto=ptr;
278d4cc4
CJ
161 return *this;
162 }
163
164 output_iterator_wrapper
165 operator++(int)
166 {
167 output_iterator_wrapper<T> tmp = *this;
168 ++*this;
169 return tmp;
170 }
171
f970a17d
JW
172#if __cplusplus >= 201103L
173 template<typename U>
174 void operator,(const U&) const = delete;
175#else
176 private:
177 template<typename U>
178 void operator,(const U&) const;
179#endif
278d4cc4
CJ
180 };
181
d67be443
JW
182#if __cplusplus >= 201103L
183 template<typename T, typename U>
184 void operator,(const T&, const output_iterator_wrapper<U>&) = delete;
185#endif
186
5211593c 187#if __cplusplus >= 201103L
9921ac3d
JW
188 using std::remove_cv;
189#else
e112d53a
JW
190 template<typename T> struct remove_cv { typedef T type; };
191 template<typename T> struct remove_cv<const T> { typedef T type; };
192 template<typename T> struct remove_cv<volatile T> { typedef T type; };
193 template<typename T> struct remove_cv<const volatile T> { typedef T type; };
9921ac3d 194#endif
e112d53a 195
278d4cc4
CJ
196 /**
197 * @brief input_iterator wrapper for pointer
f92ab29f 198 *
278d4cc4
CJ
199 * This class takes a pointer and wraps it to provide exactly
200 * the requirements of a input_iterator. It should not be
f7fbb003 201 * instantiated directly, but generated from a test_container
278d4cc4
CJ
202 */
203 template<class T>
65be6ddd 204 class input_iterator_wrapper
e112d53a
JW
205 : public std::iterator<std::input_iterator_tag, typename remove_cv<T>::type,
206 std::ptrdiff_t, T*, T&>
278d4cc4
CJ
207 {
208 protected:
0a70fb87 209 input_iterator_wrapper() : ptr(0), SharedInfo(0)
278d4cc4
CJ
210 { }
211
212 public:
213 typedef BoundsContainer<T> ContainerType;
214 T* ptr;
215 ContainerType* SharedInfo;
216
217 input_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in)
65be6ddd 218 : ptr(_ptr), SharedInfo(SharedInfo_in)
278d4cc4 219 { ITERATOR_VERIFY(ptr >= SharedInfo->first && ptr <= SharedInfo->last); }
f92ab29f 220
0a70fb87
JW
221#if __cplusplus >= 201103L
222 input_iterator_wrapper(const input_iterator_wrapper&) = default;
223
224 input_iterator_wrapper&
225 operator=(const input_iterator_wrapper&) = default;
226#endif
278d4cc4
CJ
227
228 bool
229 operator==(const input_iterator_wrapper& in) const
230 {
8fc81078 231 ITERATOR_VERIFY(SharedInfo && SharedInfo == in.SharedInfo);
278d4cc4
CJ
232 ITERATOR_VERIFY(ptr>=SharedInfo->first && in.ptr>=SharedInfo->first);
233 return ptr == in.ptr;
234 }
235
236 bool
237 operator!=(const input_iterator_wrapper& in) const
238 {
239 return !(*this == in);
240 }
241
242 T&
243 operator*() const
244 {
245 ITERATOR_VERIFY(SharedInfo && ptr < SharedInfo->last);
246 ITERATOR_VERIFY(ptr >= SharedInfo->first);
247 return *ptr;
248 }
249
250 T*
251 operator->() const
252 {
253 return &**this;
254 }
255
278d4cc4
CJ
256 input_iterator_wrapper&
257 operator++()
258 {
259 ITERATOR_VERIFY(SharedInfo && ptr < SharedInfo->last);
260 ITERATOR_VERIFY(ptr>=SharedInfo->first);
261 ptr++;
262 SharedInfo->first=ptr;
263 return *this;
264 }
265
266 void
267 operator++(int)
268 {
269 ++*this;
270 }
f970a17d
JW
271
272#if __cplusplus >= 201103L
273 template<typename U>
274 void operator,(const U&) const = delete;
275#else
276 private:
277 template<typename U>
278 void operator,(const U&) const;
279#endif
278d4cc4
CJ
280 };
281
d67be443
JW
282#if __cplusplus >= 201103L
283 template<typename T, typename U>
284 void operator,(const T&, const input_iterator_wrapper<U>&) = delete;
285#endif
278d4cc4
CJ
286
287 /**
288 * @brief forward_iterator wrapper for pointer
f92ab29f 289 *
278d4cc4
CJ
290 * This class takes a pointer and wraps it to provide exactly
291 * the requirements of a forward_iterator. It should not be
f7fbb003 292 * instantiated directly, but generated from a test_container
278d4cc4
CJ
293 */
294 template<class T>
65be6ddd 295 struct forward_iterator_wrapper : public input_iterator_wrapper<T>
278d4cc4
CJ
296 {
297 typedef BoundsContainer<T> ContainerType;
298 typedef std::forward_iterator_tag iterator_category;
0a70fb87 299
278d4cc4 300 forward_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in)
65be6ddd 301 : input_iterator_wrapper<T>(_ptr, SharedInfo_in)
278d4cc4 302 { }
f92ab29f 303
0a70fb87 304 forward_iterator_wrapper()
278d4cc4
CJ
305 { }
306
0a70fb87
JW
307#if __cplusplus >= 201103L
308 forward_iterator_wrapper(const forward_iterator_wrapper&) = default;
309
310 forward_iterator_wrapper&
311 operator=(const forward_iterator_wrapper&) = default;
312#endif
278d4cc4
CJ
313
314 T&
315 operator*() const
316 {
317 ITERATOR_VERIFY(this->SharedInfo && this->ptr < this->SharedInfo->last);
318 return *(this->ptr);
319 }
320
321 T*
322 operator->() const
323 { return &**this; }
324
325 forward_iterator_wrapper&
326 operator++()
327 {
328 ITERATOR_VERIFY(this->SharedInfo && this->ptr < this->SharedInfo->last);
329 this->ptr++;
330 return *this;
331 }
332
333 forward_iterator_wrapper
334 operator++(int)
335 {
336 forward_iterator_wrapper<T> tmp = *this;
337 ++*this;
338 return tmp;
339 }
f970a17d 340 };
278d4cc4
CJ
341
342 /**
343 * @brief bidirectional_iterator wrapper for pointer
f92ab29f 344 *
278d4cc4 345 * This class takes a pointer and wraps it to provide exactly
ac2dca4d 346 * the requirements of a bidirectional_iterator. It should not be
f7fbb003 347 * instantiated directly, but generated from a test_container
278d4cc4
CJ
348 */
349 template<class T>
65be6ddd 350 struct bidirectional_iterator_wrapper : public forward_iterator_wrapper<T>
278d4cc4
CJ
351 {
352 typedef BoundsContainer<T> ContainerType;
353 typedef std::bidirectional_iterator_tag iterator_category;
0a70fb87 354
278d4cc4 355 bidirectional_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in)
65be6ddd 356 : forward_iterator_wrapper<T>(_ptr, SharedInfo_in)
278d4cc4
CJ
357 { }
358
0a70fb87
JW
359 bidirectional_iterator_wrapper()
360 : forward_iterator_wrapper<T>()
278d4cc4
CJ
361 { }
362
0a70fb87
JW
363#if __cplusplus >= 201103L
364 bidirectional_iterator_wrapper(
365 const bidirectional_iterator_wrapper&) = default;
278d4cc4
CJ
366
367 bidirectional_iterator_wrapper&
0a70fb87
JW
368 operator=(const bidirectional_iterator_wrapper&) = default;
369#endif
f92ab29f 370
278d4cc4
CJ
371 bidirectional_iterator_wrapper&
372 operator++()
373 {
374 ITERATOR_VERIFY(this->SharedInfo && this->ptr < this->SharedInfo->last);
375 this->ptr++;
376 return *this;
377 }
378
379 bidirectional_iterator_wrapper
380 operator++(int)
381 {
382 bidirectional_iterator_wrapper<T> tmp = *this;
383 ++*this;
384 return tmp;
385 }
386
f92ab29f 387 bidirectional_iterator_wrapper&
278d4cc4
CJ
388 operator--()
389 {
390 ITERATOR_VERIFY(this->SharedInfo && this->ptr > this->SharedInfo->first);
391 this->ptr--;
392 return *this;
393 }
394
395 bidirectional_iterator_wrapper
396 operator--(int)
f92ab29f 397 {
278d4cc4
CJ
398 bidirectional_iterator_wrapper<T> tmp = *this;
399 --*this;
400 return tmp;
401 }
f970a17d 402 };
278d4cc4
CJ
403
404 /**
405 * @brief random_access_iterator wrapper for pointer
f92ab29f 406 *
278d4cc4 407 * This class takes a pointer and wraps it to provide exactly
ac2dca4d 408 * the requirements of a random_access_iterator. It should not be
f7fbb003 409 * instantiated directly, but generated from a test_container
278d4cc4
CJ
410 */
411 template<class T>
f92ab29f 412 struct random_access_iterator_wrapper
65be6ddd 413 : public bidirectional_iterator_wrapper<T>
278d4cc4
CJ
414 {
415 typedef BoundsContainer<T> ContainerType;
416 typedef std::random_access_iterator_tag iterator_category;
0a70fb87 417
278d4cc4 418 random_access_iterator_wrapper(T* _ptr, ContainerType* SharedInfo_in)
65be6ddd 419 : bidirectional_iterator_wrapper<T>(_ptr, SharedInfo_in)
278d4cc4
CJ
420 { }
421
0a70fb87
JW
422 random_access_iterator_wrapper()
423 : bidirectional_iterator_wrapper<T>()
278d4cc4
CJ
424 { }
425
0a70fb87
JW
426#if __cplusplus >= 201103L
427 random_access_iterator_wrapper(
428 const random_access_iterator_wrapper&) = default;
278d4cc4
CJ
429
430 random_access_iterator_wrapper&
0a70fb87
JW
431 operator=(const random_access_iterator_wrapper&) = default;
432#endif
278d4cc4
CJ
433
434 random_access_iterator_wrapper&
435 operator++()
436 {
437 ITERATOR_VERIFY(this->SharedInfo && this->ptr < this->SharedInfo->last);
438 this->ptr++;
439 return *this;
440 }
441
442 random_access_iterator_wrapper
443 operator++(int)
444 {
445 random_access_iterator_wrapper<T> tmp = *this;
446 ++*this;
447 return tmp;
448 }
449
450 random_access_iterator_wrapper&
451 operator--()
452 {
453 ITERATOR_VERIFY(this->SharedInfo && this->ptr > this->SharedInfo->first);
454 this->ptr--;
455 return *this;
456 }
457
458 random_access_iterator_wrapper
459 operator--(int)
460 {
461 random_access_iterator_wrapper<T> tmp = *this;
561e7a36 462 --*this;
278d4cc4
CJ
463 return tmp;
464 }
465
466 random_access_iterator_wrapper&
445877a9 467 operator+=(std::ptrdiff_t n)
278d4cc4
CJ
468 {
469 if(n > 0)
470 {
471 ITERATOR_VERIFY(n <= this->SharedInfo->last - this->ptr);
472 this->ptr += n;
473 }
474 else
475 {
476 ITERATOR_VERIFY(n <= this->ptr - this->SharedInfo->first);
477 this->ptr += n;
478 }
479 return *this;
480 }
481
278d4cc4 482 random_access_iterator_wrapper&
445877a9 483 operator-=(std::ptrdiff_t n)
278d4cc4
CJ
484 { return *this += -n; }
485
486 random_access_iterator_wrapper
445877a9 487 operator-(std::ptrdiff_t n) const
278d4cc4
CJ
488 {
489 random_access_iterator_wrapper<T> tmp = *this;
490 return tmp -= n;
491 }
492
445877a9 493 std::ptrdiff_t
561e7a36 494 operator-(const random_access_iterator_wrapper<T>& in) const
278d4cc4
CJ
495 {
496 ITERATOR_VERIFY(this->SharedInfo == in.SharedInfo);
497 return this->ptr - in.ptr;
498 }
499
500 T&
445877a9 501 operator[](std::ptrdiff_t n) const
561e7a36 502 { return *(*this + n); }
278d4cc4
CJ
503
504 bool
505 operator<(const random_access_iterator_wrapper<T>& in) const
506 {
507 ITERATOR_VERIFY(this->SharedInfo == in.SharedInfo);
508 return this->ptr < in.ptr;
509 }
510
511 bool
512 operator>(const random_access_iterator_wrapper<T>& in) const
513 {
514 return in < *this;
515 }
516
517 bool
518 operator>=(const random_access_iterator_wrapper<T>& in) const
519 {
520 return !(*this < in);
521 }
522
f92ab29f 523 bool
278d4cc4
CJ
524 operator<=(const random_access_iterator_wrapper<T>& in) const
525 {
526 return !(*this > in);
527 }
f970a17d 528 };
278d4cc4 529
561e7a36
PC
530 template<typename T>
531 random_access_iterator_wrapper<T>
445877a9 532 operator+(random_access_iterator_wrapper<T> it, std::ptrdiff_t n)
561e7a36
PC
533 { return it += n; }
534
535 template<typename T>
536 random_access_iterator_wrapper<T>
f92ab29f 537 operator+(std::ptrdiff_t n, random_access_iterator_wrapper<T> it)
561e7a36
PC
538 { return it += n; }
539
278d4cc4 540
f92ab29f 541 /**
278d4cc4
CJ
542 * @brief A container-type class for holding iterator wrappers
543 * test_container takes two parameters, a class T and an iterator
544 * wrapper templated by T (for example forward_iterator_wrapper<T>.
f92ab29f 545 * It takes two pointers representing a range and presents them as
278d4cc4
CJ
546 * a container of iterators.
547 */
060269c4 548 template <class T, template<class TT> class ItType>
278d4cc4
CJ
549 struct test_container
550 {
551 typename ItType<T>::ContainerType bounds;
9921ac3d 552
4e66b02b 553 test_container(T* _first, T* _last) : bounds(_first, _last)
278d4cc4
CJ
554 { }
555
3ebacabd 556#if __cplusplus >= 201103L
4e66b02b
JW
557 template<std::size_t N>
558 explicit
559 test_container(T (&arr)[N]) : test_container(arr, arr+N)
560 { }
3ebacabd
JW
561#endif
562
278d4cc4
CJ
563 ItType<T>
564 it(int pos)
565 {
9921ac3d 566 ITERATOR_VERIFY(pos >= 0 && pos <= size());
278d4cc4
CJ
567 return ItType<T>(bounds.first + pos, &bounds);
568 }
569
570 ItType<T>
571 it(T* pos)
572 {
573 ITERATOR_VERIFY(pos >= bounds.first && pos <= bounds.last);
574 return ItType<T>(pos, &bounds);
575 }
576
c2240038
CJ
577 const T&
578 val(int pos)
579 { return (bounds.first)[pos]; }
580
278d4cc4
CJ
581 ItType<T>
582 begin()
583 { return it(bounds.first); }
584
585 ItType<T>
586 end()
587 { return it(bounds.last); }
ed920373
JW
588
589 std::size_t
590 size() const
9921ac3d 591 { return bounds.size(); }
4e66b02b 592 };
6d0dff49
JW
593
594#if __cplusplus > 201703L
595 template<typename T>
596 struct contiguous_iterator_wrapper
597 : random_access_iterator_wrapper<T>
598 {
599 using random_access_iterator_wrapper<T>::random_access_iterator_wrapper;
600
601 using iterator_concept = std::contiguous_iterator_tag;
602
603 contiguous_iterator_wrapper&
604 operator++()
605 {
606 random_access_iterator_wrapper<T>::operator++();
607 return *this;
608 }
609
610 contiguous_iterator_wrapper&
611 operator--()
612 {
613 random_access_iterator_wrapper<T>::operator--();
614 return *this;
615 }
616
617 contiguous_iterator_wrapper
618 operator++(int)
619 {
620 auto tmp = *this;
621 ++*this;
622 return tmp;
623 }
624
625 contiguous_iterator_wrapper
626 operator--(int)
627 {
628 auto tmp = *this;
629 --*this;
630 return tmp;
631 }
632
633 contiguous_iterator_wrapper&
634 operator+=(std::ptrdiff_t n)
635 {
636 random_access_iterator_wrapper<T>::operator+=(n);
637 return *this;
638 }
639
640 friend contiguous_iterator_wrapper
641 operator+(contiguous_iterator_wrapper iter, std::ptrdiff_t n)
642 { return iter += n; }
643
644 friend contiguous_iterator_wrapper
645 operator+(std::ptrdiff_t n, contiguous_iterator_wrapper iter)
646 { return iter += n; }
647
648 contiguous_iterator_wrapper&
649 operator-=(std::ptrdiff_t n)
650 { return *this += -n; }
651
652 friend contiguous_iterator_wrapper
653 operator-(contiguous_iterator_wrapper iter, std::ptrdiff_t n)
654 { return iter -= n; }
655 };
656
657 // A type meeting the minimum std::range requirements
658 template<typename T, template<typename> class Iter>
659 class test_range
660 {
661 // Adds default constructor to Iter<T> if needed
662 struct iterator : Iter<T>
663 {
664 using Iter<T>::Iter;
665
666 iterator() : Iter<T>(nullptr, nullptr) { }
667
668 using Iter<T>::operator++;
669
670 iterator& operator++() { Iter<T>::operator++(); return *this; }
671 };
672
673 template<typename I>
674 struct sentinel
675 {
676 T* end;
677
678 friend bool operator==(const sentinel& s, const I& i)
679 { return s.end == i.ptr; }
6d0dff49
JW
680 };
681
682 auto
683 get_iterator(T* p)
684 {
a31517cb 685 if constexpr (std::default_initializable<Iter<T>>)
6d0dff49
JW
686 return Iter<T>(p, &bounds);
687 else
688 return iterator(p, &bounds);
689 }
690
691 public:
692 test_range(T* first, T* last) : bounds(first, last)
693 { }
694
695 template<std::size_t N>
696 explicit
697 test_range(T (&arr)[N]) : test_range(arr, arr+N)
698 { }
699
700 auto begin() & { return get_iterator(bounds.first); }
701
702 auto end() &
703 {
704 using I = decltype(get_iterator(bounds.last));
705 if constexpr (std::sentinel_for<I, I>)
706 return get_iterator(bounds.last);
707 else
708 return sentinel<I>{bounds.last};
709 }
710
711 typename Iter<T>::ContainerType bounds;
712 };
713
328b52d6
JW
714 template<typename T>
715 using test_contiguous_range
716 = test_range<T, contiguous_iterator_wrapper>;
717 template<typename T>
718 using test_random_access_range
719 = test_range<T, random_access_iterator_wrapper>;
720 template<typename T>
721 using test_bidirectional_range
722 = test_range<T, bidirectional_iterator_wrapper>;
723 template<typename T>
724 using test_forward_range
725 = test_range<T, forward_iterator_wrapper>;
726 template<typename T>
727 using test_input_range
728 = test_range<T, input_iterator_wrapper>;
729 template<typename T>
730 using test_output_range
731 = test_range<T, output_iterator_wrapper>;
732
6d0dff49
JW
733 // A type meeting the minimum std::sized_range requirements
734 template<typename T, template<typename> class Iter>
735 struct test_sized_range : test_range<T, Iter>
736 {
737 using test_range<T, Iter>::test_range;
738
739 std::size_t size() const noexcept
740 { return this->bounds.size(); }
741 };
328b52d6
JW
742
743 template<typename T>
744 using test_contiguous_sized_range
745 = test_sized_range<T, contiguous_iterator_wrapper>;
746 template<typename T>
747 using test_random_access_sized_range
748 = test_sized_range<T, random_access_iterator_wrapper>;
749 template<typename T>
750 using test_bidirectional_sized_range
751 = test_sized_range<T, bidirectional_iterator_wrapper>;
752 template<typename T>
753 using test_forward_sized_range
754 = test_sized_range<T, forward_iterator_wrapper>;
755 template<typename T>
756 using test_input_sized_range
757 = test_sized_range<T, input_iterator_wrapper>;
758 template<typename T>
759 using test_output_sized_range
760 = test_sized_range<T, output_iterator_wrapper>;
b5b2e387 761
68be73fc
JW
762// test_range and test_sized_range do not own their elements, so they model
763// std::ranges::safe_range. This file does not define specializations of
764// std::ranges::enable_safe_range, so that individual tests can decide
765// whether or not to do so.
766// This is also true for test_container, although only when it has forward
767// iterators (because output_iterator_wrapper and input_iterator_wrapper are
768// not default constructible so do not model std::input_or_output_iterator).
6d0dff49
JW
769#endif // C++20
770} // namespace __gnu_test
771#endif // _TESTSUITE_ITERATORS
This page took 1.520335 seconds and 5 git commands to generate.