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