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