]> gcc.gnu.org Git - gcc.git/blob - libstdc++-v3/include/bits/stl_iterator.h
libstdc++: Use alias template for iterator_category [PR110970]
[gcc.git] / libstdc++-v3 / include / bits / stl_iterator.h
1 // Iterators -*- C++ -*-
2
3 // Copyright (C) 2001-2023 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
10
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
19
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 // <http://www.gnu.org/licenses/>.
24
25 /*
26 *
27 * Copyright (c) 1994
28 * Hewlett-Packard Company
29 *
30 * Permission to use, copy, modify, distribute and sell this software
31 * and its documentation for any purpose is hereby granted without fee,
32 * provided that the above copyright notice appear in all copies and
33 * that both that copyright notice and this permission notice appear
34 * in supporting documentation. Hewlett-Packard Company makes no
35 * representations about the suitability of this software for any
36 * purpose. It is provided "as is" without express or implied warranty.
37 *
38 *
39 * Copyright (c) 1996-1998
40 * Silicon Graphics Computer Systems, Inc.
41 *
42 * Permission to use, copy, modify, distribute and sell this software
43 * and its documentation for any purpose is hereby granted without fee,
44 * provided that the above copyright notice appear in all copies and
45 * that both that copyright notice and this permission notice appear
46 * in supporting documentation. Silicon Graphics makes no
47 * representations about the suitability of this software for any
48 * purpose. It is provided "as is" without express or implied warranty.
49 */
50
51 /** @file bits/stl_iterator.h
52 * This is an internal header file, included by other library headers.
53 * Do not attempt to use it directly. @headername{iterator}
54 *
55 * This file implements reverse_iterator, back_insert_iterator,
56 * front_insert_iterator, insert_iterator, __normal_iterator, and their
57 * supporting functions and overloaded operators.
58 */
59
60 #ifndef _STL_ITERATOR_H
61 #define _STL_ITERATOR_H 1
62
63 #include <bits/cpp_type_traits.h>
64 #include <bits/stl_iterator_base_types.h>
65 #include <ext/type_traits.h>
66 #include <bits/move.h>
67 #include <bits/ptr_traits.h>
68
69 #if __cplusplus >= 201103L
70 # include <type_traits>
71 #endif
72
73 #if __cplusplus > 201703L
74 # define __cpp_lib_array_constexpr 201811L
75 # define __cpp_lib_constexpr_iterator 201811L
76 #elif __cplusplus == 201703L
77 # define __cpp_lib_array_constexpr 201803L
78 #endif
79
80 #if __cplusplus >= 202002L
81 # include <compare>
82 # include <new>
83 # include <bits/exception_defines.h>
84 # include <bits/iterator_concepts.h>
85 # include <bits/stl_construct.h>
86 #endif
87
88 namespace std _GLIBCXX_VISIBILITY(default)
89 {
90 _GLIBCXX_BEGIN_NAMESPACE_VERSION
91
92 /**
93 * @addtogroup iterators
94 * @{
95 */
96
97 #if __cpp_lib_concepts
98 namespace __detail
99 {
100 // Weaken iterator_category _Cat to _Limit if it is derived from that,
101 // otherwise use _Otherwise.
102 template<typename _Cat, typename _Limit, typename _Otherwise = _Cat>
103 using __clamp_iter_cat
104 = __conditional_t<derived_from<_Cat, _Limit>, _Limit, _Otherwise>;
105
106 template<typename _Iter, typename _Limit>
107 using __clamped_iter_cat_t
108 = __clamp_iter_cat<__iter_category_t<_Iter>, _Limit>;
109
110 template<typename _Tp, typename _Up>
111 concept __different_from
112 = !same_as<remove_cvref_t<_Tp>, remove_cvref_t<_Up>>;
113 }
114 #endif
115
116 // Ignore warnings about std::iterator.
117 #pragma GCC diagnostic push
118 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
119
120 // 24.4.1 Reverse iterators
121 /**
122 * Bidirectional and random access iterators have corresponding reverse
123 * %iterator adaptors that iterate through the data structure in the
124 * opposite direction. They have the same signatures as the corresponding
125 * iterators. The fundamental relation between a reverse %iterator and its
126 * corresponding %iterator @c i is established by the identity:
127 * @code
128 * &*(reverse_iterator(i)) == &*(i - 1)
129 * @endcode
130 *
131 * <em>This mapping is dictated by the fact that while there is always a
132 * pointer past the end of an array, there might not be a valid pointer
133 * before the beginning of an array.</em> [24.4.1]/1,2
134 *
135 * Reverse iterators can be tricky and surprising at first. Their
136 * semantics make sense, however, and the trickiness is a side effect of
137 * the requirement that the iterators must be safe.
138 */
139 template<typename _Iterator>
140 class reverse_iterator
141 : public iterator<typename iterator_traits<_Iterator>::iterator_category,
142 typename iterator_traits<_Iterator>::value_type,
143 typename iterator_traits<_Iterator>::difference_type,
144 typename iterator_traits<_Iterator>::pointer,
145 typename iterator_traits<_Iterator>::reference>
146 {
147 template<typename _Iter>
148 friend class reverse_iterator;
149
150 #if __cpp_lib_concepts
151 // _GLIBCXX_RESOLVE_LIB_DEFECTS
152 // 3435. three_way_comparable_with<reverse_iterator<int*>, [...]>
153 template<typename _Iter>
154 static constexpr bool __convertible = !is_same_v<_Iter, _Iterator>
155 && convertible_to<const _Iter&, _Iterator>;
156 #endif
157
158 protected:
159 _Iterator current;
160
161 typedef iterator_traits<_Iterator> __traits_type;
162
163 public:
164 typedef _Iterator iterator_type;
165 typedef typename __traits_type::pointer pointer;
166 #if ! __cpp_lib_concepts
167 typedef typename __traits_type::difference_type difference_type;
168 typedef typename __traits_type::reference reference;
169 #else
170 using iterator_concept
171 = __conditional_t<random_access_iterator<_Iterator>,
172 random_access_iterator_tag,
173 bidirectional_iterator_tag>;
174 using iterator_category
175 = __detail::__clamped_iter_cat_t<_Iterator, random_access_iterator_tag>;
176 using value_type = iter_value_t<_Iterator>;
177 using difference_type = iter_difference_t<_Iterator>;
178 using reference = iter_reference_t<_Iterator>;
179 #endif
180
181 /**
182 * The default constructor value-initializes member @p current.
183 * If it is a pointer, that means it is zero-initialized.
184 */
185 // _GLIBCXX_RESOLVE_LIB_DEFECTS
186 // 235 No specification of default ctor for reverse_iterator
187 // 1012. reverse_iterator default ctor should value initialize
188 _GLIBCXX17_CONSTEXPR
189 reverse_iterator()
190 _GLIBCXX_NOEXCEPT_IF(noexcept(_Iterator()))
191 : current()
192 { }
193
194 /**
195 * This %iterator will move in the opposite direction that @p x does.
196 */
197 explicit _GLIBCXX17_CONSTEXPR
198 reverse_iterator(iterator_type __x)
199 _GLIBCXX_NOEXCEPT_IF(noexcept(_Iterator(__x)))
200 : current(__x)
201 { }
202
203 /**
204 * The copy constructor is normal.
205 */
206 _GLIBCXX17_CONSTEXPR
207 reverse_iterator(const reverse_iterator& __x)
208 _GLIBCXX_NOEXCEPT_IF(noexcept(_Iterator(__x.current)))
209 : current(__x.current)
210 { }
211
212 #if __cplusplus >= 201103L
213 reverse_iterator& operator=(const reverse_iterator&) = default;
214 #endif
215
216 /**
217 * A %reverse_iterator across other types can be copied if the
218 * underlying %iterator can be converted to the type of @c current.
219 */
220 template<typename _Iter>
221 #if __cpp_lib_concepts
222 requires __convertible<_Iter>
223 #endif
224 _GLIBCXX17_CONSTEXPR
225 reverse_iterator(const reverse_iterator<_Iter>& __x)
226 _GLIBCXX_NOEXCEPT_IF(noexcept(_Iterator(__x.current)))
227 : current(__x.current)
228 { }
229
230 #if __cplusplus >= 201103L
231 template<typename _Iter>
232 #if __cpp_lib_concepts
233 requires __convertible<_Iter>
234 && assignable_from<_Iterator&, const _Iter&>
235 #endif
236 _GLIBCXX17_CONSTEXPR
237 reverse_iterator&
238 operator=(const reverse_iterator<_Iter>& __x)
239 _GLIBCXX_NOEXCEPT_IF(noexcept(current = __x.current))
240 {
241 current = __x.current;
242 return *this;
243 }
244 #endif
245
246 /**
247 * @return @c current, the %iterator used for underlying work.
248 */
249 _GLIBCXX_NODISCARD
250 _GLIBCXX17_CONSTEXPR iterator_type
251 base() const
252 _GLIBCXX_NOEXCEPT_IF(noexcept(_Iterator(current)))
253 { return current; }
254
255 /**
256 * @return A reference to the value at @c --current
257 *
258 * This requires that @c --current is dereferenceable.
259 *
260 * @warning This implementation requires that for an iterator of the
261 * underlying iterator type, @c x, a reference obtained by
262 * @c *x remains valid after @c x has been modified or
263 * destroyed. This is a bug: http://gcc.gnu.org/PR51823
264 */
265 _GLIBCXX_NODISCARD
266 _GLIBCXX17_CONSTEXPR reference
267 operator*() const
268 {
269 _Iterator __tmp = current;
270 return *--__tmp;
271 }
272
273 /**
274 * @return A pointer to the value at @c --current
275 *
276 * This requires that @c --current is dereferenceable.
277 */
278 _GLIBCXX_NODISCARD
279 _GLIBCXX17_CONSTEXPR pointer
280 operator->() const
281 #if __cplusplus > 201703L && __cpp_concepts >= 201907L
282 requires is_pointer_v<_Iterator>
283 || requires(const _Iterator __i) { __i.operator->(); }
284 #endif
285 {
286 // _GLIBCXX_RESOLVE_LIB_DEFECTS
287 // 1052. operator-> should also support smart pointers
288 _Iterator __tmp = current;
289 --__tmp;
290 return _S_to_pointer(__tmp);
291 }
292
293 /**
294 * @return @c *this
295 *
296 * Decrements the underlying iterator.
297 */
298 _GLIBCXX17_CONSTEXPR reverse_iterator&
299 operator++()
300 {
301 --current;
302 return *this;
303 }
304
305 /**
306 * @return The original value of @c *this
307 *
308 * Decrements the underlying iterator.
309 */
310 _GLIBCXX17_CONSTEXPR reverse_iterator
311 operator++(int)
312 {
313 reverse_iterator __tmp = *this;
314 --current;
315 return __tmp;
316 }
317
318 /**
319 * @return @c *this
320 *
321 * Increments the underlying iterator.
322 */
323 _GLIBCXX17_CONSTEXPR reverse_iterator&
324 operator--()
325 {
326 ++current;
327 return *this;
328 }
329
330 /**
331 * @return A reverse_iterator with the previous value of @c *this
332 *
333 * Increments the underlying iterator.
334 */
335 _GLIBCXX17_CONSTEXPR reverse_iterator
336 operator--(int)
337 {
338 reverse_iterator __tmp = *this;
339 ++current;
340 return __tmp;
341 }
342
343 /**
344 * @return A reverse_iterator that refers to @c current - @a __n
345 *
346 * The underlying iterator must be a Random Access Iterator.
347 */
348 _GLIBCXX_NODISCARD
349 _GLIBCXX17_CONSTEXPR reverse_iterator
350 operator+(difference_type __n) const
351 { return reverse_iterator(current - __n); }
352
353 /**
354 * @return *this
355 *
356 * Moves the underlying iterator backwards @a __n steps.
357 * The underlying iterator must be a Random Access Iterator.
358 */
359 _GLIBCXX17_CONSTEXPR reverse_iterator&
360 operator+=(difference_type __n)
361 {
362 current -= __n;
363 return *this;
364 }
365
366 /**
367 * @return A reverse_iterator that refers to @c current - @a __n
368 *
369 * The underlying iterator must be a Random Access Iterator.
370 */
371 _GLIBCXX_NODISCARD
372 _GLIBCXX17_CONSTEXPR reverse_iterator
373 operator-(difference_type __n) const
374 { return reverse_iterator(current + __n); }
375
376 /**
377 * @return *this
378 *
379 * Moves the underlying iterator forwards @a __n steps.
380 * The underlying iterator must be a Random Access Iterator.
381 */
382 _GLIBCXX17_CONSTEXPR reverse_iterator&
383 operator-=(difference_type __n)
384 {
385 current += __n;
386 return *this;
387 }
388
389 /**
390 * @return The value at @c current - @a __n - 1
391 *
392 * The underlying iterator must be a Random Access Iterator.
393 */
394 _GLIBCXX_NODISCARD
395 _GLIBCXX17_CONSTEXPR reference
396 operator[](difference_type __n) const
397 { return *(*this + __n); }
398
399 #if __cplusplus > 201703L && __cpp_lib_concepts
400 [[nodiscard]]
401 friend constexpr iter_rvalue_reference_t<_Iterator>
402 iter_move(const reverse_iterator& __i)
403 noexcept(is_nothrow_copy_constructible_v<_Iterator>
404 && noexcept(ranges::iter_move(--std::declval<_Iterator&>())))
405 {
406 auto __tmp = __i.base();
407 return ranges::iter_move(--__tmp);
408 }
409
410 template<indirectly_swappable<_Iterator> _Iter2>
411 friend constexpr void
412 iter_swap(const reverse_iterator& __x,
413 const reverse_iterator<_Iter2>& __y)
414 noexcept(is_nothrow_copy_constructible_v<_Iterator>
415 && is_nothrow_copy_constructible_v<_Iter2>
416 && noexcept(ranges::iter_swap(--std::declval<_Iterator&>(),
417 --std::declval<_Iter2&>())))
418 {
419 auto __xtmp = __x.base();
420 auto __ytmp = __y.base();
421 ranges::iter_swap(--__xtmp, --__ytmp);
422 }
423 #endif
424
425 private:
426 template<typename _Tp>
427 static _GLIBCXX17_CONSTEXPR _Tp*
428 _S_to_pointer(_Tp* __p)
429 { return __p; }
430
431 template<typename _Tp>
432 static _GLIBCXX17_CONSTEXPR pointer
433 _S_to_pointer(_Tp __t)
434 { return __t.operator->(); }
435 };
436
437 ///@{
438 /**
439 * @param __x A %reverse_iterator.
440 * @param __y A %reverse_iterator.
441 * @return A simple bool.
442 *
443 * Reverse iterators forward comparisons to their underlying base()
444 * iterators.
445 *
446 */
447 #if __cplusplus <= 201703L || ! defined __cpp_lib_concepts
448 template<typename _Iterator>
449 _GLIBCXX_NODISCARD
450 inline _GLIBCXX17_CONSTEXPR bool
451 operator==(const reverse_iterator<_Iterator>& __x,
452 const reverse_iterator<_Iterator>& __y)
453 { return __x.base() == __y.base(); }
454
455 template<typename _Iterator>
456 _GLIBCXX_NODISCARD
457 inline _GLIBCXX17_CONSTEXPR bool
458 operator<(const reverse_iterator<_Iterator>& __x,
459 const reverse_iterator<_Iterator>& __y)
460 { return __y.base() < __x.base(); }
461
462 template<typename _Iterator>
463 _GLIBCXX_NODISCARD
464 inline _GLIBCXX17_CONSTEXPR bool
465 operator!=(const reverse_iterator<_Iterator>& __x,
466 const reverse_iterator<_Iterator>& __y)
467 { return !(__x == __y); }
468
469 template<typename _Iterator>
470 _GLIBCXX_NODISCARD
471 inline _GLIBCXX17_CONSTEXPR bool
472 operator>(const reverse_iterator<_Iterator>& __x,
473 const reverse_iterator<_Iterator>& __y)
474 { return __y < __x; }
475
476 template<typename _Iterator>
477 _GLIBCXX_NODISCARD
478 inline _GLIBCXX17_CONSTEXPR bool
479 operator<=(const reverse_iterator<_Iterator>& __x,
480 const reverse_iterator<_Iterator>& __y)
481 { return !(__y < __x); }
482
483 template<typename _Iterator>
484 _GLIBCXX_NODISCARD
485 inline _GLIBCXX17_CONSTEXPR bool
486 operator>=(const reverse_iterator<_Iterator>& __x,
487 const reverse_iterator<_Iterator>& __y)
488 { return !(__x < __y); }
489
490 // _GLIBCXX_RESOLVE_LIB_DEFECTS
491 // DR 280. Comparison of reverse_iterator to const reverse_iterator.
492
493 template<typename _IteratorL, typename _IteratorR>
494 _GLIBCXX_NODISCARD
495 inline _GLIBCXX17_CONSTEXPR bool
496 operator==(const reverse_iterator<_IteratorL>& __x,
497 const reverse_iterator<_IteratorR>& __y)
498 { return __x.base() == __y.base(); }
499
500 template<typename _IteratorL, typename _IteratorR>
501 _GLIBCXX_NODISCARD
502 inline _GLIBCXX17_CONSTEXPR bool
503 operator<(const reverse_iterator<_IteratorL>& __x,
504 const reverse_iterator<_IteratorR>& __y)
505 { return __x.base() > __y.base(); }
506
507 template<typename _IteratorL, typename _IteratorR>
508 _GLIBCXX_NODISCARD
509 inline _GLIBCXX17_CONSTEXPR bool
510 operator!=(const reverse_iterator<_IteratorL>& __x,
511 const reverse_iterator<_IteratorR>& __y)
512 { return __x.base() != __y.base(); }
513
514 template<typename _IteratorL, typename _IteratorR>
515 _GLIBCXX_NODISCARD
516 inline _GLIBCXX17_CONSTEXPR bool
517 operator>(const reverse_iterator<_IteratorL>& __x,
518 const reverse_iterator<_IteratorR>& __y)
519 { return __x.base() < __y.base(); }
520
521 template<typename _IteratorL, typename _IteratorR>
522 inline _GLIBCXX17_CONSTEXPR bool
523 operator<=(const reverse_iterator<_IteratorL>& __x,
524 const reverse_iterator<_IteratorR>& __y)
525 { return __x.base() >= __y.base(); }
526
527 template<typename _IteratorL, typename _IteratorR>
528 _GLIBCXX_NODISCARD
529 inline _GLIBCXX17_CONSTEXPR bool
530 operator>=(const reverse_iterator<_IteratorL>& __x,
531 const reverse_iterator<_IteratorR>& __y)
532 { return __x.base() <= __y.base(); }
533 #else // C++20
534 template<typename _IteratorL, typename _IteratorR>
535 [[nodiscard]]
536 constexpr bool
537 operator==(const reverse_iterator<_IteratorL>& __x,
538 const reverse_iterator<_IteratorR>& __y)
539 requires requires { { __x.base() == __y.base() } -> convertible_to<bool>; }
540 { return __x.base() == __y.base(); }
541
542 template<typename _IteratorL, typename _IteratorR>
543 [[nodiscard]]
544 constexpr bool
545 operator!=(const reverse_iterator<_IteratorL>& __x,
546 const reverse_iterator<_IteratorR>& __y)
547 requires requires { { __x.base() != __y.base() } -> convertible_to<bool>; }
548 { return __x.base() != __y.base(); }
549
550 template<typename _IteratorL, typename _IteratorR>
551 [[nodiscard]]
552 constexpr bool
553 operator<(const reverse_iterator<_IteratorL>& __x,
554 const reverse_iterator<_IteratorR>& __y)
555 requires requires { { __x.base() > __y.base() } -> convertible_to<bool>; }
556 { return __x.base() > __y.base(); }
557
558 template<typename _IteratorL, typename _IteratorR>
559 [[nodiscard]]
560 constexpr bool
561 operator>(const reverse_iterator<_IteratorL>& __x,
562 const reverse_iterator<_IteratorR>& __y)
563 requires requires { { __x.base() < __y.base() } -> convertible_to<bool>; }
564 { return __x.base() < __y.base(); }
565
566 template<typename _IteratorL, typename _IteratorR>
567 [[nodiscard]]
568 constexpr bool
569 operator<=(const reverse_iterator<_IteratorL>& __x,
570 const reverse_iterator<_IteratorR>& __y)
571 requires requires { { __x.base() >= __y.base() } -> convertible_to<bool>; }
572 { return __x.base() >= __y.base(); }
573
574 template<typename _IteratorL, typename _IteratorR>
575 [[nodiscard]]
576 constexpr bool
577 operator>=(const reverse_iterator<_IteratorL>& __x,
578 const reverse_iterator<_IteratorR>& __y)
579 requires requires { { __x.base() <= __y.base() } -> convertible_to<bool>; }
580 { return __x.base() <= __y.base(); }
581
582 template<typename _IteratorL,
583 three_way_comparable_with<_IteratorL> _IteratorR>
584 [[nodiscard]]
585 constexpr compare_three_way_result_t<_IteratorL, _IteratorR>
586 operator<=>(const reverse_iterator<_IteratorL>& __x,
587 const reverse_iterator<_IteratorR>& __y)
588 { return __y.base() <=> __x.base(); }
589
590 // Additional, non-standard overloads to avoid ambiguities with greedy,
591 // unconstrained overloads in associated namespaces.
592
593 template<typename _Iterator>
594 [[nodiscard]]
595 constexpr bool
596 operator==(const reverse_iterator<_Iterator>& __x,
597 const reverse_iterator<_Iterator>& __y)
598 requires requires { { __x.base() == __y.base() } -> convertible_to<bool>; }
599 { return __x.base() == __y.base(); }
600
601 template<three_way_comparable _Iterator>
602 [[nodiscard]]
603 constexpr compare_three_way_result_t<_Iterator, _Iterator>
604 operator<=>(const reverse_iterator<_Iterator>& __x,
605 const reverse_iterator<_Iterator>& __y)
606 { return __y.base() <=> __x.base(); }
607 #endif // C++20
608 ///@}
609
610 #if __cplusplus < 201103L
611 template<typename _Iterator>
612 inline typename reverse_iterator<_Iterator>::difference_type
613 operator-(const reverse_iterator<_Iterator>& __x,
614 const reverse_iterator<_Iterator>& __y)
615 { return __y.base() - __x.base(); }
616
617 template<typename _IteratorL, typename _IteratorR>
618 inline typename reverse_iterator<_IteratorL>::difference_type
619 operator-(const reverse_iterator<_IteratorL>& __x,
620 const reverse_iterator<_IteratorR>& __y)
621 { return __y.base() - __x.base(); }
622 #else
623 // _GLIBCXX_RESOLVE_LIB_DEFECTS
624 // DR 685. reverse_iterator/move_iterator difference has invalid signatures
625 template<typename _IteratorL, typename _IteratorR>
626 [[__nodiscard__]]
627 inline _GLIBCXX17_CONSTEXPR auto
628 operator-(const reverse_iterator<_IteratorL>& __x,
629 const reverse_iterator<_IteratorR>& __y)
630 -> decltype(__y.base() - __x.base())
631 { return __y.base() - __x.base(); }
632 #endif
633
634 template<typename _Iterator>
635 _GLIBCXX_NODISCARD
636 inline _GLIBCXX17_CONSTEXPR reverse_iterator<_Iterator>
637 operator+(typename reverse_iterator<_Iterator>::difference_type __n,
638 const reverse_iterator<_Iterator>& __x)
639 { return reverse_iterator<_Iterator>(__x.base() - __n); }
640
641 #if __cplusplus >= 201103L
642 // Same as C++14 make_reverse_iterator but used in C++11 mode too.
643 template<typename _Iterator>
644 inline _GLIBCXX17_CONSTEXPR reverse_iterator<_Iterator>
645 __make_reverse_iterator(_Iterator __i)
646 { return reverse_iterator<_Iterator>(__i); }
647
648 # if __cplusplus >= 201402L
649 # define __cpp_lib_make_reverse_iterator 201402L
650
651 // _GLIBCXX_RESOLVE_LIB_DEFECTS
652 // DR 2285. make_reverse_iterator
653 /// Generator function for reverse_iterator.
654 template<typename _Iterator>
655 [[__nodiscard__]]
656 inline _GLIBCXX17_CONSTEXPR reverse_iterator<_Iterator>
657 make_reverse_iterator(_Iterator __i)
658 { return reverse_iterator<_Iterator>(__i); }
659
660 # if __cplusplus > 201703L && defined __cpp_lib_concepts
661 template<typename _Iterator1, typename _Iterator2>
662 requires (!sized_sentinel_for<_Iterator1, _Iterator2>)
663 inline constexpr bool
664 disable_sized_sentinel_for<reverse_iterator<_Iterator1>,
665 reverse_iterator<_Iterator2>> = true;
666 # endif // C++20
667 # endif // C++14
668
669 template<typename _Iterator>
670 _GLIBCXX20_CONSTEXPR
671 auto
672 __niter_base(reverse_iterator<_Iterator> __it)
673 -> decltype(__make_reverse_iterator(__niter_base(__it.base())))
674 { return __make_reverse_iterator(__niter_base(__it.base())); }
675
676 template<typename _Iterator>
677 struct __is_move_iterator<reverse_iterator<_Iterator> >
678 : __is_move_iterator<_Iterator>
679 { };
680
681 template<typename _Iterator>
682 _GLIBCXX20_CONSTEXPR
683 auto
684 __miter_base(reverse_iterator<_Iterator> __it)
685 -> decltype(__make_reverse_iterator(__miter_base(__it.base())))
686 { return __make_reverse_iterator(__miter_base(__it.base())); }
687 #endif // C++11
688
689 // 24.4.2.2.1 back_insert_iterator
690 /**
691 * @brief Turns assignment into insertion.
692 *
693 * These are output iterators, constructed from a container-of-T.
694 * Assigning a T to the iterator appends it to the container using
695 * push_back.
696 *
697 * Tip: Using the back_inserter function to create these iterators can
698 * save typing.
699 */
700 template<typename _Container>
701 class back_insert_iterator
702 : public iterator<output_iterator_tag, void, void, void, void>
703 {
704 protected:
705 _Container* container;
706
707 public:
708 /// A nested typedef for the type of whatever container you used.
709 typedef _Container container_type;
710 #if __cplusplus > 201703L
711 using difference_type = ptrdiff_t;
712 #endif
713
714 /// The only way to create this %iterator is with a container.
715 explicit _GLIBCXX20_CONSTEXPR
716 back_insert_iterator(_Container& __x)
717 : container(std::__addressof(__x)) { }
718
719 /**
720 * @param __value An instance of whatever type
721 * container_type::const_reference is; presumably a
722 * reference-to-const T for container<T>.
723 * @return This %iterator, for chained operations.
724 *
725 * This kind of %iterator doesn't really have a @a position in the
726 * container (you can think of the position as being permanently at
727 * the end, if you like). Assigning a value to the %iterator will
728 * always append the value to the end of the container.
729 */
730 #if __cplusplus < 201103L
731 back_insert_iterator&
732 operator=(typename _Container::const_reference __value)
733 {
734 container->push_back(__value);
735 return *this;
736 }
737 #else
738 _GLIBCXX20_CONSTEXPR
739 back_insert_iterator&
740 operator=(const typename _Container::value_type& __value)
741 {
742 container->push_back(__value);
743 return *this;
744 }
745
746 _GLIBCXX20_CONSTEXPR
747 back_insert_iterator&
748 operator=(typename _Container::value_type&& __value)
749 {
750 container->push_back(std::move(__value));
751 return *this;
752 }
753 #endif
754
755 /// Simply returns *this.
756 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
757 back_insert_iterator&
758 operator*()
759 { return *this; }
760
761 /// Simply returns *this. (This %iterator does not @a move.)
762 _GLIBCXX20_CONSTEXPR
763 back_insert_iterator&
764 operator++()
765 { return *this; }
766
767 /// Simply returns *this. (This %iterator does not @a move.)
768 _GLIBCXX20_CONSTEXPR
769 back_insert_iterator
770 operator++(int)
771 { return *this; }
772 };
773
774 /**
775 * @param __x A container of arbitrary type.
776 * @return An instance of back_insert_iterator working on @p __x.
777 *
778 * This wrapper function helps in creating back_insert_iterator instances.
779 * Typing the name of the %iterator requires knowing the precise full
780 * type of the container, which can be tedious and impedes generic
781 * programming. Using this function lets you take advantage of automatic
782 * template parameter deduction, making the compiler match the correct
783 * types for you.
784 */
785 template<typename _Container>
786 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
787 inline back_insert_iterator<_Container>
788 back_inserter(_Container& __x)
789 { return back_insert_iterator<_Container>(__x); }
790
791 /**
792 * @brief Turns assignment into insertion.
793 *
794 * These are output iterators, constructed from a container-of-T.
795 * Assigning a T to the iterator prepends it to the container using
796 * push_front.
797 *
798 * Tip: Using the front_inserter function to create these iterators can
799 * save typing.
800 */
801 template<typename _Container>
802 class front_insert_iterator
803 : public iterator<output_iterator_tag, void, void, void, void>
804 {
805 protected:
806 _Container* container;
807
808 public:
809 /// A nested typedef for the type of whatever container you used.
810 typedef _Container container_type;
811 #if __cplusplus > 201703L
812 using difference_type = ptrdiff_t;
813 #endif
814
815 /// The only way to create this %iterator is with a container.
816 explicit _GLIBCXX20_CONSTEXPR
817 front_insert_iterator(_Container& __x)
818 : container(std::__addressof(__x)) { }
819
820 /**
821 * @param __value An instance of whatever type
822 * container_type::const_reference is; presumably a
823 * reference-to-const T for container<T>.
824 * @return This %iterator, for chained operations.
825 *
826 * This kind of %iterator doesn't really have a @a position in the
827 * container (you can think of the position as being permanently at
828 * the front, if you like). Assigning a value to the %iterator will
829 * always prepend the value to the front of the container.
830 */
831 #if __cplusplus < 201103L
832 front_insert_iterator&
833 operator=(typename _Container::const_reference __value)
834 {
835 container->push_front(__value);
836 return *this;
837 }
838 #else
839 _GLIBCXX20_CONSTEXPR
840 front_insert_iterator&
841 operator=(const typename _Container::value_type& __value)
842 {
843 container->push_front(__value);
844 return *this;
845 }
846
847 _GLIBCXX20_CONSTEXPR
848 front_insert_iterator&
849 operator=(typename _Container::value_type&& __value)
850 {
851 container->push_front(std::move(__value));
852 return *this;
853 }
854 #endif
855
856 /// Simply returns *this.
857 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
858 front_insert_iterator&
859 operator*()
860 { return *this; }
861
862 /// Simply returns *this. (This %iterator does not @a move.)
863 _GLIBCXX20_CONSTEXPR
864 front_insert_iterator&
865 operator++()
866 { return *this; }
867
868 /// Simply returns *this. (This %iterator does not @a move.)
869 _GLIBCXX20_CONSTEXPR
870 front_insert_iterator
871 operator++(int)
872 { return *this; }
873 };
874
875 /**
876 * @param __x A container of arbitrary type.
877 * @return An instance of front_insert_iterator working on @p x.
878 *
879 * This wrapper function helps in creating front_insert_iterator instances.
880 * Typing the name of the %iterator requires knowing the precise full
881 * type of the container, which can be tedious and impedes generic
882 * programming. Using this function lets you take advantage of automatic
883 * template parameter deduction, making the compiler match the correct
884 * types for you.
885 */
886 template<typename _Container>
887 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
888 inline front_insert_iterator<_Container>
889 front_inserter(_Container& __x)
890 { return front_insert_iterator<_Container>(__x); }
891
892 /**
893 * @brief Turns assignment into insertion.
894 *
895 * These are output iterators, constructed from a container-of-T.
896 * Assigning a T to the iterator inserts it in the container at the
897 * %iterator's position, rather than overwriting the value at that
898 * position.
899 *
900 * (Sequences will actually insert a @e copy of the value before the
901 * %iterator's position.)
902 *
903 * Tip: Using the inserter function to create these iterators can
904 * save typing.
905 */
906 template<typename _Container>
907 class insert_iterator
908 : public iterator<output_iterator_tag, void, void, void, void>
909 {
910 #if __cplusplus > 201703L && defined __cpp_lib_concepts
911 using _Iter = std::__detail::__range_iter_t<_Container>;
912 #else
913 typedef typename _Container::iterator _Iter;
914 #endif
915 protected:
916 _Container* container;
917 _Iter iter;
918
919 public:
920 /// A nested typedef for the type of whatever container you used.
921 typedef _Container container_type;
922
923 #if __cplusplus > 201703L && defined __cpp_lib_concepts
924 using difference_type = ptrdiff_t;
925 #endif
926
927 /**
928 * The only way to create this %iterator is with a container and an
929 * initial position (a normal %iterator into the container).
930 */
931 _GLIBCXX20_CONSTEXPR
932 insert_iterator(_Container& __x, _Iter __i)
933 : container(std::__addressof(__x)), iter(__i) {}
934
935 /**
936 * @param __value An instance of whatever type
937 * container_type::const_reference is; presumably a
938 * reference-to-const T for container<T>.
939 * @return This %iterator, for chained operations.
940 *
941 * This kind of %iterator maintains its own position in the
942 * container. Assigning a value to the %iterator will insert the
943 * value into the container at the place before the %iterator.
944 *
945 * The position is maintained such that subsequent assignments will
946 * insert values immediately after one another. For example,
947 * @code
948 * // vector v contains A and Z
949 *
950 * insert_iterator i (v, ++v.begin());
951 * i = 1;
952 * i = 2;
953 * i = 3;
954 *
955 * // vector v contains A, 1, 2, 3, and Z
956 * @endcode
957 */
958 #if __cplusplus < 201103L
959 insert_iterator&
960 operator=(typename _Container::const_reference __value)
961 {
962 iter = container->insert(iter, __value);
963 ++iter;
964 return *this;
965 }
966 #else
967 _GLIBCXX20_CONSTEXPR
968 insert_iterator&
969 operator=(const typename _Container::value_type& __value)
970 {
971 iter = container->insert(iter, __value);
972 ++iter;
973 return *this;
974 }
975
976 _GLIBCXX20_CONSTEXPR
977 insert_iterator&
978 operator=(typename _Container::value_type&& __value)
979 {
980 iter = container->insert(iter, std::move(__value));
981 ++iter;
982 return *this;
983 }
984 #endif
985
986 /// Simply returns *this.
987 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
988 insert_iterator&
989 operator*()
990 { return *this; }
991
992 /// Simply returns *this. (This %iterator does not @a move.)
993 _GLIBCXX20_CONSTEXPR
994 insert_iterator&
995 operator++()
996 { return *this; }
997
998 /// Simply returns *this. (This %iterator does not @a move.)
999 _GLIBCXX20_CONSTEXPR
1000 insert_iterator&
1001 operator++(int)
1002 { return *this; }
1003 };
1004
1005 #pragma GCC diagnostic pop
1006
1007 /**
1008 * @param __x A container of arbitrary type.
1009 * @param __i An iterator into the container.
1010 * @return An instance of insert_iterator working on @p __x.
1011 *
1012 * This wrapper function helps in creating insert_iterator instances.
1013 * Typing the name of the %iterator requires knowing the precise full
1014 * type of the container, which can be tedious and impedes generic
1015 * programming. Using this function lets you take advantage of automatic
1016 * template parameter deduction, making the compiler match the correct
1017 * types for you.
1018 */
1019 #if __cplusplus > 201703L && defined __cpp_lib_concepts
1020 template<typename _Container>
1021 [[nodiscard]]
1022 constexpr insert_iterator<_Container>
1023 inserter(_Container& __x, std::__detail::__range_iter_t<_Container> __i)
1024 { return insert_iterator<_Container>(__x, __i); }
1025 #else
1026 template<typename _Container>
1027 _GLIBCXX_NODISCARD
1028 inline insert_iterator<_Container>
1029 inserter(_Container& __x, typename _Container::iterator __i)
1030 { return insert_iterator<_Container>(__x, __i); }
1031 #endif
1032
1033 /// @} group iterators
1034
1035 _GLIBCXX_END_NAMESPACE_VERSION
1036 } // namespace
1037
1038 namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
1039 {
1040 _GLIBCXX_BEGIN_NAMESPACE_VERSION
1041
1042 // This iterator adapter is @a normal in the sense that it does not
1043 // change the semantics of any of the operators of its iterator
1044 // parameter. Its primary purpose is to convert an iterator that is
1045 // not a class, e.g. a pointer, into an iterator that is a class.
1046 // The _Container parameter exists solely so that different containers
1047 // using this template can instantiate different types, even if the
1048 // _Iterator parameter is the same.
1049 template<typename _Iterator, typename _Container>
1050 class __normal_iterator
1051 {
1052 protected:
1053 _Iterator _M_current;
1054
1055 typedef std::iterator_traits<_Iterator> __traits_type;
1056
1057 #if __cplusplus >= 201103L
1058 template<typename _Iter>
1059 using __convertible_from
1060 = std::__enable_if_t<std::is_convertible<_Iter, _Iterator>::value>;
1061 #endif
1062
1063 public:
1064 typedef _Iterator iterator_type;
1065 typedef typename __traits_type::iterator_category iterator_category;
1066 typedef typename __traits_type::value_type value_type;
1067 typedef typename __traits_type::difference_type difference_type;
1068 typedef typename __traits_type::reference reference;
1069 typedef typename __traits_type::pointer pointer;
1070
1071 #if __cplusplus > 201703L && __cpp_lib_concepts
1072 using iterator_concept = std::__detail::__iter_concept<_Iterator>;
1073 #endif
1074
1075 _GLIBCXX_CONSTEXPR __normal_iterator() _GLIBCXX_NOEXCEPT
1076 : _M_current(_Iterator()) { }
1077
1078 explicit _GLIBCXX20_CONSTEXPR
1079 __normal_iterator(const _Iterator& __i) _GLIBCXX_NOEXCEPT
1080 : _M_current(__i) { }
1081
1082 // Allow iterator to const_iterator conversion
1083 #if __cplusplus >= 201103L
1084 template<typename _Iter, typename = __convertible_from<_Iter>>
1085 _GLIBCXX20_CONSTEXPR
1086 __normal_iterator(const __normal_iterator<_Iter, _Container>& __i)
1087 noexcept
1088 #else
1089 // N.B. _Container::pointer is not actually in container requirements,
1090 // but is present in std::vector and std::basic_string.
1091 template<typename _Iter>
1092 __normal_iterator(const __normal_iterator<_Iter,
1093 typename __enable_if<
1094 (std::__are_same<_Iter, typename _Container::pointer>::__value),
1095 _Container>::__type>& __i)
1096 #endif
1097 : _M_current(__i.base()) { }
1098
1099 // Forward iterator requirements
1100 _GLIBCXX20_CONSTEXPR
1101 reference
1102 operator*() const _GLIBCXX_NOEXCEPT
1103 { return *_M_current; }
1104
1105 _GLIBCXX20_CONSTEXPR
1106 pointer
1107 operator->() const _GLIBCXX_NOEXCEPT
1108 { return _M_current; }
1109
1110 _GLIBCXX20_CONSTEXPR
1111 __normal_iterator&
1112 operator++() _GLIBCXX_NOEXCEPT
1113 {
1114 ++_M_current;
1115 return *this;
1116 }
1117
1118 _GLIBCXX20_CONSTEXPR
1119 __normal_iterator
1120 operator++(int) _GLIBCXX_NOEXCEPT
1121 { return __normal_iterator(_M_current++); }
1122
1123 // Bidirectional iterator requirements
1124 _GLIBCXX20_CONSTEXPR
1125 __normal_iterator&
1126 operator--() _GLIBCXX_NOEXCEPT
1127 {
1128 --_M_current;
1129 return *this;
1130 }
1131
1132 _GLIBCXX20_CONSTEXPR
1133 __normal_iterator
1134 operator--(int) _GLIBCXX_NOEXCEPT
1135 { return __normal_iterator(_M_current--); }
1136
1137 // Random access iterator requirements
1138 _GLIBCXX20_CONSTEXPR
1139 reference
1140 operator[](difference_type __n) const _GLIBCXX_NOEXCEPT
1141 { return _M_current[__n]; }
1142
1143 _GLIBCXX20_CONSTEXPR
1144 __normal_iterator&
1145 operator+=(difference_type __n) _GLIBCXX_NOEXCEPT
1146 { _M_current += __n; return *this; }
1147
1148 _GLIBCXX20_CONSTEXPR
1149 __normal_iterator
1150 operator+(difference_type __n) const _GLIBCXX_NOEXCEPT
1151 { return __normal_iterator(_M_current + __n); }
1152
1153 _GLIBCXX20_CONSTEXPR
1154 __normal_iterator&
1155 operator-=(difference_type __n) _GLIBCXX_NOEXCEPT
1156 { _M_current -= __n; return *this; }
1157
1158 _GLIBCXX20_CONSTEXPR
1159 __normal_iterator
1160 operator-(difference_type __n) const _GLIBCXX_NOEXCEPT
1161 { return __normal_iterator(_M_current - __n); }
1162
1163 _GLIBCXX20_CONSTEXPR
1164 const _Iterator&
1165 base() const _GLIBCXX_NOEXCEPT
1166 { return _M_current; }
1167 };
1168
1169 // Note: In what follows, the left- and right-hand-side iterators are
1170 // allowed to vary in types (conceptually in cv-qualification) so that
1171 // comparison between cv-qualified and non-cv-qualified iterators be
1172 // valid. However, the greedy and unfriendly operators in std::rel_ops
1173 // will make overload resolution ambiguous (when in scope) if we don't
1174 // provide overloads whose operands are of the same type. Can someone
1175 // remind me what generic programming is about? -- Gaby
1176
1177 #if __cpp_lib_three_way_comparison
1178 template<typename _IteratorL, typename _IteratorR, typename _Container>
1179 [[nodiscard]]
1180 constexpr bool
1181 operator==(const __normal_iterator<_IteratorL, _Container>& __lhs,
1182 const __normal_iterator<_IteratorR, _Container>& __rhs)
1183 noexcept(noexcept(__lhs.base() == __rhs.base()))
1184 requires requires {
1185 { __lhs.base() == __rhs.base() } -> std::convertible_to<bool>;
1186 }
1187 { return __lhs.base() == __rhs.base(); }
1188
1189 template<typename _IteratorL, typename _IteratorR, typename _Container>
1190 [[nodiscard]]
1191 constexpr std::__detail::__synth3way_t<_IteratorR, _IteratorL>
1192 operator<=>(const __normal_iterator<_IteratorL, _Container>& __lhs,
1193 const __normal_iterator<_IteratorR, _Container>& __rhs)
1194 noexcept(noexcept(std::__detail::__synth3way(__lhs.base(), __rhs.base())))
1195 { return std::__detail::__synth3way(__lhs.base(), __rhs.base()); }
1196
1197 template<typename _Iterator, typename _Container>
1198 [[nodiscard]]
1199 constexpr bool
1200 operator==(const __normal_iterator<_Iterator, _Container>& __lhs,
1201 const __normal_iterator<_Iterator, _Container>& __rhs)
1202 noexcept(noexcept(__lhs.base() == __rhs.base()))
1203 requires requires {
1204 { __lhs.base() == __rhs.base() } -> std::convertible_to<bool>;
1205 }
1206 { return __lhs.base() == __rhs.base(); }
1207
1208 template<typename _Iterator, typename _Container>
1209 [[nodiscard]]
1210 constexpr std::__detail::__synth3way_t<_Iterator>
1211 operator<=>(const __normal_iterator<_Iterator, _Container>& __lhs,
1212 const __normal_iterator<_Iterator, _Container>& __rhs)
1213 noexcept(noexcept(std::__detail::__synth3way(__lhs.base(), __rhs.base())))
1214 { return std::__detail::__synth3way(__lhs.base(), __rhs.base()); }
1215 #else
1216 // Forward iterator requirements
1217 template<typename _IteratorL, typename _IteratorR, typename _Container>
1218 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
1219 inline bool
1220 operator==(const __normal_iterator<_IteratorL, _Container>& __lhs,
1221 const __normal_iterator<_IteratorR, _Container>& __rhs)
1222 _GLIBCXX_NOEXCEPT
1223 { return __lhs.base() == __rhs.base(); }
1224
1225 template<typename _Iterator, typename _Container>
1226 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
1227 inline bool
1228 operator==(const __normal_iterator<_Iterator, _Container>& __lhs,
1229 const __normal_iterator<_Iterator, _Container>& __rhs)
1230 _GLIBCXX_NOEXCEPT
1231 { return __lhs.base() == __rhs.base(); }
1232
1233 template<typename _IteratorL, typename _IteratorR, typename _Container>
1234 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
1235 inline bool
1236 operator!=(const __normal_iterator<_IteratorL, _Container>& __lhs,
1237 const __normal_iterator<_IteratorR, _Container>& __rhs)
1238 _GLIBCXX_NOEXCEPT
1239 { return __lhs.base() != __rhs.base(); }
1240
1241 template<typename _Iterator, typename _Container>
1242 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
1243 inline bool
1244 operator!=(const __normal_iterator<_Iterator, _Container>& __lhs,
1245 const __normal_iterator<_Iterator, _Container>& __rhs)
1246 _GLIBCXX_NOEXCEPT
1247 { return __lhs.base() != __rhs.base(); }
1248
1249 // Random access iterator requirements
1250 template<typename _IteratorL, typename _IteratorR, typename _Container>
1251 _GLIBCXX_NODISCARD
1252 inline bool
1253 operator<(const __normal_iterator<_IteratorL, _Container>& __lhs,
1254 const __normal_iterator<_IteratorR, _Container>& __rhs)
1255 _GLIBCXX_NOEXCEPT
1256 { return __lhs.base() < __rhs.base(); }
1257
1258 template<typename _Iterator, typename _Container>
1259 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
1260 inline bool
1261 operator<(const __normal_iterator<_Iterator, _Container>& __lhs,
1262 const __normal_iterator<_Iterator, _Container>& __rhs)
1263 _GLIBCXX_NOEXCEPT
1264 { return __lhs.base() < __rhs.base(); }
1265
1266 template<typename _IteratorL, typename _IteratorR, typename _Container>
1267 _GLIBCXX_NODISCARD
1268 inline bool
1269 operator>(const __normal_iterator<_IteratorL, _Container>& __lhs,
1270 const __normal_iterator<_IteratorR, _Container>& __rhs)
1271 _GLIBCXX_NOEXCEPT
1272 { return __lhs.base() > __rhs.base(); }
1273
1274 template<typename _Iterator, typename _Container>
1275 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
1276 inline bool
1277 operator>(const __normal_iterator<_Iterator, _Container>& __lhs,
1278 const __normal_iterator<_Iterator, _Container>& __rhs)
1279 _GLIBCXX_NOEXCEPT
1280 { return __lhs.base() > __rhs.base(); }
1281
1282 template<typename _IteratorL, typename _IteratorR, typename _Container>
1283 _GLIBCXX_NODISCARD
1284 inline bool
1285 operator<=(const __normal_iterator<_IteratorL, _Container>& __lhs,
1286 const __normal_iterator<_IteratorR, _Container>& __rhs)
1287 _GLIBCXX_NOEXCEPT
1288 { return __lhs.base() <= __rhs.base(); }
1289
1290 template<typename _Iterator, typename _Container>
1291 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
1292 inline bool
1293 operator<=(const __normal_iterator<_Iterator, _Container>& __lhs,
1294 const __normal_iterator<_Iterator, _Container>& __rhs)
1295 _GLIBCXX_NOEXCEPT
1296 { return __lhs.base() <= __rhs.base(); }
1297
1298 template<typename _IteratorL, typename _IteratorR, typename _Container>
1299 _GLIBCXX_NODISCARD
1300 inline bool
1301 operator>=(const __normal_iterator<_IteratorL, _Container>& __lhs,
1302 const __normal_iterator<_IteratorR, _Container>& __rhs)
1303 _GLIBCXX_NOEXCEPT
1304 { return __lhs.base() >= __rhs.base(); }
1305
1306 template<typename _Iterator, typename _Container>
1307 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
1308 inline bool
1309 operator>=(const __normal_iterator<_Iterator, _Container>& __lhs,
1310 const __normal_iterator<_Iterator, _Container>& __rhs)
1311 _GLIBCXX_NOEXCEPT
1312 { return __lhs.base() >= __rhs.base(); }
1313 #endif // three-way comparison
1314
1315 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1316 // According to the resolution of DR179 not only the various comparison
1317 // operators but also operator- must accept mixed iterator/const_iterator
1318 // parameters.
1319 template<typename _IteratorL, typename _IteratorR, typename _Container>
1320 #if __cplusplus >= 201103L
1321 // DR 685.
1322 [[__nodiscard__]] _GLIBCXX20_CONSTEXPR
1323 inline auto
1324 operator-(const __normal_iterator<_IteratorL, _Container>& __lhs,
1325 const __normal_iterator<_IteratorR, _Container>& __rhs) noexcept
1326 -> decltype(__lhs.base() - __rhs.base())
1327 #else
1328 inline typename __normal_iterator<_IteratorL, _Container>::difference_type
1329 operator-(const __normal_iterator<_IteratorL, _Container>& __lhs,
1330 const __normal_iterator<_IteratorR, _Container>& __rhs)
1331 #endif
1332 { return __lhs.base() - __rhs.base(); }
1333
1334 template<typename _Iterator, typename _Container>
1335 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
1336 inline typename __normal_iterator<_Iterator, _Container>::difference_type
1337 operator-(const __normal_iterator<_Iterator, _Container>& __lhs,
1338 const __normal_iterator<_Iterator, _Container>& __rhs)
1339 _GLIBCXX_NOEXCEPT
1340 { return __lhs.base() - __rhs.base(); }
1341
1342 template<typename _Iterator, typename _Container>
1343 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
1344 inline __normal_iterator<_Iterator, _Container>
1345 operator+(typename __normal_iterator<_Iterator, _Container>::difference_type
1346 __n, const __normal_iterator<_Iterator, _Container>& __i)
1347 _GLIBCXX_NOEXCEPT
1348 { return __normal_iterator<_Iterator, _Container>(__i.base() + __n); }
1349
1350 _GLIBCXX_END_NAMESPACE_VERSION
1351 } // namespace
1352
1353 namespace std _GLIBCXX_VISIBILITY(default)
1354 {
1355 _GLIBCXX_BEGIN_NAMESPACE_VERSION
1356
1357 template<typename _Iterator, typename _Container>
1358 _GLIBCXX20_CONSTEXPR
1359 _Iterator
1360 __niter_base(__gnu_cxx::__normal_iterator<_Iterator, _Container> __it)
1361 _GLIBCXX_NOEXCEPT_IF(std::is_nothrow_copy_constructible<_Iterator>::value)
1362 { return __it.base(); }
1363
1364 #if __cplusplus >= 201103L
1365
1366 #if __cplusplus <= 201703L
1367 // Need to overload __to_address because the pointer_traits primary template
1368 // will deduce element_type of __normal_iterator<T*, C> as T* rather than T.
1369 template<typename _Iterator, typename _Container>
1370 constexpr auto
1371 __to_address(const __gnu_cxx::__normal_iterator<_Iterator,
1372 _Container>& __it) noexcept
1373 -> decltype(std::__to_address(__it.base()))
1374 { return std::__to_address(__it.base()); }
1375 #endif
1376
1377 /**
1378 * @addtogroup iterators
1379 * @{
1380 */
1381
1382 #if __cplusplus > 201703L && __cpp_lib_concepts
1383 template<semiregular _Sent>
1384 class move_sentinel
1385 {
1386 public:
1387 constexpr
1388 move_sentinel()
1389 noexcept(is_nothrow_default_constructible_v<_Sent>)
1390 : _M_last() { }
1391
1392 constexpr explicit
1393 move_sentinel(_Sent __s)
1394 noexcept(is_nothrow_move_constructible_v<_Sent>)
1395 : _M_last(std::move(__s)) { }
1396
1397 template<typename _S2> requires convertible_to<const _S2&, _Sent>
1398 constexpr
1399 move_sentinel(const move_sentinel<_S2>& __s)
1400 noexcept(is_nothrow_constructible_v<_Sent, const _S2&>)
1401 : _M_last(__s.base())
1402 { }
1403
1404 template<typename _S2> requires assignable_from<_Sent&, const _S2&>
1405 constexpr move_sentinel&
1406 operator=(const move_sentinel<_S2>& __s)
1407 noexcept(is_nothrow_assignable_v<_Sent, const _S2&>)
1408 {
1409 _M_last = __s.base();
1410 return *this;
1411 }
1412
1413 [[nodiscard]]
1414 constexpr _Sent
1415 base() const
1416 noexcept(is_nothrow_copy_constructible_v<_Sent>)
1417 { return _M_last; }
1418
1419 private:
1420 _Sent _M_last;
1421 };
1422 #endif // C++20
1423
1424 namespace __detail
1425 {
1426 #if __cplusplus > 201703L && __cpp_lib_concepts
1427 template<typename _Iterator>
1428 struct __move_iter_cat
1429 { };
1430
1431 template<typename _Iterator>
1432 requires requires { typename __iter_category_t<_Iterator>; }
1433 struct __move_iter_cat<_Iterator>
1434 {
1435 using iterator_category
1436 = __clamped_iter_cat_t<_Iterator, random_access_iterator_tag>;
1437 };
1438 #endif
1439 }
1440
1441 // 24.4.3 Move iterators
1442 /**
1443 * Class template move_iterator is an iterator adapter with the same
1444 * behavior as the underlying iterator except that its dereference
1445 * operator implicitly converts the value returned by the underlying
1446 * iterator's dereference operator to an rvalue reference. Some
1447 * generic algorithms can be called with move iterators to replace
1448 * copying with moving.
1449 */
1450 template<typename _Iterator>
1451 class move_iterator
1452 #if __cplusplus > 201703L && __cpp_lib_concepts
1453 : public __detail::__move_iter_cat<_Iterator>
1454 #endif
1455 {
1456 _Iterator _M_current;
1457
1458 using __traits_type = iterator_traits<_Iterator>;
1459 #if ! (__cplusplus > 201703L && __cpp_lib_concepts)
1460 using __base_ref = typename __traits_type::reference;
1461 #endif
1462
1463 template<typename _Iter2>
1464 friend class move_iterator;
1465
1466 #if __cpp_lib_concepts
1467 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1468 // 3435. three_way_comparable_with<reverse_iterator<int*>, [...]>
1469 template<typename _Iter2>
1470 static constexpr bool __convertible = !is_same_v<_Iter2, _Iterator>
1471 && convertible_to<const _Iter2&, _Iterator>;
1472 #endif
1473
1474 #if __cplusplus > 201703L && __cpp_lib_concepts
1475 static auto
1476 _S_iter_concept()
1477 {
1478 if constexpr (random_access_iterator<_Iterator>)
1479 return random_access_iterator_tag{};
1480 else if constexpr (bidirectional_iterator<_Iterator>)
1481 return bidirectional_iterator_tag{};
1482 else if constexpr (forward_iterator<_Iterator>)
1483 return forward_iterator_tag{};
1484 else
1485 return input_iterator_tag{};
1486 }
1487 #endif
1488
1489 public:
1490 using iterator_type = _Iterator;
1491
1492 #if __cplusplus > 201703L && __cpp_lib_concepts
1493 // This is P2520R0, a C++23 change, but we treat it as a DR against C++20.
1494 # define __cpp_lib_move_iterator_concept 202207L
1495 using iterator_concept = decltype(_S_iter_concept());
1496
1497 // iterator_category defined in __move_iter_cat
1498 using value_type = iter_value_t<_Iterator>;
1499 using difference_type = iter_difference_t<_Iterator>;
1500 using pointer = _Iterator;
1501 using reference = iter_rvalue_reference_t<_Iterator>;
1502 #else
1503 typedef typename __traits_type::iterator_category iterator_category;
1504 typedef typename __traits_type::value_type value_type;
1505 typedef typename __traits_type::difference_type difference_type;
1506 // NB: DR 680.
1507 typedef _Iterator pointer;
1508 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1509 // 2106. move_iterator wrapping iterators returning prvalues
1510 using reference
1511 = __conditional_t<is_reference<__base_ref>::value,
1512 typename remove_reference<__base_ref>::type&&,
1513 __base_ref>;
1514 #endif
1515
1516 _GLIBCXX17_CONSTEXPR
1517 move_iterator()
1518 : _M_current() { }
1519
1520 explicit _GLIBCXX17_CONSTEXPR
1521 move_iterator(iterator_type __i)
1522 : _M_current(std::move(__i)) { }
1523
1524 template<typename _Iter>
1525 #if __cpp_lib_concepts
1526 requires __convertible<_Iter>
1527 #endif
1528 _GLIBCXX17_CONSTEXPR
1529 move_iterator(const move_iterator<_Iter>& __i)
1530 : _M_current(__i._M_current) { }
1531
1532 template<typename _Iter>
1533 #if __cpp_lib_concepts
1534 requires __convertible<_Iter>
1535 && assignable_from<_Iterator&, const _Iter&>
1536 #endif
1537 _GLIBCXX17_CONSTEXPR
1538 move_iterator& operator=(const move_iterator<_Iter>& __i)
1539 {
1540 _M_current = __i._M_current;
1541 return *this;
1542 }
1543
1544 #if __cplusplus <= 201703L
1545 [[__nodiscard__]]
1546 _GLIBCXX17_CONSTEXPR iterator_type
1547 base() const
1548 { return _M_current; }
1549 #else
1550 [[nodiscard]]
1551 constexpr const iterator_type&
1552 base() const & noexcept
1553 { return _M_current; }
1554
1555 [[nodiscard]]
1556 constexpr iterator_type
1557 base() &&
1558 { return std::move(_M_current); }
1559 #endif
1560
1561 [[__nodiscard__]]
1562 _GLIBCXX17_CONSTEXPR reference
1563 operator*() const
1564 #if __cplusplus > 201703L && __cpp_lib_concepts
1565 { return ranges::iter_move(_M_current); }
1566 #else
1567 { return static_cast<reference>(*_M_current); }
1568 #endif
1569
1570 [[__nodiscard__]]
1571 _GLIBCXX17_CONSTEXPR pointer
1572 operator->() const
1573 { return _M_current; }
1574
1575 _GLIBCXX17_CONSTEXPR move_iterator&
1576 operator++()
1577 {
1578 ++_M_current;
1579 return *this;
1580 }
1581
1582 _GLIBCXX17_CONSTEXPR move_iterator
1583 operator++(int)
1584 {
1585 move_iterator __tmp = *this;
1586 ++_M_current;
1587 return __tmp;
1588 }
1589
1590 #if __cpp_lib_concepts
1591 constexpr void
1592 operator++(int) requires (!forward_iterator<_Iterator>)
1593 { ++_M_current; }
1594 #endif
1595
1596 _GLIBCXX17_CONSTEXPR move_iterator&
1597 operator--()
1598 {
1599 --_M_current;
1600 return *this;
1601 }
1602
1603 _GLIBCXX17_CONSTEXPR move_iterator
1604 operator--(int)
1605 {
1606 move_iterator __tmp = *this;
1607 --_M_current;
1608 return __tmp;
1609 }
1610
1611 [[__nodiscard__]]
1612 _GLIBCXX17_CONSTEXPR move_iterator
1613 operator+(difference_type __n) const
1614 { return move_iterator(_M_current + __n); }
1615
1616 _GLIBCXX17_CONSTEXPR move_iterator&
1617 operator+=(difference_type __n)
1618 {
1619 _M_current += __n;
1620 return *this;
1621 }
1622
1623 [[__nodiscard__]]
1624 _GLIBCXX17_CONSTEXPR move_iterator
1625 operator-(difference_type __n) const
1626 { return move_iterator(_M_current - __n); }
1627
1628 _GLIBCXX17_CONSTEXPR move_iterator&
1629 operator-=(difference_type __n)
1630 {
1631 _M_current -= __n;
1632 return *this;
1633 }
1634
1635 [[__nodiscard__]]
1636 _GLIBCXX17_CONSTEXPR reference
1637 operator[](difference_type __n) const
1638 #if __cplusplus > 201703L && __cpp_lib_concepts
1639 { return ranges::iter_move(_M_current + __n); }
1640 #else
1641 { return std::move(_M_current[__n]); }
1642 #endif
1643
1644 #if __cplusplus > 201703L && __cpp_lib_concepts
1645 template<sentinel_for<_Iterator> _Sent>
1646 [[nodiscard]]
1647 friend constexpr bool
1648 operator==(const move_iterator& __x, const move_sentinel<_Sent>& __y)
1649 { return __x.base() == __y.base(); }
1650
1651 template<sized_sentinel_for<_Iterator> _Sent>
1652 [[nodiscard]]
1653 friend constexpr iter_difference_t<_Iterator>
1654 operator-(const move_sentinel<_Sent>& __x, const move_iterator& __y)
1655 { return __x.base() - __y.base(); }
1656
1657 template<sized_sentinel_for<_Iterator> _Sent>
1658 [[nodiscard]]
1659 friend constexpr iter_difference_t<_Iterator>
1660 operator-(const move_iterator& __x, const move_sentinel<_Sent>& __y)
1661 { return __x.base() - __y.base(); }
1662
1663 [[nodiscard]]
1664 friend constexpr iter_rvalue_reference_t<_Iterator>
1665 iter_move(const move_iterator& __i)
1666 noexcept(noexcept(ranges::iter_move(__i._M_current)))
1667 { return ranges::iter_move(__i._M_current); }
1668
1669 template<indirectly_swappable<_Iterator> _Iter2>
1670 friend constexpr void
1671 iter_swap(const move_iterator& __x, const move_iterator<_Iter2>& __y)
1672 noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
1673 { return ranges::iter_swap(__x._M_current, __y._M_current); }
1674 #endif // C++20
1675 };
1676
1677 template<typename _IteratorL, typename _IteratorR>
1678 [[__nodiscard__]]
1679 inline _GLIBCXX17_CONSTEXPR bool
1680 operator==(const move_iterator<_IteratorL>& __x,
1681 const move_iterator<_IteratorR>& __y)
1682 #if __cplusplus > 201703L && __cpp_lib_concepts
1683 requires requires { { __x.base() == __y.base() } -> convertible_to<bool>; }
1684 #endif
1685 { return __x.base() == __y.base(); }
1686
1687 #if __cpp_lib_three_way_comparison
1688 template<typename _IteratorL,
1689 three_way_comparable_with<_IteratorL> _IteratorR>
1690 [[__nodiscard__]]
1691 constexpr compare_three_way_result_t<_IteratorL, _IteratorR>
1692 operator<=>(const move_iterator<_IteratorL>& __x,
1693 const move_iterator<_IteratorR>& __y)
1694 { return __x.base() <=> __y.base(); }
1695 #else
1696 template<typename _IteratorL, typename _IteratorR>
1697 [[__nodiscard__]]
1698 inline _GLIBCXX17_CONSTEXPR bool
1699 operator!=(const move_iterator<_IteratorL>& __x,
1700 const move_iterator<_IteratorR>& __y)
1701 { return !(__x == __y); }
1702 #endif
1703
1704 template<typename _IteratorL, typename _IteratorR>
1705 [[__nodiscard__]]
1706 inline _GLIBCXX17_CONSTEXPR bool
1707 operator<(const move_iterator<_IteratorL>& __x,
1708 const move_iterator<_IteratorR>& __y)
1709 #if __cplusplus > 201703L && __cpp_lib_concepts
1710 requires requires { { __x.base() < __y.base() } -> convertible_to<bool>; }
1711 #endif
1712 { return __x.base() < __y.base(); }
1713
1714 template<typename _IteratorL, typename _IteratorR>
1715 [[__nodiscard__]]
1716 inline _GLIBCXX17_CONSTEXPR bool
1717 operator<=(const move_iterator<_IteratorL>& __x,
1718 const move_iterator<_IteratorR>& __y)
1719 #if __cplusplus > 201703L && __cpp_lib_concepts
1720 requires requires { { __y.base() < __x.base() } -> convertible_to<bool>; }
1721 #endif
1722 { return !(__y < __x); }
1723
1724 template<typename _IteratorL, typename _IteratorR>
1725 [[__nodiscard__]]
1726 inline _GLIBCXX17_CONSTEXPR bool
1727 operator>(const move_iterator<_IteratorL>& __x,
1728 const move_iterator<_IteratorR>& __y)
1729 #if __cplusplus > 201703L && __cpp_lib_concepts
1730 requires requires { { __y.base() < __x.base() } -> convertible_to<bool>; }
1731 #endif
1732 { return __y < __x; }
1733
1734 template<typename _IteratorL, typename _IteratorR>
1735 [[__nodiscard__]]
1736 inline _GLIBCXX17_CONSTEXPR bool
1737 operator>=(const move_iterator<_IteratorL>& __x,
1738 const move_iterator<_IteratorR>& __y)
1739 #if __cplusplus > 201703L && __cpp_lib_concepts
1740 requires requires { { __x.base() < __y.base() } -> convertible_to<bool>; }
1741 #endif
1742 { return !(__x < __y); }
1743
1744 // Note: See __normal_iterator operators note from Gaby to understand
1745 // why we have these extra overloads for some move_iterator operators.
1746
1747 template<typename _Iterator>
1748 [[__nodiscard__]]
1749 inline _GLIBCXX17_CONSTEXPR bool
1750 operator==(const move_iterator<_Iterator>& __x,
1751 const move_iterator<_Iterator>& __y)
1752 { return __x.base() == __y.base(); }
1753
1754 #if __cpp_lib_three_way_comparison
1755 template<three_way_comparable _Iterator>
1756 [[__nodiscard__]]
1757 constexpr compare_three_way_result_t<_Iterator>
1758 operator<=>(const move_iterator<_Iterator>& __x,
1759 const move_iterator<_Iterator>& __y)
1760 { return __x.base() <=> __y.base(); }
1761 #else
1762 template<typename _Iterator>
1763 [[__nodiscard__]]
1764 inline _GLIBCXX17_CONSTEXPR bool
1765 operator!=(const move_iterator<_Iterator>& __x,
1766 const move_iterator<_Iterator>& __y)
1767 { return !(__x == __y); }
1768
1769 template<typename _Iterator>
1770 [[__nodiscard__]]
1771 inline _GLIBCXX17_CONSTEXPR bool
1772 operator<(const move_iterator<_Iterator>& __x,
1773 const move_iterator<_Iterator>& __y)
1774 { return __x.base() < __y.base(); }
1775
1776 template<typename _Iterator>
1777 [[__nodiscard__]]
1778 inline _GLIBCXX17_CONSTEXPR bool
1779 operator<=(const move_iterator<_Iterator>& __x,
1780 const move_iterator<_Iterator>& __y)
1781 { return !(__y < __x); }
1782
1783 template<typename _Iterator>
1784 [[__nodiscard__]]
1785 inline _GLIBCXX17_CONSTEXPR bool
1786 operator>(const move_iterator<_Iterator>& __x,
1787 const move_iterator<_Iterator>& __y)
1788 { return __y < __x; }
1789
1790 template<typename _Iterator>
1791 [[__nodiscard__]]
1792 inline _GLIBCXX17_CONSTEXPR bool
1793 operator>=(const move_iterator<_Iterator>& __x,
1794 const move_iterator<_Iterator>& __y)
1795 { return !(__x < __y); }
1796 #endif // ! C++20
1797
1798 // DR 685.
1799 template<typename _IteratorL, typename _IteratorR>
1800 [[__nodiscard__]]
1801 inline _GLIBCXX17_CONSTEXPR auto
1802 operator-(const move_iterator<_IteratorL>& __x,
1803 const move_iterator<_IteratorR>& __y)
1804 -> decltype(__x.base() - __y.base())
1805 { return __x.base() - __y.base(); }
1806
1807 template<typename _Iterator>
1808 [[__nodiscard__]]
1809 inline _GLIBCXX17_CONSTEXPR move_iterator<_Iterator>
1810 operator+(typename move_iterator<_Iterator>::difference_type __n,
1811 const move_iterator<_Iterator>& __x)
1812 { return __x + __n; }
1813
1814 template<typename _Iterator>
1815 [[__nodiscard__]]
1816 inline _GLIBCXX17_CONSTEXPR move_iterator<_Iterator>
1817 make_move_iterator(_Iterator __i)
1818 { return move_iterator<_Iterator>(std::move(__i)); }
1819
1820 template<typename _Iterator, typename _ReturnType
1821 = __conditional_t<__move_if_noexcept_cond
1822 <typename iterator_traits<_Iterator>::value_type>::value,
1823 _Iterator, move_iterator<_Iterator>>>
1824 inline _GLIBCXX17_CONSTEXPR _ReturnType
1825 __make_move_if_noexcept_iterator(_Iterator __i)
1826 { return _ReturnType(__i); }
1827
1828 // Overload for pointers that matches std::move_if_noexcept more closely,
1829 // returning a constant iterator when we don't want to move.
1830 template<typename _Tp, typename _ReturnType
1831 = __conditional_t<__move_if_noexcept_cond<_Tp>::value,
1832 const _Tp*, move_iterator<_Tp*>>>
1833 inline _GLIBCXX17_CONSTEXPR _ReturnType
1834 __make_move_if_noexcept_iterator(_Tp* __i)
1835 { return _ReturnType(__i); }
1836
1837 #if __cplusplus > 201703L && __cpp_lib_concepts
1838 // [iterators.common] Common iterators
1839
1840 namespace __detail
1841 {
1842 template<typename _It>
1843 concept __common_iter_has_arrow = indirectly_readable<const _It>
1844 && (requires(const _It& __it) { __it.operator->(); }
1845 || is_reference_v<iter_reference_t<_It>>
1846 || constructible_from<iter_value_t<_It>, iter_reference_t<_It>>);
1847
1848 template<typename _It>
1849 concept __common_iter_use_postfix_proxy
1850 = (!requires (_It& __i) { { *__i++ } -> __can_reference; })
1851 && constructible_from<iter_value_t<_It>, iter_reference_t<_It>>
1852 && move_constructible<iter_value_t<_It>>;
1853 } // namespace __detail
1854
1855 /// An iterator/sentinel adaptor for representing a non-common range.
1856 template<input_or_output_iterator _It, sentinel_for<_It> _Sent>
1857 requires (!same_as<_It, _Sent>) && copyable<_It>
1858 class common_iterator
1859 {
1860 template<typename _Tp, typename _Up>
1861 static constexpr bool
1862 _S_noexcept1()
1863 {
1864 if constexpr (is_trivially_default_constructible_v<_Tp>)
1865 return is_nothrow_assignable_v<_Tp&, _Up>;
1866 else
1867 return is_nothrow_constructible_v<_Tp, _Up>;
1868 }
1869
1870 template<typename _It2, typename _Sent2>
1871 static constexpr bool
1872 _S_noexcept()
1873 { return _S_noexcept1<_It, _It2>() && _S_noexcept1<_Sent, _Sent2>(); }
1874
1875 class __arrow_proxy
1876 {
1877 iter_value_t<_It> _M_keep;
1878
1879 constexpr
1880 __arrow_proxy(iter_reference_t<_It>&& __x)
1881 : _M_keep(std::move(__x)) { }
1882
1883 friend class common_iterator;
1884
1885 public:
1886 constexpr const iter_value_t<_It>*
1887 operator->() const noexcept
1888 { return std::__addressof(_M_keep); }
1889 };
1890
1891 class __postfix_proxy
1892 {
1893 iter_value_t<_It> _M_keep;
1894
1895 constexpr
1896 __postfix_proxy(iter_reference_t<_It>&& __x)
1897 : _M_keep(std::forward<iter_reference_t<_It>>(__x)) { }
1898
1899 friend class common_iterator;
1900
1901 public:
1902 constexpr const iter_value_t<_It>&
1903 operator*() const noexcept
1904 { return _M_keep; }
1905 };
1906
1907 public:
1908 constexpr
1909 common_iterator()
1910 noexcept(is_nothrow_default_constructible_v<_It>)
1911 requires default_initializable<_It>
1912 : _M_it(), _M_index(0)
1913 { }
1914
1915 constexpr
1916 common_iterator(_It __i)
1917 noexcept(is_nothrow_move_constructible_v<_It>)
1918 : _M_it(std::move(__i)), _M_index(0)
1919 { }
1920
1921 constexpr
1922 common_iterator(_Sent __s)
1923 noexcept(is_nothrow_move_constructible_v<_Sent>)
1924 : _M_sent(std::move(__s)), _M_index(1)
1925 { }
1926
1927 template<typename _It2, typename _Sent2>
1928 requires convertible_to<const _It2&, _It>
1929 && convertible_to<const _Sent2&, _Sent>
1930 constexpr
1931 common_iterator(const common_iterator<_It2, _Sent2>& __x)
1932 noexcept(_S_noexcept<const _It2&, const _Sent2&>())
1933 : _M_valueless(), _M_index(__x._M_index)
1934 {
1935 __glibcxx_assert(__x._M_has_value());
1936 if (_M_index == 0)
1937 {
1938 if constexpr (is_trivially_default_constructible_v<_It>)
1939 _M_it = std::move(__x._M_it);
1940 else
1941 std::construct_at(std::__addressof(_M_it), __x._M_it);
1942 }
1943 else if (_M_index == 1)
1944 {
1945 if constexpr (is_trivially_default_constructible_v<_Sent>)
1946 _M_sent = std::move(__x._M_sent);
1947 else
1948 std::construct_at(std::__addressof(_M_sent), __x._M_sent);
1949 }
1950 }
1951
1952 common_iterator(const common_iterator&) = default;
1953
1954 constexpr
1955 common_iterator(const common_iterator& __x)
1956 noexcept(_S_noexcept<const _It&, const _Sent&>())
1957 requires (!is_trivially_copyable_v<_It> || !is_trivially_copyable_v<_Sent>)
1958 : _M_valueless(), _M_index(__x._M_index)
1959 {
1960 if (_M_index == 0)
1961 {
1962 if constexpr (is_trivially_default_constructible_v<_It>)
1963 _M_it = __x._M_it;
1964 else
1965 std::construct_at(std::__addressof(_M_it), __x._M_it);
1966 }
1967 else if (_M_index == 1)
1968 {
1969 if constexpr (is_trivially_default_constructible_v<_Sent>)
1970 _M_sent = __x._M_sent;
1971 else
1972 std::construct_at(std::__addressof(_M_sent), __x._M_sent);
1973 }
1974 }
1975
1976 common_iterator(common_iterator&&) = default;
1977
1978 constexpr
1979 common_iterator(common_iterator&& __x)
1980 noexcept(_S_noexcept<_It, _Sent>())
1981 requires (!is_trivially_copyable_v<_It> || !is_trivially_copyable_v<_Sent>)
1982 : _M_valueless(), _M_index(__x._M_index)
1983 {
1984 if (_M_index == 0)
1985 {
1986 if constexpr (is_trivially_default_constructible_v<_It>)
1987 _M_it = std::move(__x._M_it);
1988 else
1989 std::construct_at(std::__addressof(_M_it), std::move(__x._M_it));
1990 }
1991 else if (_M_index == 1)
1992 {
1993 if constexpr (is_trivially_default_constructible_v<_Sent>)
1994 _M_sent = std::move(__x._M_sent);
1995 else
1996 std::construct_at(std::__addressof(_M_sent),
1997 std::move(__x._M_sent));
1998 }
1999 }
2000
2001 constexpr common_iterator&
2002 operator=(const common_iterator&) = default;
2003
2004 constexpr common_iterator&
2005 operator=(const common_iterator& __x)
2006 noexcept(is_nothrow_copy_assignable_v<_It>
2007 && is_nothrow_copy_assignable_v<_Sent>
2008 && is_nothrow_copy_constructible_v<_It>
2009 && is_nothrow_copy_constructible_v<_Sent>)
2010 requires (!is_trivially_copy_assignable_v<_It>
2011 || !is_trivially_copy_assignable_v<_Sent>)
2012 {
2013 _M_assign(__x);
2014 return *this;
2015 }
2016
2017 constexpr common_iterator&
2018 operator=(common_iterator&&) = default;
2019
2020 constexpr common_iterator&
2021 operator=(common_iterator&& __x)
2022 noexcept(is_nothrow_move_assignable_v<_It>
2023 && is_nothrow_move_assignable_v<_Sent>
2024 && is_nothrow_move_constructible_v<_It>
2025 && is_nothrow_move_constructible_v<_Sent>)
2026 requires (!is_trivially_move_assignable_v<_It>
2027 || !is_trivially_move_assignable_v<_Sent>)
2028 {
2029 _M_assign(std::move(__x));
2030 return *this;
2031 }
2032
2033 template<typename _It2, typename _Sent2>
2034 requires convertible_to<const _It2&, _It>
2035 && convertible_to<const _Sent2&, _Sent>
2036 && assignable_from<_It&, const _It2&>
2037 && assignable_from<_Sent&, const _Sent2&>
2038 constexpr common_iterator&
2039 operator=(const common_iterator<_It2, _Sent2>& __x)
2040 noexcept(is_nothrow_constructible_v<_It, const _It2&>
2041 && is_nothrow_constructible_v<_Sent, const _Sent2&>
2042 && is_nothrow_assignable_v<_It&, const _It2&>
2043 && is_nothrow_assignable_v<_Sent&, const _Sent2&>)
2044 {
2045 __glibcxx_assert(__x._M_has_value());
2046 _M_assign(__x);
2047 return *this;
2048 }
2049
2050 #if __cpp_concepts >= 202002L // Constrained special member functions
2051 ~common_iterator() = default;
2052
2053 constexpr
2054 ~common_iterator()
2055 requires (!is_trivially_destructible_v<_It>
2056 || !is_trivially_destructible_v<_Sent>)
2057 #else
2058 constexpr
2059 ~common_iterator()
2060 #endif
2061 {
2062 if (_M_index == 0)
2063 _M_it.~_It();
2064 else if (_M_index == 1)
2065 _M_sent.~_Sent();
2066 }
2067
2068 [[nodiscard]]
2069 constexpr decltype(auto)
2070 operator*()
2071 {
2072 __glibcxx_assert(_M_index == 0);
2073 return *_M_it;
2074 }
2075
2076 [[nodiscard]]
2077 constexpr decltype(auto)
2078 operator*() const requires __detail::__dereferenceable<const _It>
2079 {
2080 __glibcxx_assert(_M_index == 0);
2081 return *_M_it;
2082 }
2083
2084 [[nodiscard]]
2085 constexpr auto
2086 operator->() const requires __detail::__common_iter_has_arrow<_It>
2087 {
2088 __glibcxx_assert(_M_index == 0);
2089 if constexpr (is_pointer_v<_It> || requires { _M_it.operator->(); })
2090 return _M_it;
2091 else if constexpr (is_reference_v<iter_reference_t<_It>>)
2092 {
2093 auto&& __tmp = *_M_it;
2094 return std::__addressof(__tmp);
2095 }
2096 else
2097 return __arrow_proxy{*_M_it};
2098 }
2099
2100 constexpr common_iterator&
2101 operator++()
2102 {
2103 __glibcxx_assert(_M_index == 0);
2104 ++_M_it;
2105 return *this;
2106 }
2107
2108 constexpr decltype(auto)
2109 operator++(int)
2110 {
2111 __glibcxx_assert(_M_index == 0);
2112 if constexpr (forward_iterator<_It>)
2113 {
2114 common_iterator __tmp = *this;
2115 ++*this;
2116 return __tmp;
2117 }
2118 else if constexpr (!__detail::__common_iter_use_postfix_proxy<_It>)
2119 return _M_it++;
2120 else
2121 {
2122 __postfix_proxy __p(**this);
2123 ++*this;
2124 return __p;
2125 }
2126 }
2127
2128 template<typename _It2, sentinel_for<_It> _Sent2>
2129 requires sentinel_for<_Sent, _It2>
2130 friend constexpr bool
2131 operator== [[nodiscard]] (const common_iterator& __x,
2132 const common_iterator<_It2, _Sent2>& __y)
2133 {
2134 switch(__x._M_index << 2 | __y._M_index)
2135 {
2136 case 0b0000:
2137 case 0b0101:
2138 return true;
2139 case 0b0001:
2140 return __x._M_it == __y._M_sent;
2141 case 0b0100:
2142 return __x._M_sent == __y._M_it;
2143 default:
2144 __glibcxx_assert(__x._M_has_value());
2145 __glibcxx_assert(__y._M_has_value());
2146 __builtin_unreachable();
2147 }
2148 }
2149
2150 template<typename _It2, sentinel_for<_It> _Sent2>
2151 requires sentinel_for<_Sent, _It2> && equality_comparable_with<_It, _It2>
2152 friend constexpr bool
2153 operator== [[nodiscard]] (const common_iterator& __x,
2154 const common_iterator<_It2, _Sent2>& __y)
2155 {
2156 switch(__x._M_index << 2 | __y._M_index)
2157 {
2158 case 0b0101:
2159 return true;
2160 case 0b0000:
2161 return __x._M_it == __y._M_it;
2162 case 0b0001:
2163 return __x._M_it == __y._M_sent;
2164 case 0b0100:
2165 return __x._M_sent == __y._M_it;
2166 default:
2167 __glibcxx_assert(__x._M_has_value());
2168 __glibcxx_assert(__y._M_has_value());
2169 __builtin_unreachable();
2170 }
2171 }
2172
2173 template<sized_sentinel_for<_It> _It2, sized_sentinel_for<_It> _Sent2>
2174 requires sized_sentinel_for<_Sent, _It2>
2175 friend constexpr iter_difference_t<_It2>
2176 operator- [[nodiscard]] (const common_iterator& __x,
2177 const common_iterator<_It2, _Sent2>& __y)
2178 {
2179 switch(__x._M_index << 2 | __y._M_index)
2180 {
2181 case 0b0101:
2182 return 0;
2183 case 0b0000:
2184 return __x._M_it - __y._M_it;
2185 case 0b0001:
2186 return __x._M_it - __y._M_sent;
2187 case 0b0100:
2188 return __x._M_sent - __y._M_it;
2189 default:
2190 __glibcxx_assert(__x._M_has_value());
2191 __glibcxx_assert(__y._M_has_value());
2192 __builtin_unreachable();
2193 }
2194 }
2195
2196 [[nodiscard]]
2197 friend constexpr iter_rvalue_reference_t<_It>
2198 iter_move(const common_iterator& __i)
2199 noexcept(noexcept(ranges::iter_move(std::declval<const _It&>())))
2200 requires input_iterator<_It>
2201 {
2202 __glibcxx_assert(__i._M_index == 0);
2203 return ranges::iter_move(__i._M_it);
2204 }
2205
2206 template<indirectly_swappable<_It> _It2, typename _Sent2>
2207 friend constexpr void
2208 iter_swap(const common_iterator& __x,
2209 const common_iterator<_It2, _Sent2>& __y)
2210 noexcept(noexcept(ranges::iter_swap(std::declval<const _It&>(),
2211 std::declval<const _It2&>())))
2212 {
2213 __glibcxx_assert(__x._M_index == 0);
2214 __glibcxx_assert(__y._M_index == 0);
2215 return ranges::iter_swap(__x._M_it, __y._M_it);
2216 }
2217
2218 private:
2219 template<input_or_output_iterator _It2, sentinel_for<_It2> _Sent2>
2220 requires (!same_as<_It2, _Sent2>) && copyable<_It2>
2221 friend class common_iterator;
2222
2223 constexpr bool
2224 _M_has_value() const noexcept { return _M_index != _S_valueless; }
2225
2226 template<typename _CIt>
2227 constexpr void
2228 _M_assign(_CIt&& __x)
2229 {
2230 if (_M_index == __x._M_index)
2231 {
2232 if (_M_index == 0)
2233 _M_it = std::forward<_CIt>(__x)._M_it;
2234 else if (_M_index == 1)
2235 _M_sent = std::forward<_CIt>(__x)._M_sent;
2236 }
2237 else
2238 {
2239 if (_M_index == 0)
2240 _M_it.~_It();
2241 else if (_M_index == 1)
2242 _M_sent.~_Sent();
2243 _M_index = _S_valueless;
2244
2245 if (__x._M_index == 0)
2246 std::construct_at(std::__addressof(_M_it),
2247 std::forward<_CIt>(__x)._M_it);
2248 else if (__x._M_index == 1)
2249 std::construct_at(std::__addressof(_M_sent),
2250 std::forward<_CIt>(__x)._M_sent);
2251 _M_index = __x._M_index;
2252 }
2253 }
2254
2255 union
2256 {
2257 _It _M_it;
2258 _Sent _M_sent;
2259 unsigned char _M_valueless;
2260 };
2261 unsigned char _M_index; // 0 == _M_it, 1 == _M_sent, 2 == valueless
2262
2263 static constexpr unsigned char _S_valueless{2};
2264 };
2265
2266 template<typename _It, typename _Sent>
2267 struct incrementable_traits<common_iterator<_It, _Sent>>
2268 {
2269 using difference_type = iter_difference_t<_It>;
2270 };
2271
2272 template<input_iterator _It, typename _Sent>
2273 struct iterator_traits<common_iterator<_It, _Sent>>
2274 {
2275 private:
2276 template<typename _Iter>
2277 struct __ptr
2278 {
2279 using type = void;
2280 };
2281
2282 template<typename _Iter>
2283 requires __detail::__common_iter_has_arrow<_Iter>
2284 struct __ptr<_Iter>
2285 {
2286 using _CIter = common_iterator<_Iter, _Sent>;
2287 using type = decltype(std::declval<const _CIter&>().operator->());
2288 };
2289
2290 static auto
2291 _S_iter_cat()
2292 {
2293 if constexpr (requires { requires derived_from<__iter_category_t<_It>,
2294 forward_iterator_tag>; })
2295 return forward_iterator_tag{};
2296 else
2297 return input_iterator_tag{};
2298 }
2299
2300 public:
2301 using iterator_concept = __conditional_t<forward_iterator<_It>,
2302 forward_iterator_tag,
2303 input_iterator_tag>;
2304 using iterator_category = decltype(_S_iter_cat());
2305 using value_type = iter_value_t<_It>;
2306 using difference_type = iter_difference_t<_It>;
2307 using pointer = typename __ptr<_It>::type;
2308 using reference = iter_reference_t<_It>;
2309 };
2310
2311 // [iterators.counted] Counted iterators
2312
2313 namespace __detail
2314 {
2315 template<typename _It>
2316 struct __counted_iter_value_type
2317 { };
2318
2319 template<indirectly_readable _It>
2320 struct __counted_iter_value_type<_It>
2321 { using value_type = iter_value_t<_It>; };
2322
2323 template<typename _It>
2324 struct __counted_iter_concept
2325 { };
2326
2327 template<typename _It>
2328 requires requires { typename _It::iterator_concept; }
2329 struct __counted_iter_concept<_It>
2330 { using iterator_concept = typename _It::iterator_concept; };
2331
2332 template<typename _It>
2333 struct __counted_iter_cat
2334 { };
2335
2336 template<typename _It>
2337 requires requires { typename _It::iterator_category; }
2338 struct __counted_iter_cat<_It>
2339 { using iterator_category = typename _It::iterator_category; };
2340 }
2341
2342 /// An iterator adaptor that keeps track of the distance to the end.
2343 template<input_or_output_iterator _It>
2344 class counted_iterator
2345 : public __detail::__counted_iter_value_type<_It>,
2346 public __detail::__counted_iter_concept<_It>,
2347 public __detail::__counted_iter_cat<_It>
2348 {
2349 public:
2350 using iterator_type = _It;
2351 // value_type defined in __counted_iter_value_type
2352 using difference_type = iter_difference_t<_It>;
2353 // iterator_concept defined in __counted_iter_concept
2354 // iterator_category defined in __counted_iter_cat
2355
2356 constexpr counted_iterator() requires default_initializable<_It> = default;
2357
2358 constexpr
2359 counted_iterator(_It __i, iter_difference_t<_It> __n)
2360 : _M_current(std::move(__i)), _M_length(__n)
2361 { __glibcxx_assert(__n >= 0); }
2362
2363 template<typename _It2>
2364 requires convertible_to<const _It2&, _It>
2365 constexpr
2366 counted_iterator(const counted_iterator<_It2>& __x)
2367 : _M_current(__x._M_current), _M_length(__x._M_length)
2368 { }
2369
2370 template<typename _It2>
2371 requires assignable_from<_It&, const _It2&>
2372 constexpr counted_iterator&
2373 operator=(const counted_iterator<_It2>& __x)
2374 {
2375 _M_current = __x._M_current;
2376 _M_length = __x._M_length;
2377 return *this;
2378 }
2379
2380 [[nodiscard]]
2381 constexpr const _It&
2382 base() const & noexcept
2383 { return _M_current; }
2384
2385 [[nodiscard]]
2386 constexpr _It
2387 base() &&
2388 noexcept(is_nothrow_move_constructible_v<_It>)
2389 { return std::move(_M_current); }
2390
2391 [[nodiscard]]
2392 constexpr iter_difference_t<_It>
2393 count() const noexcept { return _M_length; }
2394
2395 [[nodiscard]]
2396 constexpr decltype(auto)
2397 operator*()
2398 noexcept(noexcept(*_M_current))
2399 {
2400 __glibcxx_assert( _M_length > 0 );
2401 return *_M_current;
2402 }
2403
2404 [[nodiscard]]
2405 constexpr decltype(auto)
2406 operator*() const
2407 noexcept(noexcept(*_M_current))
2408 requires __detail::__dereferenceable<const _It>
2409 {
2410 __glibcxx_assert( _M_length > 0 );
2411 return *_M_current;
2412 }
2413
2414 [[nodiscard]]
2415 constexpr auto
2416 operator->() const noexcept
2417 requires contiguous_iterator<_It>
2418 { return std::to_address(_M_current); }
2419
2420 constexpr counted_iterator&
2421 operator++()
2422 {
2423 __glibcxx_assert(_M_length > 0);
2424 ++_M_current;
2425 --_M_length;
2426 return *this;
2427 }
2428
2429 constexpr decltype(auto)
2430 operator++(int)
2431 {
2432 __glibcxx_assert(_M_length > 0);
2433 --_M_length;
2434 __try
2435 {
2436 return _M_current++;
2437 } __catch(...) {
2438 ++_M_length;
2439 __throw_exception_again;
2440 }
2441 }
2442
2443 constexpr counted_iterator
2444 operator++(int) requires forward_iterator<_It>
2445 {
2446 auto __tmp = *this;
2447 ++*this;
2448 return __tmp;
2449 }
2450
2451 constexpr counted_iterator&
2452 operator--() requires bidirectional_iterator<_It>
2453 {
2454 --_M_current;
2455 ++_M_length;
2456 return *this;
2457 }
2458
2459 constexpr counted_iterator
2460 operator--(int) requires bidirectional_iterator<_It>
2461 {
2462 auto __tmp = *this;
2463 --*this;
2464 return __tmp;
2465 }
2466
2467 [[nodiscard]]
2468 constexpr counted_iterator
2469 operator+(iter_difference_t<_It> __n) const
2470 requires random_access_iterator<_It>
2471 { return counted_iterator(_M_current + __n, _M_length - __n); }
2472
2473 [[nodiscard]]
2474 friend constexpr counted_iterator
2475 operator+(iter_difference_t<_It> __n, const counted_iterator& __x)
2476 requires random_access_iterator<_It>
2477 { return __x + __n; }
2478
2479 constexpr counted_iterator&
2480 operator+=(iter_difference_t<_It> __n)
2481 requires random_access_iterator<_It>
2482 {
2483 __glibcxx_assert(__n <= _M_length);
2484 _M_current += __n;
2485 _M_length -= __n;
2486 return *this;
2487 }
2488
2489 [[nodiscard]]
2490 constexpr counted_iterator
2491 operator-(iter_difference_t<_It> __n) const
2492 requires random_access_iterator<_It>
2493 { return counted_iterator(_M_current - __n, _M_length + __n); }
2494
2495 template<common_with<_It> _It2>
2496 [[nodiscard]]
2497 friend constexpr iter_difference_t<_It2>
2498 operator-(const counted_iterator& __x,
2499 const counted_iterator<_It2>& __y)
2500 { return __y._M_length - __x._M_length; }
2501
2502 [[nodiscard]]
2503 friend constexpr iter_difference_t<_It>
2504 operator-(const counted_iterator& __x, default_sentinel_t)
2505 { return -__x._M_length; }
2506
2507 [[nodiscard]]
2508 friend constexpr iter_difference_t<_It>
2509 operator-(default_sentinel_t, const counted_iterator& __y)
2510 { return __y._M_length; }
2511
2512 constexpr counted_iterator&
2513 operator-=(iter_difference_t<_It> __n)
2514 requires random_access_iterator<_It>
2515 {
2516 __glibcxx_assert(-__n <= _M_length);
2517 _M_current -= __n;
2518 _M_length += __n;
2519 return *this;
2520 }
2521
2522 [[nodiscard]]
2523 constexpr decltype(auto)
2524 operator[](iter_difference_t<_It> __n) const
2525 noexcept(noexcept(_M_current[__n]))
2526 requires random_access_iterator<_It>
2527 {
2528 __glibcxx_assert(__n < _M_length);
2529 return _M_current[__n];
2530 }
2531
2532 template<common_with<_It> _It2>
2533 [[nodiscard]]
2534 friend constexpr bool
2535 operator==(const counted_iterator& __x,
2536 const counted_iterator<_It2>& __y)
2537 { return __x._M_length == __y._M_length; }
2538
2539 [[nodiscard]]
2540 friend constexpr bool
2541 operator==(const counted_iterator& __x, default_sentinel_t)
2542 { return __x._M_length == 0; }
2543
2544 template<common_with<_It> _It2>
2545 [[nodiscard]]
2546 friend constexpr strong_ordering
2547 operator<=>(const counted_iterator& __x,
2548 const counted_iterator<_It2>& __y)
2549 { return __y._M_length <=> __x._M_length; }
2550
2551 [[nodiscard]]
2552 friend constexpr iter_rvalue_reference_t<_It>
2553 iter_move(const counted_iterator& __i)
2554 noexcept(noexcept(ranges::iter_move(__i._M_current)))
2555 requires input_iterator<_It>
2556 {
2557 __glibcxx_assert( __i._M_length > 0 );
2558 return ranges::iter_move(__i._M_current);
2559 }
2560
2561 template<indirectly_swappable<_It> _It2>
2562 friend constexpr void
2563 iter_swap(const counted_iterator& __x,
2564 const counted_iterator<_It2>& __y)
2565 noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
2566 {
2567 __glibcxx_assert( __x._M_length > 0 && __y._M_length > 0 );
2568 ranges::iter_swap(__x._M_current, __y._M_current);
2569 }
2570
2571 private:
2572 template<input_or_output_iterator _It2> friend class counted_iterator;
2573
2574 _It _M_current = _It();
2575 iter_difference_t<_It> _M_length = 0;
2576 };
2577
2578 template<input_iterator _It>
2579 requires same_as<__detail::__iter_traits<_It>, iterator_traits<_It>>
2580 struct iterator_traits<counted_iterator<_It>> : iterator_traits<_It>
2581 {
2582 using pointer = __conditional_t<contiguous_iterator<_It>,
2583 add_pointer_t<iter_reference_t<_It>>,
2584 void>;
2585 };
2586
2587 #if __cplusplus > 202020L
2588 template<indirectly_readable _It>
2589 using iter_const_reference_t
2590 = common_reference_t<const iter_value_t<_It>&&, iter_reference_t<_It>>;
2591
2592 template<input_iterator _It> class basic_const_iterator;
2593
2594 namespace __detail
2595 {
2596 template<typename _It>
2597 concept __constant_iterator = input_iterator<_It>
2598 && same_as<iter_const_reference_t<_It>, iter_reference_t<_It>>;
2599
2600 template<typename _Tp>
2601 inline constexpr bool __is_const_iterator = false;
2602
2603 template<typename _It>
2604 inline constexpr bool __is_const_iterator<basic_const_iterator<_It>> = true;
2605
2606 template<typename _Tp>
2607 concept __not_a_const_iterator = !__is_const_iterator<_Tp>;
2608
2609 template<indirectly_readable _It>
2610 using __iter_const_rvalue_reference_t
2611 = common_reference_t<const iter_value_t<_It>&&, iter_rvalue_reference_t<_It>>;
2612
2613 template<typename _It>
2614 struct __basic_const_iterator_iter_cat
2615 { };
2616
2617 template<forward_iterator _It>
2618 struct __basic_const_iterator_iter_cat<_It>
2619 { using iterator_category = __iter_category_t<_It>; };
2620 } // namespace detail
2621
2622 template<input_iterator _It>
2623 using const_iterator
2624 = __conditional_t<__detail::__constant_iterator<_It>, _It, basic_const_iterator<_It>>;
2625
2626 namespace __detail
2627 {
2628 template<typename _Sent>
2629 struct __const_sentinel
2630 { using type = _Sent; };
2631
2632 template<input_iterator _Sent>
2633 struct __const_sentinel<_Sent>
2634 { using type = const_iterator<_Sent>; };
2635 } // namespace __detail
2636
2637 template<semiregular _Sent>
2638 using const_sentinel = typename __detail::__const_sentinel<_Sent>::type;
2639
2640 template<input_iterator _It>
2641 class basic_const_iterator
2642 : public __detail::__basic_const_iterator_iter_cat<_It>
2643 {
2644 _It _M_current = _It();
2645 using __reference = iter_const_reference_t<_It>;
2646 using __rvalue_reference = __detail::__iter_const_rvalue_reference_t<_It>;
2647
2648 static auto
2649 _S_iter_concept()
2650 {
2651 if constexpr (contiguous_iterator<_It>)
2652 return contiguous_iterator_tag{};
2653 else if constexpr (random_access_iterator<_It>)
2654 return random_access_iterator_tag{};
2655 else if constexpr (bidirectional_iterator<_It>)
2656 return bidirectional_iterator_tag{};
2657 else if constexpr (forward_iterator<_It>)
2658 return forward_iterator_tag{};
2659 else
2660 return input_iterator_tag{};
2661 }
2662
2663 template<input_iterator _It2> friend class basic_const_iterator;
2664
2665 public:
2666 using iterator_concept = decltype(_S_iter_concept());
2667 using value_type = iter_value_t<_It>;
2668 using difference_type = iter_difference_t<_It>;
2669
2670 basic_const_iterator() requires default_initializable<_It> = default;
2671
2672 constexpr
2673 basic_const_iterator(_It __current)
2674 noexcept(is_nothrow_move_constructible_v<_It>)
2675 : _M_current(std::move(__current))
2676 { }
2677
2678 template<convertible_to<_It> _It2>
2679 constexpr
2680 basic_const_iterator(basic_const_iterator<_It2> __current)
2681 noexcept(is_nothrow_constructible_v<_It, _It2>)
2682 : _M_current(std::move(__current._M_current))
2683 { }
2684
2685 template<__detail::__different_from<basic_const_iterator> _Tp>
2686 requires convertible_to<_Tp, _It>
2687 constexpr
2688 basic_const_iterator(_Tp&& __current)
2689 noexcept(is_nothrow_constructible_v<_It, _Tp>)
2690 : _M_current(std::forward<_Tp>(__current))
2691 { }
2692
2693 constexpr const _It&
2694 base() const & noexcept
2695 { return _M_current; }
2696
2697 constexpr _It
2698 base() &&
2699 noexcept(is_nothrow_move_constructible_v<_It>)
2700 { return std::move(_M_current); }
2701
2702 constexpr __reference
2703 operator*() const
2704 noexcept(noexcept(static_cast<__reference>(*_M_current)))
2705 { return static_cast<__reference>(*_M_current); }
2706
2707 constexpr const auto*
2708 operator->() const
2709 noexcept(contiguous_iterator<_It> || noexcept(*_M_current))
2710 requires is_lvalue_reference_v<iter_reference_t<_It>>
2711 && same_as<remove_cvref_t<iter_reference_t<_It>>, value_type>
2712 {
2713 if constexpr (contiguous_iterator<_It>)
2714 return std::to_address(_M_current);
2715 else
2716 return std::__addressof(*_M_current);
2717 }
2718
2719 constexpr basic_const_iterator&
2720 operator++()
2721 noexcept(noexcept(++_M_current))
2722 {
2723 ++_M_current;
2724 return *this;
2725 }
2726
2727 constexpr void
2728 operator++(int)
2729 noexcept(noexcept(++_M_current))
2730 { ++_M_current; }
2731
2732 constexpr basic_const_iterator
2733 operator++(int)
2734 noexcept(noexcept(++*this) && is_nothrow_copy_constructible_v<basic_const_iterator>)
2735 requires forward_iterator<_It>
2736 {
2737 auto __tmp = *this;
2738 ++*this;
2739 return __tmp;
2740 }
2741
2742 constexpr basic_const_iterator&
2743 operator--()
2744 noexcept(noexcept(--_M_current))
2745 requires bidirectional_iterator<_It>
2746 {
2747 --_M_current;
2748 return *this;
2749 }
2750
2751 constexpr basic_const_iterator
2752 operator--(int)
2753 noexcept(noexcept(--*this) && is_nothrow_copy_constructible_v<basic_const_iterator>)
2754 requires bidirectional_iterator<_It>
2755 {
2756 auto __tmp = *this;
2757 --*this;
2758 return __tmp;
2759 }
2760
2761 constexpr basic_const_iterator&
2762 operator+=(difference_type __n)
2763 noexcept(noexcept(_M_current += __n))
2764 requires random_access_iterator<_It>
2765 {
2766 _M_current += __n;
2767 return *this;
2768 }
2769
2770 constexpr basic_const_iterator&
2771 operator-=(difference_type __n)
2772 noexcept(noexcept(_M_current -= __n))
2773 requires random_access_iterator<_It>
2774 {
2775 _M_current -= __n;
2776 return *this;
2777 }
2778
2779 constexpr __reference
2780 operator[](difference_type __n) const
2781 noexcept(noexcept(static_cast<__reference>(_M_current[__n])))
2782 requires random_access_iterator<_It>
2783 { return static_cast<__reference>(_M_current[__n]); }
2784
2785 template<sentinel_for<_It> _Sent>
2786 constexpr bool
2787 operator==(const _Sent& __s) const
2788 noexcept(noexcept(_M_current == __s))
2789 { return _M_current == __s; }
2790
2791 constexpr bool
2792 operator<(const basic_const_iterator& __y) const
2793 noexcept(noexcept(_M_current < __y._M_current))
2794 requires random_access_iterator<_It>
2795 { return _M_current < __y._M_current; }
2796
2797 constexpr bool
2798 operator>(const basic_const_iterator& __y) const
2799 noexcept(noexcept(_M_current > __y._M_current))
2800 requires random_access_iterator<_It>
2801 { return _M_current > __y._M_current; }
2802
2803 constexpr bool
2804 operator<=(const basic_const_iterator& __y) const
2805 noexcept(noexcept(_M_current <= __y._M_current))
2806 requires random_access_iterator<_It>
2807 { return _M_current <= __y._M_current; }
2808
2809 constexpr bool
2810 operator>=(const basic_const_iterator& __y) const
2811 noexcept(noexcept(_M_current >= __y._M_current))
2812 requires random_access_iterator<_It>
2813 { return _M_current >= __y._M_current; }
2814
2815 constexpr auto
2816 operator<=>(const basic_const_iterator& __y) const
2817 noexcept(noexcept(_M_current <=> __y._M_current))
2818 requires random_access_iterator<_It> && three_way_comparable<_It>
2819 { return _M_current <=> __y._M_current; }
2820
2821 template<__detail::__different_from<basic_const_iterator> _It2>
2822 constexpr bool
2823 operator<(const _It2& __y) const
2824 noexcept(noexcept(_M_current < __y))
2825 requires random_access_iterator<_It> && totally_ordered_with<_It, _It2>
2826 { return _M_current < __y; }
2827
2828 template<__detail::__different_from<basic_const_iterator> _It2>
2829 constexpr bool
2830 operator>(const _It2& __y) const
2831 noexcept(noexcept(_M_current > __y))
2832 requires random_access_iterator<_It> && totally_ordered_with<_It, _It2>
2833 { return _M_current > __y; }
2834
2835 template<__detail::__different_from<basic_const_iterator> _It2>
2836 constexpr bool
2837 operator<=(const _It2& __y) const
2838 noexcept(noexcept(_M_current <= __y))
2839 requires random_access_iterator<_It> && totally_ordered_with<_It, _It2>
2840 { return _M_current <= __y; }
2841
2842 template<__detail::__different_from<basic_const_iterator> _It2>
2843 constexpr bool
2844 operator>=(const _It2& __y) const
2845 noexcept(noexcept(_M_current >= __y))
2846 requires random_access_iterator<_It> && totally_ordered_with<_It, _It2>
2847 { return _M_current >= __y; }
2848
2849 template<__detail::__different_from<basic_const_iterator> _It2>
2850 constexpr auto
2851 operator<=>(const _It2& __y) const
2852 noexcept(noexcept(_M_current <=> __y))
2853 requires random_access_iterator<_It> && totally_ordered_with<_It, _It2>
2854 && three_way_comparable_with<_It, _It2>
2855 { return _M_current <=> __y; }
2856
2857 template<__detail::__not_a_const_iterator _It2>
2858 friend constexpr bool
2859 operator<(const _It2& __x, const basic_const_iterator& __y)
2860 noexcept(noexcept(__x < __y._M_current))
2861 requires random_access_iterator<_It> && totally_ordered_with<_It, _It2>
2862 { return __x < __y._M_current; }
2863
2864 template<__detail::__not_a_const_iterator _It2>
2865 friend constexpr bool
2866 operator>(const _It2& __x, const basic_const_iterator& __y)
2867 noexcept(noexcept(__x > __y._M_current))
2868 requires random_access_iterator<_It> && totally_ordered_with<_It, _It2>
2869 { return __x > __y._M_current; }
2870
2871 template<__detail::__not_a_const_iterator _It2>
2872 friend constexpr bool
2873 operator<=(const _It2& __x, const basic_const_iterator& __y)
2874 noexcept(noexcept(__x <= __y._M_current))
2875 requires random_access_iterator<_It> && totally_ordered_with<_It, _It2>
2876 { return __x <= __y._M_current; }
2877
2878 template<__detail::__not_a_const_iterator _It2>
2879 friend constexpr bool
2880 operator>=(const _It2& __x, const basic_const_iterator& __y)
2881 noexcept(noexcept(__x >= __y._M_current))
2882 requires random_access_iterator<_It> && totally_ordered_with<_It, _It2>
2883 { return __x >= __y._M_current; }
2884
2885 friend constexpr basic_const_iterator
2886 operator+(const basic_const_iterator& __i, difference_type __n)
2887 noexcept(noexcept(basic_const_iterator(__i._M_current + __n)))
2888 requires random_access_iterator<_It>
2889 { return basic_const_iterator(__i._M_current + __n); }
2890
2891 friend constexpr basic_const_iterator
2892 operator+(difference_type __n, const basic_const_iterator& __i)
2893 noexcept(noexcept(basic_const_iterator(__i._M_current + __n)))
2894 requires random_access_iterator<_It>
2895 { return basic_const_iterator(__i._M_current + __n); }
2896
2897 friend constexpr basic_const_iterator
2898 operator-(const basic_const_iterator& __i, difference_type __n)
2899 noexcept(noexcept(basic_const_iterator(__i._M_current - __n)))
2900 requires random_access_iterator<_It>
2901 { return basic_const_iterator(__i._M_current - __n); }
2902
2903 template<sized_sentinel_for<_It> _Sent>
2904 constexpr difference_type
2905 operator-(const _Sent& __y) const
2906 noexcept(noexcept(_M_current - __y))
2907 { return _M_current - __y; }
2908
2909 template<__detail::__not_a_const_iterator _Sent>
2910 requires sized_sentinel_for<_Sent, _It>
2911 friend constexpr difference_type
2912 operator-(const _Sent& __x, const basic_const_iterator& __y)
2913 noexcept(noexcept(__x - __y._M_current))
2914 { return __x - __y._M_current; }
2915
2916 friend constexpr __rvalue_reference
2917 iter_move(const basic_const_iterator& __i)
2918 noexcept(noexcept(static_cast<__rvalue_reference>(ranges::iter_move(__i._M_current))))
2919 { return static_cast<__rvalue_reference>(ranges::iter_move(__i._M_current)); }
2920 };
2921
2922 template<typename _Tp, common_with<_Tp> _Up>
2923 requires input_iterator<common_type_t<_Tp, _Up>>
2924 struct common_type<basic_const_iterator<_Tp>, _Up>
2925 { using type = basic_const_iterator<common_type_t<_Tp, _Up>>; };
2926
2927 template<typename _Tp, common_with<_Tp> _Up>
2928 requires input_iterator<common_type_t<_Tp, _Up>>
2929 struct common_type<_Up, basic_const_iterator<_Tp>>
2930 { using type = basic_const_iterator<common_type_t<_Tp, _Up>>; };
2931
2932 template<typename _Tp, common_with<_Tp> _Up>
2933 requires input_iterator<common_type_t<_Tp, _Up>>
2934 struct common_type<basic_const_iterator<_Tp>, basic_const_iterator<_Up>>
2935 { using type = basic_const_iterator<common_type_t<_Tp, _Up>>; };
2936
2937 template<input_iterator _It>
2938 constexpr const_iterator<_It>
2939 make_const_iterator(_It __it)
2940 noexcept(is_nothrow_convertible_v<_It, const_iterator<_It>>)
2941 { return __it; }
2942
2943 template<semiregular _Sent>
2944 constexpr const_sentinel<_Sent>
2945 make_const_sentinel(_Sent __s)
2946 noexcept(is_nothrow_convertible_v<_Sent, const_sentinel<_Sent>>)
2947 { return __s; }
2948 #endif // C++23
2949 #endif // C++20
2950
2951 /// @} group iterators
2952
2953 template<typename _Iterator>
2954 _GLIBCXX20_CONSTEXPR
2955 auto
2956 __niter_base(move_iterator<_Iterator> __it)
2957 -> decltype(make_move_iterator(__niter_base(__it.base())))
2958 { return make_move_iterator(__niter_base(__it.base())); }
2959
2960 template<typename _Iterator>
2961 struct __is_move_iterator<move_iterator<_Iterator> >
2962 {
2963 enum { __value = 1 };
2964 typedef __true_type __type;
2965 };
2966
2967 template<typename _Iterator>
2968 _GLIBCXX20_CONSTEXPR
2969 auto
2970 __miter_base(move_iterator<_Iterator> __it)
2971 -> decltype(__miter_base(__it.base()))
2972 { return __miter_base(__it.base()); }
2973
2974 #define _GLIBCXX_MAKE_MOVE_ITERATOR(_Iter) std::make_move_iterator(_Iter)
2975 #define _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(_Iter) \
2976 std::__make_move_if_noexcept_iterator(_Iter)
2977 #else
2978 #define _GLIBCXX_MAKE_MOVE_ITERATOR(_Iter) (_Iter)
2979 #define _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(_Iter) (_Iter)
2980 #endif // C++11
2981
2982 #if __cpp_deduction_guides >= 201606
2983 // These helper traits are used for deduction guides
2984 // of associative containers.
2985 template<typename _InputIterator>
2986 using __iter_key_t = remove_const_t<
2987 typename iterator_traits<_InputIterator>::value_type::first_type>;
2988
2989 template<typename _InputIterator>
2990 using __iter_val_t
2991 = typename iterator_traits<_InputIterator>::value_type::second_type;
2992
2993 template<typename _T1, typename _T2>
2994 struct pair;
2995
2996 template<typename _InputIterator>
2997 using __iter_to_alloc_t
2998 = pair<const __iter_key_t<_InputIterator>, __iter_val_t<_InputIterator>>;
2999 #endif // __cpp_deduction_guides
3000
3001 _GLIBCXX_END_NAMESPACE_VERSION
3002 } // namespace
3003
3004 #ifdef _GLIBCXX_DEBUG
3005 # include <debug/stl_iterator.h>
3006 #endif
3007
3008 #endif
This page took 0.241272 seconds and 5 git commands to generate.