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