libstdc++
ranges
Go to the documentation of this file.
1// <ranges> -*- C++ -*-
2
3// Copyright (C) 2019-2025 Free Software Foundation, Inc.
4//
5// This file is part of the GNU ISO C++ Library. This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 3, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23// <http://www.gnu.org/licenses/>.
24
25/** @file include/ranges
26 * This is a Standard C++ Library header.
27 * @ingroup concepts
28 */
29
30#ifndef _GLIBCXX_RANGES
31#define _GLIBCXX_RANGES 1
32
33#if __cplusplus > 201703L
34
35#ifdef _GLIBCXX_SYSHDR
36#pragma GCC system_header
37#endif
38
39#include <concepts>
40
41#if __cpp_lib_concepts
42
43#include <compare>
44#include <initializer_list>
45#include <iterator>
46#include <optional>
47#include <span>
48#include <string_view>
49#include <tuple>
50#if __cplusplus > 202002L
51#include <variant>
52#endif
53#include <bits/ranges_util.h>
54#include <bits/refwrap.h>
55
56#define __glibcxx_want_algorithm_default_value_type
57#define __glibcxx_want_ranges
58#define __glibcxx_want_ranges_as_const
59#define __glibcxx_want_ranges_as_rvalue
60#define __glibcxx_want_ranges_cache_latest
61#define __glibcxx_want_ranges_cartesian_product
62#define __glibcxx_want_ranges_concat
63#define __glibcxx_want_ranges_chunk
64#define __glibcxx_want_ranges_chunk_by
65#define __glibcxx_want_ranges_enumerate
66#define __glibcxx_want_ranges_iota
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 optional<_Inner_iter> _M_inner;
3027 _Parent* _M_parent = nullptr;
3028
3029 public:
3030 using iterator_concept = decltype(_S_iter_concept());
3031 // iterator_category defined in __join_view_iter_cat
3032 using value_type = range_value_t<range_reference_t<_Base>>;
3033 using difference_type
3034 = common_type_t<range_difference_t<_Base>,
3035 range_difference_t<range_reference_t<_Base>>>;
3036
3037 _Iterator() = default;
3038
3039 constexpr
3040 _Iterator(_Iterator<!_Const> __i)
3041 requires _Const
3042 && convertible_to<iterator_t<_Vp>, _Outer_iter>
3043 && convertible_to<iterator_t<_InnerRange>, _Inner_iter>
3044 : _M_outer(std::move(__i._M_outer)), _M_inner(std::move(__i._M_inner)),
3045 _M_parent(__i._M_parent)
3046 { }
3047
3048 constexpr decltype(auto)
3049 operator*() const
3050 { return **_M_inner; }
3051
3052 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3053 // 3500. join_view::iterator::operator->() is bogus
3054 constexpr _Inner_iter
3055 operator->() const
3056 requires __detail::__has_arrow<_Inner_iter>
3057 && copyable<_Inner_iter>
3058 { return *_M_inner; }
3059
3060 constexpr _Iterator&
3061 operator++()
3062 {
3063 auto&& __inner_range = [this] () -> auto&& {
3064 if constexpr (_S_ref_is_glvalue)
3065 return *_M_get_outer();
3066 else
3067 return *_M_parent->_M_inner;
3068 }();
3069 if (++*_M_inner == ranges::end(__inner_range))
3070 {
3071 ++_M_get_outer();
3072 _M_satisfy();
3073 }
3074 return *this;
3075 }
3076
3077 constexpr void
3078 operator++(int)
3079 { ++*this; }
3080
3081 constexpr _Iterator
3082 operator++(int)
3083 requires _S_ref_is_glvalue && forward_range<_Base>
3084 && forward_range<range_reference_t<_Base>>
3085 {
3086 auto __tmp = *this;
3087 ++*this;
3088 return __tmp;
3089 }
3090
3091 constexpr _Iterator&
3092 operator--()
3093 requires _S_ref_is_glvalue && bidirectional_range<_Base>
3094 && bidirectional_range<range_reference_t<_Base>>
3095 && common_range<range_reference_t<_Base>>
3096 {
3097 if (_M_outer == ranges::end(_M_parent->_M_base))
3098 _M_inner = ranges::end(__detail::__as_lvalue(*--_M_outer));
3099 while (*_M_inner == ranges::begin(__detail::__as_lvalue(*_M_outer)))
3100 *_M_inner = ranges::end(__detail::__as_lvalue(*--_M_outer));
3101 --*_M_inner;
3102 return *this;
3103 }
3104
3105 constexpr _Iterator
3106 operator--(int)
3107 requires _S_ref_is_glvalue && bidirectional_range<_Base>
3108 && bidirectional_range<range_reference_t<_Base>>
3109 && common_range<range_reference_t<_Base>>
3110 {
3111 auto __tmp = *this;
3112 --*this;
3113 return __tmp;
3114 }
3115
3116 friend constexpr bool
3117 operator==(const _Iterator& __x, const _Iterator& __y)
3118 requires _S_ref_is_glvalue
3119 && forward_range<_Base>
3120 && equality_comparable<_Inner_iter>
3121 {
3122 return (__x._M_outer == __y._M_outer
3123 && __x._M_inner == __y._M_inner);
3124 }
3125
3126 friend constexpr decltype(auto)
3127 iter_move(const _Iterator& __i)
3128 noexcept(noexcept(ranges::iter_move(*__i._M_inner)))
3129 { return ranges::iter_move(*__i._M_inner); }
3130
3131 friend constexpr void
3132 iter_swap(const _Iterator& __x, const _Iterator& __y)
3133 noexcept(noexcept(ranges::iter_swap(*__x._M_inner, *__y._M_inner)))
3134 requires indirectly_swappable<_Inner_iter>
3135 { return ranges::iter_swap(*__x._M_inner, *__y._M_inner); }
3136
3137 friend _Iterator<!_Const>;
3138 template<bool> friend struct _Sentinel;
3139 };
3140
3141 template<bool _Const>
3142 struct _Sentinel
3143 {
3144 private:
3145 using _Parent = __detail::__maybe_const_t<_Const, join_view>;
3146 using _Base = join_view::_Base<_Const>;
3147
3148 template<bool _Const2>
3149 constexpr bool
3150 __equal(const _Iterator<_Const2>& __i) const
3151 { return __i._M_get_outer() == _M_end; }
3152
3153 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
3154
3155 public:
3156 _Sentinel() = default;
3157
3158 constexpr explicit
3159 _Sentinel(_Parent* __parent)
3160 : _M_end(ranges::end(__parent->_M_base))
3161 { }
3162
3163 constexpr
3164 _Sentinel(_Sentinel<!_Const> __s)
3165 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
3166 : _M_end(std::move(__s._M_end))
3167 { }
3168
3169 template<bool _Const2>
3170 requires sentinel_for<sentinel_t<_Base>,
3171 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
3172 friend constexpr bool
3173 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
3174 { return __y.__equal(__x); }
3175
3176 friend _Sentinel<!_Const>;
3177 };
3178
3179 _Vp _M_base = _Vp();
3180 [[no_unique_address]]
3181 __detail::__maybe_present_t<!forward_range<_Vp>,
3182 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_outer;
3183 [[no_unique_address]]
3184 __detail::__non_propagating_cache<remove_cv_t<_InnerRange>> _M_inner;
3185
3186 public:
3187 join_view() requires default_initializable<_Vp> = default;
3188
3189 constexpr explicit
3190 join_view(_Vp __base)
3191 : _M_base(std::move(__base))
3192 { }
3193
3194 constexpr _Vp
3195 base() const& requires copy_constructible<_Vp>
3196 { return _M_base; }
3197
3198 constexpr _Vp
3199 base() &&
3200 { return std::move(_M_base); }
3201
3202 constexpr auto
3203 begin()
3204 {
3205 if constexpr (forward_range<_Vp>)
3206 {
3207 constexpr bool __use_const
3208 = (__detail::__simple_view<_Vp>
3209 && is_reference_v<range_reference_t<_Vp>>);
3210 return _Iterator<__use_const>{this, ranges::begin(_M_base)};
3211 }
3212 else
3213 {
3214 _M_outer = ranges::begin(_M_base);
3215 return _Iterator<false>{this};
3216 }
3217 }
3218
3219 constexpr auto
3220 begin() const
3221 requires forward_range<const _Vp>
3222 && is_reference_v<range_reference_t<const _Vp>>
3223 && input_range<range_reference_t<const _Vp>>
3224 {
3225 return _Iterator<true>{this, ranges::begin(_M_base)};
3226 }
3227
3228 constexpr auto
3229 end()
3230 {
3231 if constexpr (forward_range<_Vp> && is_reference_v<_InnerRange>
3232 && forward_range<_InnerRange>
3233 && common_range<_Vp> && common_range<_InnerRange>)
3234 return _Iterator<__detail::__simple_view<_Vp>>{this,
3235 ranges::end(_M_base)};
3236 else
3237 return _Sentinel<__detail::__simple_view<_Vp>>{this};
3238 }
3239
3240 constexpr auto
3241 end() const
3242 requires forward_range<const _Vp>
3243 && is_reference_v<range_reference_t<const _Vp>>
3244 && input_range<range_reference_t<const _Vp>>
3245 {
3246 if constexpr (is_reference_v<range_reference_t<const _Vp>>
3247 && forward_range<range_reference_t<const _Vp>>
3248 && common_range<const _Vp>
3249 && common_range<range_reference_t<const _Vp>>)
3250 return _Iterator<true>{this, ranges::end(_M_base)};
3251 else
3252 return _Sentinel<true>{this};
3253 }
3254 };
3255
3256 template<typename _Range>
3257 explicit join_view(_Range&&) -> join_view<views::all_t<_Range>>;
3258
3259 namespace views
3260 {
3261 namespace __detail
3262 {
3263 template<typename _Range>
3264 concept __can_join_view
3265 = requires { join_view<all_t<_Range>>{std::declval<_Range>()}; };
3266 } // namespace __detail
3267
3268 struct _Join : __adaptor::_RangeAdaptorClosure<_Join>
3269 {
3270 template<viewable_range _Range>
3271 requires __detail::__can_join_view<_Range>
3272 constexpr auto
3273 operator() [[nodiscard]] (_Range&& __r) const
3274 {
3275 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3276 // 3474. Nesting join_views is broken because of CTAD
3277 return join_view<all_t<_Range>>{std::forward<_Range>(__r)};
3278 }
3279
3280 static constexpr bool _S_has_simple_call_op = true;
3281 };
3282
3283 inline constexpr _Join join;
3284 } // namespace views
3285
3286 namespace __detail
3287 {
3288 template<auto>
3289 struct __require_constant;
3290
3291 template<typename _Range>
3292 concept __tiny_range = sized_range<_Range>
3293 && requires
3294 { typename __require_constant<remove_reference_t<_Range>::size()>; }
3295 && (remove_reference_t<_Range>::size() <= 1);
3296
3297 template<typename _Base>
3298 struct __lazy_split_view_outer_iter_cat
3299 { };
3300
3301 template<forward_range _Base>
3302 struct __lazy_split_view_outer_iter_cat<_Base>
3303 { using iterator_category = input_iterator_tag; };
3304
3305 template<typename _Base>
3306 struct __lazy_split_view_inner_iter_cat
3307 { };
3308
3309 template<forward_range _Base>
3310 struct __lazy_split_view_inner_iter_cat<_Base>
3311 {
3312 private:
3313 static constexpr auto
3314 _S_iter_cat()
3315 {
3316 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
3317 if constexpr (derived_from<_Cat, forward_iterator_tag>)
3318 return forward_iterator_tag{};
3319 else
3320 return _Cat{};
3321 }
3322 public:
3323 using iterator_category = decltype(_S_iter_cat());
3324 };
3325 }
3326
3327 template<input_range _Vp, forward_range _Pattern>
3328 requires view<_Vp> && view<_Pattern>
3329 && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
3330 ranges::equal_to>
3331 && (forward_range<_Vp> || __detail::__tiny_range<_Pattern>)
3332 class lazy_split_view : public view_interface<lazy_split_view<_Vp, _Pattern>>
3333 {
3334 private:
3335 template<bool _Const>
3336 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
3337
3338 template<bool _Const>
3339 struct _InnerIter;
3340
3341 template<bool _Const>
3342 struct _OuterIter
3343 : __detail::__lazy_split_view_outer_iter_cat<_Base<_Const>>
3344 {
3345 private:
3346 using _Parent = __detail::__maybe_const_t<_Const, lazy_split_view>;
3347 using _Base = lazy_split_view::_Base<_Const>;
3348
3349 constexpr bool
3350 __at_end() const
3351 { return __current() == ranges::end(_M_parent->_M_base) && !_M_trailing_empty; }
3352
3353 // [range.lazy.split.outer] p1
3354 // Many of the following specifications refer to the notional member
3355 // current of outer-iterator. current is equivalent to current_ if
3356 // V models forward_range, and parent_->current_ otherwise.
3357 constexpr auto&
3358 __current() noexcept
3359 {
3360 if constexpr (forward_range<_Vp>)
3361 return _M_current;
3362 else
3363 return *_M_parent->_M_current;
3364 }
3365
3366 constexpr auto&
3367 __current() const noexcept
3368 {
3369 if constexpr (forward_range<_Vp>)
3370 return _M_current;
3371 else
3372 return *_M_parent->_M_current;
3373 }
3374
3375 _Parent* _M_parent = nullptr;
3376
3377 [[no_unique_address]]
3378 __detail::__maybe_present_t<forward_range<_Vp>,
3379 iterator_t<_Base>> _M_current;
3380 bool _M_trailing_empty = false;
3381
3382 public:
3383 using iterator_concept = __conditional_t<forward_range<_Base>,
3384 forward_iterator_tag,
3385 input_iterator_tag>;
3386 // iterator_category defined in __lazy_split_view_outer_iter_cat
3387 using difference_type = range_difference_t<_Base>;
3388
3389 struct value_type : view_interface<value_type>
3390 {
3391 private:
3392 _OuterIter _M_i = _OuterIter();
3393
3394 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3395 // 4013. lazy_split_view::outer-iterator::value_type should not
3396 // provide default constructor
3397 constexpr explicit
3398 value_type(_OuterIter __i)
3399 : _M_i(std::move(__i))
3400 { }
3401
3402 friend _OuterIter;
3403
3404 public:
3405 constexpr _InnerIter<_Const>
3406 begin() const
3407 { return _InnerIter<_Const>{_M_i}; }
3408
3409 constexpr default_sentinel_t
3410 end() const noexcept
3411 { return default_sentinel; }
3412 };
3413
3414 _OuterIter() = default;
3415
3416 constexpr explicit
3417 _OuterIter(_Parent* __parent) requires (!forward_range<_Base>)
3418 : _M_parent(__parent)
3419 { }
3420
3421 constexpr
3422 _OuterIter(_Parent* __parent, iterator_t<_Base> __current)
3423 requires forward_range<_Base>
3424 : _M_parent(__parent),
3425 _M_current(std::move(__current))
3426 { }
3427
3428 constexpr
3429 _OuterIter(_OuterIter<!_Const> __i)
3430 requires _Const
3431 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
3432 : _M_parent(__i._M_parent), _M_current(std::move(__i._M_current)),
3433 _M_trailing_empty(__i._M_trailing_empty)
3434 { }
3435
3436 constexpr value_type
3437 operator*() const
3438 { return value_type{*this}; }
3439
3440 constexpr _OuterIter&
3441 operator++()
3442 {
3443 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3444 // 3505. lazy_split_view::outer-iterator::operator++ misspecified
3445 const auto __end = ranges::end(_M_parent->_M_base);
3446 if (__current() == __end)
3447 {
3448 _M_trailing_empty = false;
3449 return *this;
3450 }
3451 const auto [__pbegin, __pend] = subrange{_M_parent->_M_pattern};
3452 if (__pbegin == __pend)
3453 ++__current();
3454 else if constexpr (__detail::__tiny_range<_Pattern>)
3455 {
3456 __current() = ranges::find(std::move(__current()), __end,
3457 *__pbegin);
3458 if (__current() != __end)
3459 {
3460 ++__current();
3461 if (__current() == __end)
3462 _M_trailing_empty = true;
3463 }
3464 }
3465 else
3466 do
3467 {
3468 auto [__b, __p]
3469 = ranges::mismatch(__current(), __end, __pbegin, __pend);
3470 if (__p == __pend)
3471 {
3472 __current() = __b;
3473 if (__current() == __end)
3474 _M_trailing_empty = true;
3475 break;
3476 }
3477 } while (++__current() != __end);
3478 return *this;
3479 }
3480
3481 constexpr decltype(auto)
3482 operator++(int)
3483 {
3484 if constexpr (forward_range<_Base>)
3485 {
3486 auto __tmp = *this;
3487 ++*this;
3488 return __tmp;
3489 }
3490 else
3491 ++*this;
3492 }
3493
3494 friend constexpr bool
3495 operator==(const _OuterIter& __x, const _OuterIter& __y)
3496 requires forward_range<_Base>
3497 {
3498 return __x._M_current == __y._M_current
3499 && __x._M_trailing_empty == __y._M_trailing_empty;
3500 }
3501
3502 friend constexpr bool
3503 operator==(const _OuterIter& __x, default_sentinel_t)
3504 { return __x.__at_end(); };
3505
3506 friend _OuterIter<!_Const>;
3507 friend _InnerIter<_Const>;
3508 };
3509
3510 template<bool _Const>
3511 struct _InnerIter
3512 : __detail::__lazy_split_view_inner_iter_cat<_Base<_Const>>
3513 {
3514 private:
3515 using _Base = lazy_split_view::_Base<_Const>;
3516
3517 constexpr bool
3518 __at_end() const
3519 {
3520 auto [__pcur, __pend] = subrange{_M_i._M_parent->_M_pattern};
3521 auto __end = ranges::end(_M_i._M_parent->_M_base);
3522 if constexpr (__detail::__tiny_range<_Pattern>)
3523 {
3524 const auto& __cur = _M_i_current();
3525 if (__cur == __end)
3526 return true;
3527 if (__pcur == __pend)
3528 return _M_incremented;
3529 return *__cur == *__pcur;
3530 }
3531 else
3532 {
3533 auto __cur = _M_i_current();
3534 if (__cur == __end)
3535 return true;
3536 if (__pcur == __pend)
3537 return _M_incremented;
3538 do
3539 {
3540 if (*__cur != *__pcur)
3541 return false;
3542 if (++__pcur == __pend)
3543 return true;
3544 } while (++__cur != __end);
3545 return false;
3546 }
3547 }
3548
3549 constexpr auto&
3550 _M_i_current() noexcept
3551 { return _M_i.__current(); }
3552
3553 constexpr auto&
3554 _M_i_current() const noexcept
3555 { return _M_i.__current(); }
3556
3557 _OuterIter<_Const> _M_i = _OuterIter<_Const>();
3558 bool _M_incremented = false;
3559
3560 public:
3561 using iterator_concept
3562 = typename _OuterIter<_Const>::iterator_concept;
3563 // iterator_category defined in __lazy_split_view_inner_iter_cat
3564 using value_type = range_value_t<_Base>;
3565 using difference_type = range_difference_t<_Base>;
3566
3567 _InnerIter() = default;
3568
3569 constexpr explicit
3570 _InnerIter(_OuterIter<_Const> __i)
3571 : _M_i(std::move(__i))
3572 { }
3573
3574 constexpr const iterator_t<_Base>&
3575 base() const& noexcept
3576 { return _M_i_current(); }
3577
3578 constexpr iterator_t<_Base>
3579 base() && requires forward_range<_Vp>
3580 { return std::move(_M_i_current()); }
3581
3582 constexpr decltype(auto)
3583 operator*() const
3584 { return *_M_i_current(); }
3585
3586 constexpr _InnerIter&
3587 operator++()
3588 {
3589 _M_incremented = true;
3590 if constexpr (!forward_range<_Base>)
3591 if constexpr (_Pattern::size() == 0)
3592 return *this;
3593 ++_M_i_current();
3594 return *this;
3595 }
3596
3597 constexpr decltype(auto)
3598 operator++(int)
3599 {
3600 if constexpr (forward_range<_Base>)
3601 {
3602 auto __tmp = *this;
3603 ++*this;
3604 return __tmp;
3605 }
3606 else
3607 ++*this;
3608 }
3609
3610 friend constexpr bool
3611 operator==(const _InnerIter& __x, const _InnerIter& __y)
3612 requires forward_range<_Base>
3613 { return __x._M_i == __y._M_i; }
3614
3615 friend constexpr bool
3616 operator==(const _InnerIter& __x, default_sentinel_t)
3617 { return __x.__at_end(); }
3618
3619 friend constexpr decltype(auto)
3620 iter_move(const _InnerIter& __i)
3621 noexcept(noexcept(ranges::iter_move(__i._M_i_current())))
3622 { return ranges::iter_move(__i._M_i_current()); }
3623
3624 friend constexpr void
3625 iter_swap(const _InnerIter& __x, const _InnerIter& __y)
3626 noexcept(noexcept(ranges::iter_swap(__x._M_i_current(),
3627 __y._M_i_current())))
3628 requires indirectly_swappable<iterator_t<_Base>>
3629 { ranges::iter_swap(__x._M_i_current(), __y._M_i_current()); }
3630 };
3631
3632 _Vp _M_base = _Vp();
3633 _Pattern _M_pattern = _Pattern();
3634 [[no_unique_address]]
3635 __detail::__maybe_present_t<!forward_range<_Vp>,
3636 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_current;
3637
3638
3639 public:
3640 lazy_split_view() requires (default_initializable<_Vp>
3641 && default_initializable<_Pattern>)
3642 = default;
3643
3644 constexpr
3645 lazy_split_view(_Vp __base, _Pattern __pattern)
3646 : _M_base(std::move(__base)), _M_pattern(std::move(__pattern))
3647 { }
3648
3649 template<input_range _Range>
3650 requires constructible_from<_Vp, views::all_t<_Range>>
3651 && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
3652 constexpr
3653 lazy_split_view(_Range&& __r, range_value_t<_Range> __e)
3654 : _M_base(views::all(std::forward<_Range>(__r))),
3655 _M_pattern(views::single(std::move(__e)))
3656 { }
3657
3658 constexpr _Vp
3659 base() const& requires copy_constructible<_Vp>
3660 { return _M_base; }
3661
3662 constexpr _Vp
3663 base() &&
3664 { return std::move(_M_base); }
3665
3666 constexpr auto
3667 begin()
3668 {
3669 if constexpr (forward_range<_Vp>)
3670 {
3671 constexpr bool __simple
3672 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
3673 return _OuterIter<__simple>{this, ranges::begin(_M_base)};
3674 }
3675 else
3676 {
3677 _M_current = ranges::begin(_M_base);
3678 return _OuterIter<false>{this};
3679 }
3680 }
3681
3682 constexpr auto
3683 begin() const requires forward_range<_Vp> && forward_range<const _Vp>
3684 {
3685 return _OuterIter<true>{this, ranges::begin(_M_base)};
3686 }
3687
3688 constexpr auto
3689 end() requires forward_range<_Vp> && common_range<_Vp>
3690 {
3691 constexpr bool __simple
3692 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
3693 return _OuterIter<__simple>{this, ranges::end(_M_base)};
3694 }
3695
3696 constexpr auto
3697 end() const
3698 {
3699 if constexpr (forward_range<_Vp>
3700 && forward_range<const _Vp>
3701 && common_range<const _Vp>)
3702 return _OuterIter<true>{this, ranges::end(_M_base)};
3703 else
3704 return default_sentinel;
3705 }
3706 };
3707
3708 template<typename _Range, typename _Pattern>
3709 lazy_split_view(_Range&&, _Pattern&&)
3710 -> lazy_split_view<views::all_t<_Range>, views::all_t<_Pattern>>;
3711
3712 template<input_range _Range>
3713 lazy_split_view(_Range&&, range_value_t<_Range>)
3714 -> lazy_split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;
3715
3716 namespace views
3717 {
3718 namespace __detail
3719 {
3720 template<typename _Range, typename _Pattern>
3721 concept __can_lazy_split_view
3722 = requires { lazy_split_view(std::declval<_Range>(), std::declval<_Pattern>()); };
3723 } // namespace __detail
3724
3725 struct _LazySplit : __adaptor::_RangeAdaptor<_LazySplit>
3726 {
3727 template<viewable_range _Range, typename _Pattern>
3728 requires __detail::__can_lazy_split_view<_Range, _Pattern>
3729 constexpr auto
3730 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f) const
3731 {
3732 return lazy_split_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
3733 }
3734
3735 using _RangeAdaptor<_LazySplit>::operator();
3736 static constexpr int _S_arity = 2;
3737 // The pattern argument of views::lazy_split is not always simple -- it can be
3738 // a non-view range, the value category of which affects whether the call
3739 // is well-formed. But a scalar or a view pattern argument is surely
3740 // simple.
3741 template<typename _Pattern>
3742 static constexpr bool _S_has_simple_extra_args
3743 = is_scalar_v<_Pattern> || (view<_Pattern>
3744 && copy_constructible<_Pattern>);
3745 };
3746
3747 inline constexpr _LazySplit lazy_split;
3748 } // namespace views
3749
3750 template<forward_range _Vp, forward_range _Pattern>
3751 requires view<_Vp> && view<_Pattern>
3752 && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
3753 ranges::equal_to>
3754 class split_view : public view_interface<split_view<_Vp, _Pattern>>
3755 {
3756 private:
3757 _Vp _M_base = _Vp();
3758 _Pattern _M_pattern = _Pattern();
3759 __detail::__non_propagating_cache<subrange<iterator_t<_Vp>>> _M_cached_begin;
3760
3761 struct _Iterator;
3762 struct _Sentinel;
3763
3764 public:
3765 split_view() requires (default_initializable<_Vp>
3766 && default_initializable<_Pattern>)
3767 = default;
3768
3769 constexpr
3770 split_view(_Vp __base, _Pattern __pattern)
3771 : _M_base(std::move(__base)), _M_pattern(std::move(__pattern))
3772 { }
3773
3774 template<forward_range _Range>
3775 requires constructible_from<_Vp, views::all_t<_Range>>
3776 && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
3777 constexpr
3778 split_view(_Range&& __r, range_value_t<_Range> __e)
3779 : _M_base(views::all(std::forward<_Range>(__r))),
3780 _M_pattern(views::single(std::move(__e)))
3781 { }
3782
3783 constexpr _Vp
3784 base() const& requires copy_constructible<_Vp>
3785 { return _M_base; }
3786
3787 constexpr _Vp
3788 base() &&
3789 { return std::move(_M_base); }
3790
3791 constexpr _Iterator
3792 begin()
3793 {
3794 if (!_M_cached_begin)
3795 _M_cached_begin = _M_find_next(ranges::begin(_M_base));
3796 return {this, ranges::begin(_M_base), *_M_cached_begin};
3797 }
3798
3799 constexpr auto
3800 end()
3801 {
3802 if constexpr (common_range<_Vp>)
3803 return _Iterator{this, ranges::end(_M_base), {}};
3804 else
3805 return _Sentinel{this};
3806 }
3807
3808 constexpr subrange<iterator_t<_Vp>>
3809 _M_find_next(iterator_t<_Vp> __it)
3810 {
3811 auto [__b, __e] = ranges::search(subrange(__it, ranges::end(_M_base)), _M_pattern);
3812 if (__b != ranges::end(_M_base) && ranges::empty(_M_pattern))
3813 {
3814 ++__b;
3815 ++__e;
3816 }
3817 return {__b, __e};
3818 }
3819
3820 private:
3821 struct _Iterator
3822 {
3823 private:
3824 split_view* _M_parent = nullptr;
3825 iterator_t<_Vp> _M_cur = iterator_t<_Vp>();
3826 subrange<iterator_t<_Vp>> _M_next = subrange<iterator_t<_Vp>>();
3827 bool _M_trailing_empty = false;
3828
3829 friend struct _Sentinel;
3830
3831 public:
3832 using iterator_concept = forward_iterator_tag;
3833 using iterator_category = input_iterator_tag;
3834 using value_type = subrange<iterator_t<_Vp>>;
3835 using difference_type = range_difference_t<_Vp>;
3836
3837 _Iterator() = default;
3838
3839 constexpr
3840 _Iterator(split_view* __parent,
3841 iterator_t<_Vp> __current,
3842 subrange<iterator_t<_Vp>> __next)
3843 : _M_parent(__parent),
3844 _M_cur(std::move(__current)),
3845 _M_next(std::move(__next))
3846 { }
3847
3848 constexpr iterator_t<_Vp>
3849 base() const
3850 { return _M_cur; }
3851
3852 constexpr value_type
3853 operator*() const
3854 { return {_M_cur, _M_next.begin()}; }
3855
3856 constexpr _Iterator&
3857 operator++()
3858 {
3859 _M_cur = _M_next.begin();
3860 if (_M_cur != ranges::end(_M_parent->_M_base))
3861 {
3862 _M_cur = _M_next.end();
3863 if (_M_cur == ranges::end(_M_parent->_M_base))
3864 {
3865 _M_trailing_empty = true;
3866 _M_next = {_M_cur, _M_cur};
3867 }
3868 else
3869 _M_next = _M_parent->_M_find_next(_M_cur);
3870 }
3871 else
3872 _M_trailing_empty = false;
3873 return *this;
3874 }
3875
3876 constexpr _Iterator
3877 operator++(int)
3878 {
3879 auto __tmp = *this;
3880 ++*this;
3881 return __tmp;
3882 }
3883
3884 friend constexpr bool
3885 operator==(const _Iterator& __x, const _Iterator& __y)
3886 {
3887 return __x._M_cur == __y._M_cur
3888 && __x._M_trailing_empty == __y._M_trailing_empty;
3889 }
3890 };
3891
3892 struct _Sentinel
3893 {
3894 private:
3895 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
3896
3897 constexpr bool
3898 _M_equal(const _Iterator& __x) const
3899 { return __x._M_cur == _M_end && !__x._M_trailing_empty; }
3900
3901 public:
3902 _Sentinel() = default;
3903
3904 constexpr explicit
3905 _Sentinel(split_view* __parent)
3906 : _M_end(ranges::end(__parent->_M_base))
3907 { }
3908
3909 friend constexpr bool
3910 operator==(const _Iterator& __x, const _Sentinel& __y)
3911 { return __y._M_equal(__x); }
3912 };
3913 };
3914
3915 template<typename _Range, typename _Pattern>
3916 split_view(_Range&&, _Pattern&&)
3917 -> split_view<views::all_t<_Range>, views::all_t<_Pattern>>;
3918
3919 template<forward_range _Range>
3920 split_view(_Range&&, range_value_t<_Range>)
3921 -> split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;
3922
3923 namespace views
3924 {
3925 namespace __detail
3926 {
3927 template<typename _Range, typename _Pattern>
3928 concept __can_split_view
3929 = requires { split_view(std::declval<_Range>(), std::declval<_Pattern>()); };
3930 } // namespace __detail
3931
3932 struct _Split : __adaptor::_RangeAdaptor<_Split>
3933 {
3934 template<viewable_range _Range, typename _Pattern>
3935 requires __detail::__can_split_view<_Range, _Pattern>
3936 constexpr auto
3937 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f) const
3938 {
3939 return split_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
3940 }
3941
3942 using _RangeAdaptor<_Split>::operator();
3943 static constexpr int _S_arity = 2;
3944 template<typename _Pattern>
3945 static constexpr bool _S_has_simple_extra_args
3946 = _LazySplit::_S_has_simple_extra_args<_Pattern>;
3947 };
3948
3949 inline constexpr _Split split;
3950 } // namespace views
3951
3952 namespace views
3953 {
3954 struct _Counted
3955 {
3956 template<input_or_output_iterator _Iter>
3957 constexpr auto
3958 operator() [[nodiscard]] (_Iter __i, iter_difference_t<_Iter> __n) const
3959 {
3960 if constexpr (contiguous_iterator<_Iter>)
3961 return span(std::to_address(__i), __n);
3962 else if constexpr (random_access_iterator<_Iter>)
3963 return subrange(__i, __i + __n);
3964 else
3965 return subrange(counted_iterator(std::move(__i), __n),
3966 default_sentinel);
3967 }
3968 };
3969
3970 inline constexpr _Counted counted{};
3971 } // namespace views
3972
3973 template<view _Vp>
3974 requires (!common_range<_Vp>) && copyable<iterator_t<_Vp>>
3975 class common_view : public view_interface<common_view<_Vp>>
3976 {
3977 private:
3978 _Vp _M_base = _Vp();
3979
3980 public:
3981 common_view() requires default_initializable<_Vp> = default;
3982
3983 constexpr explicit
3984 common_view(_Vp __r)
3985 : _M_base(std::move(__r))
3986 { }
3987
3988 constexpr _Vp
3989 base() const& requires copy_constructible<_Vp>
3990 { return _M_base; }
3991
3992 constexpr _Vp
3993 base() &&
3994 { return std::move(_M_base); }
3995
3996 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3997 // 4012. common_view::begin/end are missing the simple-view check
3998 constexpr auto
3999 begin() requires (!__detail::__simple_view<_Vp>)
4000 {
4001 if constexpr (random_access_range<_Vp> && sized_range<_Vp>)
4002 return ranges::begin(_M_base);
4003 else
4004 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
4005 (ranges::begin(_M_base));
4006 }
4007
4008 constexpr auto
4009 begin() const requires range<const _Vp>
4010 {
4011 if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>)
4012 return ranges::begin(_M_base);
4013 else
4014 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
4015 (ranges::begin(_M_base));
4016 }
4017
4018 constexpr auto
4019 end() requires (!__detail::__simple_view<_Vp>)
4020 {
4021 if constexpr (random_access_range<_Vp> && sized_range<_Vp>)
4022 return ranges::begin(_M_base) + ranges::size(_M_base);
4023 else
4024 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
4025 (ranges::end(_M_base));
4026 }
4027
4028 constexpr auto
4029 end() const requires range<const _Vp>
4030 {
4031 if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>)
4032 return ranges::begin(_M_base) + ranges::size(_M_base);
4033 else
4034 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
4035 (ranges::end(_M_base));
4036 }
4037
4038 constexpr auto
4039 size() requires sized_range<_Vp>
4040 { return ranges::size(_M_base); }
4041
4042 constexpr auto
4043 size() const requires sized_range<const _Vp>
4044 { return ranges::size(_M_base); }
4045 };
4046
4047 template<typename _Range>
4048 common_view(_Range&&) -> common_view<views::all_t<_Range>>;
4049
4050 template<typename _Tp>
4051 inline constexpr bool enable_borrowed_range<common_view<_Tp>>
4052 = enable_borrowed_range<_Tp>;
4053
4054 namespace views
4055 {
4056 namespace __detail
4057 {
4058 template<typename _Range>
4059 concept __already_common = common_range<_Range>
4060 && requires { views::all(std::declval<_Range>()); };
4061
4062 template<typename _Range>
4063 concept __can_common_view
4064 = requires { common_view{std::declval<_Range>()}; };
4065 } // namespace __detail
4066
4067 struct _Common : __adaptor::_RangeAdaptorClosure<_Common>
4068 {
4069 template<viewable_range _Range>
4070 requires __detail::__already_common<_Range>
4071 || __detail::__can_common_view<_Range>
4072 constexpr auto
4073 operator() [[nodiscard]] (_Range&& __r) const
4074 {
4075 if constexpr (__detail::__already_common<_Range>)
4076 return views::all(std::forward<_Range>(__r));
4077 else
4078 return common_view{std::forward<_Range>(__r)};
4079 }
4080
4081 static constexpr bool _S_has_simple_call_op = true;
4082 };
4083
4084 inline constexpr _Common common;
4085 } // namespace views
4086
4087 template<view _Vp>
4088 requires bidirectional_range<_Vp>
4089 class reverse_view : public view_interface<reverse_view<_Vp>>
4090 {
4091 private:
4092 static constexpr bool _S_needs_cached_begin
4093 = !common_range<_Vp> && !(random_access_range<_Vp>
4094 && sized_sentinel_for<sentinel_t<_Vp>,
4095 iterator_t<_Vp>>);
4096
4097 _Vp _M_base = _Vp();
4098 [[no_unique_address]]
4099 __detail::__maybe_present_t<_S_needs_cached_begin,
4100 __detail::_CachedPosition<_Vp>>
4101 _M_cached_begin;
4102
4103 public:
4104 reverse_view() requires default_initializable<_Vp> = default;
4105
4106 constexpr explicit
4107 reverse_view(_Vp __r)
4108 : _M_base(std::move(__r))
4109 { }
4110
4111 constexpr _Vp
4112 base() const& requires copy_constructible<_Vp>
4113 { return _M_base; }
4114
4115 constexpr _Vp
4116 base() &&
4117 { return std::move(_M_base); }
4118
4119 constexpr reverse_iterator<iterator_t<_Vp>>
4120 begin()
4121 {
4122 if constexpr (_S_needs_cached_begin)
4123 if (_M_cached_begin._M_has_value())
4124 return std::make_reverse_iterator(_M_cached_begin._M_get(_M_base));
4125
4126 auto __it = ranges::next(ranges::begin(_M_base), ranges::end(_M_base));
4127 if constexpr (_S_needs_cached_begin)
4128 _M_cached_begin._M_set(_M_base, __it);
4129 return std::make_reverse_iterator(std::move(__it));
4130 }
4131
4132 constexpr auto
4133 begin() requires common_range<_Vp>
4134 { return std::make_reverse_iterator(ranges::end(_M_base)); }
4135
4136 constexpr auto
4137 begin() const requires common_range<const _Vp>
4138 { return std::make_reverse_iterator(ranges::end(_M_base)); }
4139
4140 constexpr reverse_iterator<iterator_t<_Vp>>
4141 end()
4142 { return std::make_reverse_iterator(ranges::begin(_M_base)); }
4143
4144 constexpr auto
4145 end() const requires common_range<const _Vp>
4146 { return std::make_reverse_iterator(ranges::begin(_M_base)); }
4147
4148 constexpr auto
4149 size() requires sized_range<_Vp>
4150 { return ranges::size(_M_base); }
4151
4152 constexpr auto
4153 size() const requires sized_range<const _Vp>
4154 { return ranges::size(_M_base); }
4155 };
4156
4157 template<typename _Range>
4158 reverse_view(_Range&&) -> reverse_view<views::all_t<_Range>>;
4159
4160 template<typename _Tp>
4161 inline constexpr bool enable_borrowed_range<reverse_view<_Tp>>
4162 = enable_borrowed_range<_Tp>;
4163
4164 namespace views
4165 {
4166 namespace __detail
4167 {
4168 template<typename>
4169 inline constexpr bool __is_reversible_subrange = false;
4170
4171 template<typename _Iter, subrange_kind _Kind>
4172 inline constexpr bool
4173 __is_reversible_subrange<subrange<reverse_iterator<_Iter>,
4174 reverse_iterator<_Iter>,
4175 _Kind>> = true;
4176
4177 template<typename>
4178 inline constexpr bool __is_reverse_view = false;
4179
4180 template<typename _Vp>
4181 inline constexpr bool __is_reverse_view<reverse_view<_Vp>> = true;
4182
4183 template<typename _Range>
4184 concept __can_reverse_view
4185 = requires { reverse_view{std::declval<_Range>()}; };
4186 } // namespace __detail
4187
4188 struct _Reverse : __adaptor::_RangeAdaptorClosure<_Reverse>
4189 {
4190 template<viewable_range _Range>
4191 requires __detail::__is_reverse_view<remove_cvref_t<_Range>>
4192 || __detail::__is_reversible_subrange<remove_cvref_t<_Range>>
4193 || __detail::__can_reverse_view<_Range>
4194 constexpr auto
4195 operator() [[nodiscard]] (_Range&& __r) const
4196 {
4197 using _Tp = remove_cvref_t<_Range>;
4198 if constexpr (__detail::__is_reverse_view<_Tp>)
4199 return std::forward<_Range>(__r).base();
4200 else if constexpr (__detail::__is_reversible_subrange<_Tp>)
4201 {
4202 using _Iter = decltype(ranges::begin(__r).base());
4203 if constexpr (sized_range<_Tp>)
4204 return subrange<_Iter, _Iter, subrange_kind::sized>
4205 {__r.end().base(), __r.begin().base(), __r.size()};
4206 else
4207 return subrange<_Iter, _Iter, subrange_kind::unsized>
4208 {__r.end().base(), __r.begin().base()};
4209 }
4210 else
4211 return reverse_view{std::forward<_Range>(__r)};
4212 }
4213
4214 static constexpr bool _S_has_simple_call_op = true;
4215 };
4216
4217 inline constexpr _Reverse reverse;
4218 } // namespace views
4219
4220 namespace __detail
4221 {
4222#if __cpp_lib_tuple_like // >= C++23
4223 template<typename _Tp, size_t _Nm>
4224 concept __has_tuple_element = __tuple_like<_Tp> && _Nm < tuple_size_v<_Tp>;
4225#else
4226 template<typename _Tp, size_t _Nm>
4227 concept __has_tuple_element = requires(_Tp __t)
4228 {
4229 typename tuple_size<_Tp>::type;
4230 requires _Nm < tuple_size_v<_Tp>;
4231 typename tuple_element_t<_Nm, _Tp>;
4232 { std::get<_Nm>(__t) }
4233 -> convertible_to<const tuple_element_t<_Nm, _Tp>&>;
4234 };
4235#endif
4236
4237 template<typename _Tp, size_t _Nm>
4238 concept __returnable_element
4239 = is_reference_v<_Tp> || move_constructible<tuple_element_t<_Nm, _Tp>>;
4240 }
4241
4242 template<input_range _Vp, size_t _Nm>
4243 requires view<_Vp>
4244 && __detail::__has_tuple_element<range_value_t<_Vp>, _Nm>
4245 && __detail::__has_tuple_element<remove_reference_t<range_reference_t<_Vp>>,
4246 _Nm>
4247 && __detail::__returnable_element<range_reference_t<_Vp>, _Nm>
4248 class elements_view : public view_interface<elements_view<_Vp, _Nm>>
4249 {
4250 public:
4251 elements_view() requires default_initializable<_Vp> = default;
4252
4253 constexpr explicit
4254 elements_view(_Vp __base)
4255 : _M_base(std::move(__base))
4256 { }
4257
4258 constexpr _Vp
4259 base() const& requires copy_constructible<_Vp>
4260 { return _M_base; }
4261
4262 constexpr _Vp
4263 base() &&
4264 { return std::move(_M_base); }
4265
4266 constexpr auto
4267 begin() requires (!__detail::__simple_view<_Vp>)
4268 { return _Iterator<false>(ranges::begin(_M_base)); }
4269
4270 constexpr auto
4271 begin() const requires range<const _Vp>
4272 { return _Iterator<true>(ranges::begin(_M_base)); }
4273
4274 constexpr auto
4275 end() requires (!__detail::__simple_view<_Vp> && !common_range<_Vp>)
4276 { return _Sentinel<false>{ranges::end(_M_base)}; }
4277
4278 constexpr auto
4279 end() requires (!__detail::__simple_view<_Vp> && common_range<_Vp>)
4280 { return _Iterator<false>{ranges::end(_M_base)}; }
4281
4282 constexpr auto
4283 end() const requires range<const _Vp>
4284 { return _Sentinel<true>{ranges::end(_M_base)}; }
4285
4286 constexpr auto
4287 end() const requires common_range<const _Vp>
4288 { return _Iterator<true>{ranges::end(_M_base)}; }
4289
4290 constexpr auto
4291 size() requires sized_range<_Vp>
4292 { return ranges::size(_M_base); }
4293
4294 constexpr auto
4295 size() const requires sized_range<const _Vp>
4296 { return ranges::size(_M_base); }
4297
4298 private:
4299 template<bool _Const>
4300 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
4301
4302 template<bool _Const>
4303 struct __iter_cat
4304 { };
4305
4306 template<bool _Const>
4307 requires forward_range<_Base<_Const>>
4308 struct __iter_cat<_Const>
4309 {
4310 private:
4311 static auto _S_iter_cat()
4312 {
4313 using _Base = elements_view::_Base<_Const>;
4314 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
4315 using _Res = decltype((std::get<_Nm>(*std::declval<iterator_t<_Base>>())));
4316 if constexpr (!is_lvalue_reference_v<_Res>)
4317 return input_iterator_tag{};
4318 else if constexpr (derived_from<_Cat, random_access_iterator_tag>)
4319 return random_access_iterator_tag{};
4320 else
4321 return _Cat{};
4322 }
4323 public:
4324 using iterator_category = decltype(_S_iter_cat());
4325 };
4326
4327 template<bool _Const>
4328 struct _Sentinel;
4329
4330 template<bool _Const>
4331 struct _Iterator : __iter_cat<_Const>
4332 {
4333 private:
4334 using _Base = elements_view::_Base<_Const>;
4335
4336 iterator_t<_Base> _M_current = iterator_t<_Base>();
4337
4338 static constexpr decltype(auto)
4339 _S_get_element(const iterator_t<_Base>& __i)
4340 {
4341 if constexpr (is_reference_v<range_reference_t<_Base>>)
4342 return std::get<_Nm>(*__i);
4343 else
4344 {
4345 using _Et = remove_cv_t<tuple_element_t<_Nm, range_reference_t<_Base>>>;
4346 return static_cast<_Et>(std::get<_Nm>(*__i));
4347 }
4348 }
4349
4350 static auto
4351 _S_iter_concept()
4352 {
4353 if constexpr (random_access_range<_Base>)
4354 return random_access_iterator_tag{};
4355 else if constexpr (bidirectional_range<_Base>)
4356 return bidirectional_iterator_tag{};
4357 else if constexpr (forward_range<_Base>)
4358 return forward_iterator_tag{};
4359 else
4360 return input_iterator_tag{};
4361 }
4362
4363 friend _Iterator<!_Const>;
4364
4365 public:
4366 using iterator_concept = decltype(_S_iter_concept());
4367 // iterator_category defined in elements_view::__iter_cat
4368 using value_type
4369 = remove_cvref_t<tuple_element_t<_Nm, range_value_t<_Base>>>;
4370 using difference_type = range_difference_t<_Base>;
4371
4372 _Iterator() requires default_initializable<iterator_t<_Base>> = default;
4373
4374 constexpr explicit
4375 _Iterator(iterator_t<_Base> __current)
4376 : _M_current(std::move(__current))
4377 { }
4378
4379 constexpr
4380 _Iterator(_Iterator<!_Const> __i)
4381 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
4382 : _M_current(std::move(__i._M_current))
4383 { }
4384
4385 constexpr const iterator_t<_Base>&
4386 base() const& noexcept
4387 { return _M_current; }
4388
4389 constexpr iterator_t<_Base>
4390 base() &&
4391 { return std::move(_M_current); }
4392
4393 constexpr decltype(auto)
4394 operator*() const
4395 { return _S_get_element(_M_current); }
4396
4397 constexpr _Iterator&
4398 operator++()
4399 {
4400 ++_M_current;
4401 return *this;
4402 }
4403
4404 constexpr void
4405 operator++(int)
4406 { ++_M_current; }
4407
4408 constexpr _Iterator
4409 operator++(int) requires forward_range<_Base>
4410 {
4411 auto __tmp = *this;
4412 ++_M_current;
4413 return __tmp;
4414 }
4415
4416 constexpr _Iterator&
4417 operator--() requires bidirectional_range<_Base>
4418 {
4419 --_M_current;
4420 return *this;
4421 }
4422
4423 constexpr _Iterator
4424 operator--(int) requires bidirectional_range<_Base>
4425 {
4426 auto __tmp = *this;
4427 --_M_current;
4428 return __tmp;
4429 }
4430
4431 constexpr _Iterator&
4432 operator+=(difference_type __n)
4433 requires random_access_range<_Base>
4434 {
4435 _M_current += __n;
4436 return *this;
4437 }
4438
4439 constexpr _Iterator&
4440 operator-=(difference_type __n)
4441 requires random_access_range<_Base>
4442 {
4443 _M_current -= __n;
4444 return *this;
4445 }
4446
4447 constexpr decltype(auto)
4448 operator[](difference_type __n) const
4449 requires random_access_range<_Base>
4450 { return _S_get_element(_M_current + __n); }
4451
4452 friend constexpr bool
4453 operator==(const _Iterator& __x, const _Iterator& __y)
4454 requires equality_comparable<iterator_t<_Base>>
4455 { return __x._M_current == __y._M_current; }
4456
4457 friend constexpr bool
4458 operator<(const _Iterator& __x, const _Iterator& __y)
4459 requires random_access_range<_Base>
4460 { return __x._M_current < __y._M_current; }
4461
4462 friend constexpr bool
4463 operator>(const _Iterator& __x, const _Iterator& __y)
4464 requires random_access_range<_Base>
4465 { return __y._M_current < __x._M_current; }
4466
4467 friend constexpr bool
4468 operator<=(const _Iterator& __x, const _Iterator& __y)
4469 requires random_access_range<_Base>
4470 { return !(__y._M_current > __x._M_current); }
4471
4472 friend constexpr bool
4473 operator>=(const _Iterator& __x, const _Iterator& __y)
4474 requires random_access_range<_Base>
4475 { return !(__x._M_current > __y._M_current); }
4476
4477#ifdef __cpp_lib_three_way_comparison
4478 friend constexpr auto
4479 operator<=>(const _Iterator& __x, const _Iterator& __y)
4480 requires random_access_range<_Base>
4481 && three_way_comparable<iterator_t<_Base>>
4482 { return __x._M_current <=> __y._M_current; }
4483#endif
4484
4485 friend constexpr _Iterator
4486 operator+(const _Iterator& __x, difference_type __y)
4487 requires random_access_range<_Base>
4488 { return _Iterator{__x} += __y; }
4489
4490 friend constexpr _Iterator
4491 operator+(difference_type __x, const _Iterator& __y)
4492 requires random_access_range<_Base>
4493 { return __y + __x; }
4494
4495 friend constexpr _Iterator
4496 operator-(const _Iterator& __x, difference_type __y)
4497 requires random_access_range<_Base>
4498 { return _Iterator{__x} -= __y; }
4499
4500 // _GLIBCXX_RESOLVE_LIB_DEFECTS
4501 // 3483. transform_view::iterator's difference is overconstrained
4502 friend constexpr difference_type
4503 operator-(const _Iterator& __x, const _Iterator& __y)
4504 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
4505 { return __x._M_current - __y._M_current; }
4506
4507 template <bool> friend struct _Sentinel;
4508 };
4509
4510 template<bool _Const>
4511 struct _Sentinel
4512 {
4513 private:
4514 template<bool _Const2>
4515 constexpr bool
4516 _M_equal(const _Iterator<_Const2>& __x) const
4517 { return __x._M_current == _M_end; }
4518
4519 template<bool _Const2>
4520 constexpr auto
4521 _M_distance_from(const _Iterator<_Const2>& __i) const
4522 { return _M_end - __i._M_current; }
4523
4524 using _Base = elements_view::_Base<_Const>;
4525 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
4526
4527 public:
4528 _Sentinel() = default;
4529
4530 constexpr explicit
4531 _Sentinel(sentinel_t<_Base> __end)
4532 : _M_end(std::move(__end))
4533 { }
4534
4535 constexpr
4536 _Sentinel(_Sentinel<!_Const> __other)
4537 requires _Const
4538 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
4539 : _M_end(std::move(__other._M_end))
4540 { }
4541
4542 constexpr sentinel_t<_Base>
4543 base() const
4544 { return _M_end; }
4545
4546 template<bool _Const2>
4547 requires sentinel_for<sentinel_t<_Base>,
4548 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
4549 friend constexpr bool
4550 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
4551 { return __y._M_equal(__x); }
4552
4553 template<bool _Const2,
4554 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
4555 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
4556 friend constexpr range_difference_t<_Base2>
4557 operator-(const _Iterator<_Const2>& __x, const _Sentinel& __y)
4558 { return -__y._M_distance_from(__x); }
4559
4560 template<bool _Const2,
4561 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
4562 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
4563 friend constexpr range_difference_t<_Base2>
4564 operator-(const _Sentinel& __x, const _Iterator<_Const2>& __y)
4565 { return __x._M_distance_from(__y); }
4566
4567 friend _Sentinel<!_Const>;
4568 };
4569
4570 _Vp _M_base = _Vp();
4571 };
4572
4573 template<typename _Tp, size_t _Nm>
4574 inline constexpr bool enable_borrowed_range<elements_view<_Tp, _Nm>>
4575 = enable_borrowed_range<_Tp>;
4576
4577 // _GLIBCXX_RESOLVE_LIB_DEFECTS
4578 // 3563. keys_view example is broken
4579 template<typename _Range>
4580 using keys_view = elements_view<_Range, 0>;
4581
4582 template<typename _Range>
4583 using values_view = elements_view<_Range, 1>;
4584
4585 namespace views
4586 {
4587 namespace __detail
4588 {
4589 template<size_t _Nm, typename _Range>
4590 concept __can_elements_view
4591 = requires { elements_view<all_t<_Range>, _Nm>{std::declval<_Range>()}; };
4592 } // namespace __detail
4593
4594 template<size_t _Nm>
4595 struct _Elements : __adaptor::_RangeAdaptorClosure<_Elements<_Nm>>
4596 {
4597 template<viewable_range _Range>
4598 requires __detail::__can_elements_view<_Nm, _Range>
4599 constexpr auto
4600 operator() [[nodiscard]] (_Range&& __r) const
4601 {
4602 return elements_view<all_t<_Range>, _Nm>{std::forward<_Range>(__r)};
4603 }
4604
4605 static constexpr bool _S_has_simple_call_op = true;
4606 };
4607
4608 template<size_t _Nm>
4609 inline constexpr _Elements<_Nm> elements;
4610 inline constexpr auto keys = elements<0>;
4611 inline constexpr auto values = elements<1>;
4612 } // namespace views
4613
4614#ifdef __cpp_lib_ranges_zip // C++ >= 23
4615 namespace __detail
4616 {
4617 template<typename... _Rs>
4618 concept __zip_is_common = (sizeof...(_Rs) == 1 && (common_range<_Rs> && ...))
4619 || (!(bidirectional_range<_Rs> && ...) && (common_range<_Rs> && ...))
4620 || ((random_access_range<_Rs> && ...) && (sized_range<_Rs> && ...));
4621
4622 template<typename _Fp, typename _Tuple>
4623 constexpr auto
4624 __tuple_transform(_Fp&& __f, _Tuple&& __tuple)
4625 {
4626 return std::apply([&]<typename... _Ts>(_Ts&&... __elts) {
4627 return tuple<invoke_result_t<_Fp&, _Ts>...>
4628 (std::__invoke(__f, std::forward<_Ts>(__elts))...);
4629 }, std::forward<_Tuple>(__tuple));
4630 }
4631
4632 template<typename _Fp, typename _Tuple>
4633 constexpr void
4634 __tuple_for_each(_Fp&& __f, _Tuple&& __tuple)
4635 {
4636 std::apply([&]<typename... _Ts>(_Ts&&... __elts) {
4637 (std::__invoke(__f, std::forward<_Ts>(__elts)), ...);
4638 }, std::forward<_Tuple>(__tuple));
4639 }
4640 } // namespace __detail
4641
4642 template<input_range... _Vs>
4643 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0)
4644 class zip_view : public view_interface<zip_view<_Vs...>>
4645 {
4646 tuple<_Vs...> _M_views;
4647
4648 template<bool> class _Iterator;
4649 template<bool> class _Sentinel;
4650
4651 public:
4652 zip_view() = default;
4653
4654 constexpr explicit
4655 zip_view(_Vs... __views)
4656 : _M_views(std::move(__views)...)
4657 { }
4658
4659 constexpr auto
4660 begin() requires (!(__detail::__simple_view<_Vs> && ...))
4661 { return _Iterator<false>(__detail::__tuple_transform(ranges::begin, _M_views)); }
4662
4663 constexpr auto
4664 begin() const requires (range<const _Vs> && ...)
4665 { return _Iterator<true>(__detail::__tuple_transform(ranges::begin, _M_views)); }
4666
4667 constexpr auto
4668 end() requires (!(__detail::__simple_view<_Vs> && ...))
4669 {
4670 if constexpr (!__detail::__zip_is_common<_Vs...>)
4671 return _Sentinel<false>(__detail::__tuple_transform(ranges::end, _M_views));
4672 else if constexpr ((random_access_range<_Vs> && ...))
4673 return begin() + iter_difference_t<_Iterator<false>>(size());
4674 else
4675 return _Iterator<false>(__detail::__tuple_transform(ranges::end, _M_views));
4676 }
4677
4678 constexpr auto
4679 end() const requires (range<const _Vs> && ...)
4680 {
4681 if constexpr (!__detail::__zip_is_common<const _Vs...>)
4682 return _Sentinel<true>(__detail::__tuple_transform(ranges::end, _M_views));
4683 else if constexpr ((random_access_range<const _Vs> && ...))
4684 return begin() + iter_difference_t<_Iterator<true>>(size());
4685 else
4686 return _Iterator<true>(__detail::__tuple_transform(ranges::end, _M_views));
4687 }
4688
4689 constexpr auto
4690 size() requires (sized_range<_Vs> && ...)
4691 {
4692 return std::apply([](auto... sizes) {
4693 using _CT = __detail::__make_unsigned_like_t<common_type_t<decltype(sizes)...>>;
4694 return ranges::min({_CT(sizes)...});
4695 }, __detail::__tuple_transform(ranges::size, _M_views));
4696 }
4697
4698 constexpr auto
4699 size() const requires (sized_range<const _Vs> && ...)
4700 {
4701 return std::apply([](auto... sizes) {
4702 using _CT = __detail::__make_unsigned_like_t<common_type_t<decltype(sizes)...>>;
4703 return ranges::min({_CT(sizes)...});
4704 }, __detail::__tuple_transform(ranges::size, _M_views));
4705 }
4706 };
4707
4708 template<typename... _Rs>
4709 zip_view(_Rs&&...) -> zip_view<views::all_t<_Rs>...>;
4710
4711 template<typename... _Views>
4712 inline constexpr bool enable_borrowed_range<zip_view<_Views...>>
4713 = (enable_borrowed_range<_Views> && ...);
4714
4715 namespace __detail
4716 {
4717 template<bool _Const, typename... _Vs>
4718 concept __all_random_access
4719 = (random_access_range<__maybe_const_t<_Const, _Vs>> && ...);
4720
4721 template<bool _Const, typename... _Vs>
4722 concept __all_bidirectional
4723 = (bidirectional_range<__maybe_const_t<_Const, _Vs>> && ...);
4724
4725 template<bool _Const, typename... _Vs>
4726 concept __all_forward
4727 = (forward_range<__maybe_const_t<_Const, _Vs>> && ...);
4728
4729 template<bool _Const, typename... _Views>
4730 struct __zip_view_iter_cat
4731 { };
4732
4733 template<bool _Const, typename... _Views>
4734 requires __all_forward<_Const, _Views...>
4735 struct __zip_view_iter_cat<_Const, _Views...>
4736 { using iterator_category = input_iterator_tag; };
4737 } // namespace __detail
4738
4739 template<input_range... _Vs>
4740 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0)
4741 template<bool _Const>
4742 class zip_view<_Vs...>::_Iterator
4743 : public __detail::__zip_view_iter_cat<_Const, _Vs...>
4744 {
4745#ifdef _GLIBCXX_CLANG // LLVM-61763 workaround
4746 public:
4747#endif
4748 tuple<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>...> _M_current;
4749
4750 constexpr explicit
4751 _Iterator(decltype(_M_current) __current)
4752 : _M_current(std::move(__current))
4753 { }
4754
4755 static auto
4756 _S_iter_concept()
4757 {
4758 if constexpr (__detail::__all_random_access<_Const, _Vs...>)
4759 return random_access_iterator_tag{};
4760 else if constexpr (__detail::__all_bidirectional<_Const, _Vs...>)
4761 return bidirectional_iterator_tag{};
4762 else if constexpr (__detail::__all_forward<_Const, _Vs...>)
4763 return forward_iterator_tag{};
4764 else
4765 return input_iterator_tag{};
4766 }
4767
4768#ifndef _GLIBCXX_CLANG // LLVM-61763 workaround
4769 template<move_constructible _Fp, input_range... _Ws>
4770 requires (view<_Ws> && ...) && (sizeof...(_Ws) > 0) && is_object_v<_Fp>
4771 && regular_invocable<_Fp&, range_reference_t<_Ws>...>
4772 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Ws>...>>
4773 friend class zip_transform_view;
4774#endif
4775
4776 public:
4777 // iterator_category defined in __zip_view_iter_cat
4778 using iterator_concept = decltype(_S_iter_concept());
4779 using value_type
4780 = tuple<range_value_t<__detail::__maybe_const_t<_Const, _Vs>>...>;
4781 using difference_type
4782 = common_type_t<range_difference_t<__detail::__maybe_const_t<_Const, _Vs>>...>;
4783
4784 _Iterator() = default;
4785
4786 constexpr
4787 _Iterator(_Iterator<!_Const> __i)
4788 requires _Const
4789 && (convertible_to<iterator_t<_Vs>,
4790 iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4791 : _M_current(std::move(__i._M_current))
4792 { }
4793
4794 constexpr auto
4795 operator*() const
4796 {
4797 auto __f = [](auto& __i) -> decltype(auto) {
4798 return *__i;
4799 };
4800 return __detail::__tuple_transform(__f, _M_current);
4801 }
4802
4803 constexpr _Iterator&
4804 operator++()
4805 {
4806 __detail::__tuple_for_each([](auto& __i) { ++__i; }, _M_current);
4807 return *this;
4808 }
4809
4810 constexpr void
4811 operator++(int)
4812 { ++*this; }
4813
4814 constexpr _Iterator
4815 operator++(int)
4816 requires __detail::__all_forward<_Const, _Vs...>
4817 {
4818 auto __tmp = *this;
4819 ++*this;
4820 return __tmp;
4821 }
4822
4823 constexpr _Iterator&
4824 operator--()
4825 requires __detail::__all_bidirectional<_Const, _Vs...>
4826 {
4827 __detail::__tuple_for_each([](auto& __i) { --__i; }, _M_current);
4828 return *this;
4829 }
4830
4831 constexpr _Iterator
4832 operator--(int)
4833 requires __detail::__all_bidirectional<_Const, _Vs...>
4834 {
4835 auto __tmp = *this;
4836 --*this;
4837 return __tmp;
4838 }
4839
4840 constexpr _Iterator&
4841 operator+=(difference_type __x)
4842 requires __detail::__all_random_access<_Const, _Vs...>
4843 {
4844 auto __f = [&]<typename _It>(_It& __i) {
4845 __i += iter_difference_t<_It>(__x);
4846 };
4847 __detail::__tuple_for_each(__f, _M_current);
4848 return *this;
4849 }
4850
4851 constexpr _Iterator&
4852 operator-=(difference_type __x)
4853 requires __detail::__all_random_access<_Const, _Vs...>
4854 {
4855 auto __f = [&]<typename _It>(_It& __i) {
4856 __i -= iter_difference_t<_It>(__x);
4857 };
4858 __detail::__tuple_for_each(__f, _M_current);
4859 return *this;
4860 }
4861
4862 constexpr auto
4863 operator[](difference_type __n) const
4864 requires __detail::__all_random_access<_Const, _Vs...>
4865 {
4866 auto __f = [&]<typename _It>(_It& __i) -> decltype(auto) {
4867 return __i[iter_difference_t<_It>(__n)];
4868 };
4869 return __detail::__tuple_transform(__f, _M_current);
4870 }
4871
4872 friend constexpr bool
4873 operator==(const _Iterator& __x, const _Iterator& __y)
4874 requires (equality_comparable<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4875 {
4876 if constexpr (__detail::__all_bidirectional<_Const, _Vs...>)
4877 return __x._M_current == __y._M_current;
4878 else
4879 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4880 return ((std::get<_Is>(__x._M_current) == std::get<_Is>(__y._M_current)) || ...);
4881 }(make_index_sequence<sizeof...(_Vs)>{});
4882 }
4883
4884 friend constexpr auto
4885 operator<=>(const _Iterator& __x, const _Iterator& __y)
4886 requires __detail::__all_random_access<_Const, _Vs...>
4887 { return __x._M_current <=> __y._M_current; }
4888
4889 friend constexpr _Iterator
4890 operator+(const _Iterator& __i, difference_type __n)
4891 requires __detail::__all_random_access<_Const, _Vs...>
4892 {
4893 auto __r = __i;
4894 __r += __n;
4895 return __r;
4896 }
4897
4898 friend constexpr _Iterator
4899 operator+(difference_type __n, const _Iterator& __i)
4900 requires __detail::__all_random_access<_Const, _Vs...>
4901 {
4902 auto __r = __i;
4903 __r += __n;
4904 return __r;
4905 }
4906
4907 friend constexpr _Iterator
4908 operator-(const _Iterator& __i, difference_type __n)
4909 requires __detail::__all_random_access<_Const, _Vs...>
4910 {
4911 auto __r = __i;
4912 __r -= __n;
4913 return __r;
4914 }
4915
4916 friend constexpr difference_type
4917 operator-(const _Iterator& __x, const _Iterator& __y)
4918 requires (sized_sentinel_for<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>,
4919 iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4920 {
4921 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4922 return ranges::min({difference_type(std::get<_Is>(__x._M_current)
4923 - std::get<_Is>(__y._M_current))...},
4924 ranges::less{},
4925 [](difference_type __i) {
4926 return __detail::__to_unsigned_like(__i < 0 ? -__i : __i);
4927 });
4928 }(make_index_sequence<sizeof...(_Vs)>{});
4929 }
4930
4931 friend constexpr auto
4932 iter_move(const _Iterator& __i)
4933 { return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
4934
4935 friend constexpr void
4936 iter_swap(const _Iterator& __l, const _Iterator& __r)
4937 requires (indirectly_swappable<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4938 {
4939 [&]<size_t... _Is>(index_sequence<_Is...>) {
4940 (ranges::iter_swap(std::get<_Is>(__l._M_current), std::get<_Is>(__r._M_current)), ...);
4941 }(make_index_sequence<sizeof...(_Vs)>{});
4942 }
4943
4944 friend class zip_view;
4945 };
4946
4947 template<input_range... _Vs>
4948 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0)
4949 template<bool _Const>
4950 class zip_view<_Vs...>::_Sentinel
4951 {
4952 tuple<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>...> _M_end;
4953
4954 constexpr explicit
4955 _Sentinel(decltype(_M_end) __end)
4956 : _M_end(__end)
4957 { }
4958
4959 friend class zip_view;
4960
4961 public:
4962 _Sentinel() = default;
4963
4964 constexpr
4965 _Sentinel(_Sentinel<!_Const> __i)
4966 requires _Const
4967 && (convertible_to<sentinel_t<_Vs>,
4968 sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4969 : _M_end(std::move(__i._M_end))
4970 { }
4971
4972 template<bool _OtherConst>
4973 requires (sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
4974 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
4975 friend constexpr bool
4976 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
4977 {
4978 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4979 return ((std::get<_Is>(__x._M_current) == std::get<_Is>(__y._M_end)) || ...);
4980 }(make_index_sequence<sizeof...(_Vs)>{});
4981 }
4982
4983 template<bool _OtherConst>
4984 requires (sized_sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
4985 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
4986 friend constexpr auto
4987 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
4988 {
4989 using _Ret
4990 = common_type_t<range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vs>>...>;
4991 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4992 return ranges::min({_Ret(std::get<_Is>(__x._M_current) - std::get<_Is>(__y._M_end))...},
4993 ranges::less{},
4994 [](_Ret __i) {
4995 return __detail::__to_unsigned_like(__i < 0 ? -__i : __i);
4996 });
4997 }(make_index_sequence<sizeof...(_Vs)>{});
4998 }
4999
5000 template<bool _OtherConst>
5001 requires (sized_sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
5002 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
5003 friend constexpr auto
5004 operator-(const _Sentinel& __y, const _Iterator<_OtherConst>& __x)
5005 { return -(__x - __y); }
5006 };
5007
5008 namespace views
5009 {
5010 namespace __detail
5011 {
5012 template<typename... _Ts>
5013 concept __can_zip_view
5014 = requires { zip_view<all_t<_Ts>...>(std::declval<_Ts>()...); };
5015 }
5016
5017 struct _Zip
5018 {
5019 template<typename... _Ts>
5020 requires (sizeof...(_Ts) == 0 || __detail::__can_zip_view<_Ts...>)
5021 constexpr auto
5022 operator() [[nodiscard]] (_Ts&&... __ts) const
5023 {
5024 if constexpr (sizeof...(_Ts) == 0)
5025 return views::empty<tuple<>>;
5026 else
5027 return zip_view<all_t<_Ts>...>(std::forward<_Ts>(__ts)...);
5028 }
5029 };
5030
5031 inline constexpr _Zip zip;
5032 }
5033
5034 namespace __detail
5035 {
5036 template<typename _Range, bool _Const>
5037 using __range_iter_cat
5038 = typename iterator_traits<iterator_t<__maybe_const_t<_Const, _Range>>>::iterator_category;
5039 }
5040
5041 template<move_constructible _Fp, input_range... _Vs>
5042 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && is_object_v<_Fp>
5043 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
5044 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
5045 class zip_transform_view : public view_interface<zip_transform_view<_Fp, _Vs...>>
5046 {
5047 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
5048 zip_view<_Vs...> _M_zip;
5049
5050 using _InnerView = zip_view<_Vs...>;
5051
5052 template<bool _Const>
5053 using __ziperator = iterator_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5054
5055 template<bool _Const>
5056 using __zentinel = sentinel_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5057
5058 template<bool _Const>
5059 using _Base = __detail::__maybe_const_t<_Const, _InnerView>;
5060
5061 template<bool _Const>
5062 struct __iter_cat
5063 { };
5064
5065 template<bool _Const>
5066 requires forward_range<_Base<_Const>>
5067 struct __iter_cat<_Const>
5068 {
5069 private:
5070 static auto
5071 _S_iter_cat()
5072 {
5073 using __detail::__maybe_const_t;
5074 using __detail::__range_iter_cat;
5075 using _Res = invoke_result_t<__maybe_const_t<_Const, _Fp>&,
5076 range_reference_t<__maybe_const_t<_Const, _Vs>>...>;
5077 // _GLIBCXX_RESOLVE_LIB_DEFECTS
5078 // 3798. Rvalue reference and iterator_category
5079 if constexpr (!is_reference_v<_Res>)
5080 return input_iterator_tag{};
5081 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
5082 random_access_iterator_tag> && ...))
5083 return random_access_iterator_tag{};
5084 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
5085 bidirectional_iterator_tag> && ...))
5086 return bidirectional_iterator_tag{};
5087 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
5088 forward_iterator_tag> && ...))
5089 return forward_iterator_tag{};
5090 else
5091 return input_iterator_tag{};
5092 }
5093 public:
5094 using iterator_category = decltype(_S_iter_cat());
5095 };
5096
5097 template<bool> class _Iterator;
5098 template<bool> class _Sentinel;
5099
5100 public:
5101 zip_transform_view() = default;
5102
5103 constexpr explicit
5104 zip_transform_view(_Fp __fun, _Vs... __views)
5105 : _M_fun(std::move(__fun)), _M_zip(std::move(__views)...)
5106 { }
5107
5108 constexpr auto
5109 begin()
5110 { return _Iterator<false>(*this, _M_zip.begin()); }
5111
5112 constexpr auto
5113 begin() const
5114 requires range<const _InnerView>
5115 && regular_invocable<const _Fp&, range_reference_t<const _Vs>...>
5116 { return _Iterator<true>(*this, _M_zip.begin()); }
5117
5118 constexpr auto
5119 end()
5120 {
5121 if constexpr (common_range<_InnerView>)
5122 return _Iterator<false>(*this, _M_zip.end());
5123 else
5124 return _Sentinel<false>(_M_zip.end());
5125 }
5126
5127 constexpr auto
5128 end() const
5129 requires range<const _InnerView>
5130 && regular_invocable<const _Fp&, range_reference_t<const _Vs>...>
5131 {
5132 if constexpr (common_range<const _InnerView>)
5133 return _Iterator<true>(*this, _M_zip.end());
5134 else
5135 return _Sentinel<true>(_M_zip.end());
5136 }
5137
5138 constexpr auto
5139 size() requires sized_range<_InnerView>
5140 { return _M_zip.size(); }
5141
5142 constexpr auto
5143 size() const requires sized_range<const _InnerView>
5144 { return _M_zip.size(); }
5145 };
5146
5147 template<class _Fp, class... Rs>
5148 zip_transform_view(_Fp, Rs&&...) -> zip_transform_view<_Fp, views::all_t<Rs>...>;
5149
5150 template<move_constructible _Fp, input_range... _Vs>
5151 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && is_object_v<_Fp>
5152 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
5153 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
5154 template<bool _Const>
5155 class zip_transform_view<_Fp, _Vs...>::_Iterator : public __iter_cat<_Const>
5156 {
5157 using _Parent = __detail::__maybe_const_t<_Const, zip_transform_view>;
5158
5159 _Parent* _M_parent = nullptr;
5160 __ziperator<_Const> _M_inner;
5161
5162 constexpr
5163 _Iterator(_Parent& __parent, __ziperator<_Const> __inner)
5164 : _M_parent(std::__addressof(__parent)), _M_inner(std::move(__inner))
5165 { }
5166
5167 friend class zip_transform_view;
5168
5169 public:
5170 // iterator_category defined in zip_transform_view::__iter_cat
5171 using iterator_concept = typename __ziperator<_Const>::iterator_concept;
5172 using value_type
5173 = remove_cvref_t<invoke_result_t<__detail::__maybe_const_t<_Const, _Fp>&,
5174 range_reference_t<__detail::__maybe_const_t<_Const, _Vs>>...>>;
5175 using difference_type = range_difference_t<_Base<_Const>>;
5176
5177 _Iterator() = default;
5178
5179 constexpr
5180 _Iterator(_Iterator<!_Const> __i)
5181 requires _Const && convertible_to<__ziperator<false>, __ziperator<_Const>>
5182 : _M_parent(__i._M_parent), _M_inner(std::move(__i._M_inner))
5183 { }
5184
5185 constexpr decltype(auto)
5186 operator*() const
5187 {
5188 return std::apply([&](const auto&... __iters) -> decltype(auto) {
5189 return std::__invoke(*_M_parent->_M_fun, *__iters...);
5190 }, _M_inner._M_current);
5191 }
5192
5193 constexpr _Iterator&
5194 operator++()
5195 {
5196 ++_M_inner;
5197 return *this;
5198 }
5199
5200 constexpr void
5201 operator++(int)
5202 { ++*this; }
5203
5204 constexpr _Iterator
5205 operator++(int) requires forward_range<_Base<_Const>>
5206 {
5207 auto __tmp = *this;
5208 ++*this;
5209 return __tmp;
5210 }
5211
5212 constexpr _Iterator&
5213 operator--() requires bidirectional_range<_Base<_Const>>
5214 {
5215 --_M_inner;
5216 return *this;
5217 }
5218
5219 constexpr _Iterator
5220 operator--(int) requires bidirectional_range<_Base<_Const>>
5221 {
5222 auto __tmp = *this;
5223 --*this;
5224 return __tmp;
5225 }
5226
5227 constexpr _Iterator&
5228 operator+=(difference_type __x) requires random_access_range<_Base<_Const>>
5229 {
5230 _M_inner += __x;
5231 return *this;
5232 }
5233
5234 constexpr _Iterator&
5235 operator-=(difference_type __x) requires random_access_range<_Base<_Const>>
5236 {
5237 _M_inner -= __x;
5238 return *this;
5239 }
5240
5241 constexpr decltype(auto)
5242 operator[](difference_type __n) const requires random_access_range<_Base<_Const>>
5243 {
5244 return std::apply([&]<typename... _Is>(const _Is&... __iters) -> decltype(auto) {
5245 return std::__invoke(*_M_parent->_M_fun, __iters[iter_difference_t<_Is>(__n)]...);
5246 }, _M_inner._M_current);
5247 }
5248
5249 friend constexpr bool
5250 operator==(const _Iterator& __x, const _Iterator& __y)
5251 requires equality_comparable<__ziperator<_Const>>
5252 { return __x._M_inner == __y._M_inner; }
5253
5254 friend constexpr auto
5255 operator<=>(const _Iterator& __x, const _Iterator& __y)
5256 requires random_access_range<_Base<_Const>>
5257 { return __x._M_inner <=> __y._M_inner; }
5258
5259 friend constexpr _Iterator
5260 operator+(const _Iterator& __i, difference_type __n)
5261 requires random_access_range<_Base<_Const>>
5262 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5263
5264 friend constexpr _Iterator
5265 operator+(difference_type __n, const _Iterator& __i)
5266 requires random_access_range<_Base<_Const>>
5267 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5268
5269 friend constexpr _Iterator
5270 operator-(const _Iterator& __i, difference_type __n)
5271 requires random_access_range<_Base<_Const>>
5272 { return _Iterator(*__i._M_parent, __i._M_inner - __n); }
5273
5274 friend constexpr difference_type
5275 operator-(const _Iterator& __x, const _Iterator& __y)
5276 requires sized_sentinel_for<__ziperator<_Const>, __ziperator<_Const>>
5277 { return __x._M_inner - __y._M_inner; }
5278 };
5279
5280 template<move_constructible _Fp, input_range... _Vs>
5281 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && is_object_v<_Fp>
5282 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
5283 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
5284 template<bool _Const>
5285 class zip_transform_view<_Fp, _Vs...>::_Sentinel
5286 {
5287 __zentinel<_Const> _M_inner;
5288
5289 constexpr explicit
5290 _Sentinel(__zentinel<_Const> __inner)
5291 : _M_inner(__inner)
5292 { }
5293
5294 friend class zip_transform_view;
5295
5296 public:
5297 _Sentinel() = default;
5298
5299 constexpr
5300 _Sentinel(_Sentinel<!_Const> __i)
5301 requires _Const && convertible_to<__zentinel<false>, __zentinel<_Const>>
5302 : _M_inner(std::move(__i._M_inner))
5303 { }
5304
5305 template<bool _OtherConst>
5306 requires sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5307 friend constexpr bool
5308 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5309 { return __x._M_inner == __y._M_inner; }
5310
5311 template<bool _OtherConst>
5312 requires sized_sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5313 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5314 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5315 { return __x._M_inner - __y._M_inner; }
5316
5317 template<bool _OtherConst>
5318 requires sized_sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5319 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5320 operator-(const _Sentinel& __x, const _Iterator<_OtherConst>& __y)
5321 { return __x._M_inner - __y._M_inner; }
5322 };
5323
5324 namespace views
5325 {
5326 namespace __detail
5327 {
5328 template<typename _Fp, typename... _Ts>
5329 concept __can_zip_transform_view
5330 = requires { zip_transform_view(std::declval<_Fp>(), std::declval<_Ts>()...); };
5331 }
5332
5333 struct _ZipTransform
5334 {
5335 template<typename _Fp, typename... _Ts>
5336 requires (sizeof...(_Ts) == 0) || __detail::__can_zip_transform_view<_Fp, _Ts...>
5337 constexpr auto
5338 operator() [[nodiscard]] (_Fp&& __f, _Ts&&... __ts) const
5339 {
5340 if constexpr (sizeof...(_Ts) == 0)
5341 return views::empty<decay_t<invoke_result_t<decay_t<_Fp>&>>>;
5342 else
5343 return zip_transform_view(std::forward<_Fp>(__f), std::forward<_Ts>(__ts)...);
5344 }
5345 };
5346
5347 inline constexpr _ZipTransform zip_transform;
5348 }
5349
5350 template<forward_range _Vp, size_t _Nm>
5351 requires view<_Vp> && (_Nm > 0)
5352 class adjacent_view : public view_interface<adjacent_view<_Vp, _Nm>>
5353 {
5354 _Vp _M_base = _Vp();
5355
5356 template<bool> class _Iterator;
5357 template<bool> class _Sentinel;
5358
5359 struct __as_sentinel
5360 { };
5361
5362 public:
5363 adjacent_view() requires default_initializable<_Vp> = default;
5364
5365 constexpr explicit
5366 adjacent_view(_Vp __base)
5367 : _M_base(std::move(__base))
5368 { }
5369
5370 // _GLIBCXX_RESOLVE_LIB_DEFECTS
5371 // 3848. adjacent_view, adjacent_transform_view and slide_view missing base accessor
5372 constexpr _Vp
5373 base() const & requires copy_constructible<_Vp>
5374 { return _M_base; }
5375
5376 constexpr _Vp
5377 base() &&
5378 { return std::move(_M_base); }
5379
5380 constexpr auto
5381 begin() requires (!__detail::__simple_view<_Vp>)
5382 { return _Iterator<false>(ranges::begin(_M_base), ranges::end(_M_base)); }
5383
5384 constexpr auto
5385 begin() const requires range<const _Vp>
5386 { return _Iterator<true>(ranges::begin(_M_base), ranges::end(_M_base)); }
5387
5388 constexpr auto
5389 end() requires (!__detail::__simple_view<_Vp>)
5390 {
5391 if constexpr (common_range<_Vp>)
5392 return _Iterator<false>(__as_sentinel{}, ranges::begin(_M_base), ranges::end(_M_base));
5393 else
5394 return _Sentinel<false>(ranges::end(_M_base));
5395 }
5396
5397 constexpr auto
5398 end() const requires range<const _Vp>
5399 {
5400 if constexpr (common_range<const _Vp>)
5401 return _Iterator<true>(__as_sentinel{}, ranges::begin(_M_base), ranges::end(_M_base));
5402 else
5403 return _Sentinel<true>(ranges::end(_M_base));
5404 }
5405
5406 constexpr auto
5407 size() requires sized_range<_Vp>
5408 {
5409 using _ST = decltype(ranges::size(_M_base));
5410 using _CT = common_type_t<_ST, size_t>;
5411 auto __sz = static_cast<_CT>(ranges::size(_M_base));
5412 __sz -= std::min<_CT>(__sz, _Nm - 1);
5413 return static_cast<_ST>(__sz);
5414 }
5415
5416 constexpr auto
5417 size() const requires sized_range<const _Vp>
5418 {
5419 using _ST = decltype(ranges::size(_M_base));
5420 using _CT = common_type_t<_ST, size_t>;
5421 auto __sz = static_cast<_CT>(ranges::size(_M_base));
5422 __sz -= std::min<_CT>(__sz, _Nm - 1);
5423 return static_cast<_ST>(__sz);
5424 }
5425 };
5426
5427 template<typename _Vp, size_t _Nm>
5428 inline constexpr bool enable_borrowed_range<adjacent_view<_Vp, _Nm>>
5429 = enable_borrowed_range<_Vp>;
5430
5431 namespace __detail
5432 {
5433 // Yields tuple<_Tp, ..., _Tp> with _Nm elements.
5434 template<typename _Tp, size_t _Nm>
5435 using __repeated_tuple = decltype(std::tuple_cat(std::declval<array<_Tp, _Nm>>()));
5436
5437 // For a functor F that is callable with N arguments, the expression
5438 // declval<__unarize<F, N>>(x) is equivalent to declval<F>(x, ..., x).
5439 template<typename _Fp, size_t _Nm>
5440 struct __unarize
5441 {
5442 template<typename... _Ts>
5443 static invoke_result_t<_Fp, _Ts...>
5444 __tuple_apply(const tuple<_Ts...>&); // not defined
5445
5446 template<typename _Tp>
5447 decltype(__tuple_apply(std::declval<__repeated_tuple<_Tp, _Nm>>()))
5448 operator()(_Tp&&); // not defined
5449 };
5450 }
5451
5452 template<forward_range _Vp, size_t _Nm>
5453 requires view<_Vp> && (_Nm > 0)
5454 template<bool _Const>
5455 class adjacent_view<_Vp, _Nm>::_Iterator
5456 {
5457#ifdef _GLIBCXX_CLANG // LLVM-61763 workaround
5458 public:
5459#endif
5460 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5461 array<iterator_t<_Base>, _Nm> _M_current = array<iterator_t<_Base>, _Nm>();
5462
5463 constexpr
5464 _Iterator(iterator_t<_Base> __first, sentinel_t<_Base> __last)
5465 {
5466 for (auto& __i : _M_current)
5467 {
5468 __i = __first;
5469 ranges::advance(__first, 1, __last);
5470 }
5471 }
5472
5473 constexpr
5474 _Iterator(__as_sentinel, iterator_t<_Base> __first, iterator_t<_Base> __last)
5475 {
5476 if constexpr (!bidirectional_range<_Base>)
5477 for (auto& __it : _M_current)
5478 __it = __last;
5479 else
5480 for (size_t __i = 0; __i < _Nm; ++__i)
5481 {
5482 _M_current[_Nm - 1 - __i] = __last;
5483 ranges::advance(__last, -1, __first);
5484 }
5485 }
5486
5487 static auto
5488 _S_iter_concept()
5489 {
5490 if constexpr (random_access_range<_Base>)
5491 return random_access_iterator_tag{};
5492 else if constexpr (bidirectional_range<_Base>)
5493 return bidirectional_iterator_tag{};
5494 else
5495 return forward_iterator_tag{};
5496 }
5497
5498 friend class adjacent_view;
5499
5500#ifndef _GLIBCXX_CLANG // LLVM-61763 workaround
5501 template<forward_range _Wp, move_constructible _Fp, size_t _Mm>
5502 requires view<_Wp> && (_Mm > 0) && is_object_v<_Fp>
5503 && regular_invocable<__detail::__unarize<_Fp&, _Mm>, range_reference_t<_Wp>>
5504 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Mm>,
5505 range_reference_t<_Wp>>>
5506 friend class adjacent_transform_view;
5507#endif
5508
5509 public:
5510 using iterator_category = input_iterator_tag;
5511 using iterator_concept = decltype(_S_iter_concept());
5512 using value_type = conditional_t<_Nm == 2,
5513 pair<range_value_t<_Base>, range_value_t<_Base>>,
5514 __detail::__repeated_tuple<range_value_t<_Base>, _Nm>>;
5515 using difference_type = range_difference_t<_Base>;
5516
5517 _Iterator() = default;
5518
5519 constexpr
5520 _Iterator(_Iterator<!_Const> __i)
5521 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
5522 {
5523 for (size_t __j = 0; __j < _Nm; ++__j)
5524 _M_current[__j] = std::move(__i._M_current[__j]);
5525 }
5526
5527 constexpr auto
5528 operator*() const
5529 {
5530 auto __f = [](auto& __i) -> decltype(auto) { return *__i; };
5531 return __detail::__tuple_transform(__f, _M_current);
5532 }
5533
5534 constexpr _Iterator&
5535 operator++()
5536 {
5537 for (auto& __i : _M_current)
5538 ++__i;
5539 return *this;
5540 }
5541
5542 constexpr _Iterator
5543 operator++(int)
5544 {
5545 auto __tmp = *this;
5546 ++*this;
5547 return __tmp;
5548 }
5549
5550 constexpr _Iterator&
5551 operator--() requires bidirectional_range<_Base>
5552 {
5553 for (auto& __i : _M_current)
5554 --__i;
5555 return *this;
5556 }
5557
5558 constexpr _Iterator
5559 operator--(int) requires bidirectional_range<_Base>
5560 {
5561 auto __tmp = *this;
5562 --*this;
5563 return __tmp;
5564 }
5565
5566 constexpr _Iterator&
5567 operator+=(difference_type __x)
5568 requires random_access_range<_Base>
5569 {
5570 for (auto& __i : _M_current)
5571 __i += __x;
5572 return *this;
5573 }
5574
5575 constexpr _Iterator&
5576 operator-=(difference_type __x)
5577 requires random_access_range<_Base>
5578 {
5579 for (auto& __i : _M_current)
5580 __i -= __x;
5581 return *this;
5582 }
5583
5584 constexpr auto
5585 operator[](difference_type __n) const
5586 requires random_access_range<_Base>
5587 {
5588 auto __f = [&](auto& __i) -> decltype(auto) { return __i[__n]; };
5589 return __detail::__tuple_transform(__f, _M_current);
5590 }
5591
5592 friend constexpr bool
5593 operator==(const _Iterator& __x, const _Iterator& __y)
5594 { return __x._M_current.back() == __y._M_current.back(); }
5595
5596 friend constexpr bool
5597 operator<(const _Iterator& __x, const _Iterator& __y)
5598 requires random_access_range<_Base>
5599 { return __x._M_current.back() < __y._M_current.back(); }
5600
5601 friend constexpr bool
5602 operator>(const _Iterator& __x, const _Iterator& __y)
5603 requires random_access_range<_Base>
5604 { return __y < __x; }
5605
5606 friend constexpr bool
5607 operator<=(const _Iterator& __x, const _Iterator& __y)
5608 requires random_access_range<_Base>
5609 { return !(__y < __x); }
5610
5611 friend constexpr bool
5612 operator>=(const _Iterator& __x, const _Iterator& __y)
5613 requires random_access_range<_Base>
5614 { return !(__x < __y); }
5615
5616 friend constexpr auto
5617 operator<=>(const _Iterator& __x, const _Iterator& __y)
5618 requires random_access_range<_Base>
5619 && three_way_comparable<iterator_t<_Base>>
5620 { return __x._M_current.back() <=> __y._M_current.back(); }
5621
5622 friend constexpr _Iterator
5623 operator+(const _Iterator& __i, difference_type __n)
5624 requires random_access_range<_Base>
5625 {
5626 auto __r = __i;
5627 __r += __n;
5628 return __r;
5629 }
5630
5631 friend constexpr _Iterator
5632 operator+(difference_type __n, const _Iterator& __i)
5633 requires random_access_range<_Base>
5634 {
5635 auto __r = __i;
5636 __r += __n;
5637 return __r;
5638 }
5639
5640 friend constexpr _Iterator
5641 operator-(const _Iterator& __i, difference_type __n)
5642 requires random_access_range<_Base>
5643 {
5644 auto __r = __i;
5645 __r -= __n;
5646 return __r;
5647 }
5648
5649 friend constexpr difference_type
5650 operator-(const _Iterator& __x, const _Iterator& __y)
5651 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
5652 { return __x._M_current.back() - __y._M_current.back(); }
5653
5654 friend constexpr auto
5655 iter_move(const _Iterator& __i)
5656 { return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
5657
5658 friend constexpr void
5659 iter_swap(const _Iterator& __l, const _Iterator& __r)
5660 requires indirectly_swappable<iterator_t<_Base>>
5661 {
5662 for (size_t __i = 0; __i < _Nm; __i++)
5663 ranges::iter_swap(__l._M_current[__i], __r._M_current[__i]);
5664 }
5665 };
5666
5667 template<forward_range _Vp, size_t _Nm>
5668 requires view<_Vp> && (_Nm > 0)
5669 template<bool _Const>
5670 class adjacent_view<_Vp, _Nm>::_Sentinel
5671 {
5672 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5673
5674 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
5675
5676 constexpr explicit
5677 _Sentinel(sentinel_t<_Base> __end)
5678 : _M_end(__end)
5679 { }
5680
5681 friend class adjacent_view;
5682
5683 public:
5684 _Sentinel() = default;
5685
5686 constexpr
5687 _Sentinel(_Sentinel<!_Const> __i)
5688 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
5689 : _M_end(std::move(__i._M_end))
5690 { }
5691
5692 template<bool _OtherConst>
5693 requires sentinel_for<sentinel_t<_Base>,
5694 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5695 friend constexpr bool
5696 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5697 { return __x._M_current.back() == __y._M_end; }
5698
5699 template<bool _OtherConst>
5700 requires sized_sentinel_for<sentinel_t<_Base>,
5701 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5702 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vp>>
5703 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5704 { return __x._M_current.back() - __y._M_end; }
5705
5706 template<bool _OtherConst>
5707 requires sized_sentinel_for<sentinel_t<_Base>,
5708 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5709 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vp>>
5710 operator-(const _Sentinel& __y, const _Iterator<_OtherConst>& __x)
5711 { return __y._M_end - __x._M_current.back(); }
5712 };
5713
5714 namespace views
5715 {
5716 namespace __detail
5717 {
5718 template<size_t _Nm, typename _Range>
5719 concept __can_adjacent_view
5720 = requires { adjacent_view<all_t<_Range>, _Nm>(std::declval<_Range>()); };
5721 }
5722
5723 template<size_t _Nm>
5724 struct _Adjacent : __adaptor::_RangeAdaptorClosure<_Adjacent<_Nm>>
5725 {
5726 template<viewable_range _Range>
5727 requires (_Nm == 0) || __detail::__can_adjacent_view<_Nm, _Range>
5728 constexpr auto
5729 operator() [[nodiscard]] (_Range&& __r) const
5730 {
5731 if constexpr (_Nm == 0)
5732 return views::empty<tuple<>>;
5733 else
5734 return adjacent_view<all_t<_Range>, _Nm>(std::forward<_Range>(__r));
5735 }
5736 };
5737
5738 template<size_t _Nm>
5739 inline constexpr _Adjacent<_Nm> adjacent;
5740
5741 inline constexpr auto pairwise = adjacent<2>;
5742 }
5743
5744 template<forward_range _Vp, move_constructible _Fp, size_t _Nm>
5745 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5746 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5747 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5748 range_reference_t<_Vp>>>
5749 class adjacent_transform_view : public view_interface<adjacent_transform_view<_Vp, _Fp, _Nm>>
5750 {
5751 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
5752 adjacent_view<_Vp, _Nm> _M_inner;
5753
5754 using _InnerView = adjacent_view<_Vp, _Nm>;
5755
5756 template<bool _Const>
5757 using _InnerIter = iterator_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5758
5759 template<bool _Const>
5760 using _InnerSent = sentinel_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5761
5762 template<bool> class _Iterator;
5763 template<bool> class _Sentinel;
5764
5765 public:
5766 adjacent_transform_view() = default;
5767
5768 constexpr explicit
5769 adjacent_transform_view(_Vp __base, _Fp __fun)
5770 : _M_fun(std::move(__fun)), _M_inner(std::move(__base))
5771 { }
5772
5773 // _GLIBCXX_RESOLVE_LIB_DEFECTS
5774 // 3848. adjacent_view, adjacent_transform_view and slide_view missing base accessor
5775 // 3947. Unexpected constraints on adjacent_transform_view::base()
5776 constexpr _Vp
5777 base() const & requires copy_constructible<_Vp>
5778 { return _M_inner.base(); }
5779
5780 constexpr _Vp
5781 base() &&
5782 { return std::move(_M_inner.base()); }
5783
5784 constexpr auto
5785 begin()
5786 { return _Iterator<false>(*this, _M_inner.begin()); }
5787
5788 constexpr auto
5789 begin() const
5790 requires range<const _InnerView>
5791 && regular_invocable<__detail::__unarize<const _Fp&, _Nm>,
5792 range_reference_t<const _Vp>>
5793 { return _Iterator<true>(*this, _M_inner.begin()); }
5794
5795 constexpr auto
5796 end()
5797 {
5798 if constexpr (common_range<_InnerView>)
5799 return _Iterator<false>(*this, _M_inner.end());
5800 else
5801 return _Sentinel<false>(_M_inner.end());
5802 }
5803
5804 constexpr auto
5805 end() const
5806 requires range<const _InnerView>
5807 && regular_invocable<__detail::__unarize<const _Fp&, _Nm>,
5808 range_reference_t<const _Vp>>
5809 {
5810 if constexpr (common_range<const _InnerView>)
5811 return _Iterator<true>(*this, _M_inner.end());
5812 else
5813 return _Sentinel<true>(_M_inner.end());
5814 }
5815
5816 constexpr auto
5817 size() requires sized_range<_InnerView>
5818 { return _M_inner.size(); }
5819
5820 constexpr auto
5821 size() const requires sized_range<const _InnerView>
5822 { return _M_inner.size(); }
5823 };
5824
5825 template<forward_range _Vp, move_constructible _Fp, size_t _Nm>
5826 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5827 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5828 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5829 range_reference_t<_Vp>>>
5830 template<bool _Const>
5831 class adjacent_transform_view<_Vp, _Fp, _Nm>::_Iterator
5832 {
5833 using _Parent = __detail::__maybe_const_t<_Const, adjacent_transform_view>;
5834 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5835
5836 _Parent* _M_parent = nullptr;
5837 _InnerIter<_Const> _M_inner;
5838
5839 constexpr
5840 _Iterator(_Parent& __parent, _InnerIter<_Const> __inner)
5841 : _M_parent(std::__addressof(__parent)), _M_inner(std::move(__inner))
5842 { }
5843
5844 static auto
5845 _S_iter_cat()
5846 {
5847 using __detail::__maybe_const_t;
5848 using __detail::__unarize;
5849 using _Res = invoke_result_t<__unarize<__maybe_const_t<_Const, _Fp>&, _Nm>,
5850 range_reference_t<_Base>>;
5851 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
5852 // _GLIBCXX_RESOLVE_LIB_DEFECTS
5853 // 3798. Rvalue reference and iterator_category
5854 if constexpr (!is_reference_v<_Res>)
5855 return input_iterator_tag{};
5856 else if constexpr (derived_from<_Cat, random_access_iterator_tag>)
5857 return random_access_iterator_tag{};
5858 else if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
5859 return bidirectional_iterator_tag{};
5860 else if constexpr (derived_from<_Cat, forward_iterator_tag>)
5861 return forward_iterator_tag{};
5862 else
5863 return input_iterator_tag{};
5864 }
5865
5866 friend class adjacent_transform_view;
5867
5868 public:
5869 using iterator_category = decltype(_S_iter_cat());
5870 using iterator_concept = typename _InnerIter<_Const>::iterator_concept;
5871 using value_type
5872 = remove_cvref_t<invoke_result_t
5873 <__detail::__unarize<__detail::__maybe_const_t<_Const, _Fp>&, _Nm>,
5874 range_reference_t<_Base>>>;
5875 using difference_type = range_difference_t<_Base>;
5876
5877 _Iterator() = default;
5878
5879 constexpr
5880 _Iterator(_Iterator<!_Const> __i)
5881 requires _Const && convertible_to<_InnerIter<false>, _InnerIter<_Const>>
5882 : _M_parent(__i._M_parent), _M_inner(std::move(__i._M_inner))
5883 { }
5884
5885 constexpr decltype(auto)
5886 operator*() const
5887 {
5888 return std::apply([&](const auto&... __iters) -> decltype(auto) {
5889 return std::__invoke(*_M_parent->_M_fun, *__iters...);
5890 }, _M_inner._M_current);
5891 }
5892
5893 constexpr _Iterator&
5894 operator++()
5895 {
5896 ++_M_inner;
5897 return *this;
5898 }
5899
5900 constexpr _Iterator
5901 operator++(int)
5902 {
5903 auto __tmp = *this;
5904 ++*this;
5905 return __tmp;
5906 }
5907
5908 constexpr _Iterator&
5909 operator--() requires bidirectional_range<_Base>
5910 {
5911 --_M_inner;
5912 return *this;
5913 }
5914
5915 constexpr _Iterator
5916 operator--(int) requires bidirectional_range<_Base>
5917 {
5918 auto __tmp = *this;
5919 --*this;
5920 return __tmp;
5921 }
5922
5923 constexpr _Iterator&
5924 operator+=(difference_type __x) requires random_access_range<_Base>
5925 {
5926 _M_inner += __x;
5927 return *this;
5928 }
5929
5930 constexpr _Iterator&
5931 operator-=(difference_type __x) requires random_access_range<_Base>
5932 {
5933 _M_inner -= __x;
5934 return *this;
5935 }
5936
5937 constexpr decltype(auto)
5938 operator[](difference_type __n) const requires random_access_range<_Base>
5939 {
5940 return std::apply([&](const auto&... __iters) -> decltype(auto) {
5941 return std::__invoke(*_M_parent->_M_fun, __iters[__n]...);
5942 }, _M_inner._M_current);
5943 }
5944
5945 friend constexpr bool
5946 operator==(const _Iterator& __x, const _Iterator& __y)
5947 { return __x._M_inner == __y._M_inner; }
5948
5949 friend constexpr bool
5950 operator<(const _Iterator& __x, const _Iterator& __y)
5951 requires random_access_range<_Base>
5952 { return __x._M_inner < __y._M_inner; }
5953
5954 friend constexpr bool
5955 operator>(const _Iterator& __x, const _Iterator& __y)
5956 requires random_access_range<_Base>
5957 { return __x._M_inner > __y._M_inner; }
5958
5959 friend constexpr bool
5960 operator<=(const _Iterator& __x, const _Iterator& __y)
5961 requires random_access_range<_Base>
5962 { return __x._M_inner <= __y._M_inner; }
5963
5964 friend constexpr bool
5965 operator>=(const _Iterator& __x, const _Iterator& __y)
5966 requires random_access_range<_Base>
5967 { return __x._M_inner >= __y._M_inner; }
5968
5969 friend constexpr auto
5970 operator<=>(const _Iterator& __x, const _Iterator& __y)
5971 requires random_access_range<_Base> &&
5972 three_way_comparable<_InnerIter<_Const>>
5973 { return __x._M_inner <=> __y._M_inner; }
5974
5975 friend constexpr _Iterator
5976 operator+(const _Iterator& __i, difference_type __n)
5977 requires random_access_range<_Base>
5978 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5979
5980 friend constexpr _Iterator
5981 operator+(difference_type __n, const _Iterator& __i)
5982 requires random_access_range<_Base>
5983 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5984
5985 friend constexpr _Iterator
5986 operator-(const _Iterator& __i, difference_type __n)
5987 requires random_access_range<_Base>
5988 { return _Iterator(*__i._M_parent, __i._M_inner - __n); }
5989
5990 friend constexpr difference_type
5991 operator-(const _Iterator& __x, const _Iterator& __y)
5992 requires sized_sentinel_for<_InnerIter<_Const>, _InnerIter<_Const>>
5993 { return __x._M_inner - __y._M_inner; }
5994 };
5995
5996 template<forward_range _Vp, move_constructible _Fp, size_t _Nm>
5997 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5998 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5999 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
6000 range_reference_t<_Vp>>>
6001 template<bool _Const>
6002 class adjacent_transform_view<_Vp, _Fp, _Nm>::_Sentinel
6003 {
6004 _InnerSent<_Const> _M_inner;
6005
6006 constexpr explicit
6007 _Sentinel(_InnerSent<_Const> __inner)
6008 : _M_inner(__inner)
6009 { }
6010
6011 friend class adjacent_transform_view;
6012
6013 public:
6014 _Sentinel() = default;
6015
6016 constexpr
6017 _Sentinel(_Sentinel<!_Const> __i)
6018 requires _Const && convertible_to<_InnerSent<false>, _InnerSent<_Const>>
6019 : _M_inner(std::move(__i._M_inner))
6020 { }
6021
6022 template<bool _OtherConst>
6023 requires sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
6024 friend constexpr bool
6025 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
6026 { return __x._M_inner == __y._M_inner; }
6027
6028 template<bool _OtherConst>
6029 requires sized_sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
6030 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
6031 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
6032 { return __x._M_inner - __y._M_inner; }
6033
6034 template<bool _OtherConst>
6035 requires sized_sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
6036 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
6037 operator-(const _Sentinel& __x, const _Iterator<_OtherConst>& __y)
6038 { return __x._M_inner - __y._M_inner; }
6039 };
6040
6041 namespace views
6042 {
6043 namespace __detail
6044 {
6045 template<size_t _Nm, typename _Range, typename _Fp>
6046 concept __can_adjacent_transform_view
6047 = requires { adjacent_transform_view<all_t<_Range>, decay_t<_Fp>, _Nm>
6048 (std::declval<_Range>(), std::declval<_Fp>()); };
6049 }
6050
6051 template<size_t _Nm>
6052 struct _AdjacentTransform : __adaptor::_RangeAdaptor<_AdjacentTransform<_Nm>>
6053 {
6054 template<viewable_range _Range, typename _Fp>
6055 requires (_Nm == 0) || __detail::__can_adjacent_transform_view<_Nm, _Range, _Fp>
6056 constexpr auto
6057 operator() [[nodiscard]] (_Range&& __r, _Fp&& __f) const
6058 {
6059 if constexpr (_Nm == 0)
6060 return zip_transform(std::forward<_Fp>(__f));
6061 else
6062 return adjacent_transform_view<all_t<_Range>, decay_t<_Fp>, _Nm>
6063 (std::forward<_Range>(__r), std::forward<_Fp>(__f));
6064 }
6065
6066 using __adaptor::_RangeAdaptor<_AdjacentTransform>::operator();
6067 static constexpr int _S_arity = 2;
6068 static constexpr bool _S_has_simple_extra_args = true;
6069 };
6070
6071 template<size_t _Nm>
6072 inline constexpr _AdjacentTransform<_Nm> adjacent_transform;
6073
6074 inline constexpr auto pairwise_transform = adjacent_transform<2>;
6075 }
6076#endif // __cpp_lib_ranges_zip
6077
6078#ifdef __cpp_lib_ranges_chunk // C++ >= 23
6079 namespace __detail
6080 {
6081 template<typename _Tp>
6082 constexpr _Tp __div_ceil(_Tp __num, _Tp __denom)
6083 {
6084 _Tp __r = __num / __denom;
6085 if (__num % __denom)
6086 ++__r;
6087 return __r;
6088 }
6089 }
6090
6091 template<view _Vp>
6092 requires input_range<_Vp>
6093 class chunk_view : public view_interface<chunk_view<_Vp>>
6094 {
6095 _Vp _M_base;
6096 range_difference_t<_Vp> _M_n;
6097 range_difference_t<_Vp> _M_remainder = 0;
6098 __detail::__non_propagating_cache<iterator_t<_Vp>> _M_current;
6099
6100 class _OuterIter;
6101 class _InnerIter;
6102
6103 public:
6104 constexpr explicit
6105 chunk_view(_Vp __base, range_difference_t<_Vp> __n)
6106 : _M_base(std::move(__base)), _M_n(__n)
6107 { __glibcxx_assert(__n >= 0); }
6108
6109 constexpr _Vp
6110 base() const & requires copy_constructible<_Vp>
6111 { return _M_base; }
6112
6113 constexpr _Vp
6114 base() &&
6115 { return std::move(_M_base); }
6116
6117 constexpr _OuterIter
6118 begin()
6119 {
6120 _M_current = ranges::begin(_M_base);
6121 _M_remainder = _M_n;
6122 return _OuterIter(*this);
6123 }
6124
6125 constexpr default_sentinel_t
6126 end() const noexcept
6127 { return default_sentinel; }
6128
6129 constexpr auto
6130 size() requires sized_range<_Vp>
6131 {
6132 return __detail::__to_unsigned_like(__detail::__div_ceil
6133 (ranges::distance(_M_base), _M_n));
6134 }
6135
6136 constexpr auto
6137 size() const requires sized_range<const _Vp>
6138 {
6139 return __detail::__to_unsigned_like(__detail::__div_ceil
6140 (ranges::distance(_M_base), _M_n));
6141 }
6142 };
6143
6144 template<typename _Range>
6145 chunk_view(_Range&&, range_difference_t<_Range>) -> chunk_view<views::all_t<_Range>>;
6146
6147 template<view _Vp>
6148 requires input_range<_Vp>
6149 class chunk_view<_Vp>::_OuterIter
6150 {
6151 chunk_view* _M_parent;
6152
6153 constexpr explicit
6154 _OuterIter(chunk_view& __parent) noexcept
6155 : _M_parent(std::__addressof(__parent))
6156 { }
6157
6158 friend chunk_view;
6159
6160 public:
6161 using iterator_concept = input_iterator_tag;
6162 using difference_type = range_difference_t<_Vp>;
6163
6164 struct value_type;
6165
6166 _OuterIter(_OuterIter&&) = default;
6167 _OuterIter& operator=(_OuterIter&&) = default;
6168
6169 constexpr value_type
6170 operator*() const
6171 {
6172 __glibcxx_assert(*this != default_sentinel);
6173 return value_type(*_M_parent);
6174 }
6175
6176 constexpr _OuterIter&
6177 operator++()
6178 {
6179 __glibcxx_assert(*this != default_sentinel);
6180 ranges::advance(*_M_parent->_M_current, _M_parent->_M_remainder,
6181 ranges::end(_M_parent->_M_base));
6182 _M_parent->_M_remainder = _M_parent->_M_n;
6183 return *this;
6184 }
6185
6186 constexpr void
6187 operator++(int)
6188 { ++*this; }
6189
6190 friend constexpr bool
6191 operator==(const _OuterIter& __x, default_sentinel_t)
6192 {
6193 return *__x._M_parent->_M_current == ranges::end(__x._M_parent->_M_base)
6194 && __x._M_parent->_M_remainder != 0;
6195 }
6196
6197 friend constexpr difference_type
6198 operator-(default_sentinel_t, const _OuterIter& __x)
6199 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6200 {
6201 const auto __dist = ranges::end(__x._M_parent->_M_base) - *__x._M_parent->_M_current;
6202
6203 if (__dist < __x._M_parent->_M_remainder)
6204 return __dist == 0 ? 0 : 1;
6205
6206 return 1 + __detail::__div_ceil(__dist - __x._M_parent->_M_remainder,
6207 __x._M_parent->_M_n);
6208 }
6209
6210 friend constexpr difference_type
6211 operator-(const _OuterIter& __x, default_sentinel_t __y)
6212 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6213 { return -(__y - __x); }
6214 };
6215
6216 template<view _Vp>
6217 requires input_range<_Vp>
6218 struct chunk_view<_Vp>::_OuterIter::value_type : view_interface<value_type>
6219 {
6220 private:
6221 chunk_view* _M_parent;
6222
6223 constexpr explicit
6224 value_type(chunk_view& __parent) noexcept
6225 : _M_parent(std::__addressof(__parent))
6226 { }
6227
6228 friend _OuterIter;
6229
6230 public:
6231 constexpr _InnerIter
6232 begin() const noexcept
6233 { return _InnerIter(*_M_parent); }
6234
6235 constexpr default_sentinel_t
6236 end() const noexcept
6237 { return default_sentinel; }
6238
6239 constexpr auto
6240 size() const
6241 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6242 {
6243 return __detail::__to_unsigned_like
6244 (ranges::min(_M_parent->_M_remainder,
6245 ranges::end(_M_parent->_M_base) - *_M_parent->_M_current));
6246 }
6247 };
6248
6249 template<view _Vp>
6250 requires input_range<_Vp>
6251 class chunk_view<_Vp>::_InnerIter
6252 {
6253 chunk_view* _M_parent;
6254
6255 constexpr explicit
6256 _InnerIter(chunk_view& __parent) noexcept
6257 : _M_parent(std::__addressof(__parent))
6258 { }
6259
6260 friend _OuterIter::value_type;
6261
6262 public:
6263 using iterator_concept = input_iterator_tag;
6264 using difference_type = range_difference_t<_Vp>;
6265 using value_type = range_value_t<_Vp>;
6266
6267 _InnerIter(_InnerIter&&) = default;
6268 _InnerIter& operator=(_InnerIter&&) = default;
6269
6270 constexpr const iterator_t<_Vp>&
6271 base() const &
6272 { return *_M_parent->_M_current; }
6273
6274 constexpr range_reference_t<_Vp>
6275 operator*() const
6276 {
6277 __glibcxx_assert(*this != default_sentinel);
6278 return **_M_parent->_M_current;
6279 }
6280
6281 constexpr _InnerIter&
6282 operator++()
6283 {
6284 __glibcxx_assert(*this != default_sentinel);
6285 ++*_M_parent->_M_current;
6286 if (*_M_parent->_M_current == ranges::end(_M_parent->_M_base))
6287 _M_parent->_M_remainder = 0;
6288 else
6289 --_M_parent->_M_remainder;
6290 return *this;
6291 }
6292
6293 constexpr void
6294 operator++(int)
6295 { ++*this; }
6296
6297 friend constexpr bool
6298 operator==(const _InnerIter& __x, default_sentinel_t) noexcept
6299 { return __x._M_parent->_M_remainder == 0; }
6300
6301 friend constexpr difference_type
6302 operator-(default_sentinel_t, const _InnerIter& __x)
6303 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6304 {
6305 return ranges::min(__x._M_parent->_M_remainder,
6306 ranges::end(__x._M_parent->_M_base) - *__x._M_parent->_M_current);
6307 }
6308
6309 friend constexpr difference_type
6310 operator-(const _InnerIter& __x, default_sentinel_t __y)
6311 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6312 { return -(__y - __x); }
6313
6314 // _GLIBCXX_RESOLVE_LIB_DEFECTS
6315 // 3851. chunk_view::inner-iterator missing custom iter_move and iter_swap
6316 friend constexpr range_rvalue_reference_t<_Vp>
6317 iter_move(const _InnerIter& __i)
6318 noexcept(noexcept(ranges::iter_move(*__i._M_parent->_M_current)))
6319 { return ranges::iter_move(*__i._M_parent->_M_current); }
6320
6321 friend constexpr void
6322 iter_swap(const _InnerIter& __x, const _InnerIter& __y)
6323 noexcept(noexcept(ranges::iter_swap(*__x._M_parent->_M_current,
6324 *__x._M_parent->_M_current)))
6325 requires indirectly_swappable<iterator_t<_Vp>>
6326 { return ranges::iter_swap(*__x._M_parent->_M_current, *__y._M_parent->_M_current); }
6327 };
6328
6329 template<view _Vp>
6330 requires forward_range<_Vp>
6331 class chunk_view<_Vp> : public view_interface<chunk_view<_Vp>>
6332 {
6333 _Vp _M_base;
6334 range_difference_t<_Vp> _M_n;
6335 template<bool> class _Iterator;
6336
6337 public:
6338 constexpr explicit
6339 chunk_view(_Vp __base, range_difference_t<_Vp> __n)
6340 : _M_base(std::move(__base)), _M_n(__n)
6341 { __glibcxx_assert(__n > 0); }
6342
6343 constexpr _Vp
6344 base() const & requires copy_constructible<_Vp>
6345 { return _M_base; }
6346
6347 constexpr _Vp
6348 base() &&
6349 { return std::move(_M_base); }
6350
6351 constexpr auto
6352 begin() requires (!__detail::__simple_view<_Vp>)
6353 { return _Iterator<false>(this, ranges::begin(_M_base)); }
6354
6355 constexpr auto
6356 begin() const requires forward_range<const _Vp>
6357 { return _Iterator<true>(this, ranges::begin(_M_base)); }
6358
6359 constexpr auto
6360 end() requires (!__detail::__simple_view<_Vp>)
6361 {
6362 if constexpr (common_range<_Vp> && sized_range<_Vp>)
6363 {
6364 auto __missing = (_M_n - ranges::distance(_M_base) % _M_n) % _M_n;
6365 return _Iterator<false>(this, ranges::end(_M_base), __missing);
6366 }
6367 else if constexpr (common_range<_Vp> && !bidirectional_range<_Vp>)
6368 return _Iterator<false>(this, ranges::end(_M_base));
6369 else
6370 return default_sentinel;
6371 }
6372
6373 constexpr auto
6374 end() const requires forward_range<const _Vp>
6375 {
6376 if constexpr (common_range<const _Vp> && sized_range<const _Vp>)
6377 {
6378 auto __missing = (_M_n - ranges::distance(_M_base) % _M_n) % _M_n;
6379 return _Iterator<true>(this, ranges::end(_M_base), __missing);
6380 }
6381 else if constexpr (common_range<const _Vp> && !bidirectional_range<const _Vp>)
6382 return _Iterator<true>(this, ranges::end(_M_base));
6383 else
6384 return default_sentinel;
6385 }
6386
6387 constexpr auto
6388 size() requires sized_range<_Vp>
6389 {
6390 return __detail::__to_unsigned_like(__detail::__div_ceil
6391 (ranges::distance(_M_base), _M_n));
6392 }
6393
6394 constexpr auto
6395 size() const requires sized_range<const _Vp>
6396 {
6397 return __detail::__to_unsigned_like(__detail::__div_ceil
6398 (ranges::distance(_M_base), _M_n));
6399 }
6400 };
6401
6402 template<typename _Vp>
6403 inline constexpr bool enable_borrowed_range<chunk_view<_Vp>>
6404 = forward_range<_Vp> && enable_borrowed_range<_Vp>;
6405
6406 template<view _Vp>
6407 requires forward_range<_Vp>
6408 template<bool _Const>
6409 class chunk_view<_Vp>::_Iterator
6410 {
6411 using _Parent = __detail::__maybe_const_t<_Const, chunk_view>;
6412 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6413
6414 iterator_t<_Base> _M_current = iterator_t<_Base>();
6415 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
6416 range_difference_t<_Base> _M_n = 0;
6417 range_difference_t<_Base> _M_missing = 0;
6418
6419 constexpr
6420 _Iterator(_Parent* __parent, iterator_t<_Base> __current,
6421 range_difference_t<_Base> __missing = 0)
6422 : _M_current(__current), _M_end(ranges::end(__parent->_M_base)),
6423 _M_n(__parent->_M_n), _M_missing(__missing)
6424 { }
6425
6426 static auto
6427 _S_iter_cat()
6428 {
6429 if constexpr (random_access_range<_Base>)
6430 return random_access_iterator_tag{};
6431 else if constexpr (bidirectional_range<_Base>)
6432 return bidirectional_iterator_tag{};
6433 else
6434 return forward_iterator_tag{};
6435 }
6436
6437 friend chunk_view;
6438
6439 public:
6440 using iterator_category = input_iterator_tag;
6441 using iterator_concept = decltype(_S_iter_cat());
6442 using value_type = decltype(views::take(subrange(_M_current, _M_end), _M_n));
6443 using difference_type = range_difference_t<_Base>;
6444
6445 _Iterator() = default;
6446
6447 constexpr _Iterator(_Iterator<!_Const> __i)
6448 requires _Const
6449 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
6450 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
6451 : _M_current(std::move(__i._M_current)), _M_end(std::move(__i._M_end)),
6452 _M_n(__i._M_n), _M_missing(__i._M_missing)
6453 { }
6454
6455 constexpr iterator_t<_Base>
6456 base() const
6457 { return _M_current; }
6458
6459 constexpr value_type
6460 operator*() const
6461 {
6462 __glibcxx_assert(_M_current != _M_end);
6463 return views::take(subrange(_M_current, _M_end), _M_n);
6464 }
6465
6466 constexpr _Iterator&
6467 operator++()
6468 {
6469 __glibcxx_assert(_M_current != _M_end);
6470 _M_missing = ranges::advance(_M_current, _M_n, _M_end);
6471 return *this;
6472 }
6473
6474 constexpr _Iterator
6475 operator++(int)
6476 {
6477 auto __tmp = *this;
6478 ++*this;
6479 return __tmp;
6480 }
6481
6482 constexpr _Iterator&
6483 operator--() requires bidirectional_range<_Base>
6484 {
6485 ranges::advance(_M_current, _M_missing - _M_n);
6486 _M_missing = 0;
6487 return *this;
6488 }
6489
6490 constexpr _Iterator
6491 operator--(int) requires bidirectional_range<_Base>
6492 {
6493 auto __tmp = *this;
6494 --*this;
6495 return __tmp;
6496 }
6497
6498 constexpr _Iterator&
6499 operator+=(difference_type __x)
6500 requires random_access_range<_Base>
6501 {
6502 if (__x > 0)
6503 {
6504 __glibcxx_assert(ranges::distance(_M_current, _M_end) > _M_n * (__x - 1));
6505 _M_missing = ranges::advance(_M_current, _M_n * __x, _M_end);
6506 }
6507 else if (__x < 0)
6508 {
6509 ranges::advance(_M_current, _M_n * __x + _M_missing);
6510 _M_missing = 0;
6511 }
6512 return *this;
6513 }
6514
6515 constexpr _Iterator&
6516 operator-=(difference_type __x)
6517 requires random_access_range<_Base>
6518 { return *this += -__x; }
6519
6520 constexpr value_type
6521 operator[](difference_type __n) const
6522 requires random_access_range<_Base>
6523 { return *(*this + __n); }
6524
6525 friend constexpr bool
6526 operator==(const _Iterator& __x, const _Iterator& __y)
6527 { return __x._M_current == __y._M_current; }
6528
6529 friend constexpr bool
6530 operator==(const _Iterator& __x, default_sentinel_t)
6531 { return __x._M_current == __x._M_end; }
6532
6533 friend constexpr bool
6534 operator<(const _Iterator& __x, const _Iterator& __y)
6535 requires random_access_range<_Base>
6536 { return __x._M_current > __y._M_current; }
6537
6538 friend constexpr bool
6539 operator>(const _Iterator& __x, const _Iterator& __y)
6540 requires random_access_range<_Base>
6541 { return __y < __x; }
6542
6543 friend constexpr bool
6544 operator<=(const _Iterator& __x, const _Iterator& __y)
6545 requires random_access_range<_Base>
6546 { return !(__y < __x); }
6547
6548 friend constexpr bool
6549 operator>=(const _Iterator& __x, const _Iterator& __y)
6550 requires random_access_range<_Base>
6551 { return !(__x < __y); }
6552
6553 friend constexpr auto
6554 operator<=>(const _Iterator& __x, const _Iterator& __y)
6555 requires random_access_range<_Base>
6556 && three_way_comparable<iterator_t<_Base>>
6557 { return __x._M_current <=> __y._M_current; }
6558
6559 friend constexpr _Iterator
6560 operator+(const _Iterator& __i, difference_type __n)
6561 requires random_access_range<_Base>
6562 {
6563 auto __r = __i;
6564 __r += __n;
6565 return __r;
6566 }
6567
6568 friend constexpr _Iterator
6569 operator+(difference_type __n, const _Iterator& __i)
6570 requires random_access_range<_Base>
6571 {
6572 auto __r = __i;
6573 __r += __n;
6574 return __r;
6575 }
6576
6577 friend constexpr _Iterator
6578 operator-(const _Iterator& __i, difference_type __n)
6579 requires random_access_range<_Base>
6580 {
6581 auto __r = __i;
6582 __r -= __n;
6583 return __r;
6584 }
6585
6586 friend constexpr difference_type
6587 operator-(const _Iterator& __x, const _Iterator& __y)
6588 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
6589 {
6590 return (__x._M_current - __y._M_current
6591 + __x._M_missing - __y._M_missing) / __x._M_n;
6592 }
6593
6594 friend constexpr difference_type
6595 operator-(default_sentinel_t __y, const _Iterator& __x)
6596 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
6597 { return __detail::__div_ceil(__x._M_end - __x._M_current, __x._M_n); }
6598
6599 friend constexpr difference_type
6600 operator-(const _Iterator& __x, default_sentinel_t __y)
6601 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
6602 { return -(__y - __x); }
6603 };
6604
6605 namespace views
6606 {
6607 namespace __detail
6608 {
6609 template<typename _Range, typename _Dp>
6610 concept __can_chunk_view
6611 = requires { chunk_view(std::declval<_Range>(), std::declval<_Dp>()); };
6612 }
6613
6614 struct _Chunk : __adaptor::_RangeAdaptor<_Chunk>
6615 {
6616 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
6617 requires __detail::__can_chunk_view<_Range, _Dp>
6618 constexpr auto
6619 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
6620 { return chunk_view(std::forward<_Range>(__r), __n); }
6621
6622 using __adaptor::_RangeAdaptor<_Chunk>::operator();
6623 static constexpr int _S_arity = 2;
6624 static constexpr bool _S_has_simple_extra_args = true;
6625 };
6626
6627 inline constexpr _Chunk chunk;
6628 }
6629#endif // __cpp_lib_ranges_chunk
6630
6631#ifdef __cpp_lib_ranges_slide // C++ >= 23
6632 namespace __detail
6633 {
6634 template<typename _Vp>
6635 concept __slide_caches_nothing = random_access_range<_Vp> && sized_range<_Vp>;
6636
6637 template<typename _Vp>
6638 concept __slide_caches_last
6639 = !__slide_caches_nothing<_Vp> && bidirectional_range<_Vp> && common_range<_Vp>;
6640
6641 template<typename _Vp>
6642 concept __slide_caches_first
6643 = !__slide_caches_nothing<_Vp> && !__slide_caches_last<_Vp>;
6644 }
6645
6646 template<forward_range _Vp>
6647 requires view<_Vp>
6648 class slide_view : public view_interface<slide_view<_Vp>>
6649 {
6650 _Vp _M_base;
6651 range_difference_t<_Vp> _M_n;
6652 [[no_unique_address]]
6653 __detail::__maybe_present_t<__detail::__slide_caches_first<_Vp>,
6654 __detail::_CachedPosition<_Vp>, 0> _M_cached_begin;
6655 [[no_unique_address]]
6656 __detail::__maybe_present_t<__detail::__slide_caches_last<_Vp>,
6657 __detail::_CachedPosition<_Vp>, 1> _M_cached_end;
6658
6659 template<bool> class _Iterator;
6660 class _Sentinel;
6661
6662 public:
6663 constexpr explicit
6664 slide_view(_Vp __base, range_difference_t<_Vp> __n)
6665 : _M_base(std::move(__base)), _M_n(__n)
6666 { __glibcxx_assert(__n > 0); }
6667
6668 // _GLIBCXX_RESOLVE_LIB_DEFECTS
6669 // 3848. adjacent_view, adjacent_transform_view and slide_view missing base accessor
6670 constexpr _Vp
6671 base() const & requires copy_constructible<_Vp>
6672 { return _M_base; }
6673
6674 constexpr _Vp
6675 base() &&
6676 { return std::move(_M_base); }
6677
6678 constexpr auto
6679 begin() requires (!(__detail::__simple_view<_Vp>
6680 && __detail::__slide_caches_nothing<const _Vp>))
6681 {
6682 if constexpr (__detail::__slide_caches_first<_Vp>)
6683 {
6684 iterator_t<_Vp> __it;
6685 if (_M_cached_begin._M_has_value())
6686 __it = _M_cached_begin._M_get(_M_base);
6687 else
6688 {
6689 __it = ranges::next(ranges::begin(_M_base), _M_n - 1, ranges::end(_M_base));
6690 _M_cached_begin._M_set(_M_base, __it);
6691 }
6692 return _Iterator<false>(ranges::begin(_M_base), std::move(__it), _M_n);
6693 }
6694 else
6695 return _Iterator<false>(ranges::begin(_M_base), _M_n);
6696 }
6697
6698 constexpr auto
6699 begin() const requires __detail::__slide_caches_nothing<const _Vp>
6700 { return _Iterator<true>(ranges::begin(_M_base), _M_n); }
6701
6702 constexpr auto
6703 end() requires (!(__detail::__simple_view<_Vp>
6704 && __detail::__slide_caches_nothing<const _Vp>))
6705 {
6706 if constexpr (__detail::__slide_caches_nothing<_Vp>)
6707 return _Iterator<false>(ranges::begin(_M_base) + range_difference_t<_Vp>(size()),
6708 _M_n);
6709 else if constexpr (__detail::__slide_caches_last<_Vp>)
6710 {
6711 iterator_t<_Vp> __it;
6712 if (_M_cached_end._M_has_value())
6713 __it = _M_cached_end._M_get(_M_base);
6714 else
6715 {
6716 __it = ranges::prev(ranges::end(_M_base), _M_n - 1, ranges::begin(_M_base));
6717 _M_cached_end._M_set(_M_base, __it);
6718 }
6719 return _Iterator<false>(std::move(__it), _M_n);
6720 }
6721 else if constexpr (common_range<_Vp>)
6722 return _Iterator<false>(ranges::end(_M_base), ranges::end(_M_base), _M_n);
6723 else
6724 return _Sentinel(ranges::end(_M_base));
6725 }
6726
6727 constexpr auto
6728 end() const requires __detail::__slide_caches_nothing<const _Vp>
6729 { return begin() + range_difference_t<const _Vp>(size()); }
6730
6731 constexpr auto
6732 size() requires sized_range<_Vp>
6733 {
6734 auto __sz = ranges::distance(_M_base) - _M_n + 1;
6735 if (__sz < 0)
6736 __sz = 0;
6737 return __detail::__to_unsigned_like(__sz);
6738 }
6739
6740 constexpr auto
6741 size() const requires sized_range<const _Vp>
6742 {
6743 auto __sz = ranges::distance(_M_base) - _M_n + 1;
6744 if (__sz < 0)
6745 __sz = 0;
6746 return __detail::__to_unsigned_like(__sz);
6747 }
6748 };
6749
6750 template<typename _Range>
6751 slide_view(_Range&&, range_difference_t<_Range>) -> slide_view<views::all_t<_Range>>;
6752
6753 template<typename _Vp>
6754 inline constexpr bool enable_borrowed_range<slide_view<_Vp>>
6755 = enable_borrowed_range<_Vp>;
6756
6757 template<forward_range _Vp>
6758 requires view<_Vp>
6759 template<bool _Const>
6760 class slide_view<_Vp>::_Iterator
6761 {
6762 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6763 static constexpr bool _S_last_elt_present
6764 = __detail::__slide_caches_first<_Base>;
6765
6766 iterator_t<_Base> _M_current = iterator_t<_Base>();
6767 [[no_unique_address]]
6768 __detail::__maybe_present_t<_S_last_elt_present, iterator_t<_Base>>
6769 _M_last_elt = decltype(_M_last_elt)();
6770 range_difference_t<_Base> _M_n = 0;
6771
6772 constexpr
6773 _Iterator(iterator_t<_Base> __current, range_difference_t<_Base> __n)
6774 requires (!_S_last_elt_present)
6775 : _M_current(__current), _M_n(__n)
6776 { }
6777
6778 constexpr
6779 _Iterator(iterator_t<_Base> __current, iterator_t<_Base> __last_elt,
6780 range_difference_t<_Base> __n)
6781 requires _S_last_elt_present
6782 : _M_current(__current), _M_last_elt(__last_elt), _M_n(__n)
6783 { }
6784
6785 static auto
6786 _S_iter_concept()
6787 {
6788 if constexpr (random_access_range<_Base>)
6789 return random_access_iterator_tag{};
6790 else if constexpr (bidirectional_range<_Base>)
6791 return bidirectional_iterator_tag{};
6792 else
6793 return forward_iterator_tag{};
6794 }
6795
6796 friend slide_view;
6797 friend slide_view::_Sentinel;
6798
6799 public:
6800 using iterator_category = input_iterator_tag;
6801 using iterator_concept = decltype(_S_iter_concept());
6802 using value_type = decltype(views::counted(_M_current, _M_n));
6803 using difference_type = range_difference_t<_Base>;
6804
6805 _Iterator() = default;
6806
6807 constexpr
6808 _Iterator(_Iterator<!_Const> __i)
6809 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
6810 : _M_current(std::move(__i._M_current)), _M_n(__i._M_n)
6811 { }
6812
6813 constexpr auto
6814 operator*() const
6815 { return views::counted(_M_current, _M_n); }
6816
6817 constexpr _Iterator&
6818 operator++()
6819 {
6820 ++_M_current;
6821 if constexpr (_S_last_elt_present)
6822 ++_M_last_elt;
6823 return *this;
6824 }
6825
6826 constexpr _Iterator
6827 operator++(int)
6828 {
6829 auto __tmp = *this;
6830 ++*this;
6831 return __tmp;
6832 }
6833
6834 constexpr _Iterator&
6835 operator--() requires bidirectional_range<_Base>
6836 {
6837 --_M_current;
6838 if constexpr (_S_last_elt_present)
6839 --_M_last_elt;
6840 return *this;
6841 }
6842
6843 constexpr _Iterator
6844 operator--(int) requires bidirectional_range<_Base>
6845 {
6846 auto __tmp = *this;
6847 --*this;
6848 return __tmp;
6849 }
6850
6851 constexpr _Iterator&
6852 operator+=(difference_type __x)
6853 requires random_access_range<_Base>
6854 {
6855 _M_current += __x;
6856 if constexpr (_S_last_elt_present)
6857 _M_last_elt += __x;
6858 return *this;
6859 }
6860
6861 constexpr _Iterator&
6862 operator-=(difference_type __x)
6863 requires random_access_range<_Base>
6864 {
6865 _M_current -= __x;
6866 if constexpr (_S_last_elt_present)
6867 _M_last_elt -= __x;
6868 return *this;
6869 }
6870
6871 constexpr auto
6872 operator[](difference_type __n) const
6873 requires random_access_range<_Base>
6874 { return views::counted(_M_current + __n, _M_n); }
6875
6876 friend constexpr bool
6877 operator==(const _Iterator& __x, const _Iterator& __y)
6878 {
6879 if constexpr (_S_last_elt_present)
6880 return __x._M_last_elt == __y._M_last_elt;
6881 else
6882 return __x._M_current == __y._M_current;
6883 }
6884
6885 friend constexpr bool
6886 operator<(const _Iterator& __x, const _Iterator& __y)
6887 requires random_access_range<_Base>
6888 { return __x._M_current < __y._M_current; }
6889
6890 friend constexpr bool
6891 operator>(const _Iterator& __x, const _Iterator& __y)
6892 requires random_access_range<_Base>
6893 { return __y < __x; }
6894
6895 friend constexpr bool
6896 operator<=(const _Iterator& __x, const _Iterator& __y)
6897 requires random_access_range<_Base>
6898 { return !(__y < __x); }
6899
6900 friend constexpr bool
6901 operator>=(const _Iterator& __x, const _Iterator& __y)
6902 requires random_access_range<_Base>
6903 { return !(__x < __y); }
6904
6905 friend constexpr auto
6906 operator<=>(const _Iterator& __x, const _Iterator& __y)
6907 requires random_access_range<_Base>
6908 && three_way_comparable<iterator_t<_Base>>
6909 { return __x._M_current <=> __y._M_current; }
6910
6911 friend constexpr _Iterator
6912 operator+(const _Iterator& __i, difference_type __n)
6913 requires random_access_range<_Base>
6914 {
6915 auto __r = __i;
6916 __r += __n;
6917 return __r;
6918 }
6919
6920 friend constexpr _Iterator
6921 operator+(difference_type __n, const _Iterator& __i)
6922 requires random_access_range<_Base>
6923 {
6924 auto __r = __i;
6925 __r += __n;
6926 return __r;
6927 }
6928
6929 friend constexpr _Iterator
6930 operator-(const _Iterator& __i, difference_type __n)
6931 requires random_access_range<_Base>
6932 {
6933 auto __r = __i;
6934 __r -= __n;
6935 return __r;
6936 }
6937
6938 friend constexpr difference_type
6939 operator-(const _Iterator& __x, const _Iterator& __y)
6940 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
6941 {
6942 if constexpr (_S_last_elt_present)
6943 return __x._M_last_elt - __y._M_last_elt;
6944 else
6945 return __x._M_current - __y._M_current;
6946 }
6947 };
6948
6949 template<forward_range _Vp>
6950 requires view<_Vp>
6951 class slide_view<_Vp>::_Sentinel
6952 {
6953 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
6954
6955 constexpr explicit
6956 _Sentinel(sentinel_t<_Vp> __end)
6957 : _M_end(__end)
6958 { }
6959
6960 friend slide_view;
6961
6962 public:
6963 _Sentinel() = default;
6964
6965 friend constexpr bool
6966 operator==(const _Iterator<false>& __x, const _Sentinel& __y)
6967 { return __x._M_last_elt == __y._M_end; }
6968
6969 friend constexpr range_difference_t<_Vp>
6970 operator-(const _Iterator<false>& __x, const _Sentinel& __y)
6971 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6972 { return __x._M_last_elt - __y._M_end; }
6973
6974 friend constexpr range_difference_t<_Vp>
6975 operator-(const _Sentinel& __y, const _Iterator<false>& __x)
6976 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6977 { return __y._M_end -__x._M_last_elt; }
6978 };
6979
6980 namespace views
6981 {
6982 namespace __detail
6983 {
6984 template<typename _Range, typename _Dp>
6985 concept __can_slide_view
6986 = requires { slide_view(std::declval<_Range>(), std::declval<_Dp>()); };
6987 }
6988
6989 struct _Slide : __adaptor::_RangeAdaptor<_Slide>
6990 {
6991 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
6992 requires __detail::__can_slide_view<_Range, _Dp>
6993 constexpr auto
6994 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
6995 { return slide_view(std::forward<_Range>(__r), __n); }
6996
6997 using __adaptor::_RangeAdaptor<_Slide>::operator();
6998 static constexpr int _S_arity = 2;
6999 static constexpr bool _S_has_simple_extra_args = true;
7000 };
7001
7002 inline constexpr _Slide slide;
7003 }
7004#endif // __cpp_lib_ranges_slide
7005
7006#ifdef __cpp_lib_ranges_chunk_by // C++ >= 23
7007 template<forward_range _Vp,
7008 indirect_binary_predicate<iterator_t<_Vp>, iterator_t<_Vp>> _Pred>
7009 requires view<_Vp> && is_object_v<_Pred>
7010 class chunk_by_view : public view_interface<chunk_by_view<_Vp, _Pred>>
7011 {
7012 _Vp _M_base = _Vp();
7013 __detail::__box<_Pred> _M_pred;
7014 __detail::_CachedPosition<_Vp> _M_cached_begin;
7015
7016 constexpr iterator_t<_Vp>
7017 _M_find_next(iterator_t<_Vp> __current)
7018 {
7019 __glibcxx_assert(_M_pred.has_value());
7020 auto __pred = [this]<typename _Tp, typename _Up>(_Tp&& __x, _Up&& __y) {
7021 return !bool((*_M_pred)(std::forward<_Tp>(__x), std::forward<_Up>(__y)));
7022 };
7023 auto __it = ranges::adjacent_find(__current, ranges::end(_M_base), __pred);
7024 return ranges::next(__it, 1, ranges::end(_M_base));
7025 }
7026
7027 constexpr iterator_t<_Vp>
7028 _M_find_prev(iterator_t<_Vp> __current) requires bidirectional_range<_Vp>
7029 {
7030 __glibcxx_assert(_M_pred.has_value());
7031 auto __pred = [this]<typename _Tp, typename _Up>(_Tp&& __x, _Up&& __y) {
7032 return !bool((*_M_pred)(std::forward<_Up>(__y), std::forward<_Tp>(__x)));
7033 };
7034 auto __rbegin = std::make_reverse_iterator(__current);
7035 auto __rend = std::make_reverse_iterator(ranges::begin(_M_base));
7036 __glibcxx_assert(__rbegin != __rend);
7037 auto __it = ranges::adjacent_find(__rbegin, __rend, __pred).base();
7038 return ranges::prev(__it, 1, ranges::begin(_M_base));
7039 }
7040
7041 class _Iterator;
7042
7043 public:
7044 chunk_by_view() requires (default_initializable<_Vp>
7045 && default_initializable<_Pred>)
7046 = default;
7047
7048 constexpr explicit
7049 chunk_by_view(_Vp __base, _Pred __pred)
7050 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
7051 { }
7052
7053 constexpr _Vp
7054 base() const & requires copy_constructible<_Vp>
7055 { return _M_base; }
7056
7057 constexpr _Vp
7058 base() &&
7059 { return std::move(_M_base); }
7060
7061 constexpr const _Pred&
7062 pred() const
7063 { return *_M_pred; }
7064
7065 constexpr _Iterator
7066 begin()
7067 {
7068 __glibcxx_assert(_M_pred.has_value());
7069 iterator_t<_Vp> __it;
7070 if (_M_cached_begin._M_has_value())
7071 __it = _M_cached_begin._M_get(_M_base);
7072 else
7073 {
7074 __it = _M_find_next(ranges::begin(_M_base));
7075 _M_cached_begin._M_set(_M_base, __it);
7076 }
7077 return _Iterator(*this, ranges::begin(_M_base), __it);
7078 }
7079
7080 constexpr auto
7081 end()
7082 {
7083 if constexpr (common_range<_Vp>)
7084 return _Iterator(*this, ranges::end(_M_base), ranges::end(_M_base));
7085 else
7086 return default_sentinel;
7087 }
7088 };
7089
7090 template<typename _Range, typename _Pred>
7091 chunk_by_view(_Range&&, _Pred) -> chunk_by_view<views::all_t<_Range>, _Pred>;
7092
7093 template<forward_range _Vp,
7094 indirect_binary_predicate<iterator_t<_Vp>, iterator_t<_Vp>> _Pred>
7095 requires view<_Vp> && is_object_v<_Pred>
7096 class chunk_by_view<_Vp, _Pred>::_Iterator
7097 {
7098 chunk_by_view* _M_parent = nullptr;
7099 iterator_t<_Vp> _M_current = iterator_t<_Vp>();
7100 iterator_t<_Vp> _M_next = iterator_t<_Vp>();
7101
7102 constexpr
7103 _Iterator(chunk_by_view& __parent, iterator_t<_Vp> __current, iterator_t<_Vp> __next)
7104 : _M_parent(std::__addressof(__parent)), _M_current(__current), _M_next(__next)
7105 { }
7106
7107 static auto
7108 _S_iter_concept()
7109 {
7110 if constexpr (bidirectional_range<_Vp>)
7111 return bidirectional_iterator_tag{};
7112 else
7113 return forward_iterator_tag{};
7114 }
7115
7116 friend chunk_by_view;
7117
7118 public:
7119 using value_type = subrange<iterator_t<_Vp>>;
7120 using difference_type = range_difference_t<_Vp>;
7121 using iterator_category = input_iterator_tag;
7122 using iterator_concept = decltype(_S_iter_concept());
7123
7124 _Iterator() = default;
7125
7126 constexpr value_type
7127 operator*() const
7128 {
7129 __glibcxx_assert(_M_current != _M_next);
7130 return ranges::subrange(_M_current, _M_next);
7131 }
7132
7133 constexpr _Iterator&
7134 operator++()
7135 {
7136 __glibcxx_assert(_M_current != _M_next);
7137 _M_current = _M_next;
7138 _M_next = _M_parent->_M_find_next(_M_current);
7139 return *this;
7140 }
7141
7142 constexpr _Iterator
7143 operator++(int)
7144 {
7145 auto __tmp = *this;
7146 ++*this;
7147 return __tmp;
7148 }
7149
7150 constexpr _Iterator&
7151 operator--() requires bidirectional_range<_Vp>
7152 {
7153 _M_next = _M_current;
7154 _M_current = _M_parent->_M_find_prev(_M_next);
7155 return *this;
7156 }
7157
7158 constexpr _Iterator
7159 operator--(int) requires bidirectional_range<_Vp>
7160 {
7161 auto __tmp = *this;
7162 --*this;
7163 return __tmp;
7164 }
7165
7166 friend constexpr bool
7167 operator==(const _Iterator& __x, const _Iterator& __y)
7168 { return __x._M_current == __y._M_current; }
7169
7170 friend constexpr bool
7171 operator==(const _Iterator& __x, default_sentinel_t)
7172 { return __x._M_current == __x._M_next; }
7173 };
7174
7175 namespace views
7176 {
7177 namespace __detail
7178 {
7179 template<typename _Range, typename _Pred>
7180 concept __can_chunk_by_view
7181 = requires { chunk_by_view(std::declval<_Range>(), std::declval<_Pred>()); };
7182 }
7183
7184 struct _ChunkBy : __adaptor::_RangeAdaptor<_ChunkBy>
7185 {
7186 template<viewable_range _Range, typename _Pred>
7187 requires __detail::__can_chunk_by_view<_Range, _Pred>
7188 constexpr auto
7189 operator() [[nodiscard]] (_Range&& __r, _Pred&& __pred) const
7190 { return chunk_by_view(std::forward<_Range>(__r), std::forward<_Pred>(__pred)); }
7191
7192 using __adaptor::_RangeAdaptor<_ChunkBy>::operator();
7193 static constexpr int _S_arity = 2;
7194 static constexpr bool _S_has_simple_extra_args = true;
7195 };
7196
7197 inline constexpr _ChunkBy chunk_by;
7198 }
7199#endif // __cpp_lib_ranges_chunk_by
7200
7201#ifdef __cpp_lib_ranges_join_with // C++ >= 23
7202 namespace __detail
7203 {
7204 template<typename _Range, typename _Pattern>
7205 concept __compatible_joinable_ranges
7206 = common_with<range_value_t<_Range>, range_value_t<_Pattern>>
7207 && common_reference_with<range_reference_t<_Range>,
7208 range_reference_t<_Pattern>>
7209 && common_reference_with<range_rvalue_reference_t<_Range>,
7210 range_rvalue_reference_t<_Pattern>>;
7211
7212 template<typename _Range>
7213 concept __bidirectional_common = bidirectional_range<_Range> && common_range<_Range>;
7214 }
7215
7216 template<input_range _Vp, forward_range _Pattern>
7217 requires view<_Vp> && view<_Pattern>
7218 && input_range<range_reference_t<_Vp>>
7219 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7220 class join_with_view : public view_interface<join_with_view<_Vp, _Pattern>>
7221 {
7222 using _InnerRange = range_reference_t<_Vp>;
7223
7224 _Vp _M_base = _Vp();
7225 [[no_unique_address]]
7226 __detail::__maybe_present_t<!forward_range<_Vp>,
7227 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_outer_it;
7228 __detail::__non_propagating_cache<remove_cv_t<_InnerRange>> _M_inner;
7229 _Pattern _M_pattern = _Pattern();
7230
7231 template<bool _Const> using _Base = __detail::__maybe_const_t<_Const, _Vp>;
7232 template<bool _Const> using _InnerBase = range_reference_t<_Base<_Const>>;
7233 template<bool _Const> using _PatternBase = __detail::__maybe_const_t<_Const, _Pattern>;
7234
7235 template<bool _Const> using _OuterIter = iterator_t<_Base<_Const>>;
7236 template<bool _Const> using _InnerIter = iterator_t<_InnerBase<_Const>>;
7237 template<bool _Const> using _PatternIter = iterator_t<_PatternBase<_Const>>;
7238
7239 template<bool _Const>
7240 static constexpr bool _S_ref_is_glvalue = is_reference_v<_InnerBase<_Const>>;
7241
7242 template<bool _Const>
7243 struct __iter_cat
7244 { };
7245
7246 template<bool _Const>
7247 requires _S_ref_is_glvalue<_Const>
7248 && forward_range<_Base<_Const>>
7249 && forward_range<_InnerBase<_Const>>
7250 struct __iter_cat<_Const>
7251 {
7252 private:
7253 static auto
7254 _S_iter_cat()
7255 {
7256 using _OuterIter = join_with_view::_OuterIter<_Const>;
7257 using _InnerIter = join_with_view::_InnerIter<_Const>;
7258 using _PatternIter = join_with_view::_PatternIter<_Const>;
7259 using _OuterCat = typename iterator_traits<_OuterIter>::iterator_category;
7260 using _InnerCat = typename iterator_traits<_InnerIter>::iterator_category;
7261 using _PatternCat = typename iterator_traits<_PatternIter>::iterator_category;
7262 // _GLIBCXX_RESOLVE_LIB_DEFECTS
7263 // 3798. Rvalue reference and iterator_category
7264 if constexpr (!is_reference_v<common_reference_t<iter_reference_t<_InnerIter>,
7265 iter_reference_t<_PatternIter>>>)
7266 return input_iterator_tag{};
7267 else if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag>
7268 && derived_from<_InnerCat, bidirectional_iterator_tag>
7269 && derived_from<_PatternCat, bidirectional_iterator_tag>
7270 && common_range<_InnerBase<_Const>>
7271 && common_range<_PatternBase<_Const>>)
7272 return bidirectional_iterator_tag{};
7273 else if constexpr (derived_from<_OuterCat, forward_iterator_tag>
7274 && derived_from<_InnerCat, forward_iterator_tag>
7275 && derived_from<_PatternCat, forward_iterator_tag>)
7276 return forward_iterator_tag{};
7277 else
7278 return input_iterator_tag{};
7279 }
7280 public:
7281 using iterator_category = decltype(_S_iter_cat());
7282 };
7283
7284 template<bool> struct _Iterator;
7285 template<bool> struct _Sentinel;
7286
7287 public:
7288 join_with_view() requires (default_initializable<_Vp>
7289 && default_initializable<_Pattern>)
7290 = default;
7291
7292 constexpr
7293 join_with_view(_Vp __base, _Pattern __pattern)
7294 : _M_base(std::move(__base)), _M_pattern(std::move(__pattern))
7295 { }
7296
7297 template<input_range _Range>
7298 requires constructible_from<_Vp, views::all_t<_Range>>
7299 && constructible_from<_Pattern, single_view<range_value_t<_InnerRange>>>
7300 constexpr
7301 join_with_view(_Range&& __r, range_value_t<_InnerRange> __e)
7302 : _M_base(views::all(std::forward<_Range>(__r))),
7303 _M_pattern(views::single(std::move(__e)))
7304 { }
7305
7306 constexpr _Vp
7307 base() const& requires copy_constructible<_Vp>
7308 { return _M_base; }
7309
7310 constexpr _Vp
7311 base() &&
7312 { return std::move(_M_base); }
7313
7314 constexpr auto
7315 begin()
7316 {
7317 if constexpr (forward_range<_Vp>)
7318 {
7319 constexpr bool __use_const = is_reference_v<_InnerRange>
7320 && __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
7321 return _Iterator<__use_const>{*this, ranges::begin(_M_base)};
7322 }
7323 else
7324 {
7325 _M_outer_it = ranges::begin(_M_base);
7326 return _Iterator<false>{*this};
7327 }
7328 }
7329
7330 constexpr auto
7331 begin() const
7332 requires forward_range<const _Vp>
7333 && forward_range<const _Pattern>
7334 && is_reference_v<range_reference_t<const _Vp>>
7335 && input_range<range_reference_t<const _Vp>>
7336 { return _Iterator<true>{*this, ranges::begin(_M_base)}; }
7337
7338 constexpr auto
7339 end()
7340 {
7341 constexpr bool __use_const
7342 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
7343 if constexpr (is_reference_v<_InnerRange>
7344 && forward_range<_Vp> && common_range<_Vp>
7345 && forward_range<_InnerRange> && common_range<_InnerRange>)
7346 return _Iterator<__use_const>{*this, ranges::end(_M_base)};
7347 else
7348 return _Sentinel<__use_const>{*this};
7349 }
7350
7351 constexpr auto
7352 end() const
7353 requires forward_range<const _Vp>
7354 && forward_range<const _Pattern>
7355 && is_reference_v<range_reference_t<const _Vp>>
7356 && input_range<range_reference_t<const _Vp>>
7357 {
7358 using _InnerConstRange = range_reference_t<const _Vp>;
7359 if constexpr (forward_range<_InnerConstRange>
7360 && common_range<const _Vp>
7361 && common_range<_InnerConstRange>)
7362 return _Iterator<true>{*this, ranges::end(_M_base)};
7363 else
7364 return _Sentinel<true>{*this};
7365 }
7366 };
7367
7368 template<typename _Range, typename _Pattern>
7369 join_with_view(_Range&&, _Pattern&&)
7370 -> join_with_view<views::all_t<_Range>, views::all_t<_Pattern>>;
7371
7372 template<input_range _Range>
7373 join_with_view(_Range&&, range_value_t<range_reference_t<_Range>>)
7374 -> join_with_view<views::all_t<_Range>,
7375 single_view<range_value_t<range_reference_t<_Range>>>>;
7376
7377 template<input_range _Vp, forward_range _Pattern>
7378 requires view<_Vp> && view<_Pattern>
7379 && input_range<range_reference_t<_Vp>>
7380 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7381 template<bool _Const>
7382 class join_with_view<_Vp, _Pattern>::_Iterator : public __iter_cat<_Const>
7383 {
7384 using _Parent = __detail::__maybe_const_t<_Const, join_with_view>;
7385 using _Base = join_with_view::_Base<_Const>;
7386 using _InnerBase = join_with_view::_InnerBase<_Const>;
7387 using _PatternBase = join_with_view::_PatternBase<_Const>;
7388
7389 using _OuterIter = join_with_view::_OuterIter<_Const>;
7390 using _InnerIter = join_with_view::_InnerIter<_Const>;
7391 using _PatternIter = join_with_view::_PatternIter<_Const>;
7392
7393 static constexpr bool _S_ref_is_glvalue = join_with_view::_S_ref_is_glvalue<_Const>;
7394
7395 _Parent* _M_parent = nullptr;
7396 [[no_unique_address]]
7397 __detail::__maybe_present_t<forward_range<_Base>, _OuterIter> _M_outer_it;
7398 variant<_PatternIter, _InnerIter> _M_inner_it;
7399
7400 constexpr _OuterIter&
7401 _M_get_outer()
7402 {
7403 if constexpr (forward_range<_Base>)
7404 return _M_outer_it;
7405 else
7406 return *_M_parent->_M_outer_it;
7407 }
7408
7409 constexpr const _OuterIter&
7410 _M_get_outer() const
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
7419 _Iterator(_Parent& __parent, _OuterIter __outer)
7420 requires forward_range<_Base>
7421 : _M_parent(std::__addressof(__parent)), _M_outer_it(std::move(__outer))
7422 {
7423 if (_M_get_outer() != ranges::end(_M_parent->_M_base))
7424 {
7425 auto&& __inner = _M_update_inner();
7426 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7427 _M_satisfy();
7428 }
7429 }
7430
7431 constexpr
7432 _Iterator(_Parent& __parent)
7433 requires (!forward_range<_Base>)
7434 : _M_parent(std::__addressof(__parent))
7435 {
7436 if (_M_get_outer() != ranges::end(_M_parent->_M_base))
7437 {
7438 auto&& __inner = _M_update_inner();
7439 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7440 _M_satisfy();
7441 }
7442 }
7443
7444 constexpr auto&
7445 _M_update_inner()
7446 {
7447 _OuterIter& __outer = _M_get_outer();
7448 if constexpr (_S_ref_is_glvalue)
7449 return __detail::__as_lvalue(*__outer);
7450 else
7451 return _M_parent->_M_inner._M_emplace_deref(__outer);
7452 }
7453
7454 constexpr auto&
7455 _M_get_inner()
7456 {
7457 if constexpr (_S_ref_is_glvalue)
7458 return __detail::__as_lvalue(*_M_get_outer());
7459 else
7460 return *_M_parent->_M_inner;
7461 }
7462
7463 constexpr void
7464 _M_satisfy()
7465 {
7466 while (true)
7467 {
7468 if (_M_inner_it.index() == 0)
7469 {
7470 if (std::get<0>(_M_inner_it) != ranges::end(_M_parent->_M_pattern))
7471 break;
7472
7473 auto&& __inner = _M_update_inner();
7474 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7475 }
7476 else
7477 {
7478 auto&& __inner = _M_get_inner();
7479 if (std::get<1>(_M_inner_it) != ranges::end(__inner))
7480 break;
7481
7482 if (++_M_get_outer() == ranges::end(_M_parent->_M_base))
7483 {
7484 if constexpr (_S_ref_is_glvalue)
7485 _M_inner_it.template emplace<0>();
7486 break;
7487 }
7488
7489 _M_inner_it.template emplace<0>(ranges::begin(_M_parent->_M_pattern));
7490 }
7491 }
7492 }
7493
7494 static auto
7495 _S_iter_concept()
7496 {
7497 if constexpr (_S_ref_is_glvalue
7498 && bidirectional_range<_Base>
7499 && __detail::__bidirectional_common<_InnerBase>
7500 && __detail::__bidirectional_common<_PatternBase>)
7501 return bidirectional_iterator_tag{};
7502 else if constexpr (_S_ref_is_glvalue
7503 && forward_range<_Base>
7504 && forward_range<_InnerBase>)
7505 return forward_iterator_tag{};
7506 else
7507 return input_iterator_tag{};
7508 }
7509
7510 friend join_with_view;
7511
7512 public:
7513 using iterator_concept = decltype(_S_iter_concept());
7514 // iterator_category defined in join_with_view::__iter_cat
7515 using value_type = common_type_t<iter_value_t<_InnerIter>,
7516 iter_value_t<_PatternIter>>;
7517 using difference_type = common_type_t<iter_difference_t<_OuterIter>,
7518 iter_difference_t<_InnerIter>,
7519 iter_difference_t<_PatternIter>>;
7520
7521 _Iterator() = default;
7522
7523 constexpr
7524 _Iterator(_Iterator<!_Const> __i)
7525 requires _Const
7526 && convertible_to<iterator_t<_Vp>, _OuterIter>
7527 && convertible_to<iterator_t<_InnerRange>, _InnerIter>
7528 && convertible_to<iterator_t<_Pattern>, _PatternIter>
7529 : _M_parent(__i._M_parent),
7530 _M_outer_it(std::move(__i._M_outer_it))
7531 {
7532 if (__i._M_inner_it.index() == 0)
7533 _M_inner_it.template emplace<0>(std::get<0>(std::move(__i._M_inner_it)));
7534 else
7535 _M_inner_it.template emplace<1>(std::get<1>(std::move(__i._M_inner_it)));
7536 }
7537
7538 constexpr common_reference_t<iter_reference_t<_InnerIter>,
7539 iter_reference_t<_PatternIter>>
7540 operator*() const
7541 {
7542 if (_M_inner_it.index() == 0)
7543 return *std::get<0>(_M_inner_it);
7544 else
7545 return *std::get<1>(_M_inner_it);
7546 }
7547
7548 constexpr _Iterator&
7549 operator++()
7550 {
7551 if (_M_inner_it.index() == 0)
7552 ++std::get<0>(_M_inner_it);
7553 else
7554 ++std::get<1>(_M_inner_it);
7555 _M_satisfy();
7556 return *this;
7557 }
7558
7559 constexpr void
7560 operator++(int)
7561 { ++*this; }
7562
7563 constexpr _Iterator
7564 operator++(int)
7565 requires _S_ref_is_glvalue
7566 && forward_iterator<_OuterIter> && forward_iterator<_InnerIter>
7567 {
7568 _Iterator __tmp = *this;
7569 ++*this;
7570 return __tmp;
7571 }
7572
7573 constexpr _Iterator&
7574 operator--()
7575 requires _S_ref_is_glvalue
7576 && bidirectional_range<_Base>
7577 && __detail::__bidirectional_common<_InnerBase>
7578 && __detail::__bidirectional_common<_PatternBase>
7579 {
7580 if (_M_outer_it == ranges::end(_M_parent->_M_base))
7581 {
7582 auto&& __inner = *--_M_outer_it;
7583 _M_inner_it.template emplace<1>(ranges::end(__inner));
7584 }
7585
7586 while (true)
7587 {
7588 if (_M_inner_it.index() == 0)
7589 {
7590 auto& __it = std::get<0>(_M_inner_it);
7591 if (__it == ranges::begin(_M_parent->_M_pattern))
7592 {
7593 auto&& __inner = *--_M_outer_it;
7594 _M_inner_it.template emplace<1>(ranges::end(__inner));
7595 }
7596 else
7597 break;
7598 }
7599 else
7600 {
7601 auto& __it = std::get<1>(_M_inner_it);
7602 auto&& __inner = *_M_outer_it;
7603 if (__it == ranges::begin(__inner))
7604 _M_inner_it.template emplace<0>(ranges::end(_M_parent->_M_pattern));
7605 else
7606 break;
7607 }
7608 }
7609
7610 if (_M_inner_it.index() == 0)
7611 --std::get<0>(_M_inner_it);
7612 else
7613 --std::get<1>(_M_inner_it);
7614 return *this;
7615 }
7616
7617 constexpr _Iterator
7618 operator--(int)
7619 requires _S_ref_is_glvalue && bidirectional_range<_Base>
7620 && __detail::__bidirectional_common<_InnerBase>
7621 && __detail::__bidirectional_common<_PatternBase>
7622 {
7623 _Iterator __tmp = *this;
7624 --*this;
7625 return __tmp;
7626 }
7627
7628 friend constexpr bool
7629 operator==(const _Iterator& __x, const _Iterator& __y)
7630 requires _S_ref_is_glvalue
7631 && forward_range<_Base> && equality_comparable<_InnerIter>
7632 { return __x._M_outer_it == __y._M_outer_it && __x._M_inner_it ==__y._M_inner_it; }
7633
7634 friend constexpr common_reference_t<iter_rvalue_reference_t<_InnerIter>,
7635 iter_rvalue_reference_t<_PatternIter>>
7636 iter_move(const _Iterator& __x)
7637 {
7638 if (__x._M_inner_it.index() == 0)
7639 return ranges::iter_move(std::get<0>(__x._M_inner_it));
7640 else
7641 return ranges::iter_move(std::get<1>(__x._M_inner_it));
7642 }
7643
7644 friend constexpr void
7645 iter_swap(const _Iterator& __x, const _Iterator& __y)
7646 requires indirectly_swappable<_InnerIter, _PatternIter>
7647 {
7648 if (__x._M_inner_it.index() == 0)
7649 {
7650 if (__y._M_inner_it.index() == 0)
7651 ranges::iter_swap(std::get<0>(__x._M_inner_it), std::get<0>(__y._M_inner_it));
7652 else
7653 ranges::iter_swap(std::get<0>(__x._M_inner_it), std::get<1>(__y._M_inner_it));
7654 }
7655 else
7656 {
7657 if (__y._M_inner_it.index() == 0)
7658 ranges::iter_swap(std::get<1>(__x._M_inner_it), std::get<0>(__y._M_inner_it));
7659 else
7660 ranges::iter_swap(std::get<1>(__x._M_inner_it), std::get<1>(__y._M_inner_it));
7661 }
7662 }
7663 };
7664
7665 template<input_range _Vp, forward_range _Pattern>
7666 requires view<_Vp> && view<_Pattern>
7667 && input_range<range_reference_t<_Vp>>
7668 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7669 template<bool _Const>
7670 class join_with_view<_Vp, _Pattern>::_Sentinel
7671 {
7672 using _Parent = __detail::__maybe_const_t<_Const, join_with_view>;
7673 using _Base = join_with_view::_Base<_Const>;
7674
7675 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
7676
7677 constexpr explicit
7678 _Sentinel(_Parent& __parent)
7679 : _M_end(ranges::end(__parent._M_base))
7680 { }
7681
7682 friend join_with_view;
7683
7684 public:
7685 _Sentinel() = default;
7686
7687 constexpr
7688 _Sentinel(_Sentinel<!_Const> __s)
7689 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
7690 : _M_end(std::move(__s._M_end))
7691 { }
7692
7693 template<bool _OtherConst>
7694 requires sentinel_for<sentinel_t<_Base>,
7695 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
7696 friend constexpr bool
7697 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
7698 { return __x._M_get_outer() == __y._M_end; }
7699 };
7700
7701 namespace views
7702 {
7703 namespace __detail
7704 {
7705 template<typename _Range, typename _Pattern>
7706 concept __can_join_with_view
7707 = requires { join_with_view(std::declval<_Range>(), std::declval<_Pattern>()); };
7708 } // namespace __detail
7709
7710 struct _JoinWith : __adaptor::_RangeAdaptor<_JoinWith>
7711 {
7712 template<viewable_range _Range, typename _Pattern>
7713 requires __detail::__can_join_with_view<_Range, _Pattern>
7714 constexpr auto
7715 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f) const
7716 {
7717 return join_with_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
7718 }
7719
7720 using _RangeAdaptor<_JoinWith>::operator();
7721 static constexpr int _S_arity = 2;
7722 template<typename _Pattern>
7723 static constexpr bool _S_has_simple_extra_args
7724 = _LazySplit::_S_has_simple_extra_args<_Pattern>;
7725 };
7726
7727 inline constexpr _JoinWith join_with;
7728 } // namespace views
7729#endif // __cpp_lib_ranges_join_with
7730
7731#ifdef __cpp_lib_ranges_repeat // C++ >= 23
7732 template<move_constructible _Tp, semiregular _Bound = unreachable_sentinel_t>
7733 requires is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>>
7734 && (__detail::__is_integer_like<_Bound> || same_as<_Bound, unreachable_sentinel_t>)
7735 class repeat_view : public view_interface<repeat_view<_Tp, _Bound>>
7736 {
7737 __detail::__box<_Tp> _M_value;
7738 [[no_unique_address]] _Bound _M_bound = _Bound();
7739
7740 struct _Iterator;
7741
7742 template<typename _Range>
7743 friend constexpr auto
7744 views::__detail::__take_of_repeat_view(_Range&&, range_difference_t<_Range>);
7745
7746 template<typename _Range>
7747 friend constexpr auto
7748 views::__detail::__drop_of_repeat_view(_Range&&, range_difference_t<_Range>);
7749
7750 public:
7751 repeat_view() requires default_initializable<_Tp> = default;
7752
7753 constexpr explicit
7754 repeat_view(const _Tp& __value, _Bound __bound = _Bound())
7755 requires copy_constructible<_Tp>
7756 : _M_value(__value), _M_bound(__bound)
7757 {
7758 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7759 __glibcxx_assert(__bound >= 0);
7760 }
7761
7762 constexpr explicit
7763 repeat_view(_Tp&& __value, _Bound __bound = _Bound())
7764 : _M_value(std::move(__value)), _M_bound(__bound)
7765 { }
7766
7767 template<typename... _Args, typename... _BoundArgs>
7768 requires constructible_from<_Tp, _Args...>
7769 && constructible_from<_Bound, _BoundArgs...>
7770 constexpr explicit
7771 repeat_view(piecewise_construct_t,
7772 tuple<_Args...> __args,
7773 tuple<_BoundArgs...> __bound_args = tuple<>{})
7774 : _M_value(std::make_from_tuple<_Tp>(std::move(__args))),
7775 _M_bound(std::make_from_tuple<_Bound>(std::move(__bound_args)))
7776 { }
7777
7778 constexpr _Iterator
7779 begin() const
7780 { return _Iterator(std::__addressof(*_M_value)); }
7781
7782 constexpr _Iterator
7783 end() const requires (!same_as<_Bound, unreachable_sentinel_t>)
7784 { return _Iterator(std::__addressof(*_M_value), _M_bound); }
7785
7786 constexpr unreachable_sentinel_t
7787 end() const noexcept
7788 { return unreachable_sentinel; }
7789
7790 constexpr auto
7791 size() const requires (!same_as<_Bound, unreachable_sentinel_t>)
7792 { return __detail::__to_unsigned_like(_M_bound); }
7793 };
7794
7795 // _GLIBCXX_RESOLVE_LIB_DEFECTS
7796 // 4053. Unary call to std::views::repeat does not decay the argument
7797 template<typename _Tp, typename _Bound = unreachable_sentinel_t>
7798 repeat_view(_Tp, _Bound = _Bound()) -> repeat_view<_Tp, _Bound>;
7799
7800 template<move_constructible _Tp, semiregular _Bound>
7801 requires is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>>
7802 && (__detail::__is_integer_like<_Bound> || same_as<_Bound, unreachable_sentinel_t>)
7803 class repeat_view<_Tp, _Bound>::_Iterator
7804 {
7805 using __index_type
7806 = __conditional_t<same_as<_Bound, unreachable_sentinel_t>, ptrdiff_t, _Bound>;
7807
7808 const _Tp* _M_value = nullptr;
7809 __index_type _M_current = __index_type();
7810
7811 constexpr explicit
7812 _Iterator(const _Tp* __value, __index_type __bound = __index_type())
7813 : _M_value(__value), _M_current(__bound)
7814 {
7815 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7816 __glibcxx_assert(__bound >= 0);
7817 }
7818
7819 friend repeat_view;
7820
7821 public:
7822 using iterator_concept = random_access_iterator_tag;
7823 using iterator_category = random_access_iterator_tag;
7824 using value_type = _Tp;
7825 using difference_type = __conditional_t<__detail::__is_signed_integer_like<__index_type>,
7826 __index_type,
7827 __detail::__iota_diff_t<__index_type>>;
7828
7829 _Iterator() = default;
7830
7831 constexpr const _Tp&
7832 operator*() const noexcept
7833 { return *_M_value; }
7834
7835 constexpr _Iterator&
7836 operator++()
7837 {
7838 ++_M_current;
7839 return *this;
7840 }
7841
7842 constexpr _Iterator
7843 operator++(int)
7844 {
7845 auto __tmp = *this;
7846 ++*this;
7847 return __tmp;
7848 }
7849
7850 constexpr _Iterator&
7851 operator--()
7852 {
7853 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7854 __glibcxx_assert(_M_current > 0);
7855 --_M_current;
7856 return *this;
7857 }
7858
7859 constexpr _Iterator
7860 operator--(int)
7861 {
7862 auto __tmp = *this;
7863 --*this;
7864 return __tmp;
7865 }
7866
7867 constexpr _Iterator&
7868 operator+=(difference_type __n)
7869 {
7870 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7871 __glibcxx_assert(_M_current + __n >= 0);
7872 _M_current += __n;
7873 return *this;
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 const _Tp&
7886 operator[](difference_type __n) const noexcept
7887 { return *(*this + __n); }
7888
7889 friend constexpr bool
7890 operator==(const _Iterator& __x, const _Iterator& __y)
7891 { return __x._M_current == __y._M_current; }
7892
7893 friend constexpr auto
7894 operator<=>(const _Iterator& __x, const _Iterator& __y)
7895 { return __x._M_current <=> __y._M_current; }
7896
7897 friend constexpr _Iterator
7898 operator+(_Iterator __i, difference_type __n)
7899 {
7900 __i += __n;
7901 return __i;
7902 }
7903
7904 friend constexpr _Iterator
7905 operator+(difference_type __n, _Iterator __i)
7906 { return __i + __n; }
7907
7908 friend constexpr _Iterator
7909 operator-(_Iterator __i, difference_type __n)
7910 {
7911 __i -= __n;
7912 return __i;
7913 }
7914
7915 friend constexpr difference_type
7916 operator-(const _Iterator& __x, const _Iterator& __y)
7917 {
7918 return (static_cast<difference_type>(__x._M_current)
7919 - static_cast<difference_type>(__y._M_current));
7920 }
7921 };
7922
7923 namespace views
7924 {
7925 namespace __detail
7926 {
7927 template<typename _Tp, typename _Bound>
7928 inline constexpr bool __is_repeat_view<repeat_view<_Tp, _Bound>> = true;
7929
7930 template<typename _Tp>
7931 concept __can_repeat_view
7932 = requires { repeat_view(std::declval<_Tp>()); };
7933
7934 template<typename _Tp, typename _Bound>
7935 concept __can_bounded_repeat_view
7936 = requires { repeat_view(std::declval<_Tp>(), std::declval<_Bound>()); };
7937 }
7938
7939 struct _Repeat
7940 {
7941 template<typename _Tp>
7942 requires __detail::__can_repeat_view<_Tp>
7943 constexpr auto
7944 operator() [[nodiscard]] (_Tp&& __value) const
7945 {
7946 // _GLIBCXX_RESOLVE_LIB_DEFECTS
7947 // 4054. Repeating a repeat_view should repeat the view
7948 return repeat_view<decay_t<_Tp>>(std::forward<_Tp>(__value));
7949 }
7950
7951 template<typename _Tp, typename _Bound>
7952 requires __detail::__can_bounded_repeat_view<_Tp, _Bound>
7953 constexpr auto
7954 operator() [[nodiscard]] (_Tp&& __value, _Bound __bound) const
7955 { return repeat_view(std::forward<_Tp>(__value), __bound); }
7956 };
7957
7958 inline constexpr _Repeat repeat;
7959
7960 namespace __detail
7961 {
7962 template<typename _Range>
7963 constexpr auto
7964 __take_of_repeat_view(_Range&& __r, range_difference_t<_Range> __n)
7965 {
7966 using _Tp = remove_cvref_t<_Range>;
7967 static_assert(__is_repeat_view<_Tp>);
7968 if constexpr (sized_range<_Tp>)
7969 return views::repeat(*std::forward<_Range>(__r)._M_value,
7970 std::min(ranges::distance(__r), __n));
7971 else
7972 return views::repeat(*std::forward<_Range>(__r)._M_value, __n);
7973 }
7974
7975 template<typename _Range>
7976 constexpr auto
7977 __drop_of_repeat_view(_Range&& __r, range_difference_t<_Range> __n)
7978 {
7979 using _Tp = remove_cvref_t<_Range>;
7980 static_assert(__is_repeat_view<_Tp>);
7981 if constexpr (sized_range<_Tp>)
7982 {
7983 auto __sz = ranges::distance(__r);
7984 return views::repeat(*std::forward<_Range>(__r)._M_value,
7985 __sz - std::min(__sz, __n));
7986 }
7987 else
7988 return __r;
7989 }
7990 }
7991 }
7992#endif // __cpp_lib_ranges_repeat
7993
7994#ifdef __cpp_lib_ranges_stride // C++ >= 23
7995 template<input_range _Vp>
7996 requires view<_Vp>
7997 class stride_view : public view_interface<stride_view<_Vp>>
7998 {
7999 _Vp _M_base;
8000 range_difference_t<_Vp> _M_stride;
8001
8002 template<bool _Const> using _Base = __detail::__maybe_const_t<_Const, _Vp>;
8003
8004 template<bool _Const>
8005 struct __iter_cat
8006 { };
8007
8008 template<bool _Const>
8009 requires forward_range<_Base<_Const>>
8010 struct __iter_cat<_Const>
8011 {
8012 private:
8013 static auto
8014 _S_iter_cat()
8015 {
8016 using _Cat = typename iterator_traits<iterator_t<_Base<_Const>>>::iterator_category;
8017 if constexpr (derived_from<_Cat, random_access_iterator_tag>)
8018 return random_access_iterator_tag{};
8019 else
8020 return _Cat{};
8021 }
8022 public:
8023 using iterator_category = decltype(_S_iter_cat());
8024 };
8025
8026 template<bool> class _Iterator;
8027
8028 public:
8029 constexpr explicit
8030 stride_view(_Vp __base, range_difference_t<_Vp> __stride)
8031 : _M_base(std::move(__base)), _M_stride(__stride)
8032 { __glibcxx_assert(__stride > 0); }
8033
8034 constexpr _Vp
8035 base() const& requires copy_constructible<_Vp>
8036 { return _M_base; }
8037
8038 constexpr _Vp
8039 base() &&
8040 { return std::move(_M_base); }
8041
8042 constexpr range_difference_t<_Vp>
8043 stride() const noexcept
8044 { return _M_stride; }
8045
8046 constexpr auto
8047 begin() requires (!__detail::__simple_view<_Vp>)
8048 { return _Iterator<false>(this, ranges::begin(_M_base)); }
8049
8050 constexpr auto
8051 begin() const requires range<const _Vp>
8052 { return _Iterator<true>(this, ranges::begin(_M_base)); }
8053
8054 constexpr auto
8055 end() requires (!__detail::__simple_view<_Vp>)
8056 {
8057 if constexpr (common_range<_Vp> && sized_range<_Vp> && forward_range<_Vp>)
8058 {
8059 auto __missing = (_M_stride - ranges::distance(_M_base) % _M_stride) % _M_stride;
8060 return _Iterator<false>(this, ranges::end(_M_base), __missing);
8061 }
8062 else if constexpr (common_range<_Vp> && !bidirectional_range<_Vp>)
8063 return _Iterator<false>(this, ranges::end(_M_base));
8064 else
8065 return default_sentinel;
8066 }
8067
8068 constexpr auto
8069 end() const requires range<const _Vp>
8070 {
8071 if constexpr (common_range<const _Vp> && sized_range<const _Vp>
8072 && forward_range<const _Vp>)
8073 {
8074 auto __missing = (_M_stride - ranges::distance(_M_base) % _M_stride) % _M_stride;
8075 return _Iterator<true>(this, ranges::end(_M_base), __missing);
8076 }
8077 else if constexpr (common_range<const _Vp> && !bidirectional_range<const _Vp>)
8078 return _Iterator<true>(this, ranges::end(_M_base));
8079 else
8080 return default_sentinel;
8081 }
8082
8083 constexpr auto
8084 size() requires sized_range<_Vp>
8085 {
8086 return __detail::__to_unsigned_like
8087 (__detail::__div_ceil(ranges::distance(_M_base), _M_stride));
8088 }
8089
8090 constexpr auto
8091 size() const requires sized_range<const _Vp>
8092 {
8093 return __detail::__to_unsigned_like
8094 (__detail::__div_ceil(ranges::distance(_M_base), _M_stride));
8095 }
8096 };
8097
8098 template<typename _Range>
8099 stride_view(_Range&&, range_difference_t<_Range>) -> stride_view<views::all_t<_Range>>;
8100
8101 template<typename _Vp>
8102 inline constexpr bool enable_borrowed_range<stride_view<_Vp>>
8103 = enable_borrowed_range<_Vp>;
8104
8105 template<input_range _Vp>
8106 requires view<_Vp>
8107 template<bool _Const>
8108 class stride_view<_Vp>::_Iterator : public __iter_cat<_Const>
8109 {
8110 using _Parent = __detail::__maybe_const_t<_Const, stride_view>;
8111 using _Base = stride_view::_Base<_Const>;
8112
8113 iterator_t<_Base> _M_current = iterator_t<_Base>();
8114 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
8115 range_difference_t<_Base> _M_stride = 0;
8116 range_difference_t<_Base> _M_missing = 0;
8117
8118 constexpr
8119 _Iterator(_Parent* __parent, iterator_t<_Base> __current,
8120 range_difference_t<_Base> __missing = 0)
8121 : _M_current(std::move(__current)), _M_end(ranges::end(__parent->_M_base)),
8122 _M_stride(__parent->_M_stride), _M_missing(__missing)
8123 { }
8124
8125 static auto
8126 _S_iter_concept()
8127 {
8128 if constexpr (random_access_range<_Base>)
8129 return random_access_iterator_tag{};
8130 else if constexpr (bidirectional_range<_Base>)
8131 return bidirectional_iterator_tag{};
8132 else if constexpr (forward_range<_Base>)
8133 return forward_iterator_tag{};
8134 else
8135 return input_iterator_tag{};
8136 }
8137
8138 friend stride_view;
8139
8140 public:
8141 using difference_type = range_difference_t<_Base>;
8142 using value_type = range_value_t<_Base>;
8143 using iterator_concept = decltype(_S_iter_concept());
8144 // iterator_category defined in stride_view::__iter_cat
8145
8146 _Iterator() requires default_initializable<iterator_t<_Base>> = default;
8147
8148 constexpr
8149 _Iterator(_Iterator<!_Const> __other)
8150 requires _Const
8151 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
8152 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
8153 : _M_current(std::move(__other._M_current)), _M_end(std::move(__other._M_end)),
8154 _M_stride(__other._M_stride), _M_missing(__other._M_missing)
8155 { }
8156
8157 constexpr iterator_t<_Base>
8158 base() &&
8159 { return std::move(_M_current); }
8160
8161 constexpr const iterator_t<_Base>&
8162 base() const & noexcept
8163 { return _M_current; }
8164
8165 constexpr decltype(auto)
8166 operator*() const
8167 { return *_M_current; }
8168
8169 constexpr _Iterator&
8170 operator++()
8171 {
8172 __glibcxx_assert(_M_current != _M_end);
8173 _M_missing = ranges::advance(_M_current, _M_stride, _M_end);
8174 return *this;
8175 }
8176
8177 constexpr void
8178 operator++(int)
8179 { ++*this; }
8180
8181 constexpr _Iterator
8182 operator++(int) requires forward_range<_Base>
8183 {
8184 auto __tmp = *this;
8185 ++*this;
8186 return __tmp;
8187 }
8188
8189 constexpr _Iterator&
8190 operator--() requires bidirectional_range<_Base>
8191 {
8192 ranges::advance(_M_current, _M_missing - _M_stride);
8193 _M_missing = 0;
8194 return *this;
8195 }
8196
8197 constexpr _Iterator
8198 operator--(int) requires bidirectional_range<_Base>
8199 {
8200 auto __tmp = *this;
8201 --*this;
8202 return __tmp;
8203 }
8204
8205 constexpr _Iterator&
8206 operator+=(difference_type __n) requires random_access_range<_Base>
8207 {
8208 if (__n > 0)
8209 {
8210 __glibcxx_assert(ranges::distance(_M_current, _M_end) > _M_stride * (__n - 1));
8211 _M_missing = ranges::advance(_M_current, _M_stride * __n, _M_end);
8212 }
8213 else if (__n < 0)
8214 {
8215 ranges::advance(_M_current, _M_stride * __n + _M_missing);
8216 _M_missing = 0;
8217 }
8218 return *this;
8219 }
8220
8221 constexpr _Iterator&
8222 operator-=(difference_type __n) requires random_access_range<_Base>
8223 { return *this += -__n; }
8224
8225 constexpr decltype(auto) operator[](difference_type __n) const
8226 requires random_access_range<_Base>
8227 { return *(*this + __n); }
8228
8229 friend constexpr bool
8230 operator==(const _Iterator& __x, default_sentinel_t)
8231 { return __x._M_current == __x._M_end; }
8232
8233 friend constexpr bool
8234 operator==(const _Iterator& __x, const _Iterator& __y)
8235 requires equality_comparable<iterator_t<_Base>>
8236 { return __x._M_current == __y._M_current; }
8237
8238 friend constexpr bool
8239 operator<(const _Iterator& __x, const _Iterator& __y)
8240 requires random_access_range<_Base>
8241 { return __x._M_current < __y._M_current; }
8242
8243 friend constexpr bool
8244 operator>(const _Iterator& __x, const _Iterator& __y)
8245 requires random_access_range<_Base>
8246 { return __y._M_current < __x._M_current; }
8247
8248 friend constexpr bool
8249 operator<=(const _Iterator& __x, const _Iterator& __y)
8250 requires random_access_range<_Base>
8251 { return !(__y._M_current < __x._M_current); }
8252
8253 friend constexpr bool
8254 operator>=(const _Iterator& __x, const _Iterator& __y)
8255 requires random_access_range<_Base>
8256 { return !(__x._M_current < __y._M_current); }
8257
8258 friend constexpr auto
8259 operator<=>(const _Iterator& __x, const _Iterator& __y)
8260 requires random_access_range<_Base> && three_way_comparable<iterator_t<_Base>>
8261 { return __x._M_current <=> __y._M_current; }
8262
8263 friend constexpr _Iterator
8264 operator+(const _Iterator& __i, difference_type __n)
8265 requires random_access_range<_Base>
8266 {
8267 auto __r = __i;
8268 __r += __n;
8269 return __r;
8270 }
8271
8272 friend constexpr _Iterator
8273 operator+(difference_type __n, const _Iterator& __i)
8274 requires random_access_range<_Base>
8275 { return __i + __n; }
8276
8277 friend constexpr _Iterator
8278 operator-(const _Iterator& __i, difference_type __n)
8279 requires random_access_range<_Base>
8280 {
8281 auto __r = __i;
8282 __r -= __n;
8283 return __r;
8284 }
8285
8286 friend constexpr difference_type
8287 operator-(const _Iterator& __x, const _Iterator& __y)
8288 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
8289 {
8290 auto __n = __x._M_current - __y._M_current;
8291 if constexpr (forward_range<_Base>)
8292 return (__n + __x._M_missing - __y._M_missing) / __x._M_stride;
8293 else if (__n < 0)
8294 return -__detail::__div_ceil(-__n, __x._M_stride);
8295 else
8296 return __detail::__div_ceil(__n, __x._M_stride);
8297 }
8298
8299 friend constexpr difference_type
8300 operator-(default_sentinel_t __y, const _Iterator& __x)
8301 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
8302 { return __detail::__div_ceil(__x._M_end - __x._M_current, __x._M_stride); }
8303
8304 friend constexpr difference_type
8305 operator-(const _Iterator& __x, default_sentinel_t __y)
8306 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
8307 { return -(__y - __x); }
8308
8309 friend constexpr range_rvalue_reference_t<_Base>
8310 iter_move(const _Iterator& __i)
8311 noexcept(noexcept(ranges::iter_move(__i._M_current)))
8312 { return ranges::iter_move(__i._M_current); }
8313
8314 friend constexpr void
8315 iter_swap(const _Iterator& __x, const _Iterator& __y)
8316 noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
8317 requires indirectly_swappable<iterator_t<_Base>>
8318 { ranges::iter_swap(__x._M_current, __y._M_current); }
8319 };
8320
8321 namespace views
8322 {
8323 namespace __detail
8324 {
8325 template<typename _Range, typename _Dp>
8326 concept __can_stride_view
8327 = requires { stride_view(std::declval<_Range>(), std::declval<_Dp>()); };
8328 }
8329
8330 struct _Stride : __adaptor::_RangeAdaptor<_Stride>
8331 {
8332 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
8333 requires __detail::__can_stride_view<_Range, _Dp>
8334 constexpr auto
8335 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
8336 { return stride_view(std::forward<_Range>(__r), __n); }
8337
8338 using __adaptor::_RangeAdaptor<_Stride>::operator();
8339 static constexpr int _S_arity = 2;
8340 static constexpr bool _S_has_simple_extra_args = true;
8341 };
8342
8343 inline constexpr _Stride stride;
8344 }
8345#endif // __cpp_lib_ranges_stride
8346
8347#ifdef __cpp_lib_ranges_cartesian_product // C++ >= 23
8348 namespace __detail
8349 {
8350 template<bool _Const, typename _First, typename... _Vs>
8351 concept __cartesian_product_is_random_access
8352 = (random_access_range<__maybe_const_t<_Const, _First>>
8353 && ...
8354 && (random_access_range<__maybe_const_t<_Const, _Vs>>
8355 && sized_range<__maybe_const_t<_Const, _Vs>>));
8356
8357 template<typename _Range>
8358 concept __cartesian_product_common_arg
8359 = common_range<_Range> || (sized_range<_Range> && random_access_range<_Range>);
8360
8361 template<bool _Const, typename _First, typename... _Vs>
8362 concept __cartesian_product_is_bidirectional
8363 = (bidirectional_range<__maybe_const_t<_Const, _First>>
8364 && ...
8365 && (bidirectional_range<__maybe_const_t<_Const, _Vs>>
8366 && __cartesian_product_common_arg<__maybe_const_t<_Const, _Vs>>));
8367
8368 template<typename _First, typename... _Vs>
8369 concept __cartesian_product_is_common = __cartesian_product_common_arg<_First>;
8370
8371 template<typename... _Vs>
8372 concept __cartesian_product_is_sized = (sized_range<_Vs> && ...);
8373
8374 template<bool _Const, template<typename> class FirstSent, typename _First, typename... _Vs>
8375 concept __cartesian_is_sized_sentinel
8376 = (sized_sentinel_for<FirstSent<__maybe_const_t<_Const, _First>>,
8377 iterator_t<__maybe_const_t<_Const, _First>>>
8378 && ...
8379 && (sized_range<__maybe_const_t<_Const, _Vs>>
8380 && sized_sentinel_for<iterator_t<__maybe_const_t<_Const, _Vs>>,
8381 iterator_t<__maybe_const_t<_Const, _Vs>>>));
8382
8383 template<__cartesian_product_common_arg _Range>
8384 constexpr auto
8385 __cartesian_common_arg_end(_Range& __r)
8386 {
8387 if constexpr (common_range<_Range>)
8388 return ranges::end(__r);
8389 else
8390 return ranges::begin(__r) + ranges::distance(__r);
8391 }
8392 } // namespace __detail
8393
8394 template<input_range _First, forward_range... _Vs>
8395 requires (view<_First> && ... && view<_Vs>)
8396 class cartesian_product_view : public view_interface<cartesian_product_view<_First, _Vs...>>
8397 {
8398 tuple<_First, _Vs...> _M_bases;
8399
8400 template<bool> class _Iterator;
8401
8402 static auto
8403 _S_difference_type()
8404 {
8405 // TODO: Implement the recommended practice of using the smallest
8406 // sufficiently wide type according to the maximum sizes of the
8407 // underlying ranges?
8408 return common_type_t<ptrdiff_t,
8409 range_difference_t<_First>,
8410 range_difference_t<_Vs>...>{};
8411 }
8412
8413 public:
8414 cartesian_product_view() = default;
8415
8416 constexpr explicit
8417 cartesian_product_view(_First __first, _Vs... __rest)
8418 : _M_bases(std::move(__first), std::move(__rest)...)
8419 { }
8420
8421 constexpr _Iterator<false>
8422 begin() requires (!__detail::__simple_view<_First> || ... || !__detail::__simple_view<_Vs>)
8423 { return _Iterator<false>(*this, __detail::__tuple_transform(ranges::begin, _M_bases)); }
8424
8425 constexpr _Iterator<true>
8426 begin() const requires (range<const _First> && ... && range<const _Vs>)
8427 { return _Iterator<true>(*this, __detail::__tuple_transform(ranges::begin, _M_bases)); }
8428
8429 constexpr _Iterator<false>
8430 end() requires ((!__detail::__simple_view<_First> || ... || !__detail::__simple_view<_Vs>)
8431 && __detail::__cartesian_product_is_common<_First, _Vs...>)
8432 {
8433 auto __its = [this]<size_t... _Is>(index_sequence<_Is...>) {
8434 using _Ret = tuple<iterator_t<_First>, iterator_t<_Vs>...>;
8435 bool __empty_tail = (ranges::empty(std::get<1 + _Is>(_M_bases)) || ...);
8436 auto& __first = std::get<0>(_M_bases);
8437 return _Ret{(__empty_tail
8438 ? ranges::begin(__first)
8439 : __detail::__cartesian_common_arg_end(__first)),
8440 ranges::begin(std::get<1 + _Is>(_M_bases))...};
8441 }(make_index_sequence<sizeof...(_Vs)>{});
8442
8443 return _Iterator<false>{*this, std::move(__its)};
8444 }
8445
8446 constexpr _Iterator<true>
8447 end() const requires __detail::__cartesian_product_is_common<const _First, const _Vs...>
8448 {
8449 auto __its = [this]<size_t... _Is>(index_sequence<_Is...>) {
8450 using _Ret = tuple<iterator_t<const _First>, iterator_t<const _Vs>...>;
8451 bool __empty_tail = (ranges::empty(std::get<1 + _Is>(_M_bases)) || ...);
8452 auto& __first = std::get<0>(_M_bases);
8453 return _Ret{(__empty_tail
8454 ? ranges::begin(__first)
8455 : __detail::__cartesian_common_arg_end(__first)),
8456 ranges::begin(std::get<1 + _Is>(_M_bases))...};
8457 }(make_index_sequence<sizeof...(_Vs)>{});
8458
8459 return _Iterator<true>{*this, std::move(__its)};
8460 }
8461
8462 constexpr default_sentinel_t
8463 end() const noexcept
8464 { return default_sentinel; }
8465
8466 constexpr auto
8467 size() requires __detail::__cartesian_product_is_sized<_First, _Vs...>
8468 {
8469 using _ST = __detail::__make_unsigned_like_t<decltype(_S_difference_type())>;
8470 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8471 auto __size = static_cast<_ST>(1);
8472#ifdef _GLIBCXX_ASSERTIONS
8473 if constexpr (integral<_ST>)
8474 {
8475 bool __overflow
8476 = (__builtin_mul_overflow(__size,
8477 static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))),
8478 &__size)
8479 || ...);
8480 __glibcxx_assert(!__overflow);
8481 }
8482 else
8483#endif
8484 __size = (static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))) * ...);
8485 return __size;
8486 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8487 }
8488
8489 constexpr auto
8490 size() const requires __detail::__cartesian_product_is_sized<const _First, const _Vs...>
8491 {
8492 using _ST = __detail::__make_unsigned_like_t<decltype(_S_difference_type())>;
8493 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8494 auto __size = static_cast<_ST>(1);
8495#ifdef _GLIBCXX_ASSERTIONS
8496 if constexpr (integral<_ST>)
8497 {
8498 bool __overflow
8499 = (__builtin_mul_overflow(__size,
8500 static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))),
8501 &__size)
8502 || ...);
8503 __glibcxx_assert(!__overflow);
8504 }
8505 else
8506#endif
8507 __size = (static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))) * ...);
8508 return __size;
8509 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8510 }
8511 };
8512
8513 template<typename... _Vs>
8514 cartesian_product_view(_Vs&&...) -> cartesian_product_view<views::all_t<_Vs>...>;
8515
8516 template<input_range _First, forward_range... _Vs>
8517 requires (view<_First> && ... && view<_Vs>)
8518 template<bool _Const>
8519 class cartesian_product_view<_First, _Vs...>::_Iterator
8520 {
8521 using _Parent = __maybe_const_t<_Const, cartesian_product_view>;
8522 _Parent* _M_parent = nullptr;
8523 tuple<iterator_t<__maybe_const_t<_Const, _First>>,
8524 iterator_t<__maybe_const_t<_Const, _Vs>>...> _M_current;
8525
8526 constexpr
8527 _Iterator(_Parent& __parent, decltype(_M_current) __current)
8528 : _M_parent(std::__addressof(__parent)),
8529 _M_current(std::move(__current))
8530 { }
8531
8532 static auto
8533 _S_iter_concept()
8534 {
8535 if constexpr (__detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>)
8536 return random_access_iterator_tag{};
8537 else if constexpr (__detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>)
8538 return bidirectional_iterator_tag{};
8539 else if constexpr (forward_range<__maybe_const_t<_Const, _First>>)
8540 return forward_iterator_tag{};
8541 else
8542 return input_iterator_tag{};
8543 }
8544
8545 friend cartesian_product_view;
8546
8547 public:
8548 using iterator_category = input_iterator_tag;
8549 using iterator_concept = decltype(_S_iter_concept());
8550 using value_type
8551 = tuple<range_value_t<__maybe_const_t<_Const, _First>>,
8552 range_value_t<__maybe_const_t<_Const, _Vs>>...>;
8553 using reference
8554 = tuple<range_reference_t<__maybe_const_t<_Const, _First>>,
8555 range_reference_t<__maybe_const_t<_Const, _Vs>>...>;
8556 using difference_type = decltype(cartesian_product_view::_S_difference_type());
8557
8558 _Iterator() = default;
8559
8560 constexpr
8561 _Iterator(_Iterator<!_Const> __i)
8562 requires _Const
8563 && (convertible_to<iterator_t<_First>, iterator_t<const _First>>
8564 && ... && convertible_to<iterator_t<_Vs>, iterator_t<const _Vs>>)
8565 : _M_parent(std::__addressof(__i._M_parent)),
8566 _M_current(std::move(__i._M_current))
8567 { }
8568
8569 constexpr auto
8570 operator*() const
8571 {
8572 auto __f = [](auto& __i) -> decltype(auto) {
8573 return *__i;
8574 };
8575 return __detail::__tuple_transform(__f, _M_current);
8576 }
8577
8578 constexpr _Iterator&
8579 operator++()
8580 {
8581 _M_next();
8582 return *this;
8583 }
8584
8585 constexpr void
8586 operator++(int)
8587 { ++*this; }
8588
8589 constexpr _Iterator
8590 operator++(int) requires forward_range<__maybe_const_t<_Const, _First>>
8591 {
8592 auto __tmp = *this;
8593 ++*this;
8594 return __tmp;
8595 }
8596
8597 constexpr _Iterator&
8598 operator--()
8599 requires __detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>
8600 {
8601 _M_prev();
8602 return *this;
8603 }
8604
8605 constexpr _Iterator
8606 operator--(int)
8607 requires __detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>
8608 {
8609 auto __tmp = *this;
8610 --*this;
8611 return __tmp;
8612 }
8613
8614 constexpr _Iterator&
8615 operator+=(difference_type __x)
8616 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8617 {
8618 _M_advance(__x);
8619 return *this;
8620 }
8621
8622 constexpr _Iterator&
8623 operator-=(difference_type __x)
8624 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8625 { return *this += -__x; }
8626
8627 constexpr reference
8628 operator[](difference_type __n) const
8629 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8630 { return *((*this) + __n); }
8631
8632 friend constexpr bool
8633 operator==(const _Iterator& __x, const _Iterator& __y)
8634 requires equality_comparable<iterator_t<__maybe_const_t<_Const, _First>>>
8635 { return __x._M_current == __y._M_current; }
8636
8637 friend constexpr bool
8638 operator==(const _Iterator& __x, default_sentinel_t)
8639 {
8640 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8641 return ((std::get<_Is>(__x._M_current)
8642 == ranges::end(std::get<_Is>(__x._M_parent->_M_bases)))
8643 || ...);
8644 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8645 }
8646
8647 friend constexpr auto
8648 operator<=>(const _Iterator& __x, const _Iterator& __y)
8649 requires __detail::__all_random_access<_Const, _First, _Vs...>
8650 { return __x._M_current <=> __y._M_current; }
8651
8652 friend constexpr _Iterator
8653 operator+(_Iterator __x, difference_type __y)
8654 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8655 { return __x += __y; }
8656
8657 friend constexpr _Iterator
8658 operator+(difference_type __x, _Iterator __y)
8659 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8660 { return __y += __x; }
8661
8662 friend constexpr _Iterator
8663 operator-(_Iterator __x, difference_type __y)
8664 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8665 { return __x -= __y; }
8666
8667 friend constexpr difference_type
8668 operator-(const _Iterator& __x, const _Iterator& __y)
8669 requires __detail::__cartesian_is_sized_sentinel<_Const, iterator_t, _First, _Vs...>
8670 { return __x._M_distance_from(__y._M_current); }
8671
8672 friend constexpr difference_type
8673 operator-(const _Iterator& __i, default_sentinel_t)
8674 requires __detail::__cartesian_is_sized_sentinel<_Const, sentinel_t, _First, _Vs...>
8675 {
8676 tuple __end_tuple = [&]<size_t... _Is>(index_sequence<_Is...>) {
8677 return tuple{ranges::end(std::get<0>(__i._M_parent->_M_bases)),
8678 ranges::begin(std::get<1 + _Is>(__i._M_parent->_M_bases))...};
8679 }(make_index_sequence<sizeof...(_Vs)>{});
8680 return __i._M_distance_from(__end_tuple);
8681 }
8682
8683 friend constexpr difference_type
8684 operator-(default_sentinel_t, const _Iterator& __i)
8685 requires __detail::__cartesian_is_sized_sentinel<_Const, sentinel_t, _First, _Vs...>
8686 { return -(__i - default_sentinel); }
8687
8688 friend constexpr auto
8689 iter_move(const _Iterator& __i)
8690 { return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
8691
8692 friend constexpr void
8693 iter_swap(const _Iterator& __l, const _Iterator& __r)
8694 requires (indirectly_swappable<iterator_t<__maybe_const_t<_Const, _First>>>
8695 && ...
8696 && indirectly_swappable<iterator_t<__maybe_const_t<_Const, _Vs>>>)
8697 {
8698 [&]<size_t... _Is>(index_sequence<_Is...>) {
8699 (ranges::iter_swap(std::get<_Is>(__l._M_current), std::get<_Is>(__r._M_current)), ...);
8700 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8701 }
8702
8703 private:
8704 template<size_t _Nm = sizeof...(_Vs)>
8705 constexpr void
8706 _M_next()
8707 {
8708 auto& __it = std::get<_Nm>(_M_current);
8709 ++__it;
8710 if constexpr (_Nm > 0)
8711 if (__it == ranges::end(std::get<_Nm>(_M_parent->_M_bases)))
8712 {
8713 __it = ranges::begin(std::get<_Nm>(_M_parent->_M_bases));
8714 _M_next<_Nm - 1>();
8715 }
8716 }
8717
8718 template<size_t _Nm = sizeof...(_Vs)>
8719 constexpr void
8720 _M_prev()
8721 {
8722 auto& __it = std::get<_Nm>(_M_current);
8723 if constexpr (_Nm > 0)
8724 if (__it == ranges::begin(std::get<_Nm>(_M_parent->_M_bases)))
8725 {
8726 __it = __detail::__cartesian_common_arg_end(std::get<_Nm>(_M_parent->_M_bases));
8727 _M_prev<_Nm - 1>();
8728 }
8729 --__it;
8730 }
8731
8732 template<size_t _Nm = sizeof...(_Vs)>
8733 constexpr void
8734 _M_advance(difference_type __x)
8735 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8736 {
8737 if (__x == 1)
8738 _M_next<_Nm>();
8739 else if (__x == -1)
8740 _M_prev<_Nm>();
8741 else if (__x != 0)
8742 {
8743 // Constant time iterator advancement.
8744 auto& __r = std::get<_Nm>(_M_parent->_M_bases);
8745 auto& __it = std::get<_Nm>(_M_current);
8746 if constexpr (_Nm == 0)
8747 {
8748#ifdef _GLIBCXX_ASSERTIONS
8749 if constexpr (sized_range<__maybe_const_t<_Const, _First>>)
8750 {
8751 auto __size = ranges::ssize(__r);
8752 auto __begin = ranges::begin(__r);
8753 auto __offset = __it - __begin;
8754 __glibcxx_assert(__offset + __x >= 0 && __offset + __x <= __size);
8755 }
8756#endif
8757 __it += __x;
8758 }
8759 else
8760 {
8761 auto __size = ranges::ssize(__r);
8762 auto __begin = ranges::begin(__r);
8763 auto __offset = __it - __begin;
8764 __offset += __x;
8765 __x = __offset / __size;
8766 __offset %= __size;
8767 if (__offset < 0)
8768 {
8769 __offset = __size + __offset;
8770 --__x;
8771 }
8772 __it = __begin + __offset;
8773 _M_advance<_Nm - 1>(__x);
8774 }
8775 }
8776 }
8777
8778 template<typename _Tuple>
8779 constexpr difference_type
8780 _M_distance_from(const _Tuple& __t) const
8781 {
8782 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8783 auto __sum = static_cast<difference_type>(0);
8784#ifdef _GLIBCXX_ASSERTIONS
8785 if constexpr (integral<difference_type>)
8786 {
8787 bool __overflow
8788 = (__builtin_add_overflow(__sum, _M_scaled_distance<_Is>(__t), &__sum)
8789 || ...);
8790 __glibcxx_assert(!__overflow);
8791 }
8792 else
8793#endif
8794 __sum = (_M_scaled_distance<_Is>(__t) + ...);
8795 return __sum;
8796 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8797 }
8798
8799 template<size_t _Nm, typename _Tuple>
8800 constexpr difference_type
8801 _M_scaled_distance(const _Tuple& __t) const
8802 {
8803 auto __dist = static_cast<difference_type>(std::get<_Nm>(_M_current)
8804 - std::get<_Nm>(__t));
8805#ifdef _GLIBCXX_ASSERTIONS
8806 if constexpr (integral<difference_type>)
8807 {
8808 bool __overflow = __builtin_mul_overflow(__dist, _M_scaled_size<_Nm+1>(), &__dist);
8809 __glibcxx_assert(!__overflow);
8810 }
8811 else
8812#endif
8813 __dist *= _M_scaled_size<_Nm+1>();
8814 return __dist;
8815 }
8816
8817 template<size_t _Nm>
8818 constexpr difference_type
8819 _M_scaled_size() const
8820 {
8821 if constexpr (_Nm <= sizeof...(_Vs))
8822 {
8823 auto __size = static_cast<difference_type>(ranges::size
8824 (std::get<_Nm>(_M_parent->_M_bases)));
8825#ifdef _GLIBCXX_ASSERTIONS
8826 if constexpr (integral<difference_type>)
8827 {
8828 bool __overflow = __builtin_mul_overflow(__size, _M_scaled_size<_Nm+1>(), &__size);
8829 __glibcxx_assert(!__overflow);
8830 }
8831 else
8832#endif
8833 __size *= _M_scaled_size<_Nm+1>();
8834 return __size;
8835 }
8836 else
8837 return static_cast<difference_type>(1);
8838 }
8839 };
8840
8841 namespace views
8842 {
8843 namespace __detail
8844 {
8845 template<typename... _Ts>
8846 concept __can_cartesian_product_view
8847 = requires { cartesian_product_view<all_t<_Ts>...>(std::declval<_Ts>()...); };
8848 }
8849
8850 struct _CartesianProduct
8851 {
8852 template<typename... _Ts>
8853 requires (sizeof...(_Ts) == 0 || __detail::__can_cartesian_product_view<_Ts...>)
8854 constexpr auto
8855 operator() [[nodiscard]] (_Ts&&... __ts) const
8856 {
8857 if constexpr (sizeof...(_Ts) == 0)
8858 return views::single(tuple{});
8859 else
8860 return cartesian_product_view<all_t<_Ts>...>(std::forward<_Ts>(__ts)...);
8861 }
8862 };
8863
8864 inline constexpr _CartesianProduct cartesian_product;
8865 }
8866#endif // __cpp_lib_ranges_cartesian_product
8867
8868#ifdef __cpp_lib_ranges_as_rvalue // C++ >= 23
8869 template<input_range _Vp>
8870 requires view<_Vp>
8871 class as_rvalue_view : public view_interface<as_rvalue_view<_Vp>>
8872 {
8873 _Vp _M_base = _Vp();
8874
8875 public:
8876 as_rvalue_view() requires default_initializable<_Vp> = default;
8877
8878 constexpr explicit
8879 as_rvalue_view(_Vp __base)
8880 : _M_base(std::move(__base))
8881 { }
8882
8883 constexpr _Vp
8884 base() const& requires copy_constructible<_Vp>
8885 { return _M_base; }
8886
8887 constexpr _Vp
8888 base() &&
8889 { return std::move(_M_base); }
8890
8891 constexpr auto
8892 begin() requires (!__detail::__simple_view<_Vp>)
8893 { return move_iterator(ranges::begin(_M_base)); }
8894
8895 constexpr auto
8896 begin() const requires range<const _Vp>
8897 { return move_iterator(ranges::begin(_M_base)); }
8898
8899 constexpr auto
8900 end() requires (!__detail::__simple_view<_Vp>)
8901 {
8902 if constexpr (common_range<_Vp>)
8903 return move_iterator(ranges::end(_M_base));
8904 else
8905 return move_sentinel(ranges::end(_M_base));
8906 }
8907
8908 constexpr auto
8909 end() const requires range<const _Vp>
8910 {
8911 if constexpr (common_range<const _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 size() requires sized_range<_Vp>
8919 { return ranges::size(_M_base); }
8920
8921 constexpr auto
8922 size() const requires sized_range<const _Vp>
8923 { return ranges::size(_M_base); }
8924 };
8925
8926 template<typename _Range>
8927 as_rvalue_view(_Range&&) -> as_rvalue_view<views::all_t<_Range>>;
8928
8929 template<typename _Tp>
8930 inline constexpr bool enable_borrowed_range<as_rvalue_view<_Tp>>
8931 = enable_borrowed_range<_Tp>;
8932
8933 namespace views
8934 {
8935 namespace __detail
8936 {
8937 template<typename _Tp>
8938 concept __can_as_rvalue_view = requires { as_rvalue_view(std::declval<_Tp>()); };
8939 }
8940
8941 struct _AsRvalue : __adaptor::_RangeAdaptorClosure<_AsRvalue>
8942 {
8943 template<viewable_range _Range>
8944 requires __detail::__can_as_rvalue_view<_Range>
8945 constexpr auto
8946 operator() [[nodiscard]] (_Range&& __r) const
8947 {
8948 if constexpr (same_as<range_rvalue_reference_t<_Range>,
8949 range_reference_t<_Range>>)
8950 return views::all(std::forward<_Range>(__r));
8951 else
8952 return as_rvalue_view(std::forward<_Range>(__r));
8953 }
8954 };
8955
8956 inline constexpr _AsRvalue as_rvalue;
8957 }
8958#endif // __cpp_lib_as_rvalue
8959
8960#ifdef __cpp_lib_ranges_enumerate // C++ >= 23
8961 namespace __detail
8962 {
8963 template<typename _Range>
8964 concept __range_with_movable_reference = input_range<_Range>
8965 && move_constructible<range_reference_t<_Range>>
8966 && move_constructible<range_rvalue_reference_t<_Range>>;
8967 }
8968
8969 template<view _Vp>
8970 requires __detail::__range_with_movable_reference<_Vp>
8971 class enumerate_view : public view_interface<enumerate_view<_Vp>>
8972 {
8973 _Vp _M_base = _Vp();
8974
8975 template<bool _Const> class _Iterator;
8976 template<bool _Const> class _Sentinel;
8977
8978 public:
8979 enumerate_view() requires default_initializable<_Vp> = default;
8980
8981 constexpr explicit
8982 enumerate_view(_Vp __base)
8983 : _M_base(std::move(__base))
8984 { }
8985
8986 constexpr auto
8987 begin() requires (!__detail::__simple_view<_Vp>)
8988 { return _Iterator<false>(ranges::begin(_M_base), 0); }
8989
8990 constexpr auto
8991 begin() const requires __detail::__range_with_movable_reference<const _Vp>
8992 { return _Iterator<true>(ranges::begin(_M_base), 0); }
8993
8994 constexpr auto
8995 end() requires (!__detail::__simple_view<_Vp>)
8996 {
8997 if constexpr (common_range<_Vp> && sized_range<_Vp>)
8998 return _Iterator<false>(ranges::end(_M_base), ranges::distance(_M_base));
8999 else
9000 return _Sentinel<false>(ranges::end(_M_base));
9001 }
9002
9003 constexpr auto
9004 end() const requires __detail::__range_with_movable_reference<const _Vp>
9005 {
9006 if constexpr (common_range<const _Vp> && sized_range<const _Vp>)
9007 return _Iterator<true>(ranges::end(_M_base), ranges::distance(_M_base));
9008 else
9009 return _Sentinel<true>(ranges::end(_M_base));
9010 }
9011
9012 constexpr auto
9013 size() requires sized_range<_Vp>
9014 { return ranges::size(_M_base); }
9015
9016 constexpr auto
9017 size() const requires sized_range<const _Vp>
9018 { return ranges::size(_M_base); }
9019
9020 constexpr _Vp
9021 base() const & requires copy_constructible<_Vp>
9022 { return _M_base; }
9023
9024 constexpr _Vp
9025 base() &&
9026 { return std::move(_M_base); }
9027 };
9028
9029 template<typename _Range>
9030 enumerate_view(_Range&&) -> enumerate_view<views::all_t<_Range>>;
9031
9032 template<typename _Tp>
9033 inline constexpr bool enable_borrowed_range<enumerate_view<_Tp>>
9034 = enable_borrowed_range<_Tp>;
9035
9036 template<view _Vp>
9037 requires __detail::__range_with_movable_reference<_Vp>
9038 template<bool _Const>
9039 class enumerate_view<_Vp>::_Iterator
9040 {
9041 using _Base = __maybe_const_t<_Const, _Vp>;
9042
9043 static auto
9044 _S_iter_concept()
9045 {
9046 if constexpr (random_access_range<_Base>)
9047 return random_access_iterator_tag{};
9048 else if constexpr (bidirectional_range<_Base>)
9049 return bidirectional_iterator_tag{};
9050 else if constexpr (forward_range<_Base>)
9051 return forward_iterator_tag{};
9052 else
9053 return input_iterator_tag{};
9054 }
9055
9056 friend enumerate_view;
9057
9058 public:
9059 using iterator_category = input_iterator_tag;
9060 using iterator_concept = decltype(_S_iter_concept());
9061 using difference_type = range_difference_t<_Base>;
9062 using value_type = tuple<difference_type, range_value_t<_Base>>;
9063
9064 private:
9065 using __reference_type = tuple<difference_type, range_reference_t<_Base>>;
9066
9067 iterator_t<_Base> _M_current = iterator_t<_Base>();
9068 difference_type _M_pos = 0;
9069
9070 constexpr explicit
9071 _Iterator(iterator_t<_Base> __current, difference_type __pos)
9072 : _M_current(std::move(__current)), _M_pos(__pos)
9073 { }
9074
9075 public:
9076 _Iterator() requires default_initializable<iterator_t<_Base>> = default;
9077
9078 constexpr
9079 _Iterator(_Iterator<!_Const> __i)
9080 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
9081 : _M_current(std::move(__i._M_current)), _M_pos(__i._M_pos)
9082 { }
9083
9084 constexpr const iterator_t<_Base> &
9085 base() const & noexcept
9086 { return _M_current; }
9087
9088 constexpr iterator_t<_Base>
9089 base() &&
9090 { return std::move(_M_current); }
9091
9092 constexpr difference_type
9093 index() const noexcept
9094 { return _M_pos; }
9095
9096 constexpr auto
9097 operator*() const
9098 { return __reference_type(_M_pos, *_M_current); }
9099
9100 constexpr _Iterator&
9101 operator++()
9102 {
9103 ++_M_current;
9104 ++_M_pos;
9105 return *this;
9106 }
9107
9108 constexpr void
9109 operator++(int)
9110 { ++*this; }
9111
9112 constexpr _Iterator
9113 operator++(int) requires forward_range<_Base>
9114 {
9115 auto __tmp = *this;
9116 ++*this;
9117 return __tmp;
9118 }
9119
9120 constexpr _Iterator&
9121 operator--() requires bidirectional_range<_Base>
9122 {
9123 --_M_current;
9124 --_M_pos;
9125 return *this;
9126 }
9127
9128 constexpr _Iterator
9129 operator--(int) requires bidirectional_range<_Base>
9130 {
9131 auto __tmp = *this;
9132 --*this;
9133 return __tmp;
9134 }
9135
9136 constexpr _Iterator&
9137 operator+=(difference_type __n) requires random_access_range<_Base>
9138 {
9139 _M_current += __n;
9140 _M_pos += __n;
9141 return *this;
9142 }
9143
9144 constexpr _Iterator&
9145 operator-=(difference_type __n) requires random_access_range<_Base>
9146 {
9147 _M_current -= __n;
9148 _M_pos -= __n;
9149 return *this;
9150 }
9151
9152 constexpr auto
9153 operator[](difference_type __n) const requires random_access_range<_Base>
9154 { return __reference_type(_M_pos + __n, _M_current[__n]); }
9155
9156 friend constexpr bool
9157 operator==(const _Iterator& __x, const _Iterator& __y) noexcept
9158 { return __x._M_pos == __y._M_pos; }
9159
9160 friend constexpr strong_ordering
9161 operator<=>(const _Iterator& __x, const _Iterator& __y) noexcept
9162 { return __x._M_pos <=> __y._M_pos; }
9163
9164 friend constexpr _Iterator
9165 operator+(const _Iterator& __x, difference_type __y)
9166 requires random_access_range<_Base>
9167 { return (auto(__x) += __y); }
9168
9169 friend constexpr _Iterator
9170 operator+(difference_type __x, const _Iterator& __y)
9171 requires random_access_range<_Base>
9172 { return auto(__y) += __x; }
9173
9174 friend constexpr _Iterator
9175 operator-(const _Iterator& __x, difference_type __y)
9176 requires random_access_range<_Base>
9177 { return auto(__x) -= __y; }
9178
9179 friend constexpr difference_type
9180 operator-(const _Iterator& __x, const _Iterator& __y) noexcept
9181 { return __x._M_pos - __y._M_pos; }
9182
9183 friend constexpr auto
9184 iter_move(const _Iterator& __i)
9185 noexcept(noexcept(ranges::iter_move(__i._M_current))
9186 && is_nothrow_move_constructible_v<range_rvalue_reference_t<_Base>>)
9187 {
9188 return tuple<difference_type, range_rvalue_reference_t<_Base>>
9189 (__i._M_pos, ranges::iter_move(__i._M_current));
9190 }
9191 };
9192
9193 template<view _Vp>
9194 requires __detail::__range_with_movable_reference<_Vp>
9195 template<bool _Const>
9196 class enumerate_view<_Vp>::_Sentinel
9197 {
9198 using _Base = __maybe_const_t<_Const, _Vp>;
9199
9200 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
9201
9202 constexpr explicit
9203 _Sentinel(sentinel_t<_Base> __end)
9204 : _M_end(std::move(__end))
9205 { }
9206
9207 friend enumerate_view;
9208
9209 public:
9210 _Sentinel() = default;
9211
9212 constexpr
9213 _Sentinel(_Sentinel<!_Const> __other)
9214 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
9215 : _M_end(std::move(__other._M_end))
9216 { }
9217
9218 constexpr sentinel_t<_Base>
9219 base() const
9220 { return _M_end; }
9221
9222 template<bool _OtherConst>
9223 requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
9224 friend constexpr bool
9225 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
9226 { return __x._M_current == __y._M_end; }
9227
9228 template<bool _OtherConst>
9229 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
9230 friend constexpr range_difference_t<__maybe_const_t<_OtherConst, _Vp>>
9231 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
9232 { return __x._M_current - __y._M_end; }
9233
9234 template<bool _OtherConst>
9235 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
9236 friend constexpr range_difference_t<__maybe_const_t<_OtherConst, _Vp>>
9237 operator-(const _Sentinel& __x, const _Iterator<_OtherConst>& __y)
9238 { return __x._M_end - __y._M_current; }
9239 };
9240
9241 namespace views
9242 {
9243 namespace __detail
9244 {
9245 template<typename _Tp>
9246 concept __can_enumerate_view
9247 = requires { enumerate_view<all_t<_Tp>>(std::declval<_Tp>()); };
9248 }
9249
9250 struct _Enumerate : __adaptor::_RangeAdaptorClosure<_Enumerate>
9251 {
9252 template<viewable_range _Range>
9253 requires __detail::__can_enumerate_view<_Range>
9254 constexpr auto
9255 operator() [[nodiscard]] (_Range&& __r) const
9256 { return enumerate_view<all_t<_Range>>(std::forward<_Range>(__r)); }
9257 };
9258
9259 inline constexpr _Enumerate enumerate;
9260 }
9261#endif // __cpp_lib_ranges_enumerate
9262
9263#ifdef __cpp_lib_ranges_as_const // C++ >= 23
9264 template<view _Vp>
9265 requires input_range<_Vp>
9266 class as_const_view : public view_interface<as_const_view<_Vp>>
9267 {
9268 _Vp _M_base = _Vp();
9269
9270 public:
9271 as_const_view() requires default_initializable<_Vp> = default;
9272
9273 constexpr explicit
9274 as_const_view(_Vp __base)
9275 noexcept(is_nothrow_move_constructible_v<_Vp>)
9276 : _M_base(std::move(__base))
9277 { }
9278
9279 constexpr _Vp
9280 base() const &
9281 noexcept(is_nothrow_copy_constructible_v<_Vp>)
9282 requires copy_constructible<_Vp>
9283 { return _M_base; }
9284
9285 constexpr _Vp
9286 base() &&
9287 noexcept(is_nothrow_move_constructible_v<_Vp>)
9288 { return std::move(_M_base); }
9289
9290 constexpr auto
9291 begin() requires (!__detail::__simple_view<_Vp>)
9292 { return ranges::cbegin(_M_base); }
9293
9294 constexpr auto
9295 begin() const requires range<const _Vp>
9296 { return ranges::cbegin(_M_base); }
9297
9298 constexpr auto
9299 end() requires (!__detail::__simple_view<_Vp>)
9300 { return ranges::cend(_M_base); }
9301
9302 constexpr auto
9303 end() const requires range<const _Vp>
9304 { return ranges::cend(_M_base); }
9305
9306 constexpr auto
9307 size() requires sized_range<_Vp>
9308 { return ranges::size(_M_base); }
9309
9310 constexpr auto
9311 size() const requires sized_range<const _Vp>
9312 { return ranges::size(_M_base); }
9313 };
9314
9315 template<typename _Range>
9316 as_const_view(_Range&&) -> as_const_view<views::all_t<_Range>>;
9317
9318 template<typename _Tp>
9319 inline constexpr bool enable_borrowed_range<as_const_view<_Tp>>
9320 = enable_borrowed_range<_Tp>;
9321
9322 namespace views
9323 {
9324 namespace __detail
9325 {
9326 template<typename _Tp>
9327 inline constexpr bool __is_ref_view = false;
9328
9329 template<typename _Range>
9330 inline constexpr bool __is_ref_view<ref_view<_Range>> = true;
9331
9332 template<typename _Range>
9333 concept __can_as_const_view = requires { as_const_view(std::declval<_Range>()); };
9334 }
9335
9336 struct _AsConst : __adaptor::_RangeAdaptorClosure<_AsConst>
9337 {
9338 template<viewable_range _Range>
9339 constexpr auto
9340 operator()(_Range&& __r) const
9341 noexcept(noexcept(as_const_view(std::declval<_Range>())))
9342 requires __detail::__can_as_const_view<_Range>
9343 {
9344 using _Tp = remove_cvref_t<_Range>;
9345 using element_type = remove_reference_t<range_reference_t<_Range>>;
9346 if constexpr (constant_range<views::all_t<_Range>>)
9347 return views::all(std::forward<_Range>(__r));
9348 else if constexpr (__detail::__is_empty_view<_Tp>)
9349 return views::empty<const element_type>;
9350 else if constexpr (std::__detail::__is_span<_Tp>)
9351 return span<const element_type, _Tp::extent>(std::forward<_Range>(__r));
9352 else if constexpr (__detail::__is_ref_view<_Tp>
9353 && constant_range<const element_type>)
9354 return ref_view(static_cast<const element_type&>
9355 (std::forward<_Range>(__r).base()));
9356 else if constexpr (is_lvalue_reference_v<_Range>
9357 && constant_range<const _Tp>
9358 && !view<_Tp>)
9359 return ref_view(static_cast<const _Tp&>(__r));
9360 else
9361 return as_const_view(std::forward<_Range>(__r));
9362 }
9363 };
9364
9365 inline constexpr _AsConst as_const;
9366 }
9367#endif // __cpp_lib_as_const
9368} // namespace ranges
9369
9370 namespace views = ranges::views;
9371
9372#if __cpp_lib_ranges_to_container // C++ >= 23
9373namespace ranges
9374{
9375/// @cond undocumented
9376namespace __detail
9377{
9378 template<typename _Container>
9379 constexpr bool __reservable_container
9380 = sized_range<_Container>
9381 && requires(_Container& __c, range_size_t<_Container> __n) {
9382 __c.reserve(__n);
9383 { __c.capacity() } -> same_as<decltype(__n)>;
9384 { __c.max_size() } -> same_as<decltype(__n)>;
9385 };
9386
9387 template<typename _Cont, typename _Range>
9388 constexpr bool __toable = requires {
9389 requires (!input_range<_Cont>
9390 || convertible_to<range_reference_t<_Range>,
9391 range_value_t<_Cont>>);
9392 };
9393} // namespace __detail
9394/// @endcond
9395
9396 /// Convert a range to a container.
9397 /**
9398 * @tparam _Cont A container type.
9399 * @param __r A range that models the `input_range` concept.
9400 * @param __args... Arguments to pass to the container constructor.
9401 * @since C++23
9402 *
9403 * This function converts a range to the `_Cont` type.
9404 *
9405 * For example, `std::ranges::to<std::vector<int>>(some_view)`
9406 * will convert the view to `std::vector<int>`.
9407 *
9408 * Additional constructor arguments for the container can be supplied after
9409 * the input range argument, e.g.
9410 * `std::ranges::to<std::vector<int, Alloc<int>>>(a_range, an_allocator)`.
9411 */
9412 template<typename _Cont, input_range _Rg, typename... _Args>
9413 requires (!view<_Cont>)
9414 constexpr _Cont
9415 to [[nodiscard]] (_Rg&& __r, _Args&&... __args)
9416 {
9417 static_assert(!is_const_v<_Cont> && !is_volatile_v<_Cont>);
9418 static_assert(is_class_v<_Cont>);
9419
9420 if constexpr (__detail::__toable<_Cont, _Rg>)
9421 {
9422 if constexpr (constructible_from<_Cont, _Rg, _Args...>)
9423 return _Cont(std::forward<_Rg>(__r),
9424 std::forward<_Args>(__args)...);
9425 else if constexpr (constructible_from<_Cont, from_range_t, _Rg, _Args...>)
9426 return _Cont(from_range, std::forward<_Rg>(__r),
9427 std::forward<_Args>(__args)...);
9428 else if constexpr (requires { requires common_range<_Rg>;
9429 typename __iter_category_t<iterator_t<_Rg>>;
9430 requires derived_from<__iter_category_t<iterator_t<_Rg>>,
9431 input_iterator_tag>;
9432 requires constructible_from<_Cont, iterator_t<_Rg>,
9433 sentinel_t<_Rg>, _Args...>;
9434 })
9435 return _Cont(ranges::begin(__r), ranges::end(__r),
9436 std::forward<_Args>(__args)...);
9437 else
9438 {
9439 static_assert(constructible_from<_Cont, _Args...>);
9440 _Cont __c(std::forward<_Args>(__args)...);
9441 if constexpr (sized_range<_Rg>
9442 && __detail::__reservable_container<_Cont>)
9443 __c.reserve(static_cast<range_size_t<_Cont>>(ranges::size(__r)));
9444 // _GLIBCXX_RESOLVE_LIB_DEFECTS
9445 // 4016. container-insertable checks do not match what
9446 // container-inserter does
9447 auto __it = ranges::begin(__r);
9448 const auto __sent = ranges::end(__r);
9449 while (__it != __sent)
9450 {
9451 if constexpr (requires { __c.emplace_back(*__it); })
9452 __c.emplace_back(*__it);
9453 else if constexpr (requires { __c.push_back(*__it); })
9454 __c.push_back(*__it);
9455 else if constexpr (requires { __c.emplace(__c.end(), *__it); })
9456 __c.emplace(__c.end(), *__it);
9457 else
9458 __c.insert(__c.end(), *__it);
9459 ++__it;
9460 }
9461 return __c;
9462 }
9463 }
9464 else
9465 {
9466 static_assert(input_range<range_reference_t<_Rg>>);
9467 // _GLIBCXX_RESOLVE_LIB_DEFECTS
9468 // 3984. ranges::to's recursion branch may be ill-formed
9469 return ranges::to<_Cont>(ref_view(__r) | views::transform(
9470 []<typename _Elt>(_Elt&& __elem) {
9471 using _ValT = range_value_t<_Cont>;
9472 return ranges::to<_ValT>(std::forward<_Elt>(__elem));
9473 }), std::forward<_Args>(__args)...);
9474 }
9475 }
9476
9477/// @cond undocumented
9478namespace __detail
9479{
9480 template<typename _Rg>
9481 struct _InputIter
9482 {
9483 using iterator_category = input_iterator_tag;
9484 using value_type = range_value_t<_Rg>;
9485 using difference_type = ptrdiff_t;
9486 using pointer = add_pointer_t<range_reference_t<_Rg>>;
9487 using reference = range_reference_t<_Rg>;
9488 reference operator*() const;
9489 pointer operator->() const;
9490 _InputIter& operator++();
9491 _InputIter operator++(int);
9492 bool operator==(const _InputIter&) const;
9493 };
9494
9495 template<template<typename...> typename _Cont, input_range _Rg,
9496 typename... _Args>
9497 using _DeduceExpr1
9498 = decltype(_Cont(std::declval<_Rg>(), std::declval<_Args>()...));
9499
9500 template<template<typename...> typename _Cont, input_range _Rg,
9501 typename... _Args>
9502 using _DeduceExpr2
9503 = decltype(_Cont(from_range, std::declval<_Rg>(),
9504 std::declval<_Args>()...));
9505
9506 template<template<typename...> typename _Cont, input_range _Rg,
9507 typename... _Args>
9508 using _DeduceExpr3
9509 = decltype(_Cont(std::declval<_InputIter<_Rg>>(),
9510 std::declval<_InputIter<_Rg>>(),
9511 std::declval<_Args>()...));
9512
9513} // namespace __detail
9514/// @endcond
9515
9516 template<template<typename...> typename _Cont, input_range _Rg,
9517 typename... _Args>
9518 constexpr auto
9519 to [[nodiscard]] (_Rg&& __r, _Args&&... __args)
9520 {
9521 using __detail::_DeduceExpr1;
9522 using __detail::_DeduceExpr2;
9523 using __detail::_DeduceExpr3;
9524 if constexpr (requires { typename _DeduceExpr1<_Cont, _Rg, _Args...>; })
9525 return ranges::to<_DeduceExpr1<_Cont, _Rg, _Args...>>(
9526 std::forward<_Rg>(__r), std::forward<_Args>(__args)...);
9527 else if constexpr (requires { typename _DeduceExpr2<_Cont, _Rg, _Args...>; })
9528 return ranges::to<_DeduceExpr2<_Cont, _Rg, _Args...>>(
9529 std::forward<_Rg>(__r), std::forward<_Args>(__args)...);
9530 else if constexpr (requires { typename _DeduceExpr3<_Cont, _Rg, _Args...>; })
9531 return ranges::to<_DeduceExpr3<_Cont, _Rg, _Args...>>(
9532 std::forward<_Rg>(__r), std::forward<_Args>(__args)...);
9533 else
9534 static_assert(false); // Cannot deduce container specialization.
9535 }
9536
9537/// @cond undocumented
9538namespace __detail
9539{
9540 template<typename _Cont>
9541 struct _To
9542 {
9543 template<typename _Range, typename... _Args>
9544 requires requires { ranges::to<_Cont>(std::declval<_Range>(),
9545 std::declval<_Args>()...); }
9546 constexpr auto
9547 operator()(_Range&& __r, _Args&&... __args) const
9548 {
9549 return ranges::to<_Cont>(std::forward<_Range>(__r),
9550 std::forward<_Args>(__args)...);
9551 }
9552 };
9553} // namespace __detail
9554/// @endcond
9555
9556 /// ranges::to adaptor for converting a range to a container type
9557 /**
9558 * @tparam _Cont A container type.
9559 * @param __args... Arguments to pass to the container constructor.
9560 * @since C++23
9561 *
9562 * This range adaptor returns a range adaptor closure object that converts
9563 * a range to the `_Cont` type.
9564 *
9565 * For example, `some_view | std::ranges::to<std::vector<int>>()`
9566 * will convert the view to `std::vector<int>`.
9567 *
9568 * Additional constructor arguments for the container can be supplied, e.g.
9569 * `r | std::ranges::to<std::vector<int, Alloc<int>>>(an_allocator)`.
9570 */
9571 template<typename _Cont, typename... _Args>
9572 requires (!view<_Cont>)
9573 constexpr auto
9574 to [[nodiscard]] (_Args&&... __args)
9575 {
9576 static_assert(!is_const_v<_Cont> && !is_volatile_v<_Cont>);
9577 static_assert(is_class_v<_Cont>);
9578
9579 using __detail::_To;
9580 using views::__adaptor::_Partial;
9581 return _Partial<_To<_Cont>, decay_t<_Args>...>{0, std::forward<_Args>(__args)...};
9582 }
9583
9584/// @cond undocumented
9585namespace __detail
9586{
9587 template<template<typename...> typename _Cont>
9588 struct _To2
9589 {
9590 template<typename _Range, typename... _Args>
9591 requires requires { ranges::to<_Cont>(std::declval<_Range>(),
9592 std::declval<_Args>()...); }
9593 constexpr auto
9594 operator()(_Range&& __r, _Args&&... __args) const
9595 {
9596 return ranges::to<_Cont>(std::forward<_Range>(__r),
9597 std::forward<_Args>(__args)...);
9598 }
9599 };
9600} // namespace __detail
9601/// @endcond
9602
9603 /// ranges::to adaptor for converting a range to a deduced container type.
9604 /**
9605 * @tparam _Cont A container template.
9606 * @param __args... Arguments to pass to the container constructor.
9607 * @since C++23
9608 *
9609 * This range adaptor returns a range adaptor closure object that converts
9610 * a range to a specialization of the `_Cont` class template. The specific
9611 * specialization of `_Cont` to be used is deduced automatically.
9612 *
9613 * For example, `some_view | std::ranges::to<std::vector>(Alloc<int>{})`
9614 * will convert the view to `std::vector<T, Alloc<T>>`, where `T` is the
9615 * view's value type, i.e. `std::ranges::range_value_t<decltype(some_view)>`.
9616 *
9617 * Additional constructor arguments for the container can be supplied, e.g.
9618 * `r | std::ranges::to<std::vector>(an_allocator)`.
9619 */
9620 template<template<typename...> typename _Cont, typename... _Args>
9621 constexpr auto
9622 to [[nodiscard]] (_Args&&... __args)
9623 {
9624 using __detail::_To2;
9625 using views::__adaptor::_Partial;
9626 return _Partial<_To2<_Cont>, decay_t<_Args>...>{0, std::forward<_Args>(__args)...};
9627 }
9628
9629} // namespace ranges
9630#endif // __cpp_lib_ranges_to_container
9631
9632#if __cpp_lib_ranges_concat // C++ >= C++26
9633namespace ranges
9634{
9635 namespace __detail
9636 {
9637 template<typename... _Rs>
9638 using __concat_reference_t = common_reference_t<range_reference_t<_Rs>...>;
9639
9640 template<typename... _Rs>
9641 using __concat_value_t = common_type_t<range_value_t<_Rs>...>;
9642
9643 template<typename... _Rs>
9644 using __concat_rvalue_reference_t
9645 = common_reference_t<range_rvalue_reference_t<_Rs>...>;
9646
9647 template<typename _Ref, typename _RRef, typename _It>
9648 concept __concat_indirectly_readable_impl = requires(const _It __it) {
9649 { *__it } -> convertible_to<_Ref>;
9650 { ranges::iter_move(__it) } -> convertible_to<_RRef>;
9651 };
9652
9653 template<typename... _Rs>
9654 concept __concat_indirectly_readable
9655 = common_reference_with<__concat_reference_t<_Rs...>&&, __concat_value_t<_Rs...>&>
9656 && common_reference_with<__concat_reference_t<_Rs...>&&,
9657 __concat_rvalue_reference_t<_Rs...>&&>
9658 && common_reference_with<__concat_rvalue_reference_t<_Rs...>&&,
9659 __concat_value_t<_Rs...> const&>
9660 && (__concat_indirectly_readable_impl<__concat_reference_t<_Rs...>,
9661 __concat_rvalue_reference_t<_Rs...>,
9662 iterator_t<_Rs>>
9663 && ...);
9664
9665 template<typename... _Rs>
9666 concept __concatable = requires {
9667 typename __concat_reference_t<_Rs...>;
9668 typename __concat_value_t<_Rs...>;
9669 typename __concat_rvalue_reference_t<_Rs...>;
9670 } && __concat_indirectly_readable<_Rs...>;
9671
9672 template<bool _Const, typename _Range, typename... _Rs>
9673 struct __all_but_last_common
9674 {
9675 static inline constexpr bool value
9676 = requires { requires (common_range<__maybe_const_t<_Const, _Range>>
9677 && __all_but_last_common<_Const, _Rs...>::value); };
9678 };
9679
9680 template<bool _Const, typename _Range>
9681 struct __all_but_last_common<_Const, _Range>
9682 { static inline constexpr bool value = true; };
9683
9684 template<bool _Const, typename... _Rs>
9685 concept __concat_is_random_access = __all_random_access<_Const, _Rs...>
9686 && __all_but_last_common<_Const, _Rs...>::value;
9687
9688 template<bool _Const, typename... _Rs>
9689 concept __concat_is_bidirectional = __all_bidirectional<_Const, _Rs...>
9690 && __all_but_last_common<_Const, _Rs...>::value;
9691
9692 template<typename _Range, typename... _Rs>
9693 struct __all_but_first_sized
9694 { static inline constexpr bool value = (sized_range<_Rs> && ...); };
9695 } // namespace __detail
9696
9697 template<input_range... _Vs>
9698 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && __detail::__concatable<_Vs...>
9699 class concat_view : public view_interface<concat_view<_Vs...>>
9700 {
9701 tuple<_Vs...> _M_views;
9702
9703 template<bool _Const> class _Iterator;
9704
9705 public:
9706 constexpr concat_view() = default;
9707
9708 constexpr explicit
9709 concat_view(_Vs... __views)
9710 : _M_views(std::move(__views)...)
9711 { }
9712
9713 constexpr _Iterator<false>
9714 begin() requires (!(__detail::__simple_view<_Vs> && ...))
9715 {
9716 _Iterator<false> __it(this, in_place_index<0>, ranges::begin(std::get<0>(_M_views)));
9717 __it.template _M_satisfy<0>();
9718 return __it;
9719 }
9720
9721 constexpr _Iterator<true>
9722 begin() const requires (range<const _Vs> && ...) && __detail::__concatable<const _Vs...>
9723 {
9724 _Iterator<true> __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 auto
9730 end() requires (!(__detail::__simple_view<_Vs> && ...))
9731 {
9732 constexpr auto __n = sizeof...(_Vs);
9733 if constexpr ((semiregular<iterator_t<_Vs>> && ...)
9734 && common_range<_Vs...[__n - 1]>)
9735 return _Iterator<false>(this, in_place_index<__n - 1>,
9736 ranges::end(std::get<__n - 1>(_M_views)));
9737 else
9738 return default_sentinel;
9739 }
9740
9741 constexpr auto
9742 end() const requires (range<const _Vs> && ...) && __detail::__concatable<const _Vs...>
9743 {
9744 constexpr auto __n = sizeof...(_Vs);
9745 if constexpr ((semiregular<iterator_t<const _Vs>> && ...)
9746 && common_range<const _Vs...[__n - 1]>)
9747 return _Iterator<true>(this, in_place_index<__n - 1>,
9748 ranges::end(std::get<__n - 1>(_M_views)));
9749 else
9750 return default_sentinel;
9751 }
9752
9753 constexpr auto
9754 size() requires (sized_range<_Vs>&&...)
9755 {
9756 return std::apply([](auto... __sizes) {
9757 using _CT = __detail::__make_unsigned_like_t<common_type_t<decltype(__sizes)...>>;
9758 return (_CT(__sizes) + ...);
9759 }, __detail::__tuple_transform(ranges::size, _M_views));
9760 }
9761
9762 constexpr auto
9763 size() const requires (sized_range<const _Vs>&&...)
9764 {
9765 return std::apply([](auto... __sizes) {
9766 using _CT = __detail::__make_unsigned_like_t<common_type_t<decltype(__sizes)...>>;
9767 return (_CT(__sizes) + ...);
9768 }, __detail::__tuple_transform(ranges::size, _M_views));
9769 }
9770 };
9771
9772 template<typename... _Rs>
9773 concat_view(_Rs&&...) -> concat_view<views::all_t<_Rs>...>;
9774
9775 namespace __detail
9776 {
9777 template<bool _Const, typename... _Vs>
9778 struct __concat_view_iter_cat
9779 { };
9780
9781 template<bool _Const, typename... _Vs>
9782 requires __detail::__all_forward<_Const, _Vs...>
9783 struct __concat_view_iter_cat<_Const, _Vs...>
9784 {
9785 static auto
9786 _S_iter_cat()
9787 {
9788 if constexpr (!is_reference_v<__concat_reference_t<__maybe_const_t<_Const, _Vs>...>>)
9789 return input_iterator_tag{};
9790 else
9791 return []<typename... _Cats>(_Cats... __cats) {
9792 if constexpr ((derived_from<_Cats, random_access_iterator_tag> && ...)
9793 && __concat_is_random_access<_Const, _Vs...>)
9794 return random_access_iterator_tag{};
9795 else if constexpr ((derived_from<_Cats, bidirectional_iterator_tag> && ...)
9796 && __concat_is_bidirectional<_Const, _Vs...>)
9797 return bidirectional_iterator_tag{};
9798 else if constexpr ((derived_from<_Cats, forward_iterator_tag> && ...))
9799 return forward_iterator_tag{};
9800 else
9801 return input_iterator_tag{};
9802 }(typename iterator_traits<iterator_t<__maybe_const_t<_Const, _Vs>>>
9803 ::iterator_category{}...);
9804 }
9805 };
9806 }
9807
9808 template<input_range... _Vs>
9809 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && __detail::__concatable<_Vs...>
9810 template<bool _Const>
9811 class concat_view<_Vs...>::_Iterator
9812 : public __detail::__concat_view_iter_cat<_Const, _Vs...>
9813 {
9814 static auto
9815 _S_iter_concept()
9816 {
9817 if constexpr (__detail::__concat_is_random_access<_Const, _Vs...>)
9818 return random_access_iterator_tag{};
9819 else if constexpr (__detail::__concat_is_bidirectional<_Const, _Vs...>)
9820 return bidirectional_iterator_tag{};
9821 else if constexpr (__detail::__all_forward<_Const, _Vs...>)
9822 return forward_iterator_tag{};
9823 else
9824 return input_iterator_tag{};
9825 }
9826
9827 friend concat_view;
9828 friend _Iterator<!_Const>;
9829
9830 public:
9831 // iterator_category defined in __concat_view_iter_cat
9832 using iterator_concept = decltype(_S_iter_concept());
9833 using value_type = __detail::__concat_value_t<__maybe_const_t<_Const, _Vs>...>;
9834 using difference_type = common_type_t<range_difference_t<__maybe_const_t<_Const, _Vs>>...>;
9835
9836 private:
9837 using __base_iter = variant<iterator_t<__maybe_const_t<_Const, _Vs>>...>;
9838
9839 __maybe_const_t<_Const, concat_view>* _M_parent = nullptr;
9840 __base_iter _M_it;
9841
9842 template<size_t _Nm>
9843 constexpr void
9844 _M_satisfy()
9845 {
9846 if constexpr (_Nm < (sizeof...(_Vs) - 1))
9847 {
9848 if (std::get<_Nm>(_M_it) == ranges::end(std::get<_Nm>(_M_parent->_M_views)))
9849 {
9850 _M_it.template emplace<_Nm + 1>(ranges::begin
9851 (std::get<_Nm + 1>(_M_parent->_M_views)));
9852 _M_satisfy<_Nm + 1>();
9853 }
9854 }
9855 }
9856
9857 template<size_t _Nm>
9858 constexpr void
9859 _M_prev()
9860 {
9861 if constexpr (_Nm == 0)
9862 --std::get<0>(_M_it);
9863 else
9864 {
9865 if (std::get<_Nm>(_M_it) == ranges::begin(std::get<_Nm>(_M_parent->_M_views)))
9866 {
9867 _M_it.template emplace<_Nm - 1>(ranges::end
9868 (std::get<_Nm - 1>(_M_parent->_M_views)));
9869 _M_prev<_Nm - 1>();
9870 }
9871 else
9872 --std::get<_Nm>(_M_it);
9873 }
9874 }
9875
9876 template<size_t _Nm>
9877 constexpr void
9878 _M_advance_fwd(difference_type __offset, difference_type __steps)
9879 {
9880 using _Dt = iter_difference_t<variant_alternative_t<_Nm, __base_iter>>;
9881 if constexpr (_Nm == sizeof...(_Vs) - 1)
9882 std::get<_Nm>(_M_it) += static_cast<_Dt>(__steps);
9883 else
9884 {
9885 auto __n_size = ranges::distance(std::get<_Nm>(_M_parent->_M_views));
9886 if (__offset + __steps < __n_size)
9887 std::get<_Nm>(_M_it) += static_cast<_Dt>(__steps);
9888 else
9889 {
9890 _M_it.template emplace<_Nm + 1>(ranges::begin
9891 (std::get<_Nm + 1>(_M_parent->_M_views)));
9892 _M_advance_fwd<_Nm + 1>(0, __offset + __steps - __n_size);
9893 }
9894 }
9895 }
9896
9897 template<size_t _Nm>
9898 constexpr void
9899 _M_advance_bwd(difference_type __offset, difference_type __steps)
9900 {
9901 using _Dt = iter_difference_t<variant_alternative_t<_Nm, __base_iter>>;
9902 if constexpr (_Nm == 0)
9903 std::get<_Nm>(_M_it) -= static_cast<_Dt>(__steps);
9904 else {
9905 if (__offset >= __steps)
9906 std::get<_Nm>(_M_it) -= static_cast<_Dt>(__steps);
9907 else
9908 {
9909 auto __prev_size = ranges::distance(std::get<_Nm - 1>(_M_parent->_M_views));
9910 _M_it.template emplace<_Nm - 1>(ranges::end
9911 (std::get<_Nm - 1>(_M_parent->_M_views)));
9912 _M_advance_bwd<_Nm - 1>(__prev_size, __steps - __offset);
9913 }
9914 }
9915 }
9916
9917 // Invoke the function object __f, which has a call operator with a size_t
9918 // template parameter (corresponding to an index into the pack of views),
9919 // using the runtime value of __index as the template argument.
9920 template<typename _Fp>
9921 static constexpr auto
9922 _S_invoke_with_runtime_index(_Fp&& __f, size_t __index)
9923 {
9924 return [&__f, __index]<size_t _Idx>(this auto&& __self) {
9925 if (_Idx == __index)
9926 return __f.template operator()<_Idx>();
9927 if constexpr (_Idx + 1 < sizeof...(_Vs))
9928 return __self.template operator()<_Idx + 1>();
9929 __builtin_unreachable();
9930 }.template operator()<0>();
9931 }
9932
9933 template<typename _Fp>
9934 constexpr auto
9935 _M_invoke_with_runtime_index(_Fp&& __f)
9936 { return _S_invoke_with_runtime_index(std::forward<_Fp>(__f), _M_it.index()); }
9937
9938 template<typename... _Args>
9939 explicit constexpr
9940 _Iterator(__maybe_const_t<_Const, concat_view>* __parent, _Args&&... __args)
9941 requires constructible_from<__base_iter, _Args&&...>
9942 : _M_parent(__parent), _M_it(std::forward<_Args>(__args)...)
9943 { }
9944
9945 public:
9946 _Iterator() = default;
9947
9948 constexpr
9949 _Iterator(_Iterator<!_Const> __it)
9950 requires _Const && (convertible_to<iterator_t<_Vs>, iterator_t<const _Vs>> && ...)
9951 : _M_parent(__it._M_parent),
9952 _M_it(_S_invoke_with_runtime_index([this, &__it]<size_t _Idx>() {
9953 return __base_iter(in_place_index<_Idx>,
9954 std::get<_Idx>(std::move(__it._M_it)));
9955 }, __it._M_it.index()))
9956 { }
9957
9958 constexpr decltype(auto)
9959 operator*() const
9960 {
9961 __glibcxx_assert(!_M_it.valueless_by_exception());
9962 using reference = __detail::__concat_reference_t<__maybe_const_t<_Const, _Vs>...>;
9963 return std::visit([](auto&& __it) -> reference { return *__it; }, _M_it);
9964 }
9965
9966 constexpr _Iterator&
9967 operator++()
9968 {
9969 _M_invoke_with_runtime_index([this]<size_t _Idx>() {
9970 ++std::get<_Idx>(_M_it);
9971 _M_satisfy<_Idx>();
9972 });
9973 return *this;
9974 }
9975
9976 constexpr void
9977 operator++(int)
9978 { ++*this; }
9979
9980 constexpr _Iterator
9981 operator++(int)
9982 requires __detail::__all_forward<_Const, _Vs...>
9983 {
9984 auto __tmp = *this;
9985 ++*this;
9986 return __tmp;
9987 }
9988
9989 constexpr _Iterator&
9990 operator--()
9991 requires __detail::__concat_is_bidirectional<_Const, _Vs...>
9992 {
9993 __glibcxx_assert(!_M_it.valueless_by_exception());
9994 _M_invoke_with_runtime_index([this]<size_t _Idx>() {
9995 _M_prev<_Idx>();
9996 });
9997 return *this;
9998 }
9999
10000 constexpr _Iterator
10001 operator--(int)
10002 requires __detail::__concat_is_bidirectional<_Const, _Vs...>
10003 {
10004 auto __tmp = *this;
10005 --*this;
10006 return __tmp;
10007 }
10008
10009 constexpr _Iterator&
10010 operator+=(difference_type __n)
10011 requires __detail::__concat_is_random_access<_Const, _Vs...>
10012 {
10013 __glibcxx_assert(!_M_it.valueless_by_exception());
10014 _M_invoke_with_runtime_index([this, __n]<size_t _Idx>() {
10015 auto __begin = ranges::begin(std::get<_Idx>(_M_parent->_M_views));
10016 if (__n > 0)
10017 _M_advance_fwd<_Idx>(std::get<_Idx>(_M_it) - __begin, __n);
10018 else if (__n < 0)
10019 _M_advance_bwd<_Idx>(std::get<_Idx>(_M_it) - __begin, -__n);
10020 });
10021 return *this;
10022 }
10023
10024 constexpr _Iterator&
10025 operator-=(difference_type __n)
10026 requires __detail::__concat_is_random_access<_Const, _Vs...>
10027 {
10028 *this += -__n;
10029 return *this;
10030 }
10031
10032 constexpr decltype(auto)
10033 operator[](difference_type __n) const
10034 requires __detail::__concat_is_random_access<_Const, _Vs...>
10035 { return *((*this) + __n); }
10036
10037 friend constexpr bool
10038 operator==(const _Iterator& __x, const _Iterator& __y)
10039 requires (equality_comparable<iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
10040 {
10041 __glibcxx_assert(!__x._M_it.valueless_by_exception());
10042 __glibcxx_assert(!__y._M_it.valueless_by_exception());
10043 return __x._M_it == __y._M_it;
10044 }
10045
10046 friend constexpr bool
10047 operator==(const _Iterator& __it, default_sentinel_t)
10048 {
10049 __glibcxx_assert(!__it._M_it.valueless_by_exception());
10050 constexpr auto __last_idx = sizeof...(_Vs) - 1;
10051 return (__it._M_it.index() == __last_idx
10052 && (std::get<__last_idx>(__it._M_it)
10053 == ranges::end(std::get<__last_idx>(__it._M_parent->_M_views))));
10054 }
10055
10056 friend constexpr bool
10057 operator<(const _Iterator& __x, const _Iterator& __y)
10058 requires __detail::__all_random_access<_Const, _Vs...>
10059 { return __x._M_it < __y._M_it; }
10060
10061 friend constexpr bool
10062 operator>(const _Iterator& __x, const _Iterator& __y)
10063 requires __detail::__all_random_access<_Const, _Vs...>
10064 { return __x._M_it > __y._M_it; }
10065
10066 friend constexpr bool
10067 operator<=(const _Iterator& __x, const _Iterator& __y)
10068 requires __detail::__all_random_access<_Const, _Vs...>
10069 { return __x._M_it <= __y._M_it; }
10070
10071 friend constexpr bool
10072 operator>=(const _Iterator& __x, const _Iterator& __y)
10073 requires __detail::__all_random_access<_Const, _Vs...>
10074 { return __x._M_it >= __y._M_it; }
10075
10076 friend constexpr auto
10077 operator<=>(const _Iterator& __x, const _Iterator& __y)
10078 requires __detail::__all_random_access<_Const, _Vs...>
10079 && (three_way_comparable<iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
10080 { return __x._M_it <=> __y._M_it; }
10081
10082 friend constexpr _Iterator
10083 operator+(const _Iterator& __it, difference_type __n)
10084 requires __detail::__concat_is_random_access<_Const, _Vs...>
10085 { return auto(__it) += __n; }
10086
10087 friend constexpr _Iterator
10088 operator+(difference_type __n, const _Iterator& __it)
10089 requires __detail::__concat_is_random_access<_Const, _Vs...>
10090 { return __it + __n; }
10091
10092 friend constexpr _Iterator
10093 operator-(const _Iterator& __it, difference_type __n)
10094 requires __detail::__concat_is_random_access<_Const, _Vs...>
10095 { return auto(__it) -= __n; }
10096
10097 friend constexpr difference_type
10098 operator-(const _Iterator& __x, const _Iterator& __y)
10099 requires __detail::__concat_is_random_access<_Const, _Vs...>
10100 {
10101 return _S_invoke_with_runtime_index([&]<size_t _Ix>() -> difference_type {
10102 return _S_invoke_with_runtime_index([&]<size_t _Iy>() -> difference_type {
10103 if constexpr (_Ix > _Iy)
10104 {
10105 auto __dy = ranges::distance(std::get<_Iy>(__y._M_it),
10106 ranges::end(std::get<_Iy>(__y._M_parent
10107 ->_M_views)));
10108 auto __dx = ranges::distance(ranges::begin(std::get<_Ix>(__x._M_parent
10109 ->_M_views)),
10110 std::get<_Ix>(__x._M_it));
10111 difference_type __s = 0;
10112 [&]<size_t _Idx = _Iy + 1>(this auto&& __self) {
10113 if constexpr (_Idx < _Ix)
10114 {
10115 __s += ranges::size(std::get<_Idx>(__x._M_parent->_M_views));
10116 __self.template operator()<_Idx + 1>();
10117 }
10118 }();
10119 return __dy + __s + __dx;
10120 }
10121 else if constexpr (_Ix < _Iy)
10122 return -(__y - __x);
10123 else
10124 return std::get<_Ix>(__x._M_it) - std::get<_Iy>(__y._M_it);
10125 }, __y._M_it.index());
10126 }, __x._M_it.index());
10127 }
10128
10129 friend constexpr difference_type
10130 operator-(const _Iterator& __x, default_sentinel_t)
10131 requires (sized_sentinel_for<sentinel_t<__maybe_const_t<_Const, _Vs>>,
10132 iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
10133 && __detail::__all_but_first_sized<__maybe_const_t<_Const, _Vs>...>::value
10134 {
10135 return _S_invoke_with_runtime_index([&]<size_t _Ix>() -> difference_type {
10136 auto __dx = ranges::distance(std::get<_Ix>(__x._M_it),
10137 ranges::end(std::get<_Ix>(__x._M_parent->_M_views)));
10138 difference_type __s = 0;
10139 [&]<size_t _Idx = _Ix + 1>(this auto&& __self) {
10140 if constexpr (_Idx < sizeof...(_Vs))
10141 {
10142 __s += ranges::size(std::get<_Idx>(__x._M_parent->_M_views));
10143 __self.template operator()<_Idx + 1>();
10144 }
10145 }();
10146 return -(__dx + __s);
10147 }, __x._M_it.index());
10148 }
10149
10150 friend constexpr difference_type
10151 operator-(default_sentinel_t, const _Iterator& __x)
10152 requires (sized_sentinel_for<sentinel_t<__maybe_const_t<_Const, _Vs>>,
10153 iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
10154 && __detail::__all_but_first_sized<__maybe_const_t<_Const, _Vs>...>::value
10155 { return -(__x - default_sentinel); }
10156
10157 friend constexpr decltype(auto)
10158 iter_move(const _Iterator& __it)
10159 {
10160 using _Res = __detail::__concat_rvalue_reference_t<__maybe_const_t<_Const, _Vs>...>;
10161 return std::visit([](const auto& __i) -> _Res {
10162 return ranges::iter_move(__i);
10163 }, __it._M_it);
10164 }
10165
10166 friend constexpr void
10167 iter_swap(const _Iterator& __x, const _Iterator& __y)
10168 requires swappable_with<iter_reference_t<_Iterator>, iter_reference_t<_Iterator>>
10169 && (... && indirectly_swappable<iterator_t<__maybe_const_t<_Const, _Vs>>>)
10170 {
10171 std::visit([&]<typename _Tp, typename _Up>(const _Tp& __it1, const _Up& __it2) {
10172 if constexpr (is_same_v<_Tp, _Up>)
10173 ranges::iter_swap(__it1, __it2);
10174 else
10175 ranges::swap(*__it1, *__it2);
10176 }, __x._M_it, __y._M_it);
10177 }
10178 };
10179
10180 namespace views
10181 {
10182 namespace __detail
10183 {
10184 template<typename... _Ts>
10185 concept __can_concat_view = requires { concat_view(std::declval<_Ts>()...); };
10186 }
10187
10188 struct _Concat
10189 {
10190 template<typename... _Ts>
10191 requires __detail::__can_concat_view<_Ts...>
10192 constexpr auto
10193 operator() [[nodiscard]] (_Ts&&... __ts) const
10194 { return concat_view(std::forward<_Ts>(__ts)...); }
10195
10196 template<input_range _Range>
10197 constexpr auto
10198 operator() [[nodiscard]] (_Range&& __t) const
10199 { return views::all(std::forward<_Range>(__t)); }
10200 };
10201
10202 inline constexpr _Concat concat;
10203 }
10204
10205} // namespace ranges
10206#endif // __cpp_lib_ranges_concat
10207
10208#if __cpp_lib_ranges_cache_latest // C++ >= 26
10209namespace ranges
10210{
10211 template<input_range _Vp>
10212 requires view<_Vp>
10213 class cache_latest_view : public view_interface<cache_latest_view<_Vp>>
10214 {
10215 _Vp _M_base = _Vp();
10216
10217 using __cache_t = __conditional_t<is_reference_v<range_reference_t<_Vp>>,
10218 add_pointer_t<range_reference_t<_Vp>>,
10219 range_reference_t<_Vp>>;
10220 __detail::__non_propagating_cache<__cache_t> _M_cache;
10221
10222 class _Iterator;
10223 class _Sentinel;
10224
10225 public:
10226 cache_latest_view() requires default_initializable<_Vp> = default;
10227
10228 constexpr explicit
10229 cache_latest_view(_Vp __base)
10230 : _M_base(std::move(__base))
10231 { }
10232
10233 constexpr _Vp
10234 base() const & requires copy_constructible<_Vp>
10235 { return _M_base; }
10236
10237 constexpr _Vp
10238 base() &&
10239 { return std::move(_M_base); }
10240
10241 constexpr auto
10242 begin()
10243 { return _Iterator(*this); }
10244
10245 constexpr auto
10246 end()
10247 { return _Sentinel(*this); }
10248
10249 constexpr auto
10250 size() requires sized_range<_Vp>
10251 { return ranges::size(_M_base); }
10252
10253 constexpr auto
10254 size() const requires sized_range<const _Vp>
10255 { return ranges::size(_M_base); }
10256 };
10257
10258 template<typename _Range>
10259 cache_latest_view(_Range&&) -> cache_latest_view<views::all_t<_Range>>;
10260
10261 template<input_range _Vp>
10262 requires view<_Vp>
10263 class cache_latest_view<_Vp>::_Iterator
10264 {
10265 cache_latest_view* _M_parent;
10266 iterator_t<_Vp> _M_current;
10267
10268 constexpr explicit
10269 _Iterator(cache_latest_view& __parent)
10270 : _M_parent(std::__addressof(__parent)),
10271 _M_current(ranges::begin(__parent._M_base))
10272 { }
10273
10274 friend class cache_latest_view;
10275
10276 public:
10277 using difference_type = range_difference_t<_Vp>;
10278 using value_type = range_value_t<_Vp>;
10279 using iterator_concept = input_iterator_tag;
10280
10281 _Iterator(_Iterator&&) = default;
10282
10283 _Iterator&
10284 operator=(_Iterator&&) = default;
10285
10286 constexpr iterator_t<_Vp>
10287 base() &&
10288 { return std::move(_M_current); }
10289
10290 constexpr const iterator_t<_Vp>&
10291 base() const & noexcept
10292 { return _M_current; }
10293
10294 constexpr range_reference_t<_Vp>&
10295 operator*() const
10296 {
10297 if constexpr (is_reference_v<range_reference_t<_Vp>>)
10298 {
10299 if (!_M_parent->_M_cache)
10300 _M_parent->_M_cache = std::__addressof(__detail::__as_lvalue(*_M_current));
10301 return **_M_parent->_M_cache;
10302 }
10303 else
10304 {
10305 if (!_M_parent->_M_cache)
10306 _M_parent->_M_cache._M_emplace_deref(_M_current);
10307 return *_M_parent->_M_cache;
10308 }
10309 }
10310
10311 constexpr _Iterator&
10312 operator++()
10313 {
10314 _M_parent->_M_cache._M_reset();
10315 ++_M_current;
10316 return *this;
10317 }
10318
10319 constexpr void
10320 operator++(int)
10321 { ++*this; }
10322
10323 friend constexpr range_rvalue_reference_t<_Vp>
10324 iter_move(const _Iterator& __i)
10325 noexcept(noexcept(ranges::iter_move(__i._M_current)))
10326 { return ranges::iter_move(__i._M_current); }
10327
10328 friend constexpr void
10329 iter_swap(const _Iterator& __x, const _Iterator& __y)
10330 noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
10331 requires indirectly_swappable<iterator_t<_Vp>>
10332 { ranges::iter_swap(__x._M_current, __y._M_current); }
10333 };
10334
10335 template<input_range _Vp>
10336 requires view<_Vp>
10337 class cache_latest_view<_Vp>::_Sentinel
10338 {
10339 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
10340
10341 constexpr explicit
10342 _Sentinel(cache_latest_view& __parent)
10343 : _M_end(ranges::end(__parent._M_base))
10344 { }
10345
10346 friend class cache_latest_view;
10347
10348 public:
10349 _Sentinel() = default;
10350
10351 constexpr sentinel_t<_Vp>
10352 base() const
10353 { return _M_end; }
10354
10355 friend constexpr bool
10356 operator==(const _Iterator& __x, const _Sentinel& __y)
10357 { return __x._M_current == __y._M_end; }
10358
10359 friend constexpr range_difference_t<_Vp>
10360 operator-(const _Iterator& __x, const _Sentinel& __y)
10361 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
10362 { return __x._M_current - __y._M_end; }
10363
10364 friend constexpr range_difference_t<_Vp>
10365 operator-(const _Sentinel& __x, const _Iterator& __y)
10366 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
10367 { return __x._M_end - __y._M_current; }
10368 };
10369
10370 namespace views
10371 {
10372 namespace __detail
10373 {
10374 template<typename _Tp>
10375 concept __can_cache_latest = requires { cache_latest_view(std::declval<_Tp>()); };
10376 }
10377
10378 struct _CacheLatest : __adaptor::_RangeAdaptorClosure<_CacheLatest>
10379 {
10380 template<viewable_range _Range>
10381 requires __detail::__can_cache_latest<_Range>
10382 constexpr auto
10383 operator() [[nodiscard]] (_Range&& __r) const
10384 { return cache_latest_view(std::forward<_Range>(__r)); }
10385
10386 static constexpr bool _S_has_simple_call_op = true;
10387 };
10388
10389 inline constexpr _CacheLatest cache_latest;
10390 }
10391} // namespace ranges
10392#endif // __cpp_lib_ranges_cache_latest
10393
10394#if __cpp_lib_ranges_to_input // C++ >= 26
10395namespace ranges
10396{
10397 template<input_range _Vp>
10398 requires view<_Vp>
10399 class to_input_view : public view_interface<to_input_view<_Vp>>
10400 {
10401 _Vp _M_base = _Vp();
10402
10403 template<bool _Const>
10404 class _Iterator;
10405
10406 public:
10407 to_input_view() requires default_initializable<_Vp> = default;
10408
10409 constexpr explicit
10410 to_input_view(_Vp __base)
10411 : _M_base(std::move(__base))
10412 { }
10413
10414 constexpr _Vp
10415 base() const & requires copy_constructible<_Vp>
10416 { return _M_base; }
10417
10418 constexpr _Vp
10419 base() &&
10420 { return std::move(_M_base); }
10421
10422 constexpr auto
10423 begin() requires (!__detail::__simple_view<_Vp>)
10424 { return _Iterator<false>(ranges::begin(_M_base)); }
10425
10426 constexpr auto
10427 begin() const requires range<const _Vp>
10428 { return _Iterator<true>(ranges::begin(_M_base)); }
10429
10430 constexpr auto
10431 end() requires (!__detail::__simple_view<_Vp>)
10432 { return ranges::end(_M_base); }
10433
10434 constexpr auto
10435 end() const requires range<const _Vp>
10436 { return ranges::end(_M_base); }
10437
10438 constexpr auto
10439 size() requires sized_range<_Vp>
10440 { return ranges::size(_M_base); }
10441
10442 constexpr auto
10443 size() const requires sized_range<const _Vp>
10444 { return ranges::size(_M_base); }
10445 };
10446
10447 template<typename _Range>
10448 to_input_view(_Range&&) -> to_input_view<views::all_t<_Range>>;
10449
10450 template<input_range _Vp>
10451 requires view<_Vp>
10452 template<bool _Const>
10453 class to_input_view<_Vp>::_Iterator
10454 {
10455 using _Base = __maybe_const_t<_Const, _Vp>;
10456
10457 iterator_t<_Base> _M_current = iterator_t<_Base>();
10458
10459 constexpr explicit
10460 _Iterator(iterator_t<_Base> __current)
10461 : _M_current(std::move(__current))
10462 { }
10463
10464 friend to_input_view;
10465 friend _Iterator<!_Const>;
10466
10467 public:
10468 using difference_type = range_difference_t<_Base>;
10469 using value_type = range_value_t<_Base>;
10470 using iterator_concept = input_iterator_tag;
10471
10472 _Iterator() requires default_initializable<iterator_t<_Base>> = default;
10473
10474 _Iterator(_Iterator&&) = default;
10475 _Iterator& operator=(_Iterator&&) = default;
10476
10477 constexpr
10478 _Iterator(_Iterator<!_Const> __i)
10479 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
10480 : _M_current(std::move(__i._M_current))
10481 { }
10482
10483 constexpr iterator_t<_Base>
10484 base() &&
10485 { return std::move(_M_current); }
10486
10487 constexpr const iterator_t<_Base>&
10488 base() const & noexcept
10489 { return _M_current; }
10490
10491 constexpr decltype(auto)
10492 operator*() const
10493 { return *_M_current; }
10494
10495 constexpr _Iterator&
10496 operator++()
10497 {
10498 ++_M_current;
10499 return *this;
10500 }
10501
10502 constexpr void
10503 operator++(int)
10504 { ++*this; }
10505
10506 friend constexpr bool
10507 operator==(const _Iterator& __x, const sentinel_t<_Base>& __y)
10508 { return __x._M_current == __y; }
10509
10510 friend constexpr difference_type
10511 operator-(const sentinel_t<_Base>& __y, const _Iterator& __x)
10512 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
10513 { return __y - __x._M_current; }
10514
10515 friend constexpr difference_type
10516 operator-(const _Iterator& __x, const sentinel_t<_Base>& __y)
10517 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
10518 { return __x._M_current - __y; }
10519
10520 friend constexpr range_rvalue_reference_t<_Base>
10521 iter_move(const _Iterator& __i)
10522 noexcept(noexcept(ranges::iter_move(__i._M_current)))
10523 { return ranges::iter_move(__i._M_current); }
10524
10525 friend constexpr void
10526 iter_swap(const _Iterator& __x, const _Iterator& __y)
10527 noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
10528 requires indirectly_swappable<iterator_t<_Base>>
10529 { ranges::iter_swap(__x._M_current, __y._M_current); }
10530 };
10531
10532 namespace views
10533 {
10534 namespace __detail
10535 {
10536 template<typename _Tp>
10537 concept __can_to_input = requires { to_input_view(std::declval<_Tp>()); };
10538 }
10539
10540 struct _ToInput : __adaptor::_RangeAdaptorClosure<_ToInput>
10541 {
10542 template<viewable_range _Range>
10543 requires __detail::__can_to_input<_Range>
10544 constexpr auto
10545 operator() [[nodiscard]] (_Range&& __r) const
10546 {
10547 if constexpr (input_range<_Range>
10548 && !common_range<_Range>
10549 && !forward_range<_Range>)
10550 return views::all(std::forward<_Range>(__r));
10551 else
10552 return to_input_view(std::forward<_Range>(__r));
10553 }
10554
10555 static constexpr bool _S_has_simple_call_op = true;
10556 };
10557
10558 inline constexpr _ToInput to_input;
10559 }
10560} // namespace ranges
10561#endif // __cpp_lib_ranges_to_input
10562
10563_GLIBCXX_END_NAMESPACE_VERSION
10564} // namespace std
10565#endif // library concepts
10566#endif // C++2a
10567#endif /* _GLIBCXX_RANGES */