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