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