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