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