11debfc3dSmrg // Iterators -*- C++ -*-
21debfc3dSmrg
38feb0f0bSmrg // Copyright (C) 2001-2020 Free Software Foundation, Inc.
41debfc3dSmrg //
51debfc3dSmrg // This file is part of the GNU ISO C++ Library. This library is free
61debfc3dSmrg // software; you can redistribute it and/or modify it under the
71debfc3dSmrg // terms of the GNU General Public License as published by the
81debfc3dSmrg // Free Software Foundation; either version 3, or (at your option)
91debfc3dSmrg // any later version.
101debfc3dSmrg
111debfc3dSmrg // This library is distributed in the hope that it will be useful,
121debfc3dSmrg // but WITHOUT ANY WARRANTY; without even the implied warranty of
131debfc3dSmrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
141debfc3dSmrg // GNU General Public License for more details.
151debfc3dSmrg
161debfc3dSmrg // Under Section 7 of GPL version 3, you are granted additional
171debfc3dSmrg // permissions described in the GCC Runtime Library Exception, version
181debfc3dSmrg // 3.1, as published by the Free Software Foundation.
191debfc3dSmrg
201debfc3dSmrg // You should have received a copy of the GNU General Public License and
211debfc3dSmrg // a copy of the GCC Runtime Library Exception along with this program;
221debfc3dSmrg // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
231debfc3dSmrg // <http://www.gnu.org/licenses/>.
241debfc3dSmrg
251debfc3dSmrg /*
261debfc3dSmrg *
271debfc3dSmrg * Copyright (c) 1994
281debfc3dSmrg * Hewlett-Packard Company
291debfc3dSmrg *
301debfc3dSmrg * Permission to use, copy, modify, distribute and sell this software
311debfc3dSmrg * and its documentation for any purpose is hereby granted without fee,
321debfc3dSmrg * provided that the above copyright notice appear in all copies and
331debfc3dSmrg * that both that copyright notice and this permission notice appear
341debfc3dSmrg * in supporting documentation. Hewlett-Packard Company makes no
351debfc3dSmrg * representations about the suitability of this software for any
361debfc3dSmrg * purpose. It is provided "as is" without express or implied warranty.
371debfc3dSmrg *
381debfc3dSmrg *
391debfc3dSmrg * Copyright (c) 1996-1998
401debfc3dSmrg * Silicon Graphics Computer Systems, Inc.
411debfc3dSmrg *
421debfc3dSmrg * Permission to use, copy, modify, distribute and sell this software
431debfc3dSmrg * and its documentation for any purpose is hereby granted without fee,
441debfc3dSmrg * provided that the above copyright notice appear in all copies and
451debfc3dSmrg * that both that copyright notice and this permission notice appear
461debfc3dSmrg * in supporting documentation. Silicon Graphics makes no
471debfc3dSmrg * representations about the suitability of this software for any
481debfc3dSmrg * purpose. It is provided "as is" without express or implied warranty.
491debfc3dSmrg */
501debfc3dSmrg
511debfc3dSmrg /** @file bits/stl_iterator.h
521debfc3dSmrg * This is an internal header file, included by other library headers.
531debfc3dSmrg * Do not attempt to use it directly. @headername{iterator}
541debfc3dSmrg *
551debfc3dSmrg * This file implements reverse_iterator, back_insert_iterator,
561debfc3dSmrg * front_insert_iterator, insert_iterator, __normal_iterator, and their
571debfc3dSmrg * supporting functions and overloaded operators.
581debfc3dSmrg */
591debfc3dSmrg
601debfc3dSmrg #ifndef _STL_ITERATOR_H
611debfc3dSmrg #define _STL_ITERATOR_H 1
621debfc3dSmrg
631debfc3dSmrg #include <bits/cpp_type_traits.h>
648feb0f0bSmrg #include <bits/stl_iterator_base_types.h>
651debfc3dSmrg #include <ext/type_traits.h>
661debfc3dSmrg #include <bits/move.h>
671debfc3dSmrg #include <bits/ptr_traits.h>
681debfc3dSmrg
69c0a68be4Smrg #if __cplusplus >= 201103L
70c0a68be4Smrg # include <type_traits>
71c0a68be4Smrg #endif
72c0a68be4Smrg
738feb0f0bSmrg #if __cplusplus > 201703L
748feb0f0bSmrg # define __cpp_lib_array_constexpr 201811L
758feb0f0bSmrg # define __cpp_lib_constexpr_iterator 201811L
768feb0f0bSmrg #elif __cplusplus == 201703L
778feb0f0bSmrg # define __cpp_lib_array_constexpr 201803L
788feb0f0bSmrg #endif
798feb0f0bSmrg
808feb0f0bSmrg #if __cplusplus > 201703L
818feb0f0bSmrg # include <compare>
828feb0f0bSmrg # include <new>
838feb0f0bSmrg # include <bits/iterator_concepts.h>
841debfc3dSmrg #endif
851debfc3dSmrg
_GLIBCXX_VISIBILITY(default)861debfc3dSmrg namespace std _GLIBCXX_VISIBILITY(default)
871debfc3dSmrg {
881debfc3dSmrg _GLIBCXX_BEGIN_NAMESPACE_VERSION
891debfc3dSmrg
901debfc3dSmrg /**
911debfc3dSmrg * @addtogroup iterators
921debfc3dSmrg * @{
931debfc3dSmrg */
941debfc3dSmrg
958feb0f0bSmrg #if __cpp_lib_concepts
968feb0f0bSmrg namespace __detail
978feb0f0bSmrg {
988feb0f0bSmrg // Weaken iterator_category _Cat to _Limit if it is derived from that,
998feb0f0bSmrg // otherwise use _Otherwise.
1008feb0f0bSmrg template<typename _Cat, typename _Limit, typename _Otherwise = _Cat>
1018feb0f0bSmrg using __clamp_iter_cat
1028feb0f0bSmrg = conditional_t<derived_from<_Cat, _Limit>, _Limit, _Otherwise>;
1038feb0f0bSmrg }
1048feb0f0bSmrg #endif
1058feb0f0bSmrg
1061debfc3dSmrg // 24.4.1 Reverse iterators
1071debfc3dSmrg /**
1081debfc3dSmrg * Bidirectional and random access iterators have corresponding reverse
1091debfc3dSmrg * %iterator adaptors that iterate through the data structure in the
1101debfc3dSmrg * opposite direction. They have the same signatures as the corresponding
1111debfc3dSmrg * iterators. The fundamental relation between a reverse %iterator and its
1121debfc3dSmrg * corresponding %iterator @c i is established by the identity:
1131debfc3dSmrg * @code
1141debfc3dSmrg * &*(reverse_iterator(i)) == &*(i - 1)
1151debfc3dSmrg * @endcode
1161debfc3dSmrg *
1171debfc3dSmrg * <em>This mapping is dictated by the fact that while there is always a
1181debfc3dSmrg * pointer past the end of an array, there might not be a valid pointer
1191debfc3dSmrg * before the beginning of an array.</em> [24.4.1]/1,2
1201debfc3dSmrg *
1211debfc3dSmrg * Reverse iterators can be tricky and surprising at first. Their
1221debfc3dSmrg * semantics make sense, however, and the trickiness is a side effect of
1231debfc3dSmrg * the requirement that the iterators must be safe.
1241debfc3dSmrg */
1251debfc3dSmrg template<typename _Iterator>
1261debfc3dSmrg class reverse_iterator
1271debfc3dSmrg : public iterator<typename iterator_traits<_Iterator>::iterator_category,
1281debfc3dSmrg typename iterator_traits<_Iterator>::value_type,
1291debfc3dSmrg typename iterator_traits<_Iterator>::difference_type,
1301debfc3dSmrg typename iterator_traits<_Iterator>::pointer,
1311debfc3dSmrg typename iterator_traits<_Iterator>::reference>
1321debfc3dSmrg {
1331debfc3dSmrg protected:
1341debfc3dSmrg _Iterator current;
1351debfc3dSmrg
1361debfc3dSmrg typedef iterator_traits<_Iterator> __traits_type;
1371debfc3dSmrg
1381debfc3dSmrg public:
1391debfc3dSmrg typedef _Iterator iterator_type;
1401debfc3dSmrg typedef typename __traits_type::pointer pointer;
1418feb0f0bSmrg #if ! __cpp_lib_concepts
1428feb0f0bSmrg typedef typename __traits_type::difference_type difference_type;
1431debfc3dSmrg typedef typename __traits_type::reference reference;
1448feb0f0bSmrg #else
1458feb0f0bSmrg using iterator_concept
1468feb0f0bSmrg = conditional_t<random_access_iterator<_Iterator>,
1478feb0f0bSmrg random_access_iterator_tag,
1488feb0f0bSmrg bidirectional_iterator_tag>;
1498feb0f0bSmrg using iterator_category
1508feb0f0bSmrg = __detail::__clamp_iter_cat<typename __traits_type::iterator_category,
1518feb0f0bSmrg random_access_iterator_tag>;
1528feb0f0bSmrg using value_type = iter_value_t<_Iterator>;
1538feb0f0bSmrg using difference_type = iter_difference_t<_Iterator>;
1548feb0f0bSmrg using reference = iter_reference_t<_Iterator>;
1558feb0f0bSmrg #endif
1561debfc3dSmrg
1571debfc3dSmrg /**
1581debfc3dSmrg * The default constructor value-initializes member @p current.
1591debfc3dSmrg * If it is a pointer, that means it is zero-initialized.
1601debfc3dSmrg */
1611debfc3dSmrg // _GLIBCXX_RESOLVE_LIB_DEFECTS
1621debfc3dSmrg // 235 No specification of default ctor for reverse_iterator
1631debfc3dSmrg // 1012. reverse_iterator default ctor should value initialize
1641debfc3dSmrg _GLIBCXX17_CONSTEXPR
1651debfc3dSmrg reverse_iterator() : current() { }
1661debfc3dSmrg
1671debfc3dSmrg /**
1681debfc3dSmrg * This %iterator will move in the opposite direction that @p x does.
1691debfc3dSmrg */
1701debfc3dSmrg explicit _GLIBCXX17_CONSTEXPR
1711debfc3dSmrg reverse_iterator(iterator_type __x) : current(__x) { }
1721debfc3dSmrg
1731debfc3dSmrg /**
1741debfc3dSmrg * The copy constructor is normal.
1751debfc3dSmrg */
1761debfc3dSmrg _GLIBCXX17_CONSTEXPR
1771debfc3dSmrg reverse_iterator(const reverse_iterator& __x)
1781debfc3dSmrg : current(__x.current) { }
1791debfc3dSmrg
180c0a68be4Smrg #if __cplusplus >= 201103L
181c0a68be4Smrg reverse_iterator& operator=(const reverse_iterator&) = default;
182c0a68be4Smrg #endif
183c0a68be4Smrg
1841debfc3dSmrg /**
1851debfc3dSmrg * A %reverse_iterator across other types can be copied if the
1861debfc3dSmrg * underlying %iterator can be converted to the type of @c current.
1871debfc3dSmrg */
1881debfc3dSmrg template<typename _Iter>
1891debfc3dSmrg _GLIBCXX17_CONSTEXPR
1901debfc3dSmrg reverse_iterator(const reverse_iterator<_Iter>& __x)
1911debfc3dSmrg : current(__x.base()) { }
1921debfc3dSmrg
1931debfc3dSmrg /**
1941debfc3dSmrg * @return @c current, the %iterator used for underlying work.
1951debfc3dSmrg */
1961debfc3dSmrg _GLIBCXX17_CONSTEXPR iterator_type
1971debfc3dSmrg base() const
1981debfc3dSmrg { return current; }
1991debfc3dSmrg
2001debfc3dSmrg /**
2011debfc3dSmrg * @return A reference to the value at @c --current
2021debfc3dSmrg *
2031debfc3dSmrg * This requires that @c --current is dereferenceable.
2041debfc3dSmrg *
2051debfc3dSmrg * @warning This implementation requires that for an iterator of the
2061debfc3dSmrg * underlying iterator type, @c x, a reference obtained by
2071debfc3dSmrg * @c *x remains valid after @c x has been modified or
2081debfc3dSmrg * destroyed. This is a bug: http://gcc.gnu.org/PR51823
2091debfc3dSmrg */
2101debfc3dSmrg _GLIBCXX17_CONSTEXPR reference
2111debfc3dSmrg operator*() const
2121debfc3dSmrg {
2131debfc3dSmrg _Iterator __tmp = current;
2141debfc3dSmrg return *--__tmp;
2151debfc3dSmrg }
2161debfc3dSmrg
2171debfc3dSmrg /**
2181debfc3dSmrg * @return A pointer to the value at @c --current
2191debfc3dSmrg *
2201debfc3dSmrg * This requires that @c --current is dereferenceable.
2211debfc3dSmrg */
2221debfc3dSmrg _GLIBCXX17_CONSTEXPR pointer
2231debfc3dSmrg operator->() const
2248feb0f0bSmrg #if __cplusplus > 201703L && __cpp_concepts >= 201907L
2258feb0f0bSmrg requires is_pointer_v<_Iterator>
2268feb0f0bSmrg || requires(const _Iterator __i) { __i.operator->(); }
2278feb0f0bSmrg #endif
228c0a68be4Smrg {
229c0a68be4Smrg // _GLIBCXX_RESOLVE_LIB_DEFECTS
230c0a68be4Smrg // 1052. operator-> should also support smart pointers
231c0a68be4Smrg _Iterator __tmp = current;
232c0a68be4Smrg --__tmp;
233c0a68be4Smrg return _S_to_pointer(__tmp);
234c0a68be4Smrg }
2351debfc3dSmrg
2361debfc3dSmrg /**
2371debfc3dSmrg * @return @c *this
2381debfc3dSmrg *
2391debfc3dSmrg * Decrements the underlying iterator.
2401debfc3dSmrg */
2411debfc3dSmrg _GLIBCXX17_CONSTEXPR reverse_iterator&
2421debfc3dSmrg operator++()
2431debfc3dSmrg {
2441debfc3dSmrg --current;
2451debfc3dSmrg return *this;
2461debfc3dSmrg }
2471debfc3dSmrg
2481debfc3dSmrg /**
2491debfc3dSmrg * @return The original value of @c *this
2501debfc3dSmrg *
2511debfc3dSmrg * Decrements the underlying iterator.
2521debfc3dSmrg */
2531debfc3dSmrg _GLIBCXX17_CONSTEXPR reverse_iterator
2541debfc3dSmrg operator++(int)
2551debfc3dSmrg {
2561debfc3dSmrg reverse_iterator __tmp = *this;
2571debfc3dSmrg --current;
2581debfc3dSmrg return __tmp;
2591debfc3dSmrg }
2601debfc3dSmrg
2611debfc3dSmrg /**
2621debfc3dSmrg * @return @c *this
2631debfc3dSmrg *
2641debfc3dSmrg * Increments the underlying iterator.
2651debfc3dSmrg */
2661debfc3dSmrg _GLIBCXX17_CONSTEXPR reverse_iterator&
2671debfc3dSmrg operator--()
2681debfc3dSmrg {
2691debfc3dSmrg ++current;
2701debfc3dSmrg return *this;
2711debfc3dSmrg }
2721debfc3dSmrg
2731debfc3dSmrg /**
2741debfc3dSmrg * @return A reverse_iterator with the previous value of @c *this
2751debfc3dSmrg *
2761debfc3dSmrg * Increments the underlying iterator.
2771debfc3dSmrg */
2781debfc3dSmrg _GLIBCXX17_CONSTEXPR reverse_iterator
2791debfc3dSmrg operator--(int)
2801debfc3dSmrg {
2811debfc3dSmrg reverse_iterator __tmp = *this;
2821debfc3dSmrg ++current;
2831debfc3dSmrg return __tmp;
2841debfc3dSmrg }
2851debfc3dSmrg
2861debfc3dSmrg /**
2871debfc3dSmrg * @return A reverse_iterator that refers to @c current - @a __n
2881debfc3dSmrg *
2891debfc3dSmrg * The underlying iterator must be a Random Access Iterator.
2901debfc3dSmrg */
2911debfc3dSmrg _GLIBCXX17_CONSTEXPR reverse_iterator
2921debfc3dSmrg operator+(difference_type __n) const
2931debfc3dSmrg { return reverse_iterator(current - __n); }
2941debfc3dSmrg
2951debfc3dSmrg /**
2961debfc3dSmrg * @return *this
2971debfc3dSmrg *
2981debfc3dSmrg * Moves the underlying iterator backwards @a __n steps.
2991debfc3dSmrg * The underlying iterator must be a Random Access Iterator.
3001debfc3dSmrg */
3011debfc3dSmrg _GLIBCXX17_CONSTEXPR reverse_iterator&
3021debfc3dSmrg operator+=(difference_type __n)
3031debfc3dSmrg {
3041debfc3dSmrg current -= __n;
3051debfc3dSmrg return *this;
3061debfc3dSmrg }
3071debfc3dSmrg
3081debfc3dSmrg /**
3091debfc3dSmrg * @return A reverse_iterator that refers to @c current - @a __n
3101debfc3dSmrg *
3111debfc3dSmrg * The underlying iterator must be a Random Access Iterator.
3121debfc3dSmrg */
3131debfc3dSmrg _GLIBCXX17_CONSTEXPR reverse_iterator
3141debfc3dSmrg operator-(difference_type __n) const
3151debfc3dSmrg { return reverse_iterator(current + __n); }
3161debfc3dSmrg
3171debfc3dSmrg /**
3181debfc3dSmrg * @return *this
3191debfc3dSmrg *
3201debfc3dSmrg * Moves the underlying iterator forwards @a __n steps.
3211debfc3dSmrg * The underlying iterator must be a Random Access Iterator.
3221debfc3dSmrg */
3231debfc3dSmrg _GLIBCXX17_CONSTEXPR reverse_iterator&
3241debfc3dSmrg operator-=(difference_type __n)
3251debfc3dSmrg {
3261debfc3dSmrg current += __n;
3271debfc3dSmrg return *this;
3281debfc3dSmrg }
3291debfc3dSmrg
3301debfc3dSmrg /**
3311debfc3dSmrg * @return The value at @c current - @a __n - 1
3321debfc3dSmrg *
3331debfc3dSmrg * The underlying iterator must be a Random Access Iterator.
3341debfc3dSmrg */
3351debfc3dSmrg _GLIBCXX17_CONSTEXPR reference
3361debfc3dSmrg operator[](difference_type __n) const
3371debfc3dSmrg { return *(*this + __n); }
338c0a68be4Smrg
3398feb0f0bSmrg #if __cplusplus > 201703L && __cpp_lib_concepts
3408feb0f0bSmrg friend constexpr iter_rvalue_reference_t<_Iterator>
3418feb0f0bSmrg iter_move(const reverse_iterator& __i)
3428feb0f0bSmrg noexcept(is_nothrow_copy_constructible_v<_Iterator>
3438feb0f0bSmrg && noexcept(ranges::iter_move(--std::declval<_Iterator&>())))
3448feb0f0bSmrg {
3458feb0f0bSmrg auto __tmp = __i.base();
3468feb0f0bSmrg return ranges::iter_move(--__tmp);
3478feb0f0bSmrg }
3488feb0f0bSmrg
3498feb0f0bSmrg template<indirectly_swappable<_Iterator> _Iter2>
3508feb0f0bSmrg friend constexpr void
3518feb0f0bSmrg iter_swap(const reverse_iterator& __x,
3528feb0f0bSmrg const reverse_iterator<_Iter2>& __y)
3538feb0f0bSmrg noexcept(is_nothrow_copy_constructible_v<_Iterator>
3548feb0f0bSmrg && is_nothrow_copy_constructible_v<_Iter2>
3558feb0f0bSmrg && noexcept(ranges::iter_swap(--std::declval<_Iterator&>(),
3568feb0f0bSmrg --std::declval<_Iter2&>())))
3578feb0f0bSmrg {
3588feb0f0bSmrg auto __xtmp = __x.base();
3598feb0f0bSmrg auto __ytmp = __y.base();
3608feb0f0bSmrg ranges::iter_swap(--__xtmp, --__ytmp);
3618feb0f0bSmrg }
3628feb0f0bSmrg #endif
3638feb0f0bSmrg
364c0a68be4Smrg private:
365c0a68be4Smrg template<typename _Tp>
366c0a68be4Smrg static _GLIBCXX17_CONSTEXPR _Tp*
367c0a68be4Smrg _S_to_pointer(_Tp* __p)
368c0a68be4Smrg { return __p; }
369c0a68be4Smrg
370c0a68be4Smrg template<typename _Tp>
371c0a68be4Smrg static _GLIBCXX17_CONSTEXPR pointer
372c0a68be4Smrg _S_to_pointer(_Tp __t)
373c0a68be4Smrg { return __t.operator->(); }
3741debfc3dSmrg };
3751debfc3dSmrg
3768feb0f0bSmrg ///@{
3771debfc3dSmrg /**
3781debfc3dSmrg * @param __x A %reverse_iterator.
3791debfc3dSmrg * @param __y A %reverse_iterator.
3801debfc3dSmrg * @return A simple bool.
3811debfc3dSmrg *
3828feb0f0bSmrg * Reverse iterators forward comparisons to their underlying base()
3838feb0f0bSmrg * iterators.
3841debfc3dSmrg *
3851debfc3dSmrg */
3868feb0f0bSmrg #if __cplusplus <= 201703L || ! defined __cpp_lib_concepts
3871debfc3dSmrg template<typename _Iterator>
3881debfc3dSmrg inline _GLIBCXX17_CONSTEXPR bool
3891debfc3dSmrg operator==(const reverse_iterator<_Iterator>& __x,
3901debfc3dSmrg const reverse_iterator<_Iterator>& __y)
3911debfc3dSmrg { return __x.base() == __y.base(); }
3921debfc3dSmrg
3931debfc3dSmrg template<typename _Iterator>
3941debfc3dSmrg inline _GLIBCXX17_CONSTEXPR bool
3951debfc3dSmrg operator<(const reverse_iterator<_Iterator>& __x,
3961debfc3dSmrg const reverse_iterator<_Iterator>& __y)
3971debfc3dSmrg { return __y.base() < __x.base(); }
3981debfc3dSmrg
3991debfc3dSmrg template<typename _Iterator>
4001debfc3dSmrg inline _GLIBCXX17_CONSTEXPR bool
4011debfc3dSmrg operator!=(const reverse_iterator<_Iterator>& __x,
4021debfc3dSmrg const reverse_iterator<_Iterator>& __y)
4031debfc3dSmrg { return !(__x == __y); }
4041debfc3dSmrg
4051debfc3dSmrg template<typename _Iterator>
4061debfc3dSmrg inline _GLIBCXX17_CONSTEXPR bool
4071debfc3dSmrg operator>(const reverse_iterator<_Iterator>& __x,
4081debfc3dSmrg const reverse_iterator<_Iterator>& __y)
4091debfc3dSmrg { return __y < __x; }
4101debfc3dSmrg
4111debfc3dSmrg template<typename _Iterator>
4121debfc3dSmrg inline _GLIBCXX17_CONSTEXPR bool
4131debfc3dSmrg operator<=(const reverse_iterator<_Iterator>& __x,
4141debfc3dSmrg const reverse_iterator<_Iterator>& __y)
4151debfc3dSmrg { return !(__y < __x); }
4161debfc3dSmrg
4171debfc3dSmrg template<typename _Iterator>
4181debfc3dSmrg inline _GLIBCXX17_CONSTEXPR bool
4191debfc3dSmrg operator>=(const reverse_iterator<_Iterator>& __x,
4201debfc3dSmrg const reverse_iterator<_Iterator>& __y)
4211debfc3dSmrg { return !(__x < __y); }
4221debfc3dSmrg
4231debfc3dSmrg // _GLIBCXX_RESOLVE_LIB_DEFECTS
4241debfc3dSmrg // DR 280. Comparison of reverse_iterator to const reverse_iterator.
4251debfc3dSmrg template<typename _IteratorL, typename _IteratorR>
4261debfc3dSmrg inline _GLIBCXX17_CONSTEXPR bool
4271debfc3dSmrg operator==(const reverse_iterator<_IteratorL>& __x,
4281debfc3dSmrg const reverse_iterator<_IteratorR>& __y)
4291debfc3dSmrg { return __x.base() == __y.base(); }
4301debfc3dSmrg
4311debfc3dSmrg template<typename _IteratorL, typename _IteratorR>
4321debfc3dSmrg inline _GLIBCXX17_CONSTEXPR bool
4331debfc3dSmrg operator<(const reverse_iterator<_IteratorL>& __x,
4341debfc3dSmrg const reverse_iterator<_IteratorR>& __y)
4351debfc3dSmrg { return __y.base() < __x.base(); }
4361debfc3dSmrg
4371debfc3dSmrg template<typename _IteratorL, typename _IteratorR>
4381debfc3dSmrg inline _GLIBCXX17_CONSTEXPR bool
4391debfc3dSmrg operator!=(const reverse_iterator<_IteratorL>& __x,
4401debfc3dSmrg const reverse_iterator<_IteratorR>& __y)
4411debfc3dSmrg { return !(__x == __y); }
4421debfc3dSmrg
4431debfc3dSmrg template<typename _IteratorL, typename _IteratorR>
4441debfc3dSmrg inline _GLIBCXX17_CONSTEXPR bool
4451debfc3dSmrg operator>(const reverse_iterator<_IteratorL>& __x,
4461debfc3dSmrg const reverse_iterator<_IteratorR>& __y)
4471debfc3dSmrg { return __y < __x; }
4481debfc3dSmrg
4491debfc3dSmrg template<typename _IteratorL, typename _IteratorR>
4501debfc3dSmrg inline _GLIBCXX17_CONSTEXPR bool
4511debfc3dSmrg operator<=(const reverse_iterator<_IteratorL>& __x,
4521debfc3dSmrg const reverse_iterator<_IteratorR>& __y)
4531debfc3dSmrg { return !(__y < __x); }
4541debfc3dSmrg
4551debfc3dSmrg template<typename _IteratorL, typename _IteratorR>
4561debfc3dSmrg inline _GLIBCXX17_CONSTEXPR bool
4571debfc3dSmrg operator>=(const reverse_iterator<_IteratorL>& __x,
4581debfc3dSmrg const reverse_iterator<_IteratorR>& __y)
4591debfc3dSmrg { return !(__x < __y); }
4608feb0f0bSmrg #else // C++20
4618feb0f0bSmrg template<typename _IteratorL, typename _IteratorR>
4628feb0f0bSmrg constexpr bool
4638feb0f0bSmrg operator==(const reverse_iterator<_IteratorL>& __x,
4648feb0f0bSmrg const reverse_iterator<_IteratorR>& __y)
4658feb0f0bSmrg requires requires { { __x.base() == __y.base() } -> convertible_to<bool>; }
4668feb0f0bSmrg { return __x.base() == __y.base(); }
4678feb0f0bSmrg
4688feb0f0bSmrg template<typename _IteratorL, typename _IteratorR>
4698feb0f0bSmrg constexpr bool
4708feb0f0bSmrg operator!=(const reverse_iterator<_IteratorL>& __x,
4718feb0f0bSmrg const reverse_iterator<_IteratorR>& __y)
4728feb0f0bSmrg requires requires { { __x.base() != __y.base() } -> convertible_to<bool>; }
4738feb0f0bSmrg { return __x.base() != __y.base(); }
4748feb0f0bSmrg
4758feb0f0bSmrg template<typename _IteratorL, typename _IteratorR>
4768feb0f0bSmrg constexpr bool
4778feb0f0bSmrg operator<(const reverse_iterator<_IteratorL>& __x,
4788feb0f0bSmrg const reverse_iterator<_IteratorR>& __y)
4798feb0f0bSmrg requires requires { { __x.base() > __y.base() } -> convertible_to<bool>; }
4808feb0f0bSmrg { return __x.base() > __y.base(); }
4818feb0f0bSmrg
4828feb0f0bSmrg template<typename _IteratorL, typename _IteratorR>
4838feb0f0bSmrg constexpr bool
4848feb0f0bSmrg operator>(const reverse_iterator<_IteratorL>& __x,
4858feb0f0bSmrg const reverse_iterator<_IteratorR>& __y)
4868feb0f0bSmrg requires requires { { __x.base() < __y.base() } -> convertible_to<bool>; }
4878feb0f0bSmrg { return __x.base() < __y.base(); }
4888feb0f0bSmrg
4898feb0f0bSmrg template<typename _IteratorL, typename _IteratorR>
4908feb0f0bSmrg constexpr bool
4918feb0f0bSmrg operator<=(const reverse_iterator<_IteratorL>& __x,
4928feb0f0bSmrg const reverse_iterator<_IteratorR>& __y)
4938feb0f0bSmrg requires requires { { __x.base() >= __y.base() } -> convertible_to<bool>; }
4948feb0f0bSmrg { return __x.base() >= __y.base(); }
4958feb0f0bSmrg
4968feb0f0bSmrg template<typename _IteratorL, typename _IteratorR>
4978feb0f0bSmrg constexpr bool
4988feb0f0bSmrg operator>=(const reverse_iterator<_IteratorL>& __x,
4998feb0f0bSmrg const reverse_iterator<_IteratorR>& __y)
5008feb0f0bSmrg requires requires { { __x.base() <= __y.base() } -> convertible_to<bool>; }
5018feb0f0bSmrg { return __x.base() <= __y.base(); }
5028feb0f0bSmrg
5038feb0f0bSmrg template<typename _IteratorL,
5048feb0f0bSmrg three_way_comparable_with<_IteratorL> _IteratorR>
5058feb0f0bSmrg constexpr compare_three_way_result_t<_IteratorL, _IteratorR>
5068feb0f0bSmrg operator<=>(const reverse_iterator<_IteratorL>& __x,
5078feb0f0bSmrg const reverse_iterator<_IteratorR>& __y)
5088feb0f0bSmrg { return __y.base() <=> __x.base(); }
5098feb0f0bSmrg
5108feb0f0bSmrg // Additional, non-standard overloads to avoid ambiguities with greedy,
5118feb0f0bSmrg // unconstrained overloads in associated namespaces.
5128feb0f0bSmrg
5138feb0f0bSmrg template<typename _Iterator>
5148feb0f0bSmrg constexpr bool
5158feb0f0bSmrg operator==(const reverse_iterator<_Iterator>& __x,
5168feb0f0bSmrg const reverse_iterator<_Iterator>& __y)
5178feb0f0bSmrg requires requires { { __x.base() == __y.base() } -> convertible_to<bool>; }
5188feb0f0bSmrg { return __x.base() == __y.base(); }
5198feb0f0bSmrg
5208feb0f0bSmrg template<three_way_comparable _Iterator>
5218feb0f0bSmrg constexpr compare_three_way_result_t<_Iterator, _Iterator>
5228feb0f0bSmrg operator<=>(const reverse_iterator<_Iterator>& __x,
5238feb0f0bSmrg const reverse_iterator<_Iterator>& __y)
5248feb0f0bSmrg { return __y.base() <=> __x.base(); }
5258feb0f0bSmrg #endif // C++20
5268feb0f0bSmrg ///@}
5271debfc3dSmrg
5281debfc3dSmrg #if __cplusplus < 201103L
5291debfc3dSmrg template<typename _Iterator>
5301debfc3dSmrg inline typename reverse_iterator<_Iterator>::difference_type
5311debfc3dSmrg operator-(const reverse_iterator<_Iterator>& __x,
5321debfc3dSmrg const reverse_iterator<_Iterator>& __y)
5331debfc3dSmrg { return __y.base() - __x.base(); }
5341debfc3dSmrg
5351debfc3dSmrg template<typename _IteratorL, typename _IteratorR>
5361debfc3dSmrg inline typename reverse_iterator<_IteratorL>::difference_type
5371debfc3dSmrg operator-(const reverse_iterator<_IteratorL>& __x,
5381debfc3dSmrg const reverse_iterator<_IteratorR>& __y)
5391debfc3dSmrg { return __y.base() - __x.base(); }
5401debfc3dSmrg #else
5411debfc3dSmrg // _GLIBCXX_RESOLVE_LIB_DEFECTS
5421debfc3dSmrg // DR 685. reverse_iterator/move_iterator difference has invalid signatures
5431debfc3dSmrg template<typename _IteratorL, typename _IteratorR>
5441debfc3dSmrg inline _GLIBCXX17_CONSTEXPR auto
5451debfc3dSmrg operator-(const reverse_iterator<_IteratorL>& __x,
5461debfc3dSmrg const reverse_iterator<_IteratorR>& __y)
5471debfc3dSmrg -> decltype(__y.base() - __x.base())
5481debfc3dSmrg { return __y.base() - __x.base(); }
5491debfc3dSmrg #endif
5501debfc3dSmrg
5511debfc3dSmrg template<typename _Iterator>
5521debfc3dSmrg inline _GLIBCXX17_CONSTEXPR reverse_iterator<_Iterator>
5531debfc3dSmrg operator+(typename reverse_iterator<_Iterator>::difference_type __n,
5541debfc3dSmrg const reverse_iterator<_Iterator>& __x)
5551debfc3dSmrg { return reverse_iterator<_Iterator>(__x.base() - __n); }
5561debfc3dSmrg
5571debfc3dSmrg #if __cplusplus >= 201103L
558c0a68be4Smrg // Same as C++14 make_reverse_iterator but used in C++11 mode too.
5591debfc3dSmrg template<typename _Iterator>
5601debfc3dSmrg inline _GLIBCXX17_CONSTEXPR reverse_iterator<_Iterator>
5611debfc3dSmrg __make_reverse_iterator(_Iterator __i)
5621debfc3dSmrg { return reverse_iterator<_Iterator>(__i); }
5631debfc3dSmrg
5648feb0f0bSmrg # if __cplusplus >= 201402L
5651debfc3dSmrg # define __cpp_lib_make_reverse_iterator 201402
5661debfc3dSmrg
5671debfc3dSmrg // _GLIBCXX_RESOLVE_LIB_DEFECTS
5681debfc3dSmrg // DR 2285. make_reverse_iterator
5691debfc3dSmrg /// Generator function for reverse_iterator.
5701debfc3dSmrg template<typename _Iterator>
5711debfc3dSmrg inline _GLIBCXX17_CONSTEXPR reverse_iterator<_Iterator>
5721debfc3dSmrg make_reverse_iterator(_Iterator __i)
5731debfc3dSmrg { return reverse_iterator<_Iterator>(__i); }
5741debfc3dSmrg
5758feb0f0bSmrg # if __cplusplus > 201703L && defined __cpp_lib_concepts
5768feb0f0bSmrg template<typename _Iterator1, typename _Iterator2>
5778feb0f0bSmrg requires (!sized_sentinel_for<_Iterator1, _Iterator2>)
5788feb0f0bSmrg inline constexpr bool
5798feb0f0bSmrg disable_sized_sentinel_for<reverse_iterator<_Iterator1>,
5808feb0f0bSmrg reverse_iterator<_Iterator2>> = true;
5818feb0f0bSmrg # endif // C++20
5828feb0f0bSmrg # endif // C++14
5838feb0f0bSmrg
5841debfc3dSmrg template<typename _Iterator>
5858feb0f0bSmrg _GLIBCXX20_CONSTEXPR
5861debfc3dSmrg auto
5871debfc3dSmrg __niter_base(reverse_iterator<_Iterator> __it)
5881debfc3dSmrg -> decltype(__make_reverse_iterator(__niter_base(__it.base())))
5891debfc3dSmrg { return __make_reverse_iterator(__niter_base(__it.base())); }
5901debfc3dSmrg
5911debfc3dSmrg template<typename _Iterator>
5921debfc3dSmrg struct __is_move_iterator<reverse_iterator<_Iterator> >
5931debfc3dSmrg : __is_move_iterator<_Iterator>
5941debfc3dSmrg { };
5951debfc3dSmrg
5961debfc3dSmrg template<typename _Iterator>
5978feb0f0bSmrg _GLIBCXX20_CONSTEXPR
5981debfc3dSmrg auto
5991debfc3dSmrg __miter_base(reverse_iterator<_Iterator> __it)
6001debfc3dSmrg -> decltype(__make_reverse_iterator(__miter_base(__it.base())))
6011debfc3dSmrg { return __make_reverse_iterator(__miter_base(__it.base())); }
6028feb0f0bSmrg #endif // C++11
6031debfc3dSmrg
6041debfc3dSmrg // 24.4.2.2.1 back_insert_iterator
6051debfc3dSmrg /**
6061debfc3dSmrg * @brief Turns assignment into insertion.
6071debfc3dSmrg *
6081debfc3dSmrg * These are output iterators, constructed from a container-of-T.
6091debfc3dSmrg * Assigning a T to the iterator appends it to the container using
6101debfc3dSmrg * push_back.
6111debfc3dSmrg *
6121debfc3dSmrg * Tip: Using the back_inserter function to create these iterators can
6131debfc3dSmrg * save typing.
6141debfc3dSmrg */
6151debfc3dSmrg template<typename _Container>
6161debfc3dSmrg class back_insert_iterator
6171debfc3dSmrg : public iterator<output_iterator_tag, void, void, void, void>
6181debfc3dSmrg {
6191debfc3dSmrg protected:
6201debfc3dSmrg _Container* container;
6211debfc3dSmrg
6221debfc3dSmrg public:
6231debfc3dSmrg /// A nested typedef for the type of whatever container you used.
6241debfc3dSmrg typedef _Container container_type;
6258feb0f0bSmrg #if __cplusplus > 201703L
6268feb0f0bSmrg using difference_type = ptrdiff_t;
6278feb0f0bSmrg
6288feb0f0bSmrg constexpr back_insert_iterator() noexcept : container(nullptr) { }
6298feb0f0bSmrg #endif
6301debfc3dSmrg
6311debfc3dSmrg /// The only way to create this %iterator is with a container.
6328feb0f0bSmrg explicit _GLIBCXX20_CONSTEXPR
6331debfc3dSmrg back_insert_iterator(_Container& __x)
6341debfc3dSmrg : container(std::__addressof(__x)) { }
6351debfc3dSmrg
6361debfc3dSmrg /**
6371debfc3dSmrg * @param __value An instance of whatever type
6381debfc3dSmrg * container_type::const_reference is; presumably a
6391debfc3dSmrg * reference-to-const T for container<T>.
6401debfc3dSmrg * @return This %iterator, for chained operations.
6411debfc3dSmrg *
6421debfc3dSmrg * This kind of %iterator doesn't really have a @a position in the
6431debfc3dSmrg * container (you can think of the position as being permanently at
6441debfc3dSmrg * the end, if you like). Assigning a value to the %iterator will
6451debfc3dSmrg * always append the value to the end of the container.
6461debfc3dSmrg */
6471debfc3dSmrg #if __cplusplus < 201103L
6481debfc3dSmrg back_insert_iterator&
6491debfc3dSmrg operator=(typename _Container::const_reference __value)
6501debfc3dSmrg {
6511debfc3dSmrg container->push_back(__value);
6521debfc3dSmrg return *this;
6531debfc3dSmrg }
6541debfc3dSmrg #else
6558feb0f0bSmrg _GLIBCXX20_CONSTEXPR
6561debfc3dSmrg back_insert_iterator&
6571debfc3dSmrg operator=(const typename _Container::value_type& __value)
6581debfc3dSmrg {
6591debfc3dSmrg container->push_back(__value);
6601debfc3dSmrg return *this;
6611debfc3dSmrg }
6621debfc3dSmrg
6638feb0f0bSmrg _GLIBCXX20_CONSTEXPR
6641debfc3dSmrg back_insert_iterator&
6651debfc3dSmrg operator=(typename _Container::value_type&& __value)
6661debfc3dSmrg {
6671debfc3dSmrg container->push_back(std::move(__value));
6681debfc3dSmrg return *this;
6691debfc3dSmrg }
6701debfc3dSmrg #endif
6711debfc3dSmrg
6721debfc3dSmrg /// Simply returns *this.
6738feb0f0bSmrg _GLIBCXX20_CONSTEXPR
6741debfc3dSmrg back_insert_iterator&
6751debfc3dSmrg operator*()
6761debfc3dSmrg { return *this; }
6771debfc3dSmrg
6781debfc3dSmrg /// Simply returns *this. (This %iterator does not @a move.)
6798feb0f0bSmrg _GLIBCXX20_CONSTEXPR
6801debfc3dSmrg back_insert_iterator&
6811debfc3dSmrg operator++()
6821debfc3dSmrg { return *this; }
6831debfc3dSmrg
6841debfc3dSmrg /// Simply returns *this. (This %iterator does not @a move.)
6858feb0f0bSmrg _GLIBCXX20_CONSTEXPR
6861debfc3dSmrg back_insert_iterator
6871debfc3dSmrg operator++(int)
6881debfc3dSmrg { return *this; }
6891debfc3dSmrg };
6901debfc3dSmrg
6911debfc3dSmrg /**
6921debfc3dSmrg * @param __x A container of arbitrary type.
6931debfc3dSmrg * @return An instance of back_insert_iterator working on @p __x.
6941debfc3dSmrg *
6951debfc3dSmrg * This wrapper function helps in creating back_insert_iterator instances.
6961debfc3dSmrg * Typing the name of the %iterator requires knowing the precise full
6971debfc3dSmrg * type of the container, which can be tedious and impedes generic
6981debfc3dSmrg * programming. Using this function lets you take advantage of automatic
6991debfc3dSmrg * template parameter deduction, making the compiler match the correct
7001debfc3dSmrg * types for you.
7011debfc3dSmrg */
7021debfc3dSmrg template<typename _Container>
7038feb0f0bSmrg _GLIBCXX20_CONSTEXPR
7041debfc3dSmrg inline back_insert_iterator<_Container>
7051debfc3dSmrg back_inserter(_Container& __x)
7061debfc3dSmrg { return back_insert_iterator<_Container>(__x); }
7071debfc3dSmrg
7081debfc3dSmrg /**
7091debfc3dSmrg * @brief Turns assignment into insertion.
7101debfc3dSmrg *
7111debfc3dSmrg * These are output iterators, constructed from a container-of-T.
7121debfc3dSmrg * Assigning a T to the iterator prepends it to the container using
7131debfc3dSmrg * push_front.
7141debfc3dSmrg *
7151debfc3dSmrg * Tip: Using the front_inserter function to create these iterators can
7161debfc3dSmrg * save typing.
7171debfc3dSmrg */
7181debfc3dSmrg template<typename _Container>
7191debfc3dSmrg class front_insert_iterator
7201debfc3dSmrg : public iterator<output_iterator_tag, void, void, void, void>
7211debfc3dSmrg {
7221debfc3dSmrg protected:
7231debfc3dSmrg _Container* container;
7241debfc3dSmrg
7251debfc3dSmrg public:
7261debfc3dSmrg /// A nested typedef for the type of whatever container you used.
7271debfc3dSmrg typedef _Container container_type;
7288feb0f0bSmrg #if __cplusplus > 201703L
7298feb0f0bSmrg using difference_type = ptrdiff_t;
7308feb0f0bSmrg
7318feb0f0bSmrg constexpr front_insert_iterator() noexcept : container(nullptr) { }
7328feb0f0bSmrg #endif
7331debfc3dSmrg
7341debfc3dSmrg /// The only way to create this %iterator is with a container.
7358feb0f0bSmrg explicit _GLIBCXX20_CONSTEXPR
7368feb0f0bSmrg front_insert_iterator(_Container& __x)
7371debfc3dSmrg : container(std::__addressof(__x)) { }
7381debfc3dSmrg
7391debfc3dSmrg /**
7401debfc3dSmrg * @param __value An instance of whatever type
7411debfc3dSmrg * container_type::const_reference is; presumably a
7421debfc3dSmrg * reference-to-const T for container<T>.
7431debfc3dSmrg * @return This %iterator, for chained operations.
7441debfc3dSmrg *
7451debfc3dSmrg * This kind of %iterator doesn't really have a @a position in the
7461debfc3dSmrg * container (you can think of the position as being permanently at
7471debfc3dSmrg * the front, if you like). Assigning a value to the %iterator will
7481debfc3dSmrg * always prepend the value to the front of the container.
7491debfc3dSmrg */
7501debfc3dSmrg #if __cplusplus < 201103L
7511debfc3dSmrg front_insert_iterator&
7521debfc3dSmrg operator=(typename _Container::const_reference __value)
7531debfc3dSmrg {
7541debfc3dSmrg container->push_front(__value);
7551debfc3dSmrg return *this;
7561debfc3dSmrg }
7571debfc3dSmrg #else
7588feb0f0bSmrg _GLIBCXX20_CONSTEXPR
7591debfc3dSmrg front_insert_iterator&
7601debfc3dSmrg operator=(const typename _Container::value_type& __value)
7611debfc3dSmrg {
7621debfc3dSmrg container->push_front(__value);
7631debfc3dSmrg return *this;
7641debfc3dSmrg }
7651debfc3dSmrg
7668feb0f0bSmrg _GLIBCXX20_CONSTEXPR
7671debfc3dSmrg front_insert_iterator&
7681debfc3dSmrg operator=(typename _Container::value_type&& __value)
7691debfc3dSmrg {
7701debfc3dSmrg container->push_front(std::move(__value));
7711debfc3dSmrg return *this;
7721debfc3dSmrg }
7731debfc3dSmrg #endif
7741debfc3dSmrg
7751debfc3dSmrg /// Simply returns *this.
7768feb0f0bSmrg _GLIBCXX20_CONSTEXPR
7771debfc3dSmrg front_insert_iterator&
7781debfc3dSmrg operator*()
7791debfc3dSmrg { return *this; }
7801debfc3dSmrg
7811debfc3dSmrg /// Simply returns *this. (This %iterator does not @a move.)
7828feb0f0bSmrg _GLIBCXX20_CONSTEXPR
7831debfc3dSmrg front_insert_iterator&
7841debfc3dSmrg operator++()
7851debfc3dSmrg { return *this; }
7861debfc3dSmrg
7871debfc3dSmrg /// Simply returns *this. (This %iterator does not @a move.)
7888feb0f0bSmrg _GLIBCXX20_CONSTEXPR
7891debfc3dSmrg front_insert_iterator
7901debfc3dSmrg operator++(int)
7911debfc3dSmrg { return *this; }
7921debfc3dSmrg };
7931debfc3dSmrg
7941debfc3dSmrg /**
7951debfc3dSmrg * @param __x A container of arbitrary type.
7961debfc3dSmrg * @return An instance of front_insert_iterator working on @p x.
7971debfc3dSmrg *
7981debfc3dSmrg * This wrapper function helps in creating front_insert_iterator instances.
7991debfc3dSmrg * Typing the name of the %iterator requires knowing the precise full
8001debfc3dSmrg * type of the container, which can be tedious and impedes generic
8011debfc3dSmrg * programming. Using this function lets you take advantage of automatic
8021debfc3dSmrg * template parameter deduction, making the compiler match the correct
8031debfc3dSmrg * types for you.
8041debfc3dSmrg */
8051debfc3dSmrg template<typename _Container>
8068feb0f0bSmrg _GLIBCXX20_CONSTEXPR
8071debfc3dSmrg inline front_insert_iterator<_Container>
8081debfc3dSmrg front_inserter(_Container& __x)
8091debfc3dSmrg { return front_insert_iterator<_Container>(__x); }
8101debfc3dSmrg
8111debfc3dSmrg /**
8121debfc3dSmrg * @brief Turns assignment into insertion.
8131debfc3dSmrg *
8141debfc3dSmrg * These are output iterators, constructed from a container-of-T.
8151debfc3dSmrg * Assigning a T to the iterator inserts it in the container at the
8161debfc3dSmrg * %iterator's position, rather than overwriting the value at that
8171debfc3dSmrg * position.
8181debfc3dSmrg *
8191debfc3dSmrg * (Sequences will actually insert a @e copy of the value before the
8201debfc3dSmrg * %iterator's position.)
8211debfc3dSmrg *
8221debfc3dSmrg * Tip: Using the inserter function to create these iterators can
8231debfc3dSmrg * save typing.
8241debfc3dSmrg */
8251debfc3dSmrg template<typename _Container>
8261debfc3dSmrg class insert_iterator
8271debfc3dSmrg : public iterator<output_iterator_tag, void, void, void, void>
8281debfc3dSmrg {
8298feb0f0bSmrg #if __cplusplus > 201703L && defined __cpp_lib_concepts
8308feb0f0bSmrg using _Iter = std::__detail::__range_iter_t<_Container>;
8318feb0f0bSmrg
8328feb0f0bSmrg protected:
8338feb0f0bSmrg _Container* container = nullptr;
8348feb0f0bSmrg _Iter iter = _Iter();
8358feb0f0bSmrg #else
8368feb0f0bSmrg typedef typename _Container::iterator _Iter;
8378feb0f0bSmrg
8381debfc3dSmrg protected:
8391debfc3dSmrg _Container* container;
8408feb0f0bSmrg _Iter iter;
8418feb0f0bSmrg #endif
8421debfc3dSmrg
8431debfc3dSmrg public:
8441debfc3dSmrg /// A nested typedef for the type of whatever container you used.
8451debfc3dSmrg typedef _Container container_type;
8461debfc3dSmrg
8478feb0f0bSmrg #if __cplusplus > 201703L && defined __cpp_lib_concepts
8488feb0f0bSmrg using difference_type = ptrdiff_t;
8498feb0f0bSmrg
8508feb0f0bSmrg insert_iterator() = default;
8518feb0f0bSmrg #endif
8528feb0f0bSmrg
8531debfc3dSmrg /**
8541debfc3dSmrg * The only way to create this %iterator is with a container and an
8551debfc3dSmrg * initial position (a normal %iterator into the container).
8561debfc3dSmrg */
8578feb0f0bSmrg _GLIBCXX20_CONSTEXPR
8588feb0f0bSmrg insert_iterator(_Container& __x, _Iter __i)
8591debfc3dSmrg : container(std::__addressof(__x)), iter(__i) {}
8601debfc3dSmrg
8611debfc3dSmrg /**
8621debfc3dSmrg * @param __value An instance of whatever type
8631debfc3dSmrg * container_type::const_reference is; presumably a
8641debfc3dSmrg * reference-to-const T for container<T>.
8651debfc3dSmrg * @return This %iterator, for chained operations.
8661debfc3dSmrg *
8671debfc3dSmrg * This kind of %iterator maintains its own position in the
8681debfc3dSmrg * container. Assigning a value to the %iterator will insert the
8691debfc3dSmrg * value into the container at the place before the %iterator.
8701debfc3dSmrg *
8711debfc3dSmrg * The position is maintained such that subsequent assignments will
8721debfc3dSmrg * insert values immediately after one another. For example,
8731debfc3dSmrg * @code
8741debfc3dSmrg * // vector v contains A and Z
8751debfc3dSmrg *
8761debfc3dSmrg * insert_iterator i (v, ++v.begin());
8771debfc3dSmrg * i = 1;
8781debfc3dSmrg * i = 2;
8791debfc3dSmrg * i = 3;
8801debfc3dSmrg *
8811debfc3dSmrg * // vector v contains A, 1, 2, 3, and Z
8821debfc3dSmrg * @endcode
8831debfc3dSmrg */
8841debfc3dSmrg #if __cplusplus < 201103L
8851debfc3dSmrg insert_iterator&
8861debfc3dSmrg operator=(typename _Container::const_reference __value)
8871debfc3dSmrg {
8881debfc3dSmrg iter = container->insert(iter, __value);
8891debfc3dSmrg ++iter;
8901debfc3dSmrg return *this;
8911debfc3dSmrg }
8921debfc3dSmrg #else
8938feb0f0bSmrg _GLIBCXX20_CONSTEXPR
8941debfc3dSmrg insert_iterator&
8951debfc3dSmrg operator=(const typename _Container::value_type& __value)
8961debfc3dSmrg {
8971debfc3dSmrg iter = container->insert(iter, __value);
8981debfc3dSmrg ++iter;
8991debfc3dSmrg return *this;
9001debfc3dSmrg }
9011debfc3dSmrg
9028feb0f0bSmrg _GLIBCXX20_CONSTEXPR
9031debfc3dSmrg insert_iterator&
9041debfc3dSmrg operator=(typename _Container::value_type&& __value)
9051debfc3dSmrg {
9061debfc3dSmrg iter = container->insert(iter, std::move(__value));
9071debfc3dSmrg ++iter;
9081debfc3dSmrg return *this;
9091debfc3dSmrg }
9101debfc3dSmrg #endif
9111debfc3dSmrg
9121debfc3dSmrg /// Simply returns *this.
9138feb0f0bSmrg _GLIBCXX20_CONSTEXPR
9141debfc3dSmrg insert_iterator&
9151debfc3dSmrg operator*()
9161debfc3dSmrg { return *this; }
9171debfc3dSmrg
9181debfc3dSmrg /// Simply returns *this. (This %iterator does not @a move.)
9198feb0f0bSmrg _GLIBCXX20_CONSTEXPR
9201debfc3dSmrg insert_iterator&
9211debfc3dSmrg operator++()
9221debfc3dSmrg { return *this; }
9231debfc3dSmrg
9241debfc3dSmrg /// Simply returns *this. (This %iterator does not @a move.)
9258feb0f0bSmrg _GLIBCXX20_CONSTEXPR
9261debfc3dSmrg insert_iterator&
9271debfc3dSmrg operator++(int)
9281debfc3dSmrg { return *this; }
9291debfc3dSmrg };
9301debfc3dSmrg
9311debfc3dSmrg /**
9321debfc3dSmrg * @param __x A container of arbitrary type.
933a2dc1f3fSmrg * @param __i An iterator into the container.
9341debfc3dSmrg * @return An instance of insert_iterator working on @p __x.
9351debfc3dSmrg *
9361debfc3dSmrg * This wrapper function helps in creating insert_iterator instances.
9371debfc3dSmrg * Typing the name of the %iterator requires knowing the precise full
9381debfc3dSmrg * type of the container, which can be tedious and impedes generic
9391debfc3dSmrg * programming. Using this function lets you take advantage of automatic
9401debfc3dSmrg * template parameter deduction, making the compiler match the correct
9411debfc3dSmrg * types for you.
9421debfc3dSmrg */
9438feb0f0bSmrg #if __cplusplus > 201703L && defined __cpp_lib_concepts
9448feb0f0bSmrg template<typename _Container>
9458feb0f0bSmrg constexpr insert_iterator<_Container>
9468feb0f0bSmrg inserter(_Container& __x, std::__detail::__range_iter_t<_Container> __i)
9478feb0f0bSmrg { return insert_iterator<_Container>(__x, __i); }
9488feb0f0bSmrg #else
9498feb0f0bSmrg template<typename _Container>
9501debfc3dSmrg inline insert_iterator<_Container>
9518feb0f0bSmrg inserter(_Container& __x, typename _Container::iterator __i)
9528feb0f0bSmrg { return insert_iterator<_Container>(__x, __i); }
9538feb0f0bSmrg #endif
9541debfc3dSmrg
9558feb0f0bSmrg /// @} group iterators
9561debfc3dSmrg
9571debfc3dSmrg _GLIBCXX_END_NAMESPACE_VERSION
9581debfc3dSmrg } // namespace
9591debfc3dSmrg
9601debfc3dSmrg namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
9611debfc3dSmrg {
9621debfc3dSmrg _GLIBCXX_BEGIN_NAMESPACE_VERSION
9631debfc3dSmrg
9641debfc3dSmrg // This iterator adapter is @a normal in the sense that it does not
9651debfc3dSmrg // change the semantics of any of the operators of its iterator
9661debfc3dSmrg // parameter. Its primary purpose is to convert an iterator that is
9671debfc3dSmrg // not a class, e.g. a pointer, into an iterator that is a class.
9681debfc3dSmrg // The _Container parameter exists solely so that different containers
9691debfc3dSmrg // using this template can instantiate different types, even if the
9701debfc3dSmrg // _Iterator parameter is the same.
9711debfc3dSmrg template<typename _Iterator, typename _Container>
9721debfc3dSmrg class __normal_iterator
9731debfc3dSmrg {
9741debfc3dSmrg protected:
9751debfc3dSmrg _Iterator _M_current;
9761debfc3dSmrg
9778feb0f0bSmrg typedef std::iterator_traits<_Iterator> __traits_type;
9781debfc3dSmrg
9791debfc3dSmrg public:
9801debfc3dSmrg typedef _Iterator iterator_type;
9811debfc3dSmrg typedef typename __traits_type::iterator_category iterator_category;
9821debfc3dSmrg typedef typename __traits_type::value_type value_type;
9831debfc3dSmrg typedef typename __traits_type::difference_type difference_type;
9841debfc3dSmrg typedef typename __traits_type::reference reference;
9851debfc3dSmrg typedef typename __traits_type::pointer pointer;
9861debfc3dSmrg
9878feb0f0bSmrg #if __cplusplus > 201703L && __cpp_lib_concepts
9888feb0f0bSmrg using iterator_concept = std::__detail::__iter_concept<_Iterator>;
9898feb0f0bSmrg #endif
9908feb0f0bSmrg
9911debfc3dSmrg _GLIBCXX_CONSTEXPR __normal_iterator() _GLIBCXX_NOEXCEPT
9921debfc3dSmrg : _M_current(_Iterator()) { }
9931debfc3dSmrg
9948feb0f0bSmrg explicit _GLIBCXX20_CONSTEXPR
9951debfc3dSmrg __normal_iterator(const _Iterator& __i) _GLIBCXX_NOEXCEPT
9961debfc3dSmrg : _M_current(__i) { }
9971debfc3dSmrg
9981debfc3dSmrg // Allow iterator to const_iterator conversion
9991debfc3dSmrg template<typename _Iter>
10008feb0f0bSmrg _GLIBCXX20_CONSTEXPR
10011debfc3dSmrg __normal_iterator(const __normal_iterator<_Iter,
10021debfc3dSmrg typename __enable_if<
10031debfc3dSmrg (std::__are_same<_Iter, typename _Container::pointer>::__value),
10041debfc3dSmrg _Container>::__type>& __i) _GLIBCXX_NOEXCEPT
10051debfc3dSmrg : _M_current(__i.base()) { }
10061debfc3dSmrg
10071debfc3dSmrg // Forward iterator requirements
10088feb0f0bSmrg _GLIBCXX20_CONSTEXPR
10091debfc3dSmrg reference
10101debfc3dSmrg operator*() const _GLIBCXX_NOEXCEPT
10111debfc3dSmrg { return *_M_current; }
10121debfc3dSmrg
10138feb0f0bSmrg _GLIBCXX20_CONSTEXPR
10141debfc3dSmrg pointer
10151debfc3dSmrg operator->() const _GLIBCXX_NOEXCEPT
10161debfc3dSmrg { return _M_current; }
10171debfc3dSmrg
10188feb0f0bSmrg _GLIBCXX20_CONSTEXPR
10191debfc3dSmrg __normal_iterator&
10201debfc3dSmrg operator++() _GLIBCXX_NOEXCEPT
10211debfc3dSmrg {
10221debfc3dSmrg ++_M_current;
10231debfc3dSmrg return *this;
10241debfc3dSmrg }
10251debfc3dSmrg
10268feb0f0bSmrg _GLIBCXX20_CONSTEXPR
10271debfc3dSmrg __normal_iterator
10281debfc3dSmrg operator++(int) _GLIBCXX_NOEXCEPT
10291debfc3dSmrg { return __normal_iterator(_M_current++); }
10301debfc3dSmrg
10311debfc3dSmrg // Bidirectional iterator requirements
10328feb0f0bSmrg _GLIBCXX20_CONSTEXPR
10331debfc3dSmrg __normal_iterator&
10341debfc3dSmrg operator--() _GLIBCXX_NOEXCEPT
10351debfc3dSmrg {
10361debfc3dSmrg --_M_current;
10371debfc3dSmrg return *this;
10381debfc3dSmrg }
10391debfc3dSmrg
10408feb0f0bSmrg _GLIBCXX20_CONSTEXPR
10411debfc3dSmrg __normal_iterator
10421debfc3dSmrg operator--(int) _GLIBCXX_NOEXCEPT
10431debfc3dSmrg { return __normal_iterator(_M_current--); }
10441debfc3dSmrg
10451debfc3dSmrg // Random access iterator requirements
10468feb0f0bSmrg _GLIBCXX20_CONSTEXPR
10471debfc3dSmrg reference
10481debfc3dSmrg operator[](difference_type __n) const _GLIBCXX_NOEXCEPT
10491debfc3dSmrg { return _M_current[__n]; }
10501debfc3dSmrg
10518feb0f0bSmrg _GLIBCXX20_CONSTEXPR
10521debfc3dSmrg __normal_iterator&
10531debfc3dSmrg operator+=(difference_type __n) _GLIBCXX_NOEXCEPT
10541debfc3dSmrg { _M_current += __n; return *this; }
10551debfc3dSmrg
10568feb0f0bSmrg _GLIBCXX20_CONSTEXPR
10571debfc3dSmrg __normal_iterator
10581debfc3dSmrg operator+(difference_type __n) const _GLIBCXX_NOEXCEPT
10591debfc3dSmrg { return __normal_iterator(_M_current + __n); }
10601debfc3dSmrg
10618feb0f0bSmrg _GLIBCXX20_CONSTEXPR
10621debfc3dSmrg __normal_iterator&
10631debfc3dSmrg operator-=(difference_type __n) _GLIBCXX_NOEXCEPT
10641debfc3dSmrg { _M_current -= __n; return *this; }
10651debfc3dSmrg
10668feb0f0bSmrg _GLIBCXX20_CONSTEXPR
10671debfc3dSmrg __normal_iterator
10681debfc3dSmrg operator-(difference_type __n) const _GLIBCXX_NOEXCEPT
10691debfc3dSmrg { return __normal_iterator(_M_current - __n); }
10701debfc3dSmrg
10718feb0f0bSmrg _GLIBCXX20_CONSTEXPR
10721debfc3dSmrg const _Iterator&
10731debfc3dSmrg base() const _GLIBCXX_NOEXCEPT
10741debfc3dSmrg { return _M_current; }
10751debfc3dSmrg };
10761debfc3dSmrg
10771debfc3dSmrg // Note: In what follows, the left- and right-hand-side iterators are
10781debfc3dSmrg // allowed to vary in types (conceptually in cv-qualification) so that
10791debfc3dSmrg // comparison between cv-qualified and non-cv-qualified iterators be
10801debfc3dSmrg // valid. However, the greedy and unfriendly operators in std::rel_ops
10811debfc3dSmrg // will make overload resolution ambiguous (when in scope) if we don't
10821debfc3dSmrg // provide overloads whose operands are of the same type. Can someone
10831debfc3dSmrg // remind me what generic programming is about? -- Gaby
10841debfc3dSmrg
10858feb0f0bSmrg #if __cpp_lib_three_way_comparison
10868feb0f0bSmrg template<typename _IteratorL, typename _IteratorR, typename _Container>
10878feb0f0bSmrg requires requires (_IteratorL __lhs, _IteratorR __rhs)
10888feb0f0bSmrg { { __lhs == __rhs } -> std::convertible_to<bool>; }
10898feb0f0bSmrg constexpr bool
10908feb0f0bSmrg operator==(const __normal_iterator<_IteratorL, _Container>& __lhs,
10918feb0f0bSmrg const __normal_iterator<_IteratorR, _Container>& __rhs)
10928feb0f0bSmrg noexcept(noexcept(__lhs.base() == __rhs.base()))
10938feb0f0bSmrg { return __lhs.base() == __rhs.base(); }
10948feb0f0bSmrg
10958feb0f0bSmrg template<typename _IteratorL, typename _IteratorR, typename _Container>
10968feb0f0bSmrg constexpr std::__detail::__synth3way_t<_IteratorR, _IteratorL>
10978feb0f0bSmrg operator<=>(const __normal_iterator<_IteratorL, _Container>& __lhs,
10988feb0f0bSmrg const __normal_iterator<_IteratorR, _Container>& __rhs)
10998feb0f0bSmrg noexcept(noexcept(std::__detail::__synth3way(__lhs.base(), __rhs.base())))
11008feb0f0bSmrg { return std::__detail::__synth3way(__lhs.base(), __rhs.base()); }
11018feb0f0bSmrg
11028feb0f0bSmrg template<typename _Iterator, typename _Container>
11038feb0f0bSmrg constexpr bool
11048feb0f0bSmrg operator==(const __normal_iterator<_Iterator, _Container>& __lhs,
11058feb0f0bSmrg const __normal_iterator<_Iterator, _Container>& __rhs)
11068feb0f0bSmrg noexcept(noexcept(__lhs.base() == __rhs.base()))
11078feb0f0bSmrg requires requires {
11088feb0f0bSmrg { __lhs.base() == __rhs.base() } -> std::convertible_to<bool>;
11098feb0f0bSmrg }
11108feb0f0bSmrg { return __lhs.base() == __rhs.base(); }
11118feb0f0bSmrg
11128feb0f0bSmrg template<typename _Iterator, typename _Container>
11138feb0f0bSmrg constexpr std::__detail::__synth3way_t<_Iterator>
11148feb0f0bSmrg operator<=>(const __normal_iterator<_Iterator, _Container>& __lhs,
11158feb0f0bSmrg const __normal_iterator<_Iterator, _Container>& __rhs)
11168feb0f0bSmrg noexcept(noexcept(std::__detail::__synth3way(__lhs.base(), __rhs.base())))
11178feb0f0bSmrg { return std::__detail::__synth3way(__lhs.base(), __rhs.base()); }
11188feb0f0bSmrg #else
11191debfc3dSmrg // Forward iterator requirements
11201debfc3dSmrg template<typename _IteratorL, typename _IteratorR, typename _Container>
11218feb0f0bSmrg _GLIBCXX20_CONSTEXPR
11221debfc3dSmrg inline bool
11231debfc3dSmrg operator==(const __normal_iterator<_IteratorL, _Container>& __lhs,
11241debfc3dSmrg const __normal_iterator<_IteratorR, _Container>& __rhs)
11251debfc3dSmrg _GLIBCXX_NOEXCEPT
11261debfc3dSmrg { return __lhs.base() == __rhs.base(); }
11271debfc3dSmrg
11281debfc3dSmrg template<typename _Iterator, typename _Container>
11298feb0f0bSmrg _GLIBCXX20_CONSTEXPR
11301debfc3dSmrg inline bool
11311debfc3dSmrg operator==(const __normal_iterator<_Iterator, _Container>& __lhs,
11321debfc3dSmrg const __normal_iterator<_Iterator, _Container>& __rhs)
11331debfc3dSmrg _GLIBCXX_NOEXCEPT
11341debfc3dSmrg { return __lhs.base() == __rhs.base(); }
11351debfc3dSmrg
11361debfc3dSmrg template<typename _IteratorL, typename _IteratorR, typename _Container>
11378feb0f0bSmrg _GLIBCXX20_CONSTEXPR
11381debfc3dSmrg inline bool
11391debfc3dSmrg operator!=(const __normal_iterator<_IteratorL, _Container>& __lhs,
11401debfc3dSmrg const __normal_iterator<_IteratorR, _Container>& __rhs)
11411debfc3dSmrg _GLIBCXX_NOEXCEPT
11421debfc3dSmrg { return __lhs.base() != __rhs.base(); }
11431debfc3dSmrg
11441debfc3dSmrg template<typename _Iterator, typename _Container>
11458feb0f0bSmrg _GLIBCXX20_CONSTEXPR
11461debfc3dSmrg inline bool
11471debfc3dSmrg operator!=(const __normal_iterator<_Iterator, _Container>& __lhs,
11481debfc3dSmrg const __normal_iterator<_Iterator, _Container>& __rhs)
11491debfc3dSmrg _GLIBCXX_NOEXCEPT
11501debfc3dSmrg { return __lhs.base() != __rhs.base(); }
11511debfc3dSmrg
11521debfc3dSmrg // Random access iterator requirements
11531debfc3dSmrg template<typename _IteratorL, typename _IteratorR, typename _Container>
11541debfc3dSmrg inline bool
11551debfc3dSmrg operator<(const __normal_iterator<_IteratorL, _Container>& __lhs,
11561debfc3dSmrg const __normal_iterator<_IteratorR, _Container>& __rhs)
11571debfc3dSmrg _GLIBCXX_NOEXCEPT
11581debfc3dSmrg { return __lhs.base() < __rhs.base(); }
11591debfc3dSmrg
11601debfc3dSmrg template<typename _Iterator, typename _Container>
11618feb0f0bSmrg _GLIBCXX20_CONSTEXPR
11621debfc3dSmrg inline bool
11631debfc3dSmrg operator<(const __normal_iterator<_Iterator, _Container>& __lhs,
11641debfc3dSmrg const __normal_iterator<_Iterator, _Container>& __rhs)
11651debfc3dSmrg _GLIBCXX_NOEXCEPT
11661debfc3dSmrg { return __lhs.base() < __rhs.base(); }
11671debfc3dSmrg
11681debfc3dSmrg template<typename _IteratorL, typename _IteratorR, typename _Container>
11691debfc3dSmrg inline bool
11701debfc3dSmrg operator>(const __normal_iterator<_IteratorL, _Container>& __lhs,
11711debfc3dSmrg const __normal_iterator<_IteratorR, _Container>& __rhs)
11721debfc3dSmrg _GLIBCXX_NOEXCEPT
11731debfc3dSmrg { return __lhs.base() > __rhs.base(); }
11741debfc3dSmrg
11751debfc3dSmrg template<typename _Iterator, typename _Container>
11768feb0f0bSmrg _GLIBCXX20_CONSTEXPR
11771debfc3dSmrg inline bool
11781debfc3dSmrg operator>(const __normal_iterator<_Iterator, _Container>& __lhs,
11791debfc3dSmrg const __normal_iterator<_Iterator, _Container>& __rhs)
11801debfc3dSmrg _GLIBCXX_NOEXCEPT
11811debfc3dSmrg { return __lhs.base() > __rhs.base(); }
11821debfc3dSmrg
11831debfc3dSmrg template<typename _IteratorL, typename _IteratorR, typename _Container>
11841debfc3dSmrg inline bool
11851debfc3dSmrg operator<=(const __normal_iterator<_IteratorL, _Container>& __lhs,
11861debfc3dSmrg const __normal_iterator<_IteratorR, _Container>& __rhs)
11871debfc3dSmrg _GLIBCXX_NOEXCEPT
11881debfc3dSmrg { return __lhs.base() <= __rhs.base(); }
11891debfc3dSmrg
11901debfc3dSmrg template<typename _Iterator, typename _Container>
11918feb0f0bSmrg _GLIBCXX20_CONSTEXPR
11921debfc3dSmrg inline bool
11931debfc3dSmrg operator<=(const __normal_iterator<_Iterator, _Container>& __lhs,
11941debfc3dSmrg const __normal_iterator<_Iterator, _Container>& __rhs)
11951debfc3dSmrg _GLIBCXX_NOEXCEPT
11961debfc3dSmrg { return __lhs.base() <= __rhs.base(); }
11971debfc3dSmrg
11981debfc3dSmrg template<typename _IteratorL, typename _IteratorR, typename _Container>
11991debfc3dSmrg inline bool
12001debfc3dSmrg operator>=(const __normal_iterator<_IteratorL, _Container>& __lhs,
12011debfc3dSmrg const __normal_iterator<_IteratorR, _Container>& __rhs)
12021debfc3dSmrg _GLIBCXX_NOEXCEPT
12031debfc3dSmrg { return __lhs.base() >= __rhs.base(); }
12041debfc3dSmrg
12051debfc3dSmrg template<typename _Iterator, typename _Container>
12068feb0f0bSmrg _GLIBCXX20_CONSTEXPR
12071debfc3dSmrg inline bool
12081debfc3dSmrg operator>=(const __normal_iterator<_Iterator, _Container>& __lhs,
12091debfc3dSmrg const __normal_iterator<_Iterator, _Container>& __rhs)
12101debfc3dSmrg _GLIBCXX_NOEXCEPT
12111debfc3dSmrg { return __lhs.base() >= __rhs.base(); }
12128feb0f0bSmrg #endif // three-way comparison
12131debfc3dSmrg
12141debfc3dSmrg // _GLIBCXX_RESOLVE_LIB_DEFECTS
12151debfc3dSmrg // According to the resolution of DR179 not only the various comparison
12161debfc3dSmrg // operators but also operator- must accept mixed iterator/const_iterator
12171debfc3dSmrg // parameters.
12181debfc3dSmrg template<typename _IteratorL, typename _IteratorR, typename _Container>
12191debfc3dSmrg #if __cplusplus >= 201103L
12201debfc3dSmrg // DR 685.
12218feb0f0bSmrg _GLIBCXX20_CONSTEXPR
12221debfc3dSmrg inline auto
12231debfc3dSmrg operator-(const __normal_iterator<_IteratorL, _Container>& __lhs,
12241debfc3dSmrg const __normal_iterator<_IteratorR, _Container>& __rhs) noexcept
12251debfc3dSmrg -> decltype(__lhs.base() - __rhs.base())
12261debfc3dSmrg #else
12271debfc3dSmrg inline typename __normal_iterator<_IteratorL, _Container>::difference_type
12281debfc3dSmrg operator-(const __normal_iterator<_IteratorL, _Container>& __lhs,
12291debfc3dSmrg const __normal_iterator<_IteratorR, _Container>& __rhs)
12301debfc3dSmrg #endif
12311debfc3dSmrg { return __lhs.base() - __rhs.base(); }
12321debfc3dSmrg
12331debfc3dSmrg template<typename _Iterator, typename _Container>
12348feb0f0bSmrg _GLIBCXX20_CONSTEXPR
12351debfc3dSmrg inline typename __normal_iterator<_Iterator, _Container>::difference_type
12361debfc3dSmrg operator-(const __normal_iterator<_Iterator, _Container>& __lhs,
12371debfc3dSmrg const __normal_iterator<_Iterator, _Container>& __rhs)
12381debfc3dSmrg _GLIBCXX_NOEXCEPT
12391debfc3dSmrg { return __lhs.base() - __rhs.base(); }
12401debfc3dSmrg
12411debfc3dSmrg template<typename _Iterator, typename _Container>
12428feb0f0bSmrg _GLIBCXX20_CONSTEXPR
12431debfc3dSmrg inline __normal_iterator<_Iterator, _Container>
12441debfc3dSmrg operator+(typename __normal_iterator<_Iterator, _Container>::difference_type
12451debfc3dSmrg __n, const __normal_iterator<_Iterator, _Container>& __i)
12461debfc3dSmrg _GLIBCXX_NOEXCEPT
12471debfc3dSmrg { return __normal_iterator<_Iterator, _Container>(__i.base() + __n); }
12481debfc3dSmrg
12491debfc3dSmrg _GLIBCXX_END_NAMESPACE_VERSION
12501debfc3dSmrg } // namespace
12511debfc3dSmrg
12521debfc3dSmrg namespace std _GLIBCXX_VISIBILITY(default)
12531debfc3dSmrg {
12541debfc3dSmrg _GLIBCXX_BEGIN_NAMESPACE_VERSION
12551debfc3dSmrg
12561debfc3dSmrg template<typename _Iterator, typename _Container>
12578feb0f0bSmrg _GLIBCXX20_CONSTEXPR
12581debfc3dSmrg _Iterator
12591debfc3dSmrg __niter_base(__gnu_cxx::__normal_iterator<_Iterator, _Container> __it)
1260c0a68be4Smrg _GLIBCXX_NOEXCEPT_IF(std::is_nothrow_copy_constructible<_Iterator>::value)
12611debfc3dSmrg { return __it.base(); }
12621debfc3dSmrg
12631debfc3dSmrg #if __cplusplus >= 201103L
12641debfc3dSmrg /**
12651debfc3dSmrg * @addtogroup iterators
12661debfc3dSmrg * @{
12671debfc3dSmrg */
12681debfc3dSmrg
12698feb0f0bSmrg #if __cplusplus > 201703L && __cpp_lib_concepts
12708feb0f0bSmrg template<semiregular _Sent>
12718feb0f0bSmrg class move_sentinel
12728feb0f0bSmrg {
12738feb0f0bSmrg public:
12748feb0f0bSmrg constexpr
12758feb0f0bSmrg move_sentinel()
12768feb0f0bSmrg noexcept(is_nothrow_default_constructible_v<_Sent>)
12778feb0f0bSmrg : _M_last() { }
12788feb0f0bSmrg
12798feb0f0bSmrg constexpr explicit
12808feb0f0bSmrg move_sentinel(_Sent __s)
12818feb0f0bSmrg noexcept(is_nothrow_move_constructible_v<_Sent>)
12828feb0f0bSmrg : _M_last(std::move(__s)) { }
12838feb0f0bSmrg
12848feb0f0bSmrg template<typename _S2> requires convertible_to<const _S2&, _Sent>
12858feb0f0bSmrg constexpr
12868feb0f0bSmrg move_sentinel(const move_sentinel<_S2>& __s)
12878feb0f0bSmrg noexcept(is_nothrow_constructible_v<_Sent, const _S2&>)
12888feb0f0bSmrg : _M_last(__s.base())
12898feb0f0bSmrg { }
12908feb0f0bSmrg
12918feb0f0bSmrg template<typename _S2> requires assignable_from<_Sent&, const _S2&>
12928feb0f0bSmrg constexpr move_sentinel&
12938feb0f0bSmrg operator=(const move_sentinel<_S2>& __s)
12948feb0f0bSmrg noexcept(is_nothrow_assignable_v<_Sent, const _S2&>)
12958feb0f0bSmrg {
12968feb0f0bSmrg _M_last = __s.base();
12978feb0f0bSmrg return *this;
12988feb0f0bSmrg }
12998feb0f0bSmrg
13008feb0f0bSmrg constexpr _Sent
13018feb0f0bSmrg base() const
13028feb0f0bSmrg noexcept(is_nothrow_copy_constructible_v<_Sent>)
13038feb0f0bSmrg { return _M_last; }
13048feb0f0bSmrg
13058feb0f0bSmrg private:
13068feb0f0bSmrg _Sent _M_last;
13078feb0f0bSmrg };
13088feb0f0bSmrg #endif // C++20
13098feb0f0bSmrg
13108feb0f0bSmrg namespace __detail
13118feb0f0bSmrg {
13128feb0f0bSmrg #if __cplusplus > 201703L && __cpp_lib_concepts
13138feb0f0bSmrg template<typename _Iterator>
13148feb0f0bSmrg struct __move_iter_cat
13158feb0f0bSmrg { };
13168feb0f0bSmrg
13178feb0f0bSmrg template<typename _Iterator>
13188feb0f0bSmrg requires requires { typename iterator_traits<_Iterator>::iterator_category; }
13198feb0f0bSmrg struct __move_iter_cat<_Iterator>
13208feb0f0bSmrg {
13218feb0f0bSmrg using iterator_category
13228feb0f0bSmrg = __clamp_iter_cat<typename iterator_traits<_Iterator>::iterator_category,
13238feb0f0bSmrg random_access_iterator_tag>;
13248feb0f0bSmrg };
13258feb0f0bSmrg #endif
13268feb0f0bSmrg }
13278feb0f0bSmrg
13281debfc3dSmrg // 24.4.3 Move iterators
13291debfc3dSmrg /**
13301debfc3dSmrg * Class template move_iterator is an iterator adapter with the same
13311debfc3dSmrg * behavior as the underlying iterator except that its dereference
13321debfc3dSmrg * operator implicitly converts the value returned by the underlying
13331debfc3dSmrg * iterator's dereference operator to an rvalue reference. Some
13341debfc3dSmrg * generic algorithms can be called with move iterators to replace
13351debfc3dSmrg * copying with moving.
13361debfc3dSmrg */
13371debfc3dSmrg template<typename _Iterator>
13381debfc3dSmrg class move_iterator
13398feb0f0bSmrg #if __cplusplus > 201703L && __cpp_lib_concepts
13408feb0f0bSmrg : public __detail::__move_iter_cat<_Iterator>
13418feb0f0bSmrg #endif
13421debfc3dSmrg {
13431debfc3dSmrg _Iterator _M_current;
13441debfc3dSmrg
13458feb0f0bSmrg using __traits_type = iterator_traits<_Iterator>;
13468feb0f0bSmrg #if ! (__cplusplus > 201703L && __cpp_lib_concepts)
13478feb0f0bSmrg using __base_ref = typename __traits_type::reference;
13488feb0f0bSmrg #endif
13491debfc3dSmrg
13501debfc3dSmrg public:
13518feb0f0bSmrg using iterator_type = _Iterator;
13528feb0f0bSmrg
13538feb0f0bSmrg #if __cplusplus > 201703L && __cpp_lib_concepts
13548feb0f0bSmrg using iterator_concept = input_iterator_tag;
13558feb0f0bSmrg // iterator_category defined in __move_iter_cat
13568feb0f0bSmrg using value_type = iter_value_t<_Iterator>;
13578feb0f0bSmrg using difference_type = iter_difference_t<_Iterator>;
13588feb0f0bSmrg using pointer = _Iterator;
13598feb0f0bSmrg using reference = iter_rvalue_reference_t<_Iterator>;
13608feb0f0bSmrg #else
13611debfc3dSmrg typedef typename __traits_type::iterator_category iterator_category;
13621debfc3dSmrg typedef typename __traits_type::value_type value_type;
13631debfc3dSmrg typedef typename __traits_type::difference_type difference_type;
13641debfc3dSmrg // NB: DR 680.
13651debfc3dSmrg typedef _Iterator pointer;
13661debfc3dSmrg // _GLIBCXX_RESOLVE_LIB_DEFECTS
13671debfc3dSmrg // 2106. move_iterator wrapping iterators returning prvalues
13681debfc3dSmrg typedef typename conditional<is_reference<__base_ref>::value,
13691debfc3dSmrg typename remove_reference<__base_ref>::type&&,
13701debfc3dSmrg __base_ref>::type reference;
13718feb0f0bSmrg #endif
13721debfc3dSmrg
13731debfc3dSmrg _GLIBCXX17_CONSTEXPR
13741debfc3dSmrg move_iterator()
13751debfc3dSmrg : _M_current() { }
13761debfc3dSmrg
13771debfc3dSmrg explicit _GLIBCXX17_CONSTEXPR
13781debfc3dSmrg move_iterator(iterator_type __i)
13798feb0f0bSmrg : _M_current(std::move(__i)) { }
13801debfc3dSmrg
13811debfc3dSmrg template<typename _Iter>
13821debfc3dSmrg _GLIBCXX17_CONSTEXPR
13831debfc3dSmrg move_iterator(const move_iterator<_Iter>& __i)
13841debfc3dSmrg : _M_current(__i.base()) { }
13851debfc3dSmrg
13868feb0f0bSmrg template<typename _Iter>
13878feb0f0bSmrg _GLIBCXX17_CONSTEXPR
13888feb0f0bSmrg move_iterator& operator=(const move_iterator<_Iter>& __i)
13898feb0f0bSmrg {
13908feb0f0bSmrg _M_current = __i.base();
13918feb0f0bSmrg return *this;
13928feb0f0bSmrg }
13938feb0f0bSmrg
13948feb0f0bSmrg #if __cplusplus <= 201703L
13951debfc3dSmrg _GLIBCXX17_CONSTEXPR iterator_type
13961debfc3dSmrg base() const
13971debfc3dSmrg { return _M_current; }
13988feb0f0bSmrg #else
13998feb0f0bSmrg constexpr const iterator_type&
14008feb0f0bSmrg base() const & noexcept
14018feb0f0bSmrg { return _M_current; }
14028feb0f0bSmrg
14038feb0f0bSmrg constexpr iterator_type
14048feb0f0bSmrg base() &&
14058feb0f0bSmrg { return std::move(_M_current); }
14068feb0f0bSmrg #endif
14071debfc3dSmrg
14081debfc3dSmrg _GLIBCXX17_CONSTEXPR reference
14091debfc3dSmrg operator*() const
14108feb0f0bSmrg #if __cplusplus > 201703L && __cpp_lib_concepts
14118feb0f0bSmrg { return ranges::iter_move(_M_current); }
14128feb0f0bSmrg #else
14131debfc3dSmrg { return static_cast<reference>(*_M_current); }
14148feb0f0bSmrg #endif
14151debfc3dSmrg
14161debfc3dSmrg _GLIBCXX17_CONSTEXPR pointer
14171debfc3dSmrg operator->() const
14181debfc3dSmrg { return _M_current; }
14191debfc3dSmrg
14201debfc3dSmrg _GLIBCXX17_CONSTEXPR move_iterator&
14211debfc3dSmrg operator++()
14221debfc3dSmrg {
14231debfc3dSmrg ++_M_current;
14241debfc3dSmrg return *this;
14251debfc3dSmrg }
14261debfc3dSmrg
14271debfc3dSmrg _GLIBCXX17_CONSTEXPR move_iterator
14281debfc3dSmrg operator++(int)
14291debfc3dSmrg {
14301debfc3dSmrg move_iterator __tmp = *this;
14311debfc3dSmrg ++_M_current;
14321debfc3dSmrg return __tmp;
14331debfc3dSmrg }
14341debfc3dSmrg
14358feb0f0bSmrg #if __cpp_lib_concepts
14368feb0f0bSmrg constexpr void
14378feb0f0bSmrg operator++(int) requires (!forward_iterator<_Iterator>)
14388feb0f0bSmrg { ++_M_current; }
14398feb0f0bSmrg #endif
14408feb0f0bSmrg
14411debfc3dSmrg _GLIBCXX17_CONSTEXPR move_iterator&
14421debfc3dSmrg operator--()
14431debfc3dSmrg {
14441debfc3dSmrg --_M_current;
14451debfc3dSmrg return *this;
14461debfc3dSmrg }
14471debfc3dSmrg
14481debfc3dSmrg _GLIBCXX17_CONSTEXPR move_iterator
14491debfc3dSmrg operator--(int)
14501debfc3dSmrg {
14511debfc3dSmrg move_iterator __tmp = *this;
14521debfc3dSmrg --_M_current;
14531debfc3dSmrg return __tmp;
14541debfc3dSmrg }
14551debfc3dSmrg
14561debfc3dSmrg _GLIBCXX17_CONSTEXPR move_iterator
14571debfc3dSmrg operator+(difference_type __n) const
14581debfc3dSmrg { return move_iterator(_M_current + __n); }
14591debfc3dSmrg
14601debfc3dSmrg _GLIBCXX17_CONSTEXPR move_iterator&
14611debfc3dSmrg operator+=(difference_type __n)
14621debfc3dSmrg {
14631debfc3dSmrg _M_current += __n;
14641debfc3dSmrg return *this;
14651debfc3dSmrg }
14661debfc3dSmrg
14671debfc3dSmrg _GLIBCXX17_CONSTEXPR move_iterator
14681debfc3dSmrg operator-(difference_type __n) const
14691debfc3dSmrg { return move_iterator(_M_current - __n); }
14701debfc3dSmrg
14711debfc3dSmrg _GLIBCXX17_CONSTEXPR move_iterator&
14721debfc3dSmrg operator-=(difference_type __n)
14731debfc3dSmrg {
14741debfc3dSmrg _M_current -= __n;
14751debfc3dSmrg return *this;
14761debfc3dSmrg }
14771debfc3dSmrg
14781debfc3dSmrg _GLIBCXX17_CONSTEXPR reference
14791debfc3dSmrg operator[](difference_type __n) const
14808feb0f0bSmrg #if __cplusplus > 201703L && __cpp_lib_concepts
14818feb0f0bSmrg { return ranges::iter_move(_M_current + __n); }
14828feb0f0bSmrg #else
14831debfc3dSmrg { return std::move(_M_current[__n]); }
14848feb0f0bSmrg #endif
14858feb0f0bSmrg
14868feb0f0bSmrg #if __cplusplus > 201703L && __cpp_lib_concepts
14878feb0f0bSmrg template<sentinel_for<_Iterator> _Sent>
14888feb0f0bSmrg friend constexpr bool
14898feb0f0bSmrg operator==(const move_iterator& __x, const move_sentinel<_Sent>& __y)
14908feb0f0bSmrg { return __x.base() == __y.base(); }
14918feb0f0bSmrg
14928feb0f0bSmrg template<sized_sentinel_for<_Iterator> _Sent>
14938feb0f0bSmrg friend constexpr iter_difference_t<_Iterator>
14948feb0f0bSmrg operator-(const move_sentinel<_Sent>& __x, const move_iterator& __y)
14958feb0f0bSmrg { return __x.base() - __y.base(); }
14968feb0f0bSmrg
14978feb0f0bSmrg template<sized_sentinel_for<_Iterator> _Sent>
14988feb0f0bSmrg friend constexpr iter_difference_t<_Iterator>
14998feb0f0bSmrg operator-(const move_iterator& __x, const move_sentinel<_Sent>& __y)
15008feb0f0bSmrg { return __x.base() - __y.base(); }
15018feb0f0bSmrg
15028feb0f0bSmrg friend constexpr iter_rvalue_reference_t<_Iterator>
15038feb0f0bSmrg iter_move(const move_iterator& __i)
15048feb0f0bSmrg noexcept(noexcept(ranges::iter_move(__i._M_current)))
15058feb0f0bSmrg { return ranges::iter_move(__i._M_current); }
15068feb0f0bSmrg
15078feb0f0bSmrg template<indirectly_swappable<_Iterator> _Iter2>
15088feb0f0bSmrg friend constexpr void
15098feb0f0bSmrg iter_swap(const move_iterator& __x, const move_iterator<_Iter2>& __y)
15108feb0f0bSmrg noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
15118feb0f0bSmrg { return ranges::iter_swap(__x._M_current, __y._M_current); }
15128feb0f0bSmrg #endif // C++20
15131debfc3dSmrg };
15141debfc3dSmrg
15151debfc3dSmrg template<typename _IteratorL, typename _IteratorR>
15161debfc3dSmrg inline _GLIBCXX17_CONSTEXPR bool
15171debfc3dSmrg operator==(const move_iterator<_IteratorL>& __x,
15181debfc3dSmrg const move_iterator<_IteratorR>& __y)
15198feb0f0bSmrg #if __cplusplus > 201703L && __cpp_lib_concepts
15208feb0f0bSmrg requires requires { { __x.base() == __y.base() } -> convertible_to<bool>; }
15218feb0f0bSmrg #endif
15221debfc3dSmrg { return __x.base() == __y.base(); }
15231debfc3dSmrg
15248feb0f0bSmrg #if __cpp_lib_three_way_comparison
15258feb0f0bSmrg template<typename _IteratorL,
15268feb0f0bSmrg three_way_comparable_with<_IteratorL> _IteratorR>
15278feb0f0bSmrg constexpr compare_three_way_result_t<_IteratorL, _IteratorR>
15288feb0f0bSmrg operator<=>(const move_iterator<_IteratorL>& __x,
15298feb0f0bSmrg const move_iterator<_IteratorR>& __y)
15308feb0f0bSmrg { return __x.base() <=> __y.base(); }
15318feb0f0bSmrg #else
15328feb0f0bSmrg template<typename _IteratorL, typename _IteratorR>
15338feb0f0bSmrg inline _GLIBCXX17_CONSTEXPR bool
15348feb0f0bSmrg operator!=(const move_iterator<_IteratorL>& __x,
15358feb0f0bSmrg const move_iterator<_IteratorR>& __y)
15368feb0f0bSmrg { return !(__x == __y); }
15378feb0f0bSmrg #endif
15388feb0f0bSmrg
15398feb0f0bSmrg template<typename _IteratorL, typename _IteratorR>
15408feb0f0bSmrg inline _GLIBCXX17_CONSTEXPR bool
15418feb0f0bSmrg operator<(const move_iterator<_IteratorL>& __x,
15428feb0f0bSmrg const move_iterator<_IteratorR>& __y)
15438feb0f0bSmrg #if __cplusplus > 201703L && __cpp_lib_concepts
15448feb0f0bSmrg requires requires { { __x.base() < __y.base() } -> convertible_to<bool>; }
15458feb0f0bSmrg #endif
15468feb0f0bSmrg { return __x.base() < __y.base(); }
15478feb0f0bSmrg
15488feb0f0bSmrg template<typename _IteratorL, typename _IteratorR>
15498feb0f0bSmrg inline _GLIBCXX17_CONSTEXPR bool
15508feb0f0bSmrg operator<=(const move_iterator<_IteratorL>& __x,
15518feb0f0bSmrg const move_iterator<_IteratorR>& __y)
15528feb0f0bSmrg #if __cplusplus > 201703L && __cpp_lib_concepts
15538feb0f0bSmrg requires requires { { __y.base() < __x.base() } -> convertible_to<bool>; }
15548feb0f0bSmrg #endif
15558feb0f0bSmrg { return !(__y < __x); }
15568feb0f0bSmrg
15578feb0f0bSmrg template<typename _IteratorL, typename _IteratorR>
15588feb0f0bSmrg inline _GLIBCXX17_CONSTEXPR bool
15598feb0f0bSmrg operator>(const move_iterator<_IteratorL>& __x,
15608feb0f0bSmrg const move_iterator<_IteratorR>& __y)
15618feb0f0bSmrg #if __cplusplus > 201703L && __cpp_lib_concepts
15628feb0f0bSmrg requires requires { { __y.base() < __x.base() } -> convertible_to<bool>; }
15638feb0f0bSmrg #endif
15648feb0f0bSmrg { return __y < __x; }
15658feb0f0bSmrg
15668feb0f0bSmrg template<typename _IteratorL, typename _IteratorR>
15678feb0f0bSmrg inline _GLIBCXX17_CONSTEXPR bool
15688feb0f0bSmrg operator>=(const move_iterator<_IteratorL>& __x,
15698feb0f0bSmrg const move_iterator<_IteratorR>& __y)
15708feb0f0bSmrg #if __cplusplus > 201703L && __cpp_lib_concepts
15718feb0f0bSmrg requires requires { { __x.base() < __y.base() } -> convertible_to<bool>; }
15728feb0f0bSmrg #endif
15738feb0f0bSmrg { return !(__x < __y); }
15748feb0f0bSmrg
15758feb0f0bSmrg // Note: See __normal_iterator operators note from Gaby to understand
15768feb0f0bSmrg // why we have these extra overloads for some move_iterator operators.
15778feb0f0bSmrg
15781debfc3dSmrg template<typename _Iterator>
15791debfc3dSmrg inline _GLIBCXX17_CONSTEXPR bool
15801debfc3dSmrg operator==(const move_iterator<_Iterator>& __x,
15811debfc3dSmrg const move_iterator<_Iterator>& __y)
15821debfc3dSmrg { return __x.base() == __y.base(); }
15831debfc3dSmrg
15848feb0f0bSmrg #if __cpp_lib_three_way_comparison
15858feb0f0bSmrg template<three_way_comparable _Iterator>
15868feb0f0bSmrg constexpr compare_three_way_result_t<_Iterator>
15878feb0f0bSmrg operator<=>(const move_iterator<_Iterator>& __x,
15888feb0f0bSmrg const move_iterator<_Iterator>& __y)
15898feb0f0bSmrg { return __x.base() <=> __y.base(); }
15908feb0f0bSmrg #else
15911debfc3dSmrg template<typename _Iterator>
15921debfc3dSmrg inline _GLIBCXX17_CONSTEXPR bool
15931debfc3dSmrg operator!=(const move_iterator<_Iterator>& __x,
15941debfc3dSmrg const move_iterator<_Iterator>& __y)
15951debfc3dSmrg { return !(__x == __y); }
15961debfc3dSmrg
15971debfc3dSmrg template<typename _Iterator>
15981debfc3dSmrg inline _GLIBCXX17_CONSTEXPR bool
15991debfc3dSmrg operator<(const move_iterator<_Iterator>& __x,
16001debfc3dSmrg const move_iterator<_Iterator>& __y)
16011debfc3dSmrg { return __x.base() < __y.base(); }
16021debfc3dSmrg
16031debfc3dSmrg template<typename _Iterator>
16041debfc3dSmrg inline _GLIBCXX17_CONSTEXPR bool
16051debfc3dSmrg operator<=(const move_iterator<_Iterator>& __x,
16061debfc3dSmrg const move_iterator<_Iterator>& __y)
16071debfc3dSmrg { return !(__y < __x); }
16081debfc3dSmrg
16091debfc3dSmrg template<typename _Iterator>
16101debfc3dSmrg inline _GLIBCXX17_CONSTEXPR bool
16111debfc3dSmrg operator>(const move_iterator<_Iterator>& __x,
16121debfc3dSmrg const move_iterator<_Iterator>& __y)
16131debfc3dSmrg { return __y < __x; }
16141debfc3dSmrg
16151debfc3dSmrg template<typename _Iterator>
16161debfc3dSmrg inline _GLIBCXX17_CONSTEXPR bool
16171debfc3dSmrg operator>=(const move_iterator<_Iterator>& __x,
16181debfc3dSmrg const move_iterator<_Iterator>& __y)
16191debfc3dSmrg { return !(__x < __y); }
16208feb0f0bSmrg #endif // ! C++20
16211debfc3dSmrg
16221debfc3dSmrg // DR 685.
16231debfc3dSmrg template<typename _IteratorL, typename _IteratorR>
16241debfc3dSmrg inline _GLIBCXX17_CONSTEXPR auto
16251debfc3dSmrg operator-(const move_iterator<_IteratorL>& __x,
16261debfc3dSmrg const move_iterator<_IteratorR>& __y)
16271debfc3dSmrg -> decltype(__x.base() - __y.base())
16281debfc3dSmrg { return __x.base() - __y.base(); }
16291debfc3dSmrg
16301debfc3dSmrg template<typename _Iterator>
16311debfc3dSmrg inline _GLIBCXX17_CONSTEXPR move_iterator<_Iterator>
16321debfc3dSmrg operator+(typename move_iterator<_Iterator>::difference_type __n,
16331debfc3dSmrg const move_iterator<_Iterator>& __x)
16341debfc3dSmrg { return __x + __n; }
16351debfc3dSmrg
16361debfc3dSmrg template<typename _Iterator>
16371debfc3dSmrg inline _GLIBCXX17_CONSTEXPR move_iterator<_Iterator>
16381debfc3dSmrg make_move_iterator(_Iterator __i)
16398feb0f0bSmrg { return move_iterator<_Iterator>(std::move(__i)); }
16401debfc3dSmrg
16411debfc3dSmrg template<typename _Iterator, typename _ReturnType
16421debfc3dSmrg = typename conditional<__move_if_noexcept_cond
16431debfc3dSmrg <typename iterator_traits<_Iterator>::value_type>::value,
16441debfc3dSmrg _Iterator, move_iterator<_Iterator>>::type>
16451debfc3dSmrg inline _GLIBCXX17_CONSTEXPR _ReturnType
16461debfc3dSmrg __make_move_if_noexcept_iterator(_Iterator __i)
16471debfc3dSmrg { return _ReturnType(__i); }
16481debfc3dSmrg
16491debfc3dSmrg // Overload for pointers that matches std::move_if_noexcept more closely,
16501debfc3dSmrg // returning a constant iterator when we don't want to move.
16511debfc3dSmrg template<typename _Tp, typename _ReturnType
16521debfc3dSmrg = typename conditional<__move_if_noexcept_cond<_Tp>::value,
16531debfc3dSmrg const _Tp*, move_iterator<_Tp*>>::type>
16541debfc3dSmrg inline _GLIBCXX17_CONSTEXPR _ReturnType
16551debfc3dSmrg __make_move_if_noexcept_iterator(_Tp* __i)
16561debfc3dSmrg { return _ReturnType(__i); }
16571debfc3dSmrg
16588feb0f0bSmrg #if __cplusplus > 201703L && __cpp_lib_concepts
16598feb0f0bSmrg // [iterators.common] Common iterators
16608feb0f0bSmrg
16618feb0f0bSmrg namespace __detail
16628feb0f0bSmrg {
16638feb0f0bSmrg template<typename _It>
16648feb0f0bSmrg concept __common_iter_has_arrow = indirectly_readable<const _It>
16658feb0f0bSmrg && (requires(const _It& __it) { __it.operator->(); }
16668feb0f0bSmrg || is_reference_v<iter_reference_t<_It>>
16678feb0f0bSmrg || constructible_from<iter_value_t<_It>, iter_reference_t<_It>>);
16688feb0f0bSmrg
16698feb0f0bSmrg template<typename _It>
16708feb0f0bSmrg concept __common_iter_use_postfix_proxy
16718feb0f0bSmrg = (!requires (_It& __i) { { *__i++ } -> __can_reference; })
16728feb0f0bSmrg && constructible_from<iter_value_t<_It>, iter_reference_t<_It>>
16738feb0f0bSmrg && move_constructible<iter_value_t<_It>>;
16748feb0f0bSmrg } // namespace __detail
16758feb0f0bSmrg
16768feb0f0bSmrg /// An iterator/sentinel adaptor for representing a non-common range.
16778feb0f0bSmrg template<input_or_output_iterator _It, sentinel_for<_It> _Sent>
16788feb0f0bSmrg requires (!same_as<_It, _Sent>) && copyable<_It>
16798feb0f0bSmrg class common_iterator
16808feb0f0bSmrg {
16818feb0f0bSmrg template<typename _Tp, typename _Up>
16828feb0f0bSmrg static constexpr bool
16838feb0f0bSmrg _S_noexcept1()
16848feb0f0bSmrg {
16858feb0f0bSmrg if constexpr (is_trivially_default_constructible_v<_Tp>)
1686*23f5f463Smrg return is_nothrow_assignable_v<_Tp&, _Up>;
16878feb0f0bSmrg else
16888feb0f0bSmrg return is_nothrow_constructible_v<_Tp, _Up>;
16898feb0f0bSmrg }
16908feb0f0bSmrg
16918feb0f0bSmrg template<typename _It2, typename _Sent2>
16928feb0f0bSmrg static constexpr bool
16938feb0f0bSmrg _S_noexcept()
16948feb0f0bSmrg { return _S_noexcept1<_It, _It2>() && _S_noexcept1<_Sent, _Sent2>(); }
16958feb0f0bSmrg
16968feb0f0bSmrg class __arrow_proxy
16978feb0f0bSmrg {
16988feb0f0bSmrg iter_value_t<_It> _M_keep;
16998feb0f0bSmrg
17008feb0f0bSmrg constexpr
17018feb0f0bSmrg __arrow_proxy(iter_reference_t<_It>&& __x)
17028feb0f0bSmrg : _M_keep(std::move(__x)) { }
17038feb0f0bSmrg
17048feb0f0bSmrg friend class common_iterator;
17058feb0f0bSmrg
17068feb0f0bSmrg public:
17078feb0f0bSmrg constexpr const iter_value_t<_It>*
17088feb0f0bSmrg operator->() const noexcept
17098feb0f0bSmrg { return std::__addressof(_M_keep); }
17108feb0f0bSmrg };
17118feb0f0bSmrg
17128feb0f0bSmrg class __postfix_proxy
17138feb0f0bSmrg {
17148feb0f0bSmrg iter_value_t<_It> _M_keep;
17158feb0f0bSmrg
17168feb0f0bSmrg constexpr
17178feb0f0bSmrg __postfix_proxy(iter_reference_t<_It>&& __x)
17188feb0f0bSmrg : _M_keep(std::forward<iter_reference_t<_It>>(__x)) { }
17198feb0f0bSmrg
17208feb0f0bSmrg friend class common_iterator;
17218feb0f0bSmrg
17228feb0f0bSmrg public:
17238feb0f0bSmrg constexpr const iter_value_t<_It>&
17248feb0f0bSmrg operator*() const noexcept
17258feb0f0bSmrg { return _M_keep; }
17268feb0f0bSmrg };
17278feb0f0bSmrg
17288feb0f0bSmrg public:
17298feb0f0bSmrg constexpr
17308feb0f0bSmrg common_iterator()
17318feb0f0bSmrg noexcept(is_nothrow_default_constructible_v<_It>)
17328feb0f0bSmrg requires default_initializable<_It>
17338feb0f0bSmrg : _M_it(), _M_index(0)
17348feb0f0bSmrg { }
17358feb0f0bSmrg
17368feb0f0bSmrg constexpr
17378feb0f0bSmrg common_iterator(_It __i)
17388feb0f0bSmrg noexcept(is_nothrow_move_constructible_v<_It>)
17398feb0f0bSmrg : _M_it(std::move(__i)), _M_index(0)
17408feb0f0bSmrg { }
17418feb0f0bSmrg
17428feb0f0bSmrg constexpr
17438feb0f0bSmrg common_iterator(_Sent __s)
17448feb0f0bSmrg noexcept(is_nothrow_move_constructible_v<_Sent>)
17458feb0f0bSmrg : _M_sent(std::move(__s)), _M_index(1)
17468feb0f0bSmrg { }
17478feb0f0bSmrg
17488feb0f0bSmrg template<typename _It2, typename _Sent2>
17498feb0f0bSmrg requires convertible_to<const _It2&, _It>
17508feb0f0bSmrg && convertible_to<const _Sent2&, _Sent>
17518feb0f0bSmrg constexpr
17528feb0f0bSmrg common_iterator(const common_iterator<_It2, _Sent2>& __x)
17538feb0f0bSmrg noexcept(_S_noexcept<const _It2&, const _Sent2&>())
17548feb0f0bSmrg : _M_valueless(), _M_index(__x._M_index)
17558feb0f0bSmrg {
1756*23f5f463Smrg __glibcxx_assert(__x._M_has_value());
17578feb0f0bSmrg if (_M_index == 0)
17588feb0f0bSmrg {
17598feb0f0bSmrg if constexpr (is_trivially_default_constructible_v<_It>)
17608feb0f0bSmrg _M_it = std::move(__x._M_it);
17618feb0f0bSmrg else
17628feb0f0bSmrg ::new((void*)std::__addressof(_M_it)) _It(__x._M_it);
17638feb0f0bSmrg }
17648feb0f0bSmrg else if (_M_index == 1)
17658feb0f0bSmrg {
17668feb0f0bSmrg if constexpr (is_trivially_default_constructible_v<_Sent>)
17678feb0f0bSmrg _M_sent = std::move(__x._M_sent);
17688feb0f0bSmrg else
17698feb0f0bSmrg ::new((void*)std::__addressof(_M_sent)) _Sent(__x._M_sent);
17708feb0f0bSmrg }
17718feb0f0bSmrg }
17728feb0f0bSmrg
17738feb0f0bSmrg constexpr
17748feb0f0bSmrg common_iterator(const common_iterator& __x)
17758feb0f0bSmrg noexcept(_S_noexcept<const _It&, const _Sent&>())
17768feb0f0bSmrg : _M_valueless(), _M_index(__x._M_index)
17778feb0f0bSmrg {
17788feb0f0bSmrg if (_M_index == 0)
17798feb0f0bSmrg {
17808feb0f0bSmrg if constexpr (is_trivially_default_constructible_v<_It>)
1781*23f5f463Smrg _M_it = __x._M_it;
17828feb0f0bSmrg else
17838feb0f0bSmrg ::new((void*)std::__addressof(_M_it)) _It(__x._M_it);
17848feb0f0bSmrg }
17858feb0f0bSmrg else if (_M_index == 1)
17868feb0f0bSmrg {
17878feb0f0bSmrg if constexpr (is_trivially_default_constructible_v<_Sent>)
1788*23f5f463Smrg _M_sent = __x._M_sent;
17898feb0f0bSmrg else
17908feb0f0bSmrg ::new((void*)std::__addressof(_M_sent)) _Sent(__x._M_sent);
17918feb0f0bSmrg }
17928feb0f0bSmrg }
17938feb0f0bSmrg
1794*23f5f463Smrg constexpr
1795*23f5f463Smrg common_iterator(common_iterator&& __x)
1796*23f5f463Smrg noexcept(_S_noexcept<_It, _Sent>())
1797*23f5f463Smrg : _M_valueless(), _M_index(__x._M_index)
1798*23f5f463Smrg {
1799*23f5f463Smrg if (_M_index == 0)
1800*23f5f463Smrg {
1801*23f5f463Smrg if constexpr (is_trivially_default_constructible_v<_It>)
1802*23f5f463Smrg _M_it = std::move(__x._M_it);
1803*23f5f463Smrg else
1804*23f5f463Smrg ::new((void*)std::__addressof(_M_it)) _It(std::move(__x._M_it));
1805*23f5f463Smrg }
1806*23f5f463Smrg else if (_M_index == 1)
1807*23f5f463Smrg {
1808*23f5f463Smrg if constexpr (is_trivially_default_constructible_v<_Sent>)
1809*23f5f463Smrg _M_sent = std::move(__x._M_sent);
1810*23f5f463Smrg else
1811*23f5f463Smrg ::new((void*)std::__addressof(_M_sent))
1812*23f5f463Smrg _Sent(std::move(__x._M_sent));
1813*23f5f463Smrg }
1814*23f5f463Smrg }
1815*23f5f463Smrg
1816*23f5f463Smrg constexpr common_iterator&
1817*23f5f463Smrg operator=(const common_iterator&) = default;
1818*23f5f463Smrg
18198feb0f0bSmrg common_iterator&
18208feb0f0bSmrg operator=(const common_iterator& __x)
18218feb0f0bSmrg noexcept(is_nothrow_copy_assignable_v<_It>
18228feb0f0bSmrg && is_nothrow_copy_assignable_v<_Sent>
18238feb0f0bSmrg && is_nothrow_copy_constructible_v<_It>
18248feb0f0bSmrg && is_nothrow_copy_constructible_v<_Sent>)
1825*23f5f463Smrg requires (!is_trivially_copy_assignable_v<_It>
1826*23f5f463Smrg || !is_trivially_copy_assignable_v<_Sent>)
18278feb0f0bSmrg {
1828*23f5f463Smrg _M_assign(__x);
1829*23f5f463Smrg return *this;
1830*23f5f463Smrg }
1831*23f5f463Smrg
1832*23f5f463Smrg constexpr common_iterator&
1833*23f5f463Smrg operator=(common_iterator&&) = default;
1834*23f5f463Smrg
1835*23f5f463Smrg common_iterator&
1836*23f5f463Smrg operator=(common_iterator&& __x)
1837*23f5f463Smrg noexcept(is_nothrow_move_assignable_v<_It>
1838*23f5f463Smrg && is_nothrow_move_assignable_v<_Sent>
1839*23f5f463Smrg && is_nothrow_move_constructible_v<_It>
1840*23f5f463Smrg && is_nothrow_move_constructible_v<_Sent>)
1841*23f5f463Smrg requires (!is_trivially_move_assignable_v<_It>
1842*23f5f463Smrg || !is_trivially_move_assignable_v<_Sent>)
1843*23f5f463Smrg {
1844*23f5f463Smrg _M_assign(std::move(__x));
1845*23f5f463Smrg return *this;
18468feb0f0bSmrg }
18478feb0f0bSmrg
18488feb0f0bSmrg template<typename _It2, typename _Sent2>
18498feb0f0bSmrg requires convertible_to<const _It2&, _It>
18508feb0f0bSmrg && convertible_to<const _Sent2&, _Sent>
18518feb0f0bSmrg && assignable_from<_It&, const _It2&>
18528feb0f0bSmrg && assignable_from<_Sent&, const _Sent2&>
18538feb0f0bSmrg common_iterator&
18548feb0f0bSmrg operator=(const common_iterator<_It2, _Sent2>& __x)
18558feb0f0bSmrg noexcept(is_nothrow_constructible_v<_It, const _It2&>
18568feb0f0bSmrg && is_nothrow_constructible_v<_Sent, const _Sent2&>
1857*23f5f463Smrg && is_nothrow_assignable_v<_It&, const _It2&>
1858*23f5f463Smrg && is_nothrow_assignable_v<_Sent&, const _Sent2&>)
18598feb0f0bSmrg {
18608feb0f0bSmrg __glibcxx_assert(__x._M_has_value());
1861*23f5f463Smrg _M_assign(__x);
18628feb0f0bSmrg return *this;
18638feb0f0bSmrg }
18648feb0f0bSmrg
18658feb0f0bSmrg ~common_iterator()
18668feb0f0bSmrg {
1867*23f5f463Smrg if (_M_index == 0)
18688feb0f0bSmrg _M_it.~_It();
1869*23f5f463Smrg else if (_M_index == 1)
18708feb0f0bSmrg _M_sent.~_Sent();
18718feb0f0bSmrg }
18728feb0f0bSmrg
18738feb0f0bSmrg decltype(auto)
18748feb0f0bSmrg operator*()
18758feb0f0bSmrg {
18768feb0f0bSmrg __glibcxx_assert(_M_index == 0);
18778feb0f0bSmrg return *_M_it;
18788feb0f0bSmrg }
18798feb0f0bSmrg
18808feb0f0bSmrg decltype(auto)
18818feb0f0bSmrg operator*() const requires __detail::__dereferenceable<const _It>
18828feb0f0bSmrg {
18838feb0f0bSmrg __glibcxx_assert(_M_index == 0);
18848feb0f0bSmrg return *_M_it;
18858feb0f0bSmrg }
18868feb0f0bSmrg
18878feb0f0bSmrg decltype(auto)
18888feb0f0bSmrg operator->() const requires __detail::__common_iter_has_arrow<_It>
18898feb0f0bSmrg {
18908feb0f0bSmrg __glibcxx_assert(_M_index == 0);
18918feb0f0bSmrg if constexpr (is_pointer_v<_It> || requires { _M_it.operator->(); })
18928feb0f0bSmrg return _M_it;
18938feb0f0bSmrg else if constexpr (is_reference_v<iter_reference_t<_It>>)
18948feb0f0bSmrg {
18958feb0f0bSmrg auto&& __tmp = *_M_it;
18968feb0f0bSmrg return std::__addressof(__tmp);
18978feb0f0bSmrg }
18988feb0f0bSmrg else
18998feb0f0bSmrg return __arrow_proxy{*_M_it};
19008feb0f0bSmrg }
19018feb0f0bSmrg
19028feb0f0bSmrg common_iterator&
19038feb0f0bSmrg operator++()
19048feb0f0bSmrg {
19058feb0f0bSmrg __glibcxx_assert(_M_index == 0);
19068feb0f0bSmrg ++_M_it;
19078feb0f0bSmrg return *this;
19088feb0f0bSmrg }
19098feb0f0bSmrg
19108feb0f0bSmrg decltype(auto)
19118feb0f0bSmrg operator++(int)
19128feb0f0bSmrg {
19138feb0f0bSmrg __glibcxx_assert(_M_index == 0);
19148feb0f0bSmrg if constexpr (forward_iterator<_It>)
19158feb0f0bSmrg {
19168feb0f0bSmrg common_iterator __tmp = *this;
19178feb0f0bSmrg ++*this;
19188feb0f0bSmrg return __tmp;
19198feb0f0bSmrg }
19208feb0f0bSmrg else if constexpr (!__detail::__common_iter_use_postfix_proxy<_It>)
19218feb0f0bSmrg return _M_it++;
19228feb0f0bSmrg else
19238feb0f0bSmrg {
19248feb0f0bSmrg __postfix_proxy __p(**this);
19258feb0f0bSmrg ++*this;
19268feb0f0bSmrg return __p;
19278feb0f0bSmrg }
19288feb0f0bSmrg }
19298feb0f0bSmrg
19308feb0f0bSmrg template<typename _It2, sentinel_for<_It> _Sent2>
19318feb0f0bSmrg requires sentinel_for<_Sent, _It2>
19328feb0f0bSmrg friend bool
19338feb0f0bSmrg operator==(const common_iterator& __x,
19348feb0f0bSmrg const common_iterator<_It2, _Sent2>& __y)
19358feb0f0bSmrg {
19368feb0f0bSmrg switch(__x._M_index << 2 | __y._M_index)
19378feb0f0bSmrg {
19388feb0f0bSmrg case 0b0000:
19398feb0f0bSmrg case 0b0101:
19408feb0f0bSmrg return true;
19418feb0f0bSmrg case 0b0001:
19428feb0f0bSmrg return __x._M_it == __y._M_sent;
19438feb0f0bSmrg case 0b0100:
19448feb0f0bSmrg return __x._M_sent == __y._M_it;
19458feb0f0bSmrg default:
19468feb0f0bSmrg __glibcxx_assert(__x._M_has_value());
19478feb0f0bSmrg __glibcxx_assert(__y._M_has_value());
19488feb0f0bSmrg __builtin_unreachable();
19498feb0f0bSmrg }
19508feb0f0bSmrg }
19518feb0f0bSmrg
19528feb0f0bSmrg template<typename _It2, sentinel_for<_It> _Sent2>
19538feb0f0bSmrg requires sentinel_for<_Sent, _It2> && equality_comparable_with<_It, _It2>
19548feb0f0bSmrg friend bool
19558feb0f0bSmrg operator==(const common_iterator& __x,
19568feb0f0bSmrg const common_iterator<_It2, _Sent2>& __y)
19578feb0f0bSmrg {
19588feb0f0bSmrg switch(__x._M_index << 2 | __y._M_index)
19598feb0f0bSmrg {
19608feb0f0bSmrg case 0b0101:
19618feb0f0bSmrg return true;
19628feb0f0bSmrg case 0b0000:
19638feb0f0bSmrg return __x._M_it == __y._M_it;
19648feb0f0bSmrg case 0b0001:
19658feb0f0bSmrg return __x._M_it == __y._M_sent;
19668feb0f0bSmrg case 0b0100:
19678feb0f0bSmrg return __x._M_sent == __y._M_it;
19688feb0f0bSmrg default:
19698feb0f0bSmrg __glibcxx_assert(__x._M_has_value());
19708feb0f0bSmrg __glibcxx_assert(__y._M_has_value());
19718feb0f0bSmrg __builtin_unreachable();
19728feb0f0bSmrg }
19738feb0f0bSmrg }
19748feb0f0bSmrg
19758feb0f0bSmrg template<sized_sentinel_for<_It> _It2, sized_sentinel_for<_It> _Sent2>
19768feb0f0bSmrg requires sized_sentinel_for<_Sent, _It2>
19778feb0f0bSmrg friend iter_difference_t<_It2>
19788feb0f0bSmrg operator-(const common_iterator& __x,
19798feb0f0bSmrg const common_iterator<_It2, _Sent2>& __y)
19808feb0f0bSmrg {
19818feb0f0bSmrg switch(__x._M_index << 2 | __y._M_index)
19828feb0f0bSmrg {
19838feb0f0bSmrg case 0b0101:
19848feb0f0bSmrg return 0;
19858feb0f0bSmrg case 0b0000:
19868feb0f0bSmrg return __x._M_it - __y._M_it;
19878feb0f0bSmrg case 0b0001:
19888feb0f0bSmrg return __x._M_it - __y._M_sent;
19898feb0f0bSmrg case 0b0100:
19908feb0f0bSmrg return __x._M_sent - __y._M_it;
19918feb0f0bSmrg default:
19928feb0f0bSmrg __glibcxx_assert(__x._M_has_value());
19938feb0f0bSmrg __glibcxx_assert(__y._M_has_value());
19948feb0f0bSmrg __builtin_unreachable();
19958feb0f0bSmrg }
19968feb0f0bSmrg }
19978feb0f0bSmrg
19988feb0f0bSmrg friend iter_rvalue_reference_t<_It>
19998feb0f0bSmrg iter_move(const common_iterator& __i)
20008feb0f0bSmrg noexcept(noexcept(ranges::iter_move(std::declval<const _It&>())))
20018feb0f0bSmrg requires input_iterator<_It>
20028feb0f0bSmrg {
20038feb0f0bSmrg __glibcxx_assert(__i._M_index == 0);
20048feb0f0bSmrg return ranges::iter_move(__i._M_it);
20058feb0f0bSmrg }
20068feb0f0bSmrg
20078feb0f0bSmrg template<indirectly_swappable<_It> _It2, typename _Sent2>
20088feb0f0bSmrg friend void
20098feb0f0bSmrg iter_swap(const common_iterator& __x,
20108feb0f0bSmrg const common_iterator<_It2, _Sent2>& __y)
20118feb0f0bSmrg noexcept(noexcept(ranges::iter_swap(std::declval<const _It&>(),
20128feb0f0bSmrg std::declval<const _It2&>())))
20138feb0f0bSmrg {
20148feb0f0bSmrg __glibcxx_assert(__x._M_index == 0);
20158feb0f0bSmrg __glibcxx_assert(__y._M_index == 0);
20168feb0f0bSmrg return ranges::iter_swap(__x._M_it, __y._M_it);
20178feb0f0bSmrg }
20188feb0f0bSmrg
20198feb0f0bSmrg private:
20208feb0f0bSmrg template<input_or_output_iterator _It2, sentinel_for<_It2> _Sent2>
2021*23f5f463Smrg requires (!same_as<_It2, _Sent2>) && copyable<_It2>
20228feb0f0bSmrg friend class common_iterator;
20238feb0f0bSmrg
2024*23f5f463Smrg bool
2025*23f5f463Smrg _M_has_value() const noexcept { return _M_index != _S_valueless; }
2026*23f5f463Smrg
2027*23f5f463Smrg template<typename _CIt>
2028*23f5f463Smrg void
2029*23f5f463Smrg _M_assign(_CIt&& __x)
2030*23f5f463Smrg {
2031*23f5f463Smrg if (_M_index == __x._M_index)
2032*23f5f463Smrg {
2033*23f5f463Smrg if (_M_index == 0)
2034*23f5f463Smrg _M_it = std::forward<_CIt>(__x)._M_it;
2035*23f5f463Smrg else if (_M_index == 1)
2036*23f5f463Smrg _M_sent = std::forward<_CIt>(__x)._M_sent;
2037*23f5f463Smrg }
2038*23f5f463Smrg else
2039*23f5f463Smrg {
2040*23f5f463Smrg if (_M_index == 0)
2041*23f5f463Smrg _M_it.~_It();
2042*23f5f463Smrg else if (_M_index == 1)
2043*23f5f463Smrg _M_sent.~_Sent();
2044*23f5f463Smrg _M_index = _S_valueless;
2045*23f5f463Smrg
2046*23f5f463Smrg if (__x._M_index == 0)
2047*23f5f463Smrg ::new((void*)std::__addressof(_M_it))
2048*23f5f463Smrg _It(std::forward<_CIt>(__x)._M_it);
2049*23f5f463Smrg else if (__x._M_index == 1)
2050*23f5f463Smrg ::new((void*)std::__addressof(_M_sent))
2051*23f5f463Smrg _Sent(std::forward<_CIt>(__x)._M_sent);
2052*23f5f463Smrg _M_index = __x._M_index;
2053*23f5f463Smrg }
2054*23f5f463Smrg }
20558feb0f0bSmrg
20568feb0f0bSmrg union
20578feb0f0bSmrg {
20588feb0f0bSmrg _It _M_it;
20598feb0f0bSmrg _Sent _M_sent;
20608feb0f0bSmrg unsigned char _M_valueless;
20618feb0f0bSmrg };
20628feb0f0bSmrg unsigned char _M_index; // 0 == _M_it, 1 == _M_sent, 2 == valueless
2063*23f5f463Smrg
2064*23f5f463Smrg static constexpr unsigned char _S_valueless{2};
20658feb0f0bSmrg };
20668feb0f0bSmrg
20678feb0f0bSmrg template<typename _It, typename _Sent>
20688feb0f0bSmrg struct incrementable_traits<common_iterator<_It, _Sent>>
20698feb0f0bSmrg {
20708feb0f0bSmrg using difference_type = iter_difference_t<_It>;
20718feb0f0bSmrg };
20728feb0f0bSmrg
20738feb0f0bSmrg template<input_iterator _It, typename _Sent>
20748feb0f0bSmrg struct iterator_traits<common_iterator<_It, _Sent>>
20758feb0f0bSmrg {
20768feb0f0bSmrg private:
20778feb0f0bSmrg template<typename _Iter>
20788feb0f0bSmrg struct __ptr
20798feb0f0bSmrg {
20808feb0f0bSmrg using type = void;
20818feb0f0bSmrg };
20828feb0f0bSmrg
20838feb0f0bSmrg template<typename _Iter>
20848feb0f0bSmrg requires __detail::__common_iter_has_arrow<_Iter>
20858feb0f0bSmrg struct __ptr<_Iter>
20868feb0f0bSmrg {
20878feb0f0bSmrg using _CIter = common_iterator<_Iter, _Sent>;
20888feb0f0bSmrg using type = decltype(std::declval<const _CIter&>().operator->());
20898feb0f0bSmrg };
20908feb0f0bSmrg
20918feb0f0bSmrg static auto
20928feb0f0bSmrg _S_iter_cat()
20938feb0f0bSmrg {
20948feb0f0bSmrg using _Traits = iterator_traits<_It>;
20958feb0f0bSmrg if constexpr (requires { requires derived_from<typename _Traits::iterator_category,
20968feb0f0bSmrg forward_iterator_tag>; })
20978feb0f0bSmrg return forward_iterator_tag{};
20988feb0f0bSmrg else
20998feb0f0bSmrg return input_iterator_tag{};
21008feb0f0bSmrg }
21018feb0f0bSmrg
21028feb0f0bSmrg public:
21038feb0f0bSmrg using iterator_concept = conditional_t<forward_iterator<_It>,
21048feb0f0bSmrg forward_iterator_tag, input_iterator_tag>;
21058feb0f0bSmrg using iterator_category = decltype(_S_iter_cat());
21068feb0f0bSmrg using value_type = iter_value_t<_It>;
21078feb0f0bSmrg using difference_type = iter_difference_t<_It>;
21088feb0f0bSmrg using pointer = typename __ptr<_It>::type;
21098feb0f0bSmrg using reference = iter_reference_t<_It>;
21108feb0f0bSmrg };
21118feb0f0bSmrg
21128feb0f0bSmrg // [iterators.counted] Counted iterators
21138feb0f0bSmrg
21148feb0f0bSmrg namespace __detail
21158feb0f0bSmrg {
21168feb0f0bSmrg template<typename _It>
21178feb0f0bSmrg struct __counted_iter_value_type
21188feb0f0bSmrg { };
21198feb0f0bSmrg
21208feb0f0bSmrg template<indirectly_readable _It>
21218feb0f0bSmrg struct __counted_iter_value_type<_It>
21228feb0f0bSmrg { using value_type = iter_value_t<_It>; };
21238feb0f0bSmrg
21248feb0f0bSmrg template<typename _It>
21258feb0f0bSmrg struct __counted_iter_concept
21268feb0f0bSmrg { };
21278feb0f0bSmrg
21288feb0f0bSmrg template<typename _It>
21298feb0f0bSmrg requires requires { typename _It::iterator_concept; }
21308feb0f0bSmrg struct __counted_iter_concept<_It>
21318feb0f0bSmrg { using iterator_concept = typename _It::iterator_concept; };
21328feb0f0bSmrg
21338feb0f0bSmrg template<typename _It>
21348feb0f0bSmrg struct __counted_iter_cat
21358feb0f0bSmrg { };
21368feb0f0bSmrg
21378feb0f0bSmrg template<typename _It>
21388feb0f0bSmrg requires requires { typename _It::iterator_category; }
21398feb0f0bSmrg struct __counted_iter_cat<_It>
21408feb0f0bSmrg { using iterator_category = typename _It::iterator_category; };
21418feb0f0bSmrg }
21428feb0f0bSmrg
21438feb0f0bSmrg /// An iterator adaptor that keeps track of the distance to the end.
21448feb0f0bSmrg template<input_or_output_iterator _It>
21458feb0f0bSmrg class counted_iterator
21468feb0f0bSmrg : public __detail::__counted_iter_value_type<_It>,
21478feb0f0bSmrg public __detail::__counted_iter_concept<_It>,
21488feb0f0bSmrg public __detail::__counted_iter_cat<_It>
21498feb0f0bSmrg {
21508feb0f0bSmrg public:
21518feb0f0bSmrg using iterator_type = _It;
21528feb0f0bSmrg // value_type defined in __counted_iter_value_type
21538feb0f0bSmrg using difference_type = iter_difference_t<_It>;
21548feb0f0bSmrg // iterator_concept defined in __counted_iter_concept
21558feb0f0bSmrg // iterator_category defined in __counted_iter_cat
21568feb0f0bSmrg
21578feb0f0bSmrg constexpr counted_iterator() requires default_initializable<_It> = default;
21588feb0f0bSmrg
21598feb0f0bSmrg constexpr
21608feb0f0bSmrg counted_iterator(_It __i, iter_difference_t<_It> __n)
21618feb0f0bSmrg : _M_current(std::move(__i)), _M_length(__n)
21628feb0f0bSmrg { __glibcxx_assert(__n >= 0); }
21638feb0f0bSmrg
21648feb0f0bSmrg template<typename _It2>
21658feb0f0bSmrg requires convertible_to<const _It2&, _It>
21668feb0f0bSmrg constexpr
21678feb0f0bSmrg counted_iterator(const counted_iterator<_It2>& __x)
21688feb0f0bSmrg : _M_current(__x._M_current), _M_length(__x._M_length)
21698feb0f0bSmrg { }
21708feb0f0bSmrg
21718feb0f0bSmrg template<typename _It2>
21728feb0f0bSmrg requires assignable_from<_It&, const _It2&>
21738feb0f0bSmrg constexpr counted_iterator&
21748feb0f0bSmrg operator=(const counted_iterator<_It2>& __x)
21758feb0f0bSmrg {
21768feb0f0bSmrg _M_current = __x._M_current;
21778feb0f0bSmrg _M_length = __x._M_length;
21788feb0f0bSmrg return *this;
21798feb0f0bSmrg }
21808feb0f0bSmrg
21818feb0f0bSmrg constexpr const _It&
21828feb0f0bSmrg base() const & noexcept
21838feb0f0bSmrg { return _M_current; }
21848feb0f0bSmrg
21858feb0f0bSmrg constexpr _It
21868feb0f0bSmrg base() &&
21878feb0f0bSmrg noexcept(is_nothrow_move_constructible_v<_It>)
21888feb0f0bSmrg { return std::move(_M_current); }
21898feb0f0bSmrg
21908feb0f0bSmrg constexpr iter_difference_t<_It>
21918feb0f0bSmrg count() const noexcept { return _M_length; }
21928feb0f0bSmrg
21938feb0f0bSmrg constexpr decltype(auto)
21948feb0f0bSmrg operator*()
21958feb0f0bSmrg noexcept(noexcept(*_M_current))
21968feb0f0bSmrg { return *_M_current; }
21978feb0f0bSmrg
21988feb0f0bSmrg constexpr decltype(auto)
21998feb0f0bSmrg operator*() const
22008feb0f0bSmrg noexcept(noexcept(*_M_current))
22018feb0f0bSmrg requires __detail::__dereferenceable<const _It>
22028feb0f0bSmrg { return *_M_current; }
22038feb0f0bSmrg
22048feb0f0bSmrg constexpr auto
22058feb0f0bSmrg operator->() const noexcept
22068feb0f0bSmrg requires contiguous_iterator<_It>
22078feb0f0bSmrg { return std::to_address(_M_current); }
22088feb0f0bSmrg
22098feb0f0bSmrg constexpr counted_iterator&
22108feb0f0bSmrg operator++()
22118feb0f0bSmrg {
22128feb0f0bSmrg __glibcxx_assert(_M_length > 0);
22138feb0f0bSmrg ++_M_current;
22148feb0f0bSmrg --_M_length;
22158feb0f0bSmrg return *this;
22168feb0f0bSmrg }
22178feb0f0bSmrg
22188feb0f0bSmrg decltype(auto)
22198feb0f0bSmrg operator++(int)
22208feb0f0bSmrg {
22218feb0f0bSmrg __glibcxx_assert(_M_length > 0);
22228feb0f0bSmrg --_M_length;
22238feb0f0bSmrg __try
22248feb0f0bSmrg {
22258feb0f0bSmrg return _M_current++;
22268feb0f0bSmrg } __catch(...) {
22278feb0f0bSmrg ++_M_length;
22288feb0f0bSmrg __throw_exception_again;
22298feb0f0bSmrg }
22308feb0f0bSmrg
22318feb0f0bSmrg }
22328feb0f0bSmrg
22338feb0f0bSmrg constexpr counted_iterator
22348feb0f0bSmrg operator++(int) requires forward_iterator<_It>
22358feb0f0bSmrg {
22368feb0f0bSmrg auto __tmp = *this;
22378feb0f0bSmrg ++*this;
22388feb0f0bSmrg return __tmp;
22398feb0f0bSmrg }
22408feb0f0bSmrg
22418feb0f0bSmrg constexpr counted_iterator&
22428feb0f0bSmrg operator--() requires bidirectional_iterator<_It>
22438feb0f0bSmrg {
22448feb0f0bSmrg --_M_current;
22458feb0f0bSmrg ++_M_length;
22468feb0f0bSmrg return *this;
22478feb0f0bSmrg }
22488feb0f0bSmrg
22498feb0f0bSmrg constexpr counted_iterator
22508feb0f0bSmrg operator--(int) requires bidirectional_iterator<_It>
22518feb0f0bSmrg {
22528feb0f0bSmrg auto __tmp = *this;
22538feb0f0bSmrg --*this;
22548feb0f0bSmrg return __tmp;
22558feb0f0bSmrg }
22568feb0f0bSmrg
22578feb0f0bSmrg constexpr counted_iterator
22588feb0f0bSmrg operator+(iter_difference_t<_It> __n) const
22598feb0f0bSmrg requires random_access_iterator<_It>
22608feb0f0bSmrg { return counted_iterator(_M_current + __n, _M_length - __n); }
22618feb0f0bSmrg
22628feb0f0bSmrg friend constexpr counted_iterator
22638feb0f0bSmrg operator+(iter_difference_t<_It> __n, const counted_iterator& __x)
22648feb0f0bSmrg requires random_access_iterator<_It>
22658feb0f0bSmrg { return __x + __n; }
22668feb0f0bSmrg
22678feb0f0bSmrg constexpr counted_iterator&
22688feb0f0bSmrg operator+=(iter_difference_t<_It> __n)
22698feb0f0bSmrg requires random_access_iterator<_It>
22708feb0f0bSmrg {
22718feb0f0bSmrg __glibcxx_assert(__n <= _M_length);
22728feb0f0bSmrg _M_current += __n;
22738feb0f0bSmrg _M_length -= __n;
22748feb0f0bSmrg return *this;
22758feb0f0bSmrg }
22768feb0f0bSmrg
22778feb0f0bSmrg constexpr counted_iterator
22788feb0f0bSmrg operator-(iter_difference_t<_It> __n) const
22798feb0f0bSmrg requires random_access_iterator<_It>
22808feb0f0bSmrg { return counted_iterator(_M_current - __n, _M_length + __n); }
22818feb0f0bSmrg
22828feb0f0bSmrg template<common_with<_It> _It2>
22838feb0f0bSmrg friend constexpr iter_difference_t<_It2>
22848feb0f0bSmrg operator-(const counted_iterator& __x,
22858feb0f0bSmrg const counted_iterator<_It2>& __y)
22868feb0f0bSmrg { return __y._M_length - __x._M_length; }
22878feb0f0bSmrg
22888feb0f0bSmrg friend constexpr iter_difference_t<_It>
22898feb0f0bSmrg operator-(const counted_iterator& __x, default_sentinel_t)
22908feb0f0bSmrg { return -__x._M_length; }
22918feb0f0bSmrg
22928feb0f0bSmrg friend constexpr iter_difference_t<_It>
22938feb0f0bSmrg operator-(default_sentinel_t, const counted_iterator& __y)
22948feb0f0bSmrg { return __y._M_length; }
22958feb0f0bSmrg
22968feb0f0bSmrg constexpr counted_iterator&
22978feb0f0bSmrg operator-=(iter_difference_t<_It> __n)
22988feb0f0bSmrg requires random_access_iterator<_It>
22998feb0f0bSmrg {
23008feb0f0bSmrg __glibcxx_assert(-__n <= _M_length);
23018feb0f0bSmrg _M_current -= __n;
23028feb0f0bSmrg _M_length += __n;
23038feb0f0bSmrg return *this;
23048feb0f0bSmrg }
23058feb0f0bSmrg
23068feb0f0bSmrg constexpr decltype(auto)
23078feb0f0bSmrg operator[](iter_difference_t<_It> __n) const
23088feb0f0bSmrg noexcept(noexcept(_M_current[__n]))
23098feb0f0bSmrg requires random_access_iterator<_It>
23108feb0f0bSmrg {
23118feb0f0bSmrg __glibcxx_assert(__n < _M_length);
23128feb0f0bSmrg return _M_current[__n];
23138feb0f0bSmrg }
23148feb0f0bSmrg
23158feb0f0bSmrg template<common_with<_It> _It2>
23168feb0f0bSmrg friend constexpr bool
23178feb0f0bSmrg operator==(const counted_iterator& __x,
23188feb0f0bSmrg const counted_iterator<_It2>& __y)
23198feb0f0bSmrg { return __x._M_length == __y._M_length; }
23208feb0f0bSmrg
23218feb0f0bSmrg friend constexpr bool
23228feb0f0bSmrg operator==(const counted_iterator& __x, default_sentinel_t)
23238feb0f0bSmrg { return __x._M_length == 0; }
23248feb0f0bSmrg
23258feb0f0bSmrg template<common_with<_It> _It2>
23268feb0f0bSmrg friend constexpr strong_ordering
23278feb0f0bSmrg operator<=>(const counted_iterator& __x,
23288feb0f0bSmrg const counted_iterator<_It2>& __y)
23298feb0f0bSmrg { return __y._M_length <=> __x._M_length; }
23308feb0f0bSmrg
23318feb0f0bSmrg friend constexpr iter_rvalue_reference_t<_It>
23328feb0f0bSmrg iter_move(const counted_iterator& __i)
23338feb0f0bSmrg noexcept(noexcept(ranges::iter_move(__i._M_current)))
23348feb0f0bSmrg requires input_iterator<_It>
23358feb0f0bSmrg { return ranges::iter_move(__i._M_current); }
23368feb0f0bSmrg
23378feb0f0bSmrg template<indirectly_swappable<_It> _It2>
23388feb0f0bSmrg friend constexpr void
23398feb0f0bSmrg iter_swap(const counted_iterator& __x,
23408feb0f0bSmrg const counted_iterator<_It2>& __y)
23418feb0f0bSmrg noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
23428feb0f0bSmrg { ranges::iter_swap(__x._M_current, __y._M_current); }
23438feb0f0bSmrg
23448feb0f0bSmrg private:
23458feb0f0bSmrg template<input_or_output_iterator _It2> friend class counted_iterator;
23468feb0f0bSmrg
23478feb0f0bSmrg _It _M_current = _It();
23488feb0f0bSmrg iter_difference_t<_It> _M_length = 0;
23498feb0f0bSmrg };
23508feb0f0bSmrg
23518feb0f0bSmrg template<input_iterator _It>
23528feb0f0bSmrg requires same_as<__detail::__iter_traits<_It>, iterator_traits<_It>>
23538feb0f0bSmrg struct iterator_traits<counted_iterator<_It>> : iterator_traits<_It>
23548feb0f0bSmrg {
23558feb0f0bSmrg using pointer = conditional_t<contiguous_iterator<_It>,
23568feb0f0bSmrg add_pointer_t<iter_reference_t<_It>>,
23578feb0f0bSmrg void>;
23588feb0f0bSmrg };
23598feb0f0bSmrg #endif // C++20
23608feb0f0bSmrg
23618feb0f0bSmrg /// @} group iterators
23621debfc3dSmrg
23631debfc3dSmrg template<typename _Iterator>
23648feb0f0bSmrg _GLIBCXX20_CONSTEXPR
23651debfc3dSmrg auto
23661debfc3dSmrg __niter_base(move_iterator<_Iterator> __it)
23671debfc3dSmrg -> decltype(make_move_iterator(__niter_base(__it.base())))
23681debfc3dSmrg { return make_move_iterator(__niter_base(__it.base())); }
23691debfc3dSmrg
23701debfc3dSmrg template<typename _Iterator>
23711debfc3dSmrg struct __is_move_iterator<move_iterator<_Iterator> >
23721debfc3dSmrg {
23731debfc3dSmrg enum { __value = 1 };
23741debfc3dSmrg typedef __true_type __type;
23751debfc3dSmrg };
23761debfc3dSmrg
23771debfc3dSmrg template<typename _Iterator>
23788feb0f0bSmrg _GLIBCXX20_CONSTEXPR
23791debfc3dSmrg auto
23801debfc3dSmrg __miter_base(move_iterator<_Iterator> __it)
23811debfc3dSmrg -> decltype(__miter_base(__it.base()))
23821debfc3dSmrg { return __miter_base(__it.base()); }
23831debfc3dSmrg
23841debfc3dSmrg #define _GLIBCXX_MAKE_MOVE_ITERATOR(_Iter) std::make_move_iterator(_Iter)
23851debfc3dSmrg #define _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(_Iter) \
23861debfc3dSmrg std::__make_move_if_noexcept_iterator(_Iter)
23871debfc3dSmrg #else
23881debfc3dSmrg #define _GLIBCXX_MAKE_MOVE_ITERATOR(_Iter) (_Iter)
23891debfc3dSmrg #define _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(_Iter) (_Iter)
23901debfc3dSmrg #endif // C++11
23911debfc3dSmrg
2392a2dc1f3fSmrg #if __cpp_deduction_guides >= 201606
2393a2dc1f3fSmrg // These helper traits are used for deduction guides
2394a2dc1f3fSmrg // of associative containers.
2395a2dc1f3fSmrg template<typename _InputIterator>
2396a2dc1f3fSmrg using __iter_key_t = remove_const_t<
2397a2dc1f3fSmrg typename iterator_traits<_InputIterator>::value_type::first_type>;
2398a2dc1f3fSmrg
2399a2dc1f3fSmrg template<typename _InputIterator>
2400a2dc1f3fSmrg using __iter_val_t =
2401a2dc1f3fSmrg typename iterator_traits<_InputIterator>::value_type::second_type;
2402a2dc1f3fSmrg
2403a2dc1f3fSmrg template<typename _T1, typename _T2>
2404a2dc1f3fSmrg struct pair;
2405a2dc1f3fSmrg
2406a2dc1f3fSmrg template<typename _InputIterator>
2407a2dc1f3fSmrg using __iter_to_alloc_t =
2408a2dc1f3fSmrg pair<add_const_t<__iter_key_t<_InputIterator>>,
2409a2dc1f3fSmrg __iter_val_t<_InputIterator>>;
24108feb0f0bSmrg #endif // __cpp_deduction_guides
2411a2dc1f3fSmrg
2412a2dc1f3fSmrg _GLIBCXX_END_NAMESPACE_VERSION
2413a2dc1f3fSmrg } // namespace
2414a2dc1f3fSmrg
24151debfc3dSmrg #ifdef _GLIBCXX_DEBUG
24161debfc3dSmrg # include <debug/stl_iterator.h>
24171debfc3dSmrg #endif
24181debfc3dSmrg
24191debfc3dSmrg #endif
2420