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