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