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