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