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