1 // Iterators -*- C++ -*-
3 // Copyright (C) 2001-2023 Free Software Foundation, Inc.
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)
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.
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.
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/>.
28 * Hewlett-Packard Company
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.
39 * Copyright (c) 1996-1998
40 * Silicon Graphics Computer Systems, Inc.
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.
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}
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.
60 #ifndef _STL_ITERATOR_H
61 #define _STL_ITERATOR_H 1
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>
69 #if __cplusplus >= 201103L
70 # include <type_traits>
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
80 #if __cplusplus >= 202002L
83 # include <bits/exception_defines.h>
84 # include <bits/iterator_concepts.h>
85 # include <bits/stl_construct.h>
88 namespace std
_GLIBCXX_VISIBILITY(default)
90 _GLIBCXX_BEGIN_NAMESPACE_VERSION
93 * @addtogroup iterators
97 #if __cpp_lib_concepts
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
>;
106 template<typename _Iter
, typename _Limit
>
107 using __clamped_iter_cat_t
108 = __clamp_iter_cat
<__iter_category_t
<_Iter
>, _Limit
>;
110 template<typename _Tp
, typename _Up
>
111 concept __different_from
112 = !same_as
<remove_cvref_t
<_Tp
>, remove_cvref_t
<_Up
>>;
116 // Ignore warnings about std::iterator.
117 #pragma GCC diagnostic push
118 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
120 // 24.4.1 Reverse iterators
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:
128 * &*(reverse_iterator(i)) == &*(i - 1)
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
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.
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
>
147 template<typename _Iter
>
148 friend class reverse_iterator
;
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
>;
161 typedef iterator_traits
<_Iterator
> __traits_type
;
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
;
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
>;
182 * The default constructor value-initializes member @p current.
183 * If it is a pointer, that means it is zero-initialized.
185 // _GLIBCXX_RESOLVE_LIB_DEFECTS
186 // 235 No specification of default ctor for reverse_iterator
187 // 1012. reverse_iterator default ctor should value initialize
190 _GLIBCXX_NOEXCEPT_IF(noexcept(_Iterator()))
195 * This %iterator will move in the opposite direction that @p x does.
197 explicit _GLIBCXX17_CONSTEXPR
198 reverse_iterator(iterator_type __x
)
199 _GLIBCXX_NOEXCEPT_IF(noexcept(_Iterator(__x
)))
204 * The copy constructor is normal.
207 reverse_iterator(const reverse_iterator
& __x
)
208 _GLIBCXX_NOEXCEPT_IF(noexcept(_Iterator(__x
.current
)))
209 : current(__x
.current
)
212 #if __cplusplus >= 201103L
213 reverse_iterator
& operator=(const reverse_iterator
&) = default;
217 * A %reverse_iterator across other types can be copied if the
218 * underlying %iterator can be converted to the type of @c current.
220 template<typename _Iter
>
221 #if __cpp_lib_concepts
222 requires __convertible
<_Iter
>
225 reverse_iterator(const reverse_iterator
<_Iter
>& __x
)
226 _GLIBCXX_NOEXCEPT_IF(noexcept(_Iterator(__x
.current
)))
227 : current(__x
.current
)
230 #if __cplusplus >= 201103L
231 template<typename _Iter
>
232 #if __cpp_lib_concepts
233 requires __convertible
<_Iter
>
234 && assignable_from
<_Iterator
&, const _Iter
&>
238 operator=(const reverse_iterator
<_Iter
>& __x
)
239 _GLIBCXX_NOEXCEPT_IF(noexcept(current
= __x
.current
))
241 current
= __x
.current
;
247 * @return @c current, the %iterator used for underlying work.
250 _GLIBCXX17_CONSTEXPR iterator_type
252 _GLIBCXX_NOEXCEPT_IF(noexcept(_Iterator(current
)))
256 * @return A reference to the value at @c --current
258 * This requires that @c --current is dereferenceable.
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
266 _GLIBCXX17_CONSTEXPR reference
269 _Iterator __tmp
= current
;
274 * @return A pointer to the value at @c --current
276 * This requires that @c --current is dereferenceable.
279 _GLIBCXX17_CONSTEXPR pointer
281 #if __cplusplus > 201703L && __cpp_concepts >= 201907L
282 requires is_pointer_v
<_Iterator
>
283 || requires(const _Iterator __i
) { __i
.operator->(); }
286 // _GLIBCXX_RESOLVE_LIB_DEFECTS
287 // 1052. operator-> should also support smart pointers
288 _Iterator __tmp
= current
;
290 return _S_to_pointer(__tmp
);
296 * Decrements the underlying iterator.
298 _GLIBCXX17_CONSTEXPR reverse_iterator
&
306 * @return The original value of @c *this
308 * Decrements the underlying iterator.
310 _GLIBCXX17_CONSTEXPR reverse_iterator
313 reverse_iterator __tmp
= *this;
321 * Increments the underlying iterator.
323 _GLIBCXX17_CONSTEXPR reverse_iterator
&
331 * @return A reverse_iterator with the previous value of @c *this
333 * Increments the underlying iterator.
335 _GLIBCXX17_CONSTEXPR reverse_iterator
338 reverse_iterator __tmp
= *this;
344 * @return A reverse_iterator that refers to @c current - @a __n
346 * The underlying iterator must be a Random Access Iterator.
349 _GLIBCXX17_CONSTEXPR reverse_iterator
350 operator+(difference_type __n
) const
351 { return reverse_iterator(current
- __n
); }
356 * Moves the underlying iterator backwards @a __n steps.
357 * The underlying iterator must be a Random Access Iterator.
359 _GLIBCXX17_CONSTEXPR reverse_iterator
&
360 operator+=(difference_type __n
)
367 * @return A reverse_iterator that refers to @c current - @a __n
369 * The underlying iterator must be a Random Access Iterator.
372 _GLIBCXX17_CONSTEXPR reverse_iterator
373 operator-(difference_type __n
) const
374 { return reverse_iterator(current
+ __n
); }
379 * Moves the underlying iterator forwards @a __n steps.
380 * The underlying iterator must be a Random Access Iterator.
382 _GLIBCXX17_CONSTEXPR reverse_iterator
&
383 operator-=(difference_type __n
)
390 * @return The value at @c current - @a __n - 1
392 * The underlying iterator must be a Random Access Iterator.
395 _GLIBCXX17_CONSTEXPR reference
396 operator[](difference_type __n
) const
397 { return *(*this + __n
); }
399 #if __cplusplus > 201703L && __cpp_lib_concepts
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
&>())))
406 auto __tmp
= __i
.base();
407 return ranges::iter_move(--__tmp
);
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
&>())))
419 auto __xtmp
= __x
.base();
420 auto __ytmp
= __y
.base();
421 ranges::iter_swap(--__xtmp
, --__ytmp
);
426 template<typename _Tp
>
427 static _GLIBCXX17_CONSTEXPR _Tp
*
428 _S_to_pointer(_Tp
* __p
)
431 template<typename _Tp
>
432 static _GLIBCXX17_CONSTEXPR pointer
433 _S_to_pointer(_Tp __t
)
434 { return __t
.operator->(); }
439 * @param __x A %reverse_iterator.
440 * @param __y A %reverse_iterator.
441 * @return A simple bool.
443 * Reverse iterators forward comparisons to their underlying base()
447 #if __cplusplus <= 201703L || ! defined __cpp_lib_concepts
448 template<typename _Iterator
>
450 inline _GLIBCXX17_CONSTEXPR
bool
451 operator==(const reverse_iterator
<_Iterator
>& __x
,
452 const reverse_iterator
<_Iterator
>& __y
)
453 { return __x
.base() == __y
.base(); }
455 template<typename _Iterator
>
457 inline _GLIBCXX17_CONSTEXPR
bool
458 operator<(const reverse_iterator
<_Iterator
>& __x
,
459 const reverse_iterator
<_Iterator
>& __y
)
460 { return __y
.base() < __x
.base(); }
462 template<typename _Iterator
>
464 inline _GLIBCXX17_CONSTEXPR
bool
465 operator!=(const reverse_iterator
<_Iterator
>& __x
,
466 const reverse_iterator
<_Iterator
>& __y
)
467 { return !(__x
== __y
); }
469 template<typename _Iterator
>
471 inline _GLIBCXX17_CONSTEXPR
bool
472 operator>(const reverse_iterator
<_Iterator
>& __x
,
473 const reverse_iterator
<_Iterator
>& __y
)
474 { return __y
< __x
; }
476 template<typename _Iterator
>
478 inline _GLIBCXX17_CONSTEXPR
bool
479 operator<=(const reverse_iterator
<_Iterator
>& __x
,
480 const reverse_iterator
<_Iterator
>& __y
)
481 { return !(__y
< __x
); }
483 template<typename _Iterator
>
485 inline _GLIBCXX17_CONSTEXPR
bool
486 operator>=(const reverse_iterator
<_Iterator
>& __x
,
487 const reverse_iterator
<_Iterator
>& __y
)
488 { return !(__x
< __y
); }
490 // _GLIBCXX_RESOLVE_LIB_DEFECTS
491 // DR 280. Comparison of reverse_iterator to const reverse_iterator.
493 template<typename _IteratorL
, typename _IteratorR
>
495 inline _GLIBCXX17_CONSTEXPR
bool
496 operator==(const reverse_iterator
<_IteratorL
>& __x
,
497 const reverse_iterator
<_IteratorR
>& __y
)
498 { return __x
.base() == __y
.base(); }
500 template<typename _IteratorL
, typename _IteratorR
>
502 inline _GLIBCXX17_CONSTEXPR
bool
503 operator<(const reverse_iterator
<_IteratorL
>& __x
,
504 const reverse_iterator
<_IteratorR
>& __y
)
505 { return __x
.base() > __y
.base(); }
507 template<typename _IteratorL
, typename _IteratorR
>
509 inline _GLIBCXX17_CONSTEXPR
bool
510 operator!=(const reverse_iterator
<_IteratorL
>& __x
,
511 const reverse_iterator
<_IteratorR
>& __y
)
512 { return __x
.base() != __y
.base(); }
514 template<typename _IteratorL
, typename _IteratorR
>
516 inline _GLIBCXX17_CONSTEXPR
bool
517 operator>(const reverse_iterator
<_IteratorL
>& __x
,
518 const reverse_iterator
<_IteratorR
>& __y
)
519 { return __x
.base() < __y
.base(); }
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(); }
527 template<typename _IteratorL
, typename _IteratorR
>
529 inline _GLIBCXX17_CONSTEXPR
bool
530 operator>=(const reverse_iterator
<_IteratorL
>& __x
,
531 const reverse_iterator
<_IteratorR
>& __y
)
532 { return __x
.base() <= __y
.base(); }
534 template<typename _IteratorL
, typename _IteratorR
>
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(); }
542 template<typename _IteratorL
, typename _IteratorR
>
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(); }
550 template<typename _IteratorL
, typename _IteratorR
>
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(); }
558 template<typename _IteratorL
, typename _IteratorR
>
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(); }
566 template<typename _IteratorL
, typename _IteratorR
>
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(); }
574 template<typename _IteratorL
, typename _IteratorR
>
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(); }
582 template<typename _IteratorL
,
583 three_way_comparable_with
<_IteratorL
> _IteratorR
>
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(); }
590 // Additional, non-standard overloads to avoid ambiguities with greedy,
591 // unconstrained overloads in associated namespaces.
593 template<typename _Iterator
>
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(); }
601 template<three_way_comparable _Iterator
>
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(); }
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(); }
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(); }
623 // _GLIBCXX_RESOLVE_LIB_DEFECTS
624 // DR 685. reverse_iterator/move_iterator difference has invalid signatures
625 template<typename _IteratorL
, typename _IteratorR
>
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(); }
634 template<typename _Iterator
>
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
); }
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
); }
648 # if __cplusplus >= 201402L
649 # define __cpp_lib_make_reverse_iterator 201402L
651 // _GLIBCXX_RESOLVE_LIB_DEFECTS
652 // DR 2285. make_reverse_iterator
653 /// Generator function for reverse_iterator.
654 template<typename _Iterator
>
656 inline _GLIBCXX17_CONSTEXPR reverse_iterator
<_Iterator
>
657 make_reverse_iterator(_Iterator __i
)
658 { return reverse_iterator
<_Iterator
>(__i
); }
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;
669 template<typename _Iterator
>
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())); }
676 template<typename _Iterator
>
677 struct __is_move_iterator
<reverse_iterator
<_Iterator
> >
678 : __is_move_iterator
<_Iterator
>
681 template<typename _Iterator
>
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())); }
689 // 24.4.2.2.1 back_insert_iterator
691 * @brief Turns assignment into insertion.
693 * These are output iterators, constructed from a container-of-T.
694 * Assigning a T to the iterator appends it to the container using
697 * Tip: Using the back_inserter function to create these iterators can
700 template<typename _Container
>
701 class back_insert_iterator
702 : public iterator
<output_iterator_tag
, void, void, void, void>
705 _Container
* container
;
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;
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
)) { }
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.
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.
730 #if __cplusplus < 201103L
731 back_insert_iterator
&
732 operator=(typename
_Container::const_reference __value
)
734 container
->push_back(__value
);
739 back_insert_iterator
&
740 operator=(const typename
_Container::value_type
& __value
)
742 container
->push_back(__value
);
747 back_insert_iterator
&
748 operator=(typename
_Container::value_type
&& __value
)
750 container
->push_back(std::move(__value
));
755 /// Simply returns *this.
756 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
757 back_insert_iterator
&
761 /// Simply returns *this. (This %iterator does not @a move.)
763 back_insert_iterator
&
767 /// Simply returns *this. (This %iterator does not @a move.)
775 * @param __x A container of arbitrary type.
776 * @return An instance of back_insert_iterator working on @p __x.
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
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
); }
792 * @brief Turns assignment into insertion.
794 * These are output iterators, constructed from a container-of-T.
795 * Assigning a T to the iterator prepends it to the container using
798 * Tip: Using the front_inserter function to create these iterators can
801 template<typename _Container
>
802 class front_insert_iterator
803 : public iterator
<output_iterator_tag
, void, void, void, void>
806 _Container
* container
;
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;
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
)) { }
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.
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.
831 #if __cplusplus < 201103L
832 front_insert_iterator
&
833 operator=(typename
_Container::const_reference __value
)
835 container
->push_front(__value
);
840 front_insert_iterator
&
841 operator=(const typename
_Container::value_type
& __value
)
843 container
->push_front(__value
);
848 front_insert_iterator
&
849 operator=(typename
_Container::value_type
&& __value
)
851 container
->push_front(std::move(__value
));
856 /// Simply returns *this.
857 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
858 front_insert_iterator
&
862 /// Simply returns *this. (This %iterator does not @a move.)
864 front_insert_iterator
&
868 /// Simply returns *this. (This %iterator does not @a move.)
870 front_insert_iterator
876 * @param __x A container of arbitrary type.
877 * @return An instance of front_insert_iterator working on @p x.
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
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
); }
893 * @brief Turns assignment into insertion.
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
900 * (Sequences will actually insert a @e copy of the value before the
901 * %iterator's position.)
903 * Tip: Using the inserter function to create these iterators can
906 template<typename _Container
>
907 class insert_iterator
908 : public iterator
<output_iterator_tag
, void, void, void, void>
910 #if __cplusplus > 201703L && defined __cpp_lib_concepts
911 using _Iter
= std::__detail::__range_iter_t
<_Container
>;
913 typedef typename
_Container::iterator _Iter
;
916 _Container
* container
;
920 /// A nested typedef for the type of whatever container you used.
921 typedef _Container container_type
;
923 #if __cplusplus > 201703L && defined __cpp_lib_concepts
924 using difference_type
= ptrdiff_t;
928 * The only way to create this %iterator is with a container and an
929 * initial position (a normal %iterator into the container).
932 insert_iterator(_Container
& __x
, _Iter __i
)
933 : container(std::__addressof(__x
)), iter(__i
) {}
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.
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.
945 * The position is maintained such that subsequent assignments will
946 * insert values immediately after one another. For example,
948 * // vector v contains A and Z
950 * insert_iterator i (v, ++v.begin());
955 * // vector v contains A, 1, 2, 3, and Z
958 #if __cplusplus < 201103L
960 operator=(typename
_Container::const_reference __value
)
962 iter
= container
->insert(iter
, __value
);
969 operator=(const typename
_Container::value_type
& __value
)
971 iter
= container
->insert(iter
, __value
);
978 operator=(typename
_Container::value_type
&& __value
)
980 iter
= container
->insert(iter
, std::move(__value
));
986 /// Simply returns *this.
987 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
992 /// Simply returns *this. (This %iterator does not @a move.)
998 /// Simply returns *this. (This %iterator does not @a move.)
1005 #pragma GCC diagnostic pop
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.
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
1019 #if __cplusplus > 201703L && defined __cpp_lib_concepts
1020 template<typename _Container
>
1022 constexpr insert_iterator
<_Container
>
1023 inserter(_Container
& __x
, std::__detail::__range_iter_t
<_Container
> __i
)
1024 { return insert_iterator
<_Container
>(__x
, __i
); }
1026 template<typename _Container
>
1028 inline insert_iterator
<_Container
>
1029 inserter(_Container
& __x
, typename
_Container::iterator __i
)
1030 { return insert_iterator
<_Container
>(__x
, __i
); }
1033 /// @} group iterators
1035 _GLIBCXX_END_NAMESPACE_VERSION
1038 namespace __gnu_cxx
_GLIBCXX_VISIBILITY(default)
1040 _GLIBCXX_BEGIN_NAMESPACE_VERSION
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
1053 _Iterator _M_current
;
1055 typedef std::iterator_traits
<_Iterator
> __traits_type
;
1057 #if __cplusplus >= 201103L
1058 template<typename _Iter
>
1059 using __convertible_from
1060 = std::__enable_if_t
<std::is_convertible
<_Iter
, _Iterator
>::value
>;
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
;
1071 #if __cplusplus > 201703L && __cpp_lib_concepts
1072 using iterator_concept
= std::__detail::__iter_concept
<_Iterator
>;
1075 _GLIBCXX_CONSTEXPR
__normal_iterator() _GLIBCXX_NOEXCEPT
1076 : _M_current(_Iterator()) { }
1078 explicit _GLIBCXX20_CONSTEXPR
1079 __normal_iterator(const _Iterator
& __i
) _GLIBCXX_NOEXCEPT
1080 : _M_current(__i
) { }
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
)
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
)
1097 : _M_current(__i
.base()) { }
1099 // Forward iterator requirements
1100 _GLIBCXX20_CONSTEXPR
1102 operator*() const _GLIBCXX_NOEXCEPT
1103 { return *_M_current
; }
1105 _GLIBCXX20_CONSTEXPR
1107 operator->() const _GLIBCXX_NOEXCEPT
1108 { return _M_current
; }
1110 _GLIBCXX20_CONSTEXPR
1112 operator++() _GLIBCXX_NOEXCEPT
1118 _GLIBCXX20_CONSTEXPR
1120 operator++(int) _GLIBCXX_NOEXCEPT
1121 { return __normal_iterator(_M_current
++); }
1123 // Bidirectional iterator requirements
1124 _GLIBCXX20_CONSTEXPR
1126 operator--() _GLIBCXX_NOEXCEPT
1132 _GLIBCXX20_CONSTEXPR
1134 operator--(int) _GLIBCXX_NOEXCEPT
1135 { return __normal_iterator(_M_current
--); }
1137 // Random access iterator requirements
1138 _GLIBCXX20_CONSTEXPR
1140 operator[](difference_type __n
) const _GLIBCXX_NOEXCEPT
1141 { return _M_current
[__n
]; }
1143 _GLIBCXX20_CONSTEXPR
1145 operator+=(difference_type __n
) _GLIBCXX_NOEXCEPT
1146 { _M_current
+= __n
; return *this; }
1148 _GLIBCXX20_CONSTEXPR
1150 operator+(difference_type __n
) const _GLIBCXX_NOEXCEPT
1151 { return __normal_iterator(_M_current
+ __n
); }
1153 _GLIBCXX20_CONSTEXPR
1155 operator-=(difference_type __n
) _GLIBCXX_NOEXCEPT
1156 { _M_current
-= __n
; return *this; }
1158 _GLIBCXX20_CONSTEXPR
1160 operator-(difference_type __n
) const _GLIBCXX_NOEXCEPT
1161 { return __normal_iterator(_M_current
- __n
); }
1163 _GLIBCXX20_CONSTEXPR
1165 base() const _GLIBCXX_NOEXCEPT
1166 { return _M_current
; }
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
1177 #if __cpp_lib_three_way_comparison
1178 template<typename _IteratorL
, typename _IteratorR
, typename _Container
>
1181 operator==(const __normal_iterator
<_IteratorL
, _Container
>& __lhs
,
1182 const __normal_iterator
<_IteratorR
, _Container
>& __rhs
)
1183 noexcept(noexcept(__lhs
.base() == __rhs
.base()))
1185 { __lhs
.base() == __rhs
.base() } -> std::convertible_to
<bool>;
1187 { return __lhs
.base() == __rhs
.base(); }
1189 template<typename _IteratorL
, typename _IteratorR
, typename _Container
>
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()); }
1197 template<typename _Iterator
, typename _Container
>
1200 operator==(const __normal_iterator
<_Iterator
, _Container
>& __lhs
,
1201 const __normal_iterator
<_Iterator
, _Container
>& __rhs
)
1202 noexcept(noexcept(__lhs
.base() == __rhs
.base()))
1204 { __lhs
.base() == __rhs
.base() } -> std::convertible_to
<bool>;
1206 { return __lhs
.base() == __rhs
.base(); }
1208 template<typename _Iterator
, typename _Container
>
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()); }
1216 // Forward iterator requirements
1217 template<typename _IteratorL
, typename _IteratorR
, typename _Container
>
1218 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
1220 operator==(const __normal_iterator
<_IteratorL
, _Container
>& __lhs
,
1221 const __normal_iterator
<_IteratorR
, _Container
>& __rhs
)
1223 { return __lhs
.base() == __rhs
.base(); }
1225 template<typename _Iterator
, typename _Container
>
1226 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
1228 operator==(const __normal_iterator
<_Iterator
, _Container
>& __lhs
,
1229 const __normal_iterator
<_Iterator
, _Container
>& __rhs
)
1231 { return __lhs
.base() == __rhs
.base(); }
1233 template<typename _IteratorL
, typename _IteratorR
, typename _Container
>
1234 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
1236 operator!=(const __normal_iterator
<_IteratorL
, _Container
>& __lhs
,
1237 const __normal_iterator
<_IteratorR
, _Container
>& __rhs
)
1239 { return __lhs
.base() != __rhs
.base(); }
1241 template<typename _Iterator
, typename _Container
>
1242 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
1244 operator!=(const __normal_iterator
<_Iterator
, _Container
>& __lhs
,
1245 const __normal_iterator
<_Iterator
, _Container
>& __rhs
)
1247 { return __lhs
.base() != __rhs
.base(); }
1249 // Random access iterator requirements
1250 template<typename _IteratorL
, typename _IteratorR
, typename _Container
>
1253 operator<(const __normal_iterator
<_IteratorL
, _Container
>& __lhs
,
1254 const __normal_iterator
<_IteratorR
, _Container
>& __rhs
)
1256 { return __lhs
.base() < __rhs
.base(); }
1258 template<typename _Iterator
, typename _Container
>
1259 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
1261 operator<(const __normal_iterator
<_Iterator
, _Container
>& __lhs
,
1262 const __normal_iterator
<_Iterator
, _Container
>& __rhs
)
1264 { return __lhs
.base() < __rhs
.base(); }
1266 template<typename _IteratorL
, typename _IteratorR
, typename _Container
>
1269 operator>(const __normal_iterator
<_IteratorL
, _Container
>& __lhs
,
1270 const __normal_iterator
<_IteratorR
, _Container
>& __rhs
)
1272 { return __lhs
.base() > __rhs
.base(); }
1274 template<typename _Iterator
, typename _Container
>
1275 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
1277 operator>(const __normal_iterator
<_Iterator
, _Container
>& __lhs
,
1278 const __normal_iterator
<_Iterator
, _Container
>& __rhs
)
1280 { return __lhs
.base() > __rhs
.base(); }
1282 template<typename _IteratorL
, typename _IteratorR
, typename _Container
>
1285 operator<=(const __normal_iterator
<_IteratorL
, _Container
>& __lhs
,
1286 const __normal_iterator
<_IteratorR
, _Container
>& __rhs
)
1288 { return __lhs
.base() <= __rhs
.base(); }
1290 template<typename _Iterator
, typename _Container
>
1291 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
1293 operator<=(const __normal_iterator
<_Iterator
, _Container
>& __lhs
,
1294 const __normal_iterator
<_Iterator
, _Container
>& __rhs
)
1296 { return __lhs
.base() <= __rhs
.base(); }
1298 template<typename _IteratorL
, typename _IteratorR
, typename _Container
>
1301 operator>=(const __normal_iterator
<_IteratorL
, _Container
>& __lhs
,
1302 const __normal_iterator
<_IteratorR
, _Container
>& __rhs
)
1304 { return __lhs
.base() >= __rhs
.base(); }
1306 template<typename _Iterator
, typename _Container
>
1307 _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
1309 operator>=(const __normal_iterator
<_Iterator
, _Container
>& __lhs
,
1310 const __normal_iterator
<_Iterator
, _Container
>& __rhs
)
1312 { return __lhs
.base() >= __rhs
.base(); }
1313 #endif // three-way comparison
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
1319 template<typename _IteratorL
, typename _IteratorR
, typename _Container
>
1320 #if __cplusplus >= 201103L
1322 [[__nodiscard__
]] _GLIBCXX20_CONSTEXPR
1324 operator-(const __normal_iterator
<_IteratorL
, _Container
>& __lhs
,
1325 const __normal_iterator
<_IteratorR
, _Container
>& __rhs
) noexcept
1326 -> decltype(__lhs
.base() - __rhs
.base())
1328 inline typename __normal_iterator
<_IteratorL
, _Container
>::difference_type
1329 operator-(const __normal_iterator
<_IteratorL
, _Container
>& __lhs
,
1330 const __normal_iterator
<_IteratorR
, _Container
>& __rhs
)
1332 { return __lhs
.base() - __rhs
.base(); }
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
)
1340 { return __lhs
.base() - __rhs
.base(); }
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
)
1348 { return __normal_iterator
<_Iterator
, _Container
>(__i
.base() + __n
); }
1350 _GLIBCXX_END_NAMESPACE_VERSION
1353 namespace std
_GLIBCXX_VISIBILITY(default)
1355 _GLIBCXX_BEGIN_NAMESPACE_VERSION
1357 template<typename _Iterator
, typename _Container
>
1358 _GLIBCXX20_CONSTEXPR
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(); }
1364 #if __cplusplus >= 201103L
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
>
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()); }
1378 * @addtogroup iterators
1382 #if __cplusplus > 201703L && __cpp_lib_concepts
1383 template<semiregular _Sent
>
1389 noexcept(is_nothrow_default_constructible_v
<_Sent
>)
1393 move_sentinel(_Sent __s
)
1394 noexcept(is_nothrow_move_constructible_v
<_Sent
>)
1395 : _M_last(std::move(__s
)) { }
1397 template<typename _S2
> requires convertible_to
<const _S2
&, _Sent
>
1399 move_sentinel(const move_sentinel
<_S2
>& __s
)
1400 noexcept(is_nothrow_constructible_v
<_Sent
, const _S2
&>)
1401 : _M_last(__s
.base())
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
&>)
1409 _M_last
= __s
.base();
1416 noexcept(is_nothrow_copy_constructible_v
<_Sent
>)
1426 #if __cplusplus > 201703L && __cpp_lib_concepts
1427 template<typename _Iterator
>
1428 struct __move_iter_cat
1431 template<typename _Iterator
>
1432 requires requires
{ typename __iter_category_t
<_Iterator
>; }
1433 struct __move_iter_cat
<_Iterator
>
1435 using iterator_category
1436 = __clamped_iter_cat_t
<_Iterator
, random_access_iterator_tag
>;
1441 // 24.4.3 Move iterators
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.
1450 template<typename _Iterator
>
1452 #if __cplusplus > 201703L && __cpp_lib_concepts
1453 : public __detail::__move_iter_cat
<_Iterator
>
1456 _Iterator _M_current
;
1458 using __traits_type
= iterator_traits
<_Iterator
>;
1459 #if ! (__cplusplus > 201703L && __cpp_lib_concepts)
1460 using __base_ref
= typename
__traits_type::reference
;
1463 template<typename _Iter2
>
1464 friend class move_iterator
;
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
>;
1474 #if __cplusplus > 201703L && __cpp_lib_concepts
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
{};
1485 return input_iterator_tag
{};
1490 using iterator_type
= _Iterator
;
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());
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
>;
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
;
1507 typedef _Iterator pointer
;
1508 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1509 // 2106. move_iterator wrapping iterators returning prvalues
1511 = __conditional_t
<is_reference
<__base_ref
>::value
,
1512 typename remove_reference
<__base_ref
>::type
&&,
1516 _GLIBCXX17_CONSTEXPR
1520 explicit _GLIBCXX17_CONSTEXPR
1521 move_iterator(iterator_type __i
)
1522 : _M_current(std::move(__i
)) { }
1524 template<typename _Iter
>
1525 #if __cpp_lib_concepts
1526 requires __convertible
<_Iter
>
1528 _GLIBCXX17_CONSTEXPR
1529 move_iterator(const move_iterator
<_Iter
>& __i
)
1530 : _M_current(__i
._M_current
) { }
1532 template<typename _Iter
>
1533 #if __cpp_lib_concepts
1534 requires __convertible
<_Iter
>
1535 && assignable_from
<_Iterator
&, const _Iter
&>
1537 _GLIBCXX17_CONSTEXPR
1538 move_iterator
& operator=(const move_iterator
<_Iter
>& __i
)
1540 _M_current
= __i
._M_current
;
1544 #if __cplusplus <= 201703L
1546 _GLIBCXX17_CONSTEXPR iterator_type
1548 { return _M_current
; }
1551 constexpr const iterator_type
&
1552 base() const & noexcept
1553 { return _M_current
; }
1556 constexpr iterator_type
1558 { return std::move(_M_current
); }
1562 _GLIBCXX17_CONSTEXPR reference
1564 #if __cplusplus > 201703L && __cpp_lib_concepts
1565 { return ranges::iter_move(_M_current
); }
1567 { return static_cast<reference
>(*_M_current
); }
1571 _GLIBCXX17_CONSTEXPR pointer
1573 { return _M_current
; }
1575 _GLIBCXX17_CONSTEXPR move_iterator
&
1582 _GLIBCXX17_CONSTEXPR move_iterator
1585 move_iterator __tmp
= *this;
1590 #if __cpp_lib_concepts
1592 operator++(int) requires (!forward_iterator
<_Iterator
>)
1596 _GLIBCXX17_CONSTEXPR move_iterator
&
1603 _GLIBCXX17_CONSTEXPR move_iterator
1606 move_iterator __tmp
= *this;
1612 _GLIBCXX17_CONSTEXPR move_iterator
1613 operator+(difference_type __n
) const
1614 { return move_iterator(_M_current
+ __n
); }
1616 _GLIBCXX17_CONSTEXPR move_iterator
&
1617 operator+=(difference_type __n
)
1624 _GLIBCXX17_CONSTEXPR move_iterator
1625 operator-(difference_type __n
) const
1626 { return move_iterator(_M_current
- __n
); }
1628 _GLIBCXX17_CONSTEXPR move_iterator
&
1629 operator-=(difference_type __n
)
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
); }
1641 { return std::move(_M_current
[__n
]); }
1644 #if __cplusplus > 201703L && __cpp_lib_concepts
1645 template<sentinel_for
<_Iterator
> _Sent
>
1647 friend constexpr bool
1648 operator==(const move_iterator
& __x
, const move_sentinel
<_Sent
>& __y
)
1649 { return __x
.base() == __y
.base(); }
1651 template<sized_sentinel_for
<_Iterator
> _Sent
>
1653 friend constexpr iter_difference_t
<_Iterator
>
1654 operator-(const move_sentinel
<_Sent
>& __x
, const move_iterator
& __y
)
1655 { return __x
.base() - __y
.base(); }
1657 template<sized_sentinel_for
<_Iterator
> _Sent
>
1659 friend constexpr iter_difference_t
<_Iterator
>
1660 operator-(const move_iterator
& __x
, const move_sentinel
<_Sent
>& __y
)
1661 { return __x
.base() - __y
.base(); }
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
); }
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
); }
1677 template<typename _IteratorL
, typename _IteratorR
>
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>; }
1685 { return __x
.base() == __y
.base(); }
1687 #if __cpp_lib_three_way_comparison
1688 template<typename _IteratorL
,
1689 three_way_comparable_with
<_IteratorL
> _IteratorR
>
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(); }
1696 template<typename _IteratorL
, typename _IteratorR
>
1698 inline _GLIBCXX17_CONSTEXPR
bool
1699 operator!=(const move_iterator
<_IteratorL
>& __x
,
1700 const move_iterator
<_IteratorR
>& __y
)
1701 { return !(__x
== __y
); }
1704 template<typename _IteratorL
, typename _IteratorR
>
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>; }
1712 { return __x
.base() < __y
.base(); }
1714 template<typename _IteratorL
, typename _IteratorR
>
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>; }
1722 { return !(__y
< __x
); }
1724 template<typename _IteratorL
, typename _IteratorR
>
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>; }
1732 { return __y
< __x
; }
1734 template<typename _IteratorL
, typename _IteratorR
>
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>; }
1742 { return !(__x
< __y
); }
1744 // Note: See __normal_iterator operators note from Gaby to understand
1745 // why we have these extra overloads for some move_iterator operators.
1747 template<typename _Iterator
>
1749 inline _GLIBCXX17_CONSTEXPR
bool
1750 operator==(const move_iterator
<_Iterator
>& __x
,
1751 const move_iterator
<_Iterator
>& __y
)
1752 { return __x
.base() == __y
.base(); }
1754 #if __cpp_lib_three_way_comparison
1755 template<three_way_comparable _Iterator
>
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(); }
1762 template<typename _Iterator
>
1764 inline _GLIBCXX17_CONSTEXPR
bool
1765 operator!=(const move_iterator
<_Iterator
>& __x
,
1766 const move_iterator
<_Iterator
>& __y
)
1767 { return !(__x
== __y
); }
1769 template<typename _Iterator
>
1771 inline _GLIBCXX17_CONSTEXPR
bool
1772 operator<(const move_iterator
<_Iterator
>& __x
,
1773 const move_iterator
<_Iterator
>& __y
)
1774 { return __x
.base() < __y
.base(); }
1776 template<typename _Iterator
>
1778 inline _GLIBCXX17_CONSTEXPR
bool
1779 operator<=(const move_iterator
<_Iterator
>& __x
,
1780 const move_iterator
<_Iterator
>& __y
)
1781 { return !(__y
< __x
); }
1783 template<typename _Iterator
>
1785 inline _GLIBCXX17_CONSTEXPR
bool
1786 operator>(const move_iterator
<_Iterator
>& __x
,
1787 const move_iterator
<_Iterator
>& __y
)
1788 { return __y
< __x
; }
1790 template<typename _Iterator
>
1792 inline _GLIBCXX17_CONSTEXPR
bool
1793 operator>=(const move_iterator
<_Iterator
>& __x
,
1794 const move_iterator
<_Iterator
>& __y
)
1795 { return !(__x
< __y
); }
1799 template<typename _IteratorL
, typename _IteratorR
>
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(); }
1807 template<typename _Iterator
>
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
; }
1814 template<typename _Iterator
>
1816 inline _GLIBCXX17_CONSTEXPR move_iterator
<_Iterator
>
1817 make_move_iterator(_Iterator __i
)
1818 { return move_iterator
<_Iterator
>(std::move(__i
)); }
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
); }
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
); }
1837 #if __cplusplus > 201703L && __cpp_lib_concepts
1838 // [iterators.common] Common iterators
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
>>);
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
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
1860 template<typename _Tp
, typename _Up
>
1861 static constexpr bool
1864 if constexpr (is_trivially_default_constructible_v
<_Tp
>)
1865 return is_nothrow_assignable_v
<_Tp
&, _Up
>;
1867 return is_nothrow_constructible_v
<_Tp
, _Up
>;
1870 template<typename _It2
, typename _Sent2
>
1871 static constexpr bool
1873 { return _S_noexcept1
<_It
, _It2
>() && _S_noexcept1
<_Sent
, _Sent2
>(); }
1877 iter_value_t
<_It
> _M_keep
;
1880 __arrow_proxy(iter_reference_t
<_It
>&& __x
)
1881 : _M_keep(std::move(__x
)) { }
1883 friend class common_iterator
;
1886 constexpr const iter_value_t
<_It
>*
1887 operator->() const noexcept
1888 { return std::__addressof(_M_keep
); }
1891 class __postfix_proxy
1893 iter_value_t
<_It
> _M_keep
;
1896 __postfix_proxy(iter_reference_t
<_It
>&& __x
)
1897 : _M_keep(std::forward
<iter_reference_t
<_It
>>(__x
)) { }
1899 friend class common_iterator
;
1902 constexpr const iter_value_t
<_It
>&
1903 operator*() const noexcept
1910 noexcept(is_nothrow_default_constructible_v
<_It
>)
1911 requires default_initializable
<_It
>
1912 : _M_it(), _M_index(0)
1916 common_iterator(_It __i
)
1917 noexcept(is_nothrow_move_constructible_v
<_It
>)
1918 : _M_it(std::move(__i
)), _M_index(0)
1922 common_iterator(_Sent __s
)
1923 noexcept(is_nothrow_move_constructible_v
<_Sent
>)
1924 : _M_sent(std::move(__s
)), _M_index(1)
1927 template<typename _It2
, typename _Sent2
>
1928 requires convertible_to
<const _It2
&, _It
>
1929 && convertible_to
<const _Sent2
&, _Sent
>
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
)
1935 __glibcxx_assert(__x
._M_has_value());
1938 if constexpr (is_trivially_default_constructible_v
<_It
>)
1939 _M_it
= std::move(__x
._M_it
);
1941 std::construct_at(std::__addressof(_M_it
), __x
._M_it
);
1943 else if (_M_index
== 1)
1945 if constexpr (is_trivially_default_constructible_v
<_Sent
>)
1946 _M_sent
= std::move(__x
._M_sent
);
1948 std::construct_at(std::__addressof(_M_sent
), __x
._M_sent
);
1952 common_iterator(const common_iterator
&) = default;
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
)
1962 if constexpr (is_trivially_default_constructible_v
<_It
>)
1965 std::construct_at(std::__addressof(_M_it
), __x
._M_it
);
1967 else if (_M_index
== 1)
1969 if constexpr (is_trivially_default_constructible_v
<_Sent
>)
1970 _M_sent
= __x
._M_sent
;
1972 std::construct_at(std::__addressof(_M_sent
), __x
._M_sent
);
1976 common_iterator(common_iterator
&&) = default;
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
)
1986 if constexpr (is_trivially_default_constructible_v
<_It
>)
1987 _M_it
= std::move(__x
._M_it
);
1989 std::construct_at(std::__addressof(_M_it
), std::move(__x
._M_it
));
1991 else if (_M_index
== 1)
1993 if constexpr (is_trivially_default_constructible_v
<_Sent
>)
1994 _M_sent
= std::move(__x
._M_sent
);
1996 std::construct_at(std::__addressof(_M_sent
),
1997 std::move(__x
._M_sent
));
2001 constexpr common_iterator
&
2002 operator=(const common_iterator
&) = default;
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
>)
2017 constexpr common_iterator
&
2018 operator=(common_iterator
&&) = default;
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
>)
2029 _M_assign(std::move(__x
));
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
&>)
2045 __glibcxx_assert(__x
._M_has_value());
2050 #if __cpp_concepts >= 202002L // Constrained special member functions
2051 ~common_iterator() = default;
2055 requires (!is_trivially_destructible_v
<_It
>
2056 || !is_trivially_destructible_v
<_Sent
>)
2064 else if (_M_index
== 1)
2069 constexpr decltype(auto)
2072 __glibcxx_assert(_M_index
== 0);
2077 constexpr decltype(auto)
2078 operator*() const requires
__detail::__dereferenceable
<const _It
>
2080 __glibcxx_assert(_M_index
== 0);
2086 operator->() const requires
__detail::__common_iter_has_arrow
<_It
>
2088 __glibcxx_assert(_M_index
== 0);
2089 if constexpr (is_pointer_v
<_It
> || requires
{ _M_it
.operator->(); })
2091 else if constexpr (is_reference_v
<iter_reference_t
<_It
>>)
2093 auto&& __tmp
= *_M_it
;
2094 return std::__addressof(__tmp
);
2097 return __arrow_proxy
{*_M_it
};
2100 constexpr common_iterator
&
2103 __glibcxx_assert(_M_index
== 0);
2108 constexpr decltype(auto)
2111 __glibcxx_assert(_M_index
== 0);
2112 if constexpr (forward_iterator
<_It
>)
2114 common_iterator __tmp
= *this;
2118 else if constexpr (!__detail::__common_iter_use_postfix_proxy
<_It
>)
2122 __postfix_proxy
__p(**this);
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
)
2134 switch(__x
._M_index
<< 2 | __y
._M_index
)
2140 return __x
._M_it
== __y
._M_sent
;
2142 return __x
._M_sent
== __y
._M_it
;
2144 __glibcxx_assert(__x
._M_has_value());
2145 __glibcxx_assert(__y
._M_has_value());
2146 __builtin_unreachable();
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
)
2156 switch(__x
._M_index
<< 2 | __y
._M_index
)
2161 return __x
._M_it
== __y
._M_it
;
2163 return __x
._M_it
== __y
._M_sent
;
2165 return __x
._M_sent
== __y
._M_it
;
2167 __glibcxx_assert(__x
._M_has_value());
2168 __glibcxx_assert(__y
._M_has_value());
2169 __builtin_unreachable();
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
)
2179 switch(__x
._M_index
<< 2 | __y
._M_index
)
2184 return __x
._M_it
- __y
._M_it
;
2186 return __x
._M_it
- __y
._M_sent
;
2188 return __x
._M_sent
- __y
._M_it
;
2190 __glibcxx_assert(__x
._M_has_value());
2191 __glibcxx_assert(__y
._M_has_value());
2192 __builtin_unreachable();
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
>
2202 __glibcxx_assert(__i
._M_index
== 0);
2203 return ranges::iter_move(__i
._M_it
);
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
&>())))
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
);
2219 template<input_or_output_iterator _It2
, sentinel_for
<_It2
> _Sent2
>
2220 requires (!same_as
<_It2
, _Sent2
>) && copyable
<_It2
>
2221 friend class common_iterator
;
2224 _M_has_value() const noexcept
{ return _M_index
!= _S_valueless
; }
2226 template<typename _CIt
>
2228 _M_assign(_CIt
&& __x
)
2230 if (_M_index
== __x
._M_index
)
2233 _M_it
= std::forward
<_CIt
>(__x
)._M_it
;
2234 else if (_M_index
== 1)
2235 _M_sent
= std::forward
<_CIt
>(__x
)._M_sent
;
2241 else if (_M_index
== 1)
2243 _M_index
= _S_valueless
;
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
;
2259 unsigned char _M_valueless
;
2261 unsigned char _M_index
; // 0 == _M_it, 1 == _M_sent, 2 == valueless
2263 static constexpr unsigned char _S_valueless
{2};
2266 template<typename _It
, typename _Sent
>
2267 struct incrementable_traits
<common_iterator
<_It
, _Sent
>>
2269 using difference_type
= iter_difference_t
<_It
>;
2272 template<input_iterator _It
, typename _Sent
>
2273 struct iterator_traits
<common_iterator
<_It
, _Sent
>>
2276 template<typename _Iter
>
2282 template<typename _Iter
>
2283 requires
__detail::__common_iter_has_arrow
<_Iter
>
2286 using _CIter
= common_iterator
<_Iter
, _Sent
>;
2287 using type
= decltype(std::declval
<const _CIter
&>().operator->());
2293 if constexpr (requires
{ requires derived_from
<__iter_category_t
<_It
>,
2294 forward_iterator_tag
>; })
2295 return forward_iterator_tag
{};
2297 return input_iterator_tag
{};
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
>;
2311 // [iterators.counted] Counted iterators
2315 template<typename _It
>
2316 struct __counted_iter_value_type
2319 template<indirectly_readable _It
>
2320 struct __counted_iter_value_type
<_It
>
2321 { using value_type
= iter_value_t
<_It
>; };
2323 template<typename _It
>
2324 struct __counted_iter_concept
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
; };
2332 template<typename _It
>
2333 struct __counted_iter_cat
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
; };
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
>
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
2356 constexpr counted_iterator() requires default_initializable
<_It
> = default;
2359 counted_iterator(_It __i
, iter_difference_t
<_It
> __n
)
2360 : _M_current(std::move(__i
)), _M_length(__n
)
2361 { __glibcxx_assert(__n
>= 0); }
2363 template<typename _It2
>
2364 requires convertible_to
<const _It2
&, _It
>
2366 counted_iterator(const counted_iterator
<_It2
>& __x
)
2367 : _M_current(__x
._M_current
), _M_length(__x
._M_length
)
2370 template<typename _It2
>
2371 requires assignable_from
<_It
&, const _It2
&>
2372 constexpr counted_iterator
&
2373 operator=(const counted_iterator
<_It2
>& __x
)
2375 _M_current
= __x
._M_current
;
2376 _M_length
= __x
._M_length
;
2381 constexpr const _It
&
2382 base() const & noexcept
2383 { return _M_current
; }
2388 noexcept(is_nothrow_move_constructible_v
<_It
>)
2389 { return std::move(_M_current
); }
2392 constexpr iter_difference_t
<_It
>
2393 count() const noexcept
{ return _M_length
; }
2396 constexpr decltype(auto)
2398 noexcept(noexcept(*_M_current
))
2400 __glibcxx_assert( _M_length
> 0 );
2405 constexpr decltype(auto)
2407 noexcept(noexcept(*_M_current
))
2408 requires
__detail::__dereferenceable
<const _It
>
2410 __glibcxx_assert( _M_length
> 0 );
2416 operator->() const noexcept
2417 requires contiguous_iterator
<_It
>
2418 { return std::to_address(_M_current
); }
2420 constexpr counted_iterator
&
2423 __glibcxx_assert(_M_length
> 0);
2429 constexpr decltype(auto)
2432 __glibcxx_assert(_M_length
> 0);
2436 return _M_current
++;
2439 __throw_exception_again
;
2443 constexpr counted_iterator
2444 operator++(int) requires forward_iterator
<_It
>
2451 constexpr counted_iterator
&
2452 operator--() requires bidirectional_iterator
<_It
>
2459 constexpr counted_iterator
2460 operator--(int) requires bidirectional_iterator
<_It
>
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
); }
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
; }
2479 constexpr counted_iterator
&
2480 operator+=(iter_difference_t
<_It
> __n
)
2481 requires random_access_iterator
<_It
>
2483 __glibcxx_assert(__n
<= _M_length
);
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
); }
2495 template<common_with
<_It
> _It2
>
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
; }
2503 friend constexpr iter_difference_t
<_It
>
2504 operator-(const counted_iterator
& __x
, default_sentinel_t
)
2505 { return -__x
._M_length
; }
2508 friend constexpr iter_difference_t
<_It
>
2509 operator-(default_sentinel_t
, const counted_iterator
& __y
)
2510 { return __y
._M_length
; }
2512 constexpr counted_iterator
&
2513 operator-=(iter_difference_t
<_It
> __n
)
2514 requires random_access_iterator
<_It
>
2516 __glibcxx_assert(-__n
<= _M_length
);
2523 constexpr decltype(auto)
2524 operator[](iter_difference_t
<_It
> __n
) const
2525 noexcept(noexcept(_M_current
[__n
]))
2526 requires random_access_iterator
<_It
>
2528 __glibcxx_assert(__n
< _M_length
);
2529 return _M_current
[__n
];
2532 template<common_with
<_It
> _It2
>
2534 friend constexpr bool
2535 operator==(const counted_iterator
& __x
,
2536 const counted_iterator
<_It2
>& __y
)
2537 { return __x
._M_length
== __y
._M_length
; }
2540 friend constexpr bool
2541 operator==(const counted_iterator
& __x
, default_sentinel_t
)
2542 { return __x
._M_length
== 0; }
2544 template<common_with
<_It
> _It2
>
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
; }
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
>
2557 __glibcxx_assert( __i
._M_length
> 0 );
2558 return ranges::iter_move(__i
._M_current
);
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
)))
2567 __glibcxx_assert( __x
._M_length
> 0 && __y
._M_length
> 0 );
2568 ranges::iter_swap(__x
._M_current
, __y
._M_current
);
2572 template<input_or_output_iterator _It2
> friend class counted_iterator
;
2574 _It _M_current
= _It();
2575 iter_difference_t
<_It
> _M_length
= 0;
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
>
2582 using pointer
= __conditional_t
<contiguous_iterator
<_It
>,
2583 add_pointer_t
<iter_reference_t
<_It
>>,
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
>>;
2592 template<input_iterator _It
> class basic_const_iterator
;
2596 template<typename _It
>
2597 concept __constant_iterator
= input_iterator
<_It
>
2598 && same_as
<iter_const_reference_t
<_It
>, iter_reference_t
<_It
>>;
2600 template<typename _Tp
>
2601 inline constexpr bool __is_const_iterator
= false;
2603 template<typename _It
>
2604 inline constexpr bool __is_const_iterator
<basic_const_iterator
<_It
>> = true;
2606 template<typename _Tp
>
2607 concept __not_a_const_iterator
= !__is_const_iterator
<_Tp
>;
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
>>;
2613 template<typename _It
>
2614 struct __basic_const_iterator_iter_cat
2617 template<forward_iterator _It
>
2618 struct __basic_const_iterator_iter_cat
<_It
>
2619 { using iterator_category
= __iter_category_t
<_It
>; };
2620 } // namespace detail
2622 template<input_iterator _It
>
2623 using const_iterator
2624 = __conditional_t
<__detail::__constant_iterator
<_It
>, _It
, basic_const_iterator
<_It
>>;
2628 template<typename _Sent
>
2629 struct __const_sentinel
2630 { using type
= _Sent
; };
2632 template<input_iterator _Sent
>
2633 struct __const_sentinel
<_Sent
>
2634 { using type
= const_iterator
<_Sent
>; };
2635 } // namespace __detail
2637 template<semiregular _Sent
>
2638 using const_sentinel
= typename
__detail::__const_sentinel
<_Sent
>::type
;
2640 template<input_iterator _It
>
2641 class basic_const_iterator
2642 : public __detail::__basic_const_iterator_iter_cat
<_It
>
2644 _It _M_current
= _It();
2645 using __reference
= iter_const_reference_t
<_It
>;
2646 using __rvalue_reference
= __detail::__iter_const_rvalue_reference_t
<_It
>;
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
{};
2660 return input_iterator_tag
{};
2663 template<input_iterator _It2
> friend class basic_const_iterator
;
2666 using iterator_concept
= decltype(_S_iter_concept());
2667 using value_type
= iter_value_t
<_It
>;
2668 using difference_type
= iter_difference_t
<_It
>;
2670 basic_const_iterator() requires default_initializable
<_It
> = default;
2673 basic_const_iterator(_It __current
)
2674 noexcept(is_nothrow_move_constructible_v
<_It
>)
2675 : _M_current(std::move(__current
))
2678 template<convertible_to
<_It
> _It2
>
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
))
2685 template<__detail::__different_from
<basic_const_iterator
> _Tp
>
2686 requires convertible_to
<_Tp
, _It
>
2688 basic_const_iterator(_Tp
&& __current
)
2689 noexcept(is_nothrow_constructible_v
<_It
, _Tp
>)
2690 : _M_current(std::forward
<_Tp
>(__current
))
2693 constexpr const _It
&
2694 base() const & noexcept
2695 { return _M_current
; }
2699 noexcept(is_nothrow_move_constructible_v
<_It
>)
2700 { return std::move(_M_current
); }
2702 constexpr __reference
2704 noexcept(noexcept(static_cast<__reference
>(*_M_current
)))
2705 { return static_cast<__reference
>(*_M_current
); }
2707 constexpr const auto*
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
>
2713 if constexpr (contiguous_iterator
<_It
>)
2714 return std::to_address(_M_current
);
2716 return std::__addressof(*_M_current
);
2719 constexpr basic_const_iterator
&
2721 noexcept(noexcept(++_M_current
))
2729 noexcept(noexcept(++_M_current
))
2732 constexpr basic_const_iterator
2734 noexcept(noexcept(++*this) && is_nothrow_copy_constructible_v
<basic_const_iterator
>)
2735 requires forward_iterator
<_It
>
2742 constexpr basic_const_iterator
&
2744 noexcept(noexcept(--_M_current
))
2745 requires bidirectional_iterator
<_It
>
2751 constexpr basic_const_iterator
2753 noexcept(noexcept(--*this) && is_nothrow_copy_constructible_v
<basic_const_iterator
>)
2754 requires bidirectional_iterator
<_It
>
2761 constexpr basic_const_iterator
&
2762 operator+=(difference_type __n
)
2763 noexcept(noexcept(_M_current
+= __n
))
2764 requires random_access_iterator
<_It
>
2770 constexpr basic_const_iterator
&
2771 operator-=(difference_type __n
)
2772 noexcept(noexcept(_M_current
-= __n
))
2773 requires random_access_iterator
<_It
>
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
]); }
2785 template<sentinel_for
<_It
> _Sent
>
2787 operator==(const _Sent
& __s
) const
2788 noexcept(noexcept(_M_current
== __s
))
2789 { return _M_current
== __s
; }
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
; }
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
; }
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
; }
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
; }
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
; }
2821 template<__detail::__different_from
<basic_const_iterator
> _It2
>
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
; }
2828 template<__detail::__different_from
<basic_const_iterator
> _It2
>
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
; }
2835 template<__detail::__different_from
<basic_const_iterator
> _It2
>
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
; }
2842 template<__detail::__different_from
<basic_const_iterator
> _It2
>
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
; }
2849 template<__detail::__different_from
<basic_const_iterator
> _It2
>
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
; }
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
; }
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
; }
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
; }
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
; }
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
); }
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
); }
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
); }
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
; }
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
; }
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
)); }
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
>>; };
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
>>; };
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
>>; };
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
>>)
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
>>)
2951 /// @} group iterators
2953 template<typename _Iterator
>
2954 _GLIBCXX20_CONSTEXPR
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())); }
2960 template<typename _Iterator
>
2961 struct __is_move_iterator
<move_iterator
<_Iterator
> >
2963 enum { __value
= 1 };
2964 typedef __true_type __type
;
2967 template<typename _Iterator
>
2968 _GLIBCXX20_CONSTEXPR
2970 __miter_base(move_iterator
<_Iterator
> __it
)
2971 -> decltype(__miter_base(__it
.base()))
2972 { return __miter_base(__it
.base()); }
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)
2978 #define _GLIBCXX_MAKE_MOVE_ITERATOR(_Iter) (_Iter)
2979 #define _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(_Iter) (_Iter)
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
>;
2989 template<typename _InputIterator
>
2991 = typename iterator_traits
<_InputIterator
>::value_type::second_type
;
2993 template<typename _T1
, typename _T2
>
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
3001 _GLIBCXX_END_NAMESPACE_VERSION
3004 #ifdef _GLIBCXX_DEBUG
3005 # include <debug/stl_iterator.h>