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 using _Base = transform_view::_Base<_Const>;
1753 using _Res = invoke_result_t<_Fp&, range_reference_t<_Base>>;
1754 if constexpr (is_lvalue_reference_v<_Res>)
1755 {
1756 using _Cat
1757 = typename iterator_traits<iterator_t<_Base>>::iterator_category;
1758 if constexpr (derived_from<_Cat, contiguous_iterator_tag>)
1759 return random_access_iterator_tag{};
1760 else
1761 return _Cat{};
1762 }
1763 else
1764 return input_iterator_tag{};
1765 }
1766 public:
1767 using iterator_category = decltype(_S_iter_cat());
1768 };
1769
1770 template<bool _Const>
1771 struct _Sentinel;
1772
1773 template<bool _Const>
1774 struct _Iterator : __iter_cat<_Const>
1775 {
1776 private:
1777 using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
1778 using _Base = transform_view::_Base<_Const>;
1779
1780 static auto
1781 _S_iter_concept()
1782 {
1783 if constexpr (random_access_range<_Base>)
1784 return random_access_iterator_tag{};
1785 else if constexpr (bidirectional_range<_Base>)
1786 return bidirectional_iterator_tag{};
1787 else if constexpr (forward_range<_Base>)
1788 return forward_iterator_tag{};
1789 else
1790 return input_iterator_tag{};
1791 }
1792
1793 using _Base_iter = iterator_t<_Base>;
1794
1795 _Base_iter _M_current = _Base_iter();
1796 _Parent* _M_parent = nullptr;
1797
1798 public:
1799 using iterator_concept = decltype(_S_iter_concept());
1800 // iterator_category defined in __transform_view_iter_cat
1801 using value_type
1802 = remove_cvref_t<invoke_result_t<_Fp&, range_reference_t<_Base>>>;
1803 using difference_type = range_difference_t<_Base>;
1804
1805 _Iterator() requires default_initializable<_Base_iter> = default;
1806
1807 constexpr
1808 _Iterator(_Parent* __parent, _Base_iter __current)
1809 : _M_current(std::move(__current)),
1810 _M_parent(__parent)
1811 { }
1812
1813 constexpr
1814 _Iterator(_Iterator<!_Const> __i)
1815 requires _Const
1816 && convertible_to<iterator_t<_Vp>, _Base_iter>
1817 : _M_current(std::move(__i._M_current)), _M_parent(__i._M_parent)
1818 { }
1819
1820 constexpr const _Base_iter&
1821 base() const & noexcept
1822 { return _M_current; }
1823
1824 constexpr _Base_iter
1825 base() &&
1826 { return std::move(_M_current); }
1827
1828 constexpr decltype(auto)
1829 operator*() const
1830 noexcept(noexcept(std::__invoke(*_M_parent->_M_fun, *_M_current)))
1831 { return std::__invoke(*_M_parent->_M_fun, *_M_current); }
1832
1833 constexpr _Iterator&
1834 operator++()
1835 {
1836 ++_M_current;
1837 return *this;
1838 }
1839
1840 constexpr void
1841 operator++(int)
1842 { ++_M_current; }
1843
1844 constexpr _Iterator
1845 operator++(int) requires forward_range<_Base>
1846 {
1847 auto __tmp = *this;
1848 ++*this;
1849 return __tmp;
1850 }
1851
1852 constexpr _Iterator&
1853 operator--() requires bidirectional_range<_Base>
1854 {
1855 --_M_current;
1856 return *this;
1857 }
1858
1859 constexpr _Iterator
1860 operator--(int) requires bidirectional_range<_Base>
1861 {
1862 auto __tmp = *this;
1863 --*this;
1864 return __tmp;
1865 }
1866
1867 constexpr _Iterator&
1868 operator+=(difference_type __n) requires random_access_range<_Base>
1869 {
1870 _M_current += __n;
1871 return *this;
1872 }
1873
1874 constexpr _Iterator&
1875 operator-=(difference_type __n) requires random_access_range<_Base>
1876 {
1877 _M_current -= __n;
1878 return *this;
1879 }
1880
1881 constexpr decltype(auto)
1882 operator[](difference_type __n) const
1883 requires random_access_range<_Base>
1884 { return std::__invoke(*_M_parent->_M_fun, _M_current[__n]); }
1885
1886 friend constexpr bool
1887 operator==(const _Iterator& __x, const _Iterator& __y)
1888 requires equality_comparable<_Base_iter>
1889 { return __x._M_current == __y._M_current; }
1890
1891 friend constexpr bool
1892 operator<(const _Iterator& __x, const _Iterator& __y)
1893 requires random_access_range<_Base>
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 __y < __x; }
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 !(__x < __y); }
1910
1911#ifdef __cpp_lib_three_way_comparison
1912 friend constexpr auto
1913 operator<=>(const _Iterator& __x, const _Iterator& __y)
1914 requires random_access_range<_Base>
1915 && three_way_comparable<_Base_iter>
1916 { return __x._M_current <=> __y._M_current; }
1917#endif
1918
1919 friend constexpr _Iterator
1920 operator+(_Iterator __i, difference_type __n)
1921 requires random_access_range<_Base>
1922 { return {__i._M_parent, __i._M_current + __n}; }
1923
1924 friend constexpr _Iterator
1925 operator+(difference_type __n, _Iterator __i)
1926 requires random_access_range<_Base>
1927 { return {__i._M_parent, __i._M_current + __n}; }
1928
1929 friend constexpr _Iterator
1930 operator-(_Iterator __i, difference_type __n)
1931 requires random_access_range<_Base>
1932 { return {__i._M_parent, __i._M_current - __n}; }
1933
1934 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1935 // 3483. transform_view::iterator's difference is overconstrained
1936 friend constexpr difference_type
1937 operator-(const _Iterator& __x, const _Iterator& __y)
1938 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
1939 { return __x._M_current - __y._M_current; }
1940
1941 friend constexpr decltype(auto)
1942 iter_move(const _Iterator& __i) noexcept(noexcept(*__i))
1943 {
1944 if constexpr (is_lvalue_reference_v<decltype(*__i)>)
1945 return std::move(*__i);
1946 else
1947 return *__i;
1948 }
1949
1950 friend _Iterator<!_Const>;
1951 template<bool> friend struct _Sentinel;
1952 };
1953
1954 template<bool _Const>
1955 struct _Sentinel
1956 {
1957 private:
1958 using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
1959 using _Base = transform_view::_Base<_Const>;
1960
1961 template<bool _Const2>
1962 constexpr auto
1963 __distance_from(const _Iterator<_Const2>& __i) const
1964 { return _M_end - __i._M_current; }
1965
1966 template<bool _Const2>
1967 constexpr bool
1968 __equal(const _Iterator<_Const2>& __i) const
1969 { return __i._M_current == _M_end; }
1970
1971 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
1972
1973 public:
1974 _Sentinel() = default;
1975
1976 constexpr explicit
1977 _Sentinel(sentinel_t<_Base> __end)
1978 : _M_end(__end)
1979 { }
1980
1981 constexpr
1982 _Sentinel(_Sentinel<!_Const> __i)
1983 requires _Const
1984 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
1985 : _M_end(std::move(__i._M_end))
1986 { }
1987
1988 constexpr sentinel_t<_Base>
1989 base() const
1990 { return _M_end; }
1991
1992 template<bool _Const2>
1993 requires sentinel_for<sentinel_t<_Base>,
1994 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
1995 friend constexpr bool
1996 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
1997 { return __y.__equal(__x); }
1998
1999 template<bool _Const2,
2000 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
2001 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2002 friend constexpr range_difference_t<_Base2>
2003 operator-(const _Iterator<_Const2>& __x, const _Sentinel& __y)
2004 { return -__y.__distance_from(__x); }
2005
2006 template<bool _Const2,
2007 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
2008 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2009 friend constexpr range_difference_t<_Base2>
2010 operator-(const _Sentinel& __y, const _Iterator<_Const2>& __x)
2011 { return __y.__distance_from(__x); }
2012
2013 friend _Sentinel<!_Const>;
2014 };
2015
2016 _Vp _M_base = _Vp();
2017 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
2018
2019 public:
2020 transform_view() requires (default_initializable<_Vp>
2021 && default_initializable<_Fp>)
2022 = default;
2023
2024 constexpr
2025 transform_view(_Vp __base, _Fp __fun)
2026 : _M_base(std::move(__base)), _M_fun(std::move(__fun))
2027 { }
2028
2029 constexpr _Vp
2030 base() const& requires copy_constructible<_Vp>
2031 { return _M_base ; }
2032
2033 constexpr _Vp
2034 base() &&
2035 { return std::move(_M_base); }
2036
2037 constexpr _Iterator<false>
2038 begin()
2039 { return _Iterator<false>{this, ranges::begin(_M_base)}; }
2040
2041 constexpr _Iterator<true>
2042 begin() const
2043 requires range<const _Vp>
2044 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2045 { return _Iterator<true>{this, ranges::begin(_M_base)}; }
2046
2047 constexpr _Sentinel<false>
2048 end()
2049 { return _Sentinel<false>{ranges::end(_M_base)}; }
2050
2051 constexpr _Iterator<false>
2052 end() requires common_range<_Vp>
2053 { return _Iterator<false>{this, ranges::end(_M_base)}; }
2054
2055 constexpr _Sentinel<true>
2056 end() const
2057 requires range<const _Vp>
2058 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2059 { return _Sentinel<true>{ranges::end(_M_base)}; }
2060
2061 constexpr _Iterator<true>
2062 end() const
2063 requires common_range<const _Vp>
2064 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2065 { return _Iterator<true>{this, ranges::end(_M_base)}; }
2066
2067 constexpr auto
2068 size() requires sized_range<_Vp>
2069 { return ranges::size(_M_base); }
2070
2071 constexpr auto
2072 size() const requires sized_range<const _Vp>
2073 { return ranges::size(_M_base); }
2074 };
2075
2076 template<typename _Range, typename _Fp>
2077 transform_view(_Range&&, _Fp) -> transform_view<views::all_t<_Range>, _Fp>;
2078
2079 namespace views
2080 {
2081 namespace __detail
2082 {
2083 template<typename _Range, typename _Fp>
2084 concept __can_transform_view
2085 = requires { transform_view(std::declval<_Range>(), std::declval<_Fp>()); };
2086 } // namespace __detail
2087
2088 struct _Transform : __adaptor::_RangeAdaptor<_Transform>
2089 {
2090 template<viewable_range _Range, typename _Fp>
2091 requires __detail::__can_transform_view<_Range, _Fp>
2092 constexpr auto
2093 operator() [[nodiscard]] (_Range&& __r, _Fp&& __f) const
2094 {
2095 return transform_view(std::forward<_Range>(__r), std::forward<_Fp>(__f));
2096 }
2097
2098 using _RangeAdaptor<_Transform>::operator();
2099 static constexpr int _S_arity = 2;
2100 static constexpr bool _S_has_simple_extra_args = true;
2101 };
2102
2103 inline constexpr _Transform transform;
2104 } // namespace views
2105
2106 template<view _Vp>
2107 class take_view : public view_interface<take_view<_Vp>>
2108 {
2109 private:
2110 template<bool _Const>
2111 using _CI = counted_iterator<
2112 iterator_t<__detail::__maybe_const_t<_Const, _Vp>>>;
2113
2114 template<bool _Const>
2115 struct _Sentinel
2116 {
2117 private:
2118 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2119 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2120
2121 public:
2122 _Sentinel() = default;
2123
2124 constexpr explicit
2125 _Sentinel(sentinel_t<_Base> __end)
2126 : _M_end(__end)
2127 { }
2128
2129 constexpr
2130 _Sentinel(_Sentinel<!_Const> __s)
2131 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2132 : _M_end(std::move(__s._M_end))
2133 { }
2134
2135 constexpr sentinel_t<_Base>
2136 base() const
2137 { return _M_end; }
2138
2139 friend constexpr bool
2140 operator==(const _CI<_Const>& __y, const _Sentinel& __x)
2141 { return __y.count() == 0 || __y.base() == __x._M_end; }
2142
2143 template<bool _OtherConst = !_Const,
2144 typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
2145 requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2146 friend constexpr bool
2147 operator==(const _CI<_OtherConst>& __y, const _Sentinel& __x)
2148 { return __y.count() == 0 || __y.base() == __x._M_end; }
2149
2150 friend _Sentinel<!_Const>;
2151 };
2152
2153 _Vp _M_base = _Vp();
2154 range_difference_t<_Vp> _M_count = 0;
2155
2156 public:
2157 take_view() requires default_initializable<_Vp> = default;
2158
2159 constexpr
2160 take_view(_Vp __base, range_difference_t<_Vp> __count)
2161 : _M_base(std::move(__base)), _M_count(std::move(__count))
2162 { }
2163
2164 constexpr _Vp
2165 base() const& requires copy_constructible<_Vp>
2166 { return _M_base; }
2167
2168 constexpr _Vp
2169 base() &&
2170 { return std::move(_M_base); }
2171
2172 constexpr auto
2173 begin() requires (!__detail::__simple_view<_Vp>)
2174 {
2175 if constexpr (sized_range<_Vp>)
2176 {
2177 if constexpr (random_access_range<_Vp>)
2178 return ranges::begin(_M_base);
2179 else
2180 {
2181 auto __sz = size();
2182 return counted_iterator(ranges::begin(_M_base), __sz);
2183 }
2184 }
2185 else
2186 return counted_iterator(ranges::begin(_M_base), _M_count);
2187 }
2188
2189 constexpr auto
2190 begin() const requires range<const _Vp>
2191 {
2192 if constexpr (sized_range<const _Vp>)
2193 {
2194 if constexpr (random_access_range<const _Vp>)
2195 return ranges::begin(_M_base);
2196 else
2197 {
2198 auto __sz = size();
2199 return counted_iterator(ranges::begin(_M_base), __sz);
2200 }
2201 }
2202 else
2203 return counted_iterator(ranges::begin(_M_base), _M_count);
2204 }
2205
2206 constexpr auto
2207 end() requires (!__detail::__simple_view<_Vp>)
2208 {
2209 if constexpr (sized_range<_Vp>)
2210 {
2211 if constexpr (random_access_range<_Vp>)
2212 return ranges::begin(_M_base) + size();
2213 else
2214 return default_sentinel;
2215 }
2216 else
2217 return _Sentinel<false>{ranges::end(_M_base)};
2218 }
2219
2220 constexpr auto
2221 end() const requires range<const _Vp>
2222 {
2223 if constexpr (sized_range<const _Vp>)
2224 {
2225 if constexpr (random_access_range<const _Vp>)
2226 return ranges::begin(_M_base) + size();
2227 else
2228 return default_sentinel;
2229 }
2230 else
2231 return _Sentinel<true>{ranges::end(_M_base)};
2232 }
2233
2234 constexpr auto
2235 size() requires sized_range<_Vp>
2236 {
2237 auto __n = ranges::size(_M_base);
2238 return std::min(__n, static_cast<decltype(__n)>(_M_count));
2239 }
2240
2241 constexpr auto
2242 size() const requires sized_range<const _Vp>
2243 {
2244 auto __n = ranges::size(_M_base);
2245 return std::min(__n, static_cast<decltype(__n)>(_M_count));
2246 }
2247 };
2248
2249 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2250 // 3447. Deduction guides for take_view and drop_view have different
2251 // constraints
2252 template<typename _Range>
2253 take_view(_Range&&, range_difference_t<_Range>)
2254 -> take_view<views::all_t<_Range>>;
2255
2256 template<typename _Tp>
2257 inline constexpr bool enable_borrowed_range<take_view<_Tp>>
2258 = enable_borrowed_range<_Tp>;
2259
2260 namespace views
2261 {
2262 namespace __detail
2263 {
2264 template<typename _Range>
2265 inline constexpr bool __is_empty_view = false;
2266
2267 template<typename _Tp>
2268 inline constexpr bool __is_empty_view<empty_view<_Tp>> = true;
2269
2270 template<typename _Range>
2271 inline constexpr bool __is_basic_string_view = false;
2272
2273 template<typename _CharT, typename _Traits>
2274 inline constexpr bool __is_basic_string_view<basic_string_view<_CharT, _Traits>>
2275 = true;
2276
2277 template<typename _Range>
2278 inline constexpr bool __is_subrange = false;
2279
2280 template<typename _Iter, typename _Sent, subrange_kind _Kind>
2281 inline constexpr bool __is_subrange<subrange<_Iter, _Sent, _Kind>> = true;
2282
2283 template<typename _Range>
2284 inline constexpr bool __is_iota_view = false;
2285
2286 template<typename _Winc, typename _Bound>
2287 inline constexpr bool __is_iota_view<iota_view<_Winc, _Bound>> = true;
2288
2289 template<typename _Range>
2290 inline constexpr bool __is_repeat_view = false;
2291
2292 template<typename _Range>
2293 constexpr auto
2294 __take_of_repeat_view(_Range&&, range_difference_t<_Range>); // defined later
2295
2296 template<typename _Range, typename _Dp>
2297 concept __can_take_view
2298 = requires { take_view(std::declval<_Range>(), std::declval<_Dp>()); };
2299 } // namespace __detail
2300
2301 struct _Take : __adaptor::_RangeAdaptor<_Take>
2302 {
2303 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
2304 requires __detail::__can_take_view<_Range, _Dp>
2305 constexpr auto
2306 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
2307 {
2308 using _Tp = remove_cvref_t<_Range>;
2309 if constexpr (__detail::__is_empty_view<_Tp>)
2310 return _Tp();
2311 else if constexpr (random_access_range<_Tp>
2312 && sized_range<_Tp>
2313 && (std::__detail::__is_span<_Tp>
2314 || __detail::__is_basic_string_view<_Tp>
2315 || __detail::__is_subrange<_Tp>
2316 || __detail::__is_iota_view<_Tp>))
2317 {
2318 __n = std::min<_Dp>(ranges::distance(__r), __n);
2319 auto __begin = ranges::begin(__r);
2320 auto __end = __begin + __n;
2321 if constexpr (std::__detail::__is_span<_Tp>)
2322 return span<typename _Tp::element_type>(__begin, __end);
2323 else if constexpr (__detail::__is_basic_string_view<_Tp>)
2324 return _Tp(__begin, __end);
2325 else if constexpr (__detail::__is_subrange<_Tp>)
2326 return subrange<iterator_t<_Tp>>(__begin, __end);
2327 else
2328 return iota_view(*__begin, *__end);
2329 }
2330 else if constexpr (__detail::__is_repeat_view<_Tp>)
2331 return __detail::__take_of_repeat_view(std::forward<_Range>(__r), __n);
2332 else
2333 return take_view(std::forward<_Range>(__r), __n);
2334 }
2335
2336 using _RangeAdaptor<_Take>::operator();
2337 static constexpr int _S_arity = 2;
2338 // The count argument of views::take is not always simple -- it can be
2339 // e.g. a move-only class that's implicitly convertible to the difference
2340 // type. But an integer-like count argument is surely simple.
2341 template<typename _Tp>
2342 static constexpr bool _S_has_simple_extra_args
2343 = ranges::__detail::__is_integer_like<_Tp>;
2344 };
2345
2346 inline constexpr _Take take;
2347 } // namespace views
2348
2349 template<view _Vp, typename _Pred>
2350 requires input_range<_Vp> && is_object_v<_Pred>
2351 && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
2352 class take_while_view : public view_interface<take_while_view<_Vp, _Pred>>
2353 {
2354 template<bool _Const>
2355 struct _Sentinel
2356 {
2357 private:
2358 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2359
2360 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2361 const _Pred* _M_pred = nullptr;
2362
2363 public:
2364 _Sentinel() = default;
2365
2366 constexpr explicit
2367 _Sentinel(sentinel_t<_Base> __end, const _Pred* __pred)
2368 : _M_end(__end), _M_pred(__pred)
2369 { }
2370
2371 constexpr
2372 _Sentinel(_Sentinel<!_Const> __s)
2373 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2374 : _M_end(__s._M_end), _M_pred(__s._M_pred)
2375 { }
2376
2377 constexpr sentinel_t<_Base>
2378 base() const { return _M_end; }
2379
2380 friend constexpr bool
2381 operator==(const iterator_t<_Base>& __x, const _Sentinel& __y)
2382 { return __y._M_end == __x || !std::__invoke(*__y._M_pred, *__x); }
2383
2384 template<bool _OtherConst = !_Const,
2385 typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
2386 requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2387 friend constexpr bool
2388 operator==(const iterator_t<_Base2>& __x, const _Sentinel& __y)
2389 { return __y._M_end == __x || !std::__invoke(*__y._M_pred, *__x); }
2390
2391 friend _Sentinel<!_Const>;
2392 };
2393
2394 _Vp _M_base = _Vp();
2395 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
2396
2397 public:
2398 take_while_view() requires (default_initializable<_Vp>
2399 && default_initializable<_Pred>)
2400 = default;
2401
2402 constexpr
2403 take_while_view(_Vp __base, _Pred __pred)
2404 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
2405 { }
2406
2407 constexpr _Vp
2408 base() const& requires copy_constructible<_Vp>
2409 { return _M_base; }
2410
2411 constexpr _Vp
2412 base() &&
2413 { return std::move(_M_base); }
2414
2415 constexpr const _Pred&
2416 pred() const
2417 { return *_M_pred; }
2418
2419 constexpr auto
2420 begin() requires (!__detail::__simple_view<_Vp>)
2421 { return ranges::begin(_M_base); }
2422
2423 constexpr auto
2424 begin() const requires range<const _Vp>
2425 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
2426 { return ranges::begin(_M_base); }
2427
2428 constexpr auto
2429 end() requires (!__detail::__simple_view<_Vp>)
2430 { return _Sentinel<false>(ranges::end(_M_base),
2431 std::__addressof(*_M_pred)); }
2432
2433 constexpr auto
2434 end() const requires range<const _Vp>
2435 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
2436 { return _Sentinel<true>(ranges::end(_M_base),
2437 std::__addressof(*_M_pred)); }
2438 };
2439
2440 template<typename _Range, typename _Pred>
2441 take_while_view(_Range&&, _Pred)
2442 -> take_while_view<views::all_t<_Range>, _Pred>;
2443
2444 namespace views
2445 {
2446 namespace __detail
2447 {
2448 template<typename _Range, typename _Pred>
2449 concept __can_take_while_view
2450 = requires { take_while_view(std::declval<_Range>(), std::declval<_Pred>()); };
2451 } // namespace __detail
2452
2453 struct _TakeWhile : __adaptor::_RangeAdaptor<_TakeWhile>
2454 {
2455 template<viewable_range _Range, typename _Pred>
2456 requires __detail::__can_take_while_view<_Range, _Pred>
2457 constexpr auto
2458 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p) const
2459 {
2460 return take_while_view(std::forward<_Range>(__r), std::forward<_Pred>(__p));
2461 }
2462
2463 using _RangeAdaptor<_TakeWhile>::operator();
2464 static constexpr int _S_arity = 2;
2465 static constexpr bool _S_has_simple_extra_args = true;
2466 };
2467
2468 inline constexpr _TakeWhile take_while;
2469 } // namespace views
2470
2471 template<view _Vp>
2472 class drop_view : public view_interface<drop_view<_Vp>>
2473 {
2474 private:
2475 _Vp _M_base = _Vp();
2476 range_difference_t<_Vp> _M_count = 0;
2477
2478 // ranges::next(begin(base), count, end(base)) is O(1) if _Vp satisfies
2479 // both random_access_range and sized_range. Otherwise, cache its result.
2480 static constexpr bool _S_needs_cached_begin
2481 = !(random_access_range<const _Vp> && sized_range<const _Vp>);
2482 [[no_unique_address]]
2483 __detail::__maybe_present_t<_S_needs_cached_begin,
2484 __detail::_CachedPosition<_Vp>>
2485 _M_cached_begin;
2486
2487 public:
2488 drop_view() requires default_initializable<_Vp> = default;
2489
2490 constexpr
2491 drop_view(_Vp __base, range_difference_t<_Vp> __count)
2492 : _M_base(std::move(__base)), _M_count(__count)
2493 { __glibcxx_assert(__count >= 0); }
2494
2495 constexpr _Vp
2496 base() const& requires copy_constructible<_Vp>
2497 { return _M_base; }
2498
2499 constexpr _Vp
2500 base() &&
2501 { return std::move(_M_base); }
2502
2503 // This overload is disabled for simple views with constant-time begin().
2504 constexpr auto
2505 begin()
2506 requires (!(__detail::__simple_view<_Vp>
2507 && random_access_range<const _Vp>
2508 && sized_range<const _Vp>))
2509 {
2510 if constexpr (_S_needs_cached_begin)
2511 if (_M_cached_begin._M_has_value())
2512 return _M_cached_begin._M_get(_M_base);
2513
2514 auto __it = ranges::next(ranges::begin(_M_base),
2515 _M_count, ranges::end(_M_base));
2516 if constexpr (_S_needs_cached_begin)
2517 _M_cached_begin._M_set(_M_base, __it);
2518 return __it;
2519 }
2520
2521 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2522 // 3482. drop_view's const begin should additionally require sized_range
2523 constexpr auto
2524 begin() const
2525 requires random_access_range<const _Vp> && sized_range<const _Vp>
2526 {
2527 return ranges::next(ranges::begin(_M_base), _M_count,
2528 ranges::end(_M_base));
2529 }
2530
2531 constexpr auto
2532 end() requires (!__detail::__simple_view<_Vp>)
2533 { return ranges::end(_M_base); }
2534
2535 constexpr auto
2536 end() const requires range<const _Vp>
2537 { return ranges::end(_M_base); }
2538
2539 constexpr auto
2540 size() requires sized_range<_Vp>
2541 {
2542 const auto __s = ranges::size(_M_base);
2543 const auto __c = static_cast<decltype(__s)>(_M_count);
2544 return __s < __c ? 0 : __s - __c;
2545 }
2546
2547 constexpr auto
2548 size() const requires sized_range<const _Vp>
2549 {
2550 const auto __s = ranges::size(_M_base);
2551 const auto __c = static_cast<decltype(__s)>(_M_count);
2552 return __s < __c ? 0 : __s - __c;
2553 }
2554 };
2555
2556 template<typename _Range>
2557 drop_view(_Range&&, range_difference_t<_Range>)
2558 -> drop_view<views::all_t<_Range>>;
2559
2560 template<typename _Tp>
2561 inline constexpr bool enable_borrowed_range<drop_view<_Tp>>
2562 = enable_borrowed_range<_Tp>;
2563
2564 namespace views
2565 {
2566 namespace __detail
2567 {
2568 template<typename _Range>
2569 constexpr auto
2570 __drop_of_repeat_view(_Range&&, range_difference_t<_Range>); // defined later
2571
2572 template<typename _Range, typename _Dp>
2573 concept __can_drop_view
2574 = requires { drop_view(std::declval<_Range>(), std::declval<_Dp>()); };
2575 } // namespace __detail
2576
2577 struct _Drop : __adaptor::_RangeAdaptor<_Drop>
2578 {
2579 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
2580 requires __detail::__can_drop_view<_Range, _Dp>
2581 constexpr auto
2582 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
2583 {
2584 using _Tp = remove_cvref_t<_Range>;
2585 if constexpr (__detail::__is_empty_view<_Tp>)
2586 return _Tp();
2587 else if constexpr (random_access_range<_Tp>
2588 && sized_range<_Tp>
2589 && (std::__detail::__is_span<_Tp>
2590 || __detail::__is_basic_string_view<_Tp>
2591 || __detail::__is_iota_view<_Tp>
2592 || __detail::__is_subrange<_Tp>))
2593 {
2594 __n = std::min<_Dp>(ranges::distance(__r), __n);
2595 auto __begin = ranges::begin(__r) + __n;
2596 auto __end = ranges::end(__r);
2597 if constexpr (std::__detail::__is_span<_Tp>)
2598 return span<typename _Tp::element_type>(__begin, __end);
2599 else if constexpr (__detail::__is_subrange<_Tp>)
2600 {
2601 if constexpr (_Tp::_S_store_size)
2602 {
2603 using ranges::__detail::__to_unsigned_like;
2604 auto __m = ranges::distance(__r) - __n;
2605 return _Tp(__begin, __end, __to_unsigned_like(__m));
2606 }
2607 else
2608 return _Tp(__begin, __end);
2609 }
2610 else
2611 return _Tp(__begin, __end);
2612 }
2613 else if constexpr (__detail::__is_repeat_view<_Tp>)
2614 return __detail::__drop_of_repeat_view(std::forward<_Range>(__r), __n);
2615 else
2616 return drop_view(std::forward<_Range>(__r), __n);
2617 }
2618
2619 using _RangeAdaptor<_Drop>::operator();
2620 static constexpr int _S_arity = 2;
2621 template<typename _Tp>
2622 static constexpr bool _S_has_simple_extra_args
2623 = _Take::_S_has_simple_extra_args<_Tp>;
2624 };
2625
2626 inline constexpr _Drop drop;
2627 } // namespace views
2628
2629 template<view _Vp, typename _Pred>
2630 requires input_range<_Vp> && is_object_v<_Pred>
2631 && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
2632 class drop_while_view : public view_interface<drop_while_view<_Vp, _Pred>>
2633 {
2634 private:
2635 _Vp _M_base = _Vp();
2636 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
2637 [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;
2638
2639 public:
2640 drop_while_view() requires (default_initializable<_Vp>
2641 && default_initializable<_Pred>)
2642 = default;
2643
2644 constexpr
2645 drop_while_view(_Vp __base, _Pred __pred)
2646 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
2647 { }
2648
2649 constexpr _Vp
2650 base() const& requires copy_constructible<_Vp>
2651 { return _M_base; }
2652
2653 constexpr _Vp
2654 base() &&
2655 { return std::move(_M_base); }
2656
2657 constexpr const _Pred&
2658 pred() const
2659 { return *_M_pred; }
2660
2661 constexpr auto
2662 begin()
2663 {
2664 if (_M_cached_begin._M_has_value())
2665 return _M_cached_begin._M_get(_M_base);
2666
2667 __glibcxx_assert(_M_pred.has_value());
2668 auto __it = ranges::find_if_not(ranges::begin(_M_base),
2669 ranges::end(_M_base),
2670 std::cref(*_M_pred));
2671 _M_cached_begin._M_set(_M_base, __it);
2672 return __it;
2673 }
2674
2675 constexpr auto
2676 end()
2677 { return ranges::end(_M_base); }
2678 };
2679
2680 template<typename _Range, typename _Pred>
2681 drop_while_view(_Range&&, _Pred)
2682 -> drop_while_view<views::all_t<_Range>, _Pred>;
2683
2684 template<typename _Tp, typename _Pred>
2685 inline constexpr bool enable_borrowed_range<drop_while_view<_Tp, _Pred>>
2686 = enable_borrowed_range<_Tp>;
2687
2688 namespace views
2689 {
2690 namespace __detail
2691 {
2692 template<typename _Range, typename _Pred>
2693 concept __can_drop_while_view
2694 = requires { drop_while_view(std::declval<_Range>(), std::declval<_Pred>()); };
2695 } // namespace __detail
2696
2697 struct _DropWhile : __adaptor::_RangeAdaptor<_DropWhile>
2698 {
2699 template<viewable_range _Range, typename _Pred>
2700 requires __detail::__can_drop_while_view<_Range, _Pred>
2701 constexpr auto
2702 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p) const
2703 {
2704 return drop_while_view(std::forward<_Range>(__r),
2705 std::forward<_Pred>(__p));
2706 }
2707
2708 using _RangeAdaptor<_DropWhile>::operator();
2709 static constexpr int _S_arity = 2;
2710 static constexpr bool _S_has_simple_extra_args = true;
2711 };
2712
2713 inline constexpr _DropWhile drop_while;
2714 } // namespace views
2715
2716 template<input_range _Vp>
2717 requires view<_Vp> && input_range<range_reference_t<_Vp>>
2718 class join_view : public view_interface<join_view<_Vp>>
2719 {
2720 private:
2721 using _InnerRange = range_reference_t<_Vp>;
2722
2723 template<bool _Const>
2724 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2725
2726 template<bool _Const>
2727 using _Outer_iter = iterator_t<_Base<_Const>>;
2728
2729 template<bool _Const>
2730 using _Inner_iter = iterator_t<range_reference_t<_Base<_Const>>>;
2731
2732 template<bool _Const>
2733 static constexpr bool _S_ref_is_glvalue
2734 = is_reference_v<range_reference_t<_Base<_Const>>>;
2735
2736 template<bool _Const>
2737 struct __iter_cat
2738 { };
2739
2740 template<bool _Const>
2741 requires _S_ref_is_glvalue<_Const>
2742 && forward_range<_Base<_Const>>
2743 && forward_range<range_reference_t<_Base<_Const>>>
2744 struct __iter_cat<_Const>
2745 {
2746 private:
2747 static constexpr auto
2748 _S_iter_cat()
2749 {
2750 using _Outer_iter = join_view::_Outer_iter<_Const>;
2751 using _Inner_iter = join_view::_Inner_iter<_Const>;
2752 using _OuterCat = typename iterator_traits<_Outer_iter>::iterator_category;
2753 using _InnerCat = typename iterator_traits<_Inner_iter>::iterator_category;
2754 if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag>
2755 && derived_from<_InnerCat, bidirectional_iterator_tag>
2756 && common_range<range_reference_t<_Base<_Const>>>)
2757 return bidirectional_iterator_tag{};
2758 else if constexpr (derived_from<_OuterCat, forward_iterator_tag>
2759 && derived_from<_InnerCat, forward_iterator_tag>)
2760 return forward_iterator_tag{};
2761 else
2762 return input_iterator_tag{};
2763 }
2764 public:
2765 using iterator_category = decltype(_S_iter_cat());
2766 };
2767
2768 template<bool _Const>
2769 struct _Sentinel;
2770
2771 template<bool _Const>
2772 struct _Iterator : __iter_cat<_Const>
2773 {
2774 private:
2775 using _Parent = __detail::__maybe_const_t<_Const, join_view>;
2776 using _Base = join_view::_Base<_Const>;
2777
2778 static constexpr bool _S_ref_is_glvalue
2779 = join_view::_S_ref_is_glvalue<_Const>;
2780
2781 constexpr void
2782 _M_satisfy()
2783 {
2784 auto __update_inner = [this] (const iterator_t<_Base>& __x) -> auto&& {
2785 if constexpr (_S_ref_is_glvalue)
2786 return *__x;
2787 else
2788 return _M_parent->_M_inner._M_emplace_deref(__x);
2789 };
2790
2791 for (; _M_outer != ranges::end(_M_parent->_M_base); ++_M_outer)
2792 {
2793 auto&& __inner = __update_inner(_M_outer);
2794 _M_inner = ranges::begin(__inner);
2795 if (_M_inner != ranges::end(__inner))
2796 return;
2797 }
2798
2799 if constexpr (_S_ref_is_glvalue)
2800 _M_inner.reset();
2801 }
2802
2803 static constexpr auto
2804 _S_iter_concept()
2805 {
2806 if constexpr (_S_ref_is_glvalue
2807 && bidirectional_range<_Base>
2808 && bidirectional_range<range_reference_t<_Base>>
2809 && common_range<range_reference_t<_Base>>)
2810 return bidirectional_iterator_tag{};
2811 else if constexpr (_S_ref_is_glvalue
2812 && forward_range<_Base>
2813 && forward_range<range_reference_t<_Base>>)
2814 return forward_iterator_tag{};
2815 else
2816 return input_iterator_tag{};
2817 }
2818
2819 using _Outer_iter = join_view::_Outer_iter<_Const>;
2820 using _Inner_iter = join_view::_Inner_iter<_Const>;
2821
2822 _Outer_iter _M_outer = _Outer_iter();
2823 optional<_Inner_iter> _M_inner;
2824 _Parent* _M_parent = nullptr;
2825
2826 public:
2827 using iterator_concept = decltype(_S_iter_concept());
2828 // iterator_category defined in __join_view_iter_cat
2829 using value_type = range_value_t<range_reference_t<_Base>>;
2830 using difference_type
2831 = common_type_t<range_difference_t<_Base>,
2832 range_difference_t<range_reference_t<_Base>>>;
2833
2834 _Iterator() requires default_initializable<_Outer_iter> = default;
2835
2836 constexpr
2837 _Iterator(_Parent* __parent, _Outer_iter __outer)
2838 : _M_outer(std::move(__outer)),
2839 _M_parent(__parent)
2840 { _M_satisfy(); }
2841
2842 constexpr
2843 _Iterator(_Iterator<!_Const> __i)
2844 requires _Const
2845 && convertible_to<iterator_t<_Vp>, _Outer_iter>
2846 && convertible_to<iterator_t<_InnerRange>, _Inner_iter>
2847 : _M_outer(std::move(__i._M_outer)), _M_inner(std::move(__i._M_inner)),
2848 _M_parent(__i._M_parent)
2849 { }
2850
2851 constexpr decltype(auto)
2852 operator*() const
2853 { return **_M_inner; }
2854
2855 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2856 // 3500. join_view::iterator::operator->() is bogus
2857 constexpr _Inner_iter
2858 operator->() const
2859 requires __detail::__has_arrow<_Inner_iter>
2860 && copyable<_Inner_iter>
2861 { return *_M_inner; }
2862
2863 constexpr _Iterator&
2864 operator++()
2865 {
2866 auto&& __inner_range = [this] () -> auto&& {
2867 if constexpr (_S_ref_is_glvalue)
2868 return *_M_outer;
2869 else
2870 return *_M_parent->_M_inner;
2871 }();
2872 if (++*_M_inner == ranges::end(__inner_range))
2873 {
2874 ++_M_outer;
2875 _M_satisfy();
2876 }
2877 return *this;
2878 }
2879
2880 constexpr void
2881 operator++(int)
2882 { ++*this; }
2883
2884 constexpr _Iterator
2885 operator++(int)
2886 requires _S_ref_is_glvalue && forward_range<_Base>
2887 && forward_range<range_reference_t<_Base>>
2888 {
2889 auto __tmp = *this;
2890 ++*this;
2891 return __tmp;
2892 }
2893
2894 constexpr _Iterator&
2895 operator--()
2896 requires _S_ref_is_glvalue && bidirectional_range<_Base>
2897 && bidirectional_range<range_reference_t<_Base>>
2898 && common_range<range_reference_t<_Base>>
2899 {
2900 if (_M_outer == ranges::end(_M_parent->_M_base))
2901 _M_inner = ranges::end(*--_M_outer);
2902 while (*_M_inner == ranges::begin(*_M_outer))
2903 *_M_inner = ranges::end(*--_M_outer);
2904 --*_M_inner;
2905 return *this;
2906 }
2907
2908 constexpr _Iterator
2909 operator--(int)
2910 requires _S_ref_is_glvalue && bidirectional_range<_Base>
2911 && bidirectional_range<range_reference_t<_Base>>
2912 && common_range<range_reference_t<_Base>>
2913 {
2914 auto __tmp = *this;
2915 --*this;
2916 return __tmp;
2917 }
2918
2919 friend constexpr bool
2920 operator==(const _Iterator& __x, const _Iterator& __y)
2921 requires _S_ref_is_glvalue
2922 && equality_comparable<_Outer_iter>
2923 && equality_comparable<_Inner_iter>
2924 {
2925 return (__x._M_outer == __y._M_outer
2926 && __x._M_inner == __y._M_inner);
2927 }
2928
2929 friend constexpr decltype(auto)
2930 iter_move(const _Iterator& __i)
2931 noexcept(noexcept(ranges::iter_move(*__i._M_inner)))
2932 { return ranges::iter_move(*__i._M_inner); }
2933
2934 friend constexpr void
2935 iter_swap(const _Iterator& __x, const _Iterator& __y)
2936 noexcept(noexcept(ranges::iter_swap(*__x._M_inner, *__y._M_inner)))
2937 requires indirectly_swappable<_Inner_iter>
2938 { return ranges::iter_swap(*__x._M_inner, *__y._M_inner); }
2939
2940 friend _Iterator<!_Const>;
2941 template<bool> friend struct _Sentinel;
2942 };
2943
2944 template<bool _Const>
2945 struct _Sentinel
2946 {
2947 private:
2948 using _Parent = __detail::__maybe_const_t<_Const, join_view>;
2949 using _Base = join_view::_Base<_Const>;
2950
2951 template<bool _Const2>
2952 constexpr bool
2953 __equal(const _Iterator<_Const2>& __i) const
2954 { return __i._M_outer == _M_end; }
2955
2956 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2957
2958 public:
2959 _Sentinel() = default;
2960
2961 constexpr explicit
2962 _Sentinel(_Parent* __parent)
2963 : _M_end(ranges::end(__parent->_M_base))
2964 { }
2965
2966 constexpr
2967 _Sentinel(_Sentinel<!_Const> __s)
2968 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2969 : _M_end(std::move(__s._M_end))
2970 { }
2971
2972 template<bool _Const2>
2973 requires sentinel_for<sentinel_t<_Base>,
2974 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
2975 friend constexpr bool
2976 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
2977 { return __y.__equal(__x); }
2978
2979 friend _Sentinel<!_Const>;
2980 };
2981
2982 _Vp _M_base = _Vp();
2983 [[no_unique_address]]
2984 __detail::__non_propagating_cache<remove_cv_t<_InnerRange>> _M_inner;
2985
2986 public:
2987 join_view() requires default_initializable<_Vp> = default;
2988
2989 constexpr explicit
2990 join_view(_Vp __base)
2991 : _M_base(std::move(__base))
2992 { }
2993
2994 constexpr _Vp
2995 base() const& requires copy_constructible<_Vp>
2996 { return _M_base; }
2997
2998 constexpr _Vp
2999 base() &&
3000 { return std::move(_M_base); }
3001
3002 constexpr auto
3003 begin()
3004 {
3005 constexpr bool __use_const
3006 = (__detail::__simple_view<_Vp>
3007 && is_reference_v<range_reference_t<_Vp>>);
3008 return _Iterator<__use_const>{this, ranges::begin(_M_base)};
3009 }
3010
3011 constexpr auto
3012 begin() const
3013 requires input_range<const _Vp>
3014 && is_reference_v<range_reference_t<const _Vp>>
3015 {
3016 return _Iterator<true>{this, ranges::begin(_M_base)};
3017 }
3018
3019 constexpr auto
3020 end()
3021 {
3022 if constexpr (forward_range<_Vp> && is_reference_v<_InnerRange>
3023 && forward_range<_InnerRange>
3024 && common_range<_Vp> && common_range<_InnerRange>)
3025 return _Iterator<__detail::__simple_view<_Vp>>{this,
3026 ranges::end(_M_base)};
3027 else
3028 return _Sentinel<__detail::__simple_view<_Vp>>{this};
3029 }
3030
3031 constexpr auto
3032 end() const
3033 requires input_range<const _Vp>
3034 && is_reference_v<range_reference_t<const _Vp>>
3035 {
3036 if constexpr (forward_range<const _Vp>
3037 && is_reference_v<range_reference_t<const _Vp>>
3038 && forward_range<range_reference_t<const _Vp>>
3039 && common_range<const _Vp>
3040 && common_range<range_reference_t<const _Vp>>)
3041 return _Iterator<true>{this, ranges::end(_M_base)};
3042 else
3043 return _Sentinel<true>{this};
3044 }
3045 };
3046
3047 template<typename _Range>
3048 explicit join_view(_Range&&) -> join_view<views::all_t<_Range>>;
3049
3050 namespace views
3051 {
3052 namespace __detail
3053 {
3054 template<typename _Range>
3055 concept __can_join_view
3056 = requires { join_view<all_t<_Range>>{std::declval<_Range>()}; };
3057 } // namespace __detail
3058
3059 struct _Join : __adaptor::_RangeAdaptorClosure
3060 {
3061 template<viewable_range _Range>
3062 requires __detail::__can_join_view<_Range>
3063 constexpr auto
3064 operator() [[nodiscard]] (_Range&& __r) const
3065 {
3066 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3067 // 3474. Nesting join_views is broken because of CTAD
3068 return join_view<all_t<_Range>>{std::forward<_Range>(__r)};
3069 }
3070
3071 static constexpr bool _S_has_simple_call_op = true;
3072 };
3073
3074 inline constexpr _Join join;
3075 } // namespace views
3076
3077 namespace __detail
3078 {
3079 template<auto>
3080 struct __require_constant;
3081
3082 template<typename _Range>
3083 concept __tiny_range = sized_range<_Range>
3084 && requires
3085 { typename __require_constant<remove_reference_t<_Range>::size()>; }
3086 && (remove_reference_t<_Range>::size() <= 1);
3087
3088 template<typename _Base>
3089 struct __lazy_split_view_outer_iter_cat
3090 { };
3091
3092 template<forward_range _Base>
3093 struct __lazy_split_view_outer_iter_cat<_Base>
3094 { using iterator_category = input_iterator_tag; };
3095
3096 template<typename _Base>
3097 struct __lazy_split_view_inner_iter_cat
3098 { };
3099
3100 template<forward_range _Base>
3101 struct __lazy_split_view_inner_iter_cat<_Base>
3102 {
3103 private:
3104 static constexpr auto
3105 _S_iter_cat()
3106 {
3107 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
3108 if constexpr (derived_from<_Cat, forward_iterator_tag>)
3109 return forward_iterator_tag{};
3110 else
3111 return _Cat{};
3112 }
3113 public:
3114 using iterator_category = decltype(_S_iter_cat());
3115 };
3116 }
3117
3118 template<input_range _Vp, forward_range _Pattern>
3119 requires view<_Vp> && view<_Pattern>
3120 && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
3121 ranges::equal_to>
3122 && (forward_range<_Vp> || __detail::__tiny_range<_Pattern>)
3123 class lazy_split_view : public view_interface<lazy_split_view<_Vp, _Pattern>>
3124 {
3125 private:
3126 template<bool _Const>
3127 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
3128
3129 template<bool _Const>
3130 struct _InnerIter;
3131
3132 template<bool _Const>
3133 struct _OuterIter
3134 : __detail::__lazy_split_view_outer_iter_cat<_Base<_Const>>
3135 {
3136 private:
3137 using _Parent = __detail::__maybe_const_t<_Const, lazy_split_view>;
3138 using _Base = lazy_split_view::_Base<_Const>;
3139
3140 constexpr bool
3141 __at_end() const
3142 { return __current() == ranges::end(_M_parent->_M_base) && !_M_trailing_empty; }
3143
3144 // [range.lazy.split.outer] p1
3145 // Many of the following specifications refer to the notional member
3146 // current of outer-iterator. current is equivalent to current_ if
3147 // V models forward_range, and parent_->current_ otherwise.
3148 constexpr auto&
3149 __current() noexcept
3150 {
3151 if constexpr (forward_range<_Vp>)
3152 return _M_current;
3153 else
3154 return *_M_parent->_M_current;
3155 }
3156
3157 constexpr auto&
3158 __current() const noexcept
3159 {
3160 if constexpr (forward_range<_Vp>)
3161 return _M_current;
3162 else
3163 return *_M_parent->_M_current;
3164 }
3165
3166 _Parent* _M_parent = nullptr;
3167
3168 [[no_unique_address]]
3169 __detail::__maybe_present_t<forward_range<_Vp>,
3170 iterator_t<_Base>> _M_current;
3171 bool _M_trailing_empty = false;
3172
3173 public:
3174 using iterator_concept = __conditional_t<forward_range<_Base>,
3175 forward_iterator_tag,
3176 input_iterator_tag>;
3177 // iterator_category defined in __lazy_split_view_outer_iter_cat
3178 using difference_type = range_difference_t<_Base>;
3179
3180 struct value_type : view_interface<value_type>
3181 {
3182 private:
3183 _OuterIter _M_i = _OuterIter();
3184
3185 public:
3186 value_type() = default;
3187
3188 constexpr explicit
3189 value_type(_OuterIter __i)
3190 : _M_i(std::move(__i))
3191 { }
3192
3193 constexpr _InnerIter<_Const>
3194 begin() const
3195 { return _InnerIter<_Const>{_M_i}; }
3196
3197 constexpr default_sentinel_t
3198 end() const noexcept
3199 { return default_sentinel; }
3200 };
3201
3202 _OuterIter() = default;
3203
3204 constexpr explicit
3205 _OuterIter(_Parent* __parent) requires (!forward_range<_Base>)
3206 : _M_parent(__parent)
3207 { }
3208
3209 constexpr
3210 _OuterIter(_Parent* __parent, iterator_t<_Base> __current)
3211 requires forward_range<_Base>
3212 : _M_parent(__parent),
3213 _M_current(std::move(__current))
3214 { }
3215
3216 constexpr
3217 _OuterIter(_OuterIter<!_Const> __i)
3218 requires _Const
3219 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
3220 : _M_parent(__i._M_parent), _M_current(std::move(__i._M_current)),
3221 _M_trailing_empty(__i._M_trailing_empty)
3222 { }
3223
3224 constexpr value_type
3225 operator*() const
3226 { return value_type{*this}; }
3227
3228 constexpr _OuterIter&
3229 operator++()
3230 {
3231 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3232 // 3505. lazy_split_view::outer-iterator::operator++ misspecified
3233 const auto __end = ranges::end(_M_parent->_M_base);
3234 if (__current() == __end)
3235 {
3236 _M_trailing_empty = false;
3237 return *this;
3238 }
3239 const auto [__pbegin, __pend] = subrange{_M_parent->_M_pattern};
3240 if (__pbegin == __pend)
3241 ++__current();
3242 else if constexpr (__detail::__tiny_range<_Pattern>)
3243 {
3244 __current() = ranges::find(std::move(__current()), __end,
3245 *__pbegin);
3246 if (__current() != __end)
3247 {
3248 ++__current();
3249 if (__current() == __end)
3250 _M_trailing_empty = true;
3251 }
3252 }
3253 else
3254 do
3255 {
3256 auto [__b, __p]
3257 = ranges::mismatch(__current(), __end, __pbegin, __pend);
3258 if (__p == __pend)
3259 {
3260 __current() = __b;
3261 if (__current() == __end)
3262 _M_trailing_empty = true;
3263 break;
3264 }
3265 } while (++__current() != __end);
3266 return *this;
3267 }
3268
3269 constexpr decltype(auto)
3270 operator++(int)
3271 {
3272 if constexpr (forward_range<_Base>)
3273 {
3274 auto __tmp = *this;
3275 ++*this;
3276 return __tmp;
3277 }
3278 else
3279 ++*this;
3280 }
3281
3282 friend constexpr bool
3283 operator==(const _OuterIter& __x, const _OuterIter& __y)
3284 requires forward_range<_Base>
3285 {
3286 return __x._M_current == __y._M_current
3287 && __x._M_trailing_empty == __y._M_trailing_empty;
3288 }
3289
3290 friend constexpr bool
3291 operator==(const _OuterIter& __x, default_sentinel_t)
3292 { return __x.__at_end(); };
3293
3294 friend _OuterIter<!_Const>;
3295 friend _InnerIter<_Const>;
3296 };
3297
3298 template<bool _Const>
3299 struct _InnerIter
3300 : __detail::__lazy_split_view_inner_iter_cat<_Base<_Const>>
3301 {
3302 private:
3303 using _Base = lazy_split_view::_Base<_Const>;
3304
3305 constexpr bool
3306 __at_end() const
3307 {
3308 auto [__pcur, __pend] = subrange{_M_i._M_parent->_M_pattern};
3309 auto __end = ranges::end(_M_i._M_parent->_M_base);
3310 if constexpr (__detail::__tiny_range<_Pattern>)
3311 {
3312 const auto& __cur = _M_i_current();
3313 if (__cur == __end)
3314 return true;
3315 if (__pcur == __pend)
3316 return _M_incremented;
3317 return *__cur == *__pcur;
3318 }
3319 else
3320 {
3321 auto __cur = _M_i_current();
3322 if (__cur == __end)
3323 return true;
3324 if (__pcur == __pend)
3325 return _M_incremented;
3326 do
3327 {
3328 if (*__cur != *__pcur)
3329 return false;
3330 if (++__pcur == __pend)
3331 return true;
3332 } while (++__cur != __end);
3333 return false;
3334 }
3335 }
3336
3337 constexpr auto&
3338 _M_i_current() noexcept
3339 { return _M_i.__current(); }
3340
3341 constexpr auto&
3342 _M_i_current() const noexcept
3343 { return _M_i.__current(); }
3344
3345 _OuterIter<_Const> _M_i = _OuterIter<_Const>();
3346 bool _M_incremented = false;
3347
3348 public:
3349 using iterator_concept
3350 = typename _OuterIter<_Const>::iterator_concept;
3351 // iterator_category defined in __lazy_split_view_inner_iter_cat
3352 using value_type = range_value_t<_Base>;
3353 using difference_type = range_difference_t<_Base>;
3354
3355 _InnerIter() = default;
3356
3357 constexpr explicit
3358 _InnerIter(_OuterIter<_Const> __i)
3359 : _M_i(std::move(__i))
3360 { }
3361
3362 constexpr const iterator_t<_Base>&
3363 base() const& noexcept
3364 { return _M_i_current(); }
3365
3366 constexpr iterator_t<_Base>
3367 base() && requires forward_range<_Vp>
3368 { return std::move(_M_i_current()); }
3369
3370 constexpr decltype(auto)
3371 operator*() const
3372 { return *_M_i_current(); }
3373
3374 constexpr _InnerIter&
3375 operator++()
3376 {
3377 _M_incremented = true;
3378 if constexpr (!forward_range<_Base>)
3379 if constexpr (_Pattern::size() == 0)
3380 return *this;
3381 ++_M_i_current();
3382 return *this;
3383 }
3384
3385 constexpr decltype(auto)
3386 operator++(int)
3387 {
3388 if constexpr (forward_range<_Base>)
3389 {
3390 auto __tmp = *this;
3391 ++*this;
3392 return __tmp;
3393 }
3394 else
3395 ++*this;
3396 }
3397
3398 friend constexpr bool
3399 operator==(const _InnerIter& __x, const _InnerIter& __y)
3400 requires forward_range<_Base>
3401 { return __x._M_i == __y._M_i; }
3402
3403 friend constexpr bool
3404 operator==(const _InnerIter& __x, default_sentinel_t)
3405 { return __x.__at_end(); }
3406
3407 friend constexpr decltype(auto)
3408 iter_move(const _InnerIter& __i)
3409 noexcept(noexcept(ranges::iter_move(__i._M_i_current())))
3410 { return ranges::iter_move(__i._M_i_current()); }
3411
3412 friend constexpr void
3413 iter_swap(const _InnerIter& __x, const _InnerIter& __y)
3414 noexcept(noexcept(ranges::iter_swap(__x._M_i_current(),
3415 __y._M_i_current())))
3416 requires indirectly_swappable<iterator_t<_Base>>
3417 { ranges::iter_swap(__x._M_i_current(), __y._M_i_current()); }
3418 };
3419
3420 _Vp _M_base = _Vp();
3421 _Pattern _M_pattern = _Pattern();
3422 [[no_unique_address]]
3423 __detail::__maybe_present_t<!forward_range<_Vp>,
3424 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_current;
3425
3426
3427 public:
3428 lazy_split_view() requires (default_initializable<_Vp>
3429 && default_initializable<_Pattern>)
3430 = default;
3431
3432 constexpr
3433 lazy_split_view(_Vp __base, _Pattern __pattern)
3434 : _M_base(std::move(__base)), _M_pattern(std::move(__pattern))
3435 { }
3436
3437 template<input_range _Range>
3438 requires constructible_from<_Vp, views::all_t<_Range>>
3439 && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
3440 constexpr
3441 lazy_split_view(_Range&& __r, range_value_t<_Range> __e)
3442 : _M_base(views::all(std::forward<_Range>(__r))),
3443 _M_pattern(views::single(std::move(__e)))
3444 { }
3445
3446 constexpr _Vp
3447 base() const& requires copy_constructible<_Vp>
3448 { return _M_base; }
3449
3450 constexpr _Vp
3451 base() &&
3452 { return std::move(_M_base); }
3453
3454 constexpr auto
3455 begin()
3456 {
3457 if constexpr (forward_range<_Vp>)
3458 {
3459 constexpr bool __simple
3460 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
3461 return _OuterIter<__simple>{this, ranges::begin(_M_base)};
3462 }
3463 else
3464 {
3465 _M_current = ranges::begin(_M_base);
3466 return _OuterIter<false>{this};
3467 }
3468 }
3469
3470 constexpr auto
3471 begin() const requires forward_range<_Vp> && forward_range<const _Vp>
3472 {
3473 return _OuterIter<true>{this, ranges::begin(_M_base)};
3474 }
3475
3476 constexpr auto
3477 end() requires forward_range<_Vp> && common_range<_Vp>
3478 {
3479 constexpr bool __simple
3480 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
3481 return _OuterIter<__simple>{this, ranges::end(_M_base)};
3482 }
3483
3484 constexpr auto
3485 end() const
3486 {
3487 if constexpr (forward_range<_Vp>
3488 && forward_range<const _Vp>
3489 && common_range<const _Vp>)
3490 return _OuterIter<true>{this, ranges::end(_M_base)};
3491 else
3492 return default_sentinel;
3493 }
3494 };
3495
3496 template<typename _Range, typename _Pattern>
3497 lazy_split_view(_Range&&, _Pattern&&)
3498 -> lazy_split_view<views::all_t<_Range>, views::all_t<_Pattern>>;
3499
3500 template<input_range _Range>
3501 lazy_split_view(_Range&&, range_value_t<_Range>)
3502 -> lazy_split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;
3503
3504 namespace views
3505 {
3506 namespace __detail
3507 {
3508 template<typename _Range, typename _Pattern>
3509 concept __can_lazy_split_view
3510 = requires { lazy_split_view(std::declval<_Range>(), std::declval<_Pattern>()); };
3511 } // namespace __detail
3512
3513 struct _LazySplit : __adaptor::_RangeAdaptor<_LazySplit>
3514 {
3515 template<viewable_range _Range, typename _Pattern>
3516 requires __detail::__can_lazy_split_view<_Range, _Pattern>
3517 constexpr auto
3518 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f) const
3519 {
3520 return lazy_split_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
3521 }
3522
3523 using _RangeAdaptor<_LazySplit>::operator();
3524 static constexpr int _S_arity = 2;
3525 // The pattern argument of views::lazy_split is not always simple -- it can be
3526 // a non-view range, the value category of which affects whether the call
3527 // is well-formed. But a scalar or a view pattern argument is surely
3528 // simple.
3529 template<typename _Pattern>
3530 static constexpr bool _S_has_simple_extra_args
3531 = is_scalar_v<_Pattern> || (view<_Pattern>
3532 && copy_constructible<_Pattern>);
3533 };
3534
3535 inline constexpr _LazySplit lazy_split;
3536 } // namespace views
3537
3538 template<forward_range _Vp, forward_range _Pattern>
3539 requires view<_Vp> && view<_Pattern>
3540 && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
3541 ranges::equal_to>
3542 class split_view : public view_interface<split_view<_Vp, _Pattern>>
3543 {
3544 private:
3545 _Vp _M_base = _Vp();
3546 _Pattern _M_pattern = _Pattern();
3547 __detail::__non_propagating_cache<subrange<iterator_t<_Vp>>> _M_cached_begin;
3548
3549 struct _Iterator;
3550 struct _Sentinel;
3551
3552 public:
3553 split_view() requires (default_initializable<_Vp>
3554 && default_initializable<_Pattern>)
3555 = default;
3556
3557 constexpr
3558 split_view(_Vp __base, _Pattern __pattern)
3559 : _M_base(std::move(__base)), _M_pattern(std::move(__pattern))
3560 { }
3561
3562 template<forward_range _Range>
3563 requires constructible_from<_Vp, views::all_t<_Range>>
3564 && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
3565 constexpr
3566 split_view(_Range&& __r, range_value_t<_Range> __e)
3567 : _M_base(views::all(std::forward<_Range>(__r))),
3568 _M_pattern(views::single(std::move(__e)))
3569 { }
3570
3571 constexpr _Vp
3572 base() const& requires copy_constructible<_Vp>
3573 { return _M_base; }
3574
3575 constexpr _Vp
3576 base() &&
3577 { return std::move(_M_base); }
3578
3579 constexpr _Iterator
3580 begin()
3581 {
3582 if (!_M_cached_begin)
3583 _M_cached_begin = _M_find_next(ranges::begin(_M_base));
3584 return {this, ranges::begin(_M_base), *_M_cached_begin};
3585 }
3586
3587 constexpr auto
3588 end()
3589 {
3590 if constexpr (common_range<_Vp>)
3591 return _Iterator{this, ranges::end(_M_base), {}};
3592 else
3593 return _Sentinel{this};
3594 }
3595
3596 constexpr subrange<iterator_t<_Vp>>
3597 _M_find_next(iterator_t<_Vp> __it)
3598 {
3599 auto [__b, __e] = ranges::search(subrange(__it, ranges::end(_M_base)), _M_pattern);
3600 if (__b != ranges::end(_M_base) && ranges::empty(_M_pattern))
3601 {
3602 ++__b;
3603 ++__e;
3604 }
3605 return {__b, __e};
3606 }
3607
3608 private:
3609 struct _Iterator
3610 {
3611 private:
3612 split_view* _M_parent = nullptr;
3613 iterator_t<_Vp> _M_cur = iterator_t<_Vp>();
3614 subrange<iterator_t<_Vp>> _M_next = subrange<iterator_t<_Vp>>();
3615 bool _M_trailing_empty = false;
3616
3617 friend struct _Sentinel;
3618
3619 public:
3620 using iterator_concept = forward_iterator_tag;
3621 using iterator_category = input_iterator_tag;
3622 using value_type = subrange<iterator_t<_Vp>>;
3623 using difference_type = range_difference_t<_Vp>;
3624
3625 _Iterator() = default;
3626
3627 constexpr
3628 _Iterator(split_view* __parent,
3629 iterator_t<_Vp> __current,
3630 subrange<iterator_t<_Vp>> __next)
3631 : _M_parent(__parent),
3632 _M_cur(std::move(__current)),
3633 _M_next(std::move(__next))
3634 { }
3635
3636 constexpr iterator_t<_Vp>
3637 base() const
3638 { return _M_cur; }
3639
3640 constexpr value_type
3641 operator*() const
3642 { return {_M_cur, _M_next.begin()}; }
3643
3644 constexpr _Iterator&
3645 operator++()
3646 {
3647 _M_cur = _M_next.begin();
3648 if (_M_cur != ranges::end(_M_parent->_M_base))
3649 {
3650 _M_cur = _M_next.end();
3651 if (_M_cur == ranges::end(_M_parent->_M_base))
3652 {
3653 _M_trailing_empty = true;
3654 _M_next = {_M_cur, _M_cur};
3655 }
3656 else
3657 _M_next = _M_parent->_M_find_next(_M_cur);
3658 }
3659 else
3660 _M_trailing_empty = false;
3661 return *this;
3662 }
3663
3664 constexpr _Iterator
3665 operator++(int)
3666 {
3667 auto __tmp = *this;
3668 ++*this;
3669 return __tmp;
3670 }
3671
3672 friend constexpr bool
3673 operator==(const _Iterator& __x, const _Iterator& __y)
3674 {
3675 return __x._M_cur == __y._M_cur
3676 && __x._M_trailing_empty == __y._M_trailing_empty;
3677 }
3678 };
3679
3680 struct _Sentinel
3681 {
3682 private:
3683 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
3684
3685 constexpr bool
3686 _M_equal(const _Iterator& __x) const
3687 { return __x._M_cur == _M_end && !__x._M_trailing_empty; }
3688
3689 public:
3690 _Sentinel() = default;
3691
3692 constexpr explicit
3693 _Sentinel(split_view* __parent)
3694 : _M_end(ranges::end(__parent->_M_base))
3695 { }
3696
3697 friend constexpr bool
3698 operator==(const _Iterator& __x, const _Sentinel& __y)
3699 { return __y._M_equal(__x); }
3700 };
3701 };
3702
3703 template<typename _Range, typename _Pattern>
3704 split_view(_Range&&, _Pattern&&)
3705 -> split_view<views::all_t<_Range>, views::all_t<_Pattern>>;
3706
3707 template<forward_range _Range>
3708 split_view(_Range&&, range_value_t<_Range>)
3709 -> split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;
3710
3711 namespace views
3712 {
3713 namespace __detail
3714 {
3715 template<typename _Range, typename _Pattern>
3716 concept __can_split_view
3717 = requires { split_view(std::declval<_Range>(), std::declval<_Pattern>()); };
3718 } // namespace __detail
3719
3720 struct _Split : __adaptor::_RangeAdaptor<_Split>
3721 {
3722 template<viewable_range _Range, typename _Pattern>
3723 requires __detail::__can_split_view<_Range, _Pattern>
3724 constexpr auto
3725 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f) const
3726 {
3727 return split_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
3728 }
3729
3730 using _RangeAdaptor<_Split>::operator();
3731 static constexpr int _S_arity = 2;
3732 template<typename _Pattern>
3733 static constexpr bool _S_has_simple_extra_args
3734 = _LazySplit::_S_has_simple_extra_args<_Pattern>;
3735 };
3736
3737 inline constexpr _Split split;
3738 } // namespace views
3739
3740 namespace views
3741 {
3742 struct _Counted
3743 {
3744 template<input_or_output_iterator _Iter>
3745 constexpr auto
3746 operator() [[nodiscard]] (_Iter __i, iter_difference_t<_Iter> __n) const
3747 {
3748 if constexpr (contiguous_iterator<_Iter>)
3749 return span(std::__to_address(__i), __n);
3750 else if constexpr (random_access_iterator<_Iter>)
3751 return subrange(__i, __i + __n);
3752 else
3753 return subrange(counted_iterator(std::move(__i), __n),
3754 default_sentinel);
3755 }
3756 };
3757
3758 inline constexpr _Counted counted{};
3759 } // namespace views
3760
3761 template<view _Vp>
3762 requires (!common_range<_Vp>) && copyable<iterator_t<_Vp>>
3763 class common_view : public view_interface<common_view<_Vp>>
3764 {
3765 private:
3766 _Vp _M_base = _Vp();
3767
3768 public:
3769 common_view() requires default_initializable<_Vp> = default;
3770
3771 constexpr explicit
3772 common_view(_Vp __r)
3773 : _M_base(std::move(__r))
3774 { }
3775
3776 constexpr _Vp
3777 base() const& requires copy_constructible<_Vp>
3778 { return _M_base; }
3779
3780 constexpr _Vp
3781 base() &&
3782 { return std::move(_M_base); }
3783
3784 constexpr auto
3785 begin()
3786 {
3787 if constexpr (random_access_range<_Vp> && sized_range<_Vp>)
3788 return ranges::begin(_M_base);
3789 else
3790 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
3791 (ranges::begin(_M_base));
3792 }
3793
3794 constexpr auto
3795 begin() const requires range<const _Vp>
3796 {
3797 if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>)
3798 return ranges::begin(_M_base);
3799 else
3800 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
3801 (ranges::begin(_M_base));
3802 }
3803
3804 constexpr auto
3805 end()
3806 {
3807 if constexpr (random_access_range<_Vp> && sized_range<_Vp>)
3808 return ranges::begin(_M_base) + ranges::size(_M_base);
3809 else
3810 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
3811 (ranges::end(_M_base));
3812 }
3813
3814 constexpr auto
3815 end() const requires range<const _Vp>
3816 {
3817 if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>)
3818 return ranges::begin(_M_base) + ranges::size(_M_base);
3819 else
3820 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
3821 (ranges::end(_M_base));
3822 }
3823
3824 constexpr auto
3825 size() requires sized_range<_Vp>
3826 { return ranges::size(_M_base); }
3827
3828 constexpr auto
3829 size() const requires sized_range<const _Vp>
3830 { return ranges::size(_M_base); }
3831 };
3832
3833 template<typename _Range>
3834 common_view(_Range&&) -> common_view<views::all_t<_Range>>;
3835
3836 template<typename _Tp>
3837 inline constexpr bool enable_borrowed_range<common_view<_Tp>>
3838 = enable_borrowed_range<_Tp>;
3839
3840 namespace views
3841 {
3842 namespace __detail
3843 {
3844 template<typename _Range>
3845 concept __already_common = common_range<_Range>
3846 && requires { views::all(std::declval<_Range>()); };
3847
3848 template<typename _Range>
3849 concept __can_common_view
3850 = requires { common_view{std::declval<_Range>()}; };
3851 } // namespace __detail
3852
3853 struct _Common : __adaptor::_RangeAdaptorClosure
3854 {
3855 template<viewable_range _Range>
3856 requires __detail::__already_common<_Range>
3857 || __detail::__can_common_view<_Range>
3858 constexpr auto
3859 operator() [[nodiscard]] (_Range&& __r) const
3860 {
3861 if constexpr (__detail::__already_common<_Range>)
3862 return views::all(std::forward<_Range>(__r));
3863 else
3864 return common_view{std::forward<_Range>(__r)};
3865 }
3866
3867 static constexpr bool _S_has_simple_call_op = true;
3868 };
3869
3870 inline constexpr _Common common;
3871 } // namespace views
3872
3873 template<view _Vp>
3874 requires bidirectional_range<_Vp>
3875 class reverse_view : public view_interface<reverse_view<_Vp>>
3876 {
3877 private:
3878 static constexpr bool _S_needs_cached_begin
3879 = !common_range<_Vp> && !(random_access_range<_Vp>
3880 && sized_sentinel_for<sentinel_t<_Vp>,
3881 iterator_t<_Vp>>);
3882
3883 _Vp _M_base = _Vp();
3884 [[no_unique_address]]
3885 __detail::__maybe_present_t<_S_needs_cached_begin,
3886 __detail::_CachedPosition<_Vp>>
3887 _M_cached_begin;
3888
3889 public:
3890 reverse_view() requires default_initializable<_Vp> = default;
3891
3892 constexpr explicit
3893 reverse_view(_Vp __r)
3894 : _M_base(std::move(__r))
3895 { }
3896
3897 constexpr _Vp
3898 base() const& requires copy_constructible<_Vp>
3899 { return _M_base; }
3900
3901 constexpr _Vp
3902 base() &&
3903 { return std::move(_M_base); }
3904
3905 constexpr reverse_iterator<iterator_t<_Vp>>
3906 begin()
3907 {
3908 if constexpr (_S_needs_cached_begin)
3909 if (_M_cached_begin._M_has_value())
3910 return std::make_reverse_iterator(_M_cached_begin._M_get(_M_base));
3911
3912 auto __it = ranges::next(ranges::begin(_M_base), ranges::end(_M_base));
3913 if constexpr (_S_needs_cached_begin)
3914 _M_cached_begin._M_set(_M_base, __it);
3915 return std::make_reverse_iterator(std::move(__it));
3916 }
3917
3918 constexpr auto
3919 begin() requires common_range<_Vp>
3920 { return std::make_reverse_iterator(ranges::end(_M_base)); }
3921
3922 constexpr auto
3923 begin() const requires common_range<const _Vp>
3924 { return std::make_reverse_iterator(ranges::end(_M_base)); }
3925
3926 constexpr reverse_iterator<iterator_t<_Vp>>
3927 end()
3928 { return std::make_reverse_iterator(ranges::begin(_M_base)); }
3929
3930 constexpr auto
3931 end() const requires common_range<const _Vp>
3932 { return std::make_reverse_iterator(ranges::begin(_M_base)); }
3933
3934 constexpr auto
3935 size() requires sized_range<_Vp>
3936 { return ranges::size(_M_base); }
3937
3938 constexpr auto
3939 size() const requires sized_range<const _Vp>
3940 { return ranges::size(_M_base); }
3941 };
3942
3943 template<typename _Range>
3944 reverse_view(_Range&&) -> reverse_view<views::all_t<_Range>>;
3945
3946 template<typename _Tp>
3947 inline constexpr bool enable_borrowed_range<reverse_view<_Tp>>
3948 = enable_borrowed_range<_Tp>;
3949
3950 namespace views
3951 {
3952 namespace __detail
3953 {
3954 template<typename>
3955 inline constexpr bool __is_reversible_subrange = false;
3956
3957 template<typename _Iter, subrange_kind _Kind>
3958 inline constexpr bool
3959 __is_reversible_subrange<subrange<reverse_iterator<_Iter>,
3960 reverse_iterator<_Iter>,
3961 _Kind>> = true;
3962
3963 template<typename>
3964 inline constexpr bool __is_reverse_view = false;
3965
3966 template<typename _Vp>
3967 inline constexpr bool __is_reverse_view<reverse_view<_Vp>> = true;
3968
3969 template<typename _Range>
3970 concept __can_reverse_view
3971 = requires { reverse_view{std::declval<_Range>()}; };
3972 } // namespace __detail
3973
3974 struct _Reverse : __adaptor::_RangeAdaptorClosure
3975 {
3976 template<viewable_range _Range>
3977 requires __detail::__is_reverse_view<remove_cvref_t<_Range>>
3978 || __detail::__is_reversible_subrange<remove_cvref_t<_Range>>
3979 || __detail::__can_reverse_view<_Range>
3980 constexpr auto
3981 operator() [[nodiscard]] (_Range&& __r) const
3982 {
3983 using _Tp = remove_cvref_t<_Range>;
3984 if constexpr (__detail::__is_reverse_view<_Tp>)
3985 return std::forward<_Range>(__r).base();
3986 else if constexpr (__detail::__is_reversible_subrange<_Tp>)
3987 {
3988 using _Iter = decltype(ranges::begin(__r).base());
3989 if constexpr (sized_range<_Tp>)
3990 return subrange<_Iter, _Iter, subrange_kind::sized>
3991 {__r.end().base(), __r.begin().base(), __r.size()};
3992 else
3993 return subrange<_Iter, _Iter, subrange_kind::unsized>
3994 {__r.end().base(), __r.begin().base()};
3995 }
3996 else
3997 return reverse_view{std::forward<_Range>(__r)};
3998 }
3999
4000 static constexpr bool _S_has_simple_call_op = true;
4001 };
4002
4003 inline constexpr _Reverse reverse;
4004 } // namespace views
4005
4006 namespace __detail
4007 {
4008 template<typename _Tp, size_t _Nm>
4009 concept __has_tuple_element = requires(_Tp __t)
4010 {
4011 typename tuple_size<_Tp>::type;
4012 requires _Nm < tuple_size_v<_Tp>;
4013 typename tuple_element_t<_Nm, _Tp>;
4014 { std::get<_Nm>(__t) }
4015 -> convertible_to<const tuple_element_t<_Nm, _Tp>&>;
4016 };
4017
4018 template<typename _Tp, size_t _Nm>
4019 concept __returnable_element
4020 = is_reference_v<_Tp> || move_constructible<tuple_element_t<_Nm, _Tp>>;
4021 }
4022
4023 template<input_range _Vp, size_t _Nm>
4024 requires view<_Vp>
4025 && __detail::__has_tuple_element<range_value_t<_Vp>, _Nm>
4026 && __detail::__has_tuple_element<remove_reference_t<range_reference_t<_Vp>>,
4027 _Nm>
4028 && __detail::__returnable_element<range_reference_t<_Vp>, _Nm>
4029 class elements_view : public view_interface<elements_view<_Vp, _Nm>>
4030 {
4031 public:
4032 elements_view() requires default_initializable<_Vp> = default;
4033
4034 constexpr explicit
4035 elements_view(_Vp __base)
4036 : _M_base(std::move(__base))
4037 { }
4038
4039 constexpr _Vp
4040 base() const& requires copy_constructible<_Vp>
4041 { return _M_base; }
4042
4043 constexpr _Vp
4044 base() &&
4045 { return std::move(_M_base); }
4046
4047 constexpr auto
4048 begin() requires (!__detail::__simple_view<_Vp>)
4049 { return _Iterator<false>(ranges::begin(_M_base)); }
4050
4051 constexpr auto
4052 begin() const requires range<const _Vp>
4053 { return _Iterator<true>(ranges::begin(_M_base)); }
4054
4055 constexpr auto
4056 end() requires (!__detail::__simple_view<_Vp> && !common_range<_Vp>)
4057 { return _Sentinel<false>{ranges::end(_M_base)}; }
4058
4059 constexpr auto
4060 end() requires (!__detail::__simple_view<_Vp> && common_range<_Vp>)
4061 { return _Iterator<false>{ranges::end(_M_base)}; }
4062
4063 constexpr auto
4064 end() const requires range<const _Vp>
4065 { return _Sentinel<true>{ranges::end(_M_base)}; }
4066
4067 constexpr auto
4068 end() const requires common_range<const _Vp>
4069 { return _Iterator<true>{ranges::end(_M_base)}; }
4070
4071 constexpr auto
4072 size() requires sized_range<_Vp>
4073 { return ranges::size(_M_base); }
4074
4075 constexpr auto
4076 size() const requires sized_range<const _Vp>
4077 { return ranges::size(_M_base); }
4078
4079 private:
4080 template<bool _Const>
4081 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
4082
4083 template<bool _Const>
4084 struct __iter_cat
4085 { };
4086
4087 template<bool _Const>
4088 requires forward_range<_Base<_Const>>
4089 struct __iter_cat<_Const>
4090 {
4091 private:
4092 static auto _S_iter_cat()
4093 {
4094 using _Base = elements_view::_Base<_Const>;
4095 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
4096 using _Res = decltype((std::get<_Nm>(*std::declval<iterator_t<_Base>>())));
4097 if constexpr (!is_lvalue_reference_v<_Res>)
4098 return input_iterator_tag{};
4099 else if constexpr (derived_from<_Cat, random_access_iterator_tag>)
4100 return random_access_iterator_tag{};
4101 else
4102 return _Cat{};
4103 }
4104 public:
4105 using iterator_category = decltype(_S_iter_cat());
4106 };
4107
4108 template<bool _Const>
4109 struct _Sentinel;
4110
4111 template<bool _Const>
4112 struct _Iterator : __iter_cat<_Const>
4113 {
4114 private:
4115 using _Base = elements_view::_Base<_Const>;
4116
4117 iterator_t<_Base> _M_current = iterator_t<_Base>();
4118
4119 static constexpr decltype(auto)
4120 _S_get_element(const iterator_t<_Base>& __i)
4121 {
4122 if constexpr (is_reference_v<range_reference_t<_Base>>)
4123 return std::get<_Nm>(*__i);
4124 else
4125 {
4126 using _Et = remove_cv_t<tuple_element_t<_Nm, range_reference_t<_Base>>>;
4127 return static_cast<_Et>(std::get<_Nm>(*__i));
4128 }
4129 }
4130
4131 static auto
4132 _S_iter_concept()
4133 {
4134 if constexpr (random_access_range<_Base>)
4135 return random_access_iterator_tag{};
4136 else if constexpr (bidirectional_range<_Base>)
4137 return bidirectional_iterator_tag{};
4138 else if constexpr (forward_range<_Base>)
4139 return forward_iterator_tag{};
4140 else
4141 return input_iterator_tag{};
4142 }
4143
4144 friend _Iterator<!_Const>;
4145
4146 public:
4147 using iterator_concept = decltype(_S_iter_concept());
4148 // iterator_category defined in elements_view::__iter_cat
4149 using value_type
4150 = remove_cvref_t<tuple_element_t<_Nm, range_value_t<_Base>>>;
4151 using difference_type = range_difference_t<_Base>;
4152
4153 _Iterator() requires default_initializable<iterator_t<_Base>> = default;
4154
4155 constexpr explicit
4156 _Iterator(iterator_t<_Base> __current)
4157 : _M_current(std::move(__current))
4158 { }
4159
4160 constexpr
4161 _Iterator(_Iterator<!_Const> __i)
4162 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
4163 : _M_current(std::move(__i._M_current))
4164 { }
4165
4166 constexpr const iterator_t<_Base>&
4167 base() const& noexcept
4168 { return _M_current; }
4169
4170 constexpr iterator_t<_Base>
4171 base() &&
4172 { return std::move(_M_current); }
4173
4174 constexpr decltype(auto)
4175 operator*() const
4176 { return _S_get_element(_M_current); }
4177
4178 constexpr _Iterator&
4179 operator++()
4180 {
4181 ++_M_current;
4182 return *this;
4183 }
4184
4185 constexpr void
4186 operator++(int)
4187 { ++_M_current; }
4188
4189 constexpr _Iterator
4190 operator++(int) requires forward_range<_Base>
4191 {
4192 auto __tmp = *this;
4193 ++_M_current;
4194 return __tmp;
4195 }
4196
4197 constexpr _Iterator&
4198 operator--() requires bidirectional_range<_Base>
4199 {
4200 --_M_current;
4201 return *this;
4202 }
4203
4204 constexpr _Iterator
4205 operator--(int) requires bidirectional_range<_Base>
4206 {
4207 auto __tmp = *this;
4208 --_M_current;
4209 return __tmp;
4210 }
4211
4212 constexpr _Iterator&
4213 operator+=(difference_type __n)
4214 requires random_access_range<_Base>
4215 {
4216 _M_current += __n;
4217 return *this;
4218 }
4219
4220 constexpr _Iterator&
4221 operator-=(difference_type __n)
4222 requires random_access_range<_Base>
4223 {
4224 _M_current -= __n;
4225 return *this;
4226 }
4227
4228 constexpr decltype(auto)
4229 operator[](difference_type __n) const
4230 requires random_access_range<_Base>
4231 { return _S_get_element(_M_current + __n); }
4232
4233 friend constexpr bool
4234 operator==(const _Iterator& __x, const _Iterator& __y)
4235 requires equality_comparable<iterator_t<_Base>>
4236 { return __x._M_current == __y._M_current; }
4237
4238 friend constexpr bool
4239 operator<(const _Iterator& __x, const _Iterator& __y)
4240 requires random_access_range<_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 __y._M_current < __x._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 !(__x._M_current > __y._M_current); }
4257
4258#ifdef __cpp_lib_three_way_comparison
4259 friend constexpr auto
4260 operator<=>(const _Iterator& __x, const _Iterator& __y)
4261 requires random_access_range<_Base>
4262 && three_way_comparable<iterator_t<_Base>>
4263 { return __x._M_current <=> __y._M_current; }
4264#endif
4265
4266 friend constexpr _Iterator
4267 operator+(const _Iterator& __x, difference_type __y)
4268 requires random_access_range<_Base>
4269 { return _Iterator{__x} += __y; }
4270
4271 friend constexpr _Iterator
4272 operator+(difference_type __x, const _Iterator& __y)
4273 requires random_access_range<_Base>
4274 { return __y + __x; }
4275
4276 friend constexpr _Iterator
4277 operator-(const _Iterator& __x, difference_type __y)
4278 requires random_access_range<_Base>
4279 { return _Iterator{__x} -= __y; }
4280
4281 // _GLIBCXX_RESOLVE_LIB_DEFECTS
4282 // 3483. transform_view::iterator's difference is overconstrained
4283 friend constexpr difference_type
4284 operator-(const _Iterator& __x, const _Iterator& __y)
4285 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
4286 { return __x._M_current - __y._M_current; }
4287
4288 template <bool> friend struct _Sentinel;
4289 };
4290
4291 template<bool _Const>
4292 struct _Sentinel
4293 {
4294 private:
4295 template<bool _Const2>
4296 constexpr bool
4297 _M_equal(const _Iterator<_Const2>& __x) const
4298 { return __x._M_current == _M_end; }
4299
4300 template<bool _Const2>
4301 constexpr auto
4302 _M_distance_from(const _Iterator<_Const2>& __i) const
4303 { return _M_end - __i._M_current; }
4304
4305 using _Base = elements_view::_Base<_Const>;
4306 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
4307
4308 public:
4309 _Sentinel() = default;
4310
4311 constexpr explicit
4312 _Sentinel(sentinel_t<_Base> __end)
4313 : _M_end(std::move(__end))
4314 { }
4315
4316 constexpr
4317 _Sentinel(_Sentinel<!_Const> __other)
4318 requires _Const
4319 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
4320 : _M_end(std::move(__other._M_end))
4321 { }
4322
4323 constexpr sentinel_t<_Base>
4324 base() const
4325 { return _M_end; }
4326
4327 template<bool _Const2>
4328 requires sentinel_for<sentinel_t<_Base>,
4329 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
4330 friend constexpr bool
4331 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
4332 { return __y._M_equal(__x); }
4333
4334 template<bool _Const2,
4335 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
4336 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
4337 friend constexpr range_difference_t<_Base2>
4338 operator-(const _Iterator<_Const2>& __x, const _Sentinel& __y)
4339 { return -__y._M_distance_from(__x); }
4340
4341 template<bool _Const2,
4342 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
4343 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
4344 friend constexpr range_difference_t<_Base2>
4345 operator-(const _Sentinel& __x, const _Iterator<_Const2>& __y)
4346 { return __x._M_distance_from(__y); }
4347
4348 friend _Sentinel<!_Const>;
4349 };
4350
4351 _Vp _M_base = _Vp();
4352 };
4353
4354 template<typename _Tp, size_t _Nm>
4355 inline constexpr bool enable_borrowed_range<elements_view<_Tp, _Nm>>
4356 = enable_borrowed_range<_Tp>;
4357
4358 template<typename _Range>
4359 using keys_view = elements_view<views::all_t<_Range>, 0>;
4360
4361 template<typename _Range>
4362 using values_view = elements_view<views::all_t<_Range>, 1>;
4363
4364 namespace views
4365 {
4366 namespace __detail
4367 {
4368 template<size_t _Nm, typename _Range>
4369 concept __can_elements_view
4370 = requires { elements_view<all_t<_Range>, _Nm>{std::declval<_Range>()}; };
4371 } // namespace __detail
4372
4373 template<size_t _Nm>
4374 struct _Elements : __adaptor::_RangeAdaptorClosure
4375 {
4376 template<viewable_range _Range>
4377 requires __detail::__can_elements_view<_Nm, _Range>
4378 constexpr auto
4379 operator() [[nodiscard]] (_Range&& __r) const
4380 {
4381 return elements_view<all_t<_Range>, _Nm>{std::forward<_Range>(__r)};
4382 }
4383
4384 static constexpr bool _S_has_simple_call_op = true;
4385 };
4386
4387 template<size_t _Nm>
4388 inline constexpr _Elements<_Nm> elements;
4389 inline constexpr auto keys = elements<0>;
4390 inline constexpr auto values = elements<1>;
4391 } // namespace views
4392
4393#if __cplusplus > 202002L
4394
4395#define __cpp_lib_ranges_zip 202110L
4396
4397 namespace __detail
4398 {
4399 template<typename... _Rs>
4400 concept __zip_is_common = (sizeof...(_Rs) == 1 && (common_range<_Rs> && ...))
4401 || (!(bidirectional_range<_Rs> && ...) && (common_range<_Rs> && ...))
4402 || ((random_access_range<_Rs> && ...) && (sized_range<_Rs> && ...));
4403
4404 template<typename... _Ts>
4405 struct __tuple_or_pair
4406 { using type = std::tuple<_Ts...>; };
4407
4408 template<typename _Tp, typename _Up>
4409 struct __tuple_or_pair<_Tp, _Up>
4410 { using type = pair<_Tp, _Up>; };
4411
4412 template<typename... _Ts>
4413 using __tuple_or_pair_t = typename __tuple_or_pair<_Ts...>::type;
4414
4415 template<typename _Fp, typename _Tuple>
4416 constexpr auto
4417 __tuple_transform(_Fp&& __f, _Tuple&& __tuple)
4418 {
4419 return std::apply([&]<typename... _Ts>(_Ts&&... __elts) {
4420 return __tuple_or_pair_t<invoke_result_t<_Fp&, _Ts>...>
4421 (std::__invoke(__f, std::forward<_Ts>(__elts))...);
4422 }, std::forward<_Tuple>(__tuple));
4423 }
4424
4425 template<typename _Fp, typename _Tuple>
4426 constexpr void
4427 __tuple_for_each(_Fp&& __f, _Tuple&& __tuple)
4428 {
4429 std::apply([&]<typename... _Ts>(_Ts&&... __elts) {
4430 (std::__invoke(__f, std::forward<_Ts>(__elts)), ...);
4431 }, std::forward<_Tuple>(__tuple));
4432 }
4433 } // namespace __detail
4434
4435 template<input_range... _Vs>
4436 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0)
4437 class zip_view : public view_interface<zip_view<_Vs...>>
4438 {
4439 tuple<_Vs...> _M_views;
4440
4441 template<bool> class _Iterator;
4442 template<bool> class _Sentinel;
4443
4444 public:
4445 zip_view() = default;
4446
4447 constexpr explicit
4448 zip_view(_Vs... __views)
4449 : _M_views(std::move(__views)...)
4450 { }
4451
4452 constexpr auto
4453 begin() requires (!(__detail::__simple_view<_Vs> && ...))
4454 { return _Iterator<false>(__detail::__tuple_transform(ranges::begin, _M_views)); }
4455
4456 constexpr auto
4457 begin() const requires (range<const _Vs> && ...)
4458 { return _Iterator<true>(__detail::__tuple_transform(ranges::begin, _M_views)); }
4459
4460 constexpr auto
4461 end() requires (!(__detail::__simple_view<_Vs> && ...))
4462 {
4463 if constexpr (!__detail::__zip_is_common<_Vs...>)
4464 return _Sentinel<false>(__detail::__tuple_transform(ranges::end, _M_views));
4465 else if constexpr ((random_access_range<_Vs> && ...))
4466 return begin() + iter_difference_t<_Iterator<false>>(size());
4467 else
4468 return _Iterator<false>(__detail::__tuple_transform(ranges::end, _M_views));
4469 }
4470
4471 constexpr auto
4472 end() const requires (range<const _Vs> && ...)
4473 {
4474 if constexpr (!__detail::__zip_is_common<const _Vs...>)
4475 return _Sentinel<true>(__detail::__tuple_transform(ranges::end, _M_views));
4476 else if constexpr ((random_access_range<const _Vs> && ...))
4477 return begin() + iter_difference_t<_Iterator<true>>(size());
4478 else
4479 return _Iterator<true>(__detail::__tuple_transform(ranges::end, _M_views));
4480 }
4481
4482 constexpr auto
4483 size() requires (sized_range<_Vs> && ...)
4484 {
4485 return std::apply([](auto... sizes) {
4486 using _CT = __detail::__make_unsigned_like_t<common_type_t<decltype(sizes)...>>;
4487 return ranges::min({_CT(sizes)...});
4488 }, __detail::__tuple_transform(ranges::size, _M_views));
4489 }
4490
4491 constexpr auto
4492 size() const requires (sized_range<const _Vs> && ...)
4493 {
4494 return std::apply([](auto... sizes) {
4495 using _CT = __detail::__make_unsigned_like_t<common_type_t<decltype(sizes)...>>;
4496 return ranges::min({_CT(sizes)...});
4497 }, __detail::__tuple_transform(ranges::size, _M_views));
4498 }
4499 };
4500
4501 template<typename... _Rs>
4502 zip_view(_Rs&&...) -> zip_view<views::all_t<_Rs>...>;
4503
4504 template<typename... _Views>
4505 inline constexpr bool enable_borrowed_range<zip_view<_Views...>>
4506 = (enable_borrowed_range<_Views> && ...);
4507
4508 namespace __detail
4509 {
4510 template<bool _Const, typename... _Vs>
4511 concept __all_random_access
4512 = (random_access_range<__maybe_const_t<_Const, _Vs>> && ...);
4513
4514 template<bool _Const, typename... _Vs>
4515 concept __all_bidirectional
4516 = (bidirectional_range<__maybe_const_t<_Const, _Vs>> && ...);
4517
4518 template<bool _Const, typename... _Vs>
4519 concept __all_forward
4520 = (forward_range<__maybe_const_t<_Const, _Vs>> && ...);
4521
4522 template<bool _Const, typename... _Views>
4523 struct __zip_view_iter_cat
4524 { };
4525
4526 template<bool _Const, typename... _Views>
4527 requires __all_forward<_Const, _Views...>
4528 struct __zip_view_iter_cat<_Const, _Views...>
4529 { using iterator_category = input_iterator_tag; };
4530 } // namespace __detail
4531
4532 template<input_range... _Vs>
4533 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0)
4534 template<bool _Const>
4535 class zip_view<_Vs...>::_Iterator
4536 : public __detail::__zip_view_iter_cat<_Const, _Vs...>
4537 {
4538#ifdef __clang__ // LLVM-61763 workaround
4539 public:
4540#endif
4541 __detail::__tuple_or_pair_t<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>...> _M_current;
4542
4543 constexpr explicit
4544 _Iterator(decltype(_M_current) __current)
4545 : _M_current(std::move(__current))
4546 { }
4547
4548 static auto
4549 _S_iter_concept()
4550 {
4551 if constexpr (__detail::__all_random_access<_Const, _Vs...>)
4552 return random_access_iterator_tag{};
4553 else if constexpr (__detail::__all_bidirectional<_Const, _Vs...>)
4554 return bidirectional_iterator_tag{};
4555 else if constexpr (__detail::__all_forward<_Const, _Vs...>)
4556 return forward_iterator_tag{};
4557 else
4558 return input_iterator_tag{};
4559 }
4560
4561#ifndef __clang__ // LLVM-61763 workaround
4562 template<copy_constructible _Fp, input_range... _Ws>
4563 requires (view<_Ws> && ...) && (sizeof...(_Ws) > 0) && is_object_v<_Fp>
4564 && regular_invocable<_Fp&, range_reference_t<_Ws>...>
4565 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Ws>...>>
4566 friend class zip_transform_view;
4567#endif
4568
4569 public:
4570 // iterator_category defined in __zip_view_iter_cat
4571 using iterator_concept = decltype(_S_iter_concept());
4572 using value_type
4573 = __detail::__tuple_or_pair_t<range_value_t<__detail::__maybe_const_t<_Const, _Vs>>...>;
4574 using difference_type
4575 = common_type_t<range_difference_t<__detail::__maybe_const_t<_Const, _Vs>>...>;
4576
4577 _Iterator() = default;
4578
4579 constexpr
4580 _Iterator(_Iterator<!_Const> __i)
4581 requires _Const
4582 && (convertible_to<iterator_t<_Vs>,
4583 iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4584 : _M_current(std::move(__i._M_current))
4585 { }
4586
4587 constexpr auto
4588 operator*() const
4589 {
4590 auto __f = [](auto& __i) -> decltype(auto) {
4591 return *__i;
4592 };
4593 return __detail::__tuple_transform(__f, _M_current);
4594 }
4595
4596 constexpr _Iterator&
4597 operator++()
4598 {
4599 __detail::__tuple_for_each([](auto& __i) { ++__i; }, _M_current);
4600 return *this;
4601 }
4602
4603 constexpr void
4604 operator++(int)
4605 { ++*this; }
4606
4607 constexpr _Iterator
4608 operator++(int)
4609 requires __detail::__all_forward<_Const, _Vs...>
4610 {
4611 auto __tmp = *this;
4612 ++*this;
4613 return __tmp;
4614 }
4615
4616 constexpr _Iterator&
4617 operator--()
4618 requires __detail::__all_bidirectional<_Const, _Vs...>
4619 {
4620 __detail::__tuple_for_each([](auto& __i) { --__i; }, _M_current);
4621 return *this;
4622 }
4623
4624 constexpr _Iterator
4625 operator--(int)
4626 requires __detail::__all_bidirectional<_Const, _Vs...>
4627 {
4628 auto __tmp = *this;
4629 --*this;
4630 return __tmp;
4631 }
4632
4633 constexpr _Iterator&
4634 operator+=(difference_type __x)
4635 requires __detail::__all_random_access<_Const, _Vs...>
4636 {
4637 auto __f = [&]<typename _It>(_It& __i) {
4638 __i += iter_difference_t<_It>(__x);
4639 };
4640 __detail::__tuple_for_each(__f, _M_current);
4641 return *this;
4642 }
4643
4644 constexpr _Iterator&
4645 operator-=(difference_type __x)
4646 requires __detail::__all_random_access<_Const, _Vs...>
4647 {
4648 auto __f = [&]<typename _It>(_It& __i) {
4649 __i -= iter_difference_t<_It>(__x);
4650 };
4651 __detail::__tuple_for_each(__f, _M_current);
4652 return *this;
4653 }
4654
4655 constexpr auto
4656 operator[](difference_type __n) const
4657 requires __detail::__all_random_access<_Const, _Vs...>
4658 {
4659 auto __f = [&]<typename _It>(_It& __i) -> decltype(auto) {
4660 return __i[iter_difference_t<_It>(__n)];
4661 };
4662 return __detail::__tuple_transform(__f, _M_current);
4663 }
4664
4665 friend constexpr bool
4666 operator==(const _Iterator& __x, const _Iterator& __y)
4667 requires (equality_comparable<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4668 {
4669 if constexpr (__detail::__all_bidirectional<_Const, _Vs...>)
4670 return __x._M_current == __y._M_current;
4671 else
4672 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4673 return ((std::get<_Is>(__x._M_current) == std::get<_Is>(__y._M_current)) || ...);
4674 }(make_index_sequence<sizeof...(_Vs)>{});
4675 }
4676
4677 friend constexpr auto
4678 operator<=>(const _Iterator& __x, const _Iterator& __y)
4679 requires __detail::__all_random_access<_Const, _Vs...>
4680 { return __x._M_current <=> __y._M_current; }
4681
4682 friend constexpr _Iterator
4683 operator+(const _Iterator& __i, difference_type __n)
4684 requires __detail::__all_random_access<_Const, _Vs...>
4685 {
4686 auto __r = __i;
4687 __r += __n;
4688 return __r;
4689 }
4690
4691 friend constexpr _Iterator
4692 operator+(difference_type __n, const _Iterator& __i)
4693 requires __detail::__all_random_access<_Const, _Vs...>
4694 {
4695 auto __r = __i;
4696 __r += __n;
4697 return __r;
4698 }
4699
4700 friend constexpr _Iterator
4701 operator-(const _Iterator& __i, difference_type __n)
4702 requires __detail::__all_random_access<_Const, _Vs...>
4703 {
4704 auto __r = __i;
4705 __r -= __n;
4706 return __r;
4707 }
4708
4709 friend constexpr difference_type
4710 operator-(const _Iterator& __x, const _Iterator& __y)
4711 requires (sized_sentinel_for<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>,
4712 iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4713 {
4714 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4715 return ranges::min({difference_type(std::get<_Is>(__x._M_current)
4716 - std::get<_Is>(__y._M_current))...},
4717 ranges::less{},
4718 [](difference_type __i) {
4719 return __detail::__to_unsigned_like(__i < 0 ? -__i : __i);
4720 });
4721 }(make_index_sequence<sizeof...(_Vs)>{});
4722 }
4723
4724 friend constexpr auto
4725 iter_move(const _Iterator& __i)
4726 { return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
4727
4728 friend constexpr void
4729 iter_swap(const _Iterator& __l, const _Iterator& __r)
4730 requires (indirectly_swappable<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4731 {
4732 [&]<size_t... _Is>(index_sequence<_Is...>) {
4733 (ranges::iter_swap(std::get<_Is>(__l._M_current), std::get<_Is>(__r._M_current)), ...);
4734 }(make_index_sequence<sizeof...(_Vs)>{});
4735 }
4736
4737 friend class zip_view;
4738 };
4739
4740 template<input_range... _Vs>
4741 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0)
4742 template<bool _Const>
4743 class zip_view<_Vs...>::_Sentinel
4744 {
4745 __detail::__tuple_or_pair_t<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>...> _M_end;
4746
4747 constexpr explicit
4748 _Sentinel(decltype(_M_end) __end)
4749 : _M_end(__end)
4750 { }
4751
4752 friend class zip_view;
4753
4754 public:
4755 _Sentinel() = default;
4756
4757 constexpr
4758 _Sentinel(_Sentinel<!_Const> __i)
4759 requires _Const
4760 && (convertible_to<sentinel_t<_Vs>,
4761 sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4762 : _M_end(std::move(__i._M_end))
4763 { }
4764
4765 template<bool _OtherConst>
4766 requires (sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
4767 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
4768 friend constexpr bool
4769 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
4770 {
4771 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4772 return ((std::get<_Is>(__x._M_current) == std::get<_Is>(__y._M_end)) || ...);
4773 }(make_index_sequence<sizeof...(_Vs)>{});
4774 }
4775
4776 template<bool _OtherConst>
4777 requires (sized_sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
4778 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
4779 friend constexpr auto
4780 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
4781 {
4782 using _Ret
4783 = common_type_t<range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vs>>...>;
4784 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4785 return ranges::min({_Ret(std::get<_Is>(__x._M_current) - std::get<_Is>(__y._M_end))...},
4786 ranges::less{},
4787 [](_Ret __i) {
4788 return __detail::__to_unsigned_like(__i < 0 ? -__i : __i);
4789 });
4790 }(make_index_sequence<sizeof...(_Vs)>{});
4791 }
4792
4793 template<bool _OtherConst>
4794 requires (sized_sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
4795 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
4796 friend constexpr auto
4797 operator-(const _Sentinel& __y, const _Iterator<_OtherConst>& __x)
4798 { return -(__x - __y); }
4799 };
4800
4801 namespace views
4802 {
4803 namespace __detail
4804 {
4805 template<typename... _Ts>
4806 concept __can_zip_view
4807 = requires { zip_view<all_t<_Ts>...>(std::declval<_Ts>()...); };
4808 }
4809
4810 struct _Zip
4811 {
4812 template<typename... _Ts>
4813 requires (sizeof...(_Ts) == 0 || __detail::__can_zip_view<_Ts...>)
4814 constexpr auto
4815 operator() [[nodiscard]] (_Ts&&... __ts) const
4816 {
4817 if constexpr (sizeof...(_Ts) == 0)
4818 return views::empty<tuple<>>;
4819 else
4820 return zip_view<all_t<_Ts>...>(std::forward<_Ts>(__ts)...);
4821 }
4822 };
4823
4824 inline constexpr _Zip zip;
4825 }
4826
4827 namespace __detail
4828 {
4829 template<typename _Range, bool _Const>
4830 using __range_iter_cat
4831 = typename iterator_traits<iterator_t<__maybe_const_t<_Const, _Range>>>::iterator_category;
4832 }
4833
4834 template<copy_constructible _Fp, input_range... _Vs>
4835 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && is_object_v<_Fp>
4836 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
4837 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
4838 class zip_transform_view : public view_interface<zip_transform_view<_Fp, _Vs...>>
4839 {
4840 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
4841 zip_view<_Vs...> _M_zip;
4842
4843 using _InnerView = zip_view<_Vs...>;
4844
4845 template<bool _Const>
4846 using __ziperator = iterator_t<__detail::__maybe_const_t<_Const, _InnerView>>;
4847
4848 template<bool _Const>
4849 using __zentinel = sentinel_t<__detail::__maybe_const_t<_Const, _InnerView>>;
4850
4851 template<bool _Const>
4852 using _Base = __detail::__maybe_const_t<_Const, _InnerView>;
4853
4854 template<bool _Const>
4855 struct __iter_cat
4856 { };
4857
4858 template<bool _Const>
4859 requires forward_range<_Base<_Const>>
4860 struct __iter_cat<_Const>
4861 {
4862 private:
4863 static auto
4864 _S_iter_cat()
4865 {
4866 using __detail::__maybe_const_t;
4867 using __detail::__range_iter_cat;
4868 using _Res = invoke_result_t<__maybe_const_t<_Const, _Fp>&,
4869 range_reference_t<__maybe_const_t<_Const, _Vs>>...>;
4870 if constexpr (!is_lvalue_reference_v<_Res>)
4871 return input_iterator_tag{};
4872 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
4873 random_access_iterator_tag> && ...))
4874 return random_access_iterator_tag{};
4875 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
4876 bidirectional_iterator_tag> && ...))
4877 return bidirectional_iterator_tag{};
4878 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
4879 forward_iterator_tag> && ...))
4880 return forward_iterator_tag{};
4881 else
4882 return input_iterator_tag{};
4883 }
4884 public:
4885 using iterator_category = decltype(_S_iter_cat());
4886 };
4887
4888 template<bool> class _Iterator;
4889 template<bool> class _Sentinel;
4890
4891 public:
4892 zip_transform_view() = default;
4893
4894 constexpr explicit
4895 zip_transform_view(_Fp __fun, _Vs... __views)
4896 : _M_fun(std::move(__fun)), _M_zip(std::move(__views)...)
4897 { }
4898
4899 constexpr auto
4900 begin()
4901 { return _Iterator<false>(*this, _M_zip.begin()); }
4902
4903 constexpr auto
4904 begin() const
4905 requires range<const _InnerView>
4906 && regular_invocable<const _Fp&, range_reference_t<const _Vs>...>
4907 { return _Iterator<true>(*this, _M_zip.begin()); }
4908
4909 constexpr auto
4910 end()
4911 {
4912 if constexpr (common_range<_InnerView>)
4913 return _Iterator<false>(*this, _M_zip.end());
4914 else
4915 return _Sentinel<false>(_M_zip.end());
4916 }
4917
4918 constexpr auto
4919 end() const
4920 requires range<const _InnerView>
4921 && regular_invocable<const _Fp&, range_reference_t<const _Vs>...>
4922 {
4923 if constexpr (common_range<const _InnerView>)
4924 return _Iterator<true>(*this, _M_zip.end());
4925 else
4926 return _Sentinel<true>(_M_zip.end());
4927 }
4928
4929 constexpr auto
4930 size() requires sized_range<_InnerView>
4931 { return _M_zip.size(); }
4932
4933 constexpr auto
4934 size() const requires sized_range<const _InnerView>
4935 { return _M_zip.size(); }
4936 };
4937
4938 template<class _Fp, class... Rs>
4939 zip_transform_view(_Fp, Rs&&...) -> zip_transform_view<_Fp, views::all_t<Rs>...>;
4940
4941 template<copy_constructible _Fp, input_range... _Vs>
4942 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && is_object_v<_Fp>
4943 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
4944 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
4945 template<bool _Const>
4946 class zip_transform_view<_Fp, _Vs...>::_Iterator : public __iter_cat<_Const>
4947 {
4948 using _Parent = __detail::__maybe_const_t<_Const, zip_transform_view>;
4949
4950 _Parent* _M_parent = nullptr;
4951 __ziperator<_Const> _M_inner;
4952
4953 constexpr
4954 _Iterator(_Parent& __parent, __ziperator<_Const> __inner)
4955 : _M_parent(std::__addressof(__parent)), _M_inner(std::move(__inner))
4956 { }
4957
4958 friend class zip_transform_view;
4959
4960 public:
4961 // iterator_category defined in zip_transform_view::__iter_cat
4962 using iterator_concept = typename __ziperator<_Const>::iterator_concept;
4963 using value_type
4964 = remove_cvref_t<invoke_result_t<__detail::__maybe_const_t<_Const, _Fp>&,
4965 range_reference_t<__detail::__maybe_const_t<_Const, _Vs>>...>>;
4966 using difference_type = range_difference_t<_Base<_Const>>;
4967
4968 _Iterator() = default;
4969
4970 constexpr
4971 _Iterator(_Iterator<!_Const> __i)
4972 requires _Const && convertible_to<__ziperator<false>, __ziperator<_Const>>
4973 : _M_parent(__i._M_parent), _M_inner(std::move(__i._M_inner))
4974 { }
4975
4976 constexpr decltype(auto)
4977 operator*() const
4978 {
4979 return std::apply([&](const auto&... __iters) -> decltype(auto) {
4980 return std::__invoke(*_M_parent->_M_fun, *__iters...);
4981 }, _M_inner._M_current);
4982 }
4983
4984 constexpr _Iterator&
4985 operator++()
4986 {
4987 ++_M_inner;
4988 return *this;
4989 }
4990
4991 constexpr void
4992 operator++(int)
4993 { ++*this; }
4994
4995 constexpr _Iterator
4996 operator++(int) requires forward_range<_Base<_Const>>
4997 {
4998 auto __tmp = *this;
4999 ++*this;
5000 return __tmp;
5001 }
5002
5003 constexpr _Iterator&
5004 operator--() requires bidirectional_range<_Base<_Const>>
5005 {
5006 --_M_inner;
5007 return *this;
5008 }
5009
5010 constexpr _Iterator
5011 operator--(int) requires bidirectional_range<_Base<_Const>>
5012 {
5013 auto __tmp = *this;
5014 --*this;
5015 return __tmp;
5016 }
5017
5018 constexpr _Iterator&
5019 operator+=(difference_type __x) requires random_access_range<_Base<_Const>>
5020 {
5021 _M_inner += __x;
5022 return *this;
5023 }
5024
5025 constexpr _Iterator&
5026 operator-=(difference_type __x) requires random_access_range<_Base<_Const>>
5027 {
5028 _M_inner -= __x;
5029 return *this;
5030 }
5031
5032 constexpr decltype(auto)
5033 operator[](difference_type __n) const requires random_access_range<_Base<_Const>>
5034 {
5035 return std::apply([&]<typename... _Is>(const _Is&... __iters) -> decltype(auto) {
5036 return std::__invoke(*_M_parent->_M_fun, __iters[iter_difference_t<_Is>(__n)]...);
5037 }, _M_inner._M_current);
5038 }
5039
5040 friend constexpr bool
5041 operator==(const _Iterator& __x, const _Iterator& __y)
5042 requires equality_comparable<__ziperator<_Const>>
5043 { return __x._M_inner == __y._M_inner; }
5044
5045 friend constexpr auto
5046 operator<=>(const _Iterator& __x, const _Iterator& __y)
5047 requires random_access_range<_Base<_Const>>
5048 { return __x._M_inner <=> __y._M_inner; }
5049
5050 friend constexpr _Iterator
5051 operator+(const _Iterator& __i, difference_type __n)
5052 requires random_access_range<_Base<_Const>>
5053 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5054
5055 friend constexpr _Iterator
5056 operator+(difference_type __n, const _Iterator& __i)
5057 requires random_access_range<_Base<_Const>>
5058 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5059
5060 friend constexpr _Iterator
5061 operator-(const _Iterator& __i, difference_type __n)
5062 requires random_access_range<_Base<_Const>>
5063 { return _Iterator(*__i._M_parent, __i._M_inner - __n); }
5064
5065 friend constexpr difference_type
5066 operator-(const _Iterator& __x, const _Iterator& __y)
5067 requires sized_sentinel_for<__ziperator<_Const>, __ziperator<_Const>>
5068 { return __x._M_inner - __y._M_inner; }
5069 };
5070
5071 template<copy_constructible _Fp, input_range... _Vs>
5072 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && is_object_v<_Fp>
5073 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
5074 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
5075 template<bool _Const>
5076 class zip_transform_view<_Fp, _Vs...>::_Sentinel
5077 {
5078 __zentinel<_Const> _M_inner;
5079
5080 constexpr explicit
5081 _Sentinel(__zentinel<_Const> __inner)
5082 : _M_inner(__inner)
5083 { }
5084
5085 friend class zip_transform_view;
5086
5087 public:
5088 _Sentinel() = default;
5089
5090 constexpr
5091 _Sentinel(_Sentinel<!_Const> __i)
5092 requires _Const && convertible_to<__zentinel<false>, __zentinel<_Const>>
5093 : _M_inner(std::move(__i._M_inner))
5094 { }
5095
5096 template<bool _OtherConst>
5097 requires sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5098 friend constexpr bool
5099 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5100 { return __x._M_inner == __y._M_inner; }
5101
5102 template<bool _OtherConst>
5103 requires sized_sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5104 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5105 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5106 { return __x._M_inner - __y._M_inner; }
5107
5108 template<bool _OtherConst>
5109 requires sized_sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5110 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5111 operator-(const _Sentinel& __x, const _Iterator<_OtherConst>& __y)
5112 { return __x._M_inner - __y._M_inner; }
5113 };
5114
5115 namespace views
5116 {
5117 namespace __detail
5118 {
5119 template<typename _Fp, typename... _Ts>
5120 concept __can_zip_transform_view
5121 = requires { zip_transform_view(std::declval<_Fp>(), std::declval<_Ts>()...); };
5122 }
5123
5124 struct _ZipTransform
5125 {
5126 template<typename _Fp, typename... _Ts>
5127 requires (sizeof...(_Ts) == 0) || __detail::__can_zip_transform_view<_Fp, _Ts...>
5128 constexpr auto
5129 operator() [[nodiscard]] (_Fp&& __f, _Ts&&... __ts) const
5130 {
5131 if constexpr (sizeof...(_Ts) == 0)
5132 return views::empty<decay_t<invoke_result_t<decay_t<_Fp>&>>>;
5133 else
5134 return zip_transform_view(std::forward<_Fp>(__f), std::forward<_Ts>(__ts)...);
5135 }
5136 };
5137
5138 inline constexpr _ZipTransform zip_transform;
5139 }
5140
5141 template<forward_range _Vp, size_t _Nm>
5142 requires view<_Vp> && (_Nm > 0)
5143 class adjacent_view : public view_interface<adjacent_view<_Vp, _Nm>>
5144 {
5145 _Vp _M_base = _Vp();
5146
5147 template<bool> class _Iterator;
5148 template<bool> class _Sentinel;
5149
5150 struct __as_sentinel
5151 { };
5152
5153 public:
5154 adjacent_view() requires default_initializable<_Vp> = default;
5155
5156 constexpr explicit
5157 adjacent_view(_Vp __base)
5158 : _M_base(std::move(__base))
5159 { }
5160
5161 constexpr auto
5162 begin() requires (!__detail::__simple_view<_Vp>)
5163 { return _Iterator<false>(ranges::begin(_M_base), ranges::end(_M_base)); }
5164
5165 constexpr auto
5166 begin() const requires range<const _Vp>
5167 { return _Iterator<true>(ranges::begin(_M_base), ranges::end(_M_base)); }
5168
5169 constexpr auto
5170 end() requires (!__detail::__simple_view<_Vp>)
5171 {
5172 if constexpr (common_range<_Vp>)
5173 return _Iterator<false>(__as_sentinel{}, ranges::begin(_M_base), ranges::end(_M_base));
5174 else
5175 return _Sentinel<false>(ranges::end(_M_base));
5176 }
5177
5178 constexpr auto
5179 end() const requires range<const _Vp>
5180 {
5181 if constexpr (common_range<const _Vp>)
5182 return _Iterator<true>(__as_sentinel{}, ranges::begin(_M_base), ranges::end(_M_base));
5183 else
5184 return _Sentinel<true>(ranges::end(_M_base));
5185 }
5186
5187 constexpr auto
5188 size() requires sized_range<_Vp>
5189 {
5190 using _ST = decltype(ranges::size(_M_base));
5191 using _CT = common_type_t<_ST, size_t>;
5192 auto __sz = static_cast<_CT>(ranges::size(_M_base));
5193 __sz -= std::min<_CT>(__sz, _Nm - 1);
5194 return static_cast<_ST>(__sz);
5195 }
5196
5197 constexpr auto
5198 size() const requires sized_range<const _Vp>
5199 {
5200 using _ST = decltype(ranges::size(_M_base));
5201 using _CT = common_type_t<_ST, size_t>;
5202 auto __sz = static_cast<_CT>(ranges::size(_M_base));
5203 __sz -= std::min<_CT>(__sz, _Nm - 1);
5204 return static_cast<_ST>(__sz);
5205 }
5206 };
5207
5208 template<typename _Vp, size_t _Nm>
5209 inline constexpr bool enable_borrowed_range<adjacent_view<_Vp, _Nm>>
5210 = enable_borrowed_range<_Vp>;
5211
5212 namespace __detail
5213 {
5214 // Yields tuple<_Tp, ..., _Tp> with _Nm elements.
5215 template<typename _Tp, size_t _Nm>
5216 using __repeated_tuple = decltype(std::tuple_cat(std::declval<array<_Tp, _Nm>>()));
5217
5218 // For a functor F that is callable with N arguments, the expression
5219 // declval<__unarize<F, N>>(x) is equivalent to declval<F>(x, ..., x).
5220 template<typename _Fp, size_t _Nm>
5221 struct __unarize
5222 {
5223 template<typename... _Ts>
5224 static invoke_result_t<_Fp, _Ts...>
5225 __tuple_apply(const tuple<_Ts...>&); // not defined
5226
5227 template<typename _Tp>
5228 decltype(__tuple_apply(std::declval<__repeated_tuple<_Tp, _Nm>>()))
5229 operator()(_Tp&&); // not defined
5230 };
5231 }
5232
5233 template<forward_range _Vp, size_t _Nm>
5234 requires view<_Vp> && (_Nm > 0)
5235 template<bool _Const>
5236 class adjacent_view<_Vp, _Nm>::_Iterator
5237 {
5238#ifdef __clang__ // LLVM-61763 workaround
5239 public:
5240#endif
5241 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5242 array<iterator_t<_Base>, _Nm> _M_current = array<iterator_t<_Base>, _Nm>();
5243
5244 constexpr
5245 _Iterator(iterator_t<_Base> __first, sentinel_t<_Base> __last)
5246 {
5247 for (auto& __i : _M_current)
5248 {
5249 __i = __first;
5250 ranges::advance(__first, 1, __last);
5251 }
5252 }
5253
5254 constexpr
5255 _Iterator(__as_sentinel, iterator_t<_Base> __first, iterator_t<_Base> __last)
5256 {
5257 if constexpr (!bidirectional_range<_Base>)
5258 for (auto& __it : _M_current)
5259 __it = __last;
5260 else
5261 for (size_t __i = 0; __i < _Nm; ++__i)
5262 {
5263 _M_current[_Nm - 1 - __i] = __last;
5264 ranges::advance(__last, -1, __first);
5265 }
5266 }
5267
5268 static auto
5269 _S_iter_concept()
5270 {
5271 if constexpr (random_access_range<_Base>)
5272 return random_access_iterator_tag{};
5273 else if constexpr (bidirectional_range<_Base>)
5274 return bidirectional_iterator_tag{};
5275 else
5276 return forward_iterator_tag{};
5277 }
5278
5279 friend class adjacent_view;
5280
5281#ifndef __clang__ // LLVM-61763 workaround
5282 template<forward_range _Wp, copy_constructible _Fp, size_t _Mm>
5283 requires view<_Wp> && (_Mm > 0) && is_object_v<_Fp>
5284 && regular_invocable<__detail::__unarize<_Fp&, _Mm>, range_reference_t<_Wp>>
5285 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Mm>,
5286 range_reference_t<_Wp>>>
5287 friend class adjacent_transform_view;
5288#endif
5289
5290 public:
5291 using iterator_category = input_iterator_tag;
5292 using iterator_concept = decltype(_S_iter_concept());
5293 using value_type = conditional_t<_Nm == 2,
5294 pair<range_value_t<_Base>, range_value_t<_Base>>,
5295 __detail::__repeated_tuple<range_value_t<_Base>, _Nm>>;
5296 using difference_type = range_difference_t<_Base>;
5297
5298 _Iterator() = default;
5299
5300 constexpr
5301 _Iterator(_Iterator<!_Const> __i)
5302 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
5303 {
5304 for (size_t __j = 0; __j < _Nm; ++__j)
5305 _M_current[__j] = std::move(__i._M_current[__j]);
5306 }
5307
5308 constexpr auto
5309 operator*() const
5310 {
5311 auto __f = [](auto& __i) -> decltype(auto) { return *__i; };
5312 return __detail::__tuple_transform(__f, _M_current);
5313 }
5314
5315 constexpr _Iterator&
5316 operator++()
5317 {
5318 for (auto& __i : _M_current)
5319 ++__i;
5320 return *this;
5321 }
5322
5323 constexpr _Iterator
5324 operator++(int)
5325 {
5326 auto __tmp = *this;
5327 ++*this;
5328 return __tmp;
5329 }
5330
5331 constexpr _Iterator&
5332 operator--() requires bidirectional_range<_Base>
5333 {
5334 for (auto& __i : _M_current)
5335 --__i;
5336 return *this;
5337 }
5338
5339 constexpr _Iterator
5340 operator--(int) requires bidirectional_range<_Base>
5341 {
5342 auto __tmp = *this;
5343 --*this;
5344 return __tmp;
5345 }
5346
5347 constexpr _Iterator&
5348 operator+=(difference_type __x)
5349 requires random_access_range<_Base>
5350 {
5351 for (auto& __i : _M_current)
5352 __i += __x;
5353 return *this;
5354 }
5355
5356 constexpr _Iterator&
5357 operator-=(difference_type __x)
5358 requires random_access_range<_Base>
5359 {
5360 for (auto& __i : _M_current)
5361 __i -= __x;
5362 return *this;
5363 }
5364
5365 constexpr auto
5366 operator[](difference_type __n) const
5367 requires random_access_range<_Base>
5368 {
5369 auto __f = [&](auto& __i) -> decltype(auto) { return __i[__n]; };
5370 return __detail::__tuple_transform(__f, _M_current);
5371 }
5372
5373 friend constexpr bool
5374 operator==(const _Iterator& __x, const _Iterator& __y)
5375 { return __x._M_current.back() == __y._M_current.back(); }
5376
5377 friend constexpr bool
5378 operator<(const _Iterator& __x, const _Iterator& __y)
5379 requires random_access_range<_Base>
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 __y < __x; }
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 !(__x < __y); }
5396
5397 friend constexpr auto
5398 operator<=>(const _Iterator& __x, const _Iterator& __y)
5399 requires random_access_range<_Base>
5400 && three_way_comparable<iterator_t<_Base>>
5401 { return __x._M_current.back() <=> __y._M_current.back(); }
5402
5403 friend constexpr _Iterator
5404 operator+(const _Iterator& __i, difference_type __n)
5405 requires random_access_range<_Base>
5406 {
5407 auto __r = __i;
5408 __r += __n;
5409 return __r;
5410 }
5411
5412 friend constexpr _Iterator
5413 operator+(difference_type __n, const _Iterator& __i)
5414 requires random_access_range<_Base>
5415 {
5416 auto __r = __i;
5417 __r += __n;
5418 return __r;
5419 }
5420
5421 friend constexpr _Iterator
5422 operator-(const _Iterator& __i, difference_type __n)
5423 requires random_access_range<_Base>
5424 {
5425 auto __r = __i;
5426 __r -= __n;
5427 return __r;
5428 }
5429
5430 friend constexpr difference_type
5431 operator-(const _Iterator& __x, const _Iterator& __y)
5432 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
5433 { return __x._M_current.back() - __y._M_current.back(); }
5434
5435 friend constexpr auto
5436 iter_move(const _Iterator& __i)
5437 { return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
5438
5439 friend constexpr void
5440 iter_swap(const _Iterator& __l, const _Iterator& __r)
5441 requires indirectly_swappable<iterator_t<_Base>>
5442 {
5443 for (size_t __i = 0; __i < _Nm; __i++)
5444 ranges::iter_swap(__l._M_current[__i], __r._M_current[__i]);
5445 }
5446 };
5447
5448 template<forward_range _Vp, size_t _Nm>
5449 requires view<_Vp> && (_Nm > 0)
5450 template<bool _Const>
5451 class adjacent_view<_Vp, _Nm>::_Sentinel
5452 {
5453 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5454
5455 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
5456
5457 constexpr explicit
5458 _Sentinel(sentinel_t<_Base> __end)
5459 : _M_end(__end)
5460 { }
5461
5462 friend class adjacent_view;
5463
5464 public:
5465 _Sentinel() = default;
5466
5467 constexpr
5468 _Sentinel(_Sentinel<!_Const> __i)
5469 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
5470 : _M_end(std::move(__i._M_end))
5471 { }
5472
5473 template<bool _OtherConst>
5474 requires sentinel_for<sentinel_t<_Base>,
5475 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5476 friend constexpr bool
5477 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5478 { return __x._M_current.back() == __y._M_end; }
5479
5480 template<bool _OtherConst>
5481 requires sized_sentinel_for<sentinel_t<_Base>,
5482 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5483 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vp>>
5484 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5485 { return __x._M_current.back() - __y._M_end; }
5486
5487 template<bool _OtherConst>
5488 requires sized_sentinel_for<sentinel_t<_Base>,
5489 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5490 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vp>>
5491 operator-(const _Sentinel& __y, const _Iterator<_OtherConst>& __x)
5492 { return __y._M_end - __x._M_current.back(); }
5493 };
5494
5495 namespace views
5496 {
5497 namespace __detail
5498 {
5499 template<size_t _Nm, typename _Range>
5500 concept __can_adjacent_view
5501 = requires { adjacent_view<all_t<_Range>, _Nm>(std::declval<_Range>()); };
5502 }
5503
5504 template<size_t _Nm>
5505 struct _Adjacent : __adaptor::_RangeAdaptorClosure
5506 {
5507 template<viewable_range _Range>
5508 requires (_Nm == 0) || __detail::__can_adjacent_view<_Nm, _Range>
5509 constexpr auto
5510 operator() [[nodiscard]] (_Range&& __r) const
5511 {
5512 if constexpr (_Nm == 0)
5513 return views::empty<tuple<>>;
5514 else
5515 return adjacent_view<all_t<_Range>, _Nm>(std::forward<_Range>(__r));
5516 }
5517 };
5518
5519 template<size_t _Nm>
5520 inline constexpr _Adjacent<_Nm> adjacent;
5521
5522 inline constexpr auto pairwise = adjacent<2>;
5523 }
5524
5525 template<forward_range _Vp, copy_constructible _Fp, size_t _Nm>
5526 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5527 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5528 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5529 range_reference_t<_Vp>>>
5530 class adjacent_transform_view : public view_interface<adjacent_transform_view<_Vp, _Fp, _Nm>>
5531 {
5532 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
5533 adjacent_view<_Vp, _Nm> _M_inner;
5534
5535 using _InnerView = adjacent_view<_Vp, _Nm>;
5536
5537 template<bool _Const>
5538 using _InnerIter = iterator_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5539
5540 template<bool _Const>
5541 using _InnerSent = sentinel_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5542
5543 template<bool> class _Iterator;
5544 template<bool> class _Sentinel;
5545
5546 public:
5547 adjacent_transform_view() = default;
5548
5549 constexpr explicit
5550 adjacent_transform_view(_Vp __base, _Fp __fun)
5551 : _M_fun(std::move(__fun)), _M_inner(std::move(__base))
5552 { }
5553
5554 constexpr auto
5555 begin()
5556 { return _Iterator<false>(*this, _M_inner.begin()); }
5557
5558 constexpr auto
5559 begin() const
5560 requires range<const _InnerView>
5561 && regular_invocable<__detail::__unarize<const _Fp&, _Nm>,
5562 range_reference_t<const _Vp>>
5563 { return _Iterator<true>(*this, _M_inner.begin()); }
5564
5565 constexpr auto
5566 end()
5567 {
5568 if constexpr (common_range<_InnerView>)
5569 return _Iterator<false>(*this, _M_inner.end());
5570 else
5571 return _Sentinel<false>(_M_inner.end());
5572 }
5573
5574 constexpr auto
5575 end() const
5576 requires range<const _InnerView>
5577 && regular_invocable<__detail::__unarize<const _Fp&, _Nm>,
5578 range_reference_t<const _Vp>>
5579 {
5580 if constexpr (common_range<const _InnerView>)
5581 return _Iterator<true>(*this, _M_inner.end());
5582 else
5583 return _Sentinel<true>(_M_inner.end());
5584 }
5585
5586 constexpr auto
5587 size() requires sized_range<_InnerView>
5588 { return _M_inner.size(); }
5589
5590 constexpr auto
5591 size() const requires sized_range<const _InnerView>
5592 { return _M_inner.size(); }
5593 };
5594
5595 template<forward_range _Vp, copy_constructible _Fp, size_t _Nm>
5596 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5597 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5598 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5599 range_reference_t<_Vp>>>
5600 template<bool _Const>
5601 class adjacent_transform_view<_Vp, _Fp, _Nm>::_Iterator
5602 {
5603 using _Parent = __detail::__maybe_const_t<_Const, adjacent_transform_view>;
5604 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5605
5606 _Parent* _M_parent = nullptr;
5607 _InnerIter<_Const> _M_inner;
5608
5609 constexpr
5610 _Iterator(_Parent& __parent, _InnerIter<_Const> __inner)
5611 : _M_parent(std::__addressof(__parent)), _M_inner(std::move(__inner))
5612 { }
5613
5614 static auto
5615 _S_iter_cat()
5616 {
5617 using __detail::__maybe_const_t;
5618 using __detail::__unarize;
5619 using _Res = invoke_result_t<__unarize<__maybe_const_t<_Const, _Fp>&, _Nm>,
5620 range_reference_t<_Base>>;
5621 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
5622 if constexpr (!is_lvalue_reference_v<_Res>)
5623 return input_iterator_tag{};
5624 else if constexpr (derived_from<_Cat, random_access_iterator_tag>)
5625 return random_access_iterator_tag{};
5626 else if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
5627 return bidirectional_iterator_tag{};
5628 else if constexpr (derived_from<_Cat, forward_iterator_tag>)
5629 return forward_iterator_tag{};
5630 else
5631 return input_iterator_tag{};
5632 }
5633
5634 friend class adjacent_transform_view;
5635
5636 public:
5637 using iterator_category = decltype(_S_iter_cat());
5638 using iterator_concept = typename _InnerIter<_Const>::iterator_concept;
5639 using value_type
5640 = remove_cvref_t<invoke_result_t
5641 <__detail::__unarize<__detail::__maybe_const_t<_Const, _Fp>&, _Nm>,
5642 range_reference_t<_Base>>>;
5643 using difference_type = range_difference_t<_Base>;
5644
5645 _Iterator() = default;
5646
5647 constexpr
5648 _Iterator(_Iterator<!_Const> __i)
5649 requires _Const && convertible_to<_InnerIter<false>, _InnerIter<_Const>>
5650 : _M_parent(__i._M_parent), _M_inner(std::move(__i._M_inner))
5651 { }
5652
5653 constexpr decltype(auto)
5654 operator*() const
5655 {
5656 return std::apply([&](const auto&... __iters) -> decltype(auto) {
5657 return std::__invoke(*_M_parent->_M_fun, *__iters...);
5658 }, _M_inner._M_current);
5659 }
5660
5661 constexpr _Iterator&
5662 operator++()
5663 {
5664 ++_M_inner;
5665 return *this;
5666 }
5667
5668 constexpr _Iterator
5669 operator++(int)
5670 {
5671 auto __tmp = *this;
5672 ++*this;
5673 return __tmp;
5674 }
5675
5676 constexpr _Iterator&
5677 operator--() requires bidirectional_range<_Base>
5678 {
5679 --_M_inner;
5680 return *this;
5681 }
5682
5683 constexpr _Iterator
5684 operator--(int) requires bidirectional_range<_Base>
5685 {
5686 auto __tmp = *this;
5687 --*this;
5688 return __tmp;
5689 }
5690
5691 constexpr _Iterator&
5692 operator+=(difference_type __x) requires random_access_range<_Base>
5693 {
5694 _M_inner += __x;
5695 return *this;
5696 }
5697
5698 constexpr _Iterator&
5699 operator-=(difference_type __x) requires random_access_range<_Base>
5700 {
5701 _M_inner -= __x;
5702 return *this;
5703 }
5704
5705 constexpr decltype(auto)
5706 operator[](difference_type __n) const requires random_access_range<_Base>
5707 {
5708 return std::apply([&](const auto&... __iters) -> decltype(auto) {
5709 return std::__invoke(*_M_parent->_M_fun, __iters[__n]...);
5710 }, _M_inner._M_current);
5711 }
5712
5713 friend constexpr bool
5714 operator==(const _Iterator& __x, const _Iterator& __y)
5715 { return __x._M_inner == __y._M_inner; }
5716
5717 friend constexpr bool
5718 operator<(const _Iterator& __x, const _Iterator& __y)
5719 requires random_access_range<_Base>
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 auto
5738 operator<=>(const _Iterator& __x, const _Iterator& __y)
5739 requires random_access_range<_Base> &&
5740 three_way_comparable<_InnerIter<_Const>>
5741 { return __x._M_inner <=> __y._M_inner; }
5742
5743 friend constexpr _Iterator
5744 operator+(const _Iterator& __i, difference_type __n)
5745 requires random_access_range<_Base>
5746 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5747
5748 friend constexpr _Iterator
5749 operator+(difference_type __n, const _Iterator& __i)
5750 requires random_access_range<_Base>
5751 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5752
5753 friend constexpr _Iterator
5754 operator-(const _Iterator& __i, difference_type __n)
5755 requires random_access_range<_Base>
5756 { return _Iterator(*__i._M_parent, __i._M_inner - __n); }
5757
5758 friend constexpr difference_type
5759 operator-(const _Iterator& __x, const _Iterator& __y)
5760 requires sized_sentinel_for<_InnerIter<_Const>, _InnerIter<_Const>>
5761 { return __x._M_inner - __y._M_inner; }
5762 };
5763
5764 template<forward_range _Vp, copy_constructible _Fp, size_t _Nm>
5765 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5766 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5767 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5768 range_reference_t<_Vp>>>
5769 template<bool _Const>
5770 class adjacent_transform_view<_Vp, _Fp, _Nm>::_Sentinel
5771 {
5772 _InnerSent<_Const> _M_inner;
5773
5774 constexpr explicit
5775 _Sentinel(_InnerSent<_Const> __inner)
5776 : _M_inner(__inner)
5777 { }
5778
5779 friend class adjacent_transform_view;
5780
5781 public:
5782 _Sentinel() = default;
5783
5784 constexpr
5785 _Sentinel(_Sentinel<!_Const> __i)
5786 requires _Const && convertible_to<_InnerSent<false>, _InnerSent<_Const>>
5787 : _M_inner(std::move(__i._M_inner))
5788 { }
5789
5790 template<bool _OtherConst>
5791 requires sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
5792 friend constexpr bool
5793 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5794 { return __x._M_inner == __y._M_inner; }
5795
5796 template<bool _OtherConst>
5797 requires sized_sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
5798 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5799 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5800 { return __x._M_inner - __y._M_inner; }
5801
5802 template<bool _OtherConst>
5803 requires sized_sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
5804 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5805 operator-(const _Sentinel& __x, const _Iterator<_OtherConst>& __y)
5806 { return __x._M_inner - __y._M_inner; }
5807 };
5808
5809 namespace views
5810 {
5811 namespace __detail
5812 {
5813 template<size_t _Nm, typename _Range, typename _Fp>
5814 concept __can_adjacent_transform_view
5815 = requires { adjacent_transform_view<all_t<_Range>, decay_t<_Fp>, _Nm>
5816 (std::declval<_Range>(), std::declval<_Fp>()); };
5817 }
5818
5819 template<size_t _Nm>
5820 struct _AdjacentTransform : __adaptor::_RangeAdaptor<_AdjacentTransform<_Nm>>
5821 {
5822 template<viewable_range _Range, typename _Fp>
5823 requires (_Nm == 0) || __detail::__can_adjacent_transform_view<_Nm, _Range, _Fp>
5824 constexpr auto
5825 operator() [[nodiscard]] (_Range&& __r, _Fp&& __f) const
5826 {
5827 if constexpr (_Nm == 0)
5828 return zip_transform(std::forward<_Fp>(__f));
5829 else
5830 return adjacent_transform_view<all_t<_Range>, decay_t<_Fp>, _Nm>
5831 (std::forward<_Range>(__r), std::forward<_Fp>(__f));
5832 }
5833
5834 using __adaptor::_RangeAdaptor<_AdjacentTransform>::operator();
5835 static constexpr int _S_arity = 2;
5836 static constexpr bool _S_has_simple_extra_args = true;
5837 };
5838
5839 template<size_t _Nm>
5840 inline constexpr _AdjacentTransform<_Nm> adjacent_transform;
5841
5842 inline constexpr auto pairwise_transform = adjacent_transform<2>;
5843 }
5844
5845#define __cpp_lib_ranges_chunk 202202L
5846
5847 namespace __detail
5848 {
5849 template<typename _Tp>
5850 constexpr _Tp __div_ceil(_Tp __num, _Tp __denom)
5851 {
5852 _Tp __r = __num / __denom;
5853 if (__num % __denom)
5854 ++__r;
5855 return __r;
5856 }
5857 }
5858
5859 template<view _Vp>
5860 requires input_range<_Vp>
5861 class chunk_view : public view_interface<chunk_view<_Vp>>
5862 {
5863 _Vp _M_base;
5864 range_difference_t<_Vp> _M_n;
5865 range_difference_t<_Vp> _M_remainder = 0;
5866 __detail::__non_propagating_cache<iterator_t<_Vp>> _M_current;
5867
5868 class _OuterIter;
5869 class _InnerIter;
5870
5871 public:
5872 constexpr explicit
5873 chunk_view(_Vp __base, range_difference_t<_Vp> __n)
5874 : _M_base(std::move(__base)), _M_n(__n)
5875 { __glibcxx_assert(__n >= 0); }
5876
5877 constexpr _Vp
5878 base() const & requires copy_constructible<_Vp>
5879 { return _M_base; }
5880
5881 constexpr _Vp
5882 base() &&
5883 { return std::move(_M_base); }
5884
5885 constexpr _OuterIter
5886 begin()
5887 {
5888 _M_current = ranges::begin(_M_base);
5889 _M_remainder = _M_n;
5890 return _OuterIter(*this);
5891 }
5892
5893 constexpr default_sentinel_t
5894 end() const noexcept
5895 { return default_sentinel; }
5896
5897 constexpr auto
5898 size() requires sized_range<_Vp>
5899 {
5900 return __detail::__to_unsigned_like(__detail::__div_ceil
5901 (ranges::distance(_M_base), _M_n));
5902 }
5903
5904 constexpr auto
5905 size() const requires sized_range<const _Vp>
5906 {
5907 return __detail::__to_unsigned_like(__detail::__div_ceil
5908 (ranges::distance(_M_base), _M_n));
5909 }
5910 };
5911
5912 template<typename _Range>
5913 chunk_view(_Range&&, range_difference_t<_Range>) -> chunk_view<views::all_t<_Range>>;
5914
5915 template<view _Vp>
5916 requires input_range<_Vp>
5917 class chunk_view<_Vp>::_OuterIter
5918 {
5919 chunk_view* _M_parent;
5920
5921 constexpr explicit
5922 _OuterIter(chunk_view& __parent) noexcept
5923 : _M_parent(std::__addressof(__parent))
5924 { }
5925
5926 friend chunk_view;
5927
5928 public:
5929 using iterator_concept = input_iterator_tag;
5930 using difference_type = range_difference_t<_Vp>;
5931
5932 struct value_type;
5933
5934 _OuterIter(_OuterIter&&) = default;
5935 _OuterIter& operator=(_OuterIter&&) = default;
5936
5937 constexpr value_type
5938 operator*() const
5939 {
5940 __glibcxx_assert(*this != default_sentinel);
5941 return value_type(*_M_parent);
5942 }
5943
5944 constexpr _OuterIter&
5945 operator++()
5946 {
5947 __glibcxx_assert(*this != default_sentinel);
5948 ranges::advance(*_M_parent->_M_current, _M_parent->_M_remainder,
5949 ranges::end(_M_parent->_M_base));
5950 _M_parent->_M_remainder = _M_parent->_M_n;
5951 return *this;
5952 }
5953
5954 constexpr void
5955 operator++(int)
5956 { ++*this; }
5957
5958 friend constexpr bool
5959 operator==(const _OuterIter& __x, default_sentinel_t)
5960 {
5961 return *__x._M_parent->_M_current == ranges::end(__x._M_parent->_M_base)
5962 && __x._M_parent->_M_remainder != 0;
5963 }
5964
5965 friend constexpr difference_type
5966 operator-(default_sentinel_t, const _OuterIter& __x)
5967 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
5968 {
5969 const auto __dist = ranges::end(__x._M_parent->_M_base) - *__x._M_parent->_M_current;
5970
5971 if (__dist < __x._M_parent->_M_remainder)
5972 return __dist == 0 ? 0 : 1;
5973
5974 return 1 + __detail::__div_ceil(__dist - __x._M_parent->_M_remainder,
5975 __x._M_parent->_M_n);
5976 }
5977
5978 friend constexpr difference_type
5979 operator-(const _OuterIter& __x, default_sentinel_t __y)
5980 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
5981 { return -(__y - __x); }
5982 };
5983
5984 template<view _Vp>
5985 requires input_range<_Vp>
5986 struct chunk_view<_Vp>::_OuterIter::value_type : view_interface<value_type>
5987 {
5988 private:
5989 chunk_view* _M_parent;
5990
5991 constexpr explicit
5992 value_type(chunk_view& __parent) noexcept
5993 : _M_parent(std::__addressof(__parent))
5994 { }
5995
5996 friend _OuterIter;
5997
5998 public:
5999 constexpr _InnerIter
6000 begin() const noexcept
6001 { return _InnerIter(*_M_parent); }
6002
6003 constexpr default_sentinel_t
6004 end() const noexcept
6005 { return default_sentinel; }
6006
6007 constexpr auto
6008 size() const
6009 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6010 {
6011 return __detail::__to_unsigned_like
6012 (ranges::min(_M_parent->_M_remainder,
6013 ranges::end(_M_parent->_M_base) - *_M_parent->_M_current));
6014 }
6015 };
6016
6017 template<view _Vp>
6018 requires input_range<_Vp>
6019 class chunk_view<_Vp>::_InnerIter
6020 {
6021 chunk_view* _M_parent;
6022
6023 constexpr explicit
6024 _InnerIter(chunk_view& __parent) noexcept
6025 : _M_parent(std::__addressof(__parent))
6026 { }
6027
6028 friend _OuterIter::value_type;
6029
6030 public:
6031 using iterator_concept = input_iterator_tag;
6032 using difference_type = range_difference_t<_Vp>;
6033 using value_type = range_value_t<_Vp>;
6034
6035 _InnerIter(_InnerIter&&) = default;
6036 _InnerIter& operator=(_InnerIter&&) = default;
6037
6038 constexpr const iterator_t<_Vp>&
6039 base() const &
6040 { return *_M_parent->_M_current; }
6041
6042 constexpr range_reference_t<_Vp>
6043 operator*() const
6044 {
6045 __glibcxx_assert(*this != default_sentinel);
6046 return **_M_parent->_M_current;
6047 }
6048
6049 constexpr _InnerIter&
6050 operator++()
6051 {
6052 __glibcxx_assert(*this != default_sentinel);
6053 ++*_M_parent->_M_current;
6054 if (*_M_parent->_M_current == ranges::end(_M_parent->_M_base))
6055 _M_parent->_M_remainder = 0;
6056 else
6057 --_M_parent->_M_remainder;
6058 return *this;
6059 }
6060
6061 constexpr void
6062 operator++(int)
6063 { ++*this; }
6064
6065 friend constexpr bool
6066 operator==(const _InnerIter& __x, default_sentinel_t) noexcept
6067 { return __x._M_parent->_M_remainder == 0; }
6068
6069 friend constexpr difference_type
6070 operator-(default_sentinel_t, const _InnerIter& __x)
6071 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6072 {
6073 return ranges::min(__x._M_parent->_M_remainder,
6074 ranges::end(__x._M_parent->_M_base) - *__x._M_parent->_M_current);
6075 }
6076
6077 friend constexpr difference_type
6078 operator-(const _InnerIter& __x, default_sentinel_t __y)
6079 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6080 { return -(__y - __x); }
6081 };
6082
6083 template<view _Vp>
6084 requires forward_range<_Vp>
6085 class chunk_view<_Vp> : public view_interface<chunk_view<_Vp>>
6086 {
6087 _Vp _M_base;
6088 range_difference_t<_Vp> _M_n;
6089 template<bool> class _Iterator;
6090
6091 public:
6092 constexpr explicit
6093 chunk_view(_Vp __base, range_difference_t<_Vp> __n)
6094 : _M_base(std::move(__base)), _M_n(__n)
6095 { __glibcxx_assert(__n > 0); }
6096
6097 constexpr _Vp
6098 base() const & requires copy_constructible<_Vp>
6099 { return _M_base; }
6100
6101 constexpr _Vp
6102 base() &&
6103 { return std::move(_M_base); }
6104
6105 constexpr auto
6106 begin() requires (!__detail::__simple_view<_Vp>)
6107 { return _Iterator<false>(this, ranges::begin(_M_base)); }
6108
6109 constexpr auto
6110 begin() const requires forward_range<const _Vp>
6111 { return _Iterator<true>(this, ranges::begin(_M_base)); }
6112
6113 constexpr auto
6114 end() requires (!__detail::__simple_view<_Vp>)
6115 {
6116 if constexpr (common_range<_Vp> && sized_range<_Vp>)
6117 {
6118 auto __missing = (_M_n - ranges::distance(_M_base) % _M_n) % _M_n;
6119 return _Iterator<false>(this, ranges::end(_M_base), __missing);
6120 }
6121 else if constexpr (common_range<_Vp> && !bidirectional_range<_Vp>)
6122 return _Iterator<false>(this, ranges::end(_M_base));
6123 else
6124 return default_sentinel;
6125 }
6126
6127 constexpr auto
6128 end() const requires forward_range<const _Vp>
6129 {
6130 if constexpr (common_range<const _Vp> && sized_range<const _Vp>)
6131 {
6132 auto __missing = (_M_n - ranges::distance(_M_base) % _M_n) % _M_n;
6133 return _Iterator<true>(this, ranges::end(_M_base), __missing);
6134 }
6135 else if constexpr (common_range<const _Vp> && !bidirectional_range<const _Vp>)
6136 return _Iterator<true>(this, ranges::end(_M_base));
6137 else
6138 return default_sentinel;
6139 }
6140
6141 constexpr auto
6142 size() requires sized_range<_Vp>
6143 {
6144 return __detail::__to_unsigned_like(__detail::__div_ceil
6145 (ranges::distance(_M_base), _M_n));
6146 }
6147
6148 constexpr auto
6149 size() const requires sized_range<const _Vp>
6150 {
6151 return __detail::__to_unsigned_like(__detail::__div_ceil
6152 (ranges::distance(_M_base), _M_n));
6153 }
6154 };
6155
6156 template<typename _Vp>
6157 inline constexpr bool enable_borrowed_range<chunk_view<_Vp>>
6158 = forward_range<_Vp> && enable_borrowed_range<_Vp>;
6159
6160 template<view _Vp>
6161 requires forward_range<_Vp>
6162 template<bool _Const>
6163 class chunk_view<_Vp>::_Iterator
6164 {
6165 using _Parent = __detail::__maybe_const_t<_Const, chunk_view>;
6166 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6167
6168 iterator_t<_Base> _M_current = iterator_t<_Base>();
6169 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
6170 range_difference_t<_Base> _M_n = 0;
6171 range_difference_t<_Base> _M_missing = 0;
6172
6173 constexpr
6174 _Iterator(_Parent* __parent, iterator_t<_Base> __current,
6175 range_difference_t<_Base> __missing = 0)
6176 : _M_current(__current), _M_end(ranges::end(__parent->_M_base)),
6177 _M_n(__parent->_M_n), _M_missing(__missing)
6178 { }
6179
6180 static auto
6181 _S_iter_cat()
6182 {
6183 if constexpr (random_access_range<_Base>)
6184 return random_access_iterator_tag{};
6185 else if constexpr (bidirectional_range<_Base>)
6186 return bidirectional_iterator_tag{};
6187 else
6188 return forward_iterator_tag{};
6189 }
6190
6191 friend chunk_view;
6192
6193 public:
6194 using iterator_category = input_iterator_tag;
6195 using iterator_concept = decltype(_S_iter_cat());
6196 using value_type = decltype(views::take(subrange(_M_current, _M_end), _M_n));
6197 using difference_type = range_difference_t<_Base>;
6198
6199 _Iterator() = default;
6200
6201 constexpr _Iterator(_Iterator<!_Const> __i)
6202 requires _Const
6203 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
6204 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
6205 : _M_current(std::move(__i._M_current)), _M_end(std::move(__i._M_end)),
6206 _M_n(__i._M_n), _M_missing(__i._M_missing)
6207 { }
6208
6209 constexpr iterator_t<_Base>
6210 base() const
6211 { return _M_current; }
6212
6213 constexpr value_type
6214 operator*() const
6215 {
6216 __glibcxx_assert(_M_current != _M_end);
6217 return views::take(subrange(_M_current, _M_end), _M_n);
6218 }
6219
6220 constexpr _Iterator&
6221 operator++()
6222 {
6223 __glibcxx_assert(_M_current != _M_end);
6224 _M_missing = ranges::advance(_M_current, _M_n, _M_end);
6225 return *this;
6226 }
6227
6228 constexpr _Iterator
6229 operator++(int)
6230 {
6231 auto __tmp = *this;
6232 ++*this;
6233 return __tmp;
6234 }
6235
6236 constexpr _Iterator&
6237 operator--() requires bidirectional_range<_Base>
6238 {
6239 ranges::advance(_M_current, _M_missing - _M_n);
6240 _M_missing = 0;
6241 return *this;
6242 }
6243
6244 constexpr _Iterator
6245 operator--(int) requires bidirectional_range<_Base>
6246 {
6247 auto __tmp = *this;
6248 --*this;
6249 return __tmp;
6250 }
6251
6252 constexpr _Iterator&
6253 operator+=(difference_type __x)
6254 requires random_access_range<_Base>
6255 {
6256 if (__x > 0)
6257 {
6258 __glibcxx_assert(ranges::distance(_M_current, _M_end) > _M_n * (__x - 1));
6259 _M_missing = ranges::advance(_M_current, _M_n * __x, _M_end);
6260 }
6261 else if (__x < 0)
6262 {
6263 ranges::advance(_M_current, _M_n * __x + _M_missing);
6264 _M_missing = 0;
6265 }
6266 return *this;
6267 }
6268
6269 constexpr _Iterator&
6270 operator-=(difference_type __x)
6271 requires random_access_range<_Base>
6272 { return *this += -__x; }
6273
6274 constexpr value_type
6275 operator[](difference_type __n) const
6276 requires random_access_range<_Base>
6277 { return *(*this + __n); }
6278
6279 friend constexpr bool
6280 operator==(const _Iterator& __x, const _Iterator& __y)
6281 { return __x._M_current == __y._M_current; }
6282
6283 friend constexpr bool
6284 operator==(const _Iterator& __x, default_sentinel_t)
6285 { return __x._M_current == __x._M_end; }
6286
6287 friend constexpr bool
6288 operator<(const _Iterator& __x, const _Iterator& __y)
6289 requires random_access_range<_Base>
6290 { return __x._M_current > __y._M_current; }
6291
6292 friend constexpr bool
6293 operator>(const _Iterator& __x, const _Iterator& __y)
6294 requires random_access_range<_Base>
6295 { return __y < __x; }
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 !(__x < __y); }
6306
6307 friend constexpr auto
6308 operator<=>(const _Iterator& __x, const _Iterator& __y)
6309 requires random_access_range<_Base>
6310 && three_way_comparable<iterator_t<_Base>>
6311 { return __x._M_current <=> __y._M_current; }
6312
6313 friend constexpr _Iterator
6314 operator+(const _Iterator& __i, difference_type __n)
6315 requires random_access_range<_Base>
6316 {
6317 auto __r = __i;
6318 __r += __n;
6319 return __r;
6320 }
6321
6322 friend constexpr _Iterator
6323 operator+(difference_type __n, const _Iterator& __i)
6324 requires random_access_range<_Base>
6325 {
6326 auto __r = __i;
6327 __r += __n;
6328 return __r;
6329 }
6330
6331 friend constexpr _Iterator
6332 operator-(const _Iterator& __i, difference_type __n)
6333 requires random_access_range<_Base>
6334 {
6335 auto __r = __i;
6336 __r -= __n;
6337 return __r;
6338 }
6339
6340 friend constexpr difference_type
6341 operator-(const _Iterator& __x, const _Iterator& __y)
6342 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
6343 {
6344 return (__x._M_current - __y._M_current
6345 + __x._M_missing - __y._M_missing) / __x._M_n;
6346 }
6347
6348 friend constexpr difference_type
6349 operator-(default_sentinel_t __y, const _Iterator& __x)
6350 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
6351 { return __detail::__div_ceil(__x._M_end - __x._M_current, __x._M_n); }
6352
6353 friend constexpr difference_type
6354 operator-(const _Iterator& __x, default_sentinel_t __y)
6355 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
6356 { return -(__y - __x); }
6357 };
6358
6359 namespace views
6360 {
6361 namespace __detail
6362 {
6363 template<typename _Range, typename _Dp>
6364 concept __can_chunk_view
6365 = requires { chunk_view(std::declval<_Range>(), std::declval<_Dp>()); };
6366 }
6367
6368 struct _Chunk : __adaptor::_RangeAdaptor<_Chunk>
6369 {
6370 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
6371 requires __detail::__can_chunk_view<_Range, _Dp>
6372 constexpr auto
6373 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
6374 { return chunk_view(std::forward<_Range>(__r), __n); }
6375
6376 using __adaptor::_RangeAdaptor<_Chunk>::operator();
6377 static constexpr int _S_arity = 2;
6378 static constexpr bool _S_has_simple_extra_args = true;
6379 };
6380
6381 inline constexpr _Chunk chunk;
6382 }
6383
6384#define __cpp_lib_ranges_slide 202202L
6385
6386 namespace __detail
6387 {
6388 template<typename _Vp>
6389 concept __slide_caches_nothing = random_access_range<_Vp> && sized_range<_Vp>;
6390
6391 template<typename _Vp>
6392 concept __slide_caches_last
6393 = !__slide_caches_nothing<_Vp> && bidirectional_range<_Vp> && common_range<_Vp>;
6394
6395 template<typename _Vp>
6396 concept __slide_caches_first
6397 = !__slide_caches_nothing<_Vp> && !__slide_caches_last<_Vp>;
6398 }
6399
6400 template<forward_range _Vp>
6401 requires view<_Vp>
6402 class slide_view : public view_interface<slide_view<_Vp>>
6403 {
6404 _Vp _M_base;
6405 range_difference_t<_Vp> _M_n;
6406 [[no_unique_address]]
6407 __detail::__maybe_present_t<__detail::__slide_caches_first<_Vp>,
6408 __detail::_CachedPosition<_Vp>> _M_cached_begin;
6409 [[no_unique_address]]
6410 __detail::__maybe_present_t<__detail::__slide_caches_last<_Vp>,
6411 __detail::_CachedPosition<_Vp>> _M_cached_end;
6412
6413 template<bool> class _Iterator;
6414 class _Sentinel;
6415
6416 public:
6417 constexpr explicit
6418 slide_view(_Vp __base, range_difference_t<_Vp> __n)
6419 : _M_base(std::move(__base)), _M_n(__n)
6420 { __glibcxx_assert(__n > 0); }
6421
6422 constexpr auto
6423 begin() requires (!(__detail::__simple_view<_Vp>
6424 && __detail::__slide_caches_nothing<const _Vp>))
6425 {
6426 if constexpr (__detail::__slide_caches_first<_Vp>)
6427 {
6428 iterator_t<_Vp> __it;
6429 if (_M_cached_begin._M_has_value())
6430 __it = _M_cached_begin._M_get(_M_base);
6431 else
6432 {
6433 __it = ranges::next(ranges::begin(_M_base), _M_n - 1, ranges::end(_M_base));
6434 _M_cached_begin._M_set(_M_base, __it);
6435 }
6436 return _Iterator<false>(ranges::begin(_M_base), std::move(__it), _M_n);
6437 }
6438 else
6439 return _Iterator<false>(ranges::begin(_M_base), _M_n);
6440 }
6441
6442 constexpr auto
6443 begin() const requires __detail::__slide_caches_nothing<const _Vp>
6444 { return _Iterator<true>(ranges::begin(_M_base), _M_n); }
6445
6446 constexpr auto
6447 end() requires (!(__detail::__simple_view<_Vp>
6448 && __detail::__slide_caches_nothing<const _Vp>))
6449 {
6450 if constexpr (__detail::__slide_caches_nothing<_Vp>)
6451 return _Iterator<false>(ranges::begin(_M_base) + range_difference_t<_Vp>(size()),
6452 _M_n);
6453 else if constexpr (__detail::__slide_caches_last<_Vp>)
6454 {
6455 iterator_t<_Vp> __it;
6456 if (_M_cached_end._M_has_value())
6457 __it = _M_cached_end._M_get(_M_base);
6458 else
6459 {
6460 __it = ranges::prev(ranges::end(_M_base), _M_n - 1, ranges::begin(_M_base));
6461 _M_cached_end._M_set(_M_base, __it);
6462 }
6463 return _Iterator<false>(std::move(__it), _M_n);
6464 }
6465 else if constexpr (common_range<_Vp>)
6466 return _Iterator<false>(ranges::end(_M_base), ranges::end(_M_base), _M_n);
6467 else
6468 return _Sentinel(ranges::end(_M_base));
6469 }
6470
6471 constexpr auto
6472 end() const requires __detail::__slide_caches_nothing<const _Vp>
6473 { return begin() + range_difference_t<const _Vp>(size()); }
6474
6475 constexpr auto
6476 size() requires sized_range<_Vp>
6477 {
6478 auto __sz = ranges::distance(_M_base) - _M_n + 1;
6479 if (__sz < 0)
6480 __sz = 0;
6481 return __detail::__to_unsigned_like(__sz);
6482 }
6483
6484 constexpr auto
6485 size() const requires sized_range<const _Vp>
6486 {
6487 auto __sz = ranges::distance(_M_base) - _M_n + 1;
6488 if (__sz < 0)
6489 __sz = 0;
6490 return __detail::__to_unsigned_like(__sz);
6491 }
6492 };
6493
6494 template<typename _Range>
6495 slide_view(_Range&&, range_difference_t<_Range>) -> slide_view<views::all_t<_Range>>;
6496
6497 template<typename _Vp>
6498 inline constexpr bool enable_borrowed_range<slide_view<_Vp>>
6499 = enable_borrowed_range<_Vp>;
6500
6501 template<forward_range _Vp>
6502 requires view<_Vp>
6503 template<bool _Const>
6504 class slide_view<_Vp>::_Iterator
6505 {
6506 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6507 static constexpr bool _S_last_elt_present
6508 = __detail::__slide_caches_first<_Base>;
6509
6510 iterator_t<_Base> _M_current = iterator_t<_Base>();
6511 [[no_unique_address]]
6512 __detail::__maybe_present_t<_S_last_elt_present, iterator_t<_Base>>
6513 _M_last_elt = decltype(_M_last_elt)();
6514 range_difference_t<_Base> _M_n = 0;
6515
6516 constexpr
6517 _Iterator(iterator_t<_Base> __current, range_difference_t<_Base> __n)
6518 requires (!_S_last_elt_present)
6519 : _M_current(__current), _M_n(__n)
6520 { }
6521
6522 constexpr
6523 _Iterator(iterator_t<_Base> __current, iterator_t<_Base> __last_elt,
6524 range_difference_t<_Base> __n)
6525 requires _S_last_elt_present
6526 : _M_current(__current), _M_last_elt(__last_elt), _M_n(__n)
6527 { }
6528
6529 static auto
6530 _S_iter_concept()
6531 {
6532 if constexpr (random_access_range<_Base>)
6533 return random_access_iterator_tag{};
6534 else if constexpr (bidirectional_range<_Base>)
6535 return bidirectional_iterator_tag{};
6536 else
6537 return forward_iterator_tag{};
6538 }
6539
6540 friend slide_view;
6541 friend slide_view::_Sentinel;
6542
6543 public:
6544 using iterator_category = input_iterator_tag;
6545 using iterator_concept = decltype(_S_iter_concept());
6546 using value_type = decltype(views::counted(_M_current, _M_n));
6547 using difference_type = range_difference_t<_Base>;
6548
6549 _Iterator() = default;
6550
6551 constexpr
6552 _Iterator(_Iterator<!_Const> __i)
6553 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
6554 : _M_current(std::move(__i._M_current)), _M_n(__i._M_n)
6555 { }
6556
6557 constexpr auto
6558 operator*() const
6559 { return views::counted(_M_current, _M_n); }
6560
6561 constexpr _Iterator&
6562 operator++()
6563 {
6564 ++_M_current;
6565 if constexpr (_S_last_elt_present)
6566 ++_M_last_elt;
6567 return *this;
6568 }
6569
6570 constexpr _Iterator
6571 operator++(int)
6572 {
6573 auto __tmp = *this;
6574 ++*this;
6575 return __tmp;
6576 }
6577
6578 constexpr _Iterator&
6579 operator--() requires bidirectional_range<_Base>
6580 {
6581 --_M_current;
6582 if constexpr (_S_last_elt_present)
6583 --_M_last_elt;
6584 return *this;
6585 }
6586
6587 constexpr _Iterator
6588 operator--(int) requires bidirectional_range<_Base>
6589 {
6590 auto __tmp = *this;
6591 --*this;
6592 return __tmp;
6593 }
6594
6595 constexpr _Iterator&
6596 operator+=(difference_type __x)
6597 requires random_access_range<_Base>
6598 {
6599 _M_current += __x;
6600 if constexpr (_S_last_elt_present)
6601 _M_last_elt += __x;
6602 return *this;
6603 }
6604
6605 constexpr _Iterator&
6606 operator-=(difference_type __x)
6607 requires random_access_range<_Base>
6608 {
6609 _M_current -= __x;
6610 if constexpr (_S_last_elt_present)
6611 _M_last_elt -= __x;
6612 return *this;
6613 }
6614
6615 constexpr auto
6616 operator[](difference_type __n) const
6617 requires random_access_range<_Base>
6618 { return views::counted(_M_current + __n, _M_n); }
6619
6620 friend constexpr bool
6621 operator==(const _Iterator& __x, const _Iterator& __y)
6622 {
6623 if constexpr (_S_last_elt_present)
6624 return __x._M_last_elt == __y._M_last_elt;
6625 else
6626 return __x._M_current == __y._M_current;
6627 }
6628
6629 friend constexpr bool
6630 operator<(const _Iterator& __x, const _Iterator& __y)
6631 requires random_access_range<_Base>
6632 { return __x._M_current < __y._M_current; }
6633
6634 friend constexpr bool
6635 operator>(const _Iterator& __x, const _Iterator& __y)
6636 requires random_access_range<_Base>
6637 { return __y < __x; }
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 !(__x < __y); }
6648
6649 friend constexpr auto
6650 operator<=>(const _Iterator& __x, const _Iterator& __y)
6651 requires random_access_range<_Base>
6652 && three_way_comparable<iterator_t<_Base>>
6653 { return __x._M_current <=> __y._M_current; }
6654
6655 friend constexpr _Iterator
6656 operator+(const _Iterator& __i, difference_type __n)
6657 requires random_access_range<_Base>
6658 {
6659 auto __r = __i;
6660 __r += __n;
6661 return __r;
6662 }
6663
6664 friend constexpr _Iterator
6665 operator+(difference_type __n, const _Iterator& __i)
6666 requires random_access_range<_Base>
6667 {
6668 auto __r = __i;
6669 __r += __n;
6670 return __r;
6671 }
6672
6673 friend constexpr _Iterator
6674 operator-(const _Iterator& __i, difference_type __n)
6675 requires random_access_range<_Base>
6676 {
6677 auto __r = __i;
6678 __r -= __n;
6679 return __r;
6680 }
6681
6682 friend constexpr difference_type
6683 operator-(const _Iterator& __x, const _Iterator& __y)
6684 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
6685 {
6686 if constexpr (_S_last_elt_present)
6687 return __x._M_last_elt - __y._M_last_elt;
6688 else
6689 return __x._M_current - __y._M_current;
6690 }
6691 };
6692
6693 template<forward_range _Vp>
6694 requires view<_Vp>
6695 class slide_view<_Vp>::_Sentinel
6696 {
6697 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
6698
6699 constexpr explicit
6700 _Sentinel(sentinel_t<_Vp> __end)
6701 : _M_end(__end)
6702 { }
6703
6704 friend slide_view;
6705
6706 public:
6707 _Sentinel() = default;
6708
6709 friend constexpr bool
6710 operator==(const _Iterator<false>& __x, const _Sentinel& __y)
6711 { return __x._M_last_elt == __y._M_end; }
6712
6713 friend constexpr range_difference_t<_Vp>
6714 operator-(const _Iterator<false>& __x, const _Sentinel& __y)
6715 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6716 { return __x._M_last_elt - __y._M_end; }
6717
6718 friend constexpr range_difference_t<_Vp>
6719 operator-(const _Sentinel& __y, const _Iterator<false>& __x)
6720 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6721 { return __y._M_end -__x._M_last_elt; }
6722 };
6723
6724 namespace views
6725 {
6726 namespace __detail
6727 {
6728 template<typename _Range, typename _Dp>
6729 concept __can_slide_view
6730 = requires { slide_view(std::declval<_Range>(), std::declval<_Dp>()); };
6731 }
6732
6733 struct _Slide : __adaptor::_RangeAdaptor<_Slide>
6734 {
6735 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
6736 requires __detail::__can_slide_view<_Range, _Dp>
6737 constexpr auto
6738 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
6739 { return slide_view(std::forward<_Range>(__r), __n); }
6740
6741 using __adaptor::_RangeAdaptor<_Slide>::operator();
6742 static constexpr int _S_arity = 2;
6743 static constexpr bool _S_has_simple_extra_args = true;
6744 };
6745
6746 inline constexpr _Slide slide;
6747 }
6748
6749#define __cpp_lib_ranges_chunk_by 202202L
6750
6751 template<forward_range _Vp,
6752 indirect_binary_predicate<iterator_t<_Vp>, iterator_t<_Vp>> _Pred>
6753 requires view<_Vp> && is_object_v<_Pred>
6754 class chunk_by_view : public view_interface<chunk_by_view<_Vp, _Pred>>
6755 {
6756 _Vp _M_base = _Vp();
6757 __detail::__box<_Pred> _M_pred;
6758 __detail::_CachedPosition<_Vp> _M_cached_begin;
6759
6760 constexpr iterator_t<_Vp>
6761 _M_find_next(iterator_t<_Vp> __current)
6762 {
6763 __glibcxx_assert(_M_pred.has_value());
6764 auto __pred = [this]<typename _Tp, typename _Up>(_Tp&& __x, _Up&& __y) {
6765 return !bool((*_M_pred)(std::forward<_Tp>(__x), std::forward<_Up>(__y)));
6766 };
6767 auto __it = ranges::adjacent_find(__current, ranges::end(_M_base), __pred);
6768 return ranges::next(__it, 1, ranges::end(_M_base));
6769 }
6770
6771 constexpr iterator_t<_Vp>
6772 _M_find_prev(iterator_t<_Vp> __current) requires bidirectional_range<_Vp>
6773 {
6774 __glibcxx_assert(_M_pred.has_value());
6775 auto __pred = [this]<typename _Tp, typename _Up>(_Tp&& __x, _Up&& __y) {
6776 return !bool((*_M_pred)(std::forward<_Up>(__y), std::forward<_Tp>(__x)));
6777 };
6778 auto __rbegin = std::make_reverse_iterator(__current);
6779 auto __rend = std::make_reverse_iterator(ranges::begin(_M_base));
6780 __glibcxx_assert(__rbegin != __rend);
6781 auto __it = ranges::adjacent_find(__rbegin, __rend, __pred).base();
6782 return ranges::prev(__it, 1, ranges::begin(_M_base));
6783 }
6784
6785 class _Iterator;
6786
6787 public:
6788 chunk_by_view() requires (default_initializable<_Vp>
6789 && default_initializable<_Pred>)
6790 = default;
6791
6792 constexpr explicit
6793 chunk_by_view(_Vp __base, _Pred __pred)
6794 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
6795 { }
6796
6797 constexpr _Vp
6798 base() const & requires copy_constructible<_Vp>
6799 { return _M_base; }
6800
6801 constexpr _Vp
6802 base() &&
6803 { return std::move(_M_base); }
6804
6805 constexpr const _Pred&
6806 pred() const
6807 { return *_M_pred; }
6808
6809 constexpr _Iterator
6810 begin()
6811 {
6812 __glibcxx_assert(_M_pred.has_value());
6813 iterator_t<_Vp> __it;
6814 if (_M_cached_begin._M_has_value())
6815 __it = _M_cached_begin._M_get(_M_base);
6816 else
6817 {
6818 __it = _M_find_next(ranges::begin(_M_base));
6819 _M_cached_begin._M_set(_M_base, __it);
6820 }
6821 return _Iterator(*this, ranges::begin(_M_base), __it);
6822 }
6823
6824 constexpr auto
6825 end()
6826 {
6827 if constexpr (common_range<_Vp>)
6828 return _Iterator(*this, ranges::end(_M_base), ranges::end(_M_base));
6829 else
6830 return default_sentinel;
6831 }
6832 };
6833
6834 template<typename _Range, typename _Pred>
6835 chunk_by_view(_Range&&, _Pred) -> chunk_by_view<views::all_t<_Range>, _Pred>;
6836
6837 template<forward_range _Vp,
6838 indirect_binary_predicate<iterator_t<_Vp>, iterator_t<_Vp>> _Pred>
6839 requires view<_Vp> && is_object_v<_Pred>
6840 class chunk_by_view<_Vp, _Pred>::_Iterator
6841 {
6842 chunk_by_view* _M_parent = nullptr;
6843 iterator_t<_Vp> _M_current = iterator_t<_Vp>();
6844 iterator_t<_Vp> _M_next = iterator_t<_Vp>();
6845
6846 constexpr
6847 _Iterator(chunk_by_view& __parent, iterator_t<_Vp> __current, iterator_t<_Vp> __next)
6848 : _M_parent(std::__addressof(__parent)), _M_current(__current), _M_next(__next)
6849 { }
6850
6851 static auto
6852 _S_iter_concept()
6853 {
6854 if constexpr (bidirectional_range<_Vp>)
6855 return bidirectional_iterator_tag{};
6856 else
6857 return forward_iterator_tag{};
6858 }
6859
6860 friend chunk_by_view;
6861
6862 public:
6863 using value_type = subrange<iterator_t<_Vp>>;
6864 using difference_type = range_difference_t<_Vp>;
6865 using iterator_category = input_iterator_tag;
6866 using iterator_concept = decltype(_S_iter_concept());
6867
6868 _Iterator() = default;
6869
6870 constexpr value_type
6871 operator*() const
6872 {
6873 __glibcxx_assert(_M_current != _M_next);
6874 return ranges::subrange(_M_current, _M_next);
6875 }
6876
6877 constexpr _Iterator&
6878 operator++()
6879 {
6880 __glibcxx_assert(_M_current != _M_next);
6881 _M_current = _M_next;
6882 _M_next = _M_parent->_M_find_next(_M_current);
6883 return *this;
6884 }
6885
6886 constexpr _Iterator
6887 operator++(int)
6888 {
6889 auto __tmp = *this;
6890 ++*this;
6891 return __tmp;
6892 }
6893
6894 constexpr _Iterator&
6895 operator--() requires bidirectional_range<_Vp>
6896 {
6897 _M_next = _M_current;
6898 _M_current = _M_parent->_M_find_prev(_M_next);
6899 return *this;
6900 }
6901
6902 constexpr _Iterator
6903 operator--(int) requires bidirectional_range<_Vp>
6904 {
6905 auto __tmp = *this;
6906 --*this;
6907 return __tmp;
6908 }
6909
6910 friend constexpr bool
6911 operator==(const _Iterator& __x, const _Iterator& __y)
6912 { return __x._M_current == __y._M_current; }
6913
6914 friend constexpr bool
6915 operator==(const _Iterator& __x, default_sentinel_t)
6916 { return __x._M_current == __x._M_next; }
6917 };
6918
6919 namespace views
6920 {
6921 namespace __detail
6922 {
6923 template<typename _Range, typename _Pred>
6924 concept __can_chunk_by_view
6925 = requires { chunk_by_view(std::declval<_Range>(), std::declval<_Pred>()); };
6926 }
6927
6928 struct _ChunkBy : __adaptor::_RangeAdaptor<_ChunkBy>
6929 {
6930 template<viewable_range _Range, typename _Pred>
6931 requires __detail::__can_chunk_by_view<_Range, _Pred>
6932 constexpr auto
6933 operator() [[nodiscard]] (_Range&& __r, _Pred&& __pred) const
6934 { return chunk_by_view(std::forward<_Range>(__r), std::forward<_Pred>(__pred)); }
6935
6936 using __adaptor::_RangeAdaptor<_ChunkBy>::operator();
6937 static constexpr int _S_arity = 2;
6938 static constexpr bool _S_has_simple_extra_args = true;
6939 };
6940
6941 inline constexpr _ChunkBy chunk_by;
6942 }
6943
6944#define __cpp_lib_ranges_join_with 202202L
6945
6946 namespace __detail
6947 {
6948 template<typename _Range, typename _Pattern>
6949 concept __compatible_joinable_ranges
6950 = common_with<range_value_t<_Range>, range_value_t<_Pattern>>
6951 && common_reference_with<range_reference_t<_Range>,
6952 range_reference_t<_Pattern>>
6953 && common_reference_with<range_rvalue_reference_t<_Range>,
6954 range_rvalue_reference_t<_Pattern>>;
6955
6956 template<typename _Range>
6957 concept __bidirectional_common = bidirectional_range<_Range> && common_range<_Range>;
6958 }
6959
6960 template<input_range _Vp, forward_range _Pattern>
6961 requires view<_Vp> && view<_Pattern>
6962 && input_range<range_reference_t<_Vp>>
6963 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
6964 class join_with_view : public view_interface<join_with_view<_Vp, _Pattern>>
6965 {
6966 using _InnerRange = range_reference_t<_Vp>;
6967
6968 _Vp _M_base = _Vp();
6969 __detail::__non_propagating_cache<remove_cv_t<_InnerRange>> _M_inner;
6970 _Pattern _M_pattern = _Pattern();
6971
6972 template<bool _Const> using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6973 template<bool _Const> using _InnerBase = range_reference_t<_Base<_Const>>;
6974 template<bool _Const> using _PatternBase = __detail::__maybe_const_t<_Const, _Pattern>;
6975
6976 template<bool _Const> using _OuterIter = iterator_t<_Base<_Const>>;
6977 template<bool _Const> using _InnerIter = iterator_t<_InnerBase<_Const>>;
6978 template<bool _Const> using _PatternIter = iterator_t<_PatternBase<_Const>>;
6979
6980 template<bool _Const>
6981 static constexpr bool _S_ref_is_glvalue = is_reference_v<_InnerBase<_Const>>;
6982
6983 template<bool _Const>
6984 struct __iter_cat
6985 { };
6986
6987 template<bool _Const>
6988 requires _S_ref_is_glvalue<_Const>
6989 && forward_range<_Base<_Const>>
6990 && forward_range<_InnerBase<_Const>>
6991 struct __iter_cat<_Const>
6992 {
6993 private:
6994 static auto
6995 _S_iter_cat()
6996 {
6997 using _OuterIter = join_with_view::_OuterIter<_Const>;
6998 using _InnerIter = join_with_view::_InnerIter<_Const>;
6999 using _PatternIter = join_with_view::_PatternIter<_Const>;
7000 using _OuterCat = typename iterator_traits<_OuterIter>::iterator_category;
7001 using _InnerCat = typename iterator_traits<_InnerIter>::iterator_category;
7002 using _PatternCat = typename iterator_traits<_PatternIter>::iterator_category;
7003 if constexpr (!is_lvalue_reference_v<common_reference_t<iter_reference_t<_InnerIter>,
7004 iter_reference_t<_PatternIter>>>)
7005 return input_iterator_tag{};
7006 else if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag>
7007 && derived_from<_InnerCat, bidirectional_iterator_tag>
7008 && derived_from<_PatternCat, bidirectional_iterator_tag>
7009 && common_range<_InnerBase<_Const>>
7010 && common_range<_PatternBase<_Const>>)
7011 return bidirectional_iterator_tag{};
7012 else if constexpr (derived_from<_OuterCat, forward_iterator_tag>
7013 && derived_from<_InnerCat, forward_iterator_tag>
7014 && derived_from<_PatternCat, forward_iterator_tag>)
7015 return forward_iterator_tag{};
7016 else
7017 return input_iterator_tag{};
7018 }
7019 public:
7020 using iterator_category = decltype(_S_iter_cat());
7021 };
7022
7023 template<bool> struct _Iterator;
7024 template<bool> struct _Sentinel;
7025
7026 public:
7027 join_with_view() requires (default_initializable<_Vp>
7028 && default_initializable<_Pattern>)
7029 = default;
7030
7031 constexpr
7032 join_with_view(_Vp __base, _Pattern __pattern)
7033 : _M_base(std::move(__base)), _M_pattern(std::move(__pattern))
7034 { }
7035
7036 template<input_range _Range>
7037 requires constructible_from<_Vp, views::all_t<_Range>>
7038 && constructible_from<_Pattern, single_view<range_value_t<_InnerRange>>>
7039 constexpr
7040 join_with_view(_Range&& __r, range_value_t<_InnerRange> __e)
7041 : _M_base(views::all(std::forward<_Range>(__r))),
7042 _M_pattern(views::single(std::move(__e)))
7043 { }
7044
7045 constexpr _Vp
7046 base() const& requires copy_constructible<_Vp>
7047 { return _M_base; }
7048
7049 constexpr _Vp
7050 base() &&
7051 { return std::move(_M_base); }
7052
7053 constexpr auto
7054 begin()
7055 {
7056 constexpr bool __use_const = is_reference_v<_InnerRange>
7057 && __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
7058 return _Iterator<__use_const>{*this, ranges::begin(_M_base)};
7059 }
7060
7061 constexpr auto
7062 begin() const
7063 requires input_range<const _Vp>
7064 && forward_range<const _Pattern>
7065 && is_reference_v<range_reference_t<const _Vp>>
7066 { return _Iterator<true>{*this, ranges::begin(_M_base)}; }
7067
7068 constexpr auto
7069 end()
7070 {
7071 constexpr bool __use_const
7072 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
7073 if constexpr (is_reference_v<_InnerRange>
7074 && forward_range<_Vp> && common_range<_Vp>
7075 && forward_range<_InnerRange> && common_range<_InnerRange>)
7076 return _Iterator<__use_const>{*this, ranges::end(_M_base)};
7077 else
7078 return _Sentinel<__use_const>{*this};
7079 }
7080
7081 constexpr auto
7082 end() const
7083 requires input_range<const _Vp>
7084 && forward_range<const _Pattern>
7085 && is_reference_v<range_reference_t<const _Vp>>
7086 {
7087 using _InnerConstRange = range_reference_t<const _Vp>;
7088 if constexpr (forward_range<const _Vp>
7089 && forward_range<_InnerConstRange>
7090 && common_range<const _Vp>
7091 && common_range<_InnerConstRange>)
7092 return _Iterator<true>{*this, ranges::end(_M_base)};
7093 else
7094 return _Sentinel<true>{*this};
7095 }
7096 };
7097
7098 template<typename _Range, typename _Pattern>
7099 join_with_view(_Range&&, _Pattern&&)
7100 -> join_with_view<views::all_t<_Range>, views::all_t<_Pattern>>;
7101
7102 template<input_range _Range>
7103 join_with_view(_Range&&, range_value_t<range_reference_t<_Range>>)
7104 -> join_with_view<views::all_t<_Range>,
7105 single_view<range_value_t<range_reference_t<_Range>>>>;
7106
7107 template<input_range _Vp, forward_range _Pattern>
7108 requires view<_Vp> && view<_Pattern>
7109 && input_range<range_reference_t<_Vp>>
7110 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7111 template<bool _Const>
7112 class join_with_view<_Vp, _Pattern>::_Iterator : public __iter_cat<_Const>
7113 {
7114 using _Parent = __detail::__maybe_const_t<_Const, join_with_view>;
7115 using _Base = join_with_view::_Base<_Const>;
7116 using _InnerBase = join_with_view::_InnerBase<_Const>;
7117 using _PatternBase = join_with_view::_PatternBase<_Const>;
7118
7119 using _OuterIter = join_with_view::_OuterIter<_Const>;
7120 using _InnerIter = join_with_view::_InnerIter<_Const>;
7121 using _PatternIter = join_with_view::_PatternIter<_Const>;
7122
7123 static constexpr bool _S_ref_is_glvalue = join_with_view::_S_ref_is_glvalue<_Const>;
7124
7125 _Parent* _M_parent = nullptr;
7126 _OuterIter _M_outer_it = _OuterIter();
7127 variant<_PatternIter, _InnerIter> _M_inner_it;
7128
7129 constexpr
7130 _Iterator(_Parent& __parent, iterator_t<_Base> __outer)
7131 : _M_parent(std::__addressof(__parent)), _M_outer_it(std::move(__outer))
7132 {
7133 if (_M_outer_it != ranges::end(_M_parent->_M_base))
7134 {
7135 auto&& __inner = _M_update_inner(_M_outer_it);
7136 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7137 _M_satisfy();
7138 }
7139 }
7140
7141 constexpr auto&&
7142 _M_update_inner(const _OuterIter& __x)
7143 {
7144 if constexpr (_S_ref_is_glvalue)
7145 return *__x;
7146 else
7147 return _M_parent->_M_inner._M_emplace_deref(__x);
7148 }
7149
7150 constexpr auto&&
7151 _M_get_inner(const _OuterIter& __x)
7152 {
7153 if constexpr (_S_ref_is_glvalue)
7154 return *__x;
7155 else
7156 return *_M_parent->_M_inner;
7157 }
7158
7159 constexpr void
7160 _M_satisfy()
7161 {
7162 while (true)
7163 {
7164 if (_M_inner_it.index() == 0)
7165 {
7166 if (std::get<0>(_M_inner_it) != ranges::end(_M_parent->_M_pattern))
7167 break;
7168
7169 auto&& __inner = _M_update_inner(_M_outer_it);
7170 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7171 }
7172 else
7173 {
7174 auto&& __inner = _M_get_inner(_M_outer_it);
7175 if (std::get<1>(_M_inner_it) != ranges::end(__inner))
7176 break;
7177
7178 if (++_M_outer_it == ranges::end(_M_parent->_M_base))
7179 {
7180 if constexpr (_S_ref_is_glvalue)
7181 _M_inner_it.template emplace<0>();
7182 break;
7183 }
7184
7185 _M_inner_it.template emplace<0>(ranges::begin(_M_parent->_M_pattern));
7186 }
7187 }
7188 }
7189
7190 static auto
7191 _S_iter_concept()
7192 {
7193 if constexpr (_S_ref_is_glvalue
7194 && bidirectional_range<_Base>
7195 && __detail::__bidirectional_common<_InnerBase>
7196 && __detail::__bidirectional_common<_PatternBase>)
7197 return bidirectional_iterator_tag{};
7198 else if constexpr (_S_ref_is_glvalue
7199 && forward_range<_Base>
7200 && forward_range<_InnerBase>)
7201 return forward_iterator_tag{};
7202 else
7203 return input_iterator_tag{};
7204 }
7205
7206 friend join_with_view;
7207
7208 public:
7209 using iterator_concept = decltype(_S_iter_concept());
7210 // iterator_category defined in join_with_view::__iter_cat
7211 using value_type = common_type_t<iter_value_t<_InnerIter>,
7212 iter_value_t<_PatternIter>>;
7213 using difference_type = common_type_t<iter_difference_t<_OuterIter>,
7214 iter_difference_t<_InnerIter>,
7215 iter_difference_t<_PatternIter>>;
7216
7217 _Iterator() requires default_initializable<_OuterIter> = default;
7218
7219 constexpr
7220 _Iterator(_Iterator<!_Const> __i)
7221 requires _Const
7222 && convertible_to<iterator_t<_Vp>, _OuterIter>
7223 && convertible_to<iterator_t<_InnerRange>, _InnerIter>
7224 && convertible_to<iterator_t<_Pattern>, _PatternIter>
7225 : _M_parent(__i._M_parent),
7226 _M_outer_it(std::move(__i._M_outer_it))
7227 {
7228 if (__i._M_inner_it.index() == 0)
7229 _M_inner_it.template emplace<0>(std::get<0>(std::move(__i._M_inner_it)));
7230 else
7231 _M_inner_it.template emplace<1>(std::get<1>(std::move(__i._M_inner_it)));
7232 }
7233
7234 constexpr common_reference_t<iter_reference_t<_InnerIter>,
7235 iter_reference_t<_PatternIter>>
7236 operator*() const
7237 {
7238 if (_M_inner_it.index() == 0)
7239 return *std::get<0>(_M_inner_it);
7240 else
7241 return *std::get<1>(_M_inner_it);
7242 }
7243
7244 constexpr _Iterator&
7245 operator++()
7246 {
7247 if (_M_inner_it.index() == 0)
7248 ++std::get<0>(_M_inner_it);
7249 else
7250 ++std::get<1>(_M_inner_it);
7251 _M_satisfy();
7252 return *this;
7253 }
7254
7255 constexpr void
7256 operator++(int)
7257 { ++*this; }
7258
7259 constexpr _Iterator
7260 operator++(int)
7261 requires _S_ref_is_glvalue
7262 && forward_iterator<_OuterIter> && forward_iterator<_InnerIter>
7263 {
7264 _Iterator __tmp = *this;
7265 ++*this;
7266 return __tmp;
7267 }
7268
7269 constexpr _Iterator&
7270 operator--()
7271 requires _S_ref_is_glvalue
7272 && bidirectional_range<_Base>
7273 && __detail::__bidirectional_common<_InnerBase>
7274 && __detail::__bidirectional_common<_PatternBase>
7275 {
7276 if (_M_outer_it == ranges::end(_M_parent->_M_base))
7277 {
7278 auto&& __inner = *--_M_outer_it;
7279 _M_inner_it.template emplace<1>(ranges::end(__inner));
7280 }
7281
7282 while (true)
7283 {
7284 if (_M_inner_it.index() == 0)
7285 {
7286 auto& __it = std::get<0>(_M_inner_it);
7287 if (__it == ranges::begin(_M_parent->_M_pattern))
7288 {
7289 auto&& __inner = *--_M_outer_it;
7290 _M_inner_it.template emplace<1>(ranges::end(__inner));
7291 }
7292 else
7293 break;
7294 }
7295 else
7296 {
7297 auto& __it = std::get<1>(_M_inner_it);
7298 auto&& __inner = *_M_outer_it;
7299 if (__it == ranges::begin(__inner))
7300 _M_inner_it.template emplace<0>(ranges::end(_M_parent->_M_pattern));
7301 else
7302 break;
7303 }
7304 }
7305
7306 if (_M_inner_it.index() == 0)
7307 --std::get<0>(_M_inner_it);
7308 else
7309 --std::get<1>(_M_inner_it);
7310 return *this;
7311 }
7312
7313 constexpr _Iterator
7314 operator--(int)
7315 requires _S_ref_is_glvalue && bidirectional_range<_Base>
7316 && __detail::__bidirectional_common<_InnerBase>
7317 && __detail::__bidirectional_common<_PatternBase>
7318 {
7319 _Iterator __tmp = *this;
7320 --*this;
7321 return __tmp;
7322 }
7323
7324 friend constexpr bool
7325 operator==(const _Iterator& __x, const _Iterator& __y)
7326 requires _S_ref_is_glvalue
7327 && equality_comparable<_OuterIter> && equality_comparable<_InnerIter>
7328 { return __x._M_outer_it == __y._M_outer_it && __x._M_inner_it ==__y._M_inner_it; }
7329
7330 friend constexpr common_reference_t<iter_rvalue_reference_t<_InnerIter>,
7331 iter_rvalue_reference_t<_PatternIter>>
7332 iter_move(const _Iterator& __x)
7333 {
7334 if (__x._M_inner_it.index() == 0)
7335 return ranges::iter_move(std::get<0>(__x._M_inner_it));
7336 else
7337 return ranges::iter_move(std::get<1>(__x._M_inner_it));
7338 }
7339
7340 friend constexpr void
7341 iter_swap(const _Iterator& __x, const _Iterator& __y)
7342 requires indirectly_swappable<_InnerIter, _PatternIter>
7343 {
7344 if (__x._M_inner_it.index() == 0)
7345 {
7346 if (__y._M_inner_it.index() == 0)
7347 ranges::iter_swap(std::get<0>(__x._M_inner_it), std::get<0>(__y._M_inner_it));
7348 else
7349 ranges::iter_swap(std::get<0>(__x._M_inner_it), std::get<1>(__y._M_inner_it));
7350 }
7351 else
7352 {
7353 if (__y._M_inner_it.index() == 0)
7354 ranges::iter_swap(std::get<1>(__x._M_inner_it), std::get<0>(__y._M_inner_it));
7355 else
7356 ranges::iter_swap(std::get<1>(__x._M_inner_it), std::get<1>(__y._M_inner_it));
7357 }
7358 }
7359 };
7360
7361 template<input_range _Vp, forward_range _Pattern>
7362 requires view<_Vp> && view<_Pattern>
7363 && input_range<range_reference_t<_Vp>>
7364 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7365 template<bool _Const>
7366 class join_with_view<_Vp, _Pattern>::_Sentinel
7367 {
7368 using _Parent = __detail::__maybe_const_t<_Const, join_with_view>;
7369 using _Base = join_with_view::_Base<_Const>;
7370
7371 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
7372
7373 constexpr explicit
7374 _Sentinel(_Parent& __parent)
7375 : _M_end(ranges::end(__parent._M_base))
7376 { }
7377
7378 friend join_with_view;
7379
7380 public:
7381 _Sentinel() = default;
7382
7383 constexpr
7384 _Sentinel(_Sentinel<!_Const> __s)
7385 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
7386 : _M_end(std::move(__s._M_end))
7387 { }
7388
7389 template<bool _OtherConst>
7390 requires sentinel_for<sentinel_t<_Base>,
7391 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
7392 friend constexpr bool
7393 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
7394 { return __x._M_outer_it == __y._M_end; }
7395 };
7396
7397 namespace views
7398 {
7399 namespace __detail
7400 {
7401 template<typename _Range, typename _Pattern>
7402 concept __can_join_with_view
7403 = requires { join_with_view(std::declval<_Range>(), std::declval<_Pattern>()); };
7404 } // namespace __detail
7405
7406 struct _JoinWith : __adaptor::_RangeAdaptor<_JoinWith>
7407 {
7408 template<viewable_range _Range, typename _Pattern>
7409 requires __detail::__can_join_with_view<_Range, _Pattern>
7410 constexpr auto
7411 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f) const
7412 {
7413 return join_with_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
7414 }
7415
7416 using _RangeAdaptor<_JoinWith>::operator();
7417 static constexpr int _S_arity = 2;
7418 template<typename _Pattern>
7419 static constexpr bool _S_has_simple_extra_args
7420 = _LazySplit::_S_has_simple_extra_args<_Pattern>;
7421 };
7422
7423 inline constexpr _JoinWith join_with;
7424 } // namespace views
7425
7426#define __cpp_lib_ranges_repeat 202207L
7427
7428 template<copy_constructible _Tp, semiregular _Bound = unreachable_sentinel_t>
7429 requires is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>>
7430 && (__detail::__is_integer_like<_Bound> || same_as<_Bound, unreachable_sentinel_t>)
7431 class repeat_view : public view_interface<repeat_view<_Tp, _Bound>>
7432 {
7433 __detail::__box<_Tp> _M_value;
7434 [[no_unique_address]] _Bound _M_bound = _Bound();
7435
7436 struct _Iterator;
7437
7438 template<typename _Range>
7439 friend constexpr auto
7440 views::__detail::__take_of_repeat_view(_Range&&, range_difference_t<_Range>);
7441
7442 template<typename _Range>
7443 friend constexpr auto
7444 views::__detail::__drop_of_repeat_view(_Range&&, range_difference_t<_Range>);
7445
7446 public:
7447 repeat_view() requires default_initializable<_Tp> = default;
7448
7449 constexpr explicit
7450 repeat_view(const _Tp& __value, _Bound __bound = _Bound())
7451 : _M_value(__value), _M_bound(__bound)
7452 {
7453 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7454 __glibcxx_assert(__bound >= 0);
7455 }
7456
7457 constexpr explicit
7458 repeat_view(_Tp&& __value, _Bound __bound = _Bound())
7459 : _M_value(std::move(__value)), _M_bound(__bound)
7460 { }
7461
7462 template<typename... _Args, typename... _BoundArgs>
7463 requires constructible_from<_Tp, _Args...>
7464 && constructible_from<_Bound, _BoundArgs...>
7465 constexpr explicit
7466 repeat_view(piecewise_construct_t,
7467 tuple<_Args...> __args,
7468 tuple<_BoundArgs...> __bound_args = tuple<>{})
7469 : _M_value(std::make_from_tuple<_Tp>(std::move(__args))),
7470 _M_bound(std::make_from_tuple<_Bound>(std::move(__bound_args)))
7471 { }
7472
7473 constexpr _Iterator
7474 begin() const
7475 { return _Iterator(std::__addressof(*_M_value)); }
7476
7477 constexpr _Iterator
7478 end() const requires (!same_as<_Bound, unreachable_sentinel_t>)
7479 { return _Iterator(std::__addressof(*_M_value), _M_bound); }
7480
7481 constexpr unreachable_sentinel_t
7482 end() const noexcept
7483 { return unreachable_sentinel; }
7484
7485 constexpr auto
7486 size() const requires (!same_as<_Bound, unreachable_sentinel_t>)
7487 { return __detail::__to_unsigned_like(_M_bound); }
7488 };
7489
7490 template<typename _Tp, typename _Bound>
7491 repeat_view(_Tp, _Bound) -> repeat_view<_Tp, _Bound>;
7492
7493 template<copy_constructible _Tp, semiregular _Bound>
7494 requires is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>>
7495 && (__detail::__is_integer_like<_Bound> || same_as<_Bound, unreachable_sentinel_t>)
7496 class repeat_view<_Tp, _Bound>::_Iterator
7497 {
7498 using __index_type
7499 = __conditional_t<same_as<_Bound, unreachable_sentinel_t>, ptrdiff_t, _Bound>;
7500
7501 const _Tp* _M_value = nullptr;
7502 __index_type _M_current = __index_type();
7503
7504 constexpr explicit
7505 _Iterator(const _Tp* __value, __index_type __bound = __index_type())
7506 : _M_value(__value), _M_current(__bound)
7507 {
7508 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7509 __glibcxx_assert(__bound >= 0);
7510 }
7511
7512 friend repeat_view;
7513
7514 public:
7515 using iterator_concept = random_access_iterator_tag;
7516 using iterator_category = random_access_iterator_tag;
7517 using value_type = _Tp;
7518 using difference_type = __conditional_t<__detail::__is_signed_integer_like<__index_type>,
7519 __index_type,
7520 __detail::__iota_diff_t<__index_type>>;
7521
7522 _Iterator() = default;
7523
7524 constexpr const _Tp&
7525 operator*() const noexcept
7526 { return *_M_value; }
7527
7528 constexpr _Iterator&
7529 operator++()
7530 {
7531 ++_M_current;
7532 return *this;
7533 }
7534
7535 constexpr _Iterator
7536 operator++(int)
7537 {
7538 auto __tmp = *this;
7539 ++*this;
7540 return __tmp;
7541 }
7542
7543 constexpr _Iterator&
7544 operator--()
7545 {
7546 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7547 __glibcxx_assert(_M_current > 0);
7548 --_M_current;
7549 return *this;
7550 }
7551
7552 constexpr _Iterator
7553 operator--(int)
7554 {
7555 auto __tmp = *this;
7556 --*this;
7557 return __tmp;
7558 }
7559
7560 constexpr _Iterator&
7561 operator+=(difference_type __n)
7562 {
7563 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7564 __glibcxx_assert(_M_current + __n >= 0);
7565 _M_current += __n;
7566 return *this;
7567 }
7568
7569 constexpr _Iterator&
7570 operator-=(difference_type __n)
7571 {
7572 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7573 __glibcxx_assert(_M_current - __n >= 0);
7574 _M_current -= __n;
7575 return *this;
7576 }
7577
7578 constexpr const _Tp&
7579 operator[](difference_type __n) const noexcept
7580 { return *(*this + __n); }
7581
7582 friend constexpr bool
7583 operator==(const _Iterator& __x, const _Iterator& __y)
7584 { return __x._M_current == __y._M_current; }
7585
7586 friend constexpr auto
7587 operator<=>(const _Iterator& __x, const _Iterator& __y)
7588 { return __x._M_current <=> __y._M_current; }
7589
7590 friend constexpr _Iterator
7591 operator+(_Iterator __i, difference_type __n)
7592 {
7593 __i += __n;
7594 return __i;
7595 }
7596
7597 friend constexpr _Iterator
7598 operator+(difference_type __n, _Iterator __i)
7599 { return __i + __n; }
7600
7601 friend constexpr _Iterator
7602 operator-(_Iterator __i, difference_type __n)
7603 {
7604 __i -= __n;
7605 return __i;
7606 }
7607
7608 friend constexpr difference_type
7609 operator-(const _Iterator& __x, const _Iterator& __y)
7610 {
7611 return (static_cast<difference_type>(__x._M_current)
7612 - static_cast<difference_type>(__y._M_current));
7613 }
7614 };
7615
7616 namespace views
7617 {
7618 namespace __detail
7619 {
7620 template<typename _Tp, typename _Bound>
7621 inline constexpr bool __is_repeat_view<repeat_view<_Tp, _Bound>> = true;
7622
7623 template<typename _Tp>
7624 concept __can_repeat_view
7625 = requires { repeat_view(std::declval<_Tp>()); };
7626
7627 template<typename _Tp, typename _Bound>
7628 concept __can_bounded_repeat_view
7629 = requires { repeat_view(std::declval<_Tp>(), std::declval<_Bound>()); };
7630 }
7631
7632 struct _Repeat
7633 {
7634 template<typename _Tp>
7635 requires __detail::__can_repeat_view<_Tp>
7636 constexpr auto
7637 operator() [[nodiscard]] (_Tp&& __value) const
7638 { return repeat_view(std::forward<_Tp>(__value)); }
7639
7640 template<typename _Tp, typename _Bound>
7641 requires __detail::__can_bounded_repeat_view<_Tp, _Bound>
7642 constexpr auto
7643 operator() [[nodiscard]] (_Tp&& __value, _Bound __bound) const
7644 { return repeat_view(std::forward<_Tp>(__value), __bound); }
7645 };
7646
7647 inline constexpr _Repeat repeat;
7648
7649 namespace __detail
7650 {
7651 template<typename _Range>
7652 constexpr auto
7653 __take_of_repeat_view(_Range&& __r, range_difference_t<_Range> __n)
7654 {
7655 using _Tp = remove_cvref_t<_Range>;
7656 static_assert(__is_repeat_view<_Tp>);
7657 if constexpr (sized_range<_Tp>)
7658 return views::repeat(*__r._M_value, std::min(ranges::distance(__r), __n));
7659 else
7660 return views::repeat(*__r._M_value, __n);
7661 }
7662
7663 template<typename _Range>
7664 constexpr auto
7665 __drop_of_repeat_view(_Range&& __r, range_difference_t<_Range> __n)
7666 {
7667 using _Tp = remove_cvref_t<_Range>;
7668 static_assert(__is_repeat_view<_Tp>);
7669 if constexpr (sized_range<_Tp>)
7670 {
7671 auto __sz = ranges::distance(__r);
7672 return views::repeat(*__r._M_value, __sz - std::min(__sz, __n));
7673 }
7674 else
7675 return __r;
7676 }
7677 }
7678 }
7679
7680#define __cpp_lib_ranges_stride 202207L
7681
7682 template<input_range _Vp>
7683 requires view<_Vp>
7684 class stride_view : public view_interface<stride_view<_Vp>>
7685 {
7686 _Vp _M_base;
7687 range_difference_t<_Vp> _M_stride;
7688
7689 template<bool _Const> using _Base = __detail::__maybe_const_t<_Const, _Vp>;
7690
7691 template<bool _Const>
7692 struct __iter_cat
7693 { };
7694
7695 template<bool _Const>
7696 requires forward_range<_Base<_Const>>
7697 struct __iter_cat<_Const>
7698 {
7699 private:
7700 static auto
7701 _S_iter_cat()
7702 {
7703 using _Cat = typename iterator_traits<iterator_t<_Base<_Const>>>::iterator_category;
7704 if constexpr (derived_from<_Cat, random_access_iterator_tag>)
7705 return random_access_iterator_tag{};
7706 else
7707 return _Cat{};
7708 }
7709 public:
7710 using iterator_category = decltype(_S_iter_cat());
7711 };
7712
7713 template<bool> class _Iterator;
7714
7715 public:
7716 constexpr explicit
7717 stride_view(_Vp __base, range_difference_t<_Vp> __stride)
7718 : _M_base(std::move(__base)), _M_stride(__stride)
7719 { __glibcxx_assert(__stride > 0); }
7720
7721 constexpr _Vp
7722 base() const& requires copy_constructible<_Vp>
7723 { return _M_base; }
7724
7725 constexpr _Vp
7726 base() &&
7727 { return std::move(_M_base); }
7728
7729 constexpr range_difference_t<_Vp>
7730 stride() const noexcept
7731 { return _M_stride; }
7732
7733 constexpr auto
7734 begin() requires (!__detail::__simple_view<_Vp>)
7735 { return _Iterator<false>(this, ranges::begin(_M_base)); }
7736
7737 constexpr auto
7738 begin() const requires range<const _Vp>
7739 { return _Iterator<true>(this, ranges::begin(_M_base)); }
7740
7741 constexpr auto
7742 end() requires (!__detail::__simple_view<_Vp>)
7743 {
7744 if constexpr (common_range<_Vp> && sized_range<_Vp> && forward_range<_Vp>)
7745 {
7746 auto __missing = (_M_stride - ranges::distance(_M_base) % _M_stride) % _M_stride;
7747 return _Iterator<false>(this, ranges::end(_M_base), __missing);
7748 }
7749 else if constexpr (common_range<_Vp> && !bidirectional_range<_Vp>)
7750 return _Iterator<false>(this, ranges::end(_M_base));
7751 else
7752 return default_sentinel;
7753 }
7754
7755 constexpr auto
7756 end() const requires range<const _Vp>
7757 {
7758 if constexpr (common_range<const _Vp> && sized_range<const _Vp>
7759 && forward_range<const _Vp>)
7760 {
7761 auto __missing = (_M_stride - ranges::distance(_M_base) % _M_stride) % _M_stride;
7762 return _Iterator<true>(this, ranges::end(_M_base), __missing);
7763 }
7764 else if constexpr (common_range<const _Vp> && !bidirectional_range<const _Vp>)
7765 return _Iterator<true>(this, ranges::end(_M_base));
7766 else
7767 return default_sentinel;
7768 }
7769
7770 constexpr auto
7771 size() requires sized_range<_Vp>
7772 {
7773 return __detail::__to_unsigned_like
7774 (__detail::__div_ceil(ranges::distance(_M_base), _M_stride));
7775 }
7776
7777 constexpr auto
7778 size() const requires sized_range<const _Vp>
7779 {
7780 return __detail::__to_unsigned_like
7781 (__detail::__div_ceil(ranges::distance(_M_base), _M_stride));
7782 }
7783 };
7784
7785 template<typename _Range>
7786 stride_view(_Range&&, range_difference_t<_Range>) -> stride_view<views::all_t<_Range>>;
7787
7788 template<typename _Vp>
7789 inline constexpr bool enable_borrowed_range<stride_view<_Vp>>
7790 = enable_borrowed_range<_Vp>;
7791
7792 template<input_range _Vp>
7793 requires view<_Vp>
7794 template<bool _Const>
7795 class stride_view<_Vp>::_Iterator : public __iter_cat<_Const>
7796 {
7797 using _Parent = __detail::__maybe_const_t<_Const, stride_view>;
7798 using _Base = stride_view::_Base<_Const>;
7799
7800 iterator_t<_Base> _M_current = iterator_t<_Base>();
7801 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
7802 range_difference_t<_Base> _M_stride = 0;
7803 range_difference_t<_Base> _M_missing = 0;
7804
7805 constexpr
7806 _Iterator(_Parent* __parent, iterator_t<_Base> __current,
7807 range_difference_t<_Base> __missing = 0)
7808 : _M_current(std::move(__current)), _M_end(ranges::end(__parent->_M_base)),
7809 _M_stride(__parent->_M_stride), _M_missing(__missing)
7810 { }
7811
7812 static auto
7813 _S_iter_concept()
7814 {
7815 if constexpr (random_access_range<_Base>)
7816 return random_access_iterator_tag{};
7817 else if constexpr (bidirectional_range<_Base>)
7818 return bidirectional_iterator_tag{};
7819 else if constexpr (forward_range<_Base>)
7820 return forward_iterator_tag{};
7821 else
7822 return input_iterator_tag{};
7823 }
7824
7825 friend stride_view;
7826
7827 public:
7828 using difference_type = range_difference_t<_Base>;
7829 using value_type = range_value_t<_Base>;
7830 using iterator_concept = decltype(_S_iter_concept());
7831 // iterator_category defined in stride_view::__iter_cat
7832
7833 _Iterator() requires default_initializable<iterator_t<_Base>> = default;
7834
7835 constexpr
7836 _Iterator(_Iterator<!_Const> __other)
7837 requires _Const
7838 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
7839 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
7840 : _M_current(std::move(__other._M_current)), _M_end(std::move(__other._M_end)),
7841 _M_stride(__other._M_stride), _M_missing(__other._M_missing)
7842 { }
7843
7844 constexpr iterator_t<_Base>
7845 base() &&
7846 { return std::move(_M_current); }
7847
7848 constexpr const iterator_t<_Base>&
7849 base() const & noexcept
7850 { return _M_current; }
7851
7852 constexpr decltype(auto)
7853 operator*() const
7854 { return *_M_current; }
7855
7856 constexpr _Iterator&
7857 operator++()
7858 {
7859 __glibcxx_assert(_M_current != _M_end);
7860 _M_missing = ranges::advance(_M_current, _M_stride, _M_end);
7861 return *this;
7862 }
7863
7864 constexpr void
7865 operator++(int)
7866 { ++*this; }
7867
7868 constexpr _Iterator
7869 operator++(int) requires forward_range<_Base>
7870 {
7871 auto __tmp = *this;
7872 ++*this;
7873 return __tmp;
7874 }
7875
7876 constexpr _Iterator&
7877 operator--() requires bidirectional_range<_Base>
7878 {
7879 ranges::advance(_M_current, _M_missing - _M_stride);
7880 _M_missing = 0;
7881 return *this;
7882 }
7883
7884 constexpr _Iterator
7885 operator--(int) requires bidirectional_range<_Base>
7886 {
7887 auto __tmp = *this;
7888 --*this;
7889 return __tmp;
7890 }
7891
7892 constexpr _Iterator&
7893 operator+=(difference_type __n) requires random_access_range<_Base>
7894 {
7895 if (__n > 0)
7896 {
7897 __glibcxx_assert(ranges::distance(_M_current, _M_end) > _M_stride * (__n - 1));
7898 _M_missing = ranges::advance(_M_current, _M_stride * __n, _M_end);
7899 }
7900 else if (__n < 0)
7901 {
7902 ranges::advance(_M_current, _M_stride * __n + _M_missing);
7903 _M_missing = 0;
7904 }
7905 return *this;
7906 }
7907
7908 constexpr _Iterator&
7909 operator-=(difference_type __n) requires random_access_range<_Base>
7910 { return *this += -__n; }
7911
7912 constexpr decltype(auto) operator[](difference_type __n) const
7913 requires random_access_range<_Base>
7914 { return *(*this + __n); }
7915
7916 friend constexpr bool
7917 operator==(const _Iterator& __x, default_sentinel_t)
7918 { return __x._M_current == __x._M_end; }
7919
7920 friend constexpr bool
7921 operator==(const _Iterator& __x, const _Iterator& __y)
7922 requires equality_comparable<iterator_t<_Base>>
7923 { return __x._M_current == __y._M_current; }
7924
7925 friend constexpr bool
7926 operator<(const _Iterator& __x, const _Iterator& __y)
7927 requires random_access_range<_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 __y._M_current < __x._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 !(__x._M_current < __y._M_current); }
7944
7945 friend constexpr auto
7946 operator<=>(const _Iterator& __x, const _Iterator& __y)
7947 requires random_access_range<_Base> && three_way_comparable<iterator_t<_Base>>
7948 { return __x._M_current <=> __y._M_current; }
7949
7950 friend constexpr _Iterator
7951 operator+(const _Iterator& __i, difference_type __n)
7952 requires random_access_range<_Base>
7953 {
7954 auto __r = __i;
7955 __r += __n;
7956 return __r;
7957 }
7958
7959 friend constexpr _Iterator
7960 operator+(difference_type __n, const _Iterator& __i)
7961 requires random_access_range<_Base>
7962 { return __i + __n; }
7963
7964 friend constexpr _Iterator
7965 operator-(const _Iterator& __i, difference_type __n)
7966 requires random_access_range<_Base>
7967 {
7968 auto __r = __i;
7969 __r -= __n;
7970 return __r;
7971 }
7972
7973 friend constexpr difference_type
7974 operator-(const _Iterator& __x, const _Iterator& __y)
7975 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
7976 {
7977 auto __n = __x._M_current - __y._M_current;
7978 if constexpr (forward_range<_Base>)
7979 return (__n + __x._M_missing - __y._M_missing) / __x._M_stride;
7980 else if (__n < 0)
7981 return -__detail::__div_ceil(-__n, __x._M_stride);
7982 else
7983 return __detail::__div_ceil(__n, __x._M_stride);
7984 }
7985
7986 friend constexpr difference_type
7987 operator-(default_sentinel_t __y, const _Iterator& __x)
7988 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
7989 { return __detail::__div_ceil(__x._M_end - __x._M_current, __x._M_stride); }
7990
7991 friend constexpr difference_type
7992 operator-(const _Iterator& __x, default_sentinel_t __y)
7993 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
7994 { return -(__y - __x); }
7995
7996 friend constexpr range_rvalue_reference_t<_Base>
7997 iter_move(const _Iterator& __i)
7998 noexcept(noexcept(ranges::iter_move(__i._M_current)))
7999 { return ranges::iter_move(__i._M_current); }
8000
8001 friend constexpr void
8002 iter_swap(const _Iterator& __x, const _Iterator& __y)
8003 noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
8004 requires indirectly_swappable<iterator_t<_Base>>
8005 { ranges::iter_swap(__x._M_current, __y._M_current); }
8006 };
8007
8008 namespace views
8009 {
8010 namespace __detail
8011 {
8012 template<typename _Range, typename _Dp>
8013 concept __can_stride_view
8014 = requires { stride_view(std::declval<_Range>(), std::declval<_Dp>()); };
8015 }
8016
8017 struct _Stride : __adaptor::_RangeAdaptor<_Stride>
8018 {
8019 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
8020 requires __detail::__can_stride_view<_Range, _Dp>
8021 constexpr auto
8022 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
8023 { return stride_view(std::forward<_Range>(__r), __n); }
8024
8025 using __adaptor::_RangeAdaptor<_Stride>::operator();
8026 static constexpr int _S_arity = 2;
8027 static constexpr bool _S_has_simple_extra_args = true;
8028 };
8029
8030 inline constexpr _Stride stride;
8031 }
8032
8033#define __cpp_lib_ranges_cartesian_product 202207L
8034
8035 namespace __detail
8036 {
8037 template<bool _Const, typename _First, typename... _Vs>
8038 concept __cartesian_product_is_random_access
8039 = (random_access_range<__maybe_const_t<_Const, _First>>
8040 && ...
8041 && (random_access_range<__maybe_const_t<_Const, _Vs>>
8042 && sized_range<__maybe_const_t<_Const, _Vs>>));
8043
8044 template<typename _Range>
8045 concept __cartesian_product_common_arg
8046 = common_range<_Range> || (sized_range<_Range> && random_access_range<_Range>);
8047
8048 template<bool _Const, typename _First, typename... _Vs>
8049 concept __cartesian_product_is_bidirectional
8050 = (bidirectional_range<__maybe_const_t<_Const, _First>>
8051 && ...
8052 && (bidirectional_range<__maybe_const_t<_Const, _Vs>>
8053 && __cartesian_product_common_arg<__maybe_const_t<_Const, _Vs>>));
8054
8055 template<typename _First, typename... _Vs>
8056 concept __cartesian_product_is_common = __cartesian_product_common_arg<_First>;
8057
8058 template<typename... _Vs>
8059 concept __cartesian_product_is_sized = (sized_range<_Vs> && ...);
8060
8061 template<bool _Const, template<typename> class FirstSent, typename _First, typename... _Vs>
8062 concept __cartesian_is_sized_sentinel
8063 = (sized_sentinel_for<FirstSent<__maybe_const_t<_Const, _First>>,
8064 iterator_t<__maybe_const_t<_Const, _First>>>
8065 && ...
8066 && (sized_range<__maybe_const_t<_Const, _Vs>>
8067 && sized_sentinel_for<iterator_t<__maybe_const_t<_Const, _Vs>>,
8068 iterator_t<__maybe_const_t<_Const, _Vs>>>));
8069
8070 template<__cartesian_product_common_arg _Range>
8071 constexpr auto
8072 __cartesian_common_arg_end(_Range& __r)
8073 {
8074 if constexpr (common_range<_Range>)
8075 return ranges::end(__r);
8076 else
8077 return ranges::begin(__r) + ranges::distance(__r);
8078 }
8079 } // namespace __detail
8080
8081 template<input_range _First, forward_range... _Vs>
8082 requires (view<_First> && ... && view<_Vs>)
8083 class cartesian_product_view : public view_interface<cartesian_product_view<_First, _Vs...>>
8084 {
8085 tuple<_First, _Vs...> _M_bases;
8086
8087 template<bool> class _Iterator;
8088
8089 static auto
8090 _S_difference_type()
8091 {
8092 // TODO: Implement the recommended practice of using the smallest
8093 // sufficiently wide type according to the maximum sizes of the
8094 // underlying ranges?
8095 return common_type_t<ptrdiff_t,
8096 range_difference_t<_First>,
8097 range_difference_t<_Vs>...>{};
8098 }
8099
8100 public:
8101 cartesian_product_view() = default;
8102
8103 constexpr explicit
8104 cartesian_product_view(_First __first, _Vs... __rest)
8105 : _M_bases(std::move(__first), std::move(__rest)...)
8106 { }
8107
8108 constexpr _Iterator<false>
8109 begin() requires (!__detail::__simple_view<_First> || ... || !__detail::__simple_view<_Vs>)
8110 { return _Iterator<false>(*this, __detail::__tuple_transform(ranges::begin, _M_bases)); }
8111
8112 constexpr _Iterator<true>
8113 begin() const requires (range<const _First> && ... && range<const _Vs>)
8114 { return _Iterator<true>(*this, __detail::__tuple_transform(ranges::begin, _M_bases)); }
8115
8116 constexpr _Iterator<false>
8117 end() requires ((!__detail::__simple_view<_First> || ... || !__detail::__simple_view<_Vs>)
8118 && __detail::__cartesian_product_is_common<_First, _Vs...>)
8119 {
8120 auto __its = [this]<size_t... _Is>(index_sequence<_Is...>) {
8121 using _Ret = __detail::__tuple_or_pair_t<iterator_t<_First>,
8122 iterator_t<_Vs>...>;
8123 bool __empty_tail = (ranges::empty(std::get<1 + _Is>(_M_bases)) || ...);
8124 auto& __first = std::get<0>(_M_bases);
8125 return _Ret{(__empty_tail
8126 ? ranges::begin(__first)
8127 : __detail::__cartesian_common_arg_end(__first)),
8128 ranges::begin(std::get<1 + _Is>(_M_bases))...};
8129 }(make_index_sequence<sizeof...(_Vs)>{});
8130
8131 return _Iterator<false>{*this, std::move(__its)};
8132 }
8133
8134 constexpr _Iterator<true>
8135 end() const requires __detail::__cartesian_product_is_common<const _First, const _Vs...>
8136 {
8137 auto __its = [this]<size_t... _Is>(index_sequence<_Is...>) {
8138 using _Ret = __detail::__tuple_or_pair_t<iterator_t<const _First>,
8139 iterator_t<const _Vs>...>;
8140 bool __empty_tail = (ranges::empty(std::get<1 + _Is>(_M_bases)) || ...);
8141 auto& __first = std::get<0>(_M_bases);
8142 return _Ret{(__empty_tail
8143 ? ranges::begin(__first)
8144 : __detail::__cartesian_common_arg_end(__first)),
8145 ranges::begin(std::get<1 + _Is>(_M_bases))...};
8146 }(make_index_sequence<sizeof...(_Vs)>{});
8147
8148 return _Iterator<true>{*this, std::move(__its)};
8149 }
8150
8151 constexpr default_sentinel_t
8152 end() const noexcept
8153 { return default_sentinel; }
8154
8155 constexpr auto
8156 size() requires __detail::__cartesian_product_is_sized<_First, _Vs...>
8157 {
8158 using _ST = __detail::__make_unsigned_like_t<decltype(_S_difference_type())>;
8159 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8160 auto __size = static_cast<_ST>(1);
8161#ifdef _GLIBCXX_ASSERTIONS
8162 if constexpr (integral<_ST>)
8163 {
8164 bool __overflow
8165 = (__builtin_mul_overflow(__size,
8166 static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))),
8167 &__size)
8168 || ...);
8169 __glibcxx_assert(!__overflow);
8170 }
8171 else
8172#endif
8173 __size = (static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))) * ...);
8174 return __size;
8175 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8176 }
8177
8178 constexpr auto
8179 size() const requires __detail::__cartesian_product_is_sized<const _First, const _Vs...>
8180 {
8181 using _ST = __detail::__make_unsigned_like_t<decltype(_S_difference_type())>;
8182 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8183 auto __size = static_cast<_ST>(1);
8184#ifdef _GLIBCXX_ASSERTIONS
8185 if constexpr (integral<_ST>)
8186 {
8187 bool __overflow
8188 = (__builtin_mul_overflow(__size,
8189 static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))),
8190 &__size)
8191 || ...);
8192 __glibcxx_assert(!__overflow);
8193 }
8194 else
8195#endif
8196 __size = (static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))) * ...);
8197 return __size;
8198 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8199 }
8200 };
8201
8202 template<typename... _Vs>
8203 cartesian_product_view(_Vs&&...) -> cartesian_product_view<views::all_t<_Vs>...>;
8204
8205 template<input_range _First, forward_range... _Vs>
8206 requires (view<_First> && ... && view<_Vs>)
8207 template<bool _Const>
8208 class cartesian_product_view<_First, _Vs...>::_Iterator
8209 {
8210 using _Parent = __maybe_const_t<_Const, cartesian_product_view>;
8211 _Parent* _M_parent = nullptr;
8212 __detail::__tuple_or_pair_t<iterator_t<__maybe_const_t<_Const, _First>>,
8213 iterator_t<__maybe_const_t<_Const, _Vs>>...> _M_current;
8214
8215 constexpr
8216 _Iterator(_Parent& __parent, decltype(_M_current) __current)
8217 : _M_parent(std::__addressof(__parent)),
8218 _M_current(std::move(__current))
8219 { }
8220
8221 static auto
8222 _S_iter_concept()
8223 {
8224 if constexpr (__detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>)
8225 return random_access_iterator_tag{};
8226 else if constexpr (__detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>)
8227 return bidirectional_iterator_tag{};
8228 else if constexpr (forward_range<__maybe_const_t<_Const, _First>>)
8229 return forward_iterator_tag{};
8230 else
8231 return input_iterator_tag{};
8232 }
8233
8234 friend cartesian_product_view;
8235
8236 public:
8237 using iterator_category = input_iterator_tag;
8238 using iterator_concept = decltype(_S_iter_concept());
8239 using value_type
8240 = __detail::__tuple_or_pair_t<range_value_t<__maybe_const_t<_Const, _First>>,
8241 range_value_t<__maybe_const_t<_Const, _Vs>>...>;
8242 using reference
8243 = __detail::__tuple_or_pair_t<range_reference_t<__maybe_const_t<_Const, _First>>,
8244 range_reference_t<__maybe_const_t<_Const, _Vs>>...>;
8245 using difference_type = decltype(cartesian_product_view::_S_difference_type());
8246
8247 _Iterator() = default;
8248
8249 constexpr
8250 _Iterator(_Iterator<!_Const> __i)
8251 requires _Const
8252 && (convertible_to<iterator_t<_First>, iterator_t<const _First>>
8253 && ... && convertible_to<iterator_t<_Vs>, iterator_t<const _Vs>>)
8254 : _M_parent(std::__addressof(__i._M_parent)),
8255 _M_current(std::move(__i._M_current))
8256 { }
8257
8258 constexpr auto
8259 operator*() const
8260 {
8261 auto __f = [](auto& __i) -> decltype(auto) {
8262 return *__i;
8263 };
8264 return __detail::__tuple_transform(__f, _M_current);
8265 }
8266
8267 constexpr _Iterator&
8268 operator++()
8269 {
8270 _M_next();
8271 return *this;
8272 }
8273
8274 constexpr void
8275 operator++(int)
8276 { ++*this; }
8277
8278 constexpr _Iterator
8279 operator++(int) requires forward_range<__maybe_const_t<_Const, _First>>
8280 {
8281 auto __tmp = *this;
8282 ++*this;
8283 return __tmp;
8284 }
8285
8286 constexpr _Iterator&
8287 operator--()
8288 requires __detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>
8289 {
8290 _M_prev();
8291 return *this;
8292 }
8293
8294 constexpr _Iterator
8295 operator--(int)
8296 requires __detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>
8297 {
8298 auto __tmp = *this;
8299 --*this;
8300 return __tmp;
8301 }
8302
8303 constexpr _Iterator&
8304 operator+=(difference_type __x)
8305 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8306 {
8307 _M_advance(__x);
8308 return *this;
8309 }
8310
8311 constexpr _Iterator&
8312 operator-=(difference_type __x)
8313 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8314 { return *this += -__x; }
8315
8316 constexpr reference
8317 operator[](difference_type __n) const
8318 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8319 { return *((*this) + __n); }
8320
8321 friend constexpr bool
8322 operator==(const _Iterator& __x, const _Iterator& __y)
8323 requires equality_comparable<iterator_t<__maybe_const_t<_Const, _First>>>
8324 { return __x._M_current == __y._M_current; }
8325
8326 friend constexpr bool
8327 operator==(const _Iterator& __x, default_sentinel_t)
8328 {
8329 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8330 return ((std::get<_Is>(__x._M_current)
8331 == ranges::end(std::get<_Is>(__x._M_parent->_M_bases)))
8332 || ...);
8333 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8334 }
8335
8336 friend constexpr auto
8337 operator<=>(const _Iterator& __x, const _Iterator& __y)
8338 requires __detail::__all_random_access<_Const, _First, _Vs...>
8339 { return __x._M_current <=> __y._M_current; }
8340
8341 friend constexpr _Iterator
8342 operator+(_Iterator __x, difference_type __y)
8343 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8344 { return __x += __y; }
8345
8346 friend constexpr _Iterator
8347 operator+(difference_type __x, _Iterator __y)
8348 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8349 { return __y += __x; }
8350
8351 friend constexpr _Iterator
8352 operator-(_Iterator __x, difference_type __y)
8353 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8354 { return __x -= __y; }
8355
8356 friend constexpr difference_type
8357 operator-(const _Iterator& __x, const _Iterator& __y)
8358 requires __detail::__cartesian_is_sized_sentinel<_Const, iterator_t, _First, _Vs...>
8359 { return __x._M_distance_from(__y._M_current); }
8360
8361 friend constexpr difference_type
8362 operator-(const _Iterator& __i, default_sentinel_t)
8363 requires __detail::__cartesian_is_sized_sentinel<_Const, sentinel_t, _First, _Vs...>
8364 {
8365 tuple __end_tuple = [&]<size_t... _Is>(index_sequence<_Is...>) {
8366 return tuple{ranges::end(std::get<0>(__i._M_parent->_M_bases)),
8367 ranges::begin(std::get<1 + _Is>(__i._M_parent->_M_bases))...};
8368 }(make_index_sequence<sizeof...(_Vs)>{});
8369 return __i._M_distance_from(__end_tuple);
8370 }
8371
8372 friend constexpr difference_type
8373 operator-(default_sentinel_t, const _Iterator& __i)
8374 requires __detail::__cartesian_is_sized_sentinel<_Const, sentinel_t, _First, _Vs...>
8375 { return -(__i - default_sentinel); }
8376
8377 friend constexpr auto
8378 iter_move(const _Iterator& __i)
8379 { return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
8380
8381 friend constexpr void
8382 iter_swap(const _Iterator& __l, const _Iterator& __r)
8383 requires (indirectly_swappable<iterator_t<__maybe_const_t<_Const, _First>>>
8384 && ...
8385 && indirectly_swappable<iterator_t<__maybe_const_t<_Const, _Vs>>>)
8386 {
8387 [&]<size_t... _Is>(index_sequence<_Is...>) {
8388 (ranges::iter_swap(std::get<_Is>(__l._M_current), std::get<_Is>(__r._M_current)), ...);
8389 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8390 }
8391
8392 private:
8393 template<size_t _Nm = sizeof...(_Vs)>
8394 constexpr void
8395 _M_next()
8396 {
8397 auto& __it = std::get<_Nm>(_M_current);
8398 ++__it;
8399 if constexpr (_Nm > 0)
8400 if (__it == ranges::end(std::get<_Nm>(_M_parent->_M_bases)))
8401 {
8402 __it = ranges::begin(std::get<_Nm>(_M_parent->_M_bases));
8403 _M_next<_Nm - 1>();
8404 }
8405 }
8406
8407 template<size_t _Nm = sizeof...(_Vs)>
8408 constexpr void
8409 _M_prev()
8410 {
8411 auto& __it = std::get<_Nm>(_M_current);
8412 if constexpr (_Nm > 0)
8413 if (__it == ranges::begin(std::get<_Nm>(_M_parent->_M_bases)))
8414 {
8415 __it = __detail::__cartesian_common_arg_end(std::get<_Nm>(_M_parent->_M_bases));
8416 _M_prev<_Nm - 1>();
8417 }
8418 --__it;
8419 }
8420
8421 template<size_t _Nm = sizeof...(_Vs)>
8422 constexpr void
8423 _M_advance(difference_type __x)
8424 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8425 {
8426 if (__x == 1)
8427 _M_next<_Nm>();
8428 else if (__x == -1)
8429 _M_prev<_Nm>();
8430 else if (__x != 0)
8431 {
8432 // Constant time iterator advancement.
8433 auto& __r = std::get<_Nm>(_M_parent->_M_bases);
8434 auto& __it = std::get<_Nm>(_M_current);
8435 if constexpr (_Nm == 0)
8436 {
8437#ifdef _GLIBCXX_ASSERTIONS
8438 if constexpr (sized_range<__maybe_const_t<_Const, _First>>)
8439 {
8440 auto __size = ranges::ssize(__r);
8441 auto __begin = ranges::begin(__r);
8442 auto __offset = __it - __begin;
8443 __glibcxx_assert(__offset + __x >= 0 && __offset + __x <= __size);
8444 }
8445#endif
8446 __it += __x;
8447 }
8448 else
8449 {
8450 auto __size = ranges::ssize(__r);
8451 auto __begin = ranges::begin(__r);
8452 auto __offset = __it - __begin;
8453 __offset += __x;
8454 __x = __offset / __size;
8455 __offset %= __size;
8456 if (__offset < 0)
8457 {
8458 __offset = __size + __offset;
8459 --__x;
8460 }
8461 __it = __begin + __offset;
8462 _M_advance<_Nm - 1>(__x);
8463 }
8464 }
8465 }
8466
8467 template<typename _Tuple>
8468 constexpr difference_type
8469 _M_distance_from(const _Tuple& __t) const
8470 {
8471 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8472 auto __sum = static_cast<difference_type>(0);
8473#ifdef _GLIBCXX_ASSERTIONS
8474 if constexpr (integral<difference_type>)
8475 {
8476 bool __overflow
8477 = (__builtin_add_overflow(__sum, _M_scaled_distance<_Is>(__t), &__sum)
8478 || ...);
8479 __glibcxx_assert(!__overflow);
8480 }
8481 else
8482#endif
8483 __sum = (_M_scaled_distance<_Is>(__t) + ...);
8484 return __sum;
8485 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8486 }
8487
8488 template<size_t _Nm, typename _Tuple>
8489 constexpr difference_type
8490 _M_scaled_distance(const _Tuple& __t) const
8491 {
8492 auto __dist = static_cast<difference_type>(std::get<_Nm>(_M_current)
8493 - std::get<_Nm>(__t));
8494#ifdef _GLIBCXX_ASSERTIONS
8495 if constexpr (integral<difference_type>)
8496 {
8497 bool __overflow = __builtin_mul_overflow(__dist, _M_scaled_size<_Nm+1>(), &__dist);
8498 __glibcxx_assert(!__overflow);
8499 }
8500 else
8501#endif
8502 __dist *= _M_scaled_size<_Nm+1>();
8503 return __dist;
8504 }
8505
8506 template<size_t _Nm>
8507 constexpr difference_type
8508 _M_scaled_size() const
8509 {
8510 if constexpr (_Nm <= sizeof...(_Vs))
8511 {
8512 auto __size = static_cast<difference_type>(ranges::size
8513 (std::get<_Nm>(_M_parent->_M_bases)));
8514#ifdef _GLIBCXX_ASSERTIONS
8515 if constexpr (integral<difference_type>)
8516 {
8517 bool __overflow = __builtin_mul_overflow(__size, _M_scaled_size<_Nm+1>(), &__size);
8518 __glibcxx_assert(!__overflow);
8519 }
8520 else
8521#endif
8522 __size *= _M_scaled_size<_Nm+1>();
8523 return __size;
8524 }
8525 else
8526 return static_cast<difference_type>(1);
8527 }
8528 };
8529
8530 namespace views
8531 {
8532 namespace __detail
8533 {
8534 template<typename... _Ts>
8535 concept __can_cartesian_product_view
8536 = requires { cartesian_product_view<all_t<_Ts>...>(std::declval<_Ts>()...); };
8537 }
8538
8539 struct _CartesianProduct
8540 {
8541 template<typename... _Ts>
8542 requires (sizeof...(_Ts) == 0 || __detail::__can_cartesian_product_view<_Ts...>)
8543 constexpr auto
8544 operator() [[nodiscard]] (_Ts&&... __ts) const
8545 {
8546 if constexpr (sizeof...(_Ts) == 0)
8547 return views::empty<tuple<>>;
8548 else
8549 return cartesian_product_view<all_t<_Ts>...>(std::forward<_Ts>(__ts)...);
8550 }
8551 };
8552
8553 inline constexpr _CartesianProduct cartesian_product;
8554 }
8555
8556#define __cpp_lib_ranges_as_rvalue 202207L
8557
8558 template<input_range _Vp>
8559 requires view<_Vp>
8560 class as_rvalue_view : public view_interface<as_rvalue_view<_Vp>>
8561 {
8562 _Vp _M_base = _Vp();
8563
8564 public:
8565 as_rvalue_view() requires default_initializable<_Vp> = default;
8566
8567 constexpr explicit
8568 as_rvalue_view(_Vp __base)
8569 : _M_base(std::move(__base))
8570 { }
8571
8572 constexpr _Vp
8573 base() const& requires copy_constructible<_Vp>
8574 { return _M_base; }
8575
8576 constexpr _Vp
8577 base() &&
8578 { return std::move(_M_base); }
8579
8580 constexpr auto
8581 begin() requires (!__detail::__simple_view<_Vp>)
8582 { return move_iterator(ranges::begin(_M_base)); }
8583
8584 constexpr auto
8585 begin() const requires range<const _Vp>
8586 { return move_iterator(ranges::begin(_M_base)); }
8587
8588 constexpr auto
8589 end() requires (!__detail::__simple_view<_Vp>)
8590 {
8591 if constexpr (common_range<_Vp>)
8592 return move_iterator(ranges::end(_M_base));
8593 else
8594 return move_sentinel(ranges::end(_M_base));
8595 }
8596
8597 constexpr auto
8598 end() const requires range<const _Vp>
8599 {
8600 if constexpr (common_range<const _Vp>)
8601 return move_iterator(ranges::end(_M_base));
8602 else
8603 return move_sentinel(ranges::end(_M_base));
8604 }
8605
8606 constexpr auto
8607 size() requires sized_range<_Vp>
8608 { return ranges::size(_M_base); }
8609
8610 constexpr auto
8611 size() const requires sized_range<const _Vp>
8612 { return ranges::size(_M_base); }
8613 };
8614
8615 template<typename _Range>
8616 as_rvalue_view(_Range&&) -> as_rvalue_view<views::all_t<_Range>>;
8617
8618 template<typename _Tp>
8619 inline constexpr bool enable_borrowed_range<as_rvalue_view<_Tp>>
8620 = enable_borrowed_range<_Tp>;
8621
8622 namespace views
8623 {
8624 namespace __detail
8625 {
8626 template<typename _Tp>
8627 concept __can_as_rvalue_view = requires { as_rvalue_view(std::declval<_Tp>()); };
8628 }
8629
8630 struct _AsRvalue : __adaptor::_RangeAdaptorClosure
8631 {
8632 template<viewable_range _Range>
8633 requires __detail::__can_as_rvalue_view<_Range>
8634 constexpr auto
8635 operator() [[nodiscard]] (_Range&& __r) const
8636 {
8637 if constexpr (same_as<range_rvalue_reference_t<_Range>,
8638 range_reference_t<_Range>>)
8639 return views::all(std::forward<_Range>(__r));
8640 else
8641 return as_rvalue_view(std::forward<_Range>(__r));
8642 }
8643 };
8644
8645 inline constexpr _AsRvalue as_rvalue;
8646 }
8647
8648#define __cpp_lib_ranges_enumerate 202302L
8649
8650 namespace __detail
8651 {
8652 template<typename _Range>
8653 concept __range_with_movable_reference = input_range<_Range>
8654 && move_constructible<range_reference_t<_Range>>
8655 && move_constructible<range_rvalue_reference_t<_Range>>;
8656 }
8657
8658 template<view _Vp>
8659 requires __detail::__range_with_movable_reference<_Vp>
8660 class enumerate_view : public view_interface<enumerate_view<_Vp>>
8661 {
8662 _Vp _M_base = _Vp();
8663
8664 template<bool _Const> class _Iterator;
8665 template<bool _Const> class _Sentinel;
8666
8667 public:
8668 enumerate_view() requires default_initializable<_Vp> = default;
8669
8670 constexpr explicit
8671 enumerate_view(_Vp __base)
8672 : _M_base(std::move(__base))
8673 { }
8674
8675 constexpr auto
8676 begin() requires (!__detail::__simple_view<_Vp>)
8677 { return _Iterator<false>(ranges::begin(_M_base), 0); }
8678
8679 constexpr auto
8680 begin() const requires __detail::__range_with_movable_reference<const _Vp>
8681 { return _Iterator<true>(ranges::begin(_M_base), 0); }
8682
8683 constexpr auto
8684 end() requires (!__detail::__simple_view<_Vp>)
8685 {
8686 if constexpr (common_range<_Vp> && sized_range<_Vp>)
8687 return _Iterator<false>(ranges::end(_M_base), ranges::distance(_M_base));
8688 else
8689 return _Sentinel<false>(ranges::end(_M_base));
8690 }
8691
8692 constexpr auto
8693 end() const requires __detail::__range_with_movable_reference<const _Vp>
8694 {
8695 if constexpr (common_range<const _Vp> && sized_range<const _Vp>)
8696 return _Iterator<true>(ranges::end(_M_base), ranges::distance(_M_base));
8697 else
8698 return _Sentinel<true>(ranges::end(_M_base));
8699 }
8700
8701 constexpr auto
8702 size() requires sized_range<_Vp>
8703 { return ranges::size(_M_base); }
8704
8705 constexpr auto
8706 size() const requires sized_range<const _Vp>
8707 { return ranges::size(_M_base); }
8708
8709 constexpr _Vp
8710 base() const & requires copy_constructible<_Vp>
8711 { return _M_base; }
8712
8713 constexpr _Vp
8714 base() &&
8715 { return std::move(_M_base); }
8716 };
8717
8718 template<typename _Range>
8719 enumerate_view(_Range&&) -> enumerate_view<views::all_t<_Range>>;
8720
8721 template<typename _Tp>
8722 inline constexpr bool enable_borrowed_range<enumerate_view<_Tp>>
8723 = enable_borrowed_range<_Tp>;
8724
8725 template<view _Vp>
8726 requires __detail::__range_with_movable_reference<_Vp>
8727 template<bool _Const>
8728 class enumerate_view<_Vp>::_Iterator
8729 {
8730 using _Base = __maybe_const_t<_Const, _Vp>;
8731
8732 static auto
8733 _S_iter_concept()
8734 {
8735 if constexpr (random_access_range<_Base>)
8736 return random_access_iterator_tag{};
8737 else if constexpr (bidirectional_range<_Base>)
8738 return bidirectional_iterator_tag{};
8739 else if constexpr (forward_range<_Base>)
8740 return forward_iterator_tag{};
8741 else
8742 return input_iterator_tag{};
8743 }
8744
8745 friend enumerate_view;
8746
8747 public:
8748 using iterator_category = input_iterator_tag;
8749 using iterator_concept = decltype(_S_iter_concept());
8750 using difference_type = range_difference_t<_Base>;
8751 using value_type = tuple<difference_type, range_value_t<_Base>>;
8752
8753 private:
8754 using __reference_type = tuple<difference_type, range_reference_t<_Base>>;
8755
8756 iterator_t<_Base> _M_current = iterator_t<_Base>();
8757 difference_type _M_pos = 0;
8758
8759 constexpr explicit
8760 _Iterator(iterator_t<_Base> __current, difference_type __pos)
8761 : _M_current(std::move(__current)), _M_pos(__pos)
8762 { }
8763
8764 public:
8765 _Iterator() requires default_initializable<iterator_t<_Base>> = default;
8766
8767 constexpr
8768 _Iterator(_Iterator<!_Const> __i)
8769 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
8770 : _M_current(std::move(__i._M_current)), _M_pos(__i._M_pos)
8771 { }
8772
8773 constexpr const iterator_t<_Base> &
8774 base() const & noexcept
8775 { return _M_current; }
8776
8777 constexpr iterator_t<_Base>
8778 base() &&
8779 { return std::move(_M_current); }
8780
8781 constexpr difference_type
8782 index() const noexcept
8783 { return _M_pos; }
8784
8785 constexpr auto
8786 operator*() const
8787 { return __reference_type(_M_pos, *_M_current); }
8788
8789 constexpr _Iterator&
8790 operator++()
8791 {
8792 ++_M_current;
8793 ++_M_pos;
8794 return *this;
8795 }
8796
8797 constexpr void
8798 operator++(int)
8799 { ++*this; }
8800
8801 constexpr _Iterator
8802 operator++(int) requires forward_range<_Base>
8803 {
8804 auto __tmp = *this;
8805 ++*this;
8806 return __tmp;
8807 }
8808
8809 constexpr _Iterator&
8810 operator--() requires bidirectional_range<_Base>
8811 {
8812 --_M_current;
8813 --_M_pos;
8814 return *this;
8815 }
8816
8817 constexpr _Iterator
8818 operator--(int) requires bidirectional_range<_Base>
8819 {
8820 auto __tmp = *this;
8821 --*this;
8822 return __tmp;
8823 }
8824
8825 constexpr _Iterator&
8826 operator+=(difference_type __n) requires random_access_range<_Base>
8827 {
8828 _M_current += __n;
8829 _M_pos += __n;
8830 return *this;
8831 }
8832
8833 constexpr _Iterator&
8834 operator-=(difference_type __n) requires random_access_range<_Base>
8835 {
8836 _M_current -= __n;
8837 _M_pos -= __n;
8838 return *this;
8839 }
8840
8841 constexpr auto
8842 operator[](difference_type __n) const requires random_access_range<_Base>
8843 { return __reference_type(_M_pos + __n, _M_current[__n]); }
8844
8845 friend constexpr bool
8846 operator==(const _Iterator& __x, const _Iterator& __y) noexcept
8847 { return __x._M_pos == __y._M_pos; }
8848
8849 friend constexpr strong_ordering
8850 operator<=>(const _Iterator& __x, const _Iterator& __y) noexcept
8851 { return __x._M_pos <=> __y._M_pos; }
8852
8853 friend constexpr _Iterator
8854 operator+(const _Iterator& __x, difference_type __y)
8855 requires random_access_range<_Base>
8856 { return (auto(__x) += __y); }
8857
8858 friend constexpr _Iterator
8859 operator+(difference_type __x, const _Iterator& __y)
8860 requires random_access_range<_Base>
8861 { return auto(__y) += __x; }
8862
8863 friend constexpr _Iterator
8864 operator-(const _Iterator& __x, difference_type __y)
8865 requires random_access_range<_Base>
8866 { return auto(__x) -= __y; }
8867
8868 friend constexpr difference_type
8869 operator-(const _Iterator& __x, const _Iterator& __y)
8870 { return __x._M_pos - __y._M_pos; }
8871
8872 friend constexpr auto
8873 iter_move(const _Iterator& __i)
8874 noexcept(noexcept(ranges::iter_move(__i._M_current))
8875 && is_nothrow_move_constructible_v<range_rvalue_reference_t<_Base>>)
8876 {
8877 return tuple<difference_type, range_rvalue_reference_t<_Base>>
8878 (__i._M_pos, ranges::iter_move(__i._M_current));
8879 }
8880 };
8881
8882 template<view _Vp>
8883 requires __detail::__range_with_movable_reference<_Vp>
8884 template<bool _Const>
8885 class enumerate_view<_Vp>::_Sentinel
8886 {
8887 using _Base = __maybe_const_t<_Const, _Vp>;
8888
8889 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
8890
8891 constexpr explicit
8892 _Sentinel(sentinel_t<_Base> __end)
8893 : _M_end(std::move(__end))
8894 { }
8895
8896 friend enumerate_view;
8897
8898 public:
8899 _Sentinel() = default;
8900
8901 constexpr
8902 _Sentinel(_Sentinel<!_Const> __other)
8903 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
8904 : _M_end(std::move(__other._M_end))
8905 { }
8906
8907 constexpr sentinel_t<_Base>
8908 base() const
8909 { return _M_end; }
8910
8911 template<bool _OtherConst>
8912 requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
8913 friend constexpr bool
8914 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
8915 { return __x._M_current == __y._M_end; }
8916
8917 template<bool _OtherConst>
8918 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
8919 friend constexpr range_difference_t<__maybe_const_t<_OtherConst, _Vp>>
8920 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
8921 { return __x._M_current - __y._M_end; }
8922
8923 template<bool _OtherConst>
8924 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
8925 friend constexpr range_difference_t<__maybe_const_t<_OtherConst, _Vp>>
8926 operator-(const _Sentinel& __x, const _Iterator<_OtherConst>& __y)
8927 { return __x._M_end - __y._M_current; }
8928 };
8929
8930 namespace views
8931 {
8932 namespace __detail
8933 {
8934 template<typename _Tp>
8935 concept __can_enumerate_view
8936 = requires { enumerate_view<all_t<_Tp>>(std::declval<_Tp>()); };
8937 }
8938
8939 struct _Enumerate : __adaptor::_RangeAdaptorClosure
8940 {
8941 template<viewable_range _Range>
8942 requires __detail::__can_enumerate_view<_Range>
8943 constexpr auto
8944 operator() [[nodiscard]] (_Range&& __r) const
8945 { return enumerate_view<all_t<_Range>>(std::forward<_Range>(__r)); }
8946 };
8947
8948 inline constexpr _Enumerate enumerate;
8949 }
8950
8951#define __cpp_lib_ranges_as_const 202207L
8952
8953 template<view _Vp>
8954 requires input_range<_Vp>
8955 class as_const_view : public view_interface<as_const_view<_Vp>>
8956 {
8957 _Vp _M_base = _Vp();
8958
8959 public:
8960 as_const_view() requires default_initializable<_Vp> = default;
8961
8962 constexpr explicit
8963 as_const_view(_Vp __base)
8964 noexcept(is_nothrow_move_constructible_v<_Vp>)
8965 : _M_base(std::move(__base))
8966 { }
8967
8968 constexpr _Vp
8969 base() const &
8970 noexcept(is_nothrow_copy_constructible_v<_Vp>)
8971 requires copy_constructible<_Vp>
8972 { return _M_base; }
8973
8974 constexpr _Vp
8975 base() &&
8976 noexcept(is_nothrow_move_constructible_v<_Vp>)
8977 { return std::move(_M_base); }
8978
8979 constexpr auto
8980 begin() requires (!__detail::__simple_view<_Vp>)
8981 { return ranges::cbegin(_M_base); }
8982
8983 constexpr auto
8984 begin() const requires range<const _Vp>
8985 { return ranges::cbegin(_M_base); }
8986
8987 constexpr auto
8988 end() requires (!__detail::__simple_view<_Vp>)
8989 { return ranges::cend(_M_base); }
8990
8991 constexpr auto
8992 end() const requires range<const _Vp>
8993 { return ranges::cend(_M_base); }
8994
8995 constexpr auto
8996 size() requires sized_range<_Vp>
8997 { return ranges::size(_M_base); }
8998
8999 constexpr auto
9000 size() const requires sized_range<const _Vp>
9001 { return ranges::size(_M_base); }
9002 };
9003
9004 template<typename _Range>
9005 as_const_view(_Range&&) -> as_const_view<views::all_t<_Range>>;
9006
9007 template<typename _Tp>
9008 inline constexpr bool enable_borrowed_range<as_const_view<_Tp>>
9009 = enable_borrowed_range<_Tp>;
9010
9011 namespace views
9012 {
9013 namespace __detail
9014 {
9015 template<typename _Tp>
9016 inline constexpr bool __is_ref_view = false;
9017
9018 template<typename _Range>
9019 inline constexpr bool __is_ref_view<ref_view<_Range>> = true;
9020
9021 template<typename _Range>
9022 concept __can_as_const_view = requires { as_const_view(std::declval<_Range>()); };
9023 }
9024
9025 struct _AsConst : __adaptor::_RangeAdaptorClosure
9026 {
9027 template<viewable_range _Range>
9028 constexpr auto
9029 operator()(_Range&& __r) const
9030 noexcept(noexcept(as_const_view(std::declval<_Range>())))
9031 requires __detail::__can_as_const_view<_Range>
9032 {
9033 using _Tp = remove_cvref_t<_Range>;
9034 using element_type = remove_reference_t<range_reference_t<_Range>>;
9035 if constexpr (constant_range<views::all_t<_Range>>)
9036 return views::all(std::forward<_Range>(__r));
9037 else if constexpr (__detail::__is_empty_view<_Tp>)
9038 return views::empty<const element_type>;
9039 else if constexpr (std::__detail::__is_span<_Tp>)
9040 return span<const element_type, _Tp::extent>(std::forward<_Range>(__r));
9041 else if constexpr (__detail::__is_ref_view<_Tp>
9042 && constant_range<const element_type>)
9043 return ref_view(static_cast<const element_type&>
9044 (std::forward<_Range>(__r).base()));
9045 else if constexpr (is_lvalue_reference_v<_Range>
9046 && constant_range<const _Tp>
9047 && !view<_Tp>)
9048 return ref_view(static_cast<const _Tp&>(__r));
9049 else
9050 return as_const_view(std::forward<_Range>(__r));
9051 }
9052 };
9053
9054 inline constexpr _AsConst as_const;
9055 }
9056#endif // C++23
9057} // namespace ranges
9058
9059 namespace views = ranges::views;
9060
9061_GLIBCXX_END_NAMESPACE_VERSION
9062} // namespace
9063#endif // library concepts
9064#endif // C++2a
9065#endif /* _GLIBCXX_RANGES */