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