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