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