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