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