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