libstdc++
ranges
Go to the documentation of this file.
1// <ranges> -*- C++ -*-
2
3// Copyright (C) 2019-2025 Free Software Foundation, Inc.
4//
5// This file is part of the GNU ISO C++ Library. This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 3, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23// <http://www.gnu.org/licenses/>.
24
25/** @file include/ranges
26 * This is a Standard C++ Library header.
27 * @ingroup concepts
28 */
29
30#ifndef _GLIBCXX_RANGES
31#define _GLIBCXX_RANGES 1
32
33#if __cplusplus > 201703L
34
35#ifdef _GLIBCXX_SYSHDR
36#pragma GCC system_header
37#endif
38
39#include <concepts>
40
41#if __cpp_lib_concepts
42
43#include <compare>
44#include <initializer_list>
45#include <iterator>
46#include <optional>
47#include <span>
48#include <string_view>
49#include <tuple>
50#if __cplusplus > 202002L
51#include <variant>
52#endif
53#include <bits/ranges_util.h>
54#include <bits/refwrap.h>
55
56#define __glibcxx_want_algorithm_default_value_type
57#define __glibcxx_want_ranges
58#define __glibcxx_want_ranges_as_const
59#define __glibcxx_want_ranges_as_rvalue
60#define __glibcxx_want_ranges_cartesian_product
61#define __glibcxx_want_ranges_concat
62#define __glibcxx_want_ranges_chunk
63#define __glibcxx_want_ranges_chunk_by
64#define __glibcxx_want_ranges_enumerate
65#define __glibcxx_want_ranges_iota
66#define __glibcxx_want_ranges_join_with
67#define __glibcxx_want_ranges_repeat
68#define __glibcxx_want_ranges_slide
69#define __glibcxx_want_ranges_stride
70#define __glibcxx_want_ranges_to_container
71#define __glibcxx_want_ranges_zip
72#include <bits/version.h>
73
74#ifdef __glibcxx_generator // C++ >= 23 && __glibcxx_coroutine
75# include <bits/elements_of.h>
76#endif
77
78/**
79 * @defgroup ranges Ranges
80 *
81 * Components for dealing with ranges of elements.
82 */
83
84namespace std _GLIBCXX_VISIBILITY(default)
85{
86_GLIBCXX_BEGIN_NAMESPACE_VERSION
87namespace ranges
88{
89 // [range.access] customization point objects
90 // [range.req] range and view concepts
91 // [range.dangling] dangling iterator handling
92 // Defined in <bits/ranges_base.h>
93
94 // [view.interface] View interface
95 // [range.subrange] Sub-ranges
96 // Defined in <bits/ranges_util.h>
97
98 // C++20 24.6 [range.factories] Range factories
99
100 /// A view that contains no elements.
101 template<typename _Tp> requires is_object_v<_Tp>
102 class empty_view
103 : public view_interface<empty_view<_Tp>>
104 {
105 public:
106 static constexpr _Tp* begin() noexcept { return nullptr; }
107 static constexpr _Tp* end() noexcept { return nullptr; }
108 static constexpr _Tp* data() noexcept { return nullptr; }
109 static constexpr size_t size() noexcept { return 0; }
110 static constexpr bool empty() noexcept { return true; }
111 };
112
113 template<typename _Tp>
114 inline constexpr bool enable_borrowed_range<empty_view<_Tp>> = true;
115
116 namespace __detail
117 {
118#if __cpp_lib_ranges >= 202207L // C++ >= 23
119 // P2494R2 Relaxing range adaptors to allow for move only types
120 template<typename _Tp>
121 concept __boxable = move_constructible<_Tp> && is_object_v<_Tp>;
122#else
123 template<typename _Tp>
124 concept __boxable = copy_constructible<_Tp> && is_object_v<_Tp>;
125#endif
126
127 template<__boxable _Tp>
128 struct __box : std::optional<_Tp>
129 {
130 using std::optional<_Tp>::optional;
131
132 constexpr
133 __box()
134 noexcept(is_nothrow_default_constructible_v<_Tp>)
135 requires default_initializable<_Tp>
136 : std::optional<_Tp>{std::in_place}
137 { }
138
139 __box(const __box&) = default;
140 __box(__box&&) = default;
141
142 using std::optional<_Tp>::operator=;
143
144 // _GLIBCXX_RESOLVE_LIB_DEFECTS
145 // 3477. Simplify constraints for semiregular-box
146 // 3572. copyable-box should be fully constexpr
147 constexpr __box&
148 operator=(const __box& __that)
149 noexcept(is_nothrow_copy_constructible_v<_Tp>)
150 requires (!copyable<_Tp>) && copy_constructible<_Tp>
151 {
152 if (this != std::__addressof(__that))
153 {
154 if ((bool)__that)
155 this->emplace(*__that);
156 else
157 this->reset();
158 }
159 return *this;
160 }
161
162 constexpr __box&
163 operator=(__box&& __that)
164 noexcept(is_nothrow_move_constructible_v<_Tp>)
165 requires (!movable<_Tp>)
166 {
167 if (this != std::__addressof(__that))
168 {
169 if ((bool)__that)
170 this->emplace(std::move(*__that));
171 else
172 this->reset();
173 }
174 return *this;
175 }
176 };
177
178 template<typename _Tp>
179 concept __boxable_copyable
180 = copy_constructible<_Tp>
181 && (copyable<_Tp> || (is_nothrow_move_constructible_v<_Tp>
182 && is_nothrow_copy_constructible_v<_Tp>));
183 template<typename _Tp>
184 concept __boxable_movable
185 = (!copy_constructible<_Tp>)
186 && (movable<_Tp> || is_nothrow_move_constructible_v<_Tp>);
187
188 // For types which are already copyable (or since C++23, movable)
189 // this specialization of the box wrapper stores the object directly
190 // without going through std::optional. It provides just the subset of
191 // the primary template's API that we currently use.
192 template<__boxable _Tp>
193 requires __boxable_copyable<_Tp> || __boxable_movable<_Tp>
194 struct __box<_Tp>
195 {
196 private:
197 [[no_unique_address]] _Tp _M_value = _Tp();
198
199 public:
200 __box() requires default_initializable<_Tp> = default;
201
202 constexpr explicit
203 __box(const _Tp& __t)
204 noexcept(is_nothrow_copy_constructible_v<_Tp>)
205 requires copy_constructible<_Tp>
206 : _M_value(__t)
207 { }
208
209 constexpr explicit
210 __box(_Tp&& __t)
211 noexcept(is_nothrow_move_constructible_v<_Tp>)
212 : _M_value(std::move(__t))
213 { }
214
215 template<typename... _Args>
216 requires constructible_from<_Tp, _Args...>
217 constexpr explicit
218 __box(in_place_t, _Args&&... __args)
219 noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
220 : _M_value(std::forward<_Args>(__args)...)
221 { }
222
223 __box(const __box&) = default;
224 __box(__box&&) = default;
225 __box& operator=(const __box&) requires copyable<_Tp> = default;
226 __box& operator=(__box&&) requires movable<_Tp> = default;
227
228 // When _Tp is nothrow_copy_constructible but not copy_assignable,
229 // copy assignment is implemented via destroy-then-copy-construct.
230 constexpr __box&
231 operator=(const __box& __that) noexcept
232 requires (!copyable<_Tp>) && copy_constructible<_Tp>
233 {
234 static_assert(is_nothrow_copy_constructible_v<_Tp>);
235 if (this != std::__addressof(__that))
236 {
237 _M_value.~_Tp();
238 std::construct_at(std::__addressof(_M_value), *__that);
239 }
240 return *this;
241 }
242
243 // Likewise for move assignment.
244 constexpr __box&
245 operator=(__box&& __that) noexcept
246 requires (!movable<_Tp>)
247 {
248 static_assert(is_nothrow_move_constructible_v<_Tp>);
249 if (this != std::__addressof(__that))
250 {
251 _M_value.~_Tp();
252 std::construct_at(std::__addressof(_M_value), std::move(*__that));
253 }
254 return *this;
255 }
256
257 constexpr bool
258 has_value() const noexcept
259 { return true; };
260
261 constexpr _Tp&
262 operator*() & noexcept
263 { return _M_value; }
264
265 constexpr const _Tp&
266 operator*() const & noexcept
267 { return _M_value; }
268
269 constexpr _Tp&&
270 operator*() && noexcept
271 { return std::move(_M_value); }
272
273 constexpr const _Tp&&
274 operator*() const && noexcept
275 { return std::move(_M_value); }
276
277 constexpr _Tp*
278 operator->() noexcept
279 { return std::__addressof(_M_value); }
280
281 constexpr const _Tp*
282 operator->() const noexcept
283 { return std::__addressof(_M_value); }
284 };
285 } // namespace __detail
286
287 /// A view that contains exactly one element.
288#if __cpp_lib_ranges >= 202207L // C++ >= 23
289 template<move_constructible _Tp>
290#else
291 template<copy_constructible _Tp>
292#endif
293 requires is_object_v<_Tp>
294 class single_view : public view_interface<single_view<_Tp>>
295 {
296 public:
297 single_view() requires default_initializable<_Tp> = default;
298
299 constexpr explicit
300 single_view(const _Tp& __t)
301 noexcept(is_nothrow_copy_constructible_v<_Tp>)
302 requires copy_constructible<_Tp>
303 : _M_value(__t)
304 { }
305
306 constexpr explicit
307 single_view(_Tp&& __t)
308 noexcept(is_nothrow_move_constructible_v<_Tp>)
309 : _M_value(std::move(__t))
310 { }
311
312 // _GLIBCXX_RESOLVE_LIB_DEFECTS
313 // 3428. single_view's in place constructor should be explicit
314 template<typename... _Args>
315 requires constructible_from<_Tp, _Args...>
316 constexpr explicit
317 single_view(in_place_t, _Args&&... __args)
318 noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
319 : _M_value{in_place, std::forward<_Args>(__args)...}
320 { }
321
322 constexpr _Tp*
323 begin() noexcept
324 { return data(); }
325
326 constexpr const _Tp*
327 begin() const noexcept
328 { return data(); }
329
330 constexpr _Tp*
331 end() noexcept
332 { return data() + 1; }
333
334 constexpr const _Tp*
335 end() const noexcept
336 { return data() + 1; }
337
338 // _GLIBCXX_RESOLVE_LIB_DEFECTS
339 // 4035. single_view should provide empty
340 static constexpr bool
341 empty() noexcept
342 { return false; }
343
344 static constexpr size_t
345 size() noexcept
346 { return 1; }
347
348 constexpr _Tp*
349 data() noexcept
350 { return _M_value.operator->(); }
351
352 constexpr const _Tp*
353 data() const noexcept
354 { return _M_value.operator->(); }
355
356 private:
357 [[no_unique_address]] __detail::__box<_Tp> _M_value;
358 };
359
360 template<typename _Tp>
361 single_view(_Tp) -> single_view<_Tp>;
362
363 namespace __detail
364 {
365 template<typename _Wp>
366 constexpr auto __to_signed_like(_Wp __w) noexcept
367 {
368 if constexpr (!integral<_Wp>)
369 return iter_difference_t<_Wp>();
370 else if constexpr (sizeof(iter_difference_t<_Wp>) > sizeof(_Wp))
371 return iter_difference_t<_Wp>(__w);
372 else if constexpr (sizeof(ptrdiff_t) > sizeof(_Wp))
373 return ptrdiff_t(__w);
374 else if constexpr (sizeof(long long) > sizeof(_Wp))
375 return (long long)(__w);
376#ifdef __SIZEOF_INT128__
377 else if constexpr (__SIZEOF_INT128__ > sizeof(_Wp))
378 return __int128(__w);
379#endif
380 else
381 return __max_diff_type(__w);
382 }
383
384 template<typename _Wp>
385 using __iota_diff_t = decltype(__to_signed_like(std::declval<_Wp>()));
386
387 template<typename _It>
388 concept __decrementable = incrementable<_It>
389 && requires(_It __i)
390 {
391 { --__i } -> same_as<_It&>;
392 { __i-- } -> same_as<_It>;
393 };
394
395 template<typename _It>
396 concept __advanceable = __decrementable<_It> && totally_ordered<_It>
397 && requires( _It __i, const _It __j, const __iota_diff_t<_It> __n)
398 {
399 { __i += __n } -> same_as<_It&>;
400 { __i -= __n } -> same_as<_It&>;
401 _It(__j + __n);
402 _It(__n + __j);
403 _It(__j - __n);
404 { __j - __j } -> convertible_to<__iota_diff_t<_It>>;
405 };
406
407 template<typename _Winc>
408 struct __iota_view_iter_cat
409 { };
410
411 template<incrementable _Winc>
412 struct __iota_view_iter_cat<_Winc>
413 { using iterator_category = input_iterator_tag; };
414 } // namespace __detail
415
416 template<weakly_incrementable _Winc,
417 semiregular _Bound = unreachable_sentinel_t>
418 requires std::__detail::__weakly_eq_cmp_with<_Winc, _Bound>
419 && copyable<_Winc>
420 class iota_view : public view_interface<iota_view<_Winc, _Bound>>
421 {
422 private:
423 struct _Sentinel;
424
425 struct _Iterator : __detail::__iota_view_iter_cat<_Winc>
426 {
427 private:
428 static auto
429 _S_iter_concept()
430 {
431 using namespace __detail;
432 if constexpr (__advanceable<_Winc>)
433 return random_access_iterator_tag{};
434 else if constexpr (__decrementable<_Winc>)
435 return bidirectional_iterator_tag{};
436 else if constexpr (incrementable<_Winc>)
437 return forward_iterator_tag{};
438 else
439 return input_iterator_tag{};
440 }
441
442 public:
443 using iterator_concept = decltype(_S_iter_concept());
444 // iterator_category defined in __iota_view_iter_cat
445 using value_type = _Winc;
446 using difference_type = __detail::__iota_diff_t<_Winc>;
447
448 _Iterator() requires default_initializable<_Winc> = default;
449
450 constexpr explicit
451 _Iterator(_Winc __value)
452 : _M_value(__value) { }
453
454 constexpr _Winc
455 operator*() const noexcept(is_nothrow_copy_constructible_v<_Winc>)
456 { return _M_value; }
457
458 constexpr _Iterator&
459 operator++()
460 {
461 ++_M_value;
462 return *this;
463 }
464
465 constexpr void
466 operator++(int)
467 { ++*this; }
468
469 constexpr _Iterator
470 operator++(int) requires incrementable<_Winc>
471 {
472 auto __tmp = *this;
473 ++*this;
474 return __tmp;
475 }
476
477 constexpr _Iterator&
478 operator--() requires __detail::__decrementable<_Winc>
479 {
480 --_M_value;
481 return *this;
482 }
483
484 constexpr _Iterator
485 operator--(int) requires __detail::__decrementable<_Winc>
486 {
487 auto __tmp = *this;
488 --*this;
489 return __tmp;
490 }
491
492 constexpr _Iterator&
493 operator+=(difference_type __n) requires __detail::__advanceable<_Winc>
494 {
495 using __detail::__is_integer_like;
496 using __detail::__is_signed_integer_like;
497 if constexpr (__is_integer_like<_Winc>
498 && !__is_signed_integer_like<_Winc>)
499 {
500 if (__n >= difference_type(0))
501 _M_value += static_cast<_Winc>(__n);
502 else
503 _M_value -= static_cast<_Winc>(-__n);
504 }
505 else
506 _M_value += __n;
507 return *this;
508 }
509
510 constexpr _Iterator&
511 operator-=(difference_type __n) requires __detail::__advanceable<_Winc>
512 {
513 using __detail::__is_integer_like;
514 using __detail::__is_signed_integer_like;
515 if constexpr (__is_integer_like<_Winc>
516 && !__is_signed_integer_like<_Winc>)
517 {
518 if (__n >= difference_type(0))
519 _M_value -= static_cast<_Winc>(__n);
520 else
521 _M_value += static_cast<_Winc>(-__n);
522 }
523 else
524 _M_value -= __n;
525 return *this;
526 }
527
528 constexpr _Winc
529 operator[](difference_type __n) const
530 requires __detail::__advanceable<_Winc>
531 { return _Winc(_M_value + __n); }
532
533 friend constexpr bool
534 operator==(const _Iterator& __x, const _Iterator& __y)
535 requires equality_comparable<_Winc>
536 { return __x._M_value == __y._M_value; }
537
538 friend constexpr bool
539 operator<(const _Iterator& __x, const _Iterator& __y)
540 requires totally_ordered<_Winc>
541 { return __x._M_value < __y._M_value; }
542
543 friend constexpr bool
544 operator>(const _Iterator& __x, const _Iterator& __y)
545 requires totally_ordered<_Winc>
546 { return __y < __x; }
547
548 friend constexpr bool
549 operator<=(const _Iterator& __x, const _Iterator& __y)
550 requires totally_ordered<_Winc>
551 { return !(__y < __x); }
552
553 friend constexpr bool
554 operator>=(const _Iterator& __x, const _Iterator& __y)
555 requires totally_ordered<_Winc>
556 { return !(__x < __y); }
557
558#ifdef __cpp_lib_three_way_comparison
559 friend constexpr auto
560 operator<=>(const _Iterator& __x, const _Iterator& __y)
561 requires totally_ordered<_Winc> && three_way_comparable<_Winc>
562 { return __x._M_value <=> __y._M_value; }
563#endif
564
565 friend constexpr _Iterator
566 operator+(_Iterator __i, difference_type __n)
567 requires __detail::__advanceable<_Winc>
568 {
569 __i += __n;
570 return __i;
571 }
572
573 friend constexpr _Iterator
574 operator+(difference_type __n, _Iterator __i)
575 requires __detail::__advanceable<_Winc>
576 { return __i += __n; }
577
578 friend constexpr _Iterator
579 operator-(_Iterator __i, difference_type __n)
580 requires __detail::__advanceable<_Winc>
581 {
582 __i -= __n;
583 return __i;
584 }
585
586 friend constexpr difference_type
587 operator-(const _Iterator& __x, const _Iterator& __y)
588 requires __detail::__advanceable<_Winc>
589 {
590 using __detail::__is_integer_like;
591 using __detail::__is_signed_integer_like;
592 using _Dt = difference_type;
593 if constexpr (__is_integer_like<_Winc>)
594 {
595 if constexpr (__is_signed_integer_like<_Winc>)
596 return _Dt(_Dt(__x._M_value) - _Dt(__y._M_value));
597 else
598 return (__y._M_value > __x._M_value)
599 ? _Dt(-_Dt(__y._M_value - __x._M_value))
600 : _Dt(__x._M_value - __y._M_value);
601 }
602 else
603 return __x._M_value - __y._M_value;
604 }
605
606 private:
607 _Winc _M_value = _Winc();
608
609 friend iota_view;
610 friend _Sentinel;
611 };
612
613 struct _Sentinel
614 {
615 private:
616 constexpr bool
617 _M_equal(const _Iterator& __x) const
618 { return __x._M_value == _M_bound; }
619
620 constexpr auto
621 _M_distance_from(const _Iterator& __x) const
622 { return _M_bound - __x._M_value; }
623
624 _Bound _M_bound = _Bound();
625
626 public:
627 _Sentinel() = default;
628
629 constexpr explicit
630 _Sentinel(_Bound __bound)
631 : _M_bound(__bound) { }
632
633 friend constexpr bool
634 operator==(const _Iterator& __x, const _Sentinel& __y)
635 { return __y._M_equal(__x); }
636
637 friend constexpr iter_difference_t<_Winc>
638 operator-(const _Iterator& __x, const _Sentinel& __y)
639 requires sized_sentinel_for<_Bound, _Winc>
640 { return -__y._M_distance_from(__x); }
641
642 friend constexpr iter_difference_t<_Winc>
643 operator-(const _Sentinel& __x, const _Iterator& __y)
644 requires sized_sentinel_for<_Bound, _Winc>
645 { return __x._M_distance_from(__y); }
646
647 friend iota_view;
648 };
649
650 _Winc _M_value = _Winc();
651 [[no_unique_address]] _Bound _M_bound = _Bound();
652
653 public:
654 iota_view() requires default_initializable<_Winc> = default;
655
656 constexpr explicit
657 iota_view(_Winc __value)
658 : _M_value(__value)
659 { }
660
661 constexpr
662 iota_view(type_identity_t<_Winc> __value,
663 type_identity_t<_Bound> __bound)
664 : _M_value(__value), _M_bound(__bound)
665 {
666 if constexpr (totally_ordered_with<_Winc, _Bound>)
667 __glibcxx_assert( bool(__value <= __bound) );
668 }
669
670 constexpr
671 iota_view(_Iterator __first, _Iterator __last)
672 requires same_as<_Winc, _Bound>
673 : iota_view(__first._M_value, __last._M_value)
674 { }
675
676 constexpr
677 iota_view(_Iterator __first, unreachable_sentinel_t __last)
678 requires same_as<_Bound, unreachable_sentinel_t>
679 : iota_view(__first._M_value, __last)
680 { }
681
682 constexpr
683 iota_view(_Iterator __first, _Sentinel __last)
684 requires (!same_as<_Winc, _Bound>) && (!same_as<_Bound, unreachable_sentinel_t>)
685 : iota_view(__first._M_value, __last._M_bound)
686 { }
687
688 constexpr _Iterator
689 begin() const { return _Iterator{_M_value}; }
690
691 constexpr auto
692 end() const
693 {
694 if constexpr (same_as<_Bound, unreachable_sentinel_t>)
695 return unreachable_sentinel;
696 else
697 return _Sentinel{_M_bound};
698 }
699
700 constexpr _Iterator
701 end() const requires same_as<_Winc, _Bound>
702 { return _Iterator{_M_bound}; }
703
704 // _GLIBCXX_RESOLVE_LIB_DEFECTS
705 // 4001. iota_view should provide empty
706 constexpr bool
707 empty() const
708 { return _M_value == _M_bound; }
709
710 constexpr auto
711 size() const
712 requires (same_as<_Winc, _Bound> && __detail::__advanceable<_Winc>)
713 || (integral<_Winc> && integral<_Bound>)
714 || sized_sentinel_for<_Bound, _Winc>
715 {
716 using __detail::__is_integer_like;
717 using __detail::__to_unsigned_like;
718 if constexpr (integral<_Winc> && integral<_Bound>)
719 {
720 using _Up = make_unsigned_t<decltype(_M_bound - _M_value)>;
721 return _Up(_M_bound) - _Up(_M_value);
722 }
723 else if constexpr (__is_integer_like<_Winc>)
724 return __to_unsigned_like(_M_bound) - __to_unsigned_like(_M_value);
725 else
726 return __to_unsigned_like(_M_bound - _M_value);
727 }
728 };
729
730 template<typename _Winc, typename _Bound>
731 requires (!__detail::__is_integer_like<_Winc>
732 || !__detail::__is_integer_like<_Bound>
733 || (__detail::__is_signed_integer_like<_Winc>
734 == __detail::__is_signed_integer_like<_Bound>))
735 iota_view(_Winc, _Bound) -> iota_view<_Winc, _Bound>;
736
737 template<typename _Winc, typename _Bound>
738 inline constexpr bool
739 enable_borrowed_range<iota_view<_Winc, _Bound>> = true;
740
741namespace views
742{
743 template<typename _Tp>
744 inline constexpr empty_view<_Tp> empty{};
745
746 namespace __detail
747 {
748 template<typename _Tp>
749 concept __can_single_view
750 = requires { single_view<decay_t<_Tp>>(std::declval<_Tp>()); };
751 } // namespace __detail
752
753 struct _Single
754 {
755 template<__detail::__can_single_view _Tp>
756 constexpr auto
757 operator() [[nodiscard]] (_Tp&& __e) const
758 noexcept(noexcept(single_view<decay_t<_Tp>>(std::forward<_Tp>(__e))))
759 { return single_view<decay_t<_Tp>>(std::forward<_Tp>(__e)); }
760 };
761
762 inline constexpr _Single single{};
763
764 namespace __detail
765 {
766 template<typename... _Args>
767 concept __can_iota_view = requires { iota_view(std::declval<_Args>()...); };
768 } // namespace __detail
769
770 struct _Iota
771 {
772 template<__detail::__can_iota_view _Tp>
773 constexpr auto
774 operator() [[nodiscard]] (_Tp&& __e) const
775 { return iota_view(std::forward<_Tp>(__e)); }
776
777 template<typename _Tp, typename _Up>
778 requires __detail::__can_iota_view<_Tp, _Up>
779 constexpr auto
780 operator() [[nodiscard]] (_Tp&& __e, _Up&& __f) const
781 { return iota_view(std::forward<_Tp>(__e), std::forward<_Up>(__f)); }
782 };
783
784 inline constexpr _Iota iota{};
785} // namespace views
786
787#if _GLIBCXX_HOSTED
788 namespace __detail
789 {
790 template<typename _Val, typename _CharT, typename _Traits>
791 concept __stream_extractable
792 = requires(basic_istream<_CharT, _Traits>& is, _Val& t) { is >> t; };
793 } // namespace __detail
794
795 template<movable _Val, typename _CharT,
796 typename _Traits = char_traits<_CharT>>
797 requires default_initializable<_Val>
798 && __detail::__stream_extractable<_Val, _CharT, _Traits>
799 class basic_istream_view
800 : public view_interface<basic_istream_view<_Val, _CharT, _Traits>>
801 {
802 public:
803 constexpr explicit
804 basic_istream_view(basic_istream<_CharT, _Traits>& __stream)
805 : _M_stream(std::__addressof(__stream))
806 { }
807
808 constexpr auto
809 begin()
810 {
811 *_M_stream >> _M_object;
812 return _Iterator{this};
813 }
814
815 constexpr default_sentinel_t
816 end() const noexcept
817 { return default_sentinel; }
818
819 private:
820 basic_istream<_CharT, _Traits>* _M_stream;
821 _Val _M_object = _Val();
822
823 struct _Iterator
824 {
825 public:
826 using iterator_concept = input_iterator_tag;
827 using difference_type = ptrdiff_t;
828 using value_type = _Val;
829
830 constexpr explicit
831 _Iterator(basic_istream_view* __parent) noexcept
832 : _M_parent(__parent)
833 { }
834
835 _Iterator(const _Iterator&) = delete;
836 _Iterator(_Iterator&&) = default;
837 _Iterator& operator=(const _Iterator&) = delete;
838 _Iterator& operator=(_Iterator&&) = default;
839
840 _Iterator&
841 operator++()
842 {
843 *_M_parent->_M_stream >> _M_parent->_M_object;
844 return *this;
845 }
846
847 void
848 operator++(int)
849 { ++*this; }
850
851 _Val&
852 operator*() const
853 { return _M_parent->_M_object; }
854
855 friend bool
856 operator==(const _Iterator& __x, default_sentinel_t)
857 { return __x._M_at_end(); }
858
859 private:
860 basic_istream_view* _M_parent;
861
862 bool
863 _M_at_end() const
864 { return !*_M_parent->_M_stream; }
865 };
866
867 friend _Iterator;
868 };
869
870 template<typename _Val>
871 using istream_view = basic_istream_view<_Val, char>;
872
873 template<typename _Val>
874 using wistream_view = basic_istream_view<_Val, wchar_t>;
875
876namespace views
877{
878 namespace __detail
879 {
880 template<typename _Tp, typename _Up>
881 concept __can_istream_view = requires (_Up __e) {
882 basic_istream_view<_Tp, typename _Up::char_type, typename _Up::traits_type>(__e);
883 };
884 } // namespace __detail
885
886 template<typename _Tp>
887 struct _Istream
888 {
889 template<typename _CharT, typename _Traits>
890 constexpr auto
891 operator() [[nodiscard]] (basic_istream<_CharT, _Traits>& __e) const
892 requires __detail::__can_istream_view<_Tp, remove_reference_t<decltype(__e)>>
893 { return basic_istream_view<_Tp, _CharT, _Traits>(__e); }
894 };
895
896 template<typename _Tp>
897 inline constexpr _Istream<_Tp> istream;
898}
899#endif // HOSTED
900
901 // C++20 24.7 [range.adaptors] Range adaptors
902
903namespace __detail
904{
905 template<typename _Tp, int _Disc>
906 struct _Absent { };
907
908 // Alias for a type that is conditionally present
909 // (and is an empty type otherwise).
910 // Data members using this alias should use [[no_unique_address]] so that
911 // they take no space when not needed.
912 // The optional template parameter _Disc is for discriminating two otherwise
913 // equivalent absent types so that even they can overlap.
914 template<bool _Present, typename _Tp, int _Disc = 0>
915 using __maybe_present_t = __conditional_t<_Present, _Tp, _Absent<_Tp, _Disc>>;
916
917 // Alias for a type that is conditionally const.
918 template<bool _Const, typename _Tp>
919 using __maybe_const_t = __conditional_t<_Const, const _Tp, _Tp>;
920
921} // namespace __detail
922
923// Shorthand for __detail::__maybe_const_t.
924using __detail::__maybe_const_t;
925
926namespace views::__adaptor
927{
928 // True if the range adaptor _Adaptor can be applied with _Args.
929 template<typename _Adaptor, typename... _Args>
930 concept __adaptor_invocable
931 = requires { std::declval<_Adaptor>()(declval<_Args>()...); };
932
933 // True if the range adaptor non-closure _Adaptor can be partially applied
934 // with _Args.
935 template<typename _Adaptor, typename... _Args>
936 concept __adaptor_partial_app_viable = (_Adaptor::_S_arity > 1)
937 && (sizeof...(_Args) == _Adaptor::_S_arity - 1)
938 && (constructible_from<decay_t<_Args>, _Args> && ...);
939
940 template<typename _Adaptor, typename... _Args>
941 struct _Partial;
942
943 template<typename _Lhs, typename _Rhs>
944 struct _Pipe;
945
946 // The base class of every range adaptor closure.
947 //
948 // The derived class should define the optional static data member
949 // _S_has_simple_call_op to true if the behavior of this adaptor is
950 // independent of the constness/value category of the adaptor object.
951 template<typename _Derived>
952 struct _RangeAdaptorClosure;
953
954 template<typename _Tp, typename _Up>
955 requires (!same_as<_Tp, _RangeAdaptorClosure<_Up>>)
956 void __is_range_adaptor_closure_fn
957 (const _Tp&, const _RangeAdaptorClosure<_Up>&); // not defined
958
959 template<typename _Tp>
960 concept __is_range_adaptor_closure
961 = requires (_Tp __t) { __adaptor::__is_range_adaptor_closure_fn(__t, __t); };
962
963#pragma GCC diagnostic push
964#pragma GCC diagnostic ignored "-Wdangling-reference"
965 // range | adaptor is equivalent to adaptor(range).
966 template<typename _Self, typename _Range>
967 requires __is_range_adaptor_closure<_Self>
968 && __adaptor_invocable<_Self, _Range>
969 constexpr auto
970 operator|(_Range&& __r, _Self&& __self)
971 { return std::forward<_Self>(__self)(std::forward<_Range>(__r)); }
972
973 // Compose the adaptors __lhs and __rhs into a pipeline, returning
974 // another range adaptor closure object.
975 template<typename _Lhs, typename _Rhs>
976 requires __is_range_adaptor_closure<_Lhs>
977 && __is_range_adaptor_closure<_Rhs>
978 constexpr auto
979 operator|(_Lhs&& __lhs, _Rhs&& __rhs)
980 {
981 return _Pipe<decay_t<_Lhs>, decay_t<_Rhs>>{std::forward<_Lhs>(__lhs),
982 std::forward<_Rhs>(__rhs)};
983 }
984#pragma GCC diagnostic pop
985
986 template<typename _Derived>
987 struct _RangeAdaptorClosure
988 {
989 // In non-modules compilation ADL finds these operators either way and
990 // the friend declarations are redundant. But with the std module these
991 // friend declarations enable ADL to find these operators without having
992 // to export them.
993 template<typename _Self, typename _Range>
994 requires __is_range_adaptor_closure<_Self>
995 && __adaptor_invocable<_Self, _Range>
996 friend constexpr auto
997 operator|(_Range&& __r, _Self&& __self);
998
999 template<typename _Lhs, typename _Rhs>
1000 requires __is_range_adaptor_closure<_Lhs>
1001 && __is_range_adaptor_closure<_Rhs>
1002 friend constexpr auto
1003 operator|(_Lhs&& __lhs, _Rhs&& __rhs);
1004 };
1005
1006 // The base class of every range adaptor non-closure.
1007 //
1008 // The static data member _Derived::_S_arity must contain the total number of
1009 // arguments that the adaptor takes, and the class _Derived must introduce
1010 // _RangeAdaptor::operator() into the class scope via a using-declaration.
1011 //
1012 // The optional static data member _Derived::_S_has_simple_extra_args should
1013 // be defined to true if the behavior of this adaptor is independent of the
1014 // constness/value category of the extra arguments. This data member could
1015 // also be defined as a variable template parameterized by the types of the
1016 // extra arguments.
1017 template<typename _Derived>
1018 struct _RangeAdaptor
1019 {
1020 // Partially apply the arguments __args to the range adaptor _Derived,
1021 // returning a range adaptor closure object.
1022 template<typename... _Args>
1023 requires __adaptor_partial_app_viable<_Derived, _Args...>
1024 constexpr auto
1025 operator()(_Args&&... __args) const
1026 {
1027 return _Partial<_Derived, decay_t<_Args>...>{0, std::forward<_Args>(__args)...};
1028 }
1029 };
1030
1031 // True if the range adaptor closure _Adaptor has a simple operator(), i.e.
1032 // one that's not overloaded according to constness or value category of the
1033 // _Adaptor object.
1034 template<typename _Adaptor>
1035 concept __closure_has_simple_call_op = _Adaptor::_S_has_simple_call_op;
1036
1037 // True if the behavior of the range adaptor non-closure _Adaptor is
1038 // independent of the value category of its extra arguments _Args.
1039 template<typename _Adaptor, typename... _Args>
1040 concept __adaptor_has_simple_extra_args = _Adaptor::_S_has_simple_extra_args
1041 || _Adaptor::template _S_has_simple_extra_args<_Args...>;
1042
1043 // A range adaptor closure that represents partial application of
1044 // the range adaptor _Adaptor with arguments _Args.
1045 template<typename _Adaptor, typename... _Args>
1046 struct _Partial : _RangeAdaptorClosure<_Partial<_Adaptor, _Args...>>
1047 {
1048 tuple<_Args...> _M_args;
1049
1050 // First parameter is to ensure this constructor is never used
1051 // instead of the copy/move constructor.
1052 template<typename... _Ts>
1053 constexpr
1054 _Partial(int, _Ts&&... __args)
1055 : _M_args(std::forward<_Ts>(__args)...)
1056 { }
1057
1058 // Invoke _Adaptor with arguments __r, _M_args... according to the
1059 // value category of this _Partial object.
1060#if __cpp_explicit_this_parameter
1061 template<typename _Self, typename _Range>
1062 requires __adaptor_invocable<_Adaptor, _Range, __like_t<_Self, _Args>...>
1063 constexpr auto
1064 operator()(this _Self&& __self, _Range&& __r)
1065 {
1066 auto __forwarder = [&__r] (auto&&... __args) {
1067 return _Adaptor{}(std::forward<_Range>(__r),
1068 std::forward<decltype(__args)>(__args)...);
1069 };
1070 return std::apply(__forwarder, __like_t<_Self, _Partial>(__self)._M_args);
1071 }
1072#else
1073 template<typename _Range>
1074 requires __adaptor_invocable<_Adaptor, _Range, const _Args&...>
1075 constexpr auto
1076 operator()(_Range&& __r) const &
1077 {
1078 auto __forwarder = [&__r] (const auto&... __args) {
1079 return _Adaptor{}(std::forward<_Range>(__r), __args...);
1080 };
1081 return std::apply(__forwarder, _M_args);
1082 }
1083
1084 template<typename _Range>
1085 requires __adaptor_invocable<_Adaptor, _Range, _Args...>
1086 constexpr auto
1087 operator()(_Range&& __r) &&
1088 {
1089 auto __forwarder = [&__r] (auto&... __args) {
1090 return _Adaptor{}(std::forward<_Range>(__r), std::move(__args)...);
1091 };
1092 return std::apply(__forwarder, _M_args);
1093 }
1094
1095 template<typename _Range>
1096 constexpr auto
1097 operator()(_Range&& __r) const && = delete;
1098#endif
1099 };
1100
1101 // A lightweight specialization of the above primary template for
1102 // the common case where _Adaptor accepts a single extra argument.
1103 template<typename _Adaptor, typename _Arg>
1104 struct _Partial<_Adaptor, _Arg> : _RangeAdaptorClosure<_Partial<_Adaptor, _Arg>>
1105 {
1106 _Arg _M_arg;
1107
1108 template<typename _Tp>
1109 constexpr
1110 _Partial(int, _Tp&& __arg)
1111 : _M_arg(std::forward<_Tp>(__arg))
1112 { }
1113
1114#if __cpp_explicit_this_parameter
1115 template<typename _Self, typename _Range>
1116 requires __adaptor_invocable<_Adaptor, _Range, __like_t<_Self, _Arg>>
1117 constexpr auto
1118 operator()(this _Self&& __self, _Range&& __r)
1119 {
1120 return _Adaptor{}(std::forward<_Range>(__r),
1121 __like_t<_Self, _Partial>(__self)._M_arg);
1122 }
1123#else
1124 template<typename _Range>
1125 requires __adaptor_invocable<_Adaptor, _Range, const _Arg&>
1126 constexpr auto
1127 operator()(_Range&& __r) const &
1128 { return _Adaptor{}(std::forward<_Range>(__r), _M_arg); }
1129
1130 template<typename _Range>
1131 requires __adaptor_invocable<_Adaptor, _Range, _Arg>
1132 constexpr auto
1133 operator()(_Range&& __r) &&
1134 { return _Adaptor{}(std::forward<_Range>(__r), std::move(_M_arg)); }
1135
1136 template<typename _Range>
1137 constexpr auto
1138 operator()(_Range&& __r) const && = delete;
1139#endif
1140 };
1141
1142 // Partial specialization of the primary template for the case where the extra
1143 // arguments of the adaptor can always be safely and efficiently forwarded by
1144 // const reference. This lets us get away with a single operator() overload,
1145 // which makes overload resolution failure diagnostics more concise.
1146 template<typename _Adaptor, typename... _Args>
1147 requires __adaptor_has_simple_extra_args<_Adaptor, _Args...>
1148 && (is_trivially_copy_constructible_v<_Args> && ...)
1149 struct _Partial<_Adaptor, _Args...> : _RangeAdaptorClosure<_Partial<_Adaptor, _Args...>>
1150 {
1151 tuple<_Args...> _M_args;
1152
1153 template<typename... _Ts>
1154 constexpr
1155 _Partial(int, _Ts&&... __args)
1156 : _M_args(std::forward<_Ts>(__args)...)
1157 { }
1158
1159 // Invoke _Adaptor with arguments __r, const _M_args&... regardless
1160 // of the value category of this _Partial object.
1161 template<typename _Range>
1162 requires __adaptor_invocable<_Adaptor, _Range, const _Args&...>
1163 constexpr auto
1164 operator()(_Range&& __r) const
1165 {
1166 auto __forwarder = [&__r] (const auto&... __args) {
1167 return _Adaptor{}(std::forward<_Range>(__r), __args...);
1168 };
1169 return std::apply(__forwarder, _M_args);
1170 }
1171
1172 static constexpr bool _S_has_simple_call_op = true;
1173 };
1174
1175 // A lightweight specialization of the above template for the common case
1176 // where _Adaptor accepts a single extra argument.
1177 template<typename _Adaptor, typename _Arg>
1178 requires __adaptor_has_simple_extra_args<_Adaptor, _Arg>
1179 && is_trivially_copy_constructible_v<_Arg>
1180 struct _Partial<_Adaptor, _Arg> : _RangeAdaptorClosure<_Partial<_Adaptor, _Arg>>
1181 {
1182 _Arg _M_arg;
1183
1184 template<typename _Tp>
1185 constexpr
1186 _Partial(int, _Tp&& __arg)
1187 : _M_arg(std::forward<_Tp>(__arg))
1188 { }
1189
1190 template<typename _Range>
1191 requires __adaptor_invocable<_Adaptor, _Range, const _Arg&>
1192 constexpr auto
1193 operator()(_Range&& __r) const
1194 { return _Adaptor{}(std::forward<_Range>(__r), _M_arg); }
1195
1196 static constexpr bool _S_has_simple_call_op = true;
1197 };
1198
1199 template<typename _Lhs, typename _Rhs, typename _Range>
1200 concept __pipe_invocable
1201 = requires { std::declval<_Rhs>()(std::declval<_Lhs>()(std::declval<_Range>())); };
1202
1203 // A range adaptor closure that represents composition of the range
1204 // adaptor closures _Lhs and _Rhs.
1205 template<typename _Lhs, typename _Rhs>
1206 struct _Pipe : _RangeAdaptorClosure<_Pipe<_Lhs, _Rhs>>
1207 {
1208 [[no_unique_address]] _Lhs _M_lhs;
1209 [[no_unique_address]] _Rhs _M_rhs;
1210
1211 template<typename _Tp, typename _Up>
1212 constexpr
1213 _Pipe(_Tp&& __lhs, _Up&& __rhs)
1214 : _M_lhs(std::forward<_Tp>(__lhs)), _M_rhs(std::forward<_Up>(__rhs))
1215 { }
1216
1217 // Invoke _M_rhs(_M_lhs(__r)) according to the value category of this
1218 // range adaptor closure object.
1219#if __cpp_explicit_this_parameter
1220 template<typename _Self, typename _Range>
1221 requires __pipe_invocable<__like_t<_Self, _Lhs>, __like_t<_Self, _Rhs>, _Range>
1222 constexpr auto
1223 operator()(this _Self&& __self, _Range&& __r)
1224 {
1225 return (__like_t<_Self, _Pipe>(__self)._M_rhs
1226 (__like_t<_Self, _Pipe>(__self)._M_lhs
1227 (std::forward<_Range>(__r))));
1228 }
1229#else
1230 template<typename _Range>
1231 requires __pipe_invocable<const _Lhs&, const _Rhs&, _Range>
1232 constexpr auto
1233 operator()(_Range&& __r) const &
1234 { return _M_rhs(_M_lhs(std::forward<_Range>(__r))); }
1235
1236 template<typename _Range>
1237 requires __pipe_invocable<_Lhs, _Rhs, _Range>
1238 constexpr auto
1239 operator()(_Range&& __r) &&
1240 { return std::move(_M_rhs)(std::move(_M_lhs)(std::forward<_Range>(__r))); }
1241
1242 template<typename _Range>
1243 constexpr auto
1244 operator()(_Range&& __r) const && = delete;
1245#endif
1246 };
1247
1248 // A partial specialization of the above primary template for the case where
1249 // both adaptor operands have a simple operator(). This in turn lets us
1250 // implement composition using a single simple operator(), which makes
1251 // overload resolution failure diagnostics more concise.
1252 template<typename _Lhs, typename _Rhs>
1253 requires __closure_has_simple_call_op<_Lhs>
1254 && __closure_has_simple_call_op<_Rhs>
1255 struct _Pipe<_Lhs, _Rhs> : _RangeAdaptorClosure<_Pipe<_Lhs, _Rhs>>
1256 {
1257 [[no_unique_address]] _Lhs _M_lhs;
1258 [[no_unique_address]] _Rhs _M_rhs;
1259
1260 template<typename _Tp, typename _Up>
1261 constexpr
1262 _Pipe(_Tp&& __lhs, _Up&& __rhs)
1263 : _M_lhs(std::forward<_Tp>(__lhs)), _M_rhs(std::forward<_Up>(__rhs))
1264 { }
1265
1266 template<typename _Range>
1267 requires __pipe_invocable<const _Lhs&, const _Rhs&, _Range>
1268 constexpr auto
1269 operator()(_Range&& __r) const
1270 { return _M_rhs(_M_lhs(std::forward<_Range>(__r))); }
1271
1272 static constexpr bool _S_has_simple_call_op = true;
1273 };
1274} // namespace views::__adaptor
1275
1276#if __cpp_lib_ranges >= 202202L
1277 // P2387R3 Pipe support for user-defined range adaptors
1278 template<typename _Derived>
1279 requires is_class_v<_Derived> && same_as<_Derived, remove_cv_t<_Derived>>
1280 class range_adaptor_closure
1281 : public views::__adaptor::_RangeAdaptorClosure<_Derived>
1282 { };
1283#endif
1284
1285 template<range _Range> requires is_object_v<_Range>
1286 class ref_view : public view_interface<ref_view<_Range>>
1287 {
1288 private:
1289 _Range* _M_r;
1290
1291 static void _S_fun(_Range&); // not defined
1292 static void _S_fun(_Range&&) = delete;
1293
1294 public:
1295 template<__detail::__different_from<ref_view> _Tp>
1296 requires convertible_to<_Tp, _Range&>
1297 && requires { _S_fun(declval<_Tp>()); }
1298 constexpr
1299 ref_view(_Tp&& __t)
1300 noexcept(noexcept(static_cast<_Range&>(std::declval<_Tp>())))
1301 : _M_r(std::__addressof(static_cast<_Range&>(std::forward<_Tp>(__t))))
1302 { }
1303
1304 constexpr _Range&
1305 base() const
1306 { return *_M_r; }
1307
1308 constexpr iterator_t<_Range>
1309 begin() const
1310 { return ranges::begin(*_M_r); }
1311
1312 constexpr sentinel_t<_Range>
1313 end() const
1314 { return ranges::end(*_M_r); }
1315
1316 constexpr bool
1317 empty() const requires requires { ranges::empty(*_M_r); }
1318 { return ranges::empty(*_M_r); }
1319
1320 constexpr auto
1321 size() const requires sized_range<_Range>
1322 { return ranges::size(*_M_r); }
1323
1324 constexpr auto
1325 data() const requires contiguous_range<_Range>
1326 { return ranges::data(*_M_r); }
1327 };
1328
1329 template<typename _Range>
1330 ref_view(_Range&) -> ref_view<_Range>;
1331
1332 template<typename _Tp>
1333 inline constexpr bool enable_borrowed_range<ref_view<_Tp>> = true;
1334
1335 template<range _Range>
1336 requires movable<_Range>
1337 && (!__detail::__is_initializer_list<remove_cv_t<_Range>>)
1338 class owning_view : public view_interface<owning_view<_Range>>
1339 {
1340 private:
1341 _Range _M_r = _Range();
1342
1343 public:
1344 owning_view() requires default_initializable<_Range> = default;
1345
1346 constexpr
1347 owning_view(_Range&& __t)
1348 noexcept(is_nothrow_move_constructible_v<_Range>)
1349 : _M_r(std::move(__t))
1350 { }
1351
1352 owning_view(owning_view&&) = default;
1353 owning_view& operator=(owning_view&&) = default;
1354
1355 constexpr _Range&
1356 base() & noexcept
1357 { return _M_r; }
1358
1359 constexpr const _Range&
1360 base() const& noexcept
1361 { return _M_r; }
1362
1363 constexpr _Range&&
1364 base() && noexcept
1365 { return std::move(_M_r); }
1366
1367 constexpr const _Range&&
1368 base() const&& noexcept
1369 { return std::move(_M_r); }
1370
1371 constexpr iterator_t<_Range>
1372 begin()
1373 { return ranges::begin(_M_r); }
1374
1375 constexpr sentinel_t<_Range>
1376 end()
1377 { return ranges::end(_M_r); }
1378
1379 constexpr auto
1380 begin() const requires range<const _Range>
1381 { return ranges::begin(_M_r); }
1382
1383 constexpr auto
1384 end() const requires range<const _Range>
1385 { return ranges::end(_M_r); }
1386
1387 constexpr bool
1388 empty() requires requires { ranges::empty(_M_r); }
1389 { return ranges::empty(_M_r); }
1390
1391 constexpr bool
1392 empty() const requires requires { ranges::empty(_M_r); }
1393 { return ranges::empty(_M_r); }
1394
1395 constexpr auto
1396 size() requires sized_range<_Range>
1397 { return ranges::size(_M_r); }
1398
1399 constexpr auto
1400 size() const requires sized_range<const _Range>
1401 { return ranges::size(_M_r); }
1402
1403 constexpr auto
1404 data() requires contiguous_range<_Range>
1405 { return ranges::data(_M_r); }
1406
1407 constexpr auto
1408 data() const requires contiguous_range<const _Range>
1409 { return ranges::data(_M_r); }
1410 };
1411
1412 template<typename _Tp>
1413 inline constexpr bool enable_borrowed_range<owning_view<_Tp>>
1414 = enable_borrowed_range<_Tp>;
1415
1416 namespace views
1417 {
1418 namespace __detail
1419 {
1420 template<typename _Range>
1421 concept __can_ref_view = requires { ref_view{std::declval<_Range>()}; };
1422
1423 template<typename _Range>
1424 concept __can_owning_view = requires { owning_view{std::declval<_Range>()}; };
1425 } // namespace __detail
1426
1427 struct _All : __adaptor::_RangeAdaptorClosure<_All>
1428 {
1429 template<typename _Range>
1430 static constexpr bool
1431 _S_noexcept()
1432 {
1433 if constexpr (view<decay_t<_Range>>)
1434 return is_nothrow_constructible_v<decay_t<_Range>, _Range>;
1435 else if constexpr (__detail::__can_ref_view<_Range>)
1436 return true;
1437 else
1438 return noexcept(owning_view{std::declval<_Range>()});
1439 }
1440
1441 template<viewable_range _Range>
1442 requires view<decay_t<_Range>>
1443 || __detail::__can_ref_view<_Range>
1444 || __detail::__can_owning_view<_Range>
1445 constexpr auto
1446 operator() [[nodiscard]] (_Range&& __r) const
1447 noexcept(_S_noexcept<_Range>())
1448 {
1449 if constexpr (view<decay_t<_Range>>)
1450 return std::forward<_Range>(__r);
1451 else if constexpr (__detail::__can_ref_view<_Range>)
1452 return ref_view{std::forward<_Range>(__r)};
1453 else
1454 return owning_view{std::forward<_Range>(__r)};
1455 }
1456
1457 static constexpr bool _S_has_simple_call_op = true;
1458 };
1459
1460 inline constexpr _All all;
1461
1462 template<viewable_range _Range>
1463 using all_t = decltype(all(std::declval<_Range>()));
1464 } // namespace views
1465
1466 namespace __detail
1467 {
1468 template<typename _Tp>
1469 struct __non_propagating_cache
1470 {
1471 // When _Tp is not an object type (e.g. is a reference type), we make
1472 // __non_propagating_cache<_Tp> empty rather than ill-formed so that
1473 // users can easily conditionally declare data members with this type
1474 // (such as join_view::_M_inner).
1475 };
1476
1477 template<typename _Tp>
1478 requires is_object_v<_Tp>
1479 struct __non_propagating_cache<_Tp>
1480 : protected _Optional_base<_Tp>
1481 {
1482 __non_propagating_cache() = default;
1483
1484 constexpr
1485 __non_propagating_cache(const __non_propagating_cache&) noexcept
1486 { }
1487
1488 constexpr
1489 __non_propagating_cache(__non_propagating_cache&& __other) noexcept
1490 { __other._M_reset(); }
1491
1492 constexpr __non_propagating_cache&
1493 operator=(const __non_propagating_cache& __other) noexcept
1494 {
1495 if (std::__addressof(__other) != this)
1496 this->_M_reset();
1497 return *this;
1498 }
1499
1500 constexpr __non_propagating_cache&
1501 operator=(__non_propagating_cache&& __other) noexcept
1502 {
1503 this->_M_reset();
1504 __other._M_reset();
1505 return *this;
1506 }
1507
1508 constexpr __non_propagating_cache&
1509 operator=(_Tp __val)
1510 {
1511 this->_M_reset();
1512 this->_M_payload._M_construct(std::move(__val));
1513 return *this;
1514 }
1515
1516 constexpr explicit
1517 operator bool() const noexcept
1518 { return this->_M_is_engaged(); }
1519
1520 constexpr _Tp&
1521 operator*() noexcept
1522 { return this->_M_get(); }
1523
1524 constexpr const _Tp&
1525 operator*() const noexcept
1526 { return this->_M_get(); }
1527
1528 template<typename _Iter>
1529 constexpr _Tp&
1530 _M_emplace_deref(const _Iter& __i)
1531 {
1532 this->_M_reset();
1533 auto __f = [] (auto& __x) { return *__x; };
1534 this->_M_payload._M_apply(_Optional_func{__f}, __i);
1535 return this->_M_get();
1536 }
1537 };
1538
1539 template<range _Range>
1540 struct _CachedPosition
1541 {
1542 constexpr bool
1543 _M_has_value() const
1544 { return false; }
1545
1546 constexpr iterator_t<_Range>
1547 _M_get(const _Range&) const
1548 {
1549 __glibcxx_assert(false);
1550 __builtin_unreachable();
1551 }
1552
1553 constexpr void
1554 _M_set(const _Range&, const iterator_t<_Range>&) const
1555 { }
1556 };
1557
1558 template<forward_range _Range>
1559 struct _CachedPosition<_Range>
1560 : protected __non_propagating_cache<iterator_t<_Range>>
1561 {
1562 constexpr bool
1563 _M_has_value() const
1564 { return this->_M_is_engaged(); }
1565
1566 constexpr iterator_t<_Range>
1567 _M_get(const _Range&) const
1568 {
1569 __glibcxx_assert(_M_has_value());
1570 return **this;
1571 }
1572
1573 constexpr void
1574 _M_set(const _Range&, const iterator_t<_Range>& __it)
1575 {
1576 __glibcxx_assert(!_M_has_value());
1577 std::construct_at(std::__addressof(this->_M_payload._M_payload),
1578 in_place, __it);
1579 this->_M_payload._M_engaged = true;
1580 }
1581 };
1582
1583 template<random_access_range _Range>
1584 requires (sizeof(range_difference_t<_Range>)
1585 <= sizeof(iterator_t<_Range>))
1586 struct _CachedPosition<_Range>
1587 {
1588 private:
1589 range_difference_t<_Range> _M_offset = -1;
1590
1591 public:
1592 _CachedPosition() = default;
1593
1594 constexpr
1595 _CachedPosition(const _CachedPosition&) = default;
1596
1597 constexpr
1598 _CachedPosition(_CachedPosition&& __other) noexcept
1599 { *this = std::move(__other); }
1600
1601 constexpr _CachedPosition&
1602 operator=(const _CachedPosition&) = default;
1603
1604 constexpr _CachedPosition&
1605 operator=(_CachedPosition&& __other) noexcept
1606 {
1607 // Propagate the cached offset, but invalidate the source.
1608 _M_offset = __other._M_offset;
1609 __other._M_offset = -1;
1610 return *this;
1611 }
1612
1613 constexpr bool
1614 _M_has_value() const
1615 { return _M_offset >= 0; }
1616
1617 constexpr iterator_t<_Range>
1618 _M_get(_Range& __r) const
1619 {
1620 __glibcxx_assert(_M_has_value());
1621 return ranges::begin(__r) + _M_offset;
1622 }
1623
1624 constexpr void
1625 _M_set(_Range& __r, const iterator_t<_Range>& __it)
1626 {
1627 __glibcxx_assert(!_M_has_value());
1628 _M_offset = __it - ranges::begin(__r);
1629 }
1630 };
1631 } // namespace __detail
1632
1633 namespace __detail
1634 {
1635 template<typename _Base>
1636 struct __filter_view_iter_cat
1637 { };
1638
1639 template<forward_range _Base>
1640 struct __filter_view_iter_cat<_Base>
1641 {
1642 private:
1643 static auto
1644 _S_iter_cat()
1645 {
1646 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
1647 if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
1648 return bidirectional_iterator_tag{};
1649 else if constexpr (derived_from<_Cat, forward_iterator_tag>)
1650 return forward_iterator_tag{};
1651 else
1652 return _Cat{};
1653 }
1654 public:
1655 using iterator_category = decltype(_S_iter_cat());
1656 };
1657 } // namespace __detail
1658
1659 template<input_range _Vp,
1660 indirect_unary_predicate<iterator_t<_Vp>> _Pred>
1661 requires view<_Vp> && is_object_v<_Pred>
1662 class filter_view : public view_interface<filter_view<_Vp, _Pred>>
1663 {
1664 private:
1665 struct _Sentinel;
1666
1667 struct _Iterator : __detail::__filter_view_iter_cat<_Vp>
1668 {
1669 private:
1670 static constexpr auto
1671 _S_iter_concept()
1672 {
1673 if constexpr (bidirectional_range<_Vp>)
1674 return bidirectional_iterator_tag{};
1675 else if constexpr (forward_range<_Vp>)
1676 return forward_iterator_tag{};
1677 else
1678 return input_iterator_tag{};
1679 }
1680
1681 friend filter_view;
1682
1683 using _Vp_iter = iterator_t<_Vp>;
1684
1685 _Vp_iter _M_current = _Vp_iter();
1686 filter_view* _M_parent = nullptr;
1687
1688 public:
1689 using iterator_concept = decltype(_S_iter_concept());
1690 // iterator_category defined in __filter_view_iter_cat
1691 using value_type = range_value_t<_Vp>;
1692 using difference_type = range_difference_t<_Vp>;
1693
1694 _Iterator() requires default_initializable<_Vp_iter> = default;
1695
1696 constexpr
1697 _Iterator(filter_view* __parent, _Vp_iter __current)
1698 : _M_current(std::move(__current)),
1699 _M_parent(__parent)
1700 { }
1701
1702 constexpr const _Vp_iter&
1703 base() const & noexcept
1704 { return _M_current; }
1705
1706 constexpr _Vp_iter
1707 base() &&
1708 { return std::move(_M_current); }
1709
1710 constexpr range_reference_t<_Vp>
1711 operator*() const
1712 { return *_M_current; }
1713
1714 constexpr _Vp_iter
1715 operator->() const
1716 requires __detail::__has_arrow<_Vp_iter>
1717 && copyable<_Vp_iter>
1718 { return _M_current; }
1719
1720 constexpr _Iterator&
1721 operator++()
1722 {
1723 _M_current = ranges::find_if(std::move(++_M_current),
1724 ranges::end(_M_parent->_M_base),
1725 std::ref(*_M_parent->_M_pred));
1726 return *this;
1727 }
1728
1729 constexpr void
1730 operator++(int)
1731 { ++*this; }
1732
1733 constexpr _Iterator
1734 operator++(int) requires forward_range<_Vp>
1735 {
1736 auto __tmp = *this;
1737 ++*this;
1738 return __tmp;
1739 }
1740
1741 constexpr _Iterator&
1742 operator--() requires bidirectional_range<_Vp>
1743 {
1744 do
1745 --_M_current;
1746 while (!std::__invoke(*_M_parent->_M_pred, *_M_current));
1747 return *this;
1748 }
1749
1750 constexpr _Iterator
1751 operator--(int) requires bidirectional_range<_Vp>
1752 {
1753 auto __tmp = *this;
1754 --*this;
1755 return __tmp;
1756 }
1757
1758 friend constexpr bool
1759 operator==(const _Iterator& __x, const _Iterator& __y)
1760 requires equality_comparable<_Vp_iter>
1761 { return __x._M_current == __y._M_current; }
1762
1763 friend constexpr range_rvalue_reference_t<_Vp>
1764 iter_move(const _Iterator& __i)
1765 noexcept(noexcept(ranges::iter_move(__i._M_current)))
1766 { return ranges::iter_move(__i._M_current); }
1767
1768 friend constexpr void
1769 iter_swap(const _Iterator& __x, const _Iterator& __y)
1770 noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
1771 requires indirectly_swappable<_Vp_iter>
1772 { ranges::iter_swap(__x._M_current, __y._M_current); }
1773 };
1774
1775 struct _Sentinel
1776 {
1777 private:
1778 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
1779
1780 constexpr bool
1781 __equal(const _Iterator& __i) const
1782 { return __i._M_current == _M_end; }
1783
1784 public:
1785 _Sentinel() = default;
1786
1787 constexpr explicit
1788 _Sentinel(filter_view* __parent)
1789 : _M_end(ranges::end(__parent->_M_base))
1790 { }
1791
1792 constexpr sentinel_t<_Vp>
1793 base() const
1794 { return _M_end; }
1795
1796 friend constexpr bool
1797 operator==(const _Iterator& __x, const _Sentinel& __y)
1798 { return __y.__equal(__x); }
1799 };
1800
1801 _Vp _M_base = _Vp();
1802 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
1803 [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;
1804
1805 public:
1806 filter_view() requires (default_initializable<_Vp>
1807 && default_initializable<_Pred>)
1808 = default;
1809
1810 constexpr
1811 filter_view(_Vp __base, _Pred __pred)
1812 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
1813 { }
1814
1815 constexpr _Vp
1816 base() const& requires copy_constructible<_Vp>
1817 { return _M_base; }
1818
1819 constexpr _Vp
1820 base() &&
1821 { return std::move(_M_base); }
1822
1823 constexpr const _Pred&
1824 pred() const
1825 { return *_M_pred; }
1826
1827 constexpr _Iterator
1828 begin()
1829 {
1830 if (_M_cached_begin._M_has_value())
1831 return {this, _M_cached_begin._M_get(_M_base)};
1832
1833 __glibcxx_assert(_M_pred.has_value());
1834 auto __it = ranges::find_if(ranges::begin(_M_base),
1835 ranges::end(_M_base),
1836 std::ref(*_M_pred));
1837 _M_cached_begin._M_set(_M_base, __it);
1838 return {this, std::move(__it)};
1839 }
1840
1841 constexpr auto
1842 end()
1843 {
1844 if constexpr (common_range<_Vp>)
1845 return _Iterator{this, ranges::end(_M_base)};
1846 else
1847 return _Sentinel{this};
1848 }
1849 };
1850
1851 template<typename _Range, typename _Pred>
1852 filter_view(_Range&&, _Pred) -> filter_view<views::all_t<_Range>, _Pred>;
1853
1854 namespace views
1855 {
1856 namespace __detail
1857 {
1858 template<typename _Range, typename _Pred>
1859 concept __can_filter_view
1860 = requires { filter_view(std::declval<_Range>(), std::declval<_Pred>()); };
1861 } // namespace __detail
1862
1863 struct _Filter : __adaptor::_RangeAdaptor<_Filter>
1864 {
1865 template<viewable_range _Range, typename _Pred>
1866 requires __detail::__can_filter_view<_Range, _Pred>
1867 constexpr auto
1868 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p) const
1869 {
1870 return filter_view(std::forward<_Range>(__r), std::forward<_Pred>(__p));
1871 }
1872
1873 using _RangeAdaptor<_Filter>::operator();
1874 static constexpr int _S_arity = 2;
1875 static constexpr bool _S_has_simple_extra_args = true;
1876 };
1877
1878 inline constexpr _Filter filter;
1879 } // namespace views
1880
1881#if __cpp_lib_ranges >= 202207L // C++ >= 23
1882 template<input_range _Vp, move_constructible _Fp>
1883#else
1884 template<input_range _Vp, copy_constructible _Fp>
1885#endif
1886 requires view<_Vp> && is_object_v<_Fp>
1887 && regular_invocable<_Fp&, range_reference_t<_Vp>>
1888 && std::__detail::__can_reference<invoke_result_t<_Fp&,
1889 range_reference_t<_Vp>>>
1890 class transform_view : public view_interface<transform_view<_Vp, _Fp>>
1891 {
1892 private:
1893 template<bool _Const>
1894 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
1895
1896 template<bool _Const>
1897 struct __iter_cat
1898 { };
1899
1900 template<bool _Const>
1901 requires forward_range<_Base<_Const>>
1902 struct __iter_cat<_Const>
1903 {
1904 private:
1905 static auto
1906 _S_iter_cat()
1907 {
1908 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1909 // 3564. transform_view::iterator<true>::value_type and
1910 // iterator_category should use const F&
1911 using _Base = transform_view::_Base<_Const>;
1912 using _Res = invoke_result_t<__maybe_const_t<_Const, _Fp>&,
1913 range_reference_t<_Base>>;
1914 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1915 // 3798. Rvalue reference and iterator_category
1916 if constexpr (is_reference_v<_Res>)
1917 {
1918 using _Cat
1919 = typename iterator_traits<iterator_t<_Base>>::iterator_category;
1920 if constexpr (derived_from<_Cat, contiguous_iterator_tag>)
1921 return random_access_iterator_tag{};
1922 else
1923 return _Cat{};
1924 }
1925 else
1926 return input_iterator_tag{};
1927 }
1928 public:
1929 using iterator_category = decltype(_S_iter_cat());
1930 };
1931
1932 template<bool _Const>
1933 struct _Sentinel;
1934
1935 template<bool _Const>
1936 struct _Iterator : __iter_cat<_Const>
1937 {
1938 private:
1939 using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
1940 using _Base = transform_view::_Base<_Const>;
1941
1942 static auto
1943 _S_iter_concept()
1944 {
1945 if constexpr (random_access_range<_Base>)
1946 return random_access_iterator_tag{};
1947 else if constexpr (bidirectional_range<_Base>)
1948 return bidirectional_iterator_tag{};
1949 else if constexpr (forward_range<_Base>)
1950 return forward_iterator_tag{};
1951 else
1952 return input_iterator_tag{};
1953 }
1954
1955 using _Base_iter = iterator_t<_Base>;
1956
1957 _Base_iter _M_current = _Base_iter();
1958 _Parent* _M_parent = nullptr;
1959
1960 public:
1961 using iterator_concept = decltype(_S_iter_concept());
1962 // iterator_category defined in __transform_view_iter_cat
1963 using value_type
1964 = remove_cvref_t<invoke_result_t<__maybe_const_t<_Const, _Fp>&,
1965 range_reference_t<_Base>>>;
1966 using difference_type = range_difference_t<_Base>;
1967
1968 _Iterator() requires default_initializable<_Base_iter> = default;
1969
1970 constexpr
1971 _Iterator(_Parent* __parent, _Base_iter __current)
1972 : _M_current(std::move(__current)),
1973 _M_parent(__parent)
1974 { }
1975
1976 constexpr
1977 _Iterator(_Iterator<!_Const> __i)
1978 requires _Const
1979 && convertible_to<iterator_t<_Vp>, _Base_iter>
1980 : _M_current(std::move(__i._M_current)), _M_parent(__i._M_parent)
1981 { }
1982
1983 constexpr const _Base_iter&
1984 base() const & noexcept
1985 { return _M_current; }
1986
1987 constexpr _Base_iter
1988 base() &&
1989 { return std::move(_M_current); }
1990
1991 constexpr decltype(auto)
1992 operator*() const
1993 noexcept(noexcept(std::__invoke(*_M_parent->_M_fun, *_M_current)))
1994 { return std::__invoke(*_M_parent->_M_fun, *_M_current); }
1995
1996 constexpr _Iterator&
1997 operator++()
1998 {
1999 ++_M_current;
2000 return *this;
2001 }
2002
2003 constexpr void
2004 operator++(int)
2005 { ++_M_current; }
2006
2007 constexpr _Iterator
2008 operator++(int) requires forward_range<_Base>
2009 {
2010 auto __tmp = *this;
2011 ++*this;
2012 return __tmp;
2013 }
2014
2015 constexpr _Iterator&
2016 operator--() requires bidirectional_range<_Base>
2017 {
2018 --_M_current;
2019 return *this;
2020 }
2021
2022 constexpr _Iterator
2023 operator--(int) requires bidirectional_range<_Base>
2024 {
2025 auto __tmp = *this;
2026 --*this;
2027 return __tmp;
2028 }
2029
2030 constexpr _Iterator&
2031 operator+=(difference_type __n) requires random_access_range<_Base>
2032 {
2033 _M_current += __n;
2034 return *this;
2035 }
2036
2037 constexpr _Iterator&
2038 operator-=(difference_type __n) requires random_access_range<_Base>
2039 {
2040 _M_current -= __n;
2041 return *this;
2042 }
2043
2044 constexpr decltype(auto)
2045 operator[](difference_type __n) const
2046 requires random_access_range<_Base>
2047 { return std::__invoke(*_M_parent->_M_fun, _M_current[__n]); }
2048
2049 friend constexpr bool
2050 operator==(const _Iterator& __x, const _Iterator& __y)
2051 requires equality_comparable<_Base_iter>
2052 { return __x._M_current == __y._M_current; }
2053
2054 friend constexpr bool
2055 operator<(const _Iterator& __x, const _Iterator& __y)
2056 requires random_access_range<_Base>
2057 { return __x._M_current < __y._M_current; }
2058
2059 friend constexpr bool
2060 operator>(const _Iterator& __x, const _Iterator& __y)
2061 requires random_access_range<_Base>
2062 { return __y < __x; }
2063
2064 friend constexpr bool
2065 operator<=(const _Iterator& __x, const _Iterator& __y)
2066 requires random_access_range<_Base>
2067 { return !(__y < __x); }
2068
2069 friend constexpr bool
2070 operator>=(const _Iterator& __x, const _Iterator& __y)
2071 requires random_access_range<_Base>
2072 { return !(__x < __y); }
2073
2074#ifdef __cpp_lib_three_way_comparison
2075 friend constexpr auto
2076 operator<=>(const _Iterator& __x, const _Iterator& __y)
2077 requires random_access_range<_Base>
2078 && three_way_comparable<_Base_iter>
2079 { return __x._M_current <=> __y._M_current; }
2080#endif
2081
2082 friend constexpr _Iterator
2083 operator+(_Iterator __i, difference_type __n)
2084 requires random_access_range<_Base>
2085 { return {__i._M_parent, __i._M_current + __n}; }
2086
2087 friend constexpr _Iterator
2088 operator+(difference_type __n, _Iterator __i)
2089 requires random_access_range<_Base>
2090 { return {__i._M_parent, __i._M_current + __n}; }
2091
2092 friend constexpr _Iterator
2093 operator-(_Iterator __i, difference_type __n)
2094 requires random_access_range<_Base>
2095 { return {__i._M_parent, __i._M_current - __n}; }
2096
2097 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2098 // 3483. transform_view::iterator's difference is overconstrained
2099 friend constexpr difference_type
2100 operator-(const _Iterator& __x, const _Iterator& __y)
2101 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
2102 { return __x._M_current - __y._M_current; }
2103
2104 friend constexpr decltype(auto)
2105 iter_move(const _Iterator& __i) noexcept(noexcept(*__i))
2106 {
2107 if constexpr (is_lvalue_reference_v<decltype(*__i)>)
2108 return std::move(*__i);
2109 else
2110 return *__i;
2111 }
2112
2113 friend _Iterator<!_Const>;
2114 template<bool> friend struct _Sentinel;
2115 };
2116
2117 template<bool _Const>
2118 struct _Sentinel
2119 {
2120 private:
2121 using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
2122 using _Base = transform_view::_Base<_Const>;
2123
2124 template<bool _Const2>
2125 constexpr auto
2126 __distance_from(const _Iterator<_Const2>& __i) const
2127 { return _M_end - __i._M_current; }
2128
2129 template<bool _Const2>
2130 constexpr bool
2131 __equal(const _Iterator<_Const2>& __i) const
2132 { return __i._M_current == _M_end; }
2133
2134 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2135
2136 public:
2137 _Sentinel() = default;
2138
2139 constexpr explicit
2140 _Sentinel(sentinel_t<_Base> __end)
2141 : _M_end(__end)
2142 { }
2143
2144 constexpr
2145 _Sentinel(_Sentinel<!_Const> __i)
2146 requires _Const
2147 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2148 : _M_end(std::move(__i._M_end))
2149 { }
2150
2151 constexpr sentinel_t<_Base>
2152 base() const
2153 { return _M_end; }
2154
2155 template<bool _Const2>
2156 requires sentinel_for<sentinel_t<_Base>,
2157 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
2158 friend constexpr bool
2159 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
2160 { return __y.__equal(__x); }
2161
2162 template<bool _Const2,
2163 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
2164 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2165 friend constexpr range_difference_t<_Base2>
2166 operator-(const _Iterator<_Const2>& __x, const _Sentinel& __y)
2167 { return -__y.__distance_from(__x); }
2168
2169 template<bool _Const2,
2170 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
2171 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2172 friend constexpr range_difference_t<_Base2>
2173 operator-(const _Sentinel& __y, const _Iterator<_Const2>& __x)
2174 { return __y.__distance_from(__x); }
2175
2176 friend _Sentinel<!_Const>;
2177 };
2178
2179 _Vp _M_base = _Vp();
2180 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
2181
2182 public:
2183 transform_view() requires (default_initializable<_Vp>
2184 && default_initializable<_Fp>)
2185 = default;
2186
2187 constexpr
2188 transform_view(_Vp __base, _Fp __fun)
2189 : _M_base(std::move(__base)), _M_fun(std::move(__fun))
2190 { }
2191
2192 constexpr _Vp
2193 base() const& requires copy_constructible<_Vp>
2194 { return _M_base ; }
2195
2196 constexpr _Vp
2197 base() &&
2198 { return std::move(_M_base); }
2199
2200 constexpr _Iterator<false>
2201 begin()
2202 { return _Iterator<false>{this, ranges::begin(_M_base)}; }
2203
2204 constexpr _Iterator<true>
2205 begin() const
2206 requires range<const _Vp>
2207 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2208 { return _Iterator<true>{this, ranges::begin(_M_base)}; }
2209
2210 constexpr _Sentinel<false>
2211 end()
2212 { return _Sentinel<false>{ranges::end(_M_base)}; }
2213
2214 constexpr _Iterator<false>
2215 end() requires common_range<_Vp>
2216 { return _Iterator<false>{this, ranges::end(_M_base)}; }
2217
2218 constexpr _Sentinel<true>
2219 end() const
2220 requires range<const _Vp>
2221 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2222 { return _Sentinel<true>{ranges::end(_M_base)}; }
2223
2224 constexpr _Iterator<true>
2225 end() const
2226 requires common_range<const _Vp>
2227 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2228 { return _Iterator<true>{this, ranges::end(_M_base)}; }
2229
2230 constexpr auto
2231 size() requires sized_range<_Vp>
2232 { return ranges::size(_M_base); }
2233
2234 constexpr auto
2235 size() const requires sized_range<const _Vp>
2236 { return ranges::size(_M_base); }
2237 };
2238
2239 template<typename _Range, typename _Fp>
2240 transform_view(_Range&&, _Fp) -> transform_view<views::all_t<_Range>, _Fp>;
2241
2242 namespace views
2243 {
2244 namespace __detail
2245 {
2246 template<typename _Range, typename _Fp>
2247 concept __can_transform_view
2248 = requires { transform_view(std::declval<_Range>(), std::declval<_Fp>()); };
2249 } // namespace __detail
2250
2251 struct _Transform : __adaptor::_RangeAdaptor<_Transform>
2252 {
2253 template<viewable_range _Range, typename _Fp>
2254 requires __detail::__can_transform_view<_Range, _Fp>
2255 constexpr auto
2256 operator() [[nodiscard]] (_Range&& __r, _Fp&& __f) const
2257 {
2258 return transform_view(std::forward<_Range>(__r), std::forward<_Fp>(__f));
2259 }
2260
2261 using _RangeAdaptor<_Transform>::operator();
2262 static constexpr int _S_arity = 2;
2263 static constexpr bool _S_has_simple_extra_args = true;
2264 };
2265
2266 inline constexpr _Transform transform;
2267 } // namespace views
2268
2269 template<view _Vp>
2270 class take_view : public view_interface<take_view<_Vp>>
2271 {
2272 private:
2273 template<bool _Const>
2274 using _CI = counted_iterator<
2275 iterator_t<__detail::__maybe_const_t<_Const, _Vp>>>;
2276
2277 template<bool _Const>
2278 struct _Sentinel
2279 {
2280 private:
2281 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2282 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2283
2284 public:
2285 _Sentinel() = default;
2286
2287 constexpr explicit
2288 _Sentinel(sentinel_t<_Base> __end)
2289 : _M_end(__end)
2290 { }
2291
2292 constexpr
2293 _Sentinel(_Sentinel<!_Const> __s)
2294 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2295 : _M_end(std::move(__s._M_end))
2296 { }
2297
2298 constexpr sentinel_t<_Base>
2299 base() const
2300 { return _M_end; }
2301
2302 friend constexpr bool
2303 operator==(const _CI<_Const>& __y, const _Sentinel& __x)
2304 { return __y.count() == 0 || __y.base() == __x._M_end; }
2305
2306 template<bool _OtherConst = !_Const,
2307 typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
2308 requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2309 friend constexpr bool
2310 operator==(const _CI<_OtherConst>& __y, const _Sentinel& __x)
2311 { return __y.count() == 0 || __y.base() == __x._M_end; }
2312
2313 friend _Sentinel<!_Const>;
2314 };
2315
2316 _Vp _M_base = _Vp();
2317 range_difference_t<_Vp> _M_count = 0;
2318
2319 public:
2320 take_view() requires default_initializable<_Vp> = default;
2321
2322 constexpr
2323 take_view(_Vp __base, range_difference_t<_Vp> __count)
2324 : _M_base(std::move(__base)), _M_count(std::move(__count))
2325 { }
2326
2327 constexpr _Vp
2328 base() const& requires copy_constructible<_Vp>
2329 { return _M_base; }
2330
2331 constexpr _Vp
2332 base() &&
2333 { return std::move(_M_base); }
2334
2335 constexpr auto
2336 begin() requires (!__detail::__simple_view<_Vp>)
2337 {
2338 if constexpr (sized_range<_Vp>)
2339 {
2340 if constexpr (random_access_range<_Vp>)
2341 return ranges::begin(_M_base);
2342 else
2343 {
2344 auto __sz = size();
2345 return counted_iterator(ranges::begin(_M_base), __sz);
2346 }
2347 }
2348 else
2349 return counted_iterator(ranges::begin(_M_base), _M_count);
2350 }
2351
2352 constexpr auto
2353 begin() const requires range<const _Vp>
2354 {
2355 if constexpr (sized_range<const _Vp>)
2356 {
2357 if constexpr (random_access_range<const _Vp>)
2358 return ranges::begin(_M_base);
2359 else
2360 {
2361 auto __sz = size();
2362 return counted_iterator(ranges::begin(_M_base), __sz);
2363 }
2364 }
2365 else
2366 return counted_iterator(ranges::begin(_M_base), _M_count);
2367 }
2368
2369 constexpr auto
2370 end() requires (!__detail::__simple_view<_Vp>)
2371 {
2372 if constexpr (sized_range<_Vp>)
2373 {
2374 if constexpr (random_access_range<_Vp>)
2375 return ranges::begin(_M_base) + size();
2376 else
2377 return default_sentinel;
2378 }
2379 else
2380 return _Sentinel<false>{ranges::end(_M_base)};
2381 }
2382
2383 constexpr auto
2384 end() const requires range<const _Vp>
2385 {
2386 if constexpr (sized_range<const _Vp>)
2387 {
2388 if constexpr (random_access_range<const _Vp>)
2389 return ranges::begin(_M_base) + size();
2390 else
2391 return default_sentinel;
2392 }
2393 else
2394 return _Sentinel<true>{ranges::end(_M_base)};
2395 }
2396
2397 constexpr auto
2398 size() requires sized_range<_Vp>
2399 {
2400 auto __n = ranges::size(_M_base);
2401 return std::min(__n, static_cast<decltype(__n)>(_M_count));
2402 }
2403
2404 constexpr auto
2405 size() const requires sized_range<const _Vp>
2406 {
2407 auto __n = ranges::size(_M_base);
2408 return std::min(__n, static_cast<decltype(__n)>(_M_count));
2409 }
2410 };
2411
2412 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2413 // 3447. Deduction guides for take_view and drop_view have different
2414 // constraints
2415 template<typename _Range>
2416 take_view(_Range&&, range_difference_t<_Range>)
2417 -> take_view<views::all_t<_Range>>;
2418
2419 template<typename _Tp>
2420 inline constexpr bool enable_borrowed_range<take_view<_Tp>>
2421 = enable_borrowed_range<_Tp>;
2422
2423 namespace views
2424 {
2425 namespace __detail
2426 {
2427 template<typename _Range>
2428 inline constexpr bool __is_empty_view = false;
2429
2430 template<typename _Tp>
2431 inline constexpr bool __is_empty_view<empty_view<_Tp>> = true;
2432
2433 template<typename _Range>
2434 inline constexpr bool __is_basic_string_view = false;
2435
2436 template<typename _CharT, typename _Traits>
2437 inline constexpr bool __is_basic_string_view<basic_string_view<_CharT, _Traits>>
2438 = true;
2439
2440 using ranges::__detail::__is_subrange;
2441
2442 template<typename _Range>
2443 inline constexpr bool __is_iota_view = false;
2444
2445 template<typename _Winc, typename _Bound>
2446 inline constexpr bool __is_iota_view<iota_view<_Winc, _Bound>> = true;
2447
2448 template<typename _Range>
2449 inline constexpr bool __is_repeat_view = false;
2450
2451 template<typename _Range>
2452 constexpr auto
2453 __take_of_repeat_view(_Range&&, range_difference_t<_Range>); // defined later
2454
2455 template<typename _Range, typename _Dp>
2456 concept __can_take_view
2457 = requires { take_view(std::declval<_Range>(), std::declval<_Dp>()); };
2458 } // namespace __detail
2459
2460 struct _Take : __adaptor::_RangeAdaptor<_Take>
2461 {
2462 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
2463 requires __detail::__can_take_view<_Range, _Dp>
2464 constexpr auto
2465 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
2466 {
2467 using _Tp = remove_cvref_t<_Range>;
2468 if constexpr (__detail::__is_empty_view<_Tp>)
2469 return _Tp();
2470 else if constexpr (random_access_range<_Tp>
2471 && sized_range<_Tp>
2472 && (std::__detail::__is_span<_Tp>
2473 || __detail::__is_basic_string_view<_Tp>
2474 || __detail::__is_subrange<_Tp>
2475 || __detail::__is_iota_view<_Tp>))
2476 {
2477 __n = std::min<_Dp>(ranges::distance(__r), __n);
2478 auto __begin = ranges::begin(__r);
2479 auto __end = __begin + __n;
2480 if constexpr (std::__detail::__is_span<_Tp>)
2481 return span<typename _Tp::element_type>(__begin, __end);
2482 else if constexpr (__detail::__is_basic_string_view<_Tp>)
2483 return _Tp(__begin, __end);
2484 else if constexpr (__detail::__is_subrange<_Tp>)
2485 return subrange<iterator_t<_Tp>>(__begin, __end);
2486 else
2487 return iota_view(*__begin, *__end);
2488 }
2489 else if constexpr (__detail::__is_repeat_view<_Tp>)
2490 return __detail::__take_of_repeat_view(std::forward<_Range>(__r), __n);
2491 else
2492 return take_view(std::forward<_Range>(__r), __n);
2493 }
2494
2495 using _RangeAdaptor<_Take>::operator();
2496 static constexpr int _S_arity = 2;
2497 // The count argument of views::take is not always simple -- it can be
2498 // e.g. a move-only class that's implicitly convertible to the difference
2499 // type. But an integer-like count argument is surely simple.
2500 template<typename _Tp>
2501 static constexpr bool _S_has_simple_extra_args
2502 = ranges::__detail::__is_integer_like<_Tp>;
2503 };
2504
2505 inline constexpr _Take take;
2506 } // namespace views
2507
2508 template<view _Vp, typename _Pred>
2509 requires input_range<_Vp> && is_object_v<_Pred>
2510 && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
2511 class take_while_view : public view_interface<take_while_view<_Vp, _Pred>>
2512 {
2513 template<bool _Const>
2514 struct _Sentinel
2515 {
2516 private:
2517 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2518
2519 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2520 const _Pred* _M_pred = nullptr;
2521
2522 public:
2523 _Sentinel() = default;
2524
2525 constexpr explicit
2526 _Sentinel(sentinel_t<_Base> __end, const _Pred* __pred)
2527 : _M_end(__end), _M_pred(__pred)
2528 { }
2529
2530 constexpr
2531 _Sentinel(_Sentinel<!_Const> __s)
2532 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2533 : _M_end(__s._M_end), _M_pred(__s._M_pred)
2534 { }
2535
2536 constexpr sentinel_t<_Base>
2537 base() const { return _M_end; }
2538
2539 friend constexpr bool
2540 operator==(const iterator_t<_Base>& __x, const _Sentinel& __y)
2541 { return __y._M_end == __x || !std::__invoke(*__y._M_pred, *__x); }
2542
2543 template<bool _OtherConst = !_Const,
2544 typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
2545 requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2546 friend constexpr bool
2547 operator==(const iterator_t<_Base2>& __x, const _Sentinel& __y)
2548 { return __y._M_end == __x || !std::__invoke(*__y._M_pred, *__x); }
2549
2550 friend _Sentinel<!_Const>;
2551 };
2552
2553 _Vp _M_base = _Vp();
2554 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
2555
2556 public:
2557 take_while_view() requires (default_initializable<_Vp>
2558 && default_initializable<_Pred>)
2559 = default;
2560
2561 constexpr
2562 take_while_view(_Vp __base, _Pred __pred)
2563 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
2564 { }
2565
2566 constexpr _Vp
2567 base() const& requires copy_constructible<_Vp>
2568 { return _M_base; }
2569
2570 constexpr _Vp
2571 base() &&
2572 { return std::move(_M_base); }
2573
2574 constexpr const _Pred&
2575 pred() const
2576 { return *_M_pred; }
2577
2578 constexpr auto
2579 begin() requires (!__detail::__simple_view<_Vp>)
2580 { return ranges::begin(_M_base); }
2581
2582 constexpr auto
2583 begin() const requires range<const _Vp>
2584 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
2585 { return ranges::begin(_M_base); }
2586
2587 constexpr auto
2588 end() requires (!__detail::__simple_view<_Vp>)
2589 { return _Sentinel<false>(ranges::end(_M_base),
2590 std::__addressof(*_M_pred)); }
2591
2592 constexpr auto
2593 end() const requires range<const _Vp>
2594 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
2595 { return _Sentinel<true>(ranges::end(_M_base),
2596 std::__addressof(*_M_pred)); }
2597 };
2598
2599 template<typename _Range, typename _Pred>
2600 take_while_view(_Range&&, _Pred)
2601 -> take_while_view<views::all_t<_Range>, _Pred>;
2602
2603 namespace views
2604 {
2605 namespace __detail
2606 {
2607 template<typename _Range, typename _Pred>
2608 concept __can_take_while_view
2609 = requires { take_while_view(std::declval<_Range>(), std::declval<_Pred>()); };
2610 } // namespace __detail
2611
2612 struct _TakeWhile : __adaptor::_RangeAdaptor<_TakeWhile>
2613 {
2614 template<viewable_range _Range, typename _Pred>
2615 requires __detail::__can_take_while_view<_Range, _Pred>
2616 constexpr auto
2617 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p) const
2618 {
2619 return take_while_view(std::forward<_Range>(__r), std::forward<_Pred>(__p));
2620 }
2621
2622 using _RangeAdaptor<_TakeWhile>::operator();
2623 static constexpr int _S_arity = 2;
2624 static constexpr bool _S_has_simple_extra_args = true;
2625 };
2626
2627 inline constexpr _TakeWhile take_while;
2628 } // namespace views
2629
2630 template<view _Vp>
2631 class drop_view : public view_interface<drop_view<_Vp>>
2632 {
2633 private:
2634 _Vp _M_base = _Vp();
2635 range_difference_t<_Vp> _M_count = 0;
2636
2637 // ranges::next(begin(base), count, end(base)) is O(1) if _Vp satisfies
2638 // both random_access_range and sized_range. Otherwise, cache its result.
2639 static constexpr bool _S_needs_cached_begin
2640 = !(random_access_range<const _Vp> && sized_range<const _Vp>);
2641 [[no_unique_address]]
2642 __detail::__maybe_present_t<_S_needs_cached_begin,
2643 __detail::_CachedPosition<_Vp>>
2644 _M_cached_begin;
2645
2646 public:
2647 drop_view() requires default_initializable<_Vp> = default;
2648
2649 constexpr
2650 drop_view(_Vp __base, range_difference_t<_Vp> __count)
2651 : _M_base(std::move(__base)), _M_count(__count)
2652 { __glibcxx_assert(__count >= 0); }
2653
2654 constexpr _Vp
2655 base() const& requires copy_constructible<_Vp>
2656 { return _M_base; }
2657
2658 constexpr _Vp
2659 base() &&
2660 { return std::move(_M_base); }
2661
2662 // This overload is disabled for simple views with constant-time begin().
2663 constexpr auto
2664 begin()
2665 requires (!(__detail::__simple_view<_Vp>
2666 && random_access_range<const _Vp>
2667 && sized_range<const _Vp>))
2668 {
2669 if constexpr (_S_needs_cached_begin)
2670 if (_M_cached_begin._M_has_value())
2671 return _M_cached_begin._M_get(_M_base);
2672
2673 auto __it = ranges::next(ranges::begin(_M_base),
2674 _M_count, ranges::end(_M_base));
2675 if constexpr (_S_needs_cached_begin)
2676 _M_cached_begin._M_set(_M_base, __it);
2677 return __it;
2678 }
2679
2680 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2681 // 3482. drop_view's const begin should additionally require sized_range
2682 constexpr auto
2683 begin() const
2684 requires random_access_range<const _Vp> && sized_range<const _Vp>
2685 {
2686 return ranges::begin(_M_base) + ranges::min(ranges::distance(_M_base),
2687 _M_count);
2688 }
2689
2690 constexpr auto
2691 end() requires (!__detail::__simple_view<_Vp>)
2692 { return ranges::end(_M_base); }
2693
2694 constexpr auto
2695 end() const requires range<const _Vp>
2696 { return ranges::end(_M_base); }
2697
2698 constexpr auto
2699 size() requires sized_range<_Vp>
2700 {
2701 const auto __s = ranges::size(_M_base);
2702 const auto __c = static_cast<decltype(__s)>(_M_count);
2703 return __s < __c ? 0 : __s - __c;
2704 }
2705
2706 constexpr auto
2707 size() const requires sized_range<const _Vp>
2708 {
2709 const auto __s = ranges::size(_M_base);
2710 const auto __c = static_cast<decltype(__s)>(_M_count);
2711 return __s < __c ? 0 : __s - __c;
2712 }
2713 };
2714
2715 template<typename _Range>
2716 drop_view(_Range&&, range_difference_t<_Range>)
2717 -> drop_view<views::all_t<_Range>>;
2718
2719 template<typename _Tp>
2720 inline constexpr bool enable_borrowed_range<drop_view<_Tp>>
2721 = enable_borrowed_range<_Tp>;
2722
2723 namespace views
2724 {
2725 namespace __detail
2726 {
2727 template<typename _Range>
2728 constexpr auto
2729 __drop_of_repeat_view(_Range&&, range_difference_t<_Range>); // defined later
2730
2731 template<typename _Range, typename _Dp>
2732 concept __can_drop_view
2733 = requires { drop_view(std::declval<_Range>(), std::declval<_Dp>()); };
2734 } // namespace __detail
2735
2736 struct _Drop : __adaptor::_RangeAdaptor<_Drop>
2737 {
2738 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
2739 requires __detail::__can_drop_view<_Range, _Dp>
2740 constexpr auto
2741 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
2742 {
2743 using _Tp = remove_cvref_t<_Range>;
2744 if constexpr (__detail::__is_empty_view<_Tp>)
2745 return _Tp();
2746 else if constexpr (random_access_range<_Tp>
2747 && sized_range<_Tp>
2748 && (std::__detail::__is_span<_Tp>
2749 || __detail::__is_basic_string_view<_Tp>
2750 || __detail::__is_iota_view<_Tp>
2751 || __detail::__is_subrange<_Tp>))
2752 {
2753 __n = std::min<_Dp>(ranges::distance(__r), __n);
2754 auto __begin = ranges::begin(__r) + __n;
2755 auto __end = ranges::end(__r);
2756 if constexpr (std::__detail::__is_span<_Tp>)
2757 return span<typename _Tp::element_type>(__begin, __end);
2758 else if constexpr (__detail::__is_subrange<_Tp>)
2759 {
2760 if constexpr (_Tp::_S_store_size)
2761 {
2762 using ranges::__detail::__to_unsigned_like;
2763 auto __m = ranges::distance(__r) - __n;
2764 return _Tp(__begin, __end, __to_unsigned_like(__m));
2765 }
2766 else
2767 return _Tp(__begin, __end);
2768 }
2769 else
2770 return _Tp(__begin, __end);
2771 }
2772 else if constexpr (__detail::__is_repeat_view<_Tp>)
2773 return __detail::__drop_of_repeat_view(std::forward<_Range>(__r), __n);
2774 else
2775 return drop_view(std::forward<_Range>(__r), __n);
2776 }
2777
2778 using _RangeAdaptor<_Drop>::operator();
2779 static constexpr int _S_arity = 2;
2780 template<typename _Tp>
2781 static constexpr bool _S_has_simple_extra_args
2782 = _Take::_S_has_simple_extra_args<_Tp>;
2783 };
2784
2785 inline constexpr _Drop drop;
2786 } // namespace views
2787
2788 template<view _Vp, typename _Pred>
2789 requires input_range<_Vp> && is_object_v<_Pred>
2790 && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
2791 class drop_while_view : public view_interface<drop_while_view<_Vp, _Pred>>
2792 {
2793 private:
2794 _Vp _M_base = _Vp();
2795 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
2796 [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;
2797
2798 public:
2799 drop_while_view() requires (default_initializable<_Vp>
2800 && default_initializable<_Pred>)
2801 = default;
2802
2803 constexpr
2804 drop_while_view(_Vp __base, _Pred __pred)
2805 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
2806 { }
2807
2808 constexpr _Vp
2809 base() const& requires copy_constructible<_Vp>
2810 { return _M_base; }
2811
2812 constexpr _Vp
2813 base() &&
2814 { return std::move(_M_base); }
2815
2816 constexpr const _Pred&
2817 pred() const
2818 { return *_M_pred; }
2819
2820 constexpr auto
2821 begin()
2822 {
2823 if (_M_cached_begin._M_has_value())
2824 return _M_cached_begin._M_get(_M_base);
2825
2826 __glibcxx_assert(_M_pred.has_value());
2827 auto __it = ranges::find_if_not(ranges::begin(_M_base),
2828 ranges::end(_M_base),
2829 std::cref(*_M_pred));
2830 _M_cached_begin._M_set(_M_base, __it);
2831 return __it;
2832 }
2833
2834 constexpr auto
2835 end()
2836 { return ranges::end(_M_base); }
2837 };
2838
2839 template<typename _Range, typename _Pred>
2840 drop_while_view(_Range&&, _Pred)
2841 -> drop_while_view<views::all_t<_Range>, _Pred>;
2842
2843 template<typename _Tp, typename _Pred>
2844 inline constexpr bool enable_borrowed_range<drop_while_view<_Tp, _Pred>>
2845 = enable_borrowed_range<_Tp>;
2846
2847 namespace views
2848 {
2849 namespace __detail
2850 {
2851 template<typename _Range, typename _Pred>
2852 concept __can_drop_while_view
2853 = requires { drop_while_view(std::declval<_Range>(), std::declval<_Pred>()); };
2854 } // namespace __detail
2855
2856 struct _DropWhile : __adaptor::_RangeAdaptor<_DropWhile>
2857 {
2858 template<viewable_range _Range, typename _Pred>
2859 requires __detail::__can_drop_while_view<_Range, _Pred>
2860 constexpr auto
2861 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p) const
2862 {
2863 return drop_while_view(std::forward<_Range>(__r),
2864 std::forward<_Pred>(__p));
2865 }
2866
2867 using _RangeAdaptor<_DropWhile>::operator();
2868 static constexpr int _S_arity = 2;
2869 static constexpr bool _S_has_simple_extra_args = true;
2870 };
2871
2872 inline constexpr _DropWhile drop_while;
2873 } // namespace views
2874
2875 namespace __detail
2876 {
2877 template<typename _Tp>
2878 constexpr _Tp&
2879 __as_lvalue(_Tp&& __t)
2880 { return static_cast<_Tp&>(__t); }
2881 } // namespace __detail
2882
2883 template<input_range _Vp>
2884 requires view<_Vp> && input_range<range_reference_t<_Vp>>
2885 class join_view : public view_interface<join_view<_Vp>>
2886 {
2887 private:
2888 using _InnerRange = range_reference_t<_Vp>;
2889
2890 template<bool _Const>
2891 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2892
2893 template<bool _Const>
2894 using _Outer_iter = iterator_t<_Base<_Const>>;
2895
2896 template<bool _Const>
2897 using _Inner_iter = iterator_t<range_reference_t<_Base<_Const>>>;
2898
2899 template<bool _Const>
2900 static constexpr bool _S_ref_is_glvalue
2901 = is_reference_v<range_reference_t<_Base<_Const>>>;
2902
2903 template<bool _Const>
2904 struct __iter_cat
2905 { };
2906
2907 template<bool _Const>
2908 requires _S_ref_is_glvalue<_Const>
2909 && forward_range<_Base<_Const>>
2910 && forward_range<range_reference_t<_Base<_Const>>>
2911 struct __iter_cat<_Const>
2912 {
2913 private:
2914 static constexpr auto
2915 _S_iter_cat()
2916 {
2917 using _Outer_iter = join_view::_Outer_iter<_Const>;
2918 using _Inner_iter = join_view::_Inner_iter<_Const>;
2919 using _OuterCat = typename iterator_traits<_Outer_iter>::iterator_category;
2920 using _InnerCat = typename iterator_traits<_Inner_iter>::iterator_category;
2921 if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag>
2922 && derived_from<_InnerCat, bidirectional_iterator_tag>
2923 && common_range<range_reference_t<_Base<_Const>>>)
2924 return bidirectional_iterator_tag{};
2925 else if constexpr (derived_from<_OuterCat, forward_iterator_tag>
2926 && derived_from<_InnerCat, forward_iterator_tag>)
2927 return forward_iterator_tag{};
2928 else
2929 return input_iterator_tag{};
2930 }
2931 public:
2932 using iterator_category = decltype(_S_iter_cat());
2933 };
2934
2935 template<bool _Const>
2936 struct _Sentinel;
2937
2938 template<bool _Const>
2939 struct _Iterator : __iter_cat<_Const>
2940 {
2941 private:
2942 using _Parent = __detail::__maybe_const_t<_Const, join_view>;
2943 using _Base = join_view::_Base<_Const>;
2944
2945 friend join_view;
2946
2947 static constexpr bool _S_ref_is_glvalue
2948 = join_view::_S_ref_is_glvalue<_Const>;
2949
2950 constexpr void
2951 _M_satisfy()
2952 {
2953 auto __update_inner = [this] (const iterator_t<_Base>& __x) -> auto&& {
2954 if constexpr (_S_ref_is_glvalue)
2955 return *__x;
2956 else
2957 return _M_parent->_M_inner._M_emplace_deref(__x);
2958 };
2959
2960 _Outer_iter& __outer = _M_get_outer();
2961 for (; __outer != ranges::end(_M_parent->_M_base); ++__outer)
2962 {
2963 auto&& __inner = __update_inner(__outer);
2964 _M_inner = ranges::begin(__inner);
2965 if (_M_inner != ranges::end(__inner))
2966 return;
2967 }
2968
2969 if constexpr (_S_ref_is_glvalue)
2970 _M_inner.reset();
2971 }
2972
2973 static constexpr auto
2974 _S_iter_concept()
2975 {
2976 if constexpr (_S_ref_is_glvalue
2977 && bidirectional_range<_Base>
2978 && bidirectional_range<range_reference_t<_Base>>
2979 && common_range<range_reference_t<_Base>>)
2980 return bidirectional_iterator_tag{};
2981 else if constexpr (_S_ref_is_glvalue
2982 && forward_range<_Base>
2983 && forward_range<range_reference_t<_Base>>)
2984 return forward_iterator_tag{};
2985 else
2986 return input_iterator_tag{};
2987 }
2988
2989 using _Outer_iter = join_view::_Outer_iter<_Const>;
2990 using _Inner_iter = join_view::_Inner_iter<_Const>;
2991
2992 constexpr _Outer_iter&
2993 _M_get_outer()
2994 {
2995 if constexpr (forward_range<_Base>)
2996 return _M_outer;
2997 else
2998 return *_M_parent->_M_outer;
2999 }
3000
3001 constexpr const _Outer_iter&
3002 _M_get_outer() const
3003 {
3004 if constexpr (forward_range<_Base>)
3005 return _M_outer;
3006 else
3007 return *_M_parent->_M_outer;
3008 }
3009
3010 constexpr
3011 _Iterator(_Parent* __parent, _Outer_iter __outer) requires forward_range<_Base>
3012 : _M_outer(std::move(__outer)), _M_parent(__parent)
3013 { _M_satisfy(); }
3014
3015 constexpr explicit
3016 _Iterator(_Parent* __parent) requires (!forward_range<_Base>)
3017 : _M_parent(__parent)
3018 { _M_satisfy(); }
3019
3020 [[no_unique_address]]
3021 __detail::__maybe_present_t<forward_range<_Base>, _Outer_iter> _M_outer;
3022 optional<_Inner_iter> _M_inner;
3023 _Parent* _M_parent = nullptr;
3024
3025 public:
3026 using iterator_concept = decltype(_S_iter_concept());
3027 // iterator_category defined in __join_view_iter_cat
3028 using value_type = range_value_t<range_reference_t<_Base>>;
3029 using difference_type
3030 = common_type_t<range_difference_t<_Base>,
3031 range_difference_t<range_reference_t<_Base>>>;
3032
3033 _Iterator() = default;
3034
3035 constexpr
3036 _Iterator(_Iterator<!_Const> __i)
3037 requires _Const
3038 && convertible_to<iterator_t<_Vp>, _Outer_iter>
3039 && convertible_to<iterator_t<_InnerRange>, _Inner_iter>
3040 : _M_outer(std::move(__i._M_outer)), _M_inner(std::move(__i._M_inner)),
3041 _M_parent(__i._M_parent)
3042 { }
3043
3044 constexpr decltype(auto)
3045 operator*() const
3046 { return **_M_inner; }
3047
3048 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3049 // 3500. join_view::iterator::operator->() is bogus
3050 constexpr _Inner_iter
3051 operator->() const
3052 requires __detail::__has_arrow<_Inner_iter>
3053 && copyable<_Inner_iter>
3054 { return *_M_inner; }
3055
3056 constexpr _Iterator&
3057 operator++()
3058 {
3059 auto&& __inner_range = [this] () -> auto&& {
3060 if constexpr (_S_ref_is_glvalue)
3061 return *_M_get_outer();
3062 else
3063 return *_M_parent->_M_inner;
3064 }();
3065 if (++*_M_inner == ranges::end(__inner_range))
3066 {
3067 ++_M_get_outer();
3068 _M_satisfy();
3069 }
3070 return *this;
3071 }
3072
3073 constexpr void
3074 operator++(int)
3075 { ++*this; }
3076
3077 constexpr _Iterator
3078 operator++(int)
3079 requires _S_ref_is_glvalue && forward_range<_Base>
3080 && forward_range<range_reference_t<_Base>>
3081 {
3082 auto __tmp = *this;
3083 ++*this;
3084 return __tmp;
3085 }
3086
3087 constexpr _Iterator&
3088 operator--()
3089 requires _S_ref_is_glvalue && bidirectional_range<_Base>
3090 && bidirectional_range<range_reference_t<_Base>>
3091 && common_range<range_reference_t<_Base>>
3092 {
3093 if (_M_outer == ranges::end(_M_parent->_M_base))
3094 _M_inner = ranges::end(__detail::__as_lvalue(*--_M_outer));
3095 while (*_M_inner == ranges::begin(__detail::__as_lvalue(*_M_outer)))
3096 *_M_inner = ranges::end(__detail::__as_lvalue(*--_M_outer));
3097 --*_M_inner;
3098 return *this;
3099 }
3100
3101 constexpr _Iterator
3102 operator--(int)
3103 requires _S_ref_is_glvalue && bidirectional_range<_Base>
3104 && bidirectional_range<range_reference_t<_Base>>
3105 && common_range<range_reference_t<_Base>>
3106 {
3107 auto __tmp = *this;
3108 --*this;
3109 return __tmp;
3110 }
3111
3112 friend constexpr bool
3113 operator==(const _Iterator& __x, const _Iterator& __y)
3114 requires _S_ref_is_glvalue
3115 && forward_range<_Base>
3116 && equality_comparable<_Inner_iter>
3117 {
3118 return (__x._M_outer == __y._M_outer
3119 && __x._M_inner == __y._M_inner);
3120 }
3121
3122 friend constexpr decltype(auto)
3123 iter_move(const _Iterator& __i)
3124 noexcept(noexcept(ranges::iter_move(*__i._M_inner)))
3125 { return ranges::iter_move(*__i._M_inner); }
3126
3127 friend constexpr void
3128 iter_swap(const _Iterator& __x, const _Iterator& __y)
3129 noexcept(noexcept(ranges::iter_swap(*__x._M_inner, *__y._M_inner)))
3130 requires indirectly_swappable<_Inner_iter>
3131 { return ranges::iter_swap(*__x._M_inner, *__y._M_inner); }
3132
3133 friend _Iterator<!_Const>;
3134 template<bool> friend struct _Sentinel;
3135 };
3136
3137 template<bool _Const>
3138 struct _Sentinel
3139 {
3140 private:
3141 using _Parent = __detail::__maybe_const_t<_Const, join_view>;
3142 using _Base = join_view::_Base<_Const>;
3143
3144 template<bool _Const2>
3145 constexpr bool
3146 __equal(const _Iterator<_Const2>& __i) const
3147 { return __i._M_get_outer() == _M_end; }
3148
3149 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
3150
3151 public:
3152 _Sentinel() = default;
3153
3154 constexpr explicit
3155 _Sentinel(_Parent* __parent)
3156 : _M_end(ranges::end(__parent->_M_base))
3157 { }
3158
3159 constexpr
3160 _Sentinel(_Sentinel<!_Const> __s)
3161 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
3162 : _M_end(std::move(__s._M_end))
3163 { }
3164
3165 template<bool _Const2>
3166 requires sentinel_for<sentinel_t<_Base>,
3167 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
3168 friend constexpr bool
3169 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
3170 { return __y.__equal(__x); }
3171
3172 friend _Sentinel<!_Const>;
3173 };
3174
3175 _Vp _M_base = _Vp();
3176 [[no_unique_address]]
3177 __detail::__maybe_present_t<!forward_range<_Vp>,
3178 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_outer;
3179 [[no_unique_address]]
3180 __detail::__non_propagating_cache<remove_cv_t<_InnerRange>> _M_inner;
3181
3182 public:
3183 join_view() requires default_initializable<_Vp> = default;
3184
3185 constexpr explicit
3186 join_view(_Vp __base)
3187 : _M_base(std::move(__base))
3188 { }
3189
3190 constexpr _Vp
3191 base() const& requires copy_constructible<_Vp>
3192 { return _M_base; }
3193
3194 constexpr _Vp
3195 base() &&
3196 { return std::move(_M_base); }
3197
3198 constexpr auto
3199 begin()
3200 {
3201 if constexpr (forward_range<_Vp>)
3202 {
3203 constexpr bool __use_const
3204 = (__detail::__simple_view<_Vp>
3205 && is_reference_v<range_reference_t<_Vp>>);
3206 return _Iterator<__use_const>{this, ranges::begin(_M_base)};
3207 }
3208 else
3209 {
3210 _M_outer = ranges::begin(_M_base);
3211 return _Iterator<false>{this};
3212 }
3213 }
3214
3215 constexpr auto
3216 begin() const
3217 requires forward_range<const _Vp>
3218 && is_reference_v<range_reference_t<const _Vp>>
3219 && input_range<range_reference_t<const _Vp>>
3220 {
3221 return _Iterator<true>{this, ranges::begin(_M_base)};
3222 }
3223
3224 constexpr auto
3225 end()
3226 {
3227 if constexpr (forward_range<_Vp> && is_reference_v<_InnerRange>
3228 && forward_range<_InnerRange>
3229 && common_range<_Vp> && common_range<_InnerRange>)
3230 return _Iterator<__detail::__simple_view<_Vp>>{this,
3231 ranges::end(_M_base)};
3232 else
3233 return _Sentinel<__detail::__simple_view<_Vp>>{this};
3234 }
3235
3236 constexpr auto
3237 end() const
3238 requires forward_range<const _Vp>
3239 && is_reference_v<range_reference_t<const _Vp>>
3240 && input_range<range_reference_t<const _Vp>>
3241 {
3242 if constexpr (is_reference_v<range_reference_t<const _Vp>>
3243 && forward_range<range_reference_t<const _Vp>>
3244 && common_range<const _Vp>
3245 && common_range<range_reference_t<const _Vp>>)
3246 return _Iterator<true>{this, ranges::end(_M_base)};
3247 else
3248 return _Sentinel<true>{this};
3249 }
3250 };
3251
3252 template<typename _Range>
3253 explicit join_view(_Range&&) -> join_view<views::all_t<_Range>>;
3254
3255 namespace views
3256 {
3257 namespace __detail
3258 {
3259 template<typename _Range>
3260 concept __can_join_view
3261 = requires { join_view<all_t<_Range>>{std::declval<_Range>()}; };
3262 } // namespace __detail
3263
3264 struct _Join : __adaptor::_RangeAdaptorClosure<_Join>
3265 {
3266 template<viewable_range _Range>
3267 requires __detail::__can_join_view<_Range>
3268 constexpr auto
3269 operator() [[nodiscard]] (_Range&& __r) const
3270 {
3271 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3272 // 3474. Nesting join_views is broken because of CTAD
3273 return join_view<all_t<_Range>>{std::forward<_Range>(__r)};
3274 }
3275
3276 static constexpr bool _S_has_simple_call_op = true;
3277 };
3278
3279 inline constexpr _Join join;
3280 } // namespace views
3281
3282 namespace __detail
3283 {
3284 template<auto>
3285 struct __require_constant;
3286
3287 template<typename _Range>
3288 concept __tiny_range = sized_range<_Range>
3289 && requires
3290 { typename __require_constant<remove_reference_t<_Range>::size()>; }
3291 && (remove_reference_t<_Range>::size() <= 1);
3292
3293 template<typename _Base>
3294 struct __lazy_split_view_outer_iter_cat
3295 { };
3296
3297 template<forward_range _Base>
3298 struct __lazy_split_view_outer_iter_cat<_Base>
3299 { using iterator_category = input_iterator_tag; };
3300
3301 template<typename _Base>
3302 struct __lazy_split_view_inner_iter_cat
3303 { };
3304
3305 template<forward_range _Base>
3306 struct __lazy_split_view_inner_iter_cat<_Base>
3307 {
3308 private:
3309 static constexpr auto
3310 _S_iter_cat()
3311 {
3312 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
3313 if constexpr (derived_from<_Cat, forward_iterator_tag>)
3314 return forward_iterator_tag{};
3315 else
3316 return _Cat{};
3317 }
3318 public:
3319 using iterator_category = decltype(_S_iter_cat());
3320 };
3321 }
3322
3323 template<input_range _Vp, forward_range _Pattern>
3324 requires view<_Vp> && view<_Pattern>
3325 && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
3326 ranges::equal_to>
3327 && (forward_range<_Vp> || __detail::__tiny_range<_Pattern>)
3328 class lazy_split_view : public view_interface<lazy_split_view<_Vp, _Pattern>>
3329 {
3330 private:
3331 template<bool _Const>
3332 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
3333
3334 template<bool _Const>
3335 struct _InnerIter;
3336
3337 template<bool _Const>
3338 struct _OuterIter
3339 : __detail::__lazy_split_view_outer_iter_cat<_Base<_Const>>
3340 {
3341 private:
3342 using _Parent = __detail::__maybe_const_t<_Const, lazy_split_view>;
3343 using _Base = lazy_split_view::_Base<_Const>;
3344
3345 constexpr bool
3346 __at_end() const
3347 { return __current() == ranges::end(_M_parent->_M_base) && !_M_trailing_empty; }
3348
3349 // [range.lazy.split.outer] p1
3350 // Many of the following specifications refer to the notional member
3351 // current of outer-iterator. current is equivalent to current_ if
3352 // V models forward_range, and parent_->current_ otherwise.
3353 constexpr auto&
3354 __current() noexcept
3355 {
3356 if constexpr (forward_range<_Vp>)
3357 return _M_current;
3358 else
3359 return *_M_parent->_M_current;
3360 }
3361
3362 constexpr auto&
3363 __current() const noexcept
3364 {
3365 if constexpr (forward_range<_Vp>)
3366 return _M_current;
3367 else
3368 return *_M_parent->_M_current;
3369 }
3370
3371 _Parent* _M_parent = nullptr;
3372
3373 [[no_unique_address]]
3374 __detail::__maybe_present_t<forward_range<_Vp>,
3375 iterator_t<_Base>> _M_current;
3376 bool _M_trailing_empty = false;
3377
3378 public:
3379 using iterator_concept = __conditional_t<forward_range<_Base>,
3380 forward_iterator_tag,
3381 input_iterator_tag>;
3382 // iterator_category defined in __lazy_split_view_outer_iter_cat
3383 using difference_type = range_difference_t<_Base>;
3384
3385 struct value_type : view_interface<value_type>
3386 {
3387 private:
3388 _OuterIter _M_i = _OuterIter();
3389
3390 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3391 // 4013. lazy_split_view::outer-iterator::value_type should not
3392 // provide default constructor
3393 constexpr explicit
3394 value_type(_OuterIter __i)
3395 : _M_i(std::move(__i))
3396 { }
3397
3398 friend _OuterIter;
3399
3400 public:
3401 constexpr _InnerIter<_Const>
3402 begin() const
3403 { return _InnerIter<_Const>{_M_i}; }
3404
3405 constexpr default_sentinel_t
3406 end() const noexcept
3407 { return default_sentinel; }
3408 };
3409
3410 _OuterIter() = default;
3411
3412 constexpr explicit
3413 _OuterIter(_Parent* __parent) requires (!forward_range<_Base>)
3414 : _M_parent(__parent)
3415 { }
3416
3417 constexpr
3418 _OuterIter(_Parent* __parent, iterator_t<_Base> __current)
3419 requires forward_range<_Base>
3420 : _M_parent(__parent),
3421 _M_current(std::move(__current))
3422 { }
3423
3424 constexpr
3425 _OuterIter(_OuterIter<!_Const> __i)
3426 requires _Const
3427 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
3428 : _M_parent(__i._M_parent), _M_current(std::move(__i._M_current)),
3429 _M_trailing_empty(__i._M_trailing_empty)
3430 { }
3431
3432 constexpr value_type
3433 operator*() const
3434 { return value_type{*this}; }
3435
3436 constexpr _OuterIter&
3437 operator++()
3438 {
3439 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3440 // 3505. lazy_split_view::outer-iterator::operator++ misspecified
3441 const auto __end = ranges::end(_M_parent->_M_base);
3442 if (__current() == __end)
3443 {
3444 _M_trailing_empty = false;
3445 return *this;
3446 }
3447 const auto [__pbegin, __pend] = subrange{_M_parent->_M_pattern};
3448 if (__pbegin == __pend)
3449 ++__current();
3450 else if constexpr (__detail::__tiny_range<_Pattern>)
3451 {
3452 __current() = ranges::find(std::move(__current()), __end,
3453 *__pbegin);
3454 if (__current() != __end)
3455 {
3456 ++__current();
3457 if (__current() == __end)
3458 _M_trailing_empty = true;
3459 }
3460 }
3461 else
3462 do
3463 {
3464 auto [__b, __p]
3465 = ranges::mismatch(__current(), __end, __pbegin, __pend);
3466 if (__p == __pend)
3467 {
3468 __current() = __b;
3469 if (__current() == __end)
3470 _M_trailing_empty = true;
3471 break;
3472 }
3473 } while (++__current() != __end);
3474 return *this;
3475 }
3476
3477 constexpr decltype(auto)
3478 operator++(int)
3479 {
3480 if constexpr (forward_range<_Base>)
3481 {
3482 auto __tmp = *this;
3483 ++*this;
3484 return __tmp;
3485 }
3486 else
3487 ++*this;
3488 }
3489
3490 friend constexpr bool
3491 operator==(const _OuterIter& __x, const _OuterIter& __y)
3492 requires forward_range<_Base>
3493 {
3494 return __x._M_current == __y._M_current
3495 && __x._M_trailing_empty == __y._M_trailing_empty;
3496 }
3497
3498 friend constexpr bool
3499 operator==(const _OuterIter& __x, default_sentinel_t)
3500 { return __x.__at_end(); };
3501
3502 friend _OuterIter<!_Const>;
3503 friend _InnerIter<_Const>;
3504 };
3505
3506 template<bool _Const>
3507 struct _InnerIter
3508 : __detail::__lazy_split_view_inner_iter_cat<_Base<_Const>>
3509 {
3510 private:
3511 using _Base = lazy_split_view::_Base<_Const>;
3512
3513 constexpr bool
3514 __at_end() const
3515 {
3516 auto [__pcur, __pend] = subrange{_M_i._M_parent->_M_pattern};
3517 auto __end = ranges::end(_M_i._M_parent->_M_base);
3518 if constexpr (__detail::__tiny_range<_Pattern>)
3519 {
3520 const auto& __cur = _M_i_current();
3521 if (__cur == __end)
3522 return true;
3523 if (__pcur == __pend)
3524 return _M_incremented;
3525 return *__cur == *__pcur;
3526 }
3527 else
3528 {
3529 auto __cur = _M_i_current();
3530 if (__cur == __end)
3531 return true;
3532 if (__pcur == __pend)
3533 return _M_incremented;
3534 do
3535 {
3536 if (*__cur != *__pcur)
3537 return false;
3538 if (++__pcur == __pend)
3539 return true;
3540 } while (++__cur != __end);
3541 return false;
3542 }
3543 }
3544
3545 constexpr auto&
3546 _M_i_current() noexcept
3547 { return _M_i.__current(); }
3548
3549 constexpr auto&
3550 _M_i_current() const noexcept
3551 { return _M_i.__current(); }
3552
3553 _OuterIter<_Const> _M_i = _OuterIter<_Const>();
3554 bool _M_incremented = false;
3555
3556 public:
3557 using iterator_concept
3558 = typename _OuterIter<_Const>::iterator_concept;
3559 // iterator_category defined in __lazy_split_view_inner_iter_cat
3560 using value_type = range_value_t<_Base>;
3561 using difference_type = range_difference_t<_Base>;
3562
3563 _InnerIter() = default;
3564
3565 constexpr explicit
3566 _InnerIter(_OuterIter<_Const> __i)
3567 : _M_i(std::move(__i))
3568 { }
3569
3570 constexpr const iterator_t<_Base>&
3571 base() const& noexcept
3572 { return _M_i_current(); }
3573
3574 constexpr iterator_t<_Base>
3575 base() && requires forward_range<_Vp>
3576 { return std::move(_M_i_current()); }
3577
3578 constexpr decltype(auto)
3579 operator*() const
3580 { return *_M_i_current(); }
3581
3582 constexpr _InnerIter&
3583 operator++()
3584 {
3585 _M_incremented = true;
3586 if constexpr (!forward_range<_Base>)
3587 if constexpr (_Pattern::size() == 0)
3588 return *this;
3589 ++_M_i_current();
3590 return *this;
3591 }
3592
3593 constexpr decltype(auto)
3594 operator++(int)
3595 {
3596 if constexpr (forward_range<_Base>)
3597 {
3598 auto __tmp = *this;
3599 ++*this;
3600 return __tmp;
3601 }
3602 else
3603 ++*this;
3604 }
3605
3606 friend constexpr bool
3607 operator==(const _InnerIter& __x, const _InnerIter& __y)
3608 requires forward_range<_Base>
3609 { return __x._M_i == __y._M_i; }
3610
3611 friend constexpr bool
3612 operator==(const _InnerIter& __x, default_sentinel_t)
3613 { return __x.__at_end(); }
3614
3615 friend constexpr decltype(auto)
3616 iter_move(const _InnerIter& __i)
3617 noexcept(noexcept(ranges::iter_move(__i._M_i_current())))
3618 { return ranges::iter_move(__i._M_i_current()); }
3619
3620 friend constexpr void
3621 iter_swap(const _InnerIter& __x, const _InnerIter& __y)
3622 noexcept(noexcept(ranges::iter_swap(__x._M_i_current(),
3623 __y._M_i_current())))
3624 requires indirectly_swappable<iterator_t<_Base>>
3625 { ranges::iter_swap(__x._M_i_current(), __y._M_i_current()); }
3626 };
3627
3628 _Vp _M_base = _Vp();
3629 _Pattern _M_pattern = _Pattern();
3630 [[no_unique_address]]
3631 __detail::__maybe_present_t<!forward_range<_Vp>,
3632 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_current;
3633
3634
3635 public:
3636 lazy_split_view() requires (default_initializable<_Vp>
3637 && default_initializable<_Pattern>)
3638 = default;
3639
3640 constexpr
3641 lazy_split_view(_Vp __base, _Pattern __pattern)
3642 : _M_base(std::move(__base)), _M_pattern(std::move(__pattern))
3643 { }
3644
3645 template<input_range _Range>
3646 requires constructible_from<_Vp, views::all_t<_Range>>
3647 && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
3648 constexpr
3649 lazy_split_view(_Range&& __r, range_value_t<_Range> __e)
3650 : _M_base(views::all(std::forward<_Range>(__r))),
3651 _M_pattern(views::single(std::move(__e)))
3652 { }
3653
3654 constexpr _Vp
3655 base() const& requires copy_constructible<_Vp>
3656 { return _M_base; }
3657
3658 constexpr _Vp
3659 base() &&
3660 { return std::move(_M_base); }
3661
3662 constexpr auto
3663 begin()
3664 {
3665 if constexpr (forward_range<_Vp>)
3666 {
3667 constexpr bool __simple
3668 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
3669 return _OuterIter<__simple>{this, ranges::begin(_M_base)};
3670 }
3671 else
3672 {
3673 _M_current = ranges::begin(_M_base);
3674 return _OuterIter<false>{this};
3675 }
3676 }
3677
3678 constexpr auto
3679 begin() const requires forward_range<_Vp> && forward_range<const _Vp>
3680 {
3681 return _OuterIter<true>{this, ranges::begin(_M_base)};
3682 }
3683
3684 constexpr auto
3685 end() requires forward_range<_Vp> && common_range<_Vp>
3686 {
3687 constexpr bool __simple
3688 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
3689 return _OuterIter<__simple>{this, ranges::end(_M_base)};
3690 }
3691
3692 constexpr auto
3693 end() const
3694 {
3695 if constexpr (forward_range<_Vp>
3696 && forward_range<const _Vp>
3697 && common_range<const _Vp>)
3698 return _OuterIter<true>{this, ranges::end(_M_base)};
3699 else
3700 return default_sentinel;
3701 }
3702 };
3703
3704 template<typename _Range, typename _Pattern>
3705 lazy_split_view(_Range&&, _Pattern&&)
3706 -> lazy_split_view<views::all_t<_Range>, views::all_t<_Pattern>>;
3707
3708 template<input_range _Range>
3709 lazy_split_view(_Range&&, range_value_t<_Range>)
3710 -> lazy_split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;
3711
3712 namespace views
3713 {
3714 namespace __detail
3715 {
3716 template<typename _Range, typename _Pattern>
3717 concept __can_lazy_split_view
3718 = requires { lazy_split_view(std::declval<_Range>(), std::declval<_Pattern>()); };
3719 } // namespace __detail
3720
3721 struct _LazySplit : __adaptor::_RangeAdaptor<_LazySplit>
3722 {
3723 template<viewable_range _Range, typename _Pattern>
3724 requires __detail::__can_lazy_split_view<_Range, _Pattern>
3725 constexpr auto
3726 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f) const
3727 {
3728 return lazy_split_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
3729 }
3730
3731 using _RangeAdaptor<_LazySplit>::operator();
3732 static constexpr int _S_arity = 2;
3733 // The pattern argument of views::lazy_split is not always simple -- it can be
3734 // a non-view range, the value category of which affects whether the call
3735 // is well-formed. But a scalar or a view pattern argument is surely
3736 // simple.
3737 template<typename _Pattern>
3738 static constexpr bool _S_has_simple_extra_args
3739 = is_scalar_v<_Pattern> || (view<_Pattern>
3740 && copy_constructible<_Pattern>);
3741 };
3742
3743 inline constexpr _LazySplit lazy_split;
3744 } // namespace views
3745
3746 template<forward_range _Vp, forward_range _Pattern>
3747 requires view<_Vp> && view<_Pattern>
3748 && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
3749 ranges::equal_to>
3750 class split_view : public view_interface<split_view<_Vp, _Pattern>>
3751 {
3752 private:
3753 _Vp _M_base = _Vp();
3754 _Pattern _M_pattern = _Pattern();
3755 __detail::__non_propagating_cache<subrange<iterator_t<_Vp>>> _M_cached_begin;
3756
3757 struct _Iterator;
3758 struct _Sentinel;
3759
3760 public:
3761 split_view() requires (default_initializable<_Vp>
3762 && default_initializable<_Pattern>)
3763 = default;
3764
3765 constexpr
3766 split_view(_Vp __base, _Pattern __pattern)
3767 : _M_base(std::move(__base)), _M_pattern(std::move(__pattern))
3768 { }
3769
3770 template<forward_range _Range>
3771 requires constructible_from<_Vp, views::all_t<_Range>>
3772 && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
3773 constexpr
3774 split_view(_Range&& __r, range_value_t<_Range> __e)
3775 : _M_base(views::all(std::forward<_Range>(__r))),
3776 _M_pattern(views::single(std::move(__e)))
3777 { }
3778
3779 constexpr _Vp
3780 base() const& requires copy_constructible<_Vp>
3781 { return _M_base; }
3782
3783 constexpr _Vp
3784 base() &&
3785 { return std::move(_M_base); }
3786
3787 constexpr _Iterator
3788 begin()
3789 {
3790 if (!_M_cached_begin)
3791 _M_cached_begin = _M_find_next(ranges::begin(_M_base));
3792 return {this, ranges::begin(_M_base), *_M_cached_begin};
3793 }
3794
3795 constexpr auto
3796 end()
3797 {
3798 if constexpr (common_range<_Vp>)
3799 return _Iterator{this, ranges::end(_M_base), {}};
3800 else
3801 return _Sentinel{this};
3802 }
3803
3804 constexpr subrange<iterator_t<_Vp>>
3805 _M_find_next(iterator_t<_Vp> __it)
3806 {
3807 auto [__b, __e] = ranges::search(subrange(__it, ranges::end(_M_base)), _M_pattern);
3808 if (__b != ranges::end(_M_base) && ranges::empty(_M_pattern))
3809 {
3810 ++__b;
3811 ++__e;
3812 }
3813 return {__b, __e};
3814 }
3815
3816 private:
3817 struct _Iterator
3818 {
3819 private:
3820 split_view* _M_parent = nullptr;
3821 iterator_t<_Vp> _M_cur = iterator_t<_Vp>();
3822 subrange<iterator_t<_Vp>> _M_next = subrange<iterator_t<_Vp>>();
3823 bool _M_trailing_empty = false;
3824
3825 friend struct _Sentinel;
3826
3827 public:
3828 using iterator_concept = forward_iterator_tag;
3829 using iterator_category = input_iterator_tag;
3830 using value_type = subrange<iterator_t<_Vp>>;
3831 using difference_type = range_difference_t<_Vp>;
3832
3833 _Iterator() = default;
3834
3835 constexpr
3836 _Iterator(split_view* __parent,
3837 iterator_t<_Vp> __current,
3838 subrange<iterator_t<_Vp>> __next)
3839 : _M_parent(__parent),
3840 _M_cur(std::move(__current)),
3841 _M_next(std::move(__next))
3842 { }
3843
3844 constexpr iterator_t<_Vp>
3845 base() const
3846 { return _M_cur; }
3847
3848 constexpr value_type
3849 operator*() const
3850 { return {_M_cur, _M_next.begin()}; }
3851
3852 constexpr _Iterator&
3853 operator++()
3854 {
3855 _M_cur = _M_next.begin();
3856 if (_M_cur != ranges::end(_M_parent->_M_base))
3857 {
3858 _M_cur = _M_next.end();
3859 if (_M_cur == ranges::end(_M_parent->_M_base))
3860 {
3861 _M_trailing_empty = true;
3862 _M_next = {_M_cur, _M_cur};
3863 }
3864 else
3865 _M_next = _M_parent->_M_find_next(_M_cur);
3866 }
3867 else
3868 _M_trailing_empty = false;
3869 return *this;
3870 }
3871
3872 constexpr _Iterator
3873 operator++(int)
3874 {
3875 auto __tmp = *this;
3876 ++*this;
3877 return __tmp;
3878 }
3879
3880 friend constexpr bool
3881 operator==(const _Iterator& __x, const _Iterator& __y)
3882 {
3883 return __x._M_cur == __y._M_cur
3884 && __x._M_trailing_empty == __y._M_trailing_empty;
3885 }
3886 };
3887
3888 struct _Sentinel
3889 {
3890 private:
3891 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
3892
3893 constexpr bool
3894 _M_equal(const _Iterator& __x) const
3895 { return __x._M_cur == _M_end && !__x._M_trailing_empty; }
3896
3897 public:
3898 _Sentinel() = default;
3899
3900 constexpr explicit
3901 _Sentinel(split_view* __parent)
3902 : _M_end(ranges::end(__parent->_M_base))
3903 { }
3904
3905 friend constexpr bool
3906 operator==(const _Iterator& __x, const _Sentinel& __y)
3907 { return __y._M_equal(__x); }
3908 };
3909 };
3910
3911 template<typename _Range, typename _Pattern>
3912 split_view(_Range&&, _Pattern&&)
3913 -> split_view<views::all_t<_Range>, views::all_t<_Pattern>>;
3914
3915 template<forward_range _Range>
3916 split_view(_Range&&, range_value_t<_Range>)
3917 -> split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;
3918
3919 namespace views
3920 {
3921 namespace __detail
3922 {
3923 template<typename _Range, typename _Pattern>
3924 concept __can_split_view
3925 = requires { split_view(std::declval<_Range>(), std::declval<_Pattern>()); };
3926 } // namespace __detail
3927
3928 struct _Split : __adaptor::_RangeAdaptor<_Split>
3929 {
3930 template<viewable_range _Range, typename _Pattern>
3931 requires __detail::__can_split_view<_Range, _Pattern>
3932 constexpr auto
3933 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f) const
3934 {
3935 return split_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
3936 }
3937
3938 using _RangeAdaptor<_Split>::operator();
3939 static constexpr int _S_arity = 2;
3940 template<typename _Pattern>
3941 static constexpr bool _S_has_simple_extra_args
3942 = _LazySplit::_S_has_simple_extra_args<_Pattern>;
3943 };
3944
3945 inline constexpr _Split split;
3946 } // namespace views
3947
3948 namespace views
3949 {
3950 struct _Counted
3951 {
3952 template<input_or_output_iterator _Iter>
3953 constexpr auto
3954 operator() [[nodiscard]] (_Iter __i, iter_difference_t<_Iter> __n) const
3955 {
3956 if constexpr (contiguous_iterator<_Iter>)
3957 return span(std::to_address(__i), __n);
3958 else if constexpr (random_access_iterator<_Iter>)
3959 return subrange(__i, __i + __n);
3960 else
3961 return subrange(counted_iterator(std::move(__i), __n),
3962 default_sentinel);
3963 }
3964 };
3965
3966 inline constexpr _Counted counted{};
3967 } // namespace views
3968
3969 template<view _Vp>
3970 requires (!common_range<_Vp>) && copyable<iterator_t<_Vp>>
3971 class common_view : public view_interface<common_view<_Vp>>
3972 {
3973 private:
3974 _Vp _M_base = _Vp();
3975
3976 public:
3977 common_view() requires default_initializable<_Vp> = default;
3978
3979 constexpr explicit
3980 common_view(_Vp __r)
3981 : _M_base(std::move(__r))
3982 { }
3983
3984 constexpr _Vp
3985 base() const& requires copy_constructible<_Vp>
3986 { return _M_base; }
3987
3988 constexpr _Vp
3989 base() &&
3990 { return std::move(_M_base); }
3991
3992 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3993 // 4012. common_view::begin/end are missing the simple-view check
3994 constexpr auto
3995 begin() requires (!__detail::__simple_view<_Vp>)
3996 {
3997 if constexpr (random_access_range<_Vp> && sized_range<_Vp>)
3998 return ranges::begin(_M_base);
3999 else
4000 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
4001 (ranges::begin(_M_base));
4002 }
4003
4004 constexpr auto
4005 begin() const requires range<const _Vp>
4006 {
4007 if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>)
4008 return ranges::begin(_M_base);
4009 else
4010 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
4011 (ranges::begin(_M_base));
4012 }
4013
4014 constexpr auto
4015 end() requires (!__detail::__simple_view<_Vp>)
4016 {
4017 if constexpr (random_access_range<_Vp> && sized_range<_Vp>)
4018 return ranges::begin(_M_base) + ranges::size(_M_base);
4019 else
4020 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
4021 (ranges::end(_M_base));
4022 }
4023
4024 constexpr auto
4025 end() const requires range<const _Vp>
4026 {
4027 if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>)
4028 return ranges::begin(_M_base) + ranges::size(_M_base);
4029 else
4030 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
4031 (ranges::end(_M_base));
4032 }
4033
4034 constexpr auto
4035 size() requires sized_range<_Vp>
4036 { return ranges::size(_M_base); }
4037
4038 constexpr auto
4039 size() const requires sized_range<const _Vp>
4040 { return ranges::size(_M_base); }
4041 };
4042
4043 template<typename _Range>
4044 common_view(_Range&&) -> common_view<views::all_t<_Range>>;
4045
4046 template<typename _Tp>
4047 inline constexpr bool enable_borrowed_range<common_view<_Tp>>
4048 = enable_borrowed_range<_Tp>;
4049
4050 namespace views
4051 {
4052 namespace __detail
4053 {
4054 template<typename _Range>
4055 concept __already_common = common_range<_Range>
4056 && requires { views::all(std::declval<_Range>()); };
4057
4058 template<typename _Range>
4059 concept __can_common_view
4060 = requires { common_view{std::declval<_Range>()}; };
4061 } // namespace __detail
4062
4063 struct _Common : __adaptor::_RangeAdaptorClosure<_Common>
4064 {
4065 template<viewable_range _Range>
4066 requires __detail::__already_common<_Range>
4067 || __detail::__can_common_view<_Range>
4068 constexpr auto
4069 operator() [[nodiscard]] (_Range&& __r) const
4070 {
4071 if constexpr (__detail::__already_common<_Range>)
4072 return views::all(std::forward<_Range>(__r));
4073 else
4074 return common_view{std::forward<_Range>(__r)};
4075 }
4076
4077 static constexpr bool _S_has_simple_call_op = true;
4078 };
4079
4080 inline constexpr _Common common;
4081 } // namespace views
4082
4083 template<view _Vp>
4084 requires bidirectional_range<_Vp>
4085 class reverse_view : public view_interface<reverse_view<_Vp>>
4086 {
4087 private:
4088 static constexpr bool _S_needs_cached_begin
4089 = !common_range<_Vp> && !(random_access_range<_Vp>
4090 && sized_sentinel_for<sentinel_t<_Vp>,
4091 iterator_t<_Vp>>);
4092
4093 _Vp _M_base = _Vp();
4094 [[no_unique_address]]
4095 __detail::__maybe_present_t<_S_needs_cached_begin,
4096 __detail::_CachedPosition<_Vp>>
4097 _M_cached_begin;
4098
4099 public:
4100 reverse_view() requires default_initializable<_Vp> = default;
4101
4102 constexpr explicit
4103 reverse_view(_Vp __r)
4104 : _M_base(std::move(__r))
4105 { }
4106
4107 constexpr _Vp
4108 base() const& requires copy_constructible<_Vp>
4109 { return _M_base; }
4110
4111 constexpr _Vp
4112 base() &&
4113 { return std::move(_M_base); }
4114
4115 constexpr reverse_iterator<iterator_t<_Vp>>
4116 begin()
4117 {
4118 if constexpr (_S_needs_cached_begin)
4119 if (_M_cached_begin._M_has_value())
4120 return std::make_reverse_iterator(_M_cached_begin._M_get(_M_base));
4121
4122 auto __it = ranges::next(ranges::begin(_M_base), ranges::end(_M_base));
4123 if constexpr (_S_needs_cached_begin)
4124 _M_cached_begin._M_set(_M_base, __it);
4126 }
4127
4128 constexpr auto
4129 begin() requires common_range<_Vp>
4130 { return std::make_reverse_iterator(ranges::end(_M_base)); }
4131
4132 constexpr auto
4133 begin() const requires common_range<const _Vp>
4134 { return std::make_reverse_iterator(ranges::end(_M_base)); }
4135
4136 constexpr reverse_iterator<iterator_t<_Vp>>
4137 end()
4138 { return std::make_reverse_iterator(ranges::begin(_M_base)); }
4139
4140 constexpr auto
4141 end() const requires common_range<const _Vp>
4142 { return std::make_reverse_iterator(ranges::begin(_M_base)); }
4143
4144 constexpr auto
4145 size() requires sized_range<_Vp>
4146 { return ranges::size(_M_base); }
4147
4148 constexpr auto
4149 size() const requires sized_range<const _Vp>
4150 { return ranges::size(_M_base); }
4151 };
4152
4153 template<typename _Range>
4154 reverse_view(_Range&&) -> reverse_view<views::all_t<_Range>>;
4155
4156 template<typename _Tp>
4157 inline constexpr bool enable_borrowed_range<reverse_view<_Tp>>
4158 = enable_borrowed_range<_Tp>;
4159
4160 namespace views
4161 {
4162 namespace __detail
4163 {
4164 template<typename>
4165 inline constexpr bool __is_reversible_subrange = false;
4166
4167 template<typename _Iter, subrange_kind _Kind>
4168 inline constexpr bool
4169 __is_reversible_subrange<subrange<reverse_iterator<_Iter>,
4170 reverse_iterator<_Iter>,
4171 _Kind>> = true;
4172
4173 template<typename>
4174 inline constexpr bool __is_reverse_view = false;
4175
4176 template<typename _Vp>
4177 inline constexpr bool __is_reverse_view<reverse_view<_Vp>> = true;
4178
4179 template<typename _Range>
4180 concept __can_reverse_view
4181 = requires { reverse_view{std::declval<_Range>()}; };
4182 } // namespace __detail
4183
4184 struct _Reverse : __adaptor::_RangeAdaptorClosure<_Reverse>
4185 {
4186 template<viewable_range _Range>
4187 requires __detail::__is_reverse_view<remove_cvref_t<_Range>>
4188 || __detail::__is_reversible_subrange<remove_cvref_t<_Range>>
4189 || __detail::__can_reverse_view<_Range>
4190 constexpr auto
4191 operator() [[nodiscard]] (_Range&& __r) const
4192 {
4193 using _Tp = remove_cvref_t<_Range>;
4194 if constexpr (__detail::__is_reverse_view<_Tp>)
4195 return std::forward<_Range>(__r).base();
4196 else if constexpr (__detail::__is_reversible_subrange<_Tp>)
4197 {
4198 using _Iter = decltype(ranges::begin(__r).base());
4199 if constexpr (sized_range<_Tp>)
4200 return subrange<_Iter, _Iter, subrange_kind::sized>
4201 {__r.end().base(), __r.begin().base(), __r.size()};
4202 else
4203 return subrange<_Iter, _Iter, subrange_kind::unsized>
4204 {__r.end().base(), __r.begin().base()};
4205 }
4206 else
4207 return reverse_view{std::forward<_Range>(__r)};
4208 }
4209
4210 static constexpr bool _S_has_simple_call_op = true;
4211 };
4212
4213 inline constexpr _Reverse reverse;
4214 } // namespace views
4215
4216 namespace __detail
4217 {
4218#if __cpp_lib_tuple_like // >= C++23
4219 template<typename _Tp, size_t _Nm>
4220 concept __has_tuple_element = __tuple_like<_Tp> && _Nm < tuple_size_v<_Tp>;
4221#else
4222 template<typename _Tp, size_t _Nm>
4223 concept __has_tuple_element = requires(_Tp __t)
4224 {
4225 typename tuple_size<_Tp>::type;
4226 requires _Nm < tuple_size_v<_Tp>;
4227 typename tuple_element_t<_Nm, _Tp>;
4228 { std::get<_Nm>(__t) }
4229 -> convertible_to<const tuple_element_t<_Nm, _Tp>&>;
4230 };
4231#endif
4232
4233 template<typename _Tp, size_t _Nm>
4234 concept __returnable_element
4235 = is_reference_v<_Tp> || move_constructible<tuple_element_t<_Nm, _Tp>>;
4236 }
4237
4238 template<input_range _Vp, size_t _Nm>
4239 requires view<_Vp>
4240 && __detail::__has_tuple_element<range_value_t<_Vp>, _Nm>
4241 && __detail::__has_tuple_element<remove_reference_t<range_reference_t<_Vp>>,
4242 _Nm>
4243 && __detail::__returnable_element<range_reference_t<_Vp>, _Nm>
4244 class elements_view : public view_interface<elements_view<_Vp, _Nm>>
4245 {
4246 public:
4247 elements_view() requires default_initializable<_Vp> = default;
4248
4249 constexpr explicit
4250 elements_view(_Vp __base)
4251 : _M_base(std::move(__base))
4252 { }
4253
4254 constexpr _Vp
4255 base() const& requires copy_constructible<_Vp>
4256 { return _M_base; }
4257
4258 constexpr _Vp
4259 base() &&
4260 { return std::move(_M_base); }
4261
4262 constexpr auto
4263 begin() requires (!__detail::__simple_view<_Vp>)
4264 { return _Iterator<false>(ranges::begin(_M_base)); }
4265
4266 constexpr auto
4267 begin() const requires range<const _Vp>
4268 { return _Iterator<true>(ranges::begin(_M_base)); }
4269
4270 constexpr auto
4271 end() requires (!__detail::__simple_view<_Vp> && !common_range<_Vp>)
4272 { return _Sentinel<false>{ranges::end(_M_base)}; }
4273
4274 constexpr auto
4275 end() requires (!__detail::__simple_view<_Vp> && common_range<_Vp>)
4276 { return _Iterator<false>{ranges::end(_M_base)}; }
4277
4278 constexpr auto
4279 end() const requires range<const _Vp>
4280 { return _Sentinel<true>{ranges::end(_M_base)}; }
4281
4282 constexpr auto
4283 end() const requires common_range<const _Vp>
4284 { return _Iterator<true>{ranges::end(_M_base)}; }
4285
4286 constexpr auto
4287 size() requires sized_range<_Vp>
4288 { return ranges::size(_M_base); }
4289
4290 constexpr auto
4291 size() const requires sized_range<const _Vp>
4292 { return ranges::size(_M_base); }
4293
4294 private:
4295 template<bool _Const>
4296 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
4297
4298 template<bool _Const>
4299 struct __iter_cat
4300 { };
4301
4302 template<bool _Const>
4303 requires forward_range<_Base<_Const>>
4304 struct __iter_cat<_Const>
4305 {
4306 private:
4307 static auto _S_iter_cat()
4308 {
4309 using _Base = elements_view::_Base<_Const>;
4310 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
4311 using _Res = decltype((std::get<_Nm>(*std::declval<iterator_t<_Base>>())));
4312 if constexpr (!is_lvalue_reference_v<_Res>)
4313 return input_iterator_tag{};
4314 else if constexpr (derived_from<_Cat, random_access_iterator_tag>)
4315 return random_access_iterator_tag{};
4316 else
4317 return _Cat{};
4318 }
4319 public:
4320 using iterator_category = decltype(_S_iter_cat());
4321 };
4322
4323 template<bool _Const>
4324 struct _Sentinel;
4325
4326 template<bool _Const>
4327 struct _Iterator : __iter_cat<_Const>
4328 {
4329 private:
4330 using _Base = elements_view::_Base<_Const>;
4331
4332 iterator_t<_Base> _M_current = iterator_t<_Base>();
4333
4334 static constexpr decltype(auto)
4335 _S_get_element(const iterator_t<_Base>& __i)
4336 {
4337 if constexpr (is_reference_v<range_reference_t<_Base>>)
4338 return std::get<_Nm>(*__i);
4339 else
4340 {
4341 using _Et = remove_cv_t<tuple_element_t<_Nm, range_reference_t<_Base>>>;
4342 return static_cast<_Et>(std::get<_Nm>(*__i));
4343 }
4344 }
4345
4346 static auto
4347 _S_iter_concept()
4348 {
4349 if constexpr (random_access_range<_Base>)
4350 return random_access_iterator_tag{};
4351 else if constexpr (bidirectional_range<_Base>)
4352 return bidirectional_iterator_tag{};
4353 else if constexpr (forward_range<_Base>)
4354 return forward_iterator_tag{};
4355 else
4356 return input_iterator_tag{};
4357 }
4358
4359 friend _Iterator<!_Const>;
4360
4361 public:
4362 using iterator_concept = decltype(_S_iter_concept());
4363 // iterator_category defined in elements_view::__iter_cat
4364 using value_type
4365 = remove_cvref_t<tuple_element_t<_Nm, range_value_t<_Base>>>;
4366 using difference_type = range_difference_t<_Base>;
4367
4368 _Iterator() requires default_initializable<iterator_t<_Base>> = default;
4369
4370 constexpr explicit
4371 _Iterator(iterator_t<_Base> __current)
4372 : _M_current(std::move(__current))
4373 { }
4374
4375 constexpr
4376 _Iterator(_Iterator<!_Const> __i)
4377 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
4378 : _M_current(std::move(__i._M_current))
4379 { }
4380
4381 constexpr const iterator_t<_Base>&
4382 base() const& noexcept
4383 { return _M_current; }
4384
4385 constexpr iterator_t<_Base>
4386 base() &&
4387 { return std::move(_M_current); }
4388
4389 constexpr decltype(auto)
4390 operator*() const
4391 { return _S_get_element(_M_current); }
4392
4393 constexpr _Iterator&
4394 operator++()
4395 {
4396 ++_M_current;
4397 return *this;
4398 }
4399
4400 constexpr void
4401 operator++(int)
4402 { ++_M_current; }
4403
4404 constexpr _Iterator
4405 operator++(int) requires forward_range<_Base>
4406 {
4407 auto __tmp = *this;
4408 ++_M_current;
4409 return __tmp;
4410 }
4411
4412 constexpr _Iterator&
4413 operator--() requires bidirectional_range<_Base>
4414 {
4415 --_M_current;
4416 return *this;
4417 }
4418
4419 constexpr _Iterator
4420 operator--(int) requires bidirectional_range<_Base>
4421 {
4422 auto __tmp = *this;
4423 --_M_current;
4424 return __tmp;
4425 }
4426
4427 constexpr _Iterator&
4428 operator+=(difference_type __n)
4429 requires random_access_range<_Base>
4430 {
4431 _M_current += __n;
4432 return *this;
4433 }
4434
4435 constexpr _Iterator&
4436 operator-=(difference_type __n)
4437 requires random_access_range<_Base>
4438 {
4439 _M_current -= __n;
4440 return *this;
4441 }
4442
4443 constexpr decltype(auto)
4444 operator[](difference_type __n) const
4445 requires random_access_range<_Base>
4446 { return _S_get_element(_M_current + __n); }
4447
4448 friend constexpr bool
4449 operator==(const _Iterator& __x, const _Iterator& __y)
4450 requires equality_comparable<iterator_t<_Base>>
4451 { return __x._M_current == __y._M_current; }
4452
4453 friend constexpr bool
4454 operator<(const _Iterator& __x, const _Iterator& __y)
4455 requires random_access_range<_Base>
4456 { return __x._M_current < __y._M_current; }
4457
4458 friend constexpr bool
4459 operator>(const _Iterator& __x, const _Iterator& __y)
4460 requires random_access_range<_Base>
4461 { return __y._M_current < __x._M_current; }
4462
4463 friend constexpr bool
4464 operator<=(const _Iterator& __x, const _Iterator& __y)
4465 requires random_access_range<_Base>
4466 { return !(__y._M_current > __x._M_current); }
4467
4468 friend constexpr bool
4469 operator>=(const _Iterator& __x, const _Iterator& __y)
4470 requires random_access_range<_Base>
4471 { return !(__x._M_current > __y._M_current); }
4472
4473#ifdef __cpp_lib_three_way_comparison
4474 friend constexpr auto
4475 operator<=>(const _Iterator& __x, const _Iterator& __y)
4476 requires random_access_range<_Base>
4477 && three_way_comparable<iterator_t<_Base>>
4478 { return __x._M_current <=> __y._M_current; }
4479#endif
4480
4481 friend constexpr _Iterator
4482 operator+(const _Iterator& __x, difference_type __y)
4483 requires random_access_range<_Base>
4484 { return _Iterator{__x} += __y; }
4485
4486 friend constexpr _Iterator
4487 operator+(difference_type __x, const _Iterator& __y)
4488 requires random_access_range<_Base>
4489 { return __y + __x; }
4490
4491 friend constexpr _Iterator
4492 operator-(const _Iterator& __x, difference_type __y)
4493 requires random_access_range<_Base>
4494 { return _Iterator{__x} -= __y; }
4495
4496 // _GLIBCXX_RESOLVE_LIB_DEFECTS
4497 // 3483. transform_view::iterator's difference is overconstrained
4498 friend constexpr difference_type
4499 operator-(const _Iterator& __x, const _Iterator& __y)
4500 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
4501 { return __x._M_current - __y._M_current; }
4502
4503 template <bool> friend struct _Sentinel;
4504 };
4505
4506 template<bool _Const>
4507 struct _Sentinel
4508 {
4509 private:
4510 template<bool _Const2>
4511 constexpr bool
4512 _M_equal(const _Iterator<_Const2>& __x) const
4513 { return __x._M_current == _M_end; }
4514
4515 template<bool _Const2>
4516 constexpr auto
4517 _M_distance_from(const _Iterator<_Const2>& __i) const
4518 { return _M_end - __i._M_current; }
4519
4520 using _Base = elements_view::_Base<_Const>;
4521 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
4522
4523 public:
4524 _Sentinel() = default;
4525
4526 constexpr explicit
4527 _Sentinel(sentinel_t<_Base> __end)
4528 : _M_end(std::move(__end))
4529 { }
4530
4531 constexpr
4532 _Sentinel(_Sentinel<!_Const> __other)
4533 requires _Const
4534 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
4535 : _M_end(std::move(__other._M_end))
4536 { }
4537
4538 constexpr sentinel_t<_Base>
4539 base() const
4540 { return _M_end; }
4541
4542 template<bool _Const2>
4543 requires sentinel_for<sentinel_t<_Base>,
4544 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
4545 friend constexpr bool
4546 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
4547 { return __y._M_equal(__x); }
4548
4549 template<bool _Const2,
4550 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
4551 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
4552 friend constexpr range_difference_t<_Base2>
4553 operator-(const _Iterator<_Const2>& __x, const _Sentinel& __y)
4554 { return -__y._M_distance_from(__x); }
4555
4556 template<bool _Const2,
4557 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
4558 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
4559 friend constexpr range_difference_t<_Base2>
4560 operator-(const _Sentinel& __x, const _Iterator<_Const2>& __y)
4561 { return __x._M_distance_from(__y); }
4562
4563 friend _Sentinel<!_Const>;
4564 };
4565
4566 _Vp _M_base = _Vp();
4567 };
4568
4569 template<typename _Tp, size_t _Nm>
4570 inline constexpr bool enable_borrowed_range<elements_view<_Tp, _Nm>>
4571 = enable_borrowed_range<_Tp>;
4572
4573 // _GLIBCXX_RESOLVE_LIB_DEFECTS
4574 // 3563. keys_view example is broken
4575 template<typename _Range>
4576 using keys_view = elements_view<_Range, 0>;
4577
4578 template<typename _Range>
4579 using values_view = elements_view<_Range, 1>;
4580
4581 namespace views
4582 {
4583 namespace __detail
4584 {
4585 template<size_t _Nm, typename _Range>
4586 concept __can_elements_view
4587 = requires { elements_view<all_t<_Range>, _Nm>{std::declval<_Range>()}; };
4588 } // namespace __detail
4589
4590 template<size_t _Nm>
4591 struct _Elements : __adaptor::_RangeAdaptorClosure<_Elements<_Nm>>
4592 {
4593 template<viewable_range _Range>
4594 requires __detail::__can_elements_view<_Nm, _Range>
4595 constexpr auto
4596 operator() [[nodiscard]] (_Range&& __r) const
4597 {
4598 return elements_view<all_t<_Range>, _Nm>{std::forward<_Range>(__r)};
4599 }
4600
4601 static constexpr bool _S_has_simple_call_op = true;
4602 };
4603
4604 template<size_t _Nm>
4605 inline constexpr _Elements<_Nm> elements;
4606 inline constexpr auto keys = elements<0>;
4607 inline constexpr auto values = elements<1>;
4608 } // namespace views
4609
4610#ifdef __cpp_lib_ranges_zip // C++ >= 23
4611 namespace __detail
4612 {
4613 template<typename... _Rs>
4614 concept __zip_is_common = (sizeof...(_Rs) == 1 && (common_range<_Rs> && ...))
4615 || (!(bidirectional_range<_Rs> && ...) && (common_range<_Rs> && ...))
4616 || ((random_access_range<_Rs> && ...) && (sized_range<_Rs> && ...));
4617
4618 template<typename _Fp, typename _Tuple>
4619 constexpr auto
4620 __tuple_transform(_Fp&& __f, _Tuple&& __tuple)
4621 {
4622 return std::apply([&]<typename... _Ts>(_Ts&&... __elts) {
4623 return tuple<invoke_result_t<_Fp&, _Ts>...>
4624 (std::__invoke(__f, std::forward<_Ts>(__elts))...);
4625 }, std::forward<_Tuple>(__tuple));
4626 }
4627
4628 template<typename _Fp, typename _Tuple>
4629 constexpr void
4630 __tuple_for_each(_Fp&& __f, _Tuple&& __tuple)
4631 {
4632 std::apply([&]<typename... _Ts>(_Ts&&... __elts) {
4633 (std::__invoke(__f, std::forward<_Ts>(__elts)), ...);
4634 }, std::forward<_Tuple>(__tuple));
4635 }
4636 } // namespace __detail
4637
4638 template<input_range... _Vs>
4639 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0)
4640 class zip_view : public view_interface<zip_view<_Vs...>>
4641 {
4642 tuple<_Vs...> _M_views;
4643
4644 template<bool> class _Iterator;
4645 template<bool> class _Sentinel;
4646
4647 public:
4648 zip_view() = default;
4649
4650 constexpr explicit
4651 zip_view(_Vs... __views)
4652 : _M_views(std::move(__views)...)
4653 { }
4654
4655 constexpr auto
4656 begin() requires (!(__detail::__simple_view<_Vs> && ...))
4657 { return _Iterator<false>(__detail::__tuple_transform(ranges::begin, _M_views)); }
4658
4659 constexpr auto
4660 begin() const requires (range<const _Vs> && ...)
4661 { return _Iterator<true>(__detail::__tuple_transform(ranges::begin, _M_views)); }
4662
4663 constexpr auto
4664 end() requires (!(__detail::__simple_view<_Vs> && ...))
4665 {
4666 if constexpr (!__detail::__zip_is_common<_Vs...>)
4667 return _Sentinel<false>(__detail::__tuple_transform(ranges::end, _M_views));
4668 else if constexpr ((random_access_range<_Vs> && ...))
4669 return begin() + iter_difference_t<_Iterator<false>>(size());
4670 else
4671 return _Iterator<false>(__detail::__tuple_transform(ranges::end, _M_views));
4672 }
4673
4674 constexpr auto
4675 end() const requires (range<const _Vs> && ...)
4676 {
4677 if constexpr (!__detail::__zip_is_common<const _Vs...>)
4678 return _Sentinel<true>(__detail::__tuple_transform(ranges::end, _M_views));
4679 else if constexpr ((random_access_range<const _Vs> && ...))
4680 return begin() + iter_difference_t<_Iterator<true>>(size());
4681 else
4682 return _Iterator<true>(__detail::__tuple_transform(ranges::end, _M_views));
4683 }
4684
4685 constexpr auto
4686 size() requires (sized_range<_Vs> && ...)
4687 {
4688 return std::apply([](auto... sizes) {
4689 using _CT = __detail::__make_unsigned_like_t<common_type_t<decltype(sizes)...>>;
4690 return ranges::min({_CT(sizes)...});
4691 }, __detail::__tuple_transform(ranges::size, _M_views));
4692 }
4693
4694 constexpr auto
4695 size() const requires (sized_range<const _Vs> && ...)
4696 {
4697 return std::apply([](auto... sizes) {
4698 using _CT = __detail::__make_unsigned_like_t<common_type_t<decltype(sizes)...>>;
4699 return ranges::min({_CT(sizes)...});
4700 }, __detail::__tuple_transform(ranges::size, _M_views));
4701 }
4702 };
4703
4704 template<typename... _Rs>
4705 zip_view(_Rs&&...) -> zip_view<views::all_t<_Rs>...>;
4706
4707 template<typename... _Views>
4708 inline constexpr bool enable_borrowed_range<zip_view<_Views...>>
4709 = (enable_borrowed_range<_Views> && ...);
4710
4711 namespace __detail
4712 {
4713 template<bool _Const, typename... _Vs>
4714 concept __all_random_access
4715 = (random_access_range<__maybe_const_t<_Const, _Vs>> && ...);
4716
4717 template<bool _Const, typename... _Vs>
4718 concept __all_bidirectional
4719 = (bidirectional_range<__maybe_const_t<_Const, _Vs>> && ...);
4720
4721 template<bool _Const, typename... _Vs>
4722 concept __all_forward
4723 = (forward_range<__maybe_const_t<_Const, _Vs>> && ...);
4724
4725 template<bool _Const, typename... _Views>
4726 struct __zip_view_iter_cat
4727 { };
4728
4729 template<bool _Const, typename... _Views>
4730 requires __all_forward<_Const, _Views...>
4731 struct __zip_view_iter_cat<_Const, _Views...>
4732 { using iterator_category = input_iterator_tag; };
4733 } // namespace __detail
4734
4735 template<input_range... _Vs>
4736 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0)
4737 template<bool _Const>
4738 class zip_view<_Vs...>::_Iterator
4739 : public __detail::__zip_view_iter_cat<_Const, _Vs...>
4740 {
4741#ifdef _GLIBCXX_CLANG // LLVM-61763 workaround
4742 public:
4743#endif
4744 tuple<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>...> _M_current;
4745
4746 constexpr explicit
4747 _Iterator(decltype(_M_current) __current)
4748 : _M_current(std::move(__current))
4749 { }
4750
4751 static auto
4752 _S_iter_concept()
4753 {
4754 if constexpr (__detail::__all_random_access<_Const, _Vs...>)
4755 return random_access_iterator_tag{};
4756 else if constexpr (__detail::__all_bidirectional<_Const, _Vs...>)
4757 return bidirectional_iterator_tag{};
4758 else if constexpr (__detail::__all_forward<_Const, _Vs...>)
4759 return forward_iterator_tag{};
4760 else
4761 return input_iterator_tag{};
4762 }
4763
4764#ifndef _GLIBCXX_CLANG // LLVM-61763 workaround
4765 template<move_constructible _Fp, input_range... _Ws>
4766 requires (view<_Ws> && ...) && (sizeof...(_Ws) > 0) && is_object_v<_Fp>
4767 && regular_invocable<_Fp&, range_reference_t<_Ws>...>
4768 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Ws>...>>
4769 friend class zip_transform_view;
4770#endif
4771
4772 public:
4773 // iterator_category defined in __zip_view_iter_cat
4774 using iterator_concept = decltype(_S_iter_concept());
4775 using value_type
4776 = tuple<range_value_t<__detail::__maybe_const_t<_Const, _Vs>>...>;
4777 using difference_type
4778 = common_type_t<range_difference_t<__detail::__maybe_const_t<_Const, _Vs>>...>;
4779
4780 _Iterator() = default;
4781
4782 constexpr
4783 _Iterator(_Iterator<!_Const> __i)
4784 requires _Const
4785 && (convertible_to<iterator_t<_Vs>,
4786 iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4787 : _M_current(std::move(__i._M_current))
4788 { }
4789
4790 constexpr auto
4791 operator*() const
4792 {
4793 auto __f = [](auto& __i) -> decltype(auto) {
4794 return *__i;
4795 };
4796 return __detail::__tuple_transform(__f, _M_current);
4797 }
4798
4799 constexpr _Iterator&
4800 operator++()
4801 {
4802 __detail::__tuple_for_each([](auto& __i) { ++__i; }, _M_current);
4803 return *this;
4804 }
4805
4806 constexpr void
4807 operator++(int)
4808 { ++*this; }
4809
4810 constexpr _Iterator
4811 operator++(int)
4812 requires __detail::__all_forward<_Const, _Vs...>
4813 {
4814 auto __tmp = *this;
4815 ++*this;
4816 return __tmp;
4817 }
4818
4819 constexpr _Iterator&
4820 operator--()
4821 requires __detail::__all_bidirectional<_Const, _Vs...>
4822 {
4823 __detail::__tuple_for_each([](auto& __i) { --__i; }, _M_current);
4824 return *this;
4825 }
4826
4827 constexpr _Iterator
4828 operator--(int)
4829 requires __detail::__all_bidirectional<_Const, _Vs...>
4830 {
4831 auto __tmp = *this;
4832 --*this;
4833 return __tmp;
4834 }
4835
4836 constexpr _Iterator&
4837 operator+=(difference_type __x)
4838 requires __detail::__all_random_access<_Const, _Vs...>
4839 {
4840 auto __f = [&]<typename _It>(_It& __i) {
4841 __i += iter_difference_t<_It>(__x);
4842 };
4843 __detail::__tuple_for_each(__f, _M_current);
4844 return *this;
4845 }
4846
4847 constexpr _Iterator&
4848 operator-=(difference_type __x)
4849 requires __detail::__all_random_access<_Const, _Vs...>
4850 {
4851 auto __f = [&]<typename _It>(_It& __i) {
4852 __i -= iter_difference_t<_It>(__x);
4853 };
4854 __detail::__tuple_for_each(__f, _M_current);
4855 return *this;
4856 }
4857
4858 constexpr auto
4859 operator[](difference_type __n) const
4860 requires __detail::__all_random_access<_Const, _Vs...>
4861 {
4862 auto __f = [&]<typename _It>(_It& __i) -> decltype(auto) {
4863 return __i[iter_difference_t<_It>(__n)];
4864 };
4865 return __detail::__tuple_transform(__f, _M_current);
4866 }
4867
4868 friend constexpr bool
4869 operator==(const _Iterator& __x, const _Iterator& __y)
4870 requires (equality_comparable<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4871 {
4872 if constexpr (__detail::__all_bidirectional<_Const, _Vs...>)
4873 return __x._M_current == __y._M_current;
4874 else
4875 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4876 return ((std::get<_Is>(__x._M_current) == std::get<_Is>(__y._M_current)) || ...);
4877 }(make_index_sequence<sizeof...(_Vs)>{});
4878 }
4879
4880 friend constexpr auto
4881 operator<=>(const _Iterator& __x, const _Iterator& __y)
4882 requires __detail::__all_random_access<_Const, _Vs...>
4883 { return __x._M_current <=> __y._M_current; }
4884
4885 friend constexpr _Iterator
4886 operator+(const _Iterator& __i, difference_type __n)
4887 requires __detail::__all_random_access<_Const, _Vs...>
4888 {
4889 auto __r = __i;
4890 __r += __n;
4891 return __r;
4892 }
4893
4894 friend constexpr _Iterator
4895 operator+(difference_type __n, const _Iterator& __i)
4896 requires __detail::__all_random_access<_Const, _Vs...>
4897 {
4898 auto __r = __i;
4899 __r += __n;
4900 return __r;
4901 }
4902
4903 friend constexpr _Iterator
4904 operator-(const _Iterator& __i, difference_type __n)
4905 requires __detail::__all_random_access<_Const, _Vs...>
4906 {
4907 auto __r = __i;
4908 __r -= __n;
4909 return __r;
4910 }
4911
4912 friend constexpr difference_type
4913 operator-(const _Iterator& __x, const _Iterator& __y)
4914 requires (sized_sentinel_for<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>,
4915 iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4916 {
4917 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4918 return ranges::min({difference_type(std::get<_Is>(__x._M_current)
4919 - std::get<_Is>(__y._M_current))...},
4920 ranges::less{},
4921 [](difference_type __i) {
4922 return __detail::__to_unsigned_like(__i < 0 ? -__i : __i);
4923 });
4924 }(make_index_sequence<sizeof...(_Vs)>{});
4925 }
4926
4927 friend constexpr auto
4928 iter_move(const _Iterator& __i)
4929 { return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
4930
4931 friend constexpr void
4932 iter_swap(const _Iterator& __l, const _Iterator& __r)
4933 requires (indirectly_swappable<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4934 {
4935 [&]<size_t... _Is>(index_sequence<_Is...>) {
4936 (ranges::iter_swap(std::get<_Is>(__l._M_current), std::get<_Is>(__r._M_current)), ...);
4937 }(make_index_sequence<sizeof...(_Vs)>{});
4938 }
4939
4940 friend class zip_view;
4941 };
4942
4943 template<input_range... _Vs>
4944 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0)
4945 template<bool _Const>
4946 class zip_view<_Vs...>::_Sentinel
4947 {
4948 tuple<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>...> _M_end;
4949
4950 constexpr explicit
4951 _Sentinel(decltype(_M_end) __end)
4952 : _M_end(__end)
4953 { }
4954
4955 friend class zip_view;
4956
4957 public:
4958 _Sentinel() = default;
4959
4960 constexpr
4961 _Sentinel(_Sentinel<!_Const> __i)
4962 requires _Const
4963 && (convertible_to<sentinel_t<_Vs>,
4964 sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4965 : _M_end(std::move(__i._M_end))
4966 { }
4967
4968 template<bool _OtherConst>
4969 requires (sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
4970 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
4971 friend constexpr bool
4972 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
4973 {
4974 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4975 return ((std::get<_Is>(__x._M_current) == std::get<_Is>(__y._M_end)) || ...);
4976 }(make_index_sequence<sizeof...(_Vs)>{});
4977 }
4978
4979 template<bool _OtherConst>
4980 requires (sized_sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
4981 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
4982 friend constexpr auto
4983 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
4984 {
4985 using _Ret
4986 = common_type_t<range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vs>>...>;
4987 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4988 return ranges::min({_Ret(std::get<_Is>(__x._M_current) - std::get<_Is>(__y._M_end))...},
4989 ranges::less{},
4990 [](_Ret __i) {
4991 return __detail::__to_unsigned_like(__i < 0 ? -__i : __i);
4992 });
4993 }(make_index_sequence<sizeof...(_Vs)>{});
4994 }
4995
4996 template<bool _OtherConst>
4997 requires (sized_sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
4998 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
4999 friend constexpr auto
5000 operator-(const _Sentinel& __y, const _Iterator<_OtherConst>& __x)
5001 { return -(__x - __y); }
5002 };
5003
5004 namespace views
5005 {
5006 namespace __detail
5007 {
5008 template<typename... _Ts>
5009 concept __can_zip_view
5010 = requires { zip_view<all_t<_Ts>...>(std::declval<_Ts>()...); };
5011 }
5012
5013 struct _Zip
5014 {
5015 template<typename... _Ts>
5016 requires (sizeof...(_Ts) == 0 || __detail::__can_zip_view<_Ts...>)
5017 constexpr auto
5018 operator() [[nodiscard]] (_Ts&&... __ts) const
5019 {
5020 if constexpr (sizeof...(_Ts) == 0)
5021 return views::empty<tuple<>>;
5022 else
5023 return zip_view<all_t<_Ts>...>(std::forward<_Ts>(__ts)...);
5024 }
5025 };
5026
5027 inline constexpr _Zip zip;
5028 }
5029
5030 namespace __detail
5031 {
5032 template<typename _Range, bool _Const>
5033 using __range_iter_cat
5034 = typename iterator_traits<iterator_t<__maybe_const_t<_Const, _Range>>>::iterator_category;
5035 }
5036
5037 template<move_constructible _Fp, input_range... _Vs>
5038 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && is_object_v<_Fp>
5039 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
5040 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
5041 class zip_transform_view : public view_interface<zip_transform_view<_Fp, _Vs...>>
5042 {
5043 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
5044 zip_view<_Vs...> _M_zip;
5045
5046 using _InnerView = zip_view<_Vs...>;
5047
5048 template<bool _Const>
5049 using __ziperator = iterator_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5050
5051 template<bool _Const>
5052 using __zentinel = sentinel_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5053
5054 template<bool _Const>
5055 using _Base = __detail::__maybe_const_t<_Const, _InnerView>;
5056
5057 template<bool _Const>
5058 struct __iter_cat
5059 { };
5060
5061 template<bool _Const>
5062 requires forward_range<_Base<_Const>>
5063 struct __iter_cat<_Const>
5064 {
5065 private:
5066 static auto
5067 _S_iter_cat()
5068 {
5069 using __detail::__maybe_const_t;
5070 using __detail::__range_iter_cat;
5071 using _Res = invoke_result_t<__maybe_const_t<_Const, _Fp>&,
5072 range_reference_t<__maybe_const_t<_Const, _Vs>>...>;
5073 // _GLIBCXX_RESOLVE_LIB_DEFECTS
5074 // 3798. Rvalue reference and iterator_category
5075 if constexpr (!is_reference_v<_Res>)
5076 return input_iterator_tag{};
5077 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
5078 random_access_iterator_tag> && ...))
5079 return random_access_iterator_tag{};
5080 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
5081 bidirectional_iterator_tag> && ...))
5082 return bidirectional_iterator_tag{};
5083 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
5084 forward_iterator_tag> && ...))
5085 return forward_iterator_tag{};
5086 else
5087 return input_iterator_tag{};
5088 }
5089 public:
5090 using iterator_category = decltype(_S_iter_cat());
5091 };
5092
5093 template<bool> class _Iterator;
5094 template<bool> class _Sentinel;
5095
5096 public:
5097 zip_transform_view() = default;
5098
5099 constexpr explicit
5100 zip_transform_view(_Fp __fun, _Vs... __views)
5101 : _M_fun(std::move(__fun)), _M_zip(std::move(__views)...)
5102 { }
5103
5104 constexpr auto
5105 begin()
5106 { return _Iterator<false>(*this, _M_zip.begin()); }
5107
5108 constexpr auto
5109 begin() const
5110 requires range<const _InnerView>
5111 && regular_invocable<const _Fp&, range_reference_t<const _Vs>...>
5112 { return _Iterator<true>(*this, _M_zip.begin()); }
5113
5114 constexpr auto
5115 end()
5116 {
5117 if constexpr (common_range<_InnerView>)
5118 return _Iterator<false>(*this, _M_zip.end());
5119 else
5120 return _Sentinel<false>(_M_zip.end());
5121 }
5122
5123 constexpr auto
5124 end() const
5125 requires range<const _InnerView>
5126 && regular_invocable<const _Fp&, range_reference_t<const _Vs>...>
5127 {
5128 if constexpr (common_range<const _InnerView>)
5129 return _Iterator<true>(*this, _M_zip.end());
5130 else
5131 return _Sentinel<true>(_M_zip.end());
5132 }
5133
5134 constexpr auto
5135 size() requires sized_range<_InnerView>
5136 { return _M_zip.size(); }
5137
5138 constexpr auto
5139 size() const requires sized_range<const _InnerView>
5140 { return _M_zip.size(); }
5141 };
5142
5143 template<class _Fp, class... Rs>
5144 zip_transform_view(_Fp, Rs&&...) -> zip_transform_view<_Fp, views::all_t<Rs>...>;
5145
5146 template<move_constructible _Fp, input_range... _Vs>
5147 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && is_object_v<_Fp>
5148 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
5149 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
5150 template<bool _Const>
5151 class zip_transform_view<_Fp, _Vs...>::_Iterator : public __iter_cat<_Const>
5152 {
5153 using _Parent = __detail::__maybe_const_t<_Const, zip_transform_view>;
5154
5155 _Parent* _M_parent = nullptr;
5156 __ziperator<_Const> _M_inner;
5157
5158 constexpr
5159 _Iterator(_Parent& __parent, __ziperator<_Const> __inner)
5160 : _M_parent(std::__addressof(__parent)), _M_inner(std::move(__inner))
5161 { }
5162
5163 friend class zip_transform_view;
5164
5165 public:
5166 // iterator_category defined in zip_transform_view::__iter_cat
5167 using iterator_concept = typename __ziperator<_Const>::iterator_concept;
5168 using value_type
5169 = remove_cvref_t<invoke_result_t<__detail::__maybe_const_t<_Const, _Fp>&,
5170 range_reference_t<__detail::__maybe_const_t<_Const, _Vs>>...>>;
5171 using difference_type = range_difference_t<_Base<_Const>>;
5172
5173 _Iterator() = default;
5174
5175 constexpr
5176 _Iterator(_Iterator<!_Const> __i)
5177 requires _Const && convertible_to<__ziperator<false>, __ziperator<_Const>>
5178 : _M_parent(__i._M_parent), _M_inner(std::move(__i._M_inner))
5179 { }
5180
5181 constexpr decltype(auto)
5182 operator*() const
5183 {
5184 return std::apply([&](const auto&... __iters) -> decltype(auto) {
5185 return std::__invoke(*_M_parent->_M_fun, *__iters...);
5186 }, _M_inner._M_current);
5187 }
5188
5189 constexpr _Iterator&
5190 operator++()
5191 {
5192 ++_M_inner;
5193 return *this;
5194 }
5195
5196 constexpr void
5197 operator++(int)
5198 { ++*this; }
5199
5200 constexpr _Iterator
5201 operator++(int) requires forward_range<_Base<_Const>>
5202 {
5203 auto __tmp = *this;
5204 ++*this;
5205 return __tmp;
5206 }
5207
5208 constexpr _Iterator&
5209 operator--() requires bidirectional_range<_Base<_Const>>
5210 {
5211 --_M_inner;
5212 return *this;
5213 }
5214
5215 constexpr _Iterator
5216 operator--(int) requires bidirectional_range<_Base<_Const>>
5217 {
5218 auto __tmp = *this;
5219 --*this;
5220 return __tmp;
5221 }
5222
5223 constexpr _Iterator&
5224 operator+=(difference_type __x) requires random_access_range<_Base<_Const>>
5225 {
5226 _M_inner += __x;
5227 return *this;
5228 }
5229
5230 constexpr _Iterator&
5231 operator-=(difference_type __x) requires random_access_range<_Base<_Const>>
5232 {
5233 _M_inner -= __x;
5234 return *this;
5235 }
5236
5237 constexpr decltype(auto)
5238 operator[](difference_type __n) const requires random_access_range<_Base<_Const>>
5239 {
5240 return std::apply([&]<typename... _Is>(const _Is&... __iters) -> decltype(auto) {
5241 return std::__invoke(*_M_parent->_M_fun, __iters[iter_difference_t<_Is>(__n)]...);
5242 }, _M_inner._M_current);
5243 }
5244
5245 friend constexpr bool
5246 operator==(const _Iterator& __x, const _Iterator& __y)
5247 requires equality_comparable<__ziperator<_Const>>
5248 { return __x._M_inner == __y._M_inner; }
5249
5250 friend constexpr auto
5251 operator<=>(const _Iterator& __x, const _Iterator& __y)
5252 requires random_access_range<_Base<_Const>>
5253 { return __x._M_inner <=> __y._M_inner; }
5254
5255 friend constexpr _Iterator
5256 operator+(const _Iterator& __i, difference_type __n)
5257 requires random_access_range<_Base<_Const>>
5258 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5259
5260 friend constexpr _Iterator
5261 operator+(difference_type __n, const _Iterator& __i)
5262 requires random_access_range<_Base<_Const>>
5263 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5264
5265 friend constexpr _Iterator
5266 operator-(const _Iterator& __i, difference_type __n)
5267 requires random_access_range<_Base<_Const>>
5268 { return _Iterator(*__i._M_parent, __i._M_inner - __n); }
5269
5270 friend constexpr difference_type
5271 operator-(const _Iterator& __x, const _Iterator& __y)
5272 requires sized_sentinel_for<__ziperator<_Const>, __ziperator<_Const>>
5273 { return __x._M_inner - __y._M_inner; }
5274 };
5275
5276 template<move_constructible _Fp, input_range... _Vs>
5277 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && is_object_v<_Fp>
5278 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
5279 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
5280 template<bool _Const>
5281 class zip_transform_view<_Fp, _Vs...>::_Sentinel
5282 {
5283 __zentinel<_Const> _M_inner;
5284
5285 constexpr explicit
5286 _Sentinel(__zentinel<_Const> __inner)
5287 : _M_inner(__inner)
5288 { }
5289
5290 friend class zip_transform_view;
5291
5292 public:
5293 _Sentinel() = default;
5294
5295 constexpr
5296 _Sentinel(_Sentinel<!_Const> __i)
5297 requires _Const && convertible_to<__zentinel<false>, __zentinel<_Const>>
5298 : _M_inner(std::move(__i._M_inner))
5299 { }
5300
5301 template<bool _OtherConst>
5302 requires sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5303 friend constexpr bool
5304 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5305 { return __x._M_inner == __y._M_inner; }
5306
5307 template<bool _OtherConst>
5308 requires sized_sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5309 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5310 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5311 { return __x._M_inner - __y._M_inner; }
5312
5313 template<bool _OtherConst>
5314 requires sized_sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5315 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5316 operator-(const _Sentinel& __x, const _Iterator<_OtherConst>& __y)
5317 { return __x._M_inner - __y._M_inner; }
5318 };
5319
5320 namespace views
5321 {
5322 namespace __detail
5323 {
5324 template<typename _Fp, typename... _Ts>
5325 concept __can_zip_transform_view
5326 = requires { zip_transform_view(std::declval<_Fp>(), std::declval<_Ts>()...); };
5327 }
5328
5329 struct _ZipTransform
5330 {
5331 template<typename _Fp, typename... _Ts>
5332 requires (sizeof...(_Ts) == 0) || __detail::__can_zip_transform_view<_Fp, _Ts...>
5333 constexpr auto
5334 operator() [[nodiscard]] (_Fp&& __f, _Ts&&... __ts) const
5335 {
5336 if constexpr (sizeof...(_Ts) == 0)
5337 return views::empty<decay_t<invoke_result_t<decay_t<_Fp>&>>>;
5338 else
5339 return zip_transform_view(std::forward<_Fp>(__f), std::forward<_Ts>(__ts)...);
5340 }
5341 };
5342
5343 inline constexpr _ZipTransform zip_transform;
5344 }
5345
5346 template<forward_range _Vp, size_t _Nm>
5347 requires view<_Vp> && (_Nm > 0)
5348 class adjacent_view : public view_interface<adjacent_view<_Vp, _Nm>>
5349 {
5350 _Vp _M_base = _Vp();
5351
5352 template<bool> class _Iterator;
5353 template<bool> class _Sentinel;
5354
5355 struct __as_sentinel
5356 { };
5357
5358 public:
5359 adjacent_view() requires default_initializable<_Vp> = default;
5360
5361 constexpr explicit
5362 adjacent_view(_Vp __base)
5363 : _M_base(std::move(__base))
5364 { }
5365
5366 // _GLIBCXX_RESOLVE_LIB_DEFECTS
5367 // 3848. adjacent_view, adjacent_transform_view and slide_view missing base accessor
5368 constexpr _Vp
5369 base() const & requires copy_constructible<_Vp>
5370 { return _M_base; }
5371
5372 constexpr _Vp
5373 base() &&
5374 { return std::move(_M_base); }
5375
5376 constexpr auto
5377 begin() requires (!__detail::__simple_view<_Vp>)
5378 { return _Iterator<false>(ranges::begin(_M_base), ranges::end(_M_base)); }
5379
5380 constexpr auto
5381 begin() const requires range<const _Vp>
5382 { return _Iterator<true>(ranges::begin(_M_base), ranges::end(_M_base)); }
5383
5384 constexpr auto
5385 end() requires (!__detail::__simple_view<_Vp>)
5386 {
5387 if constexpr (common_range<_Vp>)
5388 return _Iterator<false>(__as_sentinel{}, ranges::begin(_M_base), ranges::end(_M_base));
5389 else
5390 return _Sentinel<false>(ranges::end(_M_base));
5391 }
5392
5393 constexpr auto
5394 end() const requires range<const _Vp>
5395 {
5396 if constexpr (common_range<const _Vp>)
5397 return _Iterator<true>(__as_sentinel{}, ranges::begin(_M_base), ranges::end(_M_base));
5398 else
5399 return _Sentinel<true>(ranges::end(_M_base));
5400 }
5401
5402 constexpr auto
5403 size() requires sized_range<_Vp>
5404 {
5405 using _ST = decltype(ranges::size(_M_base));
5406 using _CT = common_type_t<_ST, size_t>;
5407 auto __sz = static_cast<_CT>(ranges::size(_M_base));
5408 __sz -= std::min<_CT>(__sz, _Nm - 1);
5409 return static_cast<_ST>(__sz);
5410 }
5411
5412 constexpr auto
5413 size() const requires sized_range<const _Vp>
5414 {
5415 using _ST = decltype(ranges::size(_M_base));
5416 using _CT = common_type_t<_ST, size_t>;
5417 auto __sz = static_cast<_CT>(ranges::size(_M_base));
5418 __sz -= std::min<_CT>(__sz, _Nm - 1);
5419 return static_cast<_ST>(__sz);
5420 }
5421 };
5422
5423 template<typename _Vp, size_t _Nm>
5424 inline constexpr bool enable_borrowed_range<adjacent_view<_Vp, _Nm>>
5425 = enable_borrowed_range<_Vp>;
5426
5427 namespace __detail
5428 {
5429 // Yields tuple<_Tp, ..., _Tp> with _Nm elements.
5430 template<typename _Tp, size_t _Nm>
5431 using __repeated_tuple = decltype(std::tuple_cat(std::declval<array<_Tp, _Nm>>()));
5432
5433 // For a functor F that is callable with N arguments, the expression
5434 // declval<__unarize<F, N>>(x) is equivalent to declval<F>(x, ..., x).
5435 template<typename _Fp, size_t _Nm>
5436 struct __unarize
5437 {
5438 template<typename... _Ts>
5439 static invoke_result_t<_Fp, _Ts...>
5440 __tuple_apply(const tuple<_Ts...>&); // not defined
5441
5442 template<typename _Tp>
5443 decltype(__tuple_apply(std::declval<__repeated_tuple<_Tp, _Nm>>()))
5444 operator()(_Tp&&); // not defined
5445 };
5446 }
5447
5448 template<forward_range _Vp, size_t _Nm>
5449 requires view<_Vp> && (_Nm > 0)
5450 template<bool _Const>
5451 class adjacent_view<_Vp, _Nm>::_Iterator
5452 {
5453#ifdef _GLIBCXX_CLANG // LLVM-61763 workaround
5454 public:
5455#endif
5456 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5457 array<iterator_t<_Base>, _Nm> _M_current = array<iterator_t<_Base>, _Nm>();
5458
5459 constexpr
5460 _Iterator(iterator_t<_Base> __first, sentinel_t<_Base> __last)
5461 {
5462 for (auto& __i : _M_current)
5463 {
5464 __i = __first;
5465 ranges::advance(__first, 1, __last);
5466 }
5467 }
5468
5469 constexpr
5470 _Iterator(__as_sentinel, iterator_t<_Base> __first, iterator_t<_Base> __last)
5471 {
5472 if constexpr (!bidirectional_range<_Base>)
5473 for (auto& __it : _M_current)
5474 __it = __last;
5475 else
5476 for (size_t __i = 0; __i < _Nm; ++__i)
5477 {
5478 _M_current[_Nm - 1 - __i] = __last;
5479 ranges::advance(__last, -1, __first);
5480 }
5481 }
5482
5483 static auto
5484 _S_iter_concept()
5485 {
5486 if constexpr (random_access_range<_Base>)
5487 return random_access_iterator_tag{};
5488 else if constexpr (bidirectional_range<_Base>)
5489 return bidirectional_iterator_tag{};
5490 else
5491 return forward_iterator_tag{};
5492 }
5493
5494 friend class adjacent_view;
5495
5496#ifndef _GLIBCXX_CLANG // LLVM-61763 workaround
5497 template<forward_range _Wp, move_constructible _Fp, size_t _Mm>
5498 requires view<_Wp> && (_Mm > 0) && is_object_v<_Fp>
5499 && regular_invocable<__detail::__unarize<_Fp&, _Mm>, range_reference_t<_Wp>>
5500 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Mm>,
5501 range_reference_t<_Wp>>>
5502 friend class adjacent_transform_view;
5503#endif
5504
5505 public:
5506 using iterator_category = input_iterator_tag;
5507 using iterator_concept = decltype(_S_iter_concept());
5508 using value_type = conditional_t<_Nm == 2,
5509 pair<range_value_t<_Base>, range_value_t<_Base>>,
5510 __detail::__repeated_tuple<range_value_t<_Base>, _Nm>>;
5511 using difference_type = range_difference_t<_Base>;
5512
5513 _Iterator() = default;
5514
5515 constexpr
5516 _Iterator(_Iterator<!_Const> __i)
5517 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
5518 {
5519 for (size_t __j = 0; __j < _Nm; ++__j)
5520 _M_current[__j] = std::move(__i._M_current[__j]);
5521 }
5522
5523 constexpr auto
5524 operator*() const
5525 {
5526 auto __f = [](auto& __i) -> decltype(auto) { return *__i; };
5527 return __detail::__tuple_transform(__f, _M_current);
5528 }
5529
5530 constexpr _Iterator&
5531 operator++()
5532 {
5533 for (auto& __i : _M_current)
5534 ++__i;
5535 return *this;
5536 }
5537
5538 constexpr _Iterator
5539 operator++(int)
5540 {
5541 auto __tmp = *this;
5542 ++*this;
5543 return __tmp;
5544 }
5545
5546 constexpr _Iterator&
5547 operator--() requires bidirectional_range<_Base>
5548 {
5549 for (auto& __i : _M_current)
5550 --__i;
5551 return *this;
5552 }
5553
5554 constexpr _Iterator
5555 operator--(int) requires bidirectional_range<_Base>
5556 {
5557 auto __tmp = *this;
5558 --*this;
5559 return __tmp;
5560 }
5561
5562 constexpr _Iterator&
5563 operator+=(difference_type __x)
5564 requires random_access_range<_Base>
5565 {
5566 for (auto& __i : _M_current)
5567 __i += __x;
5568 return *this;
5569 }
5570
5571 constexpr _Iterator&
5572 operator-=(difference_type __x)
5573 requires random_access_range<_Base>
5574 {
5575 for (auto& __i : _M_current)
5576 __i -= __x;
5577 return *this;
5578 }
5579
5580 constexpr auto
5581 operator[](difference_type __n) const
5582 requires random_access_range<_Base>
5583 {
5584 auto __f = [&](auto& __i) -> decltype(auto) { return __i[__n]; };
5585 return __detail::__tuple_transform(__f, _M_current);
5586 }
5587
5588 friend constexpr bool
5589 operator==(const _Iterator& __x, const _Iterator& __y)
5590 { return __x._M_current.back() == __y._M_current.back(); }
5591
5592 friend constexpr bool
5593 operator<(const _Iterator& __x, const _Iterator& __y)
5594 requires random_access_range<_Base>
5595 { return __x._M_current.back() < __y._M_current.back(); }
5596
5597 friend constexpr bool
5598 operator>(const _Iterator& __x, const _Iterator& __y)
5599 requires random_access_range<_Base>
5600 { return __y < __x; }
5601
5602 friend constexpr bool
5603 operator<=(const _Iterator& __x, const _Iterator& __y)
5604 requires random_access_range<_Base>
5605 { return !(__y < __x); }
5606
5607 friend constexpr bool
5608 operator>=(const _Iterator& __x, const _Iterator& __y)
5609 requires random_access_range<_Base>
5610 { return !(__x < __y); }
5611
5612 friend constexpr auto
5613 operator<=>(const _Iterator& __x, const _Iterator& __y)
5614 requires random_access_range<_Base>
5615 && three_way_comparable<iterator_t<_Base>>
5616 { return __x._M_current.back() <=> __y._M_current.back(); }
5617
5618 friend constexpr _Iterator
5619 operator+(const _Iterator& __i, difference_type __n)
5620 requires random_access_range<_Base>
5621 {
5622 auto __r = __i;
5623 __r += __n;
5624 return __r;
5625 }
5626
5627 friend constexpr _Iterator
5628 operator+(difference_type __n, const _Iterator& __i)
5629 requires random_access_range<_Base>
5630 {
5631 auto __r = __i;
5632 __r += __n;
5633 return __r;
5634 }
5635
5636 friend constexpr _Iterator
5637 operator-(const _Iterator& __i, difference_type __n)
5638 requires random_access_range<_Base>
5639 {
5640 auto __r = __i;
5641 __r -= __n;
5642 return __r;
5643 }
5644
5645 friend constexpr difference_type
5646 operator-(const _Iterator& __x, const _Iterator& __y)
5647 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
5648 { return __x._M_current.back() - __y._M_current.back(); }
5649
5650 friend constexpr auto
5651 iter_move(const _Iterator& __i)
5652 { return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
5653
5654 friend constexpr void
5655 iter_swap(const _Iterator& __l, const _Iterator& __r)
5656 requires indirectly_swappable<iterator_t<_Base>>
5657 {
5658 for (size_t __i = 0; __i < _Nm; __i++)
5659 ranges::iter_swap(__l._M_current[__i], __r._M_current[__i]);
5660 }
5661 };
5662
5663 template<forward_range _Vp, size_t _Nm>
5664 requires view<_Vp> && (_Nm > 0)
5665 template<bool _Const>
5666 class adjacent_view<_Vp, _Nm>::_Sentinel
5667 {
5668 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5669
5670 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
5671
5672 constexpr explicit
5673 _Sentinel(sentinel_t<_Base> __end)
5674 : _M_end(__end)
5675 { }
5676
5677 friend class adjacent_view;
5678
5679 public:
5680 _Sentinel() = default;
5681
5682 constexpr
5683 _Sentinel(_Sentinel<!_Const> __i)
5684 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
5685 : _M_end(std::move(__i._M_end))
5686 { }
5687
5688 template<bool _OtherConst>
5689 requires sentinel_for<sentinel_t<_Base>,
5690 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5691 friend constexpr bool
5692 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5693 { return __x._M_current.back() == __y._M_end; }
5694
5695 template<bool _OtherConst>
5696 requires sized_sentinel_for<sentinel_t<_Base>,
5697 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5698 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vp>>
5699 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5700 { return __x._M_current.back() - __y._M_end; }
5701
5702 template<bool _OtherConst>
5703 requires sized_sentinel_for<sentinel_t<_Base>,
5704 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5705 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vp>>
5706 operator-(const _Sentinel& __y, const _Iterator<_OtherConst>& __x)
5707 { return __y._M_end - __x._M_current.back(); }
5708 };
5709
5710 namespace views
5711 {
5712 namespace __detail
5713 {
5714 template<size_t _Nm, typename _Range>
5715 concept __can_adjacent_view
5716 = requires { adjacent_view<all_t<_Range>, _Nm>(std::declval<_Range>()); };
5717 }
5718
5719 template<size_t _Nm>
5720 struct _Adjacent : __adaptor::_RangeAdaptorClosure<_Adjacent<_Nm>>
5721 {
5722 template<viewable_range _Range>
5723 requires (_Nm == 0) || __detail::__can_adjacent_view<_Nm, _Range>
5724 constexpr auto
5725 operator() [[nodiscard]] (_Range&& __r) const
5726 {
5727 if constexpr (_Nm == 0)
5728 return views::empty<tuple<>>;
5729 else
5730 return adjacent_view<all_t<_Range>, _Nm>(std::forward<_Range>(__r));
5731 }
5732 };
5733
5734 template<size_t _Nm>
5735 inline constexpr _Adjacent<_Nm> adjacent;
5736
5737 inline constexpr auto pairwise = adjacent<2>;
5738 }
5739
5740 template<forward_range _Vp, move_constructible _Fp, size_t _Nm>
5741 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5742 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5743 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5744 range_reference_t<_Vp>>>
5745 class adjacent_transform_view : public view_interface<adjacent_transform_view<_Vp, _Fp, _Nm>>
5746 {
5747 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
5748 adjacent_view<_Vp, _Nm> _M_inner;
5749
5750 using _InnerView = adjacent_view<_Vp, _Nm>;
5751
5752 template<bool _Const>
5753 using _InnerIter = iterator_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5754
5755 template<bool _Const>
5756 using _InnerSent = sentinel_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5757
5758 template<bool> class _Iterator;
5759 template<bool> class _Sentinel;
5760
5761 public:
5762 adjacent_transform_view() = default;
5763
5764 constexpr explicit
5765 adjacent_transform_view(_Vp __base, _Fp __fun)
5766 : _M_fun(std::move(__fun)), _M_inner(std::move(__base))
5767 { }
5768
5769 // _GLIBCXX_RESOLVE_LIB_DEFECTS
5770 // 3848. adjacent_view, adjacent_transform_view and slide_view missing base accessor
5771 // 3947. Unexpected constraints on adjacent_transform_view::base()
5772 constexpr _Vp
5773 base() const & requires copy_constructible<_Vp>
5774 { return _M_inner.base(); }
5775
5776 constexpr _Vp
5777 base() &&
5778 { return std::move(_M_inner.base()); }
5779
5780 constexpr auto
5781 begin()
5782 { return _Iterator<false>(*this, _M_inner.begin()); }
5783
5784 constexpr auto
5785 begin() const
5786 requires range<const _InnerView>
5787 && regular_invocable<__detail::__unarize<const _Fp&, _Nm>,
5788 range_reference_t<const _Vp>>
5789 { return _Iterator<true>(*this, _M_inner.begin()); }
5790
5791 constexpr auto
5792 end()
5793 {
5794 if constexpr (common_range<_InnerView>)
5795 return _Iterator<false>(*this, _M_inner.end());
5796 else
5797 return _Sentinel<false>(_M_inner.end());
5798 }
5799
5800 constexpr auto
5801 end() const
5802 requires range<const _InnerView>
5803 && regular_invocable<__detail::__unarize<const _Fp&, _Nm>,
5804 range_reference_t<const _Vp>>
5805 {
5806 if constexpr (common_range<const _InnerView>)
5807 return _Iterator<true>(*this, _M_inner.end());
5808 else
5809 return _Sentinel<true>(_M_inner.end());
5810 }
5811
5812 constexpr auto
5813 size() requires sized_range<_InnerView>
5814 { return _M_inner.size(); }
5815
5816 constexpr auto
5817 size() const requires sized_range<const _InnerView>
5818 { return _M_inner.size(); }
5819 };
5820
5821 template<forward_range _Vp, move_constructible _Fp, size_t _Nm>
5822 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5823 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5824 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5825 range_reference_t<_Vp>>>
5826 template<bool _Const>
5827 class adjacent_transform_view<_Vp, _Fp, _Nm>::_Iterator
5828 {
5829 using _Parent = __detail::__maybe_const_t<_Const, adjacent_transform_view>;
5830 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5831
5832 _Parent* _M_parent = nullptr;
5833 _InnerIter<_Const> _M_inner;
5834
5835 constexpr
5836 _Iterator(_Parent& __parent, _InnerIter<_Const> __inner)
5837 : _M_parent(std::__addressof(__parent)), _M_inner(std::move(__inner))
5838 { }
5839
5840 static auto
5841 _S_iter_cat()
5842 {
5843 using __detail::__maybe_const_t;
5844 using __detail::__unarize;
5845 using _Res = invoke_result_t<__unarize<__maybe_const_t<_Const, _Fp>&, _Nm>,
5846 range_reference_t<_Base>>;
5847 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
5848 // _GLIBCXX_RESOLVE_LIB_DEFECTS
5849 // 3798. Rvalue reference and iterator_category
5850 if constexpr (!is_reference_v<_Res>)
5851 return input_iterator_tag{};
5852 else if constexpr (derived_from<_Cat, random_access_iterator_tag>)
5853 return random_access_iterator_tag{};
5854 else if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
5855 return bidirectional_iterator_tag{};
5856 else if constexpr (derived_from<_Cat, forward_iterator_tag>)
5857 return forward_iterator_tag{};
5858 else
5859 return input_iterator_tag{};
5860 }
5861
5862 friend class adjacent_transform_view;
5863
5864 public:
5865 using iterator_category = decltype(_S_iter_cat());
5866 using iterator_concept = typename _InnerIter<_Const>::iterator_concept;
5867 using value_type
5868 = remove_cvref_t<invoke_result_t
5869 <__detail::__unarize<__detail::__maybe_const_t<_Const, _Fp>&, _Nm>,
5870 range_reference_t<_Base>>>;
5871 using difference_type = range_difference_t<_Base>;
5872
5873 _Iterator() = default;
5874
5875 constexpr
5876 _Iterator(_Iterator<!_Const> __i)
5877 requires _Const && convertible_to<_InnerIter<false>, _InnerIter<_Const>>
5878 : _M_parent(__i._M_parent), _M_inner(std::move(__i._M_inner))
5879 { }
5880
5881 constexpr decltype(auto)
5882 operator*() const
5883 {
5884 return std::apply([&](const auto&... __iters) -> decltype(auto) {
5885 return std::__invoke(*_M_parent->_M_fun, *__iters...);
5886 }, _M_inner._M_current);
5887 }
5888
5889 constexpr _Iterator&
5890 operator++()
5891 {
5892 ++_M_inner;
5893 return *this;
5894 }
5895
5896 constexpr _Iterator
5897 operator++(int)
5898 {
5899 auto __tmp = *this;
5900 ++*this;
5901 return __tmp;
5902 }
5903
5904 constexpr _Iterator&
5905 operator--() requires bidirectional_range<_Base>
5906 {
5907 --_M_inner;
5908 return *this;
5909 }
5910
5911 constexpr _Iterator
5912 operator--(int) requires bidirectional_range<_Base>
5913 {
5914 auto __tmp = *this;
5915 --*this;
5916 return __tmp;
5917 }
5918
5919 constexpr _Iterator&
5920 operator+=(difference_type __x) requires random_access_range<_Base>
5921 {
5922 _M_inner += __x;
5923 return *this;
5924 }
5925
5926 constexpr _Iterator&
5927 operator-=(difference_type __x) requires random_access_range<_Base>
5928 {
5929 _M_inner -= __x;
5930 return *this;
5931 }
5932
5933 constexpr decltype(auto)
5934 operator[](difference_type __n) const requires random_access_range<_Base>
5935 {
5936 return std::apply([&](const auto&... __iters) -> decltype(auto) {
5937 return std::__invoke(*_M_parent->_M_fun, __iters[__n]...);
5938 }, _M_inner._M_current);
5939 }
5940
5941 friend constexpr bool
5942 operator==(const _Iterator& __x, const _Iterator& __y)
5943 { return __x._M_inner == __y._M_inner; }
5944
5945 friend constexpr bool
5946 operator<(const _Iterator& __x, const _Iterator& __y)
5947 requires random_access_range<_Base>
5948 { return __x._M_inner < __y._M_inner; }
5949
5950 friend constexpr bool
5951 operator>(const _Iterator& __x, const _Iterator& __y)
5952 requires random_access_range<_Base>
5953 { return __x._M_inner > __y._M_inner; }
5954
5955 friend constexpr bool
5956 operator<=(const _Iterator& __x, const _Iterator& __y)
5957 requires random_access_range<_Base>
5958 { return __x._M_inner <= __y._M_inner; }
5959
5960 friend constexpr bool
5961 operator>=(const _Iterator& __x, const _Iterator& __y)
5962 requires random_access_range<_Base>
5963 { return __x._M_inner >= __y._M_inner; }
5964
5965 friend constexpr auto
5966 operator<=>(const _Iterator& __x, const _Iterator& __y)
5967 requires random_access_range<_Base> &&
5968 three_way_comparable<_InnerIter<_Const>>
5969 { return __x._M_inner <=> __y._M_inner; }
5970
5971 friend constexpr _Iterator
5972 operator+(const _Iterator& __i, difference_type __n)
5973 requires random_access_range<_Base>
5974 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5975
5976 friend constexpr _Iterator
5977 operator+(difference_type __n, const _Iterator& __i)
5978 requires random_access_range<_Base>
5979 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5980
5981 friend constexpr _Iterator
5982 operator-(const _Iterator& __i, difference_type __n)
5983 requires random_access_range<_Base>
5984 { return _Iterator(*__i._M_parent, __i._M_inner - __n); }
5985
5986 friend constexpr difference_type
5987 operator-(const _Iterator& __x, const _Iterator& __y)
5988 requires sized_sentinel_for<_InnerIter<_Const>, _InnerIter<_Const>>
5989 { return __x._M_inner - __y._M_inner; }
5990 };
5991
5992 template<forward_range _Vp, move_constructible _Fp, size_t _Nm>
5993 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5994 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5995 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5996 range_reference_t<_Vp>>>
5997 template<bool _Const>
5998 class adjacent_transform_view<_Vp, _Fp, _Nm>::_Sentinel
5999 {
6000 _InnerSent<_Const> _M_inner;
6001
6002 constexpr explicit
6003 _Sentinel(_InnerSent<_Const> __inner)
6004 : _M_inner(__inner)
6005 { }
6006
6007 friend class adjacent_transform_view;
6008
6009 public:
6010 _Sentinel() = default;
6011
6012 constexpr
6013 _Sentinel(_Sentinel<!_Const> __i)
6014 requires _Const && convertible_to<_InnerSent<false>, _InnerSent<_Const>>
6015 : _M_inner(std::move(__i._M_inner))
6016 { }
6017
6018 template<bool _OtherConst>
6019 requires sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
6020 friend constexpr bool
6021 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
6022 { return __x._M_inner == __y._M_inner; }
6023
6024 template<bool _OtherConst>
6025 requires sized_sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
6026 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
6027 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
6028 { return __x._M_inner - __y._M_inner; }
6029
6030 template<bool _OtherConst>
6031 requires sized_sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
6032 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
6033 operator-(const _Sentinel& __x, const _Iterator<_OtherConst>& __y)
6034 { return __x._M_inner - __y._M_inner; }
6035 };
6036
6037 namespace views
6038 {
6039 namespace __detail
6040 {
6041 template<size_t _Nm, typename _Range, typename _Fp>
6042 concept __can_adjacent_transform_view
6043 = requires { adjacent_transform_view<all_t<_Range>, decay_t<_Fp>, _Nm>
6044 (std::declval<_Range>(), std::declval<_Fp>()); };
6045 }
6046
6047 template<size_t _Nm>
6048 struct _AdjacentTransform : __adaptor::_RangeAdaptor<_AdjacentTransform<_Nm>>
6049 {
6050 template<viewable_range _Range, typename _Fp>
6051 requires (_Nm == 0) || __detail::__can_adjacent_transform_view<_Nm, _Range, _Fp>
6052 constexpr auto
6053 operator() [[nodiscard]] (_Range&& __r, _Fp&& __f) const
6054 {
6055 if constexpr (_Nm == 0)
6056 return zip_transform(std::forward<_Fp>(__f));
6057 else
6058 return adjacent_transform_view<all_t<_Range>, decay_t<_Fp>, _Nm>
6059 (std::forward<_Range>(__r), std::forward<_Fp>(__f));
6060 }
6061
6062 using __adaptor::_RangeAdaptor<_AdjacentTransform>::operator();
6063 static constexpr int _S_arity = 2;
6064 static constexpr bool _S_has_simple_extra_args = true;
6065 };
6066
6067 template<size_t _Nm>
6068 inline constexpr _AdjacentTransform<_Nm> adjacent_transform;
6069
6070 inline constexpr auto pairwise_transform = adjacent_transform<2>;
6071 }
6072#endif // __cpp_lib_ranges_zip
6073
6074#ifdef __cpp_lib_ranges_chunk // C++ >= 23
6075 namespace __detail
6076 {
6077 template<typename _Tp>
6078 constexpr _Tp __div_ceil(_Tp __num, _Tp __denom)
6079 {
6080 _Tp __r = __num / __denom;
6081 if (__num % __denom)
6082 ++__r;
6083 return __r;
6084 }
6085 }
6086
6087 template<view _Vp>
6088 requires input_range<_Vp>
6089 class chunk_view : public view_interface<chunk_view<_Vp>>
6090 {
6091 _Vp _M_base;
6092 range_difference_t<_Vp> _M_n;
6093 range_difference_t<_Vp> _M_remainder = 0;
6094 __detail::__non_propagating_cache<iterator_t<_Vp>> _M_current;
6095
6096 class _OuterIter;
6097 class _InnerIter;
6098
6099 public:
6100 constexpr explicit
6101 chunk_view(_Vp __base, range_difference_t<_Vp> __n)
6102 : _M_base(std::move(__base)), _M_n(__n)
6103 { __glibcxx_assert(__n >= 0); }
6104
6105 constexpr _Vp
6106 base() const & requires copy_constructible<_Vp>
6107 { return _M_base; }
6108
6109 constexpr _Vp
6110 base() &&
6111 { return std::move(_M_base); }
6112
6113 constexpr _OuterIter
6114 begin()
6115 {
6116 _M_current = ranges::begin(_M_base);
6117 _M_remainder = _M_n;
6118 return _OuterIter(*this);
6119 }
6120
6121 constexpr default_sentinel_t
6122 end() const noexcept
6123 { return default_sentinel; }
6124
6125 constexpr auto
6126 size() requires sized_range<_Vp>
6127 {
6128 return __detail::__to_unsigned_like(__detail::__div_ceil
6129 (ranges::distance(_M_base), _M_n));
6130 }
6131
6132 constexpr auto
6133 size() const requires sized_range<const _Vp>
6134 {
6135 return __detail::__to_unsigned_like(__detail::__div_ceil
6136 (ranges::distance(_M_base), _M_n));
6137 }
6138 };
6139
6140 template<typename _Range>
6141 chunk_view(_Range&&, range_difference_t<_Range>) -> chunk_view<views::all_t<_Range>>;
6142
6143 template<view _Vp>
6144 requires input_range<_Vp>
6145 class chunk_view<_Vp>::_OuterIter
6146 {
6147 chunk_view* _M_parent;
6148
6149 constexpr explicit
6150 _OuterIter(chunk_view& __parent) noexcept
6151 : _M_parent(std::__addressof(__parent))
6152 { }
6153
6154 friend chunk_view;
6155
6156 public:
6157 using iterator_concept = input_iterator_tag;
6158 using difference_type = range_difference_t<_Vp>;
6159
6160 struct value_type;
6161
6162 _OuterIter(_OuterIter&&) = default;
6163 _OuterIter& operator=(_OuterIter&&) = default;
6164
6165 constexpr value_type
6166 operator*() const
6167 {
6168 __glibcxx_assert(*this != default_sentinel);
6169 return value_type(*_M_parent);
6170 }
6171
6172 constexpr _OuterIter&
6173 operator++()
6174 {
6175 __glibcxx_assert(*this != default_sentinel);
6176 ranges::advance(*_M_parent->_M_current, _M_parent->_M_remainder,
6177 ranges::end(_M_parent->_M_base));
6178 _M_parent->_M_remainder = _M_parent->_M_n;
6179 return *this;
6180 }
6181
6182 constexpr void
6183 operator++(int)
6184 { ++*this; }
6185
6186 friend constexpr bool
6187 operator==(const _OuterIter& __x, default_sentinel_t)
6188 {
6189 return *__x._M_parent->_M_current == ranges::end(__x._M_parent->_M_base)
6190 && __x._M_parent->_M_remainder != 0;
6191 }
6192
6193 friend constexpr difference_type
6194 operator-(default_sentinel_t, const _OuterIter& __x)
6195 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6196 {
6197 const auto __dist = ranges::end(__x._M_parent->_M_base) - *__x._M_parent->_M_current;
6198
6199 if (__dist < __x._M_parent->_M_remainder)
6200 return __dist == 0 ? 0 : 1;
6201
6202 return 1 + __detail::__div_ceil(__dist - __x._M_parent->_M_remainder,
6203 __x._M_parent->_M_n);
6204 }
6205
6206 friend constexpr difference_type
6207 operator-(const _OuterIter& __x, default_sentinel_t __y)
6208 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6209 { return -(__y - __x); }
6210 };
6211
6212 template<view _Vp>
6213 requires input_range<_Vp>
6214 struct chunk_view<_Vp>::_OuterIter::value_type : view_interface<value_type>
6215 {
6216 private:
6217 chunk_view* _M_parent;
6218
6219 constexpr explicit
6220 value_type(chunk_view& __parent) noexcept
6221 : _M_parent(std::__addressof(__parent))
6222 { }
6223
6224 friend _OuterIter;
6225
6226 public:
6227 constexpr _InnerIter
6228 begin() const noexcept
6229 { return _InnerIter(*_M_parent); }
6230
6231 constexpr default_sentinel_t
6232 end() const noexcept
6233 { return default_sentinel; }
6234
6235 constexpr auto
6236 size() const
6237 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6238 {
6239 return __detail::__to_unsigned_like
6240 (ranges::min(_M_parent->_M_remainder,
6241 ranges::end(_M_parent->_M_base) - *_M_parent->_M_current));
6242 }
6243 };
6244
6245 template<view _Vp>
6246 requires input_range<_Vp>
6247 class chunk_view<_Vp>::_InnerIter
6248 {
6249 chunk_view* _M_parent;
6250
6251 constexpr explicit
6252 _InnerIter(chunk_view& __parent) noexcept
6253 : _M_parent(std::__addressof(__parent))
6254 { }
6255
6256 friend _OuterIter::value_type;
6257
6258 public:
6259 using iterator_concept = input_iterator_tag;
6260 using difference_type = range_difference_t<_Vp>;
6261 using value_type = range_value_t<_Vp>;
6262
6263 _InnerIter(_InnerIter&&) = default;
6264 _InnerIter& operator=(_InnerIter&&) = default;
6265
6266 constexpr const iterator_t<_Vp>&
6267 base() const &
6268 { return *_M_parent->_M_current; }
6269
6270 constexpr range_reference_t<_Vp>
6271 operator*() const
6272 {
6273 __glibcxx_assert(*this != default_sentinel);
6274 return **_M_parent->_M_current;
6275 }
6276
6277 constexpr _InnerIter&
6278 operator++()
6279 {
6280 __glibcxx_assert(*this != default_sentinel);
6281 ++*_M_parent->_M_current;
6282 if (*_M_parent->_M_current == ranges::end(_M_parent->_M_base))
6283 _M_parent->_M_remainder = 0;
6284 else
6285 --_M_parent->_M_remainder;
6286 return *this;
6287 }
6288
6289 constexpr void
6290 operator++(int)
6291 { ++*this; }
6292
6293 friend constexpr bool
6294 operator==(const _InnerIter& __x, default_sentinel_t) noexcept
6295 { return __x._M_parent->_M_remainder == 0; }
6296
6297 friend constexpr difference_type
6298 operator-(default_sentinel_t, const _InnerIter& __x)
6299 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6300 {
6301 return ranges::min(__x._M_parent->_M_remainder,
6302 ranges::end(__x._M_parent->_M_base) - *__x._M_parent->_M_current);
6303 }
6304
6305 friend constexpr difference_type
6306 operator-(const _InnerIter& __x, default_sentinel_t __y)
6307 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6308 { return -(__y - __x); }
6309
6310 // _GLIBCXX_RESOLVE_LIB_DEFECTS
6311 // 3851. chunk_view::inner-iterator missing custom iter_move and iter_swap
6312 friend constexpr range_rvalue_reference_t<_Vp>
6313 iter_move(const _InnerIter& __i)
6314 noexcept(noexcept(ranges::iter_move(*__i._M_parent->_M_current)))
6315 { return ranges::iter_move(*__i._M_parent->_M_current); }
6316
6317 friend constexpr void
6318 iter_swap(const _InnerIter& __x, const _InnerIter& __y)
6319 noexcept(noexcept(ranges::iter_swap(*__x._M_parent->_M_current,
6320 *__x._M_parent->_M_current)))
6321 requires indirectly_swappable<iterator_t<_Vp>>
6322 { return ranges::iter_swap(*__x._M_parent->_M_current, *__y._M_parent->_M_current); }
6323 };
6324
6325 template<view _Vp>
6326 requires forward_range<_Vp>
6327 class chunk_view<_Vp> : public view_interface<chunk_view<_Vp>>
6328 {
6329 _Vp _M_base;
6330 range_difference_t<_Vp> _M_n;
6331 template<bool> class _Iterator;
6332
6333 public:
6334 constexpr explicit
6335 chunk_view(_Vp __base, range_difference_t<_Vp> __n)
6336 : _M_base(std::move(__base)), _M_n(__n)
6337 { __glibcxx_assert(__n > 0); }
6338
6339 constexpr _Vp
6340 base() const & requires copy_constructible<_Vp>
6341 { return _M_base; }
6342
6343 constexpr _Vp
6344 base() &&
6345 { return std::move(_M_base); }
6346
6347 constexpr auto
6348 begin() requires (!__detail::__simple_view<_Vp>)
6349 { return _Iterator<false>(this, ranges::begin(_M_base)); }
6350
6351 constexpr auto
6352 begin() const requires forward_range<const _Vp>
6353 { return _Iterator<true>(this, ranges::begin(_M_base)); }
6354
6355 constexpr auto
6356 end() requires (!__detail::__simple_view<_Vp>)
6357 {
6358 if constexpr (common_range<_Vp> && sized_range<_Vp>)
6359 {
6360 auto __missing = (_M_n - ranges::distance(_M_base) % _M_n) % _M_n;
6361 return _Iterator<false>(this, ranges::end(_M_base), __missing);
6362 }
6363 else if constexpr (common_range<_Vp> && !bidirectional_range<_Vp>)
6364 return _Iterator<false>(this, ranges::end(_M_base));
6365 else
6366 return default_sentinel;
6367 }
6368
6369 constexpr auto
6370 end() const requires forward_range<const _Vp>
6371 {
6372 if constexpr (common_range<const _Vp> && sized_range<const _Vp>)
6373 {
6374 auto __missing = (_M_n - ranges::distance(_M_base) % _M_n) % _M_n;
6375 return _Iterator<true>(this, ranges::end(_M_base), __missing);
6376 }
6377 else if constexpr (common_range<const _Vp> && !bidirectional_range<const _Vp>)
6378 return _Iterator<true>(this, ranges::end(_M_base));
6379 else
6380 return default_sentinel;
6381 }
6382
6383 constexpr auto
6384 size() requires sized_range<_Vp>
6385 {
6386 return __detail::__to_unsigned_like(__detail::__div_ceil
6387 (ranges::distance(_M_base), _M_n));
6388 }
6389
6390 constexpr auto
6391 size() const requires sized_range<const _Vp>
6392 {
6393 return __detail::__to_unsigned_like(__detail::__div_ceil
6394 (ranges::distance(_M_base), _M_n));
6395 }
6396 };
6397
6398 template<typename _Vp>
6399 inline constexpr bool enable_borrowed_range<chunk_view<_Vp>>
6400 = forward_range<_Vp> && enable_borrowed_range<_Vp>;
6401
6402 template<view _Vp>
6403 requires forward_range<_Vp>
6404 template<bool _Const>
6405 class chunk_view<_Vp>::_Iterator
6406 {
6407 using _Parent = __detail::__maybe_const_t<_Const, chunk_view>;
6408 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6409
6410 iterator_t<_Base> _M_current = iterator_t<_Base>();
6411 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
6412 range_difference_t<_Base> _M_n = 0;
6413 range_difference_t<_Base> _M_missing = 0;
6414
6415 constexpr
6416 _Iterator(_Parent* __parent, iterator_t<_Base> __current,
6417 range_difference_t<_Base> __missing = 0)
6418 : _M_current(__current), _M_end(ranges::end(__parent->_M_base)),
6419 _M_n(__parent->_M_n), _M_missing(__missing)
6420 { }
6421
6422 static auto
6423 _S_iter_cat()
6424 {
6425 if constexpr (random_access_range<_Base>)
6426 return random_access_iterator_tag{};
6427 else if constexpr (bidirectional_range<_Base>)
6428 return bidirectional_iterator_tag{};
6429 else
6430 return forward_iterator_tag{};
6431 }
6432
6433 friend chunk_view;
6434
6435 public:
6436 using iterator_category = input_iterator_tag;
6437 using iterator_concept = decltype(_S_iter_cat());
6438 using value_type = decltype(views::take(subrange(_M_current, _M_end), _M_n));
6439 using difference_type = range_difference_t<_Base>;
6440
6441 _Iterator() = default;
6442
6443 constexpr _Iterator(_Iterator<!_Const> __i)
6444 requires _Const
6445 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
6446 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
6447 : _M_current(std::move(__i._M_current)), _M_end(std::move(__i._M_end)),
6448 _M_n(__i._M_n), _M_missing(__i._M_missing)
6449 { }
6450
6451 constexpr iterator_t<_Base>
6452 base() const
6453 { return _M_current; }
6454
6455 constexpr value_type
6456 operator*() const
6457 {
6458 __glibcxx_assert(_M_current != _M_end);
6459 return views::take(subrange(_M_current, _M_end), _M_n);
6460 }
6461
6462 constexpr _Iterator&
6463 operator++()
6464 {
6465 __glibcxx_assert(_M_current != _M_end);
6466 _M_missing = ranges::advance(_M_current, _M_n, _M_end);
6467 return *this;
6468 }
6469
6470 constexpr _Iterator
6471 operator++(int)
6472 {
6473 auto __tmp = *this;
6474 ++*this;
6475 return __tmp;
6476 }
6477
6478 constexpr _Iterator&
6479 operator--() requires bidirectional_range<_Base>
6480 {
6481 ranges::advance(_M_current, _M_missing - _M_n);
6482 _M_missing = 0;
6483 return *this;
6484 }
6485
6486 constexpr _Iterator
6487 operator--(int) requires bidirectional_range<_Base>
6488 {
6489 auto __tmp = *this;
6490 --*this;
6491 return __tmp;
6492 }
6493
6494 constexpr _Iterator&
6495 operator+=(difference_type __x)
6496 requires random_access_range<_Base>
6497 {
6498 if (__x > 0)
6499 {
6500 __glibcxx_assert(ranges::distance(_M_current, _M_end) > _M_n * (__x - 1));
6501 _M_missing = ranges::advance(_M_current, _M_n * __x, _M_end);
6502 }
6503 else if (__x < 0)
6504 {
6505 ranges::advance(_M_current, _M_n * __x + _M_missing);
6506 _M_missing = 0;
6507 }
6508 return *this;
6509 }
6510
6511 constexpr _Iterator&
6512 operator-=(difference_type __x)
6513 requires random_access_range<_Base>
6514 { return *this += -__x; }
6515
6516 constexpr value_type
6517 operator[](difference_type __n) const
6518 requires random_access_range<_Base>
6519 { return *(*this + __n); }
6520
6521 friend constexpr bool
6522 operator==(const _Iterator& __x, const _Iterator& __y)
6523 { return __x._M_current == __y._M_current; }
6524
6525 friend constexpr bool
6526 operator==(const _Iterator& __x, default_sentinel_t)
6527 { return __x._M_current == __x._M_end; }
6528
6529 friend constexpr bool
6530 operator<(const _Iterator& __x, const _Iterator& __y)
6531 requires random_access_range<_Base>
6532 { return __x._M_current > __y._M_current; }
6533
6534 friend constexpr bool
6535 operator>(const _Iterator& __x, const _Iterator& __y)
6536 requires random_access_range<_Base>
6537 { return __y < __x; }
6538
6539 friend constexpr bool
6540 operator<=(const _Iterator& __x, const _Iterator& __y)
6541 requires random_access_range<_Base>
6542 { return !(__y < __x); }
6543
6544 friend constexpr bool
6545 operator>=(const _Iterator& __x, const _Iterator& __y)
6546 requires random_access_range<_Base>
6547 { return !(__x < __y); }
6548
6549 friend constexpr auto
6550 operator<=>(const _Iterator& __x, const _Iterator& __y)
6551 requires random_access_range<_Base>
6552 && three_way_comparable<iterator_t<_Base>>
6553 { return __x._M_current <=> __y._M_current; }
6554
6555 friend constexpr _Iterator
6556 operator+(const _Iterator& __i, difference_type __n)
6557 requires random_access_range<_Base>
6558 {
6559 auto __r = __i;
6560 __r += __n;
6561 return __r;
6562 }
6563
6564 friend constexpr _Iterator
6565 operator+(difference_type __n, const _Iterator& __i)
6566 requires random_access_range<_Base>
6567 {
6568 auto __r = __i;
6569 __r += __n;
6570 return __r;
6571 }
6572
6573 friend constexpr _Iterator
6574 operator-(const _Iterator& __i, difference_type __n)
6575 requires random_access_range<_Base>
6576 {
6577 auto __r = __i;
6578 __r -= __n;
6579 return __r;
6580 }
6581
6582 friend constexpr difference_type
6583 operator-(const _Iterator& __x, const _Iterator& __y)
6584 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
6585 {
6586 return (__x._M_current - __y._M_current
6587 + __x._M_missing - __y._M_missing) / __x._M_n;
6588 }
6589
6590 friend constexpr difference_type
6591 operator-(default_sentinel_t __y, const _Iterator& __x)
6592 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
6593 { return __detail::__div_ceil(__x._M_end - __x._M_current, __x._M_n); }
6594
6595 friend constexpr difference_type
6596 operator-(const _Iterator& __x, default_sentinel_t __y)
6597 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
6598 { return -(__y - __x); }
6599 };
6600
6601 namespace views
6602 {
6603 namespace __detail
6604 {
6605 template<typename _Range, typename _Dp>
6606 concept __can_chunk_view
6607 = requires { chunk_view(std::declval<_Range>(), std::declval<_Dp>()); };
6608 }
6609
6610 struct _Chunk : __adaptor::_RangeAdaptor<_Chunk>
6611 {
6612 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
6613 requires __detail::__can_chunk_view<_Range, _Dp>
6614 constexpr auto
6615 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
6616 { return chunk_view(std::forward<_Range>(__r), __n); }
6617
6618 using __adaptor::_RangeAdaptor<_Chunk>::operator();
6619 static constexpr int _S_arity = 2;
6620 static constexpr bool _S_has_simple_extra_args = true;
6621 };
6622
6623 inline constexpr _Chunk chunk;
6624 }
6625#endif // __cpp_lib_ranges_chunk
6626
6627#ifdef __cpp_lib_ranges_slide // C++ >= 23
6628 namespace __detail
6629 {
6630 template<typename _Vp>
6631 concept __slide_caches_nothing = random_access_range<_Vp> && sized_range<_Vp>;
6632
6633 template<typename _Vp>
6634 concept __slide_caches_last
6635 = !__slide_caches_nothing<_Vp> && bidirectional_range<_Vp> && common_range<_Vp>;
6636
6637 template<typename _Vp>
6638 concept __slide_caches_first
6639 = !__slide_caches_nothing<_Vp> && !__slide_caches_last<_Vp>;
6640 }
6641
6642 template<forward_range _Vp>
6643 requires view<_Vp>
6644 class slide_view : public view_interface<slide_view<_Vp>>
6645 {
6646 _Vp _M_base;
6647 range_difference_t<_Vp> _M_n;
6648 [[no_unique_address]]
6649 __detail::__maybe_present_t<__detail::__slide_caches_first<_Vp>,
6650 __detail::_CachedPosition<_Vp>, 0> _M_cached_begin;
6651 [[no_unique_address]]
6652 __detail::__maybe_present_t<__detail::__slide_caches_last<_Vp>,
6653 __detail::_CachedPosition<_Vp>, 1> _M_cached_end;
6654
6655 template<bool> class _Iterator;
6656 class _Sentinel;
6657
6658 public:
6659 constexpr explicit
6660 slide_view(_Vp __base, range_difference_t<_Vp> __n)
6661 : _M_base(std::move(__base)), _M_n(__n)
6662 { __glibcxx_assert(__n > 0); }
6663
6664 // _GLIBCXX_RESOLVE_LIB_DEFECTS
6665 // 3848. adjacent_view, adjacent_transform_view and slide_view missing base accessor
6666 constexpr _Vp
6667 base() const & requires copy_constructible<_Vp>
6668 { return _M_base; }
6669
6670 constexpr _Vp
6671 base() &&
6672 { return std::move(_M_base); }
6673
6674 constexpr auto
6675 begin() requires (!(__detail::__simple_view<_Vp>
6676 && __detail::__slide_caches_nothing<const _Vp>))
6677 {
6678 if constexpr (__detail::__slide_caches_first<_Vp>)
6679 {
6680 iterator_t<_Vp> __it;
6681 if (_M_cached_begin._M_has_value())
6682 __it = _M_cached_begin._M_get(_M_base);
6683 else
6684 {
6685 __it = ranges::next(ranges::begin(_M_base), _M_n - 1, ranges::end(_M_base));
6686 _M_cached_begin._M_set(_M_base, __it);
6687 }
6688 return _Iterator<false>(ranges::begin(_M_base), std::move(__it), _M_n);
6689 }
6690 else
6691 return _Iterator<false>(ranges::begin(_M_base), _M_n);
6692 }
6693
6694 constexpr auto
6695 begin() const requires __detail::__slide_caches_nothing<const _Vp>
6696 { return _Iterator<true>(ranges::begin(_M_base), _M_n); }
6697
6698 constexpr auto
6699 end() requires (!(__detail::__simple_view<_Vp>
6700 && __detail::__slide_caches_nothing<const _Vp>))
6701 {
6702 if constexpr (__detail::__slide_caches_nothing<_Vp>)
6703 return _Iterator<false>(ranges::begin(_M_base) + range_difference_t<_Vp>(size()),
6704 _M_n);
6705 else if constexpr (__detail::__slide_caches_last<_Vp>)
6706 {
6707 iterator_t<_Vp> __it;
6708 if (_M_cached_end._M_has_value())
6709 __it = _M_cached_end._M_get(_M_base);
6710 else
6711 {
6712 __it = ranges::prev(ranges::end(_M_base), _M_n - 1, ranges::begin(_M_base));
6713 _M_cached_end._M_set(_M_base, __it);
6714 }
6715 return _Iterator<false>(std::move(__it), _M_n);
6716 }
6717 else if constexpr (common_range<_Vp>)
6718 return _Iterator<false>(ranges::end(_M_base), ranges::end(_M_base), _M_n);
6719 else
6720 return _Sentinel(ranges::end(_M_base));
6721 }
6722
6723 constexpr auto
6724 end() const requires __detail::__slide_caches_nothing<const _Vp>
6725 { return begin() + range_difference_t<const _Vp>(size()); }
6726
6727 constexpr auto
6728 size() requires sized_range<_Vp>
6729 {
6730 auto __sz = ranges::distance(_M_base) - _M_n + 1;
6731 if (__sz < 0)
6732 __sz = 0;
6733 return __detail::__to_unsigned_like(__sz);
6734 }
6735
6736 constexpr auto
6737 size() const requires sized_range<const _Vp>
6738 {
6739 auto __sz = ranges::distance(_M_base) - _M_n + 1;
6740 if (__sz < 0)
6741 __sz = 0;
6742 return __detail::__to_unsigned_like(__sz);
6743 }
6744 };
6745
6746 template<typename _Range>
6747 slide_view(_Range&&, range_difference_t<_Range>) -> slide_view<views::all_t<_Range>>;
6748
6749 template<typename _Vp>
6750 inline constexpr bool enable_borrowed_range<slide_view<_Vp>>
6751 = enable_borrowed_range<_Vp>;
6752
6753 template<forward_range _Vp>
6754 requires view<_Vp>
6755 template<bool _Const>
6756 class slide_view<_Vp>::_Iterator
6757 {
6758 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6759 static constexpr bool _S_last_elt_present
6760 = __detail::__slide_caches_first<_Base>;
6761
6762 iterator_t<_Base> _M_current = iterator_t<_Base>();
6763 [[no_unique_address]]
6764 __detail::__maybe_present_t<_S_last_elt_present, iterator_t<_Base>>
6765 _M_last_elt = decltype(_M_last_elt)();
6766 range_difference_t<_Base> _M_n = 0;
6767
6768 constexpr
6769 _Iterator(iterator_t<_Base> __current, range_difference_t<_Base> __n)
6770 requires (!_S_last_elt_present)
6771 : _M_current(__current), _M_n(__n)
6772 { }
6773
6774 constexpr
6775 _Iterator(iterator_t<_Base> __current, iterator_t<_Base> __last_elt,
6776 range_difference_t<_Base> __n)
6777 requires _S_last_elt_present
6778 : _M_current(__current), _M_last_elt(__last_elt), _M_n(__n)
6779 { }
6780
6781 static auto
6782 _S_iter_concept()
6783 {
6784 if constexpr (random_access_range<_Base>)
6785 return random_access_iterator_tag{};
6786 else if constexpr (bidirectional_range<_Base>)
6787 return bidirectional_iterator_tag{};
6788 else
6789 return forward_iterator_tag{};
6790 }
6791
6792 friend slide_view;
6793 friend slide_view::_Sentinel;
6794
6795 public:
6796 using iterator_category = input_iterator_tag;
6797 using iterator_concept = decltype(_S_iter_concept());
6798 using value_type = decltype(views::counted(_M_current, _M_n));
6799 using difference_type = range_difference_t<_Base>;
6800
6801 _Iterator() = default;
6802
6803 constexpr
6804 _Iterator(_Iterator<!_Const> __i)
6805 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
6806 : _M_current(std::move(__i._M_current)), _M_n(__i._M_n)
6807 { }
6808
6809 constexpr auto
6810 operator*() const
6811 { return views::counted(_M_current, _M_n); }
6812
6813 constexpr _Iterator&
6814 operator++()
6815 {
6816 ++_M_current;
6817 if constexpr (_S_last_elt_present)
6818 ++_M_last_elt;
6819 return *this;
6820 }
6821
6822 constexpr _Iterator
6823 operator++(int)
6824 {
6825 auto __tmp = *this;
6826 ++*this;
6827 return __tmp;
6828 }
6829
6830 constexpr _Iterator&
6831 operator--() requires bidirectional_range<_Base>
6832 {
6833 --_M_current;
6834 if constexpr (_S_last_elt_present)
6835 --_M_last_elt;
6836 return *this;
6837 }
6838
6839 constexpr _Iterator
6840 operator--(int) requires bidirectional_range<_Base>
6841 {
6842 auto __tmp = *this;
6843 --*this;
6844 return __tmp;
6845 }
6846
6847 constexpr _Iterator&
6848 operator+=(difference_type __x)
6849 requires random_access_range<_Base>
6850 {
6851 _M_current += __x;
6852 if constexpr (_S_last_elt_present)
6853 _M_last_elt += __x;
6854 return *this;
6855 }
6856
6857 constexpr _Iterator&
6858 operator-=(difference_type __x)
6859 requires random_access_range<_Base>
6860 {
6861 _M_current -= __x;
6862 if constexpr (_S_last_elt_present)
6863 _M_last_elt -= __x;
6864 return *this;
6865 }
6866
6867 constexpr auto
6868 operator[](difference_type __n) const
6869 requires random_access_range<_Base>
6870 { return views::counted(_M_current + __n, _M_n); }
6871
6872 friend constexpr bool
6873 operator==(const _Iterator& __x, const _Iterator& __y)
6874 {
6875 if constexpr (_S_last_elt_present)
6876 return __x._M_last_elt == __y._M_last_elt;
6877 else
6878 return __x._M_current == __y._M_current;
6879 }
6880
6881 friend constexpr bool
6882 operator<(const _Iterator& __x, const _Iterator& __y)
6883 requires random_access_range<_Base>
6884 { return __x._M_current < __y._M_current; }
6885
6886 friend constexpr bool
6887 operator>(const _Iterator& __x, const _Iterator& __y)
6888 requires random_access_range<_Base>
6889 { return __y < __x; }
6890
6891 friend constexpr bool
6892 operator<=(const _Iterator& __x, const _Iterator& __y)
6893 requires random_access_range<_Base>
6894 { return !(__y < __x); }
6895
6896 friend constexpr bool
6897 operator>=(const _Iterator& __x, const _Iterator& __y)
6898 requires random_access_range<_Base>
6899 { return !(__x < __y); }
6900
6901 friend constexpr auto
6902 operator<=>(const _Iterator& __x, const _Iterator& __y)
6903 requires random_access_range<_Base>
6904 && three_way_comparable<iterator_t<_Base>>
6905 { return __x._M_current <=> __y._M_current; }
6906
6907 friend constexpr _Iterator
6908 operator+(const _Iterator& __i, difference_type __n)
6909 requires random_access_range<_Base>
6910 {
6911 auto __r = __i;
6912 __r += __n;
6913 return __r;
6914 }
6915
6916 friend constexpr _Iterator
6917 operator+(difference_type __n, const _Iterator& __i)
6918 requires random_access_range<_Base>
6919 {
6920 auto __r = __i;
6921 __r += __n;
6922 return __r;
6923 }
6924
6925 friend constexpr _Iterator
6926 operator-(const _Iterator& __i, difference_type __n)
6927 requires random_access_range<_Base>
6928 {
6929 auto __r = __i;
6930 __r -= __n;
6931 return __r;
6932 }
6933
6934 friend constexpr difference_type
6935 operator-(const _Iterator& __x, const _Iterator& __y)
6936 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
6937 {
6938 if constexpr (_S_last_elt_present)
6939 return __x._M_last_elt - __y._M_last_elt;
6940 else
6941 return __x._M_current - __y._M_current;
6942 }
6943 };
6944
6945 template<forward_range _Vp>
6946 requires view<_Vp>
6947 class slide_view<_Vp>::_Sentinel
6948 {
6949 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
6950
6951 constexpr explicit
6952 _Sentinel(sentinel_t<_Vp> __end)
6953 : _M_end(__end)
6954 { }
6955
6956 friend slide_view;
6957
6958 public:
6959 _Sentinel() = default;
6960
6961 friend constexpr bool
6962 operator==(const _Iterator<false>& __x, const _Sentinel& __y)
6963 { return __x._M_last_elt == __y._M_end; }
6964
6965 friend constexpr range_difference_t<_Vp>
6966 operator-(const _Iterator<false>& __x, const _Sentinel& __y)
6967 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6968 { return __x._M_last_elt - __y._M_end; }
6969
6970 friend constexpr range_difference_t<_Vp>
6971 operator-(const _Sentinel& __y, const _Iterator<false>& __x)
6972 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6973 { return __y._M_end -__x._M_last_elt; }
6974 };
6975
6976 namespace views
6977 {
6978 namespace __detail
6979 {
6980 template<typename _Range, typename _Dp>
6981 concept __can_slide_view
6982 = requires { slide_view(std::declval<_Range>(), std::declval<_Dp>()); };
6983 }
6984
6985 struct _Slide : __adaptor::_RangeAdaptor<_Slide>
6986 {
6987 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
6988 requires __detail::__can_slide_view<_Range, _Dp>
6989 constexpr auto
6990 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
6991 { return slide_view(std::forward<_Range>(__r), __n); }
6992
6993 using __adaptor::_RangeAdaptor<_Slide>::operator();
6994 static constexpr int _S_arity = 2;
6995 static constexpr bool _S_has_simple_extra_args = true;
6996 };
6997
6998 inline constexpr _Slide slide;
6999 }
7000#endif // __cpp_lib_ranges_slide
7001
7002#ifdef __cpp_lib_ranges_chunk_by // C++ >= 23
7003 template<forward_range _Vp,
7004 indirect_binary_predicate<iterator_t<_Vp>, iterator_t<_Vp>> _Pred>
7005 requires view<_Vp> && is_object_v<_Pred>
7006 class chunk_by_view : public view_interface<chunk_by_view<_Vp, _Pred>>
7007 {
7008 _Vp _M_base = _Vp();
7009 __detail::__box<_Pred> _M_pred;
7010 __detail::_CachedPosition<_Vp> _M_cached_begin;
7011
7012 constexpr iterator_t<_Vp>
7013 _M_find_next(iterator_t<_Vp> __current)
7014 {
7015 __glibcxx_assert(_M_pred.has_value());
7016 auto __pred = [this]<typename _Tp, typename _Up>(_Tp&& __x, _Up&& __y) {
7017 return !bool((*_M_pred)(std::forward<_Tp>(__x), std::forward<_Up>(__y)));
7018 };
7019 auto __it = ranges::adjacent_find(__current, ranges::end(_M_base), __pred);
7020 return ranges::next(__it, 1, ranges::end(_M_base));
7021 }
7022
7023 constexpr iterator_t<_Vp>
7024 _M_find_prev(iterator_t<_Vp> __current) requires bidirectional_range<_Vp>
7025 {
7026 __glibcxx_assert(_M_pred.has_value());
7027 auto __pred = [this]<typename _Tp, typename _Up>(_Tp&& __x, _Up&& __y) {
7028 return !bool((*_M_pred)(std::forward<_Up>(__y), std::forward<_Tp>(__x)));
7029 };
7030 auto __rbegin = std::make_reverse_iterator(__current);
7031 auto __rend = std::make_reverse_iterator(ranges::begin(_M_base));
7032 __glibcxx_assert(__rbegin != __rend);
7033 auto __it = ranges::adjacent_find(__rbegin, __rend, __pred).base();
7034 return ranges::prev(__it, 1, ranges::begin(_M_base));
7035 }
7036
7037 class _Iterator;
7038
7039 public:
7040 chunk_by_view() requires (default_initializable<_Vp>
7041 && default_initializable<_Pred>)
7042 = default;
7043
7044 constexpr explicit
7045 chunk_by_view(_Vp __base, _Pred __pred)
7046 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
7047 { }
7048
7049 constexpr _Vp
7050 base() const & requires copy_constructible<_Vp>
7051 { return _M_base; }
7052
7053 constexpr _Vp
7054 base() &&
7055 { return std::move(_M_base); }
7056
7057 constexpr const _Pred&
7058 pred() const
7059 { return *_M_pred; }
7060
7061 constexpr _Iterator
7062 begin()
7063 {
7064 __glibcxx_assert(_M_pred.has_value());
7065 iterator_t<_Vp> __it;
7066 if (_M_cached_begin._M_has_value())
7067 __it = _M_cached_begin._M_get(_M_base);
7068 else
7069 {
7070 __it = _M_find_next(ranges::begin(_M_base));
7071 _M_cached_begin._M_set(_M_base, __it);
7072 }
7073 return _Iterator(*this, ranges::begin(_M_base), __it);
7074 }
7075
7076 constexpr auto
7077 end()
7078 {
7079 if constexpr (common_range<_Vp>)
7080 return _Iterator(*this, ranges::end(_M_base), ranges::end(_M_base));
7081 else
7082 return default_sentinel;
7083 }
7084 };
7085
7086 template<typename _Range, typename _Pred>
7087 chunk_by_view(_Range&&, _Pred) -> chunk_by_view<views::all_t<_Range>, _Pred>;
7088
7089 template<forward_range _Vp,
7090 indirect_binary_predicate<iterator_t<_Vp>, iterator_t<_Vp>> _Pred>
7091 requires view<_Vp> && is_object_v<_Pred>
7092 class chunk_by_view<_Vp, _Pred>::_Iterator
7093 {
7094 chunk_by_view* _M_parent = nullptr;
7095 iterator_t<_Vp> _M_current = iterator_t<_Vp>();
7096 iterator_t<_Vp> _M_next = iterator_t<_Vp>();
7097
7098 constexpr
7099 _Iterator(chunk_by_view& __parent, iterator_t<_Vp> __current, iterator_t<_Vp> __next)
7100 : _M_parent(std::__addressof(__parent)), _M_current(__current), _M_next(__next)
7101 { }
7102
7103 static auto
7104 _S_iter_concept()
7105 {
7106 if constexpr (bidirectional_range<_Vp>)
7107 return bidirectional_iterator_tag{};
7108 else
7109 return forward_iterator_tag{};
7110 }
7111
7112 friend chunk_by_view;
7113
7114 public:
7115 using value_type = subrange<iterator_t<_Vp>>;
7116 using difference_type = range_difference_t<_Vp>;
7117 using iterator_category = input_iterator_tag;
7118 using iterator_concept = decltype(_S_iter_concept());
7119
7120 _Iterator() = default;
7121
7122 constexpr value_type
7123 operator*() const
7124 {
7125 __glibcxx_assert(_M_current != _M_next);
7126 return ranges::subrange(_M_current, _M_next);
7127 }
7128
7129 constexpr _Iterator&
7130 operator++()
7131 {
7132 __glibcxx_assert(_M_current != _M_next);
7133 _M_current = _M_next;
7134 _M_next = _M_parent->_M_find_next(_M_current);
7135 return *this;
7136 }
7137
7138 constexpr _Iterator
7139 operator++(int)
7140 {
7141 auto __tmp = *this;
7142 ++*this;
7143 return __tmp;
7144 }
7145
7146 constexpr _Iterator&
7147 operator--() requires bidirectional_range<_Vp>
7148 {
7149 _M_next = _M_current;
7150 _M_current = _M_parent->_M_find_prev(_M_next);
7151 return *this;
7152 }
7153
7154 constexpr _Iterator
7155 operator--(int) requires bidirectional_range<_Vp>
7156 {
7157 auto __tmp = *this;
7158 --*this;
7159 return __tmp;
7160 }
7161
7162 friend constexpr bool
7163 operator==(const _Iterator& __x, const _Iterator& __y)
7164 { return __x._M_current == __y._M_current; }
7165
7166 friend constexpr bool
7167 operator==(const _Iterator& __x, default_sentinel_t)
7168 { return __x._M_current == __x._M_next; }
7169 };
7170
7171 namespace views
7172 {
7173 namespace __detail
7174 {
7175 template<typename _Range, typename _Pred>
7176 concept __can_chunk_by_view
7177 = requires { chunk_by_view(std::declval<_Range>(), std::declval<_Pred>()); };
7178 }
7179
7180 struct _ChunkBy : __adaptor::_RangeAdaptor<_ChunkBy>
7181 {
7182 template<viewable_range _Range, typename _Pred>
7183 requires __detail::__can_chunk_by_view<_Range, _Pred>
7184 constexpr auto
7185 operator() [[nodiscard]] (_Range&& __r, _Pred&& __pred) const
7186 { return chunk_by_view(std::forward<_Range>(__r), std::forward<_Pred>(__pred)); }
7187
7188 using __adaptor::_RangeAdaptor<_ChunkBy>::operator();
7189 static constexpr int _S_arity = 2;
7190 static constexpr bool _S_has_simple_extra_args = true;
7191 };
7192
7193 inline constexpr _ChunkBy chunk_by;
7194 }
7195#endif // __cpp_lib_ranges_chunk_by
7196
7197#ifdef __cpp_lib_ranges_join_with // C++ >= 23
7198 namespace __detail
7199 {
7200 template<typename _Range, typename _Pattern>
7201 concept __compatible_joinable_ranges
7202 = common_with<range_value_t<_Range>, range_value_t<_Pattern>>
7203 && common_reference_with<range_reference_t<_Range>,
7204 range_reference_t<_Pattern>>
7205 && common_reference_with<range_rvalue_reference_t<_Range>,
7206 range_rvalue_reference_t<_Pattern>>;
7207
7208 template<typename _Range>
7209 concept __bidirectional_common = bidirectional_range<_Range> && common_range<_Range>;
7210 }
7211
7212 template<input_range _Vp, forward_range _Pattern>
7213 requires view<_Vp> && view<_Pattern>
7214 && input_range<range_reference_t<_Vp>>
7215 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7216 class join_with_view : public view_interface<join_with_view<_Vp, _Pattern>>
7217 {
7218 using _InnerRange = range_reference_t<_Vp>;
7219
7220 _Vp _M_base = _Vp();
7221 [[no_unique_address]]
7222 __detail::__maybe_present_t<!forward_range<_Vp>,
7223 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_outer_it;
7224 __detail::__non_propagating_cache<remove_cv_t<_InnerRange>> _M_inner;
7225 _Pattern _M_pattern = _Pattern();
7226
7227 template<bool _Const> using _Base = __detail::__maybe_const_t<_Const, _Vp>;
7228 template<bool _Const> using _InnerBase = range_reference_t<_Base<_Const>>;
7229 template<bool _Const> using _PatternBase = __detail::__maybe_const_t<_Const, _Pattern>;
7230
7231 template<bool _Const> using _OuterIter = iterator_t<_Base<_Const>>;
7232 template<bool _Const> using _InnerIter = iterator_t<_InnerBase<_Const>>;
7233 template<bool _Const> using _PatternIter = iterator_t<_PatternBase<_Const>>;
7234
7235 template<bool _Const>
7236 static constexpr bool _S_ref_is_glvalue = is_reference_v<_InnerBase<_Const>>;
7237
7238 template<bool _Const>
7239 struct __iter_cat
7240 { };
7241
7242 template<bool _Const>
7243 requires _S_ref_is_glvalue<_Const>
7244 && forward_range<_Base<_Const>>
7245 && forward_range<_InnerBase<_Const>>
7246 struct __iter_cat<_Const>
7247 {
7248 private:
7249 static auto
7250 _S_iter_cat()
7251 {
7252 using _OuterIter = join_with_view::_OuterIter<_Const>;
7253 using _InnerIter = join_with_view::_InnerIter<_Const>;
7254 using _PatternIter = join_with_view::_PatternIter<_Const>;
7255 using _OuterCat = typename iterator_traits<_OuterIter>::iterator_category;
7256 using _InnerCat = typename iterator_traits<_InnerIter>::iterator_category;
7257 using _PatternCat = typename iterator_traits<_PatternIter>::iterator_category;
7258 // _GLIBCXX_RESOLVE_LIB_DEFECTS
7259 // 3798. Rvalue reference and iterator_category
7260 if constexpr (!is_reference_v<common_reference_t<iter_reference_t<_InnerIter>,
7261 iter_reference_t<_PatternIter>>>)
7262 return input_iterator_tag{};
7263 else if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag>
7264 && derived_from<_InnerCat, bidirectional_iterator_tag>
7265 && derived_from<_PatternCat, bidirectional_iterator_tag>
7266 && common_range<_InnerBase<_Const>>
7267 && common_range<_PatternBase<_Const>>)
7268 return bidirectional_iterator_tag{};
7269 else if constexpr (derived_from<_OuterCat, forward_iterator_tag>
7270 && derived_from<_InnerCat, forward_iterator_tag>
7271 && derived_from<_PatternCat, forward_iterator_tag>)
7272 return forward_iterator_tag{};
7273 else
7274 return input_iterator_tag{};
7275 }
7276 public:
7277 using iterator_category = decltype(_S_iter_cat());
7278 };
7279
7280 template<bool> struct _Iterator;
7281 template<bool> struct _Sentinel;
7282
7283 public:
7284 join_with_view() requires (default_initializable<_Vp>
7285 && default_initializable<_Pattern>)
7286 = default;
7287
7288 constexpr
7289 join_with_view(_Vp __base, _Pattern __pattern)
7290 : _M_base(std::move(__base)), _M_pattern(std::move(__pattern))
7291 { }
7292
7293 template<input_range _Range>
7294 requires constructible_from<_Vp, views::all_t<_Range>>
7295 && constructible_from<_Pattern, single_view<range_value_t<_InnerRange>>>
7296 constexpr
7297 join_with_view(_Range&& __r, range_value_t<_InnerRange> __e)
7298 : _M_base(views::all(std::forward<_Range>(__r))),
7299 _M_pattern(views::single(std::move(__e)))
7300 { }
7301
7302 constexpr _Vp
7303 base() const& requires copy_constructible<_Vp>
7304 { return _M_base; }
7305
7306 constexpr _Vp
7307 base() &&
7308 { return std::move(_M_base); }
7309
7310 constexpr auto
7311 begin()
7312 {
7313 if constexpr (forward_range<_Vp>)
7314 {
7315 constexpr bool __use_const = is_reference_v<_InnerRange>
7316 && __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
7317 return _Iterator<__use_const>{*this, ranges::begin(_M_base)};
7318 }
7319 else
7320 {
7321 _M_outer_it = ranges::begin(_M_base);
7322 return _Iterator<false>{*this};
7323 }
7324 }
7325
7326 constexpr auto
7327 begin() const
7328 requires forward_range<const _Vp>
7329 && forward_range<const _Pattern>
7330 && is_reference_v<range_reference_t<const _Vp>>
7331 && input_range<range_reference_t<const _Vp>>
7332 { return _Iterator<true>{*this, ranges::begin(_M_base)}; }
7333
7334 constexpr auto
7335 end()
7336 {
7337 constexpr bool __use_const
7338 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
7339 if constexpr (is_reference_v<_InnerRange>
7340 && forward_range<_Vp> && common_range<_Vp>
7341 && forward_range<_InnerRange> && common_range<_InnerRange>)
7342 return _Iterator<__use_const>{*this, ranges::end(_M_base)};
7343 else
7344 return _Sentinel<__use_const>{*this};
7345 }
7346
7347 constexpr auto
7348 end() const
7349 requires forward_range<const _Vp>
7350 && forward_range<const _Pattern>
7351 && is_reference_v<range_reference_t<const _Vp>>
7352 && input_range<range_reference_t<const _Vp>>
7353 {
7354 using _InnerConstRange = range_reference_t<const _Vp>;
7355 if constexpr (forward_range<_InnerConstRange>
7356 && common_range<const _Vp>
7357 && common_range<_InnerConstRange>)
7358 return _Iterator<true>{*this, ranges::end(_M_base)};
7359 else
7360 return _Sentinel<true>{*this};
7361 }
7362 };
7363
7364 template<typename _Range, typename _Pattern>
7365 join_with_view(_Range&&, _Pattern&&)
7366 -> join_with_view<views::all_t<_Range>, views::all_t<_Pattern>>;
7367
7368 template<input_range _Range>
7369 join_with_view(_Range&&, range_value_t<range_reference_t<_Range>>)
7370 -> join_with_view<views::all_t<_Range>,
7371 single_view<range_value_t<range_reference_t<_Range>>>>;
7372
7373 template<input_range _Vp, forward_range _Pattern>
7374 requires view<_Vp> && view<_Pattern>
7375 && input_range<range_reference_t<_Vp>>
7376 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7377 template<bool _Const>
7378 class join_with_view<_Vp, _Pattern>::_Iterator : public __iter_cat<_Const>
7379 {
7380 using _Parent = __detail::__maybe_const_t<_Const, join_with_view>;
7381 using _Base = join_with_view::_Base<_Const>;
7382 using _InnerBase = join_with_view::_InnerBase<_Const>;
7383 using _PatternBase = join_with_view::_PatternBase<_Const>;
7384
7385 using _OuterIter = join_with_view::_OuterIter<_Const>;
7386 using _InnerIter = join_with_view::_InnerIter<_Const>;
7387 using _PatternIter = join_with_view::_PatternIter<_Const>;
7388
7389 static constexpr bool _S_ref_is_glvalue = join_with_view::_S_ref_is_glvalue<_Const>;
7390
7391 _Parent* _M_parent = nullptr;
7392 [[no_unique_address]]
7393 __detail::__maybe_present_t<forward_range<_Base>, _OuterIter> _M_outer_it;
7394 variant<_PatternIter, _InnerIter> _M_inner_it;
7395
7396 constexpr _OuterIter&
7397 _M_get_outer()
7398 {
7399 if constexpr (forward_range<_Base>)
7400 return _M_outer_it;
7401 else
7402 return *_M_parent->_M_outer_it;
7403 }
7404
7405 constexpr const _OuterIter&
7406 _M_get_outer() const
7407 {
7408 if constexpr (forward_range<_Base>)
7409 return _M_outer_it;
7410 else
7411 return *_M_parent->_M_outer_it;
7412 }
7413
7414 constexpr
7415 _Iterator(_Parent& __parent, _OuterIter __outer)
7416 requires forward_range<_Base>
7417 : _M_parent(std::__addressof(__parent)), _M_outer_it(std::move(__outer))
7418 {
7419 if (_M_get_outer() != ranges::end(_M_parent->_M_base))
7420 {
7421 auto&& __inner = _M_update_inner();
7422 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7423 _M_satisfy();
7424 }
7425 }
7426
7427 constexpr
7428 _Iterator(_Parent& __parent)
7429 requires (!forward_range<_Base>)
7430 : _M_parent(std::__addressof(__parent))
7431 {
7432 if (_M_get_outer() != ranges::end(_M_parent->_M_base))
7433 {
7434 auto&& __inner = _M_update_inner();
7435 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7436 _M_satisfy();
7437 }
7438 }
7439
7440 constexpr auto&
7441 _M_update_inner()
7442 {
7443 _OuterIter& __outer = _M_get_outer();
7444 if constexpr (_S_ref_is_glvalue)
7445 return __detail::__as_lvalue(*__outer);
7446 else
7447 return _M_parent->_M_inner._M_emplace_deref(__outer);
7448 }
7449
7450 constexpr auto&
7451 _M_get_inner()
7452 {
7453 if constexpr (_S_ref_is_glvalue)
7454 return __detail::__as_lvalue(*_M_get_outer());
7455 else
7456 return *_M_parent->_M_inner;
7457 }
7458
7459 constexpr void
7460 _M_satisfy()
7461 {
7462 while (true)
7463 {
7464 if (_M_inner_it.index() == 0)
7465 {
7466 if (std::get<0>(_M_inner_it) != ranges::end(_M_parent->_M_pattern))
7467 break;
7468
7469 auto&& __inner = _M_update_inner();
7470 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7471 }
7472 else
7473 {
7474 auto&& __inner = _M_get_inner();
7475 if (std::get<1>(_M_inner_it) != ranges::end(__inner))
7476 break;
7477
7478 if (++_M_get_outer() == ranges::end(_M_parent->_M_base))
7479 {
7480 if constexpr (_S_ref_is_glvalue)
7481 _M_inner_it.template emplace<0>();
7482 break;
7483 }
7484
7485 _M_inner_it.template emplace<0>(ranges::begin(_M_parent->_M_pattern));
7486 }
7487 }
7488 }
7489
7490 static auto
7491 _S_iter_concept()
7492 {
7493 if constexpr (_S_ref_is_glvalue
7494 && bidirectional_range<_Base>
7495 && __detail::__bidirectional_common<_InnerBase>
7496 && __detail::__bidirectional_common<_PatternBase>)
7497 return bidirectional_iterator_tag{};
7498 else if constexpr (_S_ref_is_glvalue
7499 && forward_range<_Base>
7500 && forward_range<_InnerBase>)
7501 return forward_iterator_tag{};
7502 else
7503 return input_iterator_tag{};
7504 }
7505
7506 friend join_with_view;
7507
7508 public:
7509 using iterator_concept = decltype(_S_iter_concept());
7510 // iterator_category defined in join_with_view::__iter_cat
7511 using value_type = common_type_t<iter_value_t<_InnerIter>,
7512 iter_value_t<_PatternIter>>;
7513 using difference_type = common_type_t<iter_difference_t<_OuterIter>,
7514 iter_difference_t<_InnerIter>,
7515 iter_difference_t<_PatternIter>>;
7516
7517 _Iterator() = default;
7518
7519 constexpr
7520 _Iterator(_Iterator<!_Const> __i)
7521 requires _Const
7522 && convertible_to<iterator_t<_Vp>, _OuterIter>
7523 && convertible_to<iterator_t<_InnerRange>, _InnerIter>
7524 && convertible_to<iterator_t<_Pattern>, _PatternIter>
7525 : _M_parent(__i._M_parent),
7526 _M_outer_it(std::move(__i._M_outer_it))
7527 {
7528 if (__i._M_inner_it.index() == 0)
7529 _M_inner_it.template emplace<0>(std::get<0>(std::move(__i._M_inner_it)));
7530 else
7531 _M_inner_it.template emplace<1>(std::get<1>(std::move(__i._M_inner_it)));
7532 }
7533
7534 constexpr common_reference_t<iter_reference_t<_InnerIter>,
7535 iter_reference_t<_PatternIter>>
7536 operator*() const
7537 {
7538 if (_M_inner_it.index() == 0)
7539 return *std::get<0>(_M_inner_it);
7540 else
7541 return *std::get<1>(_M_inner_it);
7542 }
7543
7544 constexpr _Iterator&
7545 operator++()
7546 {
7547 if (_M_inner_it.index() == 0)
7548 ++std::get<0>(_M_inner_it);
7549 else
7550 ++std::get<1>(_M_inner_it);
7551 _M_satisfy();
7552 return *this;
7553 }
7554
7555 constexpr void
7556 operator++(int)
7557 { ++*this; }
7558
7559 constexpr _Iterator
7560 operator++(int)
7561 requires _S_ref_is_glvalue
7562 && forward_iterator<_OuterIter> && forward_iterator<_InnerIter>
7563 {
7564 _Iterator __tmp = *this;
7565 ++*this;
7566 return __tmp;
7567 }
7568
7569 constexpr _Iterator&
7570 operator--()
7571 requires _S_ref_is_glvalue
7572 && bidirectional_range<_Base>
7573 && __detail::__bidirectional_common<_InnerBase>
7574 && __detail::__bidirectional_common<_PatternBase>
7575 {
7576 if (_M_outer_it == ranges::end(_M_parent->_M_base))
7577 {
7578 auto&& __inner = *--_M_outer_it;
7579 _M_inner_it.template emplace<1>(ranges::end(__inner));
7580 }
7581
7582 while (true)
7583 {
7584 if (_M_inner_it.index() == 0)
7585 {
7586 auto& __it = std::get<0>(_M_inner_it);
7587 if (__it == ranges::begin(_M_parent->_M_pattern))
7588 {
7589 auto&& __inner = *--_M_outer_it;
7590 _M_inner_it.template emplace<1>(ranges::end(__inner));
7591 }
7592 else
7593 break;
7594 }
7595 else
7596 {
7597 auto& __it = std::get<1>(_M_inner_it);
7598 auto&& __inner = *_M_outer_it;
7599 if (__it == ranges::begin(__inner))
7600 _M_inner_it.template emplace<0>(ranges::end(_M_parent->_M_pattern));
7601 else
7602 break;
7603 }
7604 }
7605
7606 if (_M_inner_it.index() == 0)
7607 --std::get<0>(_M_inner_it);
7608 else
7609 --std::get<1>(_M_inner_it);
7610 return *this;
7611 }
7612
7613 constexpr _Iterator
7614 operator--(int)
7615 requires _S_ref_is_glvalue && bidirectional_range<_Base>
7616 && __detail::__bidirectional_common<_InnerBase>
7617 && __detail::__bidirectional_common<_PatternBase>
7618 {
7619 _Iterator __tmp = *this;
7620 --*this;
7621 return __tmp;
7622 }
7623
7624 friend constexpr bool
7625 operator==(const _Iterator& __x, const _Iterator& __y)
7626 requires _S_ref_is_glvalue
7627 && forward_range<_Base> && equality_comparable<_InnerIter>
7628 { return __x._M_outer_it == __y._M_outer_it && __x._M_inner_it ==__y._M_inner_it; }
7629
7630 friend constexpr common_reference_t<iter_rvalue_reference_t<_InnerIter>,
7631 iter_rvalue_reference_t<_PatternIter>>
7632 iter_move(const _Iterator& __x)
7633 {
7634 if (__x._M_inner_it.index() == 0)
7635 return ranges::iter_move(std::get<0>(__x._M_inner_it));
7636 else
7637 return ranges::iter_move(std::get<1>(__x._M_inner_it));
7638 }
7639
7640 friend constexpr void
7641 iter_swap(const _Iterator& __x, const _Iterator& __y)
7642 requires indirectly_swappable<_InnerIter, _PatternIter>
7643 {
7644 if (__x._M_inner_it.index() == 0)
7645 {
7646 if (__y._M_inner_it.index() == 0)
7647 ranges::iter_swap(std::get<0>(__x._M_inner_it), std::get<0>(__y._M_inner_it));
7648 else
7649 ranges::iter_swap(std::get<0>(__x._M_inner_it), std::get<1>(__y._M_inner_it));
7650 }
7651 else
7652 {
7653 if (__y._M_inner_it.index() == 0)
7654 ranges::iter_swap(std::get<1>(__x._M_inner_it), std::get<0>(__y._M_inner_it));
7655 else
7656 ranges::iter_swap(std::get<1>(__x._M_inner_it), std::get<1>(__y._M_inner_it));
7657 }
7658 }
7659 };
7660
7661 template<input_range _Vp, forward_range _Pattern>
7662 requires view<_Vp> && view<_Pattern>
7663 && input_range<range_reference_t<_Vp>>
7664 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7665 template<bool _Const>
7666 class join_with_view<_Vp, _Pattern>::_Sentinel
7667 {
7668 using _Parent = __detail::__maybe_const_t<_Const, join_with_view>;
7669 using _Base = join_with_view::_Base<_Const>;
7670
7671 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
7672
7673 constexpr explicit
7674 _Sentinel(_Parent& __parent)
7675 : _M_end(ranges::end(__parent._M_base))
7676 { }
7677
7678 friend join_with_view;
7679
7680 public:
7681 _Sentinel() = default;
7682
7683 constexpr
7684 _Sentinel(_Sentinel<!_Const> __s)
7685 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
7686 : _M_end(std::move(__s._M_end))
7687 { }
7688
7689 template<bool _OtherConst>
7690 requires sentinel_for<sentinel_t<_Base>,
7691 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
7692 friend constexpr bool
7693 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
7694 { return __x._M_get_outer() == __y._M_end; }
7695 };
7696
7697 namespace views
7698 {
7699 namespace __detail
7700 {
7701 template<typename _Range, typename _Pattern>
7702 concept __can_join_with_view
7703 = requires { join_with_view(std::declval<_Range>(), std::declval<_Pattern>()); };
7704 } // namespace __detail
7705
7706 struct _JoinWith : __adaptor::_RangeAdaptor<_JoinWith>
7707 {
7708 template<viewable_range _Range, typename _Pattern>
7709 requires __detail::__can_join_with_view<_Range, _Pattern>
7710 constexpr auto
7711 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f) const
7712 {
7713 return join_with_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
7714 }
7715
7716 using _RangeAdaptor<_JoinWith>::operator();
7717 static constexpr int _S_arity = 2;
7718 template<typename _Pattern>
7719 static constexpr bool _S_has_simple_extra_args
7720 = _LazySplit::_S_has_simple_extra_args<_Pattern>;
7721 };
7722
7723 inline constexpr _JoinWith join_with;
7724 } // namespace views
7725#endif // __cpp_lib_ranges_join_with
7726
7727#ifdef __cpp_lib_ranges_repeat // C++ >= 23
7728 template<move_constructible _Tp, semiregular _Bound = unreachable_sentinel_t>
7729 requires is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>>
7730 && (__detail::__is_integer_like<_Bound> || same_as<_Bound, unreachable_sentinel_t>)
7731 class repeat_view : public view_interface<repeat_view<_Tp, _Bound>>
7732 {
7733 __detail::__box<_Tp> _M_value;
7734 [[no_unique_address]] _Bound _M_bound = _Bound();
7735
7736 struct _Iterator;
7737
7738 template<typename _Range>
7739 friend constexpr auto
7740 views::__detail::__take_of_repeat_view(_Range&&, range_difference_t<_Range>);
7741
7742 template<typename _Range>
7743 friend constexpr auto
7744 views::__detail::__drop_of_repeat_view(_Range&&, range_difference_t<_Range>);
7745
7746 public:
7747 repeat_view() requires default_initializable<_Tp> = default;
7748
7749 constexpr explicit
7750 repeat_view(const _Tp& __value, _Bound __bound = _Bound())
7751 requires copy_constructible<_Tp>
7752 : _M_value(__value), _M_bound(__bound)
7753 {
7754 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7755 __glibcxx_assert(__bound >= 0);
7756 }
7757
7758 constexpr explicit
7759 repeat_view(_Tp&& __value, _Bound __bound = _Bound())
7760 : _M_value(std::move(__value)), _M_bound(__bound)
7761 { }
7762
7763 template<typename... _Args, typename... _BoundArgs>
7764 requires constructible_from<_Tp, _Args...>
7765 && constructible_from<_Bound, _BoundArgs...>
7766 constexpr explicit
7767 repeat_view(piecewise_construct_t,
7768 tuple<_Args...> __args,
7769 tuple<_BoundArgs...> __bound_args = tuple<>{})
7770 : _M_value(std::make_from_tuple<_Tp>(std::move(__args))),
7771 _M_bound(std::make_from_tuple<_Bound>(std::move(__bound_args)))
7772 { }
7773
7774 constexpr _Iterator
7775 begin() const
7776 { return _Iterator(std::__addressof(*_M_value)); }
7777
7778 constexpr _Iterator
7779 end() const requires (!same_as<_Bound, unreachable_sentinel_t>)
7780 { return _Iterator(std::__addressof(*_M_value), _M_bound); }
7781
7782 constexpr unreachable_sentinel_t
7783 end() const noexcept
7784 { return unreachable_sentinel; }
7785
7786 constexpr auto
7787 size() const requires (!same_as<_Bound, unreachable_sentinel_t>)
7788 { return __detail::__to_unsigned_like(_M_bound); }
7789 };
7790
7791 // _GLIBCXX_RESOLVE_LIB_DEFECTS
7792 // 4053. Unary call to std::views::repeat does not decay the argument
7793 template<typename _Tp, typename _Bound = unreachable_sentinel_t>
7794 repeat_view(_Tp, _Bound = _Bound()) -> repeat_view<_Tp, _Bound>;
7795
7796 template<move_constructible _Tp, semiregular _Bound>
7797 requires is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>>
7798 && (__detail::__is_integer_like<_Bound> || same_as<_Bound, unreachable_sentinel_t>)
7799 class repeat_view<_Tp, _Bound>::_Iterator
7800 {
7801 using __index_type
7802 = __conditional_t<same_as<_Bound, unreachable_sentinel_t>, ptrdiff_t, _Bound>;
7803
7804 const _Tp* _M_value = nullptr;
7805 __index_type _M_current = __index_type();
7806
7807 constexpr explicit
7808 _Iterator(const _Tp* __value, __index_type __bound = __index_type())
7809 : _M_value(__value), _M_current(__bound)
7810 {
7811 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7812 __glibcxx_assert(__bound >= 0);
7813 }
7814
7815 friend repeat_view;
7816
7817 public:
7818 using iterator_concept = random_access_iterator_tag;
7819 using iterator_category = random_access_iterator_tag;
7820 using value_type = _Tp;
7821 using difference_type = __conditional_t<__detail::__is_signed_integer_like<__index_type>,
7822 __index_type,
7823 __detail::__iota_diff_t<__index_type>>;
7824
7825 _Iterator() = default;
7826
7827 constexpr const _Tp&
7828 operator*() const noexcept
7829 { return *_M_value; }
7830
7831 constexpr _Iterator&
7832 operator++()
7833 {
7834 ++_M_current;
7835 return *this;
7836 }
7837
7838 constexpr _Iterator
7839 operator++(int)
7840 {
7841 auto __tmp = *this;
7842 ++*this;
7843 return __tmp;
7844 }
7845
7846 constexpr _Iterator&
7847 operator--()
7848 {
7849 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7850 __glibcxx_assert(_M_current > 0);
7851 --_M_current;
7852 return *this;
7853 }
7854
7855 constexpr _Iterator
7856 operator--(int)
7857 {
7858 auto __tmp = *this;
7859 --*this;
7860 return __tmp;
7861 }
7862
7863 constexpr _Iterator&
7864 operator+=(difference_type __n)
7865 {
7866 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7867 __glibcxx_assert(_M_current + __n >= 0);
7868 _M_current += __n;
7869 return *this;
7870 }
7871
7872 constexpr _Iterator&
7873 operator-=(difference_type __n)
7874 {
7875 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7876 __glibcxx_assert(_M_current - __n >= 0);
7877 _M_current -= __n;
7878 return *this;
7879 }
7880
7881 constexpr const _Tp&
7882 operator[](difference_type __n) const noexcept
7883 { return *(*this + __n); }
7884
7885 friend constexpr bool
7886 operator==(const _Iterator& __x, const _Iterator& __y)
7887 { return __x._M_current == __y._M_current; }
7888
7889 friend constexpr auto
7890 operator<=>(const _Iterator& __x, const _Iterator& __y)
7891 { return __x._M_current <=> __y._M_current; }
7892
7893 friend constexpr _Iterator
7894 operator+(_Iterator __i, difference_type __n)
7895 {
7896 __i += __n;
7897 return __i;
7898 }
7899
7900 friend constexpr _Iterator
7901 operator+(difference_type __n, _Iterator __i)
7902 { return __i + __n; }
7903
7904 friend constexpr _Iterator
7905 operator-(_Iterator __i, difference_type __n)
7906 {
7907 __i -= __n;
7908 return __i;
7909 }
7910
7911 friend constexpr difference_type
7912 operator-(const _Iterator& __x, const _Iterator& __y)
7913 {
7914 return (static_cast<difference_type>(__x._M_current)
7915 - static_cast<difference_type>(__y._M_current));
7916 }
7917 };
7918
7919 namespace views
7920 {
7921 namespace __detail
7922 {
7923 template<typename _Tp, typename _Bound>
7924 inline constexpr bool __is_repeat_view<repeat_view<_Tp, _Bound>> = true;
7925
7926 template<typename _Tp>
7927 concept __can_repeat_view
7928 = requires { repeat_view(std::declval<_Tp>()); };
7929
7930 template<typename _Tp, typename _Bound>
7931 concept __can_bounded_repeat_view
7932 = requires { repeat_view(std::declval<_Tp>(), std::declval<_Bound>()); };
7933 }
7934
7935 struct _Repeat
7936 {
7937 template<typename _Tp>
7938 requires __detail::__can_repeat_view<_Tp>
7939 constexpr auto
7940 operator() [[nodiscard]] (_Tp&& __value) const
7941 {
7942 // _GLIBCXX_RESOLVE_LIB_DEFECTS
7943 // 4054. Repeating a repeat_view should repeat the view
7944 return repeat_view<decay_t<_Tp>>(std::forward<_Tp>(__value));
7945 }
7946
7947 template<typename _Tp, typename _Bound>
7948 requires __detail::__can_bounded_repeat_view<_Tp, _Bound>
7949 constexpr auto
7950 operator() [[nodiscard]] (_Tp&& __value, _Bound __bound) const
7951 { return repeat_view(std::forward<_Tp>(__value), __bound); }
7952 };
7953
7954 inline constexpr _Repeat repeat;
7955
7956 namespace __detail
7957 {
7958 template<typename _Range>
7959 constexpr auto
7960 __take_of_repeat_view(_Range&& __r, range_difference_t<_Range> __n)
7961 {
7962 using _Tp = remove_cvref_t<_Range>;
7963 static_assert(__is_repeat_view<_Tp>);
7964 if constexpr (sized_range<_Tp>)
7965 return views::repeat(*std::forward<_Range>(__r)._M_value,
7966 std::min(ranges::distance(__r), __n));
7967 else
7968 return views::repeat(*std::forward<_Range>(__r)._M_value, __n);
7969 }
7970
7971 template<typename _Range>
7972 constexpr auto
7973 __drop_of_repeat_view(_Range&& __r, range_difference_t<_Range> __n)
7974 {
7975 using _Tp = remove_cvref_t<_Range>;
7976 static_assert(__is_repeat_view<_Tp>);
7977 if constexpr (sized_range<_Tp>)
7978 {
7979 auto __sz = ranges::distance(__r);
7980 return views::repeat(*std::forward<_Range>(__r)._M_value,
7981 __sz - std::min(__sz, __n));
7982 }
7983 else
7984 return __r;
7985 }
7986 }
7987 }
7988#endif // __cpp_lib_ranges_repeat
7989
7990#ifdef __cpp_lib_ranges_stride // C++ >= 23
7991 template<input_range _Vp>
7992 requires view<_Vp>
7993 class stride_view : public view_interface<stride_view<_Vp>>
7994 {
7995 _Vp _M_base;
7996 range_difference_t<_Vp> _M_stride;
7997
7998 template<bool _Const> using _Base = __detail::__maybe_const_t<_Const, _Vp>;
7999
8000 template<bool _Const>
8001 struct __iter_cat
8002 { };
8003
8004 template<bool _Const>
8005 requires forward_range<_Base<_Const>>
8006 struct __iter_cat<_Const>
8007 {
8008 private:
8009 static auto
8010 _S_iter_cat()
8011 {
8012 using _Cat = typename iterator_traits<iterator_t<_Base<_Const>>>::iterator_category;
8013 if constexpr (derived_from<_Cat, random_access_iterator_tag>)
8014 return random_access_iterator_tag{};
8015 else
8016 return _Cat{};
8017 }
8018 public:
8019 using iterator_category = decltype(_S_iter_cat());
8020 };
8021
8022 template<bool> class _Iterator;
8023
8024 public:
8025 constexpr explicit
8026 stride_view(_Vp __base, range_difference_t<_Vp> __stride)
8027 : _M_base(std::move(__base)), _M_stride(__stride)
8028 { __glibcxx_assert(__stride > 0); }
8029
8030 constexpr _Vp
8031 base() const& requires copy_constructible<_Vp>
8032 { return _M_base; }
8033
8034 constexpr _Vp
8035 base() &&
8036 { return std::move(_M_base); }
8037
8038 constexpr range_difference_t<_Vp>
8039 stride() const noexcept
8040 { return _M_stride; }
8041
8042 constexpr auto
8043 begin() requires (!__detail::__simple_view<_Vp>)
8044 { return _Iterator<false>(this, ranges::begin(_M_base)); }
8045
8046 constexpr auto
8047 begin() const requires range<const _Vp>
8048 { return _Iterator<true>(this, ranges::begin(_M_base)); }
8049
8050 constexpr auto
8051 end() requires (!__detail::__simple_view<_Vp>)
8052 {
8053 if constexpr (common_range<_Vp> && sized_range<_Vp> && forward_range<_Vp>)
8054 {
8055 auto __missing = (_M_stride - ranges::distance(_M_base) % _M_stride) % _M_stride;
8056 return _Iterator<false>(this, ranges::end(_M_base), __missing);
8057 }
8058 else if constexpr (common_range<_Vp> && !bidirectional_range<_Vp>)
8059 return _Iterator<false>(this, ranges::end(_M_base));
8060 else
8061 return default_sentinel;
8062 }
8063
8064 constexpr auto
8065 end() const requires range<const _Vp>
8066 {
8067 if constexpr (common_range<const _Vp> && sized_range<const _Vp>
8068 && forward_range<const _Vp>)
8069 {
8070 auto __missing = (_M_stride - ranges::distance(_M_base) % _M_stride) % _M_stride;
8071 return _Iterator<true>(this, ranges::end(_M_base), __missing);
8072 }
8073 else if constexpr (common_range<const _Vp> && !bidirectional_range<const _Vp>)
8074 return _Iterator<true>(this, ranges::end(_M_base));
8075 else
8076 return default_sentinel;
8077 }
8078
8079 constexpr auto
8080 size() requires sized_range<_Vp>
8081 {
8082 return __detail::__to_unsigned_like
8083 (__detail::__div_ceil(ranges::distance(_M_base), _M_stride));
8084 }
8085
8086 constexpr auto
8087 size() const requires sized_range<const _Vp>
8088 {
8089 return __detail::__to_unsigned_like
8090 (__detail::__div_ceil(ranges::distance(_M_base), _M_stride));
8091 }
8092 };
8093
8094 template<typename _Range>
8095 stride_view(_Range&&, range_difference_t<_Range>) -> stride_view<views::all_t<_Range>>;
8096
8097 template<typename _Vp>
8098 inline constexpr bool enable_borrowed_range<stride_view<_Vp>>
8099 = enable_borrowed_range<_Vp>;
8100
8101 template<input_range _Vp>
8102 requires view<_Vp>
8103 template<bool _Const>
8104 class stride_view<_Vp>::_Iterator : public __iter_cat<_Const>
8105 {
8106 using _Parent = __detail::__maybe_const_t<_Const, stride_view>;
8107 using _Base = stride_view::_Base<_Const>;
8108
8109 iterator_t<_Base> _M_current = iterator_t<_Base>();
8110 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
8111 range_difference_t<_Base> _M_stride = 0;
8112 range_difference_t<_Base> _M_missing = 0;
8113
8114 constexpr
8115 _Iterator(_Parent* __parent, iterator_t<_Base> __current,
8116 range_difference_t<_Base> __missing = 0)
8117 : _M_current(std::move(__current)), _M_end(ranges::end(__parent->_M_base)),
8118 _M_stride(__parent->_M_stride), _M_missing(__missing)
8119 { }
8120
8121 static auto
8122 _S_iter_concept()
8123 {
8124 if constexpr (random_access_range<_Base>)
8125 return random_access_iterator_tag{};
8126 else if constexpr (bidirectional_range<_Base>)
8127 return bidirectional_iterator_tag{};
8128 else if constexpr (forward_range<_Base>)
8129 return forward_iterator_tag{};
8130 else
8131 return input_iterator_tag{};
8132 }
8133
8134 friend stride_view;
8135
8136 public:
8137 using difference_type = range_difference_t<_Base>;
8138 using value_type = range_value_t<_Base>;
8139 using iterator_concept = decltype(_S_iter_concept());
8140 // iterator_category defined in stride_view::__iter_cat
8141
8142 _Iterator() requires default_initializable<iterator_t<_Base>> = default;
8143
8144 constexpr
8145 _Iterator(_Iterator<!_Const> __other)
8146 requires _Const
8147 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
8148 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
8149 : _M_current(std::move(__other._M_current)), _M_end(std::move(__other._M_end)),
8150 _M_stride(__other._M_stride), _M_missing(__other._M_missing)
8151 { }
8152
8153 constexpr iterator_t<_Base>
8154 base() &&
8155 { return std::move(_M_current); }
8156
8157 constexpr const iterator_t<_Base>&
8158 base() const & noexcept
8159 { return _M_current; }
8160
8161 constexpr decltype(auto)
8162 operator*() const
8163 { return *_M_current; }
8164
8165 constexpr _Iterator&
8166 operator++()
8167 {
8168 __glibcxx_assert(_M_current != _M_end);
8169 _M_missing = ranges::advance(_M_current, _M_stride, _M_end);
8170 return *this;
8171 }
8172
8173 constexpr void
8174 operator++(int)
8175 { ++*this; }
8176
8177 constexpr _Iterator
8178 operator++(int) requires forward_range<_Base>
8179 {
8180 auto __tmp = *this;
8181 ++*this;
8182 return __tmp;
8183 }
8184
8185 constexpr _Iterator&
8186 operator--() requires bidirectional_range<_Base>
8187 {
8188 ranges::advance(_M_current, _M_missing - _M_stride);
8189 _M_missing = 0;
8190 return *this;
8191 }
8192
8193 constexpr _Iterator
8194 operator--(int) requires bidirectional_range<_Base>
8195 {
8196 auto __tmp = *this;
8197 --*this;
8198 return __tmp;
8199 }
8200
8201 constexpr _Iterator&
8202 operator+=(difference_type __n) requires random_access_range<_Base>
8203 {
8204 if (__n > 0)
8205 {
8206 __glibcxx_assert(ranges::distance(_M_current, _M_end) > _M_stride * (__n - 1));
8207 _M_missing = ranges::advance(_M_current, _M_stride * __n, _M_end);
8208 }
8209 else if (__n < 0)
8210 {
8211 ranges::advance(_M_current, _M_stride * __n + _M_missing);
8212 _M_missing = 0;
8213 }
8214 return *this;
8215 }
8216
8217 constexpr _Iterator&
8218 operator-=(difference_type __n) requires random_access_range<_Base>
8219 { return *this += -__n; }
8220
8221 constexpr decltype(auto) operator[](difference_type __n) const
8222 requires random_access_range<_Base>
8223 { return *(*this + __n); }
8224
8225 friend constexpr bool
8226 operator==(const _Iterator& __x, default_sentinel_t)
8227 { return __x._M_current == __x._M_end; }
8228
8229 friend constexpr bool
8230 operator==(const _Iterator& __x, const _Iterator& __y)
8231 requires equality_comparable<iterator_t<_Base>>
8232 { return __x._M_current == __y._M_current; }
8233
8234 friend constexpr bool
8235 operator<(const _Iterator& __x, const _Iterator& __y)
8236 requires random_access_range<_Base>
8237 { return __x._M_current < __y._M_current; }
8238
8239 friend constexpr bool
8240 operator>(const _Iterator& __x, const _Iterator& __y)
8241 requires random_access_range<_Base>
8242 { return __y._M_current < __x._M_current; }
8243
8244 friend constexpr bool
8245 operator<=(const _Iterator& __x, const _Iterator& __y)
8246 requires random_access_range<_Base>
8247 { return !(__y._M_current < __x._M_current); }
8248
8249 friend constexpr bool
8250 operator>=(const _Iterator& __x, const _Iterator& __y)
8251 requires random_access_range<_Base>
8252 { return !(__x._M_current < __y._M_current); }
8253
8254 friend constexpr auto
8255 operator<=>(const _Iterator& __x, const _Iterator& __y)
8256 requires random_access_range<_Base> && three_way_comparable<iterator_t<_Base>>
8257 { return __x._M_current <=> __y._M_current; }
8258
8259 friend constexpr _Iterator
8260 operator+(const _Iterator& __i, difference_type __n)
8261 requires random_access_range<_Base>
8262 {
8263 auto __r = __i;
8264 __r += __n;
8265 return __r;
8266 }
8267
8268 friend constexpr _Iterator
8269 operator+(difference_type __n, const _Iterator& __i)
8270 requires random_access_range<_Base>
8271 { return __i + __n; }
8272
8273 friend constexpr _Iterator
8274 operator-(const _Iterator& __i, difference_type __n)
8275 requires random_access_range<_Base>
8276 {
8277 auto __r = __i;
8278 __r -= __n;
8279 return __r;
8280 }
8281
8282 friend constexpr difference_type
8283 operator-(const _Iterator& __x, const _Iterator& __y)
8284 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
8285 {
8286 auto __n = __x._M_current - __y._M_current;
8287 if constexpr (forward_range<_Base>)
8288 return (__n + __x._M_missing - __y._M_missing) / __x._M_stride;
8289 else if (__n < 0)
8290 return -__detail::__div_ceil(-__n, __x._M_stride);
8291 else
8292 return __detail::__div_ceil(__n, __x._M_stride);
8293 }
8294
8295 friend constexpr difference_type
8296 operator-(default_sentinel_t __y, const _Iterator& __x)
8297 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
8298 { return __detail::__div_ceil(__x._M_end - __x._M_current, __x._M_stride); }
8299
8300 friend constexpr difference_type
8301 operator-(const _Iterator& __x, default_sentinel_t __y)
8302 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
8303 { return -(__y - __x); }
8304
8305 friend constexpr range_rvalue_reference_t<_Base>
8306 iter_move(const _Iterator& __i)
8307 noexcept(noexcept(ranges::iter_move(__i._M_current)))
8308 { return ranges::iter_move(__i._M_current); }
8309
8310 friend constexpr void
8311 iter_swap(const _Iterator& __x, const _Iterator& __y)
8312 noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
8313 requires indirectly_swappable<iterator_t<_Base>>
8314 { ranges::iter_swap(__x._M_current, __y._M_current); }
8315 };
8316
8317 namespace views
8318 {
8319 namespace __detail
8320 {
8321 template<typename _Range, typename _Dp>
8322 concept __can_stride_view
8323 = requires { stride_view(std::declval<_Range>(), std::declval<_Dp>()); };
8324 }
8325
8326 struct _Stride : __adaptor::_RangeAdaptor<_Stride>
8327 {
8328 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
8329 requires __detail::__can_stride_view<_Range, _Dp>
8330 constexpr auto
8331 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
8332 { return stride_view(std::forward<_Range>(__r), __n); }
8333
8334 using __adaptor::_RangeAdaptor<_Stride>::operator();
8335 static constexpr int _S_arity = 2;
8336 static constexpr bool _S_has_simple_extra_args = true;
8337 };
8338
8339 inline constexpr _Stride stride;
8340 }
8341#endif // __cpp_lib_ranges_stride
8342
8343#ifdef __cpp_lib_ranges_cartesian_product // C++ >= 23
8344 namespace __detail
8345 {
8346 template<bool _Const, typename _First, typename... _Vs>
8347 concept __cartesian_product_is_random_access
8348 = (random_access_range<__maybe_const_t<_Const, _First>>
8349 && ...
8350 && (random_access_range<__maybe_const_t<_Const, _Vs>>
8351 && sized_range<__maybe_const_t<_Const, _Vs>>));
8352
8353 template<typename _Range>
8354 concept __cartesian_product_common_arg
8355 = common_range<_Range> || (sized_range<_Range> && random_access_range<_Range>);
8356
8357 template<bool _Const, typename _First, typename... _Vs>
8358 concept __cartesian_product_is_bidirectional
8359 = (bidirectional_range<__maybe_const_t<_Const, _First>>
8360 && ...
8361 && (bidirectional_range<__maybe_const_t<_Const, _Vs>>
8362 && __cartesian_product_common_arg<__maybe_const_t<_Const, _Vs>>));
8363
8364 template<typename _First, typename... _Vs>
8365 concept __cartesian_product_is_common = __cartesian_product_common_arg<_First>;
8366
8367 template<typename... _Vs>
8368 concept __cartesian_product_is_sized = (sized_range<_Vs> && ...);
8369
8370 template<bool _Const, template<typename> class FirstSent, typename _First, typename... _Vs>
8371 concept __cartesian_is_sized_sentinel
8372 = (sized_sentinel_for<FirstSent<__maybe_const_t<_Const, _First>>,
8373 iterator_t<__maybe_const_t<_Const, _First>>>
8374 && ...
8375 && (sized_range<__maybe_const_t<_Const, _Vs>>
8376 && sized_sentinel_for<iterator_t<__maybe_const_t<_Const, _Vs>>,
8377 iterator_t<__maybe_const_t<_Const, _Vs>>>));
8378
8379 template<__cartesian_product_common_arg _Range>
8380 constexpr auto
8381 __cartesian_common_arg_end(_Range& __r)
8382 {
8383 if constexpr (common_range<_Range>)
8384 return ranges::end(__r);
8385 else
8386 return ranges::begin(__r) + ranges::distance(__r);
8387 }
8388 } // namespace __detail
8389
8390 template<input_range _First, forward_range... _Vs>
8391 requires (view<_First> && ... && view<_Vs>)
8392 class cartesian_product_view : public view_interface<cartesian_product_view<_First, _Vs...>>
8393 {
8394 tuple<_First, _Vs...> _M_bases;
8395
8396 template<bool> class _Iterator;
8397
8398 static auto
8399 _S_difference_type()
8400 {
8401 // TODO: Implement the recommended practice of using the smallest
8402 // sufficiently wide type according to the maximum sizes of the
8403 // underlying ranges?
8404 return common_type_t<ptrdiff_t,
8405 range_difference_t<_First>,
8406 range_difference_t<_Vs>...>{};
8407 }
8408
8409 public:
8410 cartesian_product_view() = default;
8411
8412 constexpr explicit
8413 cartesian_product_view(_First __first, _Vs... __rest)
8414 : _M_bases(std::move(__first), std::move(__rest)...)
8415 { }
8416
8417 constexpr _Iterator<false>
8418 begin() requires (!__detail::__simple_view<_First> || ... || !__detail::__simple_view<_Vs>)
8419 { return _Iterator<false>(*this, __detail::__tuple_transform(ranges::begin, _M_bases)); }
8420
8421 constexpr _Iterator<true>
8422 begin() const requires (range<const _First> && ... && range<const _Vs>)
8423 { return _Iterator<true>(*this, __detail::__tuple_transform(ranges::begin, _M_bases)); }
8424
8425 constexpr _Iterator<false>
8426 end() requires ((!__detail::__simple_view<_First> || ... || !__detail::__simple_view<_Vs>)
8427 && __detail::__cartesian_product_is_common<_First, _Vs...>)
8428 {
8429 auto __its = [this]<size_t... _Is>(index_sequence<_Is...>) {
8430 using _Ret = tuple<iterator_t<_First>, iterator_t<_Vs>...>;
8431 bool __empty_tail = (ranges::empty(std::get<1 + _Is>(_M_bases)) || ...);
8432 auto& __first = std::get<0>(_M_bases);
8433 return _Ret{(__empty_tail
8434 ? ranges::begin(__first)
8435 : __detail::__cartesian_common_arg_end(__first)),
8436 ranges::begin(std::get<1 + _Is>(_M_bases))...};
8437 }(make_index_sequence<sizeof...(_Vs)>{});
8438
8439 return _Iterator<false>{*this, std::move(__its)};
8440 }
8441
8442 constexpr _Iterator<true>
8443 end() const requires __detail::__cartesian_product_is_common<const _First, const _Vs...>
8444 {
8445 auto __its = [this]<size_t... _Is>(index_sequence<_Is...>) {
8446 using _Ret = tuple<iterator_t<const _First>, iterator_t<const _Vs>...>;
8447 bool __empty_tail = (ranges::empty(std::get<1 + _Is>(_M_bases)) || ...);
8448 auto& __first = std::get<0>(_M_bases);
8449 return _Ret{(__empty_tail
8450 ? ranges::begin(__first)
8451 : __detail::__cartesian_common_arg_end(__first)),
8452 ranges::begin(std::get<1 + _Is>(_M_bases))...};
8453 }(make_index_sequence<sizeof...(_Vs)>{});
8454
8455 return _Iterator<true>{*this, std::move(__its)};
8456 }
8457
8458 constexpr default_sentinel_t
8459 end() const noexcept
8460 { return default_sentinel; }
8461
8462 constexpr auto
8463 size() requires __detail::__cartesian_product_is_sized<_First, _Vs...>
8464 {
8465 using _ST = __detail::__make_unsigned_like_t<decltype(_S_difference_type())>;
8466 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8467 auto __size = static_cast<_ST>(1);
8468#ifdef _GLIBCXX_ASSERTIONS
8469 if constexpr (integral<_ST>)
8470 {
8471 bool __overflow
8472 = (__builtin_mul_overflow(__size,
8473 static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))),
8474 &__size)
8475 || ...);
8476 __glibcxx_assert(!__overflow);
8477 }
8478 else
8479#endif
8480 __size = (static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))) * ...);
8481 return __size;
8482 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8483 }
8484
8485 constexpr auto
8486 size() const requires __detail::__cartesian_product_is_sized<const _First, const _Vs...>
8487 {
8488 using _ST = __detail::__make_unsigned_like_t<decltype(_S_difference_type())>;
8489 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8490 auto __size = static_cast<_ST>(1);
8491#ifdef _GLIBCXX_ASSERTIONS
8492 if constexpr (integral<_ST>)
8493 {
8494 bool __overflow
8495 = (__builtin_mul_overflow(__size,
8496 static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))),
8497 &__size)
8498 || ...);
8499 __glibcxx_assert(!__overflow);
8500 }
8501 else
8502#endif
8503 __size = (static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))) * ...);
8504 return __size;
8505 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8506 }
8507 };
8508
8509 template<typename... _Vs>
8510 cartesian_product_view(_Vs&&...) -> cartesian_product_view<views::all_t<_Vs>...>;
8511
8512 template<input_range _First, forward_range... _Vs>
8513 requires (view<_First> && ... && view<_Vs>)
8514 template<bool _Const>
8515 class cartesian_product_view<_First, _Vs...>::_Iterator
8516 {
8517 using _Parent = __maybe_const_t<_Const, cartesian_product_view>;
8518 _Parent* _M_parent = nullptr;
8519 tuple<iterator_t<__maybe_const_t<_Const, _First>>,
8520 iterator_t<__maybe_const_t<_Const, _Vs>>...> _M_current;
8521
8522 constexpr
8523 _Iterator(_Parent& __parent, decltype(_M_current) __current)
8524 : _M_parent(std::__addressof(__parent)),
8525 _M_current(std::move(__current))
8526 { }
8527
8528 static auto
8529 _S_iter_concept()
8530 {
8531 if constexpr (__detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>)
8532 return random_access_iterator_tag{};
8533 else if constexpr (__detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>)
8534 return bidirectional_iterator_tag{};
8535 else if constexpr (forward_range<__maybe_const_t<_Const, _First>>)
8536 return forward_iterator_tag{};
8537 else
8538 return input_iterator_tag{};
8539 }
8540
8541 friend cartesian_product_view;
8542
8543 public:
8544 using iterator_category = input_iterator_tag;
8545 using iterator_concept = decltype(_S_iter_concept());
8546 using value_type
8547 = tuple<range_value_t<__maybe_const_t<_Const, _First>>,
8548 range_value_t<__maybe_const_t<_Const, _Vs>>...>;
8549 using reference
8550 = tuple<range_reference_t<__maybe_const_t<_Const, _First>>,
8551 range_reference_t<__maybe_const_t<_Const, _Vs>>...>;
8552 using difference_type = decltype(cartesian_product_view::_S_difference_type());
8553
8554 _Iterator() = default;
8555
8556 constexpr
8557 _Iterator(_Iterator<!_Const> __i)
8558 requires _Const
8559 && (convertible_to<iterator_t<_First>, iterator_t<const _First>>
8560 && ... && convertible_to<iterator_t<_Vs>, iterator_t<const _Vs>>)
8561 : _M_parent(std::__addressof(__i._M_parent)),
8562 _M_current(std::move(__i._M_current))
8563 { }
8564
8565 constexpr auto
8566 operator*() const
8567 {
8568 auto __f = [](auto& __i) -> decltype(auto) {
8569 return *__i;
8570 };
8571 return __detail::__tuple_transform(__f, _M_current);
8572 }
8573
8574 constexpr _Iterator&
8575 operator++()
8576 {
8577 _M_next();
8578 return *this;
8579 }
8580
8581 constexpr void
8582 operator++(int)
8583 { ++*this; }
8584
8585 constexpr _Iterator
8586 operator++(int) requires forward_range<__maybe_const_t<_Const, _First>>
8587 {
8588 auto __tmp = *this;
8589 ++*this;
8590 return __tmp;
8591 }
8592
8593 constexpr _Iterator&
8594 operator--()
8595 requires __detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>
8596 {
8597 _M_prev();
8598 return *this;
8599 }
8600
8601 constexpr _Iterator
8602 operator--(int)
8603 requires __detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>
8604 {
8605 auto __tmp = *this;
8606 --*this;
8607 return __tmp;
8608 }
8609
8610 constexpr _Iterator&
8611 operator+=(difference_type __x)
8612 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8613 {
8614 _M_advance(__x);
8615 return *this;
8616 }
8617
8618 constexpr _Iterator&
8619 operator-=(difference_type __x)
8620 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8621 { return *this += -__x; }
8622
8623 constexpr reference
8624 operator[](difference_type __n) const
8625 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8626 { return *((*this) + __n); }
8627
8628 friend constexpr bool
8629 operator==(const _Iterator& __x, const _Iterator& __y)
8630 requires equality_comparable<iterator_t<__maybe_const_t<_Const, _First>>>
8631 { return __x._M_current == __y._M_current; }
8632
8633 friend constexpr bool
8634 operator==(const _Iterator& __x, default_sentinel_t)
8635 {
8636 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8637 return ((std::get<_Is>(__x._M_current)
8638 == ranges::end(std::get<_Is>(__x._M_parent->_M_bases)))
8639 || ...);
8640 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8641 }
8642
8643 friend constexpr auto
8644 operator<=>(const _Iterator& __x, const _Iterator& __y)
8645 requires __detail::__all_random_access<_Const, _First, _Vs...>
8646 { return __x._M_current <=> __y._M_current; }
8647
8648 friend constexpr _Iterator
8649 operator+(_Iterator __x, difference_type __y)
8650 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8651 { return __x += __y; }
8652
8653 friend constexpr _Iterator
8654 operator+(difference_type __x, _Iterator __y)
8655 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8656 { return __y += __x; }
8657
8658 friend constexpr _Iterator
8659 operator-(_Iterator __x, difference_type __y)
8660 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8661 { return __x -= __y; }
8662
8663 friend constexpr difference_type
8664 operator-(const _Iterator& __x, const _Iterator& __y)
8665 requires __detail::__cartesian_is_sized_sentinel<_Const, iterator_t, _First, _Vs...>
8666 { return __x._M_distance_from(__y._M_current); }
8667
8668 friend constexpr difference_type
8669 operator-(const _Iterator& __i, default_sentinel_t)
8670 requires __detail::__cartesian_is_sized_sentinel<_Const, sentinel_t, _First, _Vs...>
8671 {
8672 tuple __end_tuple = [&]<size_t... _Is>(index_sequence<_Is...>) {
8673 return tuple{ranges::end(std::get<0>(__i._M_parent->_M_bases)),
8674 ranges::begin(std::get<1 + _Is>(__i._M_parent->_M_bases))...};
8675 }(make_index_sequence<sizeof...(_Vs)>{});
8676 return __i._M_distance_from(__end_tuple);
8677 }
8678
8679 friend constexpr difference_type
8680 operator-(default_sentinel_t, const _Iterator& __i)
8681 requires __detail::__cartesian_is_sized_sentinel<_Const, sentinel_t, _First, _Vs...>
8682 { return -(__i - default_sentinel); }
8683
8684 friend constexpr auto
8685 iter_move(const _Iterator& __i)
8686 { return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
8687
8688 friend constexpr void
8689 iter_swap(const _Iterator& __l, const _Iterator& __r)
8690 requires (indirectly_swappable<iterator_t<__maybe_const_t<_Const, _First>>>
8691 && ...
8692 && indirectly_swappable<iterator_t<__maybe_const_t<_Const, _Vs>>>)
8693 {
8694 [&]<size_t... _Is>(index_sequence<_Is...>) {
8695 (ranges::iter_swap(std::get<_Is>(__l._M_current), std::get<_Is>(__r._M_current)), ...);
8696 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8697 }
8698
8699 private:
8700 template<size_t _Nm = sizeof...(_Vs)>
8701 constexpr void
8702 _M_next()
8703 {
8704 auto& __it = std::get<_Nm>(_M_current);
8705 ++__it;
8706 if constexpr (_Nm > 0)
8707 if (__it == ranges::end(std::get<_Nm>(_M_parent->_M_bases)))
8708 {
8709 __it = ranges::begin(std::get<_Nm>(_M_parent->_M_bases));
8710 _M_next<_Nm - 1>();
8711 }
8712 }
8713
8714 template<size_t _Nm = sizeof...(_Vs)>
8715 constexpr void
8716 _M_prev()
8717 {
8718 auto& __it = std::get<_Nm>(_M_current);
8719 if constexpr (_Nm > 0)
8720 if (__it == ranges::begin(std::get<_Nm>(_M_parent->_M_bases)))
8721 {
8722 __it = __detail::__cartesian_common_arg_end(std::get<_Nm>(_M_parent->_M_bases));
8723 _M_prev<_Nm - 1>();
8724 }
8725 --__it;
8726 }
8727
8728 template<size_t _Nm = sizeof...(_Vs)>
8729 constexpr void
8730 _M_advance(difference_type __x)
8731 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8732 {
8733 if (__x == 1)
8734 _M_next<_Nm>();
8735 else if (__x == -1)
8736 _M_prev<_Nm>();
8737 else if (__x != 0)
8738 {
8739 // Constant time iterator advancement.
8740 auto& __r = std::get<_Nm>(_M_parent->_M_bases);
8741 auto& __it = std::get<_Nm>(_M_current);
8742 if constexpr (_Nm == 0)
8743 {
8744#ifdef _GLIBCXX_ASSERTIONS
8745 if constexpr (sized_range<__maybe_const_t<_Const, _First>>)
8746 {
8747 auto __size = ranges::ssize(__r);
8748 auto __begin = ranges::begin(__r);
8749 auto __offset = __it - __begin;
8750 __glibcxx_assert(__offset + __x >= 0 && __offset + __x <= __size);
8751 }
8752#endif
8753 __it += __x;
8754 }
8755 else
8756 {
8757 auto __size = ranges::ssize(__r);
8758 auto __begin = ranges::begin(__r);
8759 auto __offset = __it - __begin;
8760 __offset += __x;
8761 __x = __offset / __size;
8762 __offset %= __size;
8763 if (__offset < 0)
8764 {
8765 __offset = __size + __offset;
8766 --__x;
8767 }
8768 __it = __begin + __offset;
8769 _M_advance<_Nm - 1>(__x);
8770 }
8771 }
8772 }
8773
8774 template<typename _Tuple>
8775 constexpr difference_type
8776 _M_distance_from(const _Tuple& __t) const
8777 {
8778 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8779 auto __sum = static_cast<difference_type>(0);
8780#ifdef _GLIBCXX_ASSERTIONS
8781 if constexpr (integral<difference_type>)
8782 {
8783 bool __overflow
8784 = (__builtin_add_overflow(__sum, _M_scaled_distance<_Is>(__t), &__sum)
8785 || ...);
8786 __glibcxx_assert(!__overflow);
8787 }
8788 else
8789#endif
8790 __sum = (_M_scaled_distance<_Is>(__t) + ...);
8791 return __sum;
8792 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8793 }
8794
8795 template<size_t _Nm, typename _Tuple>
8796 constexpr difference_type
8797 _M_scaled_distance(const _Tuple& __t) const
8798 {
8799 auto __dist = static_cast<difference_type>(std::get<_Nm>(_M_current)
8800 - std::get<_Nm>(__t));
8801#ifdef _GLIBCXX_ASSERTIONS
8802 if constexpr (integral<difference_type>)
8803 {
8804 bool __overflow = __builtin_mul_overflow(__dist, _M_scaled_size<_Nm+1>(), &__dist);
8805 __glibcxx_assert(!__overflow);
8806 }
8807 else
8808#endif
8809 __dist *= _M_scaled_size<_Nm+1>();
8810 return __dist;
8811 }
8812
8813 template<size_t _Nm>
8814 constexpr difference_type
8815 _M_scaled_size() const
8816 {
8817 if constexpr (_Nm <= sizeof...(_Vs))
8818 {
8819 auto __size = static_cast<difference_type>(ranges::size
8820 (std::get<_Nm>(_M_parent->_M_bases)));
8821#ifdef _GLIBCXX_ASSERTIONS
8822 if constexpr (integral<difference_type>)
8823 {
8824 bool __overflow = __builtin_mul_overflow(__size, _M_scaled_size<_Nm+1>(), &__size);
8825 __glibcxx_assert(!__overflow);
8826 }
8827 else
8828#endif
8829 __size *= _M_scaled_size<_Nm+1>();
8830 return __size;
8831 }
8832 else
8833 return static_cast<difference_type>(1);
8834 }
8835 };
8836
8837 namespace views
8838 {
8839 namespace __detail
8840 {
8841 template<typename... _Ts>
8842 concept __can_cartesian_product_view
8843 = requires { cartesian_product_view<all_t<_Ts>...>(std::declval<_Ts>()...); };
8844 }
8845
8846 struct _CartesianProduct
8847 {
8848 template<typename... _Ts>
8849 requires (sizeof...(_Ts) == 0 || __detail::__can_cartesian_product_view<_Ts...>)
8850 constexpr auto
8851 operator() [[nodiscard]] (_Ts&&... __ts) const
8852 {
8853 if constexpr (sizeof...(_Ts) == 0)
8854 return views::single(tuple{});
8855 else
8856 return cartesian_product_view<all_t<_Ts>...>(std::forward<_Ts>(__ts)...);
8857 }
8858 };
8859
8860 inline constexpr _CartesianProduct cartesian_product;
8861 }
8862#endif // __cpp_lib_ranges_cartesian_product
8863
8864#ifdef __cpp_lib_ranges_as_rvalue // C++ >= 23
8865 template<input_range _Vp>
8866 requires view<_Vp>
8867 class as_rvalue_view : public view_interface<as_rvalue_view<_Vp>>
8868 {
8869 _Vp _M_base = _Vp();
8870
8871 public:
8872 as_rvalue_view() requires default_initializable<_Vp> = default;
8873
8874 constexpr explicit
8875 as_rvalue_view(_Vp __base)
8876 : _M_base(std::move(__base))
8877 { }
8878
8879 constexpr _Vp
8880 base() const& requires copy_constructible<_Vp>
8881 { return _M_base; }
8882
8883 constexpr _Vp
8884 base() &&
8885 { return std::move(_M_base); }
8886
8887 constexpr auto
8888 begin() requires (!__detail::__simple_view<_Vp>)
8889 { return move_iterator(ranges::begin(_M_base)); }
8890
8891 constexpr auto
8892 begin() const requires range<const _Vp>
8893 { return move_iterator(ranges::begin(_M_base)); }
8894
8895 constexpr auto
8896 end() requires (!__detail::__simple_view<_Vp>)
8897 {
8898 if constexpr (common_range<_Vp>)
8899 return move_iterator(ranges::end(_M_base));
8900 else
8901 return move_sentinel(ranges::end(_M_base));
8902 }
8903
8904 constexpr auto
8905 end() const requires range<const _Vp>
8906 {
8907 if constexpr (common_range<const _Vp>)
8908 return move_iterator(ranges::end(_M_base));
8909 else
8910 return move_sentinel(ranges::end(_M_base));
8911 }
8912
8913 constexpr auto
8914 size() requires sized_range<_Vp>
8915 { return ranges::size(_M_base); }
8916
8917 constexpr auto
8918 size() const requires sized_range<const _Vp>
8919 { return ranges::size(_M_base); }
8920 };
8921
8922 template<typename _Range>
8923 as_rvalue_view(_Range&&) -> as_rvalue_view<views::all_t<_Range>>;
8924
8925 template<typename _Tp>
8926 inline constexpr bool enable_borrowed_range<as_rvalue_view<_Tp>>
8927 = enable_borrowed_range<_Tp>;
8928
8929 namespace views
8930 {
8931 namespace __detail
8932 {
8933 template<typename _Tp>
8934 concept __can_as_rvalue_view = requires { as_rvalue_view(std::declval<_Tp>()); };
8935 }
8936
8937 struct _AsRvalue : __adaptor::_RangeAdaptorClosure<_AsRvalue>
8938 {
8939 template<viewable_range _Range>
8940 requires __detail::__can_as_rvalue_view<_Range>
8941 constexpr auto
8942 operator() [[nodiscard]] (_Range&& __r) const
8943 {
8944 if constexpr (same_as<range_rvalue_reference_t<_Range>,
8945 range_reference_t<_Range>>)
8946 return views::all(std::forward<_Range>(__r));
8947 else
8948 return as_rvalue_view(std::forward<_Range>(__r));
8949 }
8950 };
8951
8952 inline constexpr _AsRvalue as_rvalue;
8953 }
8954#endif // __cpp_lib_as_rvalue
8955
8956#ifdef __cpp_lib_ranges_enumerate // C++ >= 23
8957 namespace __detail
8958 {
8959 template<typename _Range>
8960 concept __range_with_movable_reference = input_range<_Range>
8961 && move_constructible<range_reference_t<_Range>>
8962 && move_constructible<range_rvalue_reference_t<_Range>>;
8963 }
8964
8965 template<view _Vp>
8966 requires __detail::__range_with_movable_reference<_Vp>
8967 class enumerate_view : public view_interface<enumerate_view<_Vp>>
8968 {
8969 _Vp _M_base = _Vp();
8970
8971 template<bool _Const> class _Iterator;
8972 template<bool _Const> class _Sentinel;
8973
8974 public:
8975 enumerate_view() requires default_initializable<_Vp> = default;
8976
8977 constexpr explicit
8978 enumerate_view(_Vp __base)
8979 : _M_base(std::move(__base))
8980 { }
8981
8982 constexpr auto
8983 begin() requires (!__detail::__simple_view<_Vp>)
8984 { return _Iterator<false>(ranges::begin(_M_base), 0); }
8985
8986 constexpr auto
8987 begin() const requires __detail::__range_with_movable_reference<const _Vp>
8988 { return _Iterator<true>(ranges::begin(_M_base), 0); }
8989
8990 constexpr auto
8991 end() requires (!__detail::__simple_view<_Vp>)
8992 {
8993 if constexpr (common_range<_Vp> && sized_range<_Vp>)
8994 return _Iterator<false>(ranges::end(_M_base), ranges::distance(_M_base));
8995 else
8996 return _Sentinel<false>(ranges::end(_M_base));
8997 }
8998
8999 constexpr auto
9000 end() const requires __detail::__range_with_movable_reference<const _Vp>
9001 {
9002 if constexpr (common_range<const _Vp> && sized_range<const _Vp>)
9003 return _Iterator<true>(ranges::end(_M_base), ranges::distance(_M_base));
9004 else
9005 return _Sentinel<true>(ranges::end(_M_base));
9006 }
9007
9008 constexpr auto
9009 size() requires sized_range<_Vp>
9010 { return ranges::size(_M_base); }
9011
9012 constexpr auto
9013 size() const requires sized_range<const _Vp>
9014 { return ranges::size(_M_base); }
9015
9016 constexpr _Vp
9017 base() const & requires copy_constructible<_Vp>
9018 { return _M_base; }
9019
9020 constexpr _Vp
9021 base() &&
9022 { return std::move(_M_base); }
9023 };
9024
9025 template<typename _Range>
9026 enumerate_view(_Range&&) -> enumerate_view<views::all_t<_Range>>;
9027
9028 template<typename _Tp>
9029 inline constexpr bool enable_borrowed_range<enumerate_view<_Tp>>
9030 = enable_borrowed_range<_Tp>;
9031
9032 template<view _Vp>
9033 requires __detail::__range_with_movable_reference<_Vp>
9034 template<bool _Const>
9035 class enumerate_view<_Vp>::_Iterator
9036 {
9037 using _Base = __maybe_const_t<_Const, _Vp>;
9038
9039 static auto
9040 _S_iter_concept()
9041 {
9042 if constexpr (random_access_range<_Base>)
9043 return random_access_iterator_tag{};
9044 else if constexpr (bidirectional_range<_Base>)
9045 return bidirectional_iterator_tag{};
9046 else if constexpr (forward_range<_Base>)
9047 return forward_iterator_tag{};
9048 else
9049 return input_iterator_tag{};
9050 }
9051
9052 friend enumerate_view;
9053
9054 public:
9055 using iterator_category = input_iterator_tag;
9056 using iterator_concept = decltype(_S_iter_concept());
9057 using difference_type = range_difference_t<_Base>;
9058 using value_type = tuple<difference_type, range_value_t<_Base>>;
9059
9060 private:
9061 using __reference_type = tuple<difference_type, range_reference_t<_Base>>;
9062
9063 iterator_t<_Base> _M_current = iterator_t<_Base>();
9064 difference_type _M_pos = 0;
9065
9066 constexpr explicit
9067 _Iterator(iterator_t<_Base> __current, difference_type __pos)
9068 : _M_current(std::move(__current)), _M_pos(__pos)
9069 { }
9070
9071 public:
9072 _Iterator() requires default_initializable<iterator_t<_Base>> = default;
9073
9074 constexpr
9075 _Iterator(_Iterator<!_Const> __i)
9076 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
9077 : _M_current(std::move(__i._M_current)), _M_pos(__i._M_pos)
9078 { }
9079
9080 constexpr const iterator_t<_Base> &
9081 base() const & noexcept
9082 { return _M_current; }
9083
9084 constexpr iterator_t<_Base>
9085 base() &&
9086 { return std::move(_M_current); }
9087
9088 constexpr difference_type
9089 index() const noexcept
9090 { return _M_pos; }
9091
9092 constexpr auto
9093 operator*() const
9094 { return __reference_type(_M_pos, *_M_current); }
9095
9096 constexpr _Iterator&
9097 operator++()
9098 {
9099 ++_M_current;
9100 ++_M_pos;
9101 return *this;
9102 }
9103
9104 constexpr void
9105 operator++(int)
9106 { ++*this; }
9107
9108 constexpr _Iterator
9109 operator++(int) requires forward_range<_Base>
9110 {
9111 auto __tmp = *this;
9112 ++*this;
9113 return __tmp;
9114 }
9115
9116 constexpr _Iterator&
9117 operator--() requires bidirectional_range<_Base>
9118 {
9119 --_M_current;
9120 --_M_pos;
9121 return *this;
9122 }
9123
9124 constexpr _Iterator
9125 operator--(int) requires bidirectional_range<_Base>
9126 {
9127 auto __tmp = *this;
9128 --*this;
9129 return __tmp;
9130 }
9131
9132 constexpr _Iterator&
9133 operator+=(difference_type __n) requires random_access_range<_Base>
9134 {
9135 _M_current += __n;
9136 _M_pos += __n;
9137 return *this;
9138 }
9139
9140 constexpr _Iterator&
9141 operator-=(difference_type __n) requires random_access_range<_Base>
9142 {
9143 _M_current -= __n;
9144 _M_pos -= __n;
9145 return *this;
9146 }
9147
9148 constexpr auto
9149 operator[](difference_type __n) const requires random_access_range<_Base>
9150 { return __reference_type(_M_pos + __n, _M_current[__n]); }
9151
9152 friend constexpr bool
9153 operator==(const _Iterator& __x, const _Iterator& __y) noexcept
9154 { return __x._M_pos == __y._M_pos; }
9155
9156 friend constexpr strong_ordering
9157 operator<=>(const _Iterator& __x, const _Iterator& __y) noexcept
9158 { return __x._M_pos <=> __y._M_pos; }
9159
9160 friend constexpr _Iterator
9161 operator+(const _Iterator& __x, difference_type __y)
9162 requires random_access_range<_Base>
9163 { return (auto(__x) += __y); }
9164
9165 friend constexpr _Iterator
9166 operator+(difference_type __x, const _Iterator& __y)
9167 requires random_access_range<_Base>
9168 { return auto(__y) += __x; }
9169
9170 friend constexpr _Iterator
9171 operator-(const _Iterator& __x, difference_type __y)
9172 requires random_access_range<_Base>
9173 { return auto(__x) -= __y; }
9174
9175 friend constexpr difference_type
9176 operator-(const _Iterator& __x, const _Iterator& __y)
9177 { return __x._M_pos - __y._M_pos; }
9178
9179 friend constexpr auto
9180 iter_move(const _Iterator& __i)
9181 noexcept(noexcept(ranges::iter_move(__i._M_current))
9182 && is_nothrow_move_constructible_v<range_rvalue_reference_t<_Base>>)
9183 {
9184 return tuple<difference_type, range_rvalue_reference_t<_Base>>
9185 (__i._M_pos, ranges::iter_move(__i._M_current));
9186 }
9187 };
9188
9189 template<view _Vp>
9190 requires __detail::__range_with_movable_reference<_Vp>
9191 template<bool _Const>
9192 class enumerate_view<_Vp>::_Sentinel
9193 {
9194 using _Base = __maybe_const_t<_Const, _Vp>;
9195
9196 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
9197
9198 constexpr explicit
9199 _Sentinel(sentinel_t<_Base> __end)
9200 : _M_end(std::move(__end))
9201 { }
9202
9203 friend enumerate_view;
9204
9205 public:
9206 _Sentinel() = default;
9207
9208 constexpr
9209 _Sentinel(_Sentinel<!_Const> __other)
9210 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
9211 : _M_end(std::move(__other._M_end))
9212 { }
9213
9214 constexpr sentinel_t<_Base>
9215 base() const
9216 { return _M_end; }
9217
9218 template<bool _OtherConst>
9219 requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
9220 friend constexpr bool
9221 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
9222 { return __x._M_current == __y._M_end; }
9223
9224 template<bool _OtherConst>
9225 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
9226 friend constexpr range_difference_t<__maybe_const_t<_OtherConst, _Vp>>
9227 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
9228 { return __x._M_current - __y._M_end; }
9229
9230 template<bool _OtherConst>
9231 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
9232 friend constexpr range_difference_t<__maybe_const_t<_OtherConst, _Vp>>
9233 operator-(const _Sentinel& __x, const _Iterator<_OtherConst>& __y)
9234 { return __x._M_end - __y._M_current; }
9235 };
9236
9237 namespace views
9238 {
9239 namespace __detail
9240 {
9241 template<typename _Tp>
9242 concept __can_enumerate_view
9243 = requires { enumerate_view<all_t<_Tp>>(std::declval<_Tp>()); };
9244 }
9245
9246 struct _Enumerate : __adaptor::_RangeAdaptorClosure<_Enumerate>
9247 {
9248 template<viewable_range _Range>
9249 requires __detail::__can_enumerate_view<_Range>
9250 constexpr auto
9251 operator() [[nodiscard]] (_Range&& __r) const
9252 { return enumerate_view<all_t<_Range>>(std::forward<_Range>(__r)); }
9253 };
9254
9255 inline constexpr _Enumerate enumerate;
9256 }
9257#endif // __cpp_lib_ranges_enumerate
9258
9259#ifdef __cpp_lib_ranges_as_const // C++ >= 23
9260 template<view _Vp>
9261 requires input_range<_Vp>
9262 class as_const_view : public view_interface<as_const_view<_Vp>>
9263 {
9264 _Vp _M_base = _Vp();
9265
9266 public:
9267 as_const_view() requires default_initializable<_Vp> = default;
9268
9269 constexpr explicit
9270 as_const_view(_Vp __base)
9271 noexcept(is_nothrow_move_constructible_v<_Vp>)
9272 : _M_base(std::move(__base))
9273 { }
9274
9275 constexpr _Vp
9276 base() const &
9277 noexcept(is_nothrow_copy_constructible_v<_Vp>)
9278 requires copy_constructible<_Vp>
9279 { return _M_base; }
9280
9281 constexpr _Vp
9282 base() &&
9283 noexcept(is_nothrow_move_constructible_v<_Vp>)
9284 { return std::move(_M_base); }
9285
9286 constexpr auto
9287 begin() requires (!__detail::__simple_view<_Vp>)
9288 { return ranges::cbegin(_M_base); }
9289
9290 constexpr auto
9291 begin() const requires range<const _Vp>
9292 { return ranges::cbegin(_M_base); }
9293
9294 constexpr auto
9295 end() requires (!__detail::__simple_view<_Vp>)
9296 { return ranges::cend(_M_base); }
9297
9298 constexpr auto
9299 end() const requires range<const _Vp>
9300 { return ranges::cend(_M_base); }
9301
9302 constexpr auto
9303 size() requires sized_range<_Vp>
9304 { return ranges::size(_M_base); }
9305
9306 constexpr auto
9307 size() const requires sized_range<const _Vp>
9308 { return ranges::size(_M_base); }
9309 };
9310
9311 template<typename _Range>
9312 as_const_view(_Range&&) -> as_const_view<views::all_t<_Range>>;
9313
9314 template<typename _Tp>
9315 inline constexpr bool enable_borrowed_range<as_const_view<_Tp>>
9316 = enable_borrowed_range<_Tp>;
9317
9318 namespace views
9319 {
9320 namespace __detail
9321 {
9322 template<typename _Tp>
9323 inline constexpr bool __is_ref_view = false;
9324
9325 template<typename _Range>
9326 inline constexpr bool __is_ref_view<ref_view<_Range>> = true;
9327
9328 template<typename _Range>
9329 concept __can_as_const_view = requires { as_const_view(std::declval<_Range>()); };
9330 }
9331
9332 struct _AsConst : __adaptor::_RangeAdaptorClosure<_AsConst>
9333 {
9334 template<viewable_range _Range>
9335 constexpr auto
9336 operator()(_Range&& __r) const
9337 noexcept(noexcept(as_const_view(std::declval<_Range>())))
9338 requires __detail::__can_as_const_view<_Range>
9339 {
9340 using _Tp = remove_cvref_t<_Range>;
9341 using element_type = remove_reference_t<range_reference_t<_Range>>;
9342 if constexpr (constant_range<views::all_t<_Range>>)
9343 return views::all(std::forward<_Range>(__r));
9344 else if constexpr (__detail::__is_empty_view<_Tp>)
9345 return views::empty<const element_type>;
9346 else if constexpr (std::__detail::__is_span<_Tp>)
9347 return span<const element_type, _Tp::extent>(std::forward<_Range>(__r));
9348 else if constexpr (__detail::__is_ref_view<_Tp>
9349 && constant_range<const element_type>)
9350 return ref_view(static_cast<const element_type&>
9351 (std::forward<_Range>(__r).base()));
9352 else if constexpr (is_lvalue_reference_v<_Range>
9353 && constant_range<const _Tp>
9354 && !view<_Tp>)
9355 return ref_view(static_cast<const _Tp&>(__r));
9356 else
9357 return as_const_view(std::forward<_Range>(__r));
9358 }
9359 };
9360
9361 inline constexpr _AsConst as_const;
9362 }
9363#endif // __cpp_lib_as_const
9364} // namespace ranges
9365
9366 namespace views = ranges::views;
9367
9368#if __cpp_lib_ranges_to_container // C++ >= 23
9369namespace ranges
9370{
9371/// @cond undocumented
9372namespace __detail
9373{
9374 template<typename _Container>
9375 constexpr bool __reservable_container
9376 = sized_range<_Container>
9377 && requires(_Container& __c, range_size_t<_Container> __n) {
9378 __c.reserve(__n);
9379 { __c.capacity() } -> same_as<decltype(__n)>;
9380 { __c.max_size() } -> same_as<decltype(__n)>;
9381 };
9382
9383 template<typename _Cont, typename _Range>
9384 constexpr bool __toable = requires {
9385 requires (!input_range<_Cont>
9386 || convertible_to<range_reference_t<_Range>,
9387 range_value_t<_Cont>>);
9388 };
9389} // namespace __detail
9390/// @endcond
9391
9392 /// Convert a range to a container.
9393 /**
9394 * @tparam _Cont A container type.
9395 * @param __r A range that models the `input_range` concept.
9396 * @param __args... Arguments to pass to the container constructor.
9397 * @since C++23
9398 *
9399 * This function converts a range to the `_Cont` type.
9400 *
9401 * For example, `std::ranges::to<std::vector<int>>(some_view)`
9402 * will convert the view to `std::vector<int>`.
9403 *
9404 * Additional constructor arguments for the container can be supplied after
9405 * the input range argument, e.g.
9406 * `std::ranges::to<std::vector<int, Alloc<int>>>(a_range, an_allocator)`.
9407 */
9408 template<typename _Cont, input_range _Rg, typename... _Args>
9409 requires (!view<_Cont>)
9410 constexpr _Cont
9411 to [[nodiscard]] (_Rg&& __r, _Args&&... __args)
9412 {
9413 static_assert(!is_const_v<_Cont> && !is_volatile_v<_Cont>);
9414 static_assert(is_class_v<_Cont>);
9415
9416 if constexpr (__detail::__toable<_Cont, _Rg>)
9417 {
9418 if constexpr (constructible_from<_Cont, _Rg, _Args...>)
9419 return _Cont(std::forward<_Rg>(__r),
9420 std::forward<_Args>(__args)...);
9421 else if constexpr (constructible_from<_Cont, from_range_t, _Rg, _Args...>)
9422 return _Cont(from_range, std::forward<_Rg>(__r),
9423 std::forward<_Args>(__args)...);
9424 else if constexpr (requires { requires common_range<_Rg>;
9425 typename __iter_category_t<iterator_t<_Rg>>;
9426 requires derived_from<__iter_category_t<iterator_t<_Rg>>,
9427 input_iterator_tag>;
9428 requires constructible_from<_Cont, iterator_t<_Rg>,
9429 sentinel_t<_Rg>, _Args...>;
9430 })
9431 return _Cont(ranges::begin(__r), ranges::end(__r),
9432 std::forward<_Args>(__args)...);
9433 else
9434 {
9435 static_assert(constructible_from<_Cont, _Args...>);
9436 _Cont __c(std::forward<_Args>(__args)...);
9437 if constexpr (sized_range<_Rg>
9438 && __detail::__reservable_container<_Cont>)
9439 __c.reserve(static_cast<range_size_t<_Cont>>(ranges::size(__r)));
9440 // _GLIBCXX_RESOLVE_LIB_DEFECTS
9441 // 4016. container-insertable checks do not match what
9442 // container-inserter does
9443 auto __it = ranges::begin(__r);
9444 const auto __sent = ranges::end(__r);
9445 while (__it != __sent)
9446 {
9447 if constexpr (requires { __c.emplace_back(*__it); })
9448 __c.emplace_back(*__it);
9449 else if constexpr (requires { __c.push_back(*__it); })
9450 __c.push_back(*__it);
9451 else if constexpr (requires { __c.emplace(__c.end(), *__it); })
9452 __c.emplace(__c.end(), *__it);
9453 else
9454 __c.insert(__c.end(), *__it);
9455 ++__it;
9456 }
9457 return __c;
9458 }
9459 }
9460 else
9461 {
9462 static_assert(input_range<range_reference_t<_Rg>>);
9463 // _GLIBCXX_RESOLVE_LIB_DEFECTS
9464 // 3984. ranges::to's recursion branch may be ill-formed
9465 return ranges::to<_Cont>(ref_view(__r) | views::transform(
9466 []<typename _Elt>(_Elt&& __elem) {
9467 using _ValT = range_value_t<_Cont>;
9468 return ranges::to<_ValT>(std::forward<_Elt>(__elem));
9469 }), std::forward<_Args>(__args)...);
9470 }
9471 }
9472
9473/// @cond undocumented
9474namespace __detail
9475{
9476 template<typename _Rg>
9477 struct _InputIter
9478 {
9479 using iterator_category = input_iterator_tag;
9480 using value_type = range_value_t<_Rg>;
9481 using difference_type = ptrdiff_t;
9482 using pointer = add_pointer_t<range_reference_t<_Rg>>;
9483 using reference = range_reference_t<_Rg>;
9484 reference operator*() const;
9485 pointer operator->() const;
9486 _InputIter& operator++();
9487 _InputIter operator++(int);
9488 bool operator==(const _InputIter&) const;
9489 };
9490
9491 template<template<typename...> typename _Cont, input_range _Rg,
9492 typename... _Args>
9493 using _DeduceExpr1
9494 = decltype(_Cont(std::declval<_Rg>(), std::declval<_Args>()...));
9495
9496 template<template<typename...> typename _Cont, input_range _Rg,
9497 typename... _Args>
9498 using _DeduceExpr2
9499 = decltype(_Cont(from_range, std::declval<_Rg>(),
9500 std::declval<_Args>()...));
9501
9502 template<template<typename...> typename _Cont, input_range _Rg,
9503 typename... _Args>
9504 using _DeduceExpr3
9505 = decltype(_Cont(std::declval<_InputIter<_Rg>>(),
9506 std::declval<_InputIter<_Rg>>(),
9507 std::declval<_Args>()...));
9508
9509} // namespace __detail
9510/// @endcond
9511
9512 template<template<typename...> typename _Cont, input_range _Rg,
9513 typename... _Args>
9514 constexpr auto
9515 to [[nodiscard]] (_Rg&& __r, _Args&&... __args)
9516 {
9517 using __detail::_DeduceExpr1;
9518 using __detail::_DeduceExpr2;
9519 using __detail::_DeduceExpr3;
9520 if constexpr (requires { typename _DeduceExpr1<_Cont, _Rg, _Args...>; })
9521 return ranges::to<_DeduceExpr1<_Cont, _Rg, _Args...>>(
9522 std::forward<_Rg>(__r), std::forward<_Args>(__args)...);
9523 else if constexpr (requires { typename _DeduceExpr2<_Cont, _Rg, _Args...>; })
9524 return ranges::to<_DeduceExpr2<_Cont, _Rg, _Args...>>(
9525 std::forward<_Rg>(__r), std::forward<_Args>(__args)...);
9526 else if constexpr (requires { typename _DeduceExpr3<_Cont, _Rg, _Args...>; })
9527 return ranges::to<_DeduceExpr3<_Cont, _Rg, _Args...>>(
9528 std::forward<_Rg>(__r), std::forward<_Args>(__args)...);
9529 else
9530 static_assert(false); // Cannot deduce container specialization.
9531 }
9532
9533/// @cond undocumented
9534namespace __detail
9535{
9536 template<typename _Cont>
9537 struct _To
9538 {
9539 template<typename _Range, typename... _Args>
9540 requires requires { ranges::to<_Cont>(std::declval<_Range>(),
9541 std::declval<_Args>()...); }
9542 constexpr auto
9543 operator()(_Range&& __r, _Args&&... __args) const
9544 {
9545 return ranges::to<_Cont>(std::forward<_Range>(__r),
9546 std::forward<_Args>(__args)...);
9547 }
9548 };
9549} // namespace __detail
9550/// @endcond
9551
9552 /// ranges::to adaptor for converting a range to a container type
9553 /**
9554 * @tparam _Cont A container type.
9555 * @param __args... Arguments to pass to the container constructor.
9556 * @since C++23
9557 *
9558 * This range adaptor returns a range adaptor closure object that converts
9559 * a range to the `_Cont` type.
9560 *
9561 * For example, `some_view | std::ranges::to<std::vector<int>>()`
9562 * will convert the view to `std::vector<int>`.
9563 *
9564 * Additional constructor arguments for the container can be supplied, e.g.
9565 * `r | std::ranges::to<std::vector<int, Alloc<int>>>(an_allocator)`.
9566 */
9567 template<typename _Cont, typename... _Args>
9568 requires (!view<_Cont>)
9569 constexpr auto
9570 to [[nodiscard]] (_Args&&... __args)
9571 {
9572 static_assert(!is_const_v<_Cont> && !is_volatile_v<_Cont>);
9573 static_assert(is_class_v<_Cont>);
9574
9575 using __detail::_To;
9576 using views::__adaptor::_Partial;
9577 return _Partial<_To<_Cont>, decay_t<_Args>...>{0, std::forward<_Args>(__args)...};
9578 }
9579
9580/// @cond undocumented
9581namespace __detail
9582{
9583 template<template<typename...> typename _Cont>
9584 struct _To2
9585 {
9586 template<typename _Range, typename... _Args>
9587 requires requires { ranges::to<_Cont>(std::declval<_Range>(),
9588 std::declval<_Args>()...); }
9589 constexpr auto
9590 operator()(_Range&& __r, _Args&&... __args) const
9591 {
9592 return ranges::to<_Cont>(std::forward<_Range>(__r),
9593 std::forward<_Args>(__args)...);
9594 }
9595 };
9596} // namespace __detail
9597/// @endcond
9598
9599 /// ranges::to adaptor for converting a range to a deduced container type.
9600 /**
9601 * @tparam _Cont A container template.
9602 * @param __args... Arguments to pass to the container constructor.
9603 * @since C++23
9604 *
9605 * This range adaptor returns a range adaptor closure object that converts
9606 * a range to a specialization of the `_Cont` class template. The specific
9607 * specialization of `_Cont` to be used is deduced automatically.
9608 *
9609 * For example, `some_view | std::ranges::to<std::vector>(Alloc<int>{})`
9610 * will convert the view to `std::vector<T, Alloc<T>>`, where `T` is the
9611 * view's value type, i.e. `std::ranges::range_value_t<decltype(some_view)>`.
9612 *
9613 * Additional constructor arguments for the container can be supplied, e.g.
9614 * `r | std::ranges::to<std::vector>(an_allocator)`.
9615 */
9616 template<template<typename...> typename _Cont, typename... _Args>
9617 constexpr auto
9618 to [[nodiscard]] (_Args&&... __args)
9619 {
9620 using __detail::_To2;
9621 using views::__adaptor::_Partial;
9622 return _Partial<_To2<_Cont>, decay_t<_Args>...>{0, std::forward<_Args>(__args)...};
9623 }
9624
9625} // namespace ranges
9626#endif // __cpp_lib_ranges_to_container
9627
9628#if __cpp_lib_ranges_concat // C++ >= C++26
9629namespace ranges
9630{
9631 namespace __detail
9632 {
9633 template<typename... _Rs>
9634 using __concat_reference_t = common_reference_t<range_reference_t<_Rs>...>;
9635
9636 template<typename... _Rs>
9637 using __concat_value_t = common_type_t<range_value_t<_Rs>...>;
9638
9639 template<typename... _Rs>
9640 using __concat_rvalue_reference_t
9641 = common_reference_t<range_rvalue_reference_t<_Rs>...>;
9642
9643 template<typename _Ref, typename _RRef, typename _It>
9644 concept __concat_indirectly_readable_impl = requires(const _It __it) {
9645 { *__it } -> convertible_to<_Ref>;
9646 { ranges::iter_move(__it) } -> convertible_to<_RRef>;
9647 };
9648
9649 template<typename... _Rs>
9650 concept __concat_indirectly_readable
9651 = common_reference_with<__concat_reference_t<_Rs...>&&, __concat_value_t<_Rs...>&>
9652 && common_reference_with<__concat_reference_t<_Rs...>&&,
9653 __concat_rvalue_reference_t<_Rs...>&&>
9654 && common_reference_with<__concat_rvalue_reference_t<_Rs...>&&,
9655 __concat_value_t<_Rs...> const&>
9656 && (__concat_indirectly_readable_impl<__concat_reference_t<_Rs...>,
9657 __concat_rvalue_reference_t<_Rs...>,
9658 iterator_t<_Rs>>
9659 && ...);
9660
9661 template<typename... _Rs>
9662 concept __concatable = requires {
9663 typename __concat_reference_t<_Rs...>;
9664 typename __concat_value_t<_Rs...>;
9665 typename __concat_rvalue_reference_t<_Rs...>;
9666 } && __concat_indirectly_readable<_Rs...>;
9667
9668 template<bool _Const, typename _Range, typename... _Rs>
9669 struct __all_but_last_common
9670 {
9671 static inline constexpr bool value
9672 = requires { requires (common_range<__maybe_const_t<_Const, _Range>>
9673 && __all_but_last_common<_Const, _Rs...>::value); };
9674 };
9675
9676 template<bool _Const, typename _Range>
9677 struct __all_but_last_common<_Const, _Range>
9678 { static inline constexpr bool value = true; };
9679
9680 template<bool _Const, typename... _Rs>
9681 concept __concat_is_random_access = __all_random_access<_Const, _Rs...>
9682 && __all_but_last_common<_Const, _Rs...>::value;
9683
9684 template<bool _Const, typename... _Rs>
9685 concept __concat_is_bidirectional = __all_bidirectional<_Const, _Rs...>
9686 && __all_but_last_common<_Const, _Rs...>::value;
9687
9688 template<typename _Range, typename... _Rs>
9689 struct __all_but_first_sized
9690 { static inline constexpr bool value = (sized_range<_Rs> && ...); };
9691 } // namespace __detail
9692
9693 template<input_range... _Vs>
9694 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && __detail::__concatable<_Vs...>
9695 class concat_view : public view_interface<concat_view<_Vs...>>
9696 {
9697 tuple<_Vs...> _M_views;
9698
9699 template<bool _Const> class _Iterator;
9700
9701 public:
9702 constexpr concat_view() = default;
9703
9704 constexpr explicit
9705 concat_view(_Vs... __views)
9706 : _M_views(std::move(__views)...)
9707 { }
9708
9709 constexpr _Iterator<false>
9710 begin() requires (!(__detail::__simple_view<_Vs> && ...))
9711 {
9712 _Iterator<false> __it(this, in_place_index<0>, ranges::begin(std::get<0>(_M_views)));
9713 __it.template _M_satisfy<0>();
9714 return __it;
9715 }
9716
9717 constexpr _Iterator<true>
9718 begin() const requires (range<const _Vs> && ...) && __detail::__concatable<const _Vs...>
9719 {
9720 _Iterator<true> __it(this, in_place_index<0>, ranges::begin(std::get<0>(_M_views)));
9721 __it.template _M_satisfy<0>();
9722 return __it;
9723 }
9724
9725 constexpr auto
9726 end() requires (!(__detail::__simple_view<_Vs> && ...))
9727 {
9728 constexpr auto __n = sizeof...(_Vs);
9729 if constexpr ((semiregular<iterator_t<_Vs>> && ...)
9730 && common_range<_Vs...[__n - 1]>)
9731 return _Iterator<false>(this, in_place_index<__n - 1>,
9732 ranges::end(std::get<__n - 1>(_M_views)));
9733 else
9734 return default_sentinel;
9735 }
9736
9737 constexpr auto
9738 end() const requires (range<const _Vs> && ...) && __detail::__concatable<const _Vs...>
9739 {
9740 constexpr auto __n = sizeof...(_Vs);
9741 if constexpr ((semiregular<iterator_t<const _Vs>> && ...)
9742 && common_range<const _Vs...[__n - 1]>)
9743 return _Iterator<true>(this, in_place_index<__n - 1>,
9744 ranges::end(std::get<__n - 1>(_M_views)));
9745 else
9746 return default_sentinel;
9747 }
9748
9749 constexpr auto
9750 size() requires (sized_range<_Vs>&&...)
9751 {
9752 return std::apply([](auto... __sizes) {
9753 using _CT = __detail::__make_unsigned_like_t<common_type_t<decltype(__sizes)...>>;
9754 return (_CT(__sizes) + ...);
9755 }, __detail::__tuple_transform(ranges::size, _M_views));
9756 }
9757
9758 constexpr auto
9759 size() const requires (sized_range<const _Vs>&&...)
9760 {
9761 return std::apply([](auto... __sizes) {
9762 using _CT = __detail::__make_unsigned_like_t<common_type_t<decltype(__sizes)...>>;
9763 return (_CT(__sizes) + ...);
9764 }, __detail::__tuple_transform(ranges::size, _M_views));
9765 }
9766 };
9767
9768 template<typename... _Rs>
9769 concat_view(_Rs&&...) -> concat_view<views::all_t<_Rs>...>;
9770
9771 namespace __detail
9772 {
9773 template<bool _Const, typename... _Vs>
9774 struct __concat_view_iter_cat
9775 { };
9776
9777 template<bool _Const, typename... _Vs>
9778 requires __detail::__all_forward<_Const, _Vs...>
9779 struct __concat_view_iter_cat<_Const, _Vs...>
9780 {
9781 static auto
9782 _S_iter_cat()
9783 {
9784 if constexpr (!is_reference_v<__concat_reference_t<__maybe_const_t<_Const, _Vs>...>>)
9785 return input_iterator_tag{};
9786 else
9787 return []<typename... _Cats>(_Cats... __cats) {
9788 if constexpr ((derived_from<_Cats, random_access_iterator_tag> && ...)
9789 && __concat_is_random_access<_Const, _Vs...>)
9790 return random_access_iterator_tag{};
9791 else if constexpr ((derived_from<_Cats, bidirectional_iterator_tag> && ...)
9792 && __concat_is_bidirectional<_Const, _Vs...>)
9793 return bidirectional_iterator_tag{};
9794 else if constexpr ((derived_from<_Cats, forward_iterator_tag> && ...))
9795 return forward_iterator_tag{};
9796 else
9797 return input_iterator_tag{};
9798 }(typename iterator_traits<iterator_t<__maybe_const_t<_Const, _Vs>>>
9799 ::iterator_category{}...);
9800 }
9801 };
9802 }
9803
9804 template<input_range... _Vs>
9805 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && __detail::__concatable<_Vs...>
9806 template<bool _Const>
9807 class concat_view<_Vs...>::_Iterator
9808 : public __detail::__concat_view_iter_cat<_Const, _Vs...>
9809 {
9810 static auto
9811 _S_iter_concept()
9812 {
9813 if constexpr (__detail::__concat_is_random_access<_Const, _Vs...>)
9814 return random_access_iterator_tag{};
9815 else if constexpr (__detail::__concat_is_bidirectional<_Const, _Vs...>)
9816 return bidirectional_iterator_tag{};
9817 else if constexpr (__detail::__all_forward<_Const, _Vs...>)
9818 return forward_iterator_tag{};
9819 else
9820 return input_iterator_tag{};
9821 }
9822
9823 friend concat_view;
9824 friend _Iterator<!_Const>;
9825
9826 public:
9827 // iterator_category defined in __concat_view_iter_cat
9828 using iterator_concept = decltype(_S_iter_concept());
9829 using value_type = __detail::__concat_value_t<__maybe_const_t<_Const, _Vs>...>;
9830 using difference_type = common_type_t<range_difference_t<__maybe_const_t<_Const, _Vs>>...>;
9831
9832 private:
9833 using __base_iter = variant<iterator_t<__maybe_const_t<_Const, _Vs>>...>;
9834
9835 __maybe_const_t<_Const, concat_view>* _M_parent = nullptr;
9836 __base_iter _M_it;
9837
9838 template<size_t _Nm>
9839 constexpr void
9840 _M_satisfy()
9841 {
9842 if constexpr (_Nm < (sizeof...(_Vs) - 1))
9843 {
9844 if (std::get<_Nm>(_M_it) == ranges::end(std::get<_Nm>(_M_parent->_M_views)))
9845 {
9846 _M_it.template emplace<_Nm + 1>(ranges::begin
9847 (std::get<_Nm + 1>(_M_parent->_M_views)));
9848 _M_satisfy<_Nm + 1>();
9849 }
9850 }
9851 }
9852
9853 template<size_t _Nm>
9854 constexpr void
9855 _M_prev()
9856 {
9857 if constexpr (_Nm == 0)
9858 --std::get<0>(_M_it);
9859 else
9860 {
9861 if (std::get<_Nm>(_M_it) == ranges::begin(std::get<_Nm>(_M_parent->_M_views)))
9862 {
9863 _M_it.template emplace<_Nm - 1>(ranges::end
9864 (std::get<_Nm - 1>(_M_parent->_M_views)));
9865 _M_prev<_Nm - 1>();
9866 }
9867 else
9868 --std::get<_Nm>(_M_it);
9869 }
9870 }
9871
9872 template<size_t _Nm>
9873 constexpr void
9874 _M_advance_fwd(difference_type __offset, difference_type __steps)
9875 {
9876 using _Dt = iter_difference_t<variant_alternative_t<_Nm, __base_iter>>;
9877 if constexpr (_Nm == sizeof...(_Vs) - 1)
9878 std::get<_Nm>(_M_it) += static_cast<_Dt>(__steps);
9879 else
9880 {
9881 auto __n_size = ranges::distance(std::get<_Nm>(_M_parent->_M_views));
9882 if (__offset + __steps < __n_size)
9883 std::get<_Nm>(_M_it) += static_cast<_Dt>(__steps);
9884 else
9885 {
9886 _M_it.template emplace<_Nm + 1>(ranges::begin
9887 (std::get<_Nm + 1>(_M_parent->_M_views)));
9888 _M_advance_fwd<_Nm + 1>(0, __offset + __steps - __n_size);
9889 }
9890 }
9891 }
9892
9893 template<size_t _Nm>
9894 constexpr void
9895 _M_advance_bwd(difference_type __offset, difference_type __steps)
9896 {
9897 using _Dt = iter_difference_t<variant_alternative_t<_Nm, __base_iter>>;
9898 if constexpr (_Nm == 0)
9899 std::get<_Nm>(_M_it) -= static_cast<_Dt>(__steps);
9900 else {
9901 if (__offset >= __steps)
9902 std::get<_Nm>(_M_it) -= static_cast<_Dt>(__steps);
9903 else
9904 {
9905 auto __prev_size = ranges::distance(std::get<_Nm - 1>(_M_parent->_M_views));
9906 _M_it.template emplace<_Nm - 1>(ranges::end
9907 (std::get<_Nm - 1>(_M_parent->_M_views)));
9908 _M_advance_bwd<_Nm - 1>(__prev_size, __steps - __offset);
9909 }
9910 }
9911 }
9912
9913 // Invoke the function object __f, which has a call operator with a size_t
9914 // template parameter (corresponding to an index into the pack of views),
9915 // using the runtime value of __index as the template argument.
9916 template<typename _Fp>
9917 static constexpr auto
9918 _S_invoke_with_runtime_index(_Fp&& __f, size_t __index)
9919 {
9920 return [&__f, __index]<size_t _Idx>(this auto&& __self) {
9921 if (_Idx == __index)
9922 return __f.template operator()<_Idx>();
9923 if constexpr (_Idx + 1 < sizeof...(_Vs))
9924 return __self.template operator()<_Idx + 1>();
9925 }.template operator()<0>();
9926 }
9927
9928 template<typename _Fp>
9929 constexpr auto
9930 _M_invoke_with_runtime_index(_Fp&& __f)
9931 { return _S_invoke_with_runtime_index(std::forward<_Fp>(__f), _M_it.index()); }
9932
9933 template<typename... _Args>
9934 explicit constexpr
9935 _Iterator(__maybe_const_t<_Const, concat_view>* __parent, _Args&&... __args)
9936 requires constructible_from<__base_iter, _Args&&...>
9937 : _M_parent(__parent), _M_it(std::forward<_Args>(__args)...)
9938 { }
9939
9940 public:
9941 _Iterator() = default;
9942
9943 constexpr
9944 _Iterator(_Iterator<!_Const> __it)
9945 requires _Const && (convertible_to<iterator_t<_Vs>, iterator_t<const _Vs>> && ...)
9946 : _M_parent(__it._M_parent)
9947 {
9948 _M_invoke_with_runtime_index([this, &__it]<size_t _Idx>() {
9949 _M_it.template emplace<_Idx>(std::get<_Idx>(std::move(__it._M_it)));
9950 });
9951 }
9952
9953 constexpr decltype(auto)
9954 operator*() const
9955 {
9956 __glibcxx_assert(!_M_it.valueless_by_exception());
9957 using reference = __detail::__concat_reference_t<__maybe_const_t<_Const, _Vs>...>;
9958 return std::visit([](auto&& __it) -> reference { return *__it; }, _M_it);
9959 }
9960
9961 constexpr _Iterator&
9962 operator++()
9963 {
9964 _M_invoke_with_runtime_index([this]<size_t _Idx>() {
9965 ++std::get<_Idx>(_M_it);
9966 _M_satisfy<_Idx>();
9967 });
9968 return *this;
9969 }
9970
9971 constexpr void
9972 operator++(int)
9973 { ++*this; }
9974
9975 constexpr _Iterator
9976 operator++(int)
9977 requires __detail::__all_forward<_Const, _Vs...>
9978 {
9979 auto __tmp = *this;
9980 ++*this;
9981 return __tmp;
9982 }
9983
9984 constexpr _Iterator&
9985 operator--()
9986 requires __detail::__concat_is_bidirectional<_Const, _Vs...>
9987 {
9988 __glibcxx_assert(!_M_it.valueless_by_exception());
9989 _M_invoke_with_runtime_index([this]<size_t _Idx>() {
9990 _M_prev<_Idx>();
9991 });
9992 return *this;
9993 }
9994
9995 constexpr _Iterator
9996 operator--(int)
9997 requires __detail::__concat_is_bidirectional<_Const, _Vs...>
9998 {
9999 auto __tmp = *this;
10000 --*this;
10001 return __tmp;
10002 }
10003
10004 constexpr _Iterator&
10005 operator+=(difference_type __n)
10006 requires __detail::__concat_is_random_access<_Const, _Vs...>
10007 {
10008 __glibcxx_assert(!_M_it.valueless_by_exception());
10009 _M_invoke_with_runtime_index([this, __n]<size_t _Idx>() {
10010 auto __begin = ranges::begin(std::get<_Idx>(_M_parent->_M_views));
10011 if (__n > 0)
10012 _M_advance_fwd<_Idx>(std::get<_Idx>(_M_it) - __begin, __n);
10013 else if (__n < 0)
10014 _M_advance_bwd<_Idx>(std::get<_Idx>(_M_it) - __begin, -__n);
10015 });
10016 return *this;
10017 }
10018
10019 constexpr _Iterator&
10020 operator-=(difference_type __n)
10021 requires __detail::__concat_is_random_access<_Const, _Vs...>
10022 {
10023 *this += -__n;
10024 return *this;
10025 }
10026
10027 constexpr decltype(auto)
10028 operator[](difference_type __n) const
10029 requires __detail::__concat_is_random_access<_Const, _Vs...>
10030 { return *((*this) + __n); }
10031
10032 friend constexpr bool
10033 operator==(const _Iterator& __x, const _Iterator& __y)
10034 requires (equality_comparable<iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
10035 {
10036 __glibcxx_assert(!__x._M_it.valueless_by_exception());
10037 __glibcxx_assert(!__y._M_it.valueless_by_exception());
10038 return __x._M_it == __y._M_it;
10039 }
10040
10041 friend constexpr bool
10042 operator==(const _Iterator& __it, default_sentinel_t)
10043 {
10044 __glibcxx_assert(!__it._M_it.valueless_by_exception());
10045 constexpr auto __last_idx = sizeof...(_Vs) - 1;
10046 return (__it._M_it.index() == __last_idx
10047 && (std::get<__last_idx>(__it._M_it)
10048 == ranges::end(std::get<__last_idx>(__it._M_parent->_M_views))));
10049 }
10050
10051 friend constexpr bool
10052 operator<(const _Iterator& __x, const _Iterator& __y)
10053 requires __detail::__all_random_access<_Const, _Vs...>
10054 { return __x._M_it < __y._M_it; }
10055
10056 friend constexpr bool
10057 operator>(const _Iterator& __x, const _Iterator& __y)
10058 requires __detail::__all_random_access<_Const, _Vs...>
10059 { return __x._M_it > __y._M_it; }
10060
10061 friend constexpr bool
10062 operator<=(const _Iterator& __x, const _Iterator& __y)
10063 requires __detail::__all_random_access<_Const, _Vs...>
10064 { return __x._M_it <= __y._M_it; }
10065
10066 friend constexpr bool
10067 operator>=(const _Iterator& __x, const _Iterator& __y)
10068 requires __detail::__all_random_access<_Const, _Vs...>
10069 { return __x._M_it >= __y._M_it; }
10070
10071 friend constexpr auto
10072 operator<=>(const _Iterator& __x, const _Iterator& __y)
10073 requires __detail::__all_random_access<_Const, _Vs...>
10074 && (three_way_comparable<iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
10075 { return __x._M_it <=> __y._M_it; }
10076
10077 friend constexpr _Iterator
10078 operator+(const _Iterator& __it, difference_type __n)
10079 requires __detail::__concat_is_random_access<_Const, _Vs...>
10080 { return auto(__it) += __n; }
10081
10082 friend constexpr _Iterator
10083 operator+(difference_type __n, const _Iterator& __it)
10084 requires __detail::__concat_is_random_access<_Const, _Vs...>
10085 { return __it + __n; }
10086
10087 friend constexpr _Iterator
10088 operator-(const _Iterator& __it, difference_type __n)
10089 requires __detail::__concat_is_random_access<_Const, _Vs...>
10090 { return auto(__it) -= __n; }
10091
10092 friend constexpr difference_type
10093 operator-(const _Iterator& __x, const _Iterator& __y)
10094 requires __detail::__concat_is_random_access<_Const, _Vs...>
10095 {
10096 return _S_invoke_with_runtime_index([&]<size_t _Ix>() -> difference_type {
10097 return _S_invoke_with_runtime_index([&]<size_t _Iy>() -> difference_type {
10098 if constexpr (_Ix > _Iy)
10099 {
10100 auto __dy = ranges::distance(std::get<_Iy>(__y._M_it),
10101 ranges::end(std::get<_Iy>(__y._M_parent
10102 ->_M_views)));
10103 auto __dx = ranges::distance(ranges::begin(std::get<_Ix>(__x._M_parent
10104 ->_M_views)),
10105 std::get<_Ix>(__x._M_it));
10106 difference_type __s = 0;
10107 [&]<size_t _Idx = _Iy + 1>(this auto&& __self) {
10108 if constexpr (_Idx < _Ix)
10109 {
10110 __s += ranges::size(std::get<_Idx>(__x._M_parent->_M_views));
10111 __self.template operator()<_Idx + 1>();
10112 }
10113 }();
10114 return __dy + __s + __dx;
10115 }
10116 else if constexpr (_Ix < _Iy)
10117 return -(__y - __x);
10118 else
10119 return std::get<_Ix>(__x._M_it) - std::get<_Iy>(__y._M_it);
10120 }, __y._M_it.index());
10121 }, __x._M_it.index());
10122 }
10123
10124 friend constexpr difference_type
10125 operator-(const _Iterator& __x, default_sentinel_t)
10126 requires (sized_sentinel_for<sentinel_t<__maybe_const_t<_Const, _Vs>>,
10127 iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
10128 && __detail::__all_but_first_sized<__maybe_const_t<_Const, _Vs>...>::value
10129 {
10130 return _S_invoke_with_runtime_index([&]<size_t _Ix>() -> difference_type {
10131 auto __dx = ranges::distance(std::get<_Ix>(__x._M_it),
10132 ranges::end(std::get<_Ix>(__x._M_parent->_M_views)));
10133 difference_type __s = 0;
10134 [&]<size_t _Idx = _Ix + 1>(this auto&& __self) {
10135 if constexpr (_Idx < sizeof...(_Vs))
10136 {
10137 __s += ranges::size(std::get<_Idx>(__x._M_parent->_M_views));
10138 __self.template operator()<_Idx + 1>();
10139 }
10140 }();
10141 return -(__dx + __s);
10142 }, __x._M_it.index());
10143 }
10144
10145 friend constexpr difference_type
10146 operator-(default_sentinel_t, const _Iterator& __x)
10147 requires (sized_sentinel_for<sentinel_t<__maybe_const_t<_Const, _Vs>>,
10148 iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
10149 && __detail::__all_but_first_sized<__maybe_const_t<_Const, _Vs>...>::value
10150 { return -(__x - default_sentinel); }
10151
10152 friend constexpr decltype(auto)
10153 iter_move(const _Iterator& __it)
10154 {
10155 using _Res = __detail::__concat_rvalue_reference_t<__maybe_const_t<_Const, _Vs>...>;
10156 return std::visit([](const auto& __i) -> _Res {
10157 return ranges::iter_move(__i);
10158 }, __it._M_it);
10159 }
10160
10161 friend constexpr void
10162 iter_swap(const _Iterator& __x, const _Iterator& __y)
10163 requires swappable_with<iter_reference_t<_Iterator>, iter_reference_t<_Iterator>>
10164 && (... && indirectly_swappable<iterator_t<__maybe_const_t<_Const, _Vs>>>)
10165 {
10166 std::visit([&]<typename _Tp, typename _Up>(const _Tp& __it1, const _Up& __it2) {
10167 if constexpr (is_same_v<_Tp, _Up>)
10168 ranges::iter_swap(__it1, __it2);
10169 else
10170 ranges::swap(*__it1, *__it2);
10171 }, __x._M_it, __y._M_it);
10172 }
10173 };
10174
10175 namespace views
10176 {
10177 namespace __detail
10178 {
10179 template<typename... _Ts>
10180 concept __can_concat_view = requires { concat_view(std::declval<_Ts>()...); };
10181 }
10182
10183 struct _Concat
10184 {
10185 template<typename... _Ts>
10186 requires __detail::__can_concat_view<_Ts...>
10187 constexpr auto
10188 operator() [[nodiscard]] (_Ts&&... __ts) const
10189 {
10190 if constexpr (sizeof...(_Ts) == 1)
10191 return views::all(std::forward<_Ts>(__ts)...);
10192 else
10193 return concat_view(std::forward<_Ts>(__ts)...);
10194 }
10195 };
10196
10197 inline constexpr _Concat concat;
10198 }
10199
10200} // namespace ranges
10201#endif // __cpp_lib_ranges_concat
10202
10203_GLIBCXX_END_NAMESPACE_VERSION
10204} // namespace std
10205#endif // library concepts
10206#endif // C++2a
10207#endif /* _GLIBCXX_RANGES */
constexpr bool operator<=(const duration< _Rep1, _Period1 > &__lhs, const duration< _Rep2, _Period2 > &__rhs)
Definition chrono.h:859
constexpr bool operator>=(const duration< _Rep1, _Period1 > &__lhs, const duration< _Rep2, _Period2 > &__rhs)
Definition chrono.h:873
constexpr bool operator<(const duration< _Rep1, _Period1 > &__lhs, const duration< _Rep2, _Period2 > &__rhs)
Definition chrono.h:826
constexpr bool operator>(const duration< _Rep1, _Period1 > &__lhs, const duration< _Rep2, _Period2 > &__rhs)
Definition chrono.h:866
constexpr complex< _Tp > operator*(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x times y.
Definition complex:405
constexpr complex< _Tp > operator-(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x minus y.
Definition complex:375
constexpr complex< _Tp > operator+(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x plus y.
Definition complex:345
basic_istream< char > istream
Base class for char input streams.
Definition iosfwd:142
constexpr _Tp * to_address(_Tp *__ptr) noexcept
Obtain address referenced by a pointer to an object.
Definition ptr_traits.h:232
typename make_unsigned< _Tp >::type make_unsigned_t
Alias template for make_unsigned.
Definition type_traits:2143
typename common_type< _Tp... >::type common_type_t
Alias template for common_type.
Definition type_traits:2845
typename conditional< _Cond, _Iftrue, _Iffalse >::type conditional_t
Alias template for conditional.
Definition type_traits:2841
constexpr auto tuple_cat(_Tpls &&... __tpls) -> typename __tuple_cat_result< _Tpls... >::__type
Create a tuple containing all elements from multiple tuple-like objects.
Definition tuple:2803
auto declval() noexcept -> decltype(__declval< _Tp >(0))
Definition type_traits:2611
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
Definition move.h:138
constexpr __invoke_result< _Callable, _Args... >::type __invoke(_Callable &&__fn, _Args &&... __args) noexcept(__is_nothrow_invocable< _Callable, _Args... >::value)
Invoke a callable object.
Definition invoke.h:92
constexpr _Tp * __addressof(_Tp &__r) noexcept
Same as C++11 std::addressof.
Definition move.h:52
constexpr _Tp && forward(typename std::remove_reference< _Tp >::type &__t) noexcept
Forward an lvalue.
Definition move.h:72
_Tp * end(valarray< _Tp > &__va) noexcept
Return an iterator pointing to one past the last element of the valarray.
Definition valarray:1251
_Tp * begin(valarray< _Tp > &__va) noexcept
Return an iterator pointing to the first element of the valarray.
Definition valarray:1229
constexpr const _Tp & min(const _Tp &, const _Tp &)
This does what you think it does.
constexpr reverse_iterator< _Iterator > make_reverse_iterator(_Iterator __i)
Generator function for reverse_iterator.
constexpr void iota(_ForwardIterator __first, _ForwardIterator __last, _Tp __value)
Create a range of sequentially increasing values.
Definition stl_numeric.h:88
ISO C++ entities toplevel namespace is std.
make_integer_sequence< size_t, _Num > make_index_sequence
Alias template make_index_sequence.
Definition utility.h:188
constexpr auto empty(const _Container &__cont) noexcept(noexcept(__cont.empty())) -> decltype(__cont.empty())
Return whether a container is empty.
constexpr auto size(const _Container &__cont) noexcept(noexcept(__cont.size())) -> decltype(__cont.size())
Return the size of a container.
constexpr default_sentinel_t default_sentinel
A default sentinel value.
constexpr auto data(_Container &__cont) noexcept(noexcept(__cont.data())) -> decltype(__cont.data())
Return the data pointer of a container.
constexpr bitset< _Nb > operator|(const bitset< _Nb > &__x, const bitset< _Nb > &__y) noexcept
Global bitwise operations on bitsets.
Definition bitset:1572
integer_sequence< size_t, _Idx... > index_sequence
Alias template index_sequence.
Definition utility.h:184
constexpr _Iterator __base(_Iterator __it)