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 __detail::__tuple_or_pair_t<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>...> _M_current;
4539
4540 constexpr explicit
4541 _Iterator(decltype(_M_current) __current)
4542 : _M_current(std::move(__current))
4543 { }
4544
4545 static auto
4546 _S_iter_concept()
4547 {
4548 if constexpr (__detail::__all_random_access<_Const, _Vs...>)
4549 return random_access_iterator_tag{};
4550 else if constexpr (__detail::__all_bidirectional<_Const, _Vs...>)
4551 return bidirectional_iterator_tag{};
4552 else if constexpr (__detail::__all_forward<_Const, _Vs...>)
4553 return forward_iterator_tag{};
4554 else
4555 return input_iterator_tag{};
4556 }
4557
4558 template<copy_constructible _Fp, input_range... _Ws>
4559 requires (view<_Ws> && ...) && (sizeof...(_Ws) > 0) && is_object_v<_Fp>
4560 && regular_invocable<_Fp&, range_reference_t<_Ws>...>
4561 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Ws>...>>
4562 friend class zip_transform_view;
4563
4564 public:
4565 // iterator_category defined in __zip_view_iter_cat
4566 using iterator_concept = decltype(_S_iter_concept());
4567 using value_type
4568 = __detail::__tuple_or_pair_t<range_value_t<__detail::__maybe_const_t<_Const, _Vs>>...>;
4569 using difference_type
4570 = common_type_t<range_difference_t<__detail::__maybe_const_t<_Const, _Vs>>...>;
4571
4572 _Iterator() = default;
4573
4574 constexpr
4575 _Iterator(_Iterator<!_Const> __i)
4576 requires _Const
4577 && (convertible_to<iterator_t<_Vs>,
4578 iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4579 : _M_current(std::move(__i._M_current))
4580 { }
4581
4582 constexpr auto
4583 operator*() const
4584 {
4585 auto __f = [](auto& __i) -> decltype(auto) {
4586 return *__i;
4587 };
4588 return __detail::__tuple_transform(__f, _M_current);
4589 }
4590
4591 constexpr _Iterator&
4592 operator++()
4593 {
4594 __detail::__tuple_for_each([](auto& __i) { ++__i; }, _M_current);
4595 return *this;
4596 }
4597
4598 constexpr void
4599 operator++(int)
4600 { ++*this; }
4601
4602 constexpr _Iterator
4603 operator++(int)
4604 requires __detail::__all_forward<_Const, _Vs...>
4605 {
4606 auto __tmp = *this;
4607 ++*this;
4608 return __tmp;
4609 }
4610
4611 constexpr _Iterator&
4612 operator--()
4613 requires __detail::__all_bidirectional<_Const, _Vs...>
4614 {
4615 __detail::__tuple_for_each([](auto& __i) { --__i; }, _M_current);
4616 return *this;
4617 }
4618
4619 constexpr _Iterator
4620 operator--(int)
4621 requires __detail::__all_bidirectional<_Const, _Vs...>
4622 {
4623 auto __tmp = *this;
4624 --*this;
4625 return __tmp;
4626 }
4627
4628 constexpr _Iterator&
4629 operator+=(difference_type __x)
4630 requires __detail::__all_random_access<_Const, _Vs...>
4631 {
4632 auto __f = [&]<typename _It>(_It& __i) {
4633 __i += iter_difference_t<_It>(__x);
4634 };
4635 __detail::__tuple_for_each(__f, _M_current);
4636 return *this;
4637 }
4638
4639 constexpr _Iterator&
4640 operator-=(difference_type __x)
4641 requires __detail::__all_random_access<_Const, _Vs...>
4642 {
4643 auto __f = [&]<typename _It>(_It& __i) {
4644 __i -= iter_difference_t<_It>(__x);
4645 };
4646 __detail::__tuple_for_each(__f, _M_current);
4647 return *this;
4648 }
4649
4650 constexpr auto
4651 operator[](difference_type __n) const
4652 requires __detail::__all_random_access<_Const, _Vs...>
4653 {
4654 auto __f = [&]<typename _It>(_It& __i) -> decltype(auto) {
4655 return __i[iter_difference_t<_It>(__n)];
4656 };
4657 return __detail::__tuple_transform(__f, _M_current);
4658 }
4659
4660 friend constexpr bool
4661 operator==(const _Iterator& __x, const _Iterator& __y)
4662 requires (equality_comparable<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4663 {
4664 if constexpr (__detail::__all_bidirectional<_Const, _Vs...>)
4665 return __x._M_current == __y._M_current;
4666 else
4667 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4668 return ((std::get<_Is>(__x._M_current) == std::get<_Is>(__y._M_current)) || ...);
4669 }(make_index_sequence<sizeof...(_Vs)>{});
4670 }
4671
4672 friend constexpr auto
4673 operator<=>(const _Iterator& __x, const _Iterator& __y)
4674 requires __detail::__all_random_access<_Const, _Vs...>
4675 { return __x._M_current <=> __y._M_current; }
4676
4677 friend constexpr _Iterator
4678 operator+(const _Iterator& __i, difference_type __n)
4679 requires __detail::__all_random_access<_Const, _Vs...>
4680 {
4681 auto __r = __i;
4682 __r += __n;
4683 return __r;
4684 }
4685
4686 friend constexpr _Iterator
4687 operator+(difference_type __n, const _Iterator& __i)
4688 requires __detail::__all_random_access<_Const, _Vs...>
4689 {
4690 auto __r = __i;
4691 __r += __n;
4692 return __r;
4693 }
4694
4695 friend constexpr _Iterator
4696 operator-(const _Iterator& __i, difference_type __n)
4697 requires __detail::__all_random_access<_Const, _Vs...>
4698 {
4699 auto __r = __i;
4700 __r -= __n;
4701 return __r;
4702 }
4703
4704 friend constexpr difference_type
4705 operator-(const _Iterator& __x, const _Iterator& __y)
4706 requires (sized_sentinel_for<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>,
4707 iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4708 {
4709 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4710 return ranges::min({difference_type(std::get<_Is>(__x._M_current)
4711 - std::get<_Is>(__y._M_current))...},
4712 ranges::less{},
4713 [](difference_type __i) {
4714 return __detail::__to_unsigned_like(__i < 0 ? -__i : __i);
4715 });
4716 }(make_index_sequence<sizeof...(_Vs)>{});
4717 }
4718
4719 friend constexpr auto
4720 iter_move(const _Iterator& __i)
4721 { return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
4722
4723 friend constexpr void
4724 iter_swap(const _Iterator& __l, const _Iterator& __r)
4725 requires (indirectly_swappable<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4726 {
4727 [&]<size_t... _Is>(index_sequence<_Is...>) {
4728 (ranges::iter_swap(std::get<_Is>(__l._M_current), std::get<_Is>(__r._M_current)), ...);
4729 }(make_index_sequence<sizeof...(_Vs)>{});
4730 }
4731
4732 friend class zip_view;
4733 };
4734
4735 template<input_range... _Vs>
4736 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0)
4737 template<bool _Const>
4738 class zip_view<_Vs...>::_Sentinel
4739 {
4740 __detail::__tuple_or_pair_t<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>...> _M_end;
4741
4742 constexpr explicit
4743 _Sentinel(decltype(_M_end) __end)
4744 : _M_end(__end)
4745 { }
4746
4747 friend class zip_view;
4748
4749 public:
4750 _Sentinel() = default;
4751
4752 constexpr
4753 _Sentinel(_Sentinel<!_Const> __i)
4754 requires _Const
4755 && (convertible_to<sentinel_t<_Vs>,
4756 sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4757 : _M_end(std::move(__i._M_end))
4758 { }
4759
4760 template<bool _OtherConst>
4761 requires (sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
4762 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
4763 friend constexpr bool
4764 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
4765 {
4766 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4767 return ((std::get<_Is>(__x._M_current) == std::get<_Is>(__y._M_end)) || ...);
4768 }(make_index_sequence<sizeof...(_Vs)>{});
4769 }
4770
4771 template<bool _OtherConst>
4772 requires (sized_sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
4773 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
4774 friend constexpr auto
4775 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
4776 {
4777 using _Ret
4778 = common_type_t<range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vs>>...>;
4779 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4780 return ranges::min({_Ret(std::get<_Is>(__x._M_current) - std::get<_Is>(__y._M_end))...},
4781 ranges::less{},
4782 [](_Ret __i) {
4783 return __detail::__to_unsigned_like(__i < 0 ? -__i : __i);
4784 });
4785 }(make_index_sequence<sizeof...(_Vs)>{});
4786 }
4787
4788 template<bool _OtherConst>
4789 requires (sized_sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
4790 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
4791 friend constexpr auto
4792 operator-(const _Sentinel& __y, const _Iterator<_OtherConst>& __x)
4793 { return -(__x - __y); }
4794 };
4795
4796 namespace views
4797 {
4798 namespace __detail
4799 {
4800 template<typename... _Ts>
4801 concept __can_zip_view
4802 = requires { zip_view<all_t<_Ts>...>(std::declval<_Ts>()...); };
4803 }
4804
4805 struct _Zip
4806 {
4807 template<typename... _Ts>
4808 requires (sizeof...(_Ts) == 0 || __detail::__can_zip_view<_Ts...>)
4809 constexpr auto
4810 operator() [[nodiscard]] (_Ts&&... __ts) const
4811 {
4812 if constexpr (sizeof...(_Ts) == 0)
4813 return views::empty<tuple<>>;
4814 else
4815 return zip_view<all_t<_Ts>...>(std::forward<_Ts>(__ts)...);
4816 }
4817 };
4818
4819 inline constexpr _Zip zip;
4820 }
4821
4822 namespace __detail
4823 {
4824 template<typename _Range, bool _Const>
4825 using __range_iter_cat
4826 = typename iterator_traits<iterator_t<__maybe_const_t<_Const, _Range>>>::iterator_category;
4827 }
4828
4829 template<copy_constructible _Fp, input_range... _Vs>
4830 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && is_object_v<_Fp>
4831 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
4832 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
4833 class zip_transform_view : public view_interface<zip_transform_view<_Fp, _Vs...>>
4834 {
4835 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
4836 zip_view<_Vs...> _M_zip;
4837
4838 using _InnerView = zip_view<_Vs...>;
4839
4840 template<bool _Const>
4841 using __ziperator = iterator_t<__detail::__maybe_const_t<_Const, _InnerView>>;
4842
4843 template<bool _Const>
4844 using __zentinel = sentinel_t<__detail::__maybe_const_t<_Const, _InnerView>>;
4845
4846 template<bool _Const>
4847 using _Base = __detail::__maybe_const_t<_Const, _InnerView>;
4848
4849 template<bool _Const>
4850 struct __iter_cat
4851 { };
4852
4853 template<bool _Const>
4854 requires forward_range<_Base<_Const>>
4855 struct __iter_cat<_Const>
4856 {
4857 private:
4858 static auto
4859 _S_iter_cat()
4860 {
4861 using __detail::__maybe_const_t;
4862 using __detail::__range_iter_cat;
4863 using _Res = invoke_result_t<__maybe_const_t<_Const, _Fp>&,
4864 range_reference_t<__maybe_const_t<_Const, _Vs>>...>;
4865 if constexpr (!is_lvalue_reference_v<_Res>)
4866 return input_iterator_tag{};
4867 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
4868 random_access_iterator_tag> && ...))
4869 return random_access_iterator_tag{};
4870 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
4871 bidirectional_iterator_tag> && ...))
4872 return bidirectional_iterator_tag{};
4873 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
4874 forward_iterator_tag> && ...))
4875 return forward_iterator_tag{};
4876 else
4877 return input_iterator_tag{};
4878 }
4879 public:
4880 using iterator_category = decltype(_S_iter_cat());
4881 };
4882
4883 template<bool> class _Iterator;
4884 template<bool> class _Sentinel;
4885
4886 public:
4887 zip_transform_view() = default;
4888
4889 constexpr explicit
4890 zip_transform_view(_Fp __fun, _Vs... __views)
4891 : _M_fun(std::move(__fun)), _M_zip(std::move(__views)...)
4892 { }
4893
4894 constexpr auto
4895 begin()
4896 { return _Iterator<false>(*this, _M_zip.begin()); }
4897
4898 constexpr auto
4899 begin() const
4900 requires range<const _InnerView>
4901 && regular_invocable<const _Fp&, range_reference_t<const _Vs>...>
4902 { return _Iterator<true>(*this, _M_zip.begin()); }
4903
4904 constexpr auto
4905 end()
4906 {
4907 if constexpr (common_range<_InnerView>)
4908 return _Iterator<false>(*this, _M_zip.end());
4909 else
4910 return _Sentinel<false>(_M_zip.end());
4911 }
4912
4913 constexpr auto
4914 end() const
4915 requires range<const _InnerView>
4916 && regular_invocable<const _Fp&, range_reference_t<const _Vs>...>
4917 {
4918 if constexpr (common_range<const _InnerView>)
4919 return _Iterator<true>(*this, _M_zip.end());
4920 else
4921 return _Sentinel<true>(_M_zip.end());
4922 }
4923
4924 constexpr auto
4925 size() requires sized_range<_InnerView>
4926 { return _M_zip.size(); }
4927
4928 constexpr auto
4929 size() const requires sized_range<const _InnerView>
4930 { return _M_zip.size(); }
4931 };
4932
4933 template<class _Fp, class... Rs>
4934 zip_transform_view(_Fp, Rs&&...) -> zip_transform_view<_Fp, views::all_t<Rs>...>;
4935
4936 template<copy_constructible _Fp, input_range... _Vs>
4937 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && is_object_v<_Fp>
4938 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
4939 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
4940 template<bool _Const>
4941 class zip_transform_view<_Fp, _Vs...>::_Iterator : public __iter_cat<_Const>
4942 {
4943 using _Parent = __detail::__maybe_const_t<_Const, zip_transform_view>;
4944
4945 _Parent* _M_parent = nullptr;
4946 __ziperator<_Const> _M_inner;
4947
4948 constexpr
4949 _Iterator(_Parent& __parent, __ziperator<_Const> __inner)
4950 : _M_parent(std::__addressof(__parent)), _M_inner(std::move(__inner))
4951 { }
4952
4953 friend class zip_transform_view;
4954
4955 public:
4956 // iterator_category defined in zip_transform_view::__iter_cat
4957 using iterator_concept = typename __ziperator<_Const>::iterator_concept;
4958 using value_type
4959 = remove_cvref_t<invoke_result_t<__detail::__maybe_const_t<_Const, _Fp>&,
4960 range_reference_t<__detail::__maybe_const_t<_Const, _Vs>>...>>;
4961 using difference_type = range_difference_t<_Base<_Const>>;
4962
4963 _Iterator() = default;
4964
4965 constexpr
4966 _Iterator(_Iterator<!_Const> __i)
4967 requires _Const && convertible_to<__ziperator<false>, __ziperator<_Const>>
4968 : _M_parent(__i._M_parent), _M_inner(std::move(__i._M_inner))
4969 { }
4970
4971 constexpr decltype(auto)
4972 operator*() const
4973 {
4974 return std::apply([&](const auto&... __iters) -> decltype(auto) {
4975 return std::__invoke(*_M_parent->_M_fun, *__iters...);
4976 }, _M_inner._M_current);
4977 }
4978
4979 constexpr _Iterator&
4980 operator++()
4981 {
4982 ++_M_inner;
4983 return *this;
4984 }
4985
4986 constexpr void
4987 operator++(int)
4988 { ++*this; }
4989
4990 constexpr _Iterator
4991 operator++(int) requires forward_range<_Base<_Const>>
4992 {
4993 auto __tmp = *this;
4994 ++*this;
4995 return __tmp;
4996 }
4997
4998 constexpr _Iterator&
4999 operator--() requires bidirectional_range<_Base<_Const>>
5000 {
5001 --_M_inner;
5002 return *this;
5003 }
5004
5005 constexpr _Iterator
5006 operator--(int) requires bidirectional_range<_Base<_Const>>
5007 {
5008 auto __tmp = *this;
5009 --*this;
5010 return __tmp;
5011 }
5012
5013 constexpr _Iterator&
5014 operator+=(difference_type __x) requires random_access_range<_Base<_Const>>
5015 {
5016 _M_inner += __x;
5017 return *this;
5018 }
5019
5020 constexpr _Iterator&
5021 operator-=(difference_type __x) requires random_access_range<_Base<_Const>>
5022 {
5023 _M_inner -= __x;
5024 return *this;
5025 }
5026
5027 constexpr decltype(auto)
5028 operator[](difference_type __n) const requires random_access_range<_Base<_Const>>
5029 {
5030 return std::apply([&]<typename... _Is>(const _Is&... __iters) -> decltype(auto) {
5031 return std::__invoke(*_M_parent->_M_fun, __iters[iter_difference_t<_Is>(__n)]...);
5032 }, _M_inner._M_current);
5033 }
5034
5035 friend constexpr bool
5036 operator==(const _Iterator& __x, const _Iterator& __y)
5037 requires equality_comparable<__ziperator<_Const>>
5038 { return __x._M_inner == __y._M_inner; }
5039
5040 friend constexpr auto
5041 operator<=>(const _Iterator& __x, const _Iterator& __y)
5042 requires random_access_range<_Base<_Const>>
5043 { return __x._M_inner <=> __y._M_inner; }
5044
5045 friend constexpr _Iterator
5046 operator+(const _Iterator& __i, difference_type __n)
5047 requires random_access_range<_Base<_Const>>
5048 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5049
5050 friend constexpr _Iterator
5051 operator+(difference_type __n, const _Iterator& __i)
5052 requires random_access_range<_Base<_Const>>
5053 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5054
5055 friend constexpr _Iterator
5056 operator-(const _Iterator& __i, difference_type __n)
5057 requires random_access_range<_Base<_Const>>
5058 { return _Iterator(*__i._M_parent, __i._M_inner - __n); }
5059
5060 friend constexpr difference_type
5061 operator-(const _Iterator& __x, const _Iterator& __y)
5062 requires sized_sentinel_for<__ziperator<_Const>, __ziperator<_Const>>
5063 { return __x._M_inner - __y._M_inner; }
5064 };
5065
5066 template<copy_constructible _Fp, input_range... _Vs>
5067 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && is_object_v<_Fp>
5068 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
5069 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
5070 template<bool _Const>
5071 class zip_transform_view<_Fp, _Vs...>::_Sentinel
5072 {
5073 __zentinel<_Const> _M_inner;
5074
5075 constexpr explicit
5076 _Sentinel(__zentinel<_Const> __inner)
5077 : _M_inner(__inner)
5078 { }
5079
5080 friend class zip_transform_view;
5081
5082 public:
5083 _Sentinel() = default;
5084
5085 constexpr
5086 _Sentinel(_Sentinel<!_Const> __i)
5087 requires _Const && convertible_to<__zentinel<false>, __zentinel<_Const>>
5088 : _M_inner(std::move(__i._M_inner))
5089 { }
5090
5091 template<bool _OtherConst>
5092 requires sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5093 friend constexpr bool
5094 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5095 { return __x._M_inner == __y._M_inner; }
5096
5097 template<bool _OtherConst>
5098 requires sized_sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5099 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5100 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5101 { return __x._M_inner - __y._M_inner; }
5102
5103 template<bool _OtherConst>
5104 requires sized_sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5105 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5106 operator-(const _Sentinel& __x, const _Iterator<_OtherConst>& __y)
5107 { return __x._M_inner - __y._M_inner; }
5108 };
5109
5110 namespace views
5111 {
5112 namespace __detail
5113 {
5114 template<typename _Fp, typename... _Ts>
5115 concept __can_zip_transform_view
5116 = requires { zip_transform_view(std::declval<_Fp>(), std::declval<_Ts>()...); };
5117 }
5118
5119 struct _ZipTransform
5120 {
5121 template<typename _Fp, typename... _Ts>
5122 requires (sizeof...(_Ts) == 0) || __detail::__can_zip_transform_view<_Fp, _Ts...>
5123 constexpr auto
5124 operator() [[nodiscard]] (_Fp&& __f, _Ts&&... __ts) const
5125 {
5126 if constexpr (sizeof...(_Ts) == 0)
5127 return views::empty<decay_t<invoke_result_t<decay_t<_Fp>&>>>;
5128 else
5129 return zip_transform_view(std::forward<_Fp>(__f), std::forward<_Ts>(__ts)...);
5130 }
5131 };
5132
5133 inline constexpr _ZipTransform zip_transform;
5134 }
5135
5136 template<forward_range _Vp, size_t _Nm>
5137 requires view<_Vp> && (_Nm > 0)
5138 class adjacent_view : public view_interface<adjacent_view<_Vp, _Nm>>
5139 {
5140 _Vp _M_base = _Vp();
5141
5142 template<bool> class _Iterator;
5143 template<bool> class _Sentinel;
5144
5145 struct __as_sentinel
5146 { };
5147
5148 public:
5149 adjacent_view() requires default_initializable<_Vp> = default;
5150
5151 constexpr explicit
5152 adjacent_view(_Vp __base)
5153 : _M_base(std::move(__base))
5154 { }
5155
5156 constexpr auto
5157 begin() requires (!__detail::__simple_view<_Vp>)
5158 { return _Iterator<false>(ranges::begin(_M_base), ranges::end(_M_base)); }
5159
5160 constexpr auto
5161 begin() const requires range<const _Vp>
5162 { return _Iterator<true>(ranges::begin(_M_base), ranges::end(_M_base)); }
5163
5164 constexpr auto
5165 end() requires (!__detail::__simple_view<_Vp>)
5166 {
5167 if constexpr (common_range<_Vp>)
5168 return _Iterator<false>(__as_sentinel{}, ranges::begin(_M_base), ranges::end(_M_base));
5169 else
5170 return _Sentinel<false>(ranges::end(_M_base));
5171 }
5172
5173 constexpr auto
5174 end() const requires range<const _Vp>
5175 {
5176 if constexpr (common_range<const _Vp>)
5177 return _Iterator<true>(__as_sentinel{}, ranges::begin(_M_base), ranges::end(_M_base));
5178 else
5179 return _Sentinel<true>(ranges::end(_M_base));
5180 }
5181
5182 constexpr auto
5183 size() requires sized_range<_Vp>
5184 {
5185 using _ST = decltype(ranges::size(_M_base));
5186 using _CT = common_type_t<_ST, size_t>;
5187 auto __sz = static_cast<_CT>(ranges::size(_M_base));
5188 __sz -= std::min<_CT>(__sz, _Nm - 1);
5189 return static_cast<_ST>(__sz);
5190 }
5191
5192 constexpr auto
5193 size() const requires sized_range<const _Vp>
5194 {
5195 using _ST = decltype(ranges::size(_M_base));
5196 using _CT = common_type_t<_ST, size_t>;
5197 auto __sz = static_cast<_CT>(ranges::size(_M_base));
5198 __sz -= std::min<_CT>(__sz, _Nm - 1);
5199 return static_cast<_ST>(__sz);
5200 }
5201 };
5202
5203 template<typename _Vp, size_t _Nm>
5204 inline constexpr bool enable_borrowed_range<adjacent_view<_Vp, _Nm>>
5205 = enable_borrowed_range<_Vp>;
5206
5207 namespace __detail
5208 {
5209 // Yields tuple<_Tp, ..., _Tp> with _Nm elements.
5210 template<typename _Tp, size_t _Nm>
5211 using __repeated_tuple = decltype(std::tuple_cat(std::declval<array<_Tp, _Nm>>()));
5212
5213 // For a functor F that is callable with N arguments, the expression
5214 // declval<__unarize<F, N>>(x) is equivalent to declval<F>(x, ..., x).
5215 template<typename _Fp, size_t _Nm>
5216 struct __unarize
5217 {
5218 template<typename... _Ts>
5219 static invoke_result_t<_Fp, _Ts...>
5220 __tuple_apply(const tuple<_Ts...>&); // not defined
5221
5222 template<typename _Tp>
5223 decltype(__tuple_apply(std::declval<__repeated_tuple<_Tp, _Nm>>()))
5224 operator()(_Tp&&); // not defined
5225 };
5226 }
5227
5228 template<forward_range _Vp, size_t _Nm>
5229 requires view<_Vp> && (_Nm > 0)
5230 template<bool _Const>
5231 class adjacent_view<_Vp, _Nm>::_Iterator
5232 {
5233 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5234 array<iterator_t<_Base>, _Nm> _M_current = array<iterator_t<_Base>, _Nm>();
5235
5236 constexpr
5237 _Iterator(iterator_t<_Base> __first, sentinel_t<_Base> __last)
5238 {
5239 for (auto& __i : _M_current)
5240 {
5241 __i = __first;
5242 ranges::advance(__first, 1, __last);
5243 }
5244 }
5245
5246 constexpr
5247 _Iterator(__as_sentinel, iterator_t<_Base> __first, iterator_t<_Base> __last)
5248 {
5249 if constexpr (!bidirectional_range<_Base>)
5250 for (auto& __it : _M_current)
5251 __it = __last;
5252 else
5253 for (size_t __i = 0; __i < _Nm; ++__i)
5254 {
5255 _M_current[_Nm - 1 - __i] = __last;
5256 ranges::advance(__last, -1, __first);
5257 }
5258 }
5259
5260 static auto
5261 _S_iter_concept()
5262 {
5263 if constexpr (random_access_range<_Base>)
5264 return random_access_iterator_tag{};
5265 else if constexpr (bidirectional_range<_Base>)
5266 return bidirectional_iterator_tag{};
5267 else
5268 return forward_iterator_tag{};
5269 }
5270
5271 friend class adjacent_view;
5272
5273 template<forward_range _Wp, copy_constructible _Fp, size_t _Mm>
5274 requires view<_Wp> && (_Mm > 0) && is_object_v<_Fp>
5275 && regular_invocable<__detail::__unarize<_Fp&, _Mm>, range_reference_t<_Wp>>
5276 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Mm>,
5277 range_reference_t<_Wp>>>
5278 friend class adjacent_transform_view;
5279
5280 public:
5281 using iterator_category = input_iterator_tag;
5282 using iterator_concept = decltype(_S_iter_concept());
5283 using value_type = conditional_t<_Nm == 2,
5284 pair<range_value_t<_Base>, range_value_t<_Base>>,
5285 __detail::__repeated_tuple<range_value_t<_Base>, _Nm>>;
5286 using difference_type = range_difference_t<_Base>;
5287
5288 _Iterator() = default;
5289
5290 constexpr
5291 _Iterator(_Iterator<!_Const> __i)
5292 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
5293 {
5294 for (size_t __j = 0; __j < _Nm; ++__j)
5295 _M_current[__j] = std::move(__i._M_current[__j]);
5296 }
5297
5298 constexpr auto
5299 operator*() const
5300 {
5301 auto __f = [](auto& __i) -> decltype(auto) { return *__i; };
5302 return __detail::__tuple_transform(__f, _M_current);
5303 }
5304
5305 constexpr _Iterator&
5306 operator++()
5307 {
5308 for (auto& __i : _M_current)
5309 ++__i;
5310 return *this;
5311 }
5312
5313 constexpr _Iterator
5314 operator++(int)
5315 {
5316 auto __tmp = *this;
5317 ++*this;
5318 return __tmp;
5319 }
5320
5321 constexpr _Iterator&
5322 operator--() requires bidirectional_range<_Base>
5323 {
5324 for (auto& __i : _M_current)
5325 --__i;
5326 return *this;
5327 }
5328
5329 constexpr _Iterator
5330 operator--(int) requires bidirectional_range<_Base>
5331 {
5332 auto __tmp = *this;
5333 --*this;
5334 return __tmp;
5335 }
5336
5337 constexpr _Iterator&
5338 operator+=(difference_type __x)
5339 requires random_access_range<_Base>
5340 {
5341 for (auto& __i : _M_current)
5342 __i += __x;
5343 return *this;
5344 }
5345
5346 constexpr _Iterator&
5347 operator-=(difference_type __x)
5348 requires random_access_range<_Base>
5349 {
5350 for (auto& __i : _M_current)
5351 __i -= __x;
5352 return *this;
5353 }
5354
5355 constexpr auto
5356 operator[](difference_type __n) const
5357 requires random_access_range<_Base>
5358 {
5359 auto __f = [&](auto& __i) -> decltype(auto) { return __i[__n]; };
5360 return __detail::__tuple_transform(__f, _M_current);
5361 }
5362
5363 friend constexpr bool
5364 operator==(const _Iterator& __x, const _Iterator& __y)
5365 { return __x._M_current.back() == __y._M_current.back(); }
5366
5367 friend constexpr bool
5368 operator<(const _Iterator& __x, const _Iterator& __y)
5369 requires random_access_range<_Base>
5370 { return __x._M_current.back() < __y._M_current.back(); }
5371
5372 friend constexpr bool
5373 operator>(const _Iterator& __x, const _Iterator& __y)
5374 requires random_access_range<_Base>
5375 { return __y < __x; }
5376
5377 friend constexpr bool
5378 operator<=(const _Iterator& __x, const _Iterator& __y)
5379 requires random_access_range<_Base>
5380 { return !(__y < __x); }
5381
5382 friend constexpr bool
5383 operator>=(const _Iterator& __x, const _Iterator& __y)
5384 requires random_access_range<_Base>
5385 { return !(__x < __y); }
5386
5387 friend constexpr auto
5388 operator<=>(const _Iterator& __x, const _Iterator& __y)
5389 requires random_access_range<_Base>
5390 && three_way_comparable<iterator_t<_Base>>
5391 { return __x._M_current.back() <=> __y._M_current.back(); }
5392
5393 friend constexpr _Iterator
5394 operator+(const _Iterator& __i, difference_type __n)
5395 requires random_access_range<_Base>
5396 {
5397 auto __r = __i;
5398 __r += __n;
5399 return __r;
5400 }
5401
5402 friend constexpr _Iterator
5403 operator+(difference_type __n, const _Iterator& __i)
5404 requires random_access_range<_Base>
5405 {
5406 auto __r = __i;
5407 __r += __n;
5408 return __r;
5409 }
5410
5411 friend constexpr _Iterator
5412 operator-(const _Iterator& __i, difference_type __n)
5413 requires random_access_range<_Base>
5414 {
5415 auto __r = __i;
5416 __r -= __n;
5417 return __r;
5418 }
5419
5420 friend constexpr difference_type
5421 operator-(const _Iterator& __x, const _Iterator& __y)
5422 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
5423 { return __x._M_current.back() - __y._M_current.back(); }
5424
5425 friend constexpr auto
5426 iter_move(const _Iterator& __i)
5427 { return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
5428
5429 friend constexpr void
5430 iter_swap(const _Iterator& __l, const _Iterator& __r)
5431 requires indirectly_swappable<iterator_t<_Base>>
5432 {
5433 for (size_t __i = 0; __i < _Nm; __i++)
5434 ranges::iter_swap(__l._M_current[__i], __r._M_current[__i]);
5435 }
5436 };
5437
5438 template<forward_range _Vp, size_t _Nm>
5439 requires view<_Vp> && (_Nm > 0)
5440 template<bool _Const>
5441 class adjacent_view<_Vp, _Nm>::_Sentinel
5442 {
5443 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5444
5445 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
5446
5447 constexpr explicit
5448 _Sentinel(sentinel_t<_Base> __end)
5449 : _M_end(__end)
5450 { }
5451
5452 friend class adjacent_view;
5453
5454 public:
5455 _Sentinel() = default;
5456
5457 constexpr
5458 _Sentinel(_Sentinel<!_Const> __i)
5459 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
5460 : _M_end(std::move(__i._M_end))
5461 { }
5462
5463 template<bool _OtherConst>
5464 requires sentinel_for<sentinel_t<_Base>,
5465 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5466 friend constexpr bool
5467 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5468 { return __x._M_current.back() == __y._M_end; }
5469
5470 template<bool _OtherConst>
5471 requires sized_sentinel_for<sentinel_t<_Base>,
5472 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5473 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vp>>
5474 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5475 { return __x._M_current.back() - __y._M_end; }
5476
5477 template<bool _OtherConst>
5478 requires sized_sentinel_for<sentinel_t<_Base>,
5479 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5480 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vp>>
5481 operator-(const _Sentinel& __y, const _Iterator<_OtherConst>& __x)
5482 { return __y._M_end - __x._M_current.back(); }
5483 };
5484
5485 namespace views
5486 {
5487 namespace __detail
5488 {
5489 template<size_t _Nm, typename _Range>
5490 concept __can_adjacent_view
5491 = requires { adjacent_view<all_t<_Range>, _Nm>(std::declval<_Range>()); };
5492 }
5493
5494 template<size_t _Nm>
5495 struct _Adjacent : __adaptor::_RangeAdaptorClosure
5496 {
5497 template<viewable_range _Range>
5498 requires (_Nm == 0) || __detail::__can_adjacent_view<_Nm, _Range>
5499 constexpr auto
5500 operator() [[nodiscard]] (_Range&& __r) const
5501 {
5502 if constexpr (_Nm == 0)
5503 return views::empty<tuple<>>;
5504 else
5505 return adjacent_view<all_t<_Range>, _Nm>(std::forward<_Range>(__r));
5506 }
5507 };
5508
5509 template<size_t _Nm>
5510 inline constexpr _Adjacent<_Nm> adjacent;
5511
5512 inline constexpr auto pairwise = adjacent<2>;
5513 }
5514
5515 template<forward_range _Vp, copy_constructible _Fp, size_t _Nm>
5516 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5517 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5518 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5519 range_reference_t<_Vp>>>
5520 class adjacent_transform_view : public view_interface<adjacent_transform_view<_Vp, _Fp, _Nm>>
5521 {
5522 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
5523 adjacent_view<_Vp, _Nm> _M_inner;
5524
5525 using _InnerView = adjacent_view<_Vp, _Nm>;
5526
5527 template<bool _Const>
5528 using _InnerIter = iterator_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5529
5530 template<bool _Const>
5531 using _InnerSent = sentinel_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5532
5533 template<bool> class _Iterator;
5534 template<bool> class _Sentinel;
5535
5536 public:
5537 adjacent_transform_view() = default;
5538
5539 constexpr explicit
5540 adjacent_transform_view(_Vp __base, _Fp __fun)
5541 : _M_fun(std::move(__fun)), _M_inner(std::move(__base))
5542 { }
5543
5544 constexpr auto
5545 begin()
5546 { return _Iterator<false>(*this, _M_inner.begin()); }
5547
5548 constexpr auto
5549 begin() const
5550 requires range<const _InnerView>
5551 && regular_invocable<__detail::__unarize<const _Fp&, _Nm>,
5552 range_reference_t<const _Vp>>
5553 { return _Iterator<true>(*this, _M_inner.begin()); }
5554
5555 constexpr auto
5556 end()
5557 {
5558 if constexpr (common_range<_InnerView>)
5559 return _Iterator<false>(*this, _M_inner.end());
5560 else
5561 return _Sentinel<false>(_M_inner.end());
5562 }
5563
5564 constexpr auto
5565 end() const
5566 requires range<const _InnerView>
5567 && regular_invocable<__detail::__unarize<const _Fp&, _Nm>,
5568 range_reference_t<const _Vp>>
5569 {
5570 if constexpr (common_range<const _InnerView>)
5571 return _Iterator<true>(*this, _M_inner.end());
5572 else
5573 return _Sentinel<true>(_M_inner.end());
5574 }
5575
5576 constexpr auto
5577 size() requires sized_range<_InnerView>
5578 { return _M_inner.size(); }
5579
5580 constexpr auto
5581 size() const requires sized_range<const _InnerView>
5582 { return _M_inner.size(); }
5583 };
5584
5585 template<forward_range _Vp, copy_constructible _Fp, size_t _Nm>
5586 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5587 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5588 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5589 range_reference_t<_Vp>>>
5590 template<bool _Const>
5591 class adjacent_transform_view<_Vp, _Fp, _Nm>::_Iterator
5592 {
5593 using _Parent = __detail::__maybe_const_t<_Const, adjacent_transform_view>;
5594 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5595
5596 _Parent* _M_parent = nullptr;
5597 _InnerIter<_Const> _M_inner;
5598
5599 constexpr
5600 _Iterator(_Parent& __parent, _InnerIter<_Const> __inner)
5601 : _M_parent(std::__addressof(__parent)), _M_inner(std::move(__inner))
5602 { }
5603
5604 static auto
5605 _S_iter_cat()
5606 {
5607 using __detail::__maybe_const_t;
5608 using __detail::__unarize;
5609 using _Res = invoke_result_t<__unarize<__maybe_const_t<_Const, _Fp>&, _Nm>,
5610 range_reference_t<_Base>>;
5611 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
5612 if constexpr (!is_lvalue_reference_v<_Res>)
5613 return input_iterator_tag{};
5614 else if constexpr (derived_from<_Cat, random_access_iterator_tag>)
5615 return random_access_iterator_tag{};
5616 else if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
5617 return bidirectional_iterator_tag{};
5618 else if constexpr (derived_from<_Cat, forward_iterator_tag>)
5619 return forward_iterator_tag{};
5620 else
5621 return input_iterator_tag{};
5622 }
5623
5624 friend class adjacent_transform_view;
5625
5626 public:
5627 using iterator_category = decltype(_S_iter_cat());
5628 using iterator_concept = typename _InnerIter<_Const>::iterator_concept;
5629 using value_type
5630 = remove_cvref_t<invoke_result_t
5631 <__detail::__unarize<__detail::__maybe_const_t<_Const, _Fp>&, _Nm>,
5632 range_reference_t<_Base>>>;
5633 using difference_type = range_difference_t<_Base>;
5634
5635 _Iterator() = default;
5636
5637 constexpr
5638 _Iterator(_Iterator<!_Const> __i)
5639 requires _Const && convertible_to<_InnerIter<false>, _InnerIter<_Const>>
5640 : _M_parent(__i._M_parent), _M_inner(std::move(__i._M_inner))
5641 { }
5642
5643 constexpr decltype(auto)
5644 operator*() const
5645 {
5646 return std::apply([&](const auto&... __iters) -> decltype(auto) {
5647 return std::__invoke(*_M_parent->_M_fun, *__iters...);
5648 }, _M_inner._M_current);
5649 }
5650
5651 constexpr _Iterator&
5652 operator++()
5653 {
5654 ++_M_inner;
5655 return *this;
5656 }
5657
5658 constexpr _Iterator
5659 operator++(int)
5660 {
5661 auto __tmp = *this;
5662 ++*this;
5663 return __tmp;
5664 }
5665
5666 constexpr _Iterator&
5667 operator--() requires bidirectional_range<_Base>
5668 {
5669 --_M_inner;
5670 return *this;
5671 }
5672
5673 constexpr _Iterator
5674 operator--(int) requires bidirectional_range<_Base>
5675 {
5676 auto __tmp = *this;
5677 --*this;
5678 return __tmp;
5679 }
5680
5681 constexpr _Iterator&
5682 operator+=(difference_type __x) requires random_access_range<_Base>
5683 {
5684 _M_inner += __x;
5685 return *this;
5686 }
5687
5688 constexpr _Iterator&
5689 operator-=(difference_type __x) requires random_access_range<_Base>
5690 {
5691 _M_inner -= __x;
5692 return *this;
5693 }
5694
5695 constexpr decltype(auto)
5696 operator[](difference_type __n) const requires random_access_range<_Base>
5697 {
5698 return std::apply([&](const auto&... __iters) -> decltype(auto) {
5699 return std::__invoke(*_M_parent->_M_fun, __iters[__n]...);
5700 }, _M_inner._M_current);
5701 }
5702
5703 friend constexpr bool
5704 operator==(const _Iterator& __x, const _Iterator& __y)
5705 { return __x._M_inner == __y._M_inner; }
5706
5707 friend constexpr bool
5708 operator<(const _Iterator& __x, const _Iterator& __y)
5709 requires random_access_range<_Base>
5710 { return __x._M_inner < __y._M_inner; }
5711
5712 friend constexpr bool
5713 operator>(const _Iterator& __x, const _Iterator& __y)
5714 requires random_access_range<_Base>
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 auto
5728 operator<=>(const _Iterator& __x, const _Iterator& __y)
5729 requires random_access_range<_Base> &&
5730 three_way_comparable<_InnerIter<_Const>>
5731 { return __x._M_inner <=> __y._M_inner; }
5732
5733 friend constexpr _Iterator
5734 operator+(const _Iterator& __i, difference_type __n)
5735 requires random_access_range<_Base>
5736 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5737
5738 friend constexpr _Iterator
5739 operator+(difference_type __n, const _Iterator& __i)
5740 requires random_access_range<_Base>
5741 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
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 difference_type
5749 operator-(const _Iterator& __x, const _Iterator& __y)
5750 requires sized_sentinel_for<_InnerIter<_Const>, _InnerIter<_Const>>
5751 { return __x._M_inner - __y._M_inner; }
5752 };
5753
5754 template<forward_range _Vp, copy_constructible _Fp, size_t _Nm>
5755 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5756 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5757 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5758 range_reference_t<_Vp>>>
5759 template<bool _Const>
5760 class adjacent_transform_view<_Vp, _Fp, _Nm>::_Sentinel
5761 {
5762 _InnerSent<_Const> _M_inner;
5763
5764 constexpr explicit
5765 _Sentinel(_InnerSent<_Const> __inner)
5766 : _M_inner(__inner)
5767 { }
5768
5769 friend class adjacent_transform_view;
5770
5771 public:
5772 _Sentinel() = default;
5773
5774 constexpr
5775 _Sentinel(_Sentinel<!_Const> __i)
5776 requires _Const && convertible_to<_InnerSent<false>, _InnerSent<_Const>>
5777 : _M_inner(std::move(__i._M_inner))
5778 { }
5779
5780 template<bool _OtherConst>
5781 requires sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
5782 friend constexpr bool
5783 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5784 { return __x._M_inner == __y._M_inner; }
5785
5786 template<bool _OtherConst>
5787 requires sized_sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
5788 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5789 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5790 { return __x._M_inner - __y._M_inner; }
5791
5792 template<bool _OtherConst>
5793 requires sized_sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
5794 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5795 operator-(const _Sentinel& __x, const _Iterator<_OtherConst>& __y)
5796 { return __x._M_inner - __y._M_inner; }
5797 };
5798
5799 namespace views
5800 {
5801 namespace __detail
5802 {
5803 template<size_t _Nm, typename _Range, typename _Fp>
5804 concept __can_adjacent_transform_view
5805 = requires { adjacent_transform_view<all_t<_Range>, decay_t<_Fp>, _Nm>
5806 (std::declval<_Range>(), std::declval<_Fp>()); };
5807 }
5808
5809 template<size_t _Nm>
5810 struct _AdjacentTransform : __adaptor::_RangeAdaptor<_AdjacentTransform<_Nm>>
5811 {
5812 template<viewable_range _Range, typename _Fp>
5813 requires (_Nm == 0) || __detail::__can_adjacent_transform_view<_Nm, _Range, _Fp>
5814 constexpr auto
5815 operator() [[nodiscard]] (_Range&& __r, _Fp&& __f) const
5816 {
5817 if constexpr (_Nm == 0)
5818 return zip_transform(std::forward<_Fp>(__f));
5819 else
5820 return adjacent_transform_view<all_t<_Range>, decay_t<_Fp>, _Nm>
5821 (std::forward<_Range>(__r), std::forward<_Fp>(__f));
5822 }
5823
5824 using __adaptor::_RangeAdaptor<_AdjacentTransform>::operator();
5825 static constexpr int _S_arity = 2;
5826 static constexpr bool _S_has_simple_extra_args = true;
5827 };
5828
5829 template<size_t _Nm>
5830 inline constexpr _AdjacentTransform<_Nm> adjacent_transform;
5831
5832 inline constexpr auto pairwise_transform = adjacent_transform<2>;
5833 }
5834
5835#define __cpp_lib_ranges_chunk 202202L
5836
5837 namespace __detail
5838 {
5839 template<typename _Tp>
5840 constexpr _Tp __div_ceil(_Tp __num, _Tp __denom)
5841 {
5842 _Tp __r = __num / __denom;
5843 if (__num % __denom)
5844 ++__r;
5845 return __r;
5846 }
5847 }
5848
5849 template<view _Vp>
5850 requires input_range<_Vp>
5851 class chunk_view : public view_interface<chunk_view<_Vp>>
5852 {
5853 _Vp _M_base;
5854 range_difference_t<_Vp> _M_n;
5855 range_difference_t<_Vp> _M_remainder = 0;
5856 __detail::__non_propagating_cache<iterator_t<_Vp>> _M_current;
5857
5858 class _OuterIter;
5859 class _InnerIter;
5860
5861 public:
5862 constexpr explicit
5863 chunk_view(_Vp __base, range_difference_t<_Vp> __n)
5864 : _M_base(std::move(__base)), _M_n(__n)
5865 { __glibcxx_assert(__n >= 0); }
5866
5867 constexpr _Vp
5868 base() const & requires copy_constructible<_Vp>
5869 { return _M_base; }
5870
5871 constexpr _Vp
5872 base() &&
5873 { return std::move(_M_base); }
5874
5875 constexpr _OuterIter
5876 begin()
5877 {
5878 _M_current = ranges::begin(_M_base);
5879 _M_remainder = _M_n;
5880 return _OuterIter(*this);
5881 }
5882
5883 constexpr default_sentinel_t
5884 end() const noexcept
5885 { return default_sentinel; }
5886
5887 constexpr auto
5888 size() requires sized_range<_Vp>
5889 {
5890 return __detail::__to_unsigned_like(__detail::__div_ceil
5891 (ranges::distance(_M_base), _M_n));
5892 }
5893
5894 constexpr auto
5895 size() const requires sized_range<const _Vp>
5896 {
5897 return __detail::__to_unsigned_like(__detail::__div_ceil
5898 (ranges::distance(_M_base), _M_n));
5899 }
5900 };
5901
5902 template<typename _Range>
5903 chunk_view(_Range&&, range_difference_t<_Range>) -> chunk_view<views::all_t<_Range>>;
5904
5905 template<view _Vp>
5906 requires input_range<_Vp>
5907 class chunk_view<_Vp>::_OuterIter
5908 {
5909 chunk_view* _M_parent;
5910
5911 constexpr explicit
5912 _OuterIter(chunk_view& __parent) noexcept
5913 : _M_parent(std::__addressof(__parent))
5914 { }
5915
5916 friend chunk_view;
5917
5918 public:
5919 using iterator_concept = input_iterator_tag;
5920 using difference_type = range_difference_t<_Vp>;
5921
5922 struct value_type;
5923
5924 _OuterIter(_OuterIter&&) = default;
5925 _OuterIter& operator=(_OuterIter&&) = default;
5926
5927 constexpr value_type
5928 operator*() const
5929 {
5930 __glibcxx_assert(*this != default_sentinel);
5931 return value_type(*_M_parent);
5932 }
5933
5934 constexpr _OuterIter&
5935 operator++()
5936 {
5937 __glibcxx_assert(*this != default_sentinel);
5938 ranges::advance(*_M_parent->_M_current, _M_parent->_M_remainder,
5939 ranges::end(_M_parent->_M_base));
5940 _M_parent->_M_remainder = _M_parent->_M_n;
5941 return *this;
5942 }
5943
5944 constexpr void
5945 operator++(int)
5946 { ++*this; }
5947
5948 friend constexpr bool
5949 operator==(const _OuterIter& __x, default_sentinel_t)
5950 {
5951 return *__x._M_parent->_M_current == ranges::end(__x._M_parent->_M_base)
5952 && __x._M_parent->_M_remainder != 0;
5953 }
5954
5955 friend constexpr difference_type
5956 operator-(default_sentinel_t, const _OuterIter& __x)
5957 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
5958 {
5959 const auto __dist = ranges::end(__x._M_parent->_M_base) - *__x._M_parent->_M_current;
5960
5961 if (__dist < __x._M_parent->_M_remainder)
5962 return __dist == 0 ? 0 : 1;
5963
5964 return 1 + __detail::__div_ceil(__dist - __x._M_parent->_M_remainder,
5965 __x._M_parent->_M_n);
5966 }
5967
5968 friend constexpr difference_type
5969 operator-(const _OuterIter& __x, default_sentinel_t __y)
5970 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
5971 { return -(__y - __x); }
5972 };
5973
5974 template<view _Vp>
5975 requires input_range<_Vp>
5976 struct chunk_view<_Vp>::_OuterIter::value_type : view_interface<value_type>
5977 {
5978 private:
5979 chunk_view* _M_parent;
5980
5981 constexpr explicit
5982 value_type(chunk_view& __parent) noexcept
5983 : _M_parent(std::__addressof(__parent))
5984 { }
5985
5986 friend _OuterIter;
5987
5988 public:
5989 constexpr _InnerIter
5990 begin() const noexcept
5991 { return _InnerIter(*_M_parent); }
5992
5993 constexpr default_sentinel_t
5994 end() const noexcept
5995 { return default_sentinel; }
5996
5997 constexpr auto
5998 size() const
5999 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6000 {
6001 return __detail::__to_unsigned_like
6002 (ranges::min(_M_parent->_M_remainder,
6003 ranges::end(_M_parent->_M_base) - *_M_parent->_M_current));
6004 }
6005 };
6006
6007 template<view _Vp>
6008 requires input_range<_Vp>
6009 class chunk_view<_Vp>::_InnerIter
6010 {
6011 chunk_view* _M_parent;
6012
6013 constexpr explicit
6014 _InnerIter(chunk_view& __parent) noexcept
6015 : _M_parent(std::__addressof(__parent))
6016 { }
6017
6018 friend _OuterIter::value_type;
6019
6020 public:
6021 using iterator_concept = input_iterator_tag;
6022 using difference_type = range_difference_t<_Vp>;
6023 using value_type = range_value_t<_Vp>;
6024
6025 _InnerIter(_InnerIter&&) = default;
6026 _InnerIter& operator=(_InnerIter&&) = default;
6027
6028 constexpr const iterator_t<_Vp>&
6029 base() const &
6030 { return *_M_parent->_M_current; }
6031
6032 constexpr range_reference_t<_Vp>
6033 operator*() const
6034 {
6035 __glibcxx_assert(*this != default_sentinel);
6036 return **_M_parent->_M_current;
6037 }
6038
6039 constexpr _InnerIter&
6040 operator++()
6041 {
6042 __glibcxx_assert(*this != default_sentinel);
6043 ++*_M_parent->_M_current;
6044 if (*_M_parent->_M_current == ranges::end(_M_parent->_M_base))
6045 _M_parent->_M_remainder = 0;
6046 else
6047 --_M_parent->_M_remainder;
6048 return *this;
6049 }
6050
6051 constexpr void
6052 operator++(int)
6053 { ++*this; }
6054
6055 friend constexpr bool
6056 operator==(const _InnerIter& __x, default_sentinel_t) noexcept
6057 { return __x._M_parent->_M_remainder == 0; }
6058
6059 friend constexpr difference_type
6060 operator-(default_sentinel_t, const _InnerIter& __x)
6061 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6062 {
6063 return ranges::min(__x._M_parent->_M_remainder,
6064 ranges::end(__x._M_parent->_M_base) - *__x._M_parent->_M_current);
6065 }
6066
6067 friend constexpr difference_type
6068 operator-(const _InnerIter& __x, default_sentinel_t __y)
6069 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6070 { return -(__y - __x); }
6071 };
6072
6073 template<view _Vp>
6074 requires forward_range<_Vp>
6075 class chunk_view<_Vp> : public view_interface<chunk_view<_Vp>>
6076 {
6077 _Vp _M_base;
6078 range_difference_t<_Vp> _M_n;
6079 template<bool> class _Iterator;
6080
6081 public:
6082 constexpr explicit
6083 chunk_view(_Vp __base, range_difference_t<_Vp> __n)
6084 : _M_base(std::move(__base)), _M_n(__n)
6085 { __glibcxx_assert(__n > 0); }
6086
6087 constexpr _Vp
6088 base() const & requires copy_constructible<_Vp>
6089 { return _M_base; }
6090
6091 constexpr _Vp
6092 base() &&
6093 { return std::move(_M_base); }
6094
6095 constexpr auto
6096 begin() requires (!__detail::__simple_view<_Vp>)
6097 { return _Iterator<false>(this, ranges::begin(_M_base)); }
6098
6099 constexpr auto
6100 begin() const requires forward_range<const _Vp>
6101 { return _Iterator<true>(this, ranges::begin(_M_base)); }
6102
6103 constexpr auto
6104 end() requires (!__detail::__simple_view<_Vp>)
6105 {
6106 if constexpr (common_range<_Vp> && sized_range<_Vp>)
6107 {
6108 auto __missing = (_M_n - ranges::distance(_M_base) % _M_n) % _M_n;
6109 return _Iterator<false>(this, ranges::end(_M_base), __missing);
6110 }
6111 else if constexpr (common_range<_Vp> && !bidirectional_range<_Vp>)
6112 return _Iterator<false>(this, ranges::end(_M_base));
6113 else
6114 return default_sentinel;
6115 }
6116
6117 constexpr auto
6118 end() const requires forward_range<const _Vp>
6119 {
6120 if constexpr (common_range<const _Vp> && sized_range<const _Vp>)
6121 {
6122 auto __missing = (_M_n - ranges::distance(_M_base) % _M_n) % _M_n;
6123 return _Iterator<true>(this, ranges::end(_M_base), __missing);
6124 }
6125 else if constexpr (common_range<const _Vp> && !bidirectional_range<const _Vp>)
6126 return _Iterator<true>(this, ranges::end(_M_base));
6127 else
6128 return default_sentinel;
6129 }
6130
6131 constexpr auto
6132 size() requires sized_range<_Vp>
6133 {
6134 return __detail::__to_unsigned_like(__detail::__div_ceil
6135 (ranges::distance(_M_base), _M_n));
6136 }
6137
6138 constexpr auto
6139 size() const requires sized_range<const _Vp>
6140 {
6141 return __detail::__to_unsigned_like(__detail::__div_ceil
6142 (ranges::distance(_M_base), _M_n));
6143 }
6144 };
6145
6146 template<typename _Vp>
6147 inline constexpr bool enable_borrowed_range<chunk_view<_Vp>>
6148 = forward_range<_Vp> && enable_borrowed_range<_Vp>;
6149
6150 template<view _Vp>
6151 requires forward_range<_Vp>
6152 template<bool _Const>
6153 class chunk_view<_Vp>::_Iterator
6154 {
6155 using _Parent = __detail::__maybe_const_t<_Const, chunk_view>;
6156 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6157
6158 iterator_t<_Base> _M_current = iterator_t<_Base>();
6159 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
6160 range_difference_t<_Base> _M_n = 0;
6161 range_difference_t<_Base> _M_missing = 0;
6162
6163 constexpr
6164 _Iterator(_Parent* __parent, iterator_t<_Base> __current,
6165 range_difference_t<_Base> __missing = 0)
6166 : _M_current(__current), _M_end(ranges::end(__parent->_M_base)),
6167 _M_n(__parent->_M_n), _M_missing(__missing)
6168 { }
6169
6170 static auto
6171 _S_iter_cat()
6172 {
6173 if constexpr (random_access_range<_Base>)
6174 return random_access_iterator_tag{};
6175 else if constexpr (bidirectional_range<_Base>)
6176 return bidirectional_iterator_tag{};
6177 else
6178 return forward_iterator_tag{};
6179 }
6180
6181 friend chunk_view;
6182
6183 public:
6184 using iterator_category = input_iterator_tag;
6185 using iterator_concept = decltype(_S_iter_cat());
6186 using value_type = decltype(views::take(subrange(_M_current, _M_end), _M_n));
6187 using difference_type = range_difference_t<_Base>;
6188
6189 _Iterator() = default;
6190
6191 constexpr _Iterator(_Iterator<!_Const> __i)
6192 requires _Const
6193 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
6194 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
6195 : _M_current(std::move(__i._M_current)), _M_end(std::move(__i._M_end)),
6196 _M_n(__i._M_n), _M_missing(__i._M_missing)
6197 { }
6198
6199 constexpr iterator_t<_Base>
6200 base() const
6201 { return _M_current; }
6202
6203 constexpr value_type
6204 operator*() const
6205 {
6206 __glibcxx_assert(_M_current != _M_end);
6207 return views::take(subrange(_M_current, _M_end), _M_n);
6208 }
6209
6210 constexpr _Iterator&
6211 operator++()
6212 {
6213 __glibcxx_assert(_M_current != _M_end);
6214 _M_missing = ranges::advance(_M_current, _M_n, _M_end);
6215 return *this;
6216 }
6217
6218 constexpr _Iterator
6219 operator++(int)
6220 {
6221 auto __tmp = *this;
6222 ++*this;
6223 return __tmp;
6224 }
6225
6226 constexpr _Iterator&
6227 operator--() requires bidirectional_range<_Base>
6228 {
6229 ranges::advance(_M_current, _M_missing - _M_n);
6230 _M_missing = 0;
6231 return *this;
6232 }
6233
6234 constexpr _Iterator
6235 operator--(int) requires bidirectional_range<_Base>
6236 {
6237 auto __tmp = *this;
6238 --*this;
6239 return __tmp;
6240 }
6241
6242 constexpr _Iterator&
6243 operator+=(difference_type __x)
6244 requires random_access_range<_Base>
6245 {
6246 if (__x > 0)
6247 {
6248 __glibcxx_assert(ranges::distance(_M_current, _M_end) > _M_n * (__x - 1));
6249 _M_missing = ranges::advance(_M_current, _M_n * __x, _M_end);
6250 }
6251 else if (__x < 0)
6252 {
6253 ranges::advance(_M_current, _M_n * __x + _M_missing);
6254 _M_missing = 0;
6255 }
6256 return *this;
6257 }
6258
6259 constexpr _Iterator&
6260 operator-=(difference_type __x)
6261 requires random_access_range<_Base>
6262 { return *this += -__x; }
6263
6264 constexpr value_type
6265 operator[](difference_type __n) const
6266 requires random_access_range<_Base>
6267 { return *(*this + __n); }
6268
6269 friend constexpr bool
6270 operator==(const _Iterator& __x, const _Iterator& __y)
6271 { return __x._M_current == __y._M_current; }
6272
6273 friend constexpr bool
6274 operator==(const _Iterator& __x, default_sentinel_t)
6275 { return __x._M_current == __x._M_end; }
6276
6277 friend constexpr bool
6278 operator<(const _Iterator& __x, const _Iterator& __y)
6279 requires random_access_range<_Base>
6280 { return __x._M_current > __y._M_current; }
6281
6282 friend constexpr bool
6283 operator>(const _Iterator& __x, const _Iterator& __y)
6284 requires random_access_range<_Base>
6285 { return __y < __x; }
6286
6287 friend constexpr bool
6288 operator<=(const _Iterator& __x, const _Iterator& __y)
6289 requires random_access_range<_Base>
6290 { return !(__y < __x); }
6291
6292 friend constexpr bool
6293 operator>=(const _Iterator& __x, const _Iterator& __y)
6294 requires random_access_range<_Base>
6295 { return !(__x < __y); }
6296
6297 friend constexpr auto
6298 operator<=>(const _Iterator& __x, const _Iterator& __y)
6299 requires random_access_range<_Base>
6300 && three_way_comparable<iterator_t<_Base>>
6301 { return __x._M_current <=> __y._M_current; }
6302
6303 friend constexpr _Iterator
6304 operator+(const _Iterator& __i, difference_type __n)
6305 requires random_access_range<_Base>
6306 {
6307 auto __r = __i;
6308 __r += __n;
6309 return __r;
6310 }
6311
6312 friend constexpr _Iterator
6313 operator+(difference_type __n, const _Iterator& __i)
6314 requires random_access_range<_Base>
6315 {
6316 auto __r = __i;
6317 __r += __n;
6318 return __r;
6319 }
6320
6321 friend constexpr _Iterator
6322 operator-(const _Iterator& __i, difference_type __n)
6323 requires random_access_range<_Base>
6324 {
6325 auto __r = __i;
6326 __r -= __n;
6327 return __r;
6328 }
6329
6330 friend constexpr difference_type
6331 operator-(const _Iterator& __x, const _Iterator& __y)
6332 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
6333 {
6334 return (__x._M_current - __y._M_current
6335 + __x._M_missing - __y._M_missing) / __x._M_n;
6336 }
6337
6338 friend constexpr difference_type
6339 operator-(default_sentinel_t __y, const _Iterator& __x)
6340 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
6341 { return __detail::__div_ceil(__x._M_end - __x._M_current, __x._M_n); }
6342
6343 friend constexpr difference_type
6344 operator-(const _Iterator& __x, default_sentinel_t __y)
6345 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
6346 { return -(__y - __x); }
6347 };
6348
6349 namespace views
6350 {
6351 namespace __detail
6352 {
6353 template<typename _Range, typename _Dp>
6354 concept __can_chunk_view
6355 = requires { chunk_view(std::declval<_Range>(), std::declval<_Dp>()); };
6356 }
6357
6358 struct _Chunk : __adaptor::_RangeAdaptor<_Chunk>
6359 {
6360 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
6361 requires __detail::__can_chunk_view<_Range, _Dp>
6362 constexpr auto
6363 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
6364 { return chunk_view(std::forward<_Range>(__r), __n); }
6365
6366 using __adaptor::_RangeAdaptor<_Chunk>::operator();
6367 static constexpr int _S_arity = 2;
6368 static constexpr bool _S_has_simple_extra_args = true;
6369 };
6370
6371 inline constexpr _Chunk chunk;
6372 }
6373
6374#define __cpp_lib_ranges_slide 202202L
6375
6376 namespace __detail
6377 {
6378 template<typename _Vp>
6379 concept __slide_caches_nothing = random_access_range<_Vp> && sized_range<_Vp>;
6380
6381 template<typename _Vp>
6382 concept __slide_caches_last
6383 = !__slide_caches_nothing<_Vp> && bidirectional_range<_Vp> && common_range<_Vp>;
6384
6385 template<typename _Vp>
6386 concept __slide_caches_first
6387 = !__slide_caches_nothing<_Vp> && !__slide_caches_last<_Vp>;
6388 }
6389
6390 template<forward_range _Vp>
6391 requires view<_Vp>
6392 class slide_view : public view_interface<slide_view<_Vp>>
6393 {
6394 _Vp _M_base;
6395 range_difference_t<_Vp> _M_n;
6396 [[no_unique_address]]
6397 __detail::__maybe_present_t<__detail::__slide_caches_first<_Vp>,
6398 __detail::_CachedPosition<_Vp>> _M_cached_begin;
6399 [[no_unique_address]]
6400 __detail::__maybe_present_t<__detail::__slide_caches_last<_Vp>,
6401 __detail::_CachedPosition<_Vp>> _M_cached_end;
6402
6403 template<bool> class _Iterator;
6404 class _Sentinel;
6405
6406 public:
6407 constexpr explicit
6408 slide_view(_Vp __base, range_difference_t<_Vp> __n)
6409 : _M_base(std::move(__base)), _M_n(__n)
6410 { __glibcxx_assert(__n > 0); }
6411
6412 constexpr auto
6413 begin() requires (!(__detail::__simple_view<_Vp>
6414 && __detail::__slide_caches_nothing<const _Vp>))
6415 {
6416 if constexpr (__detail::__slide_caches_first<_Vp>)
6417 {
6418 iterator_t<_Vp> __it;
6419 if (_M_cached_begin._M_has_value())
6420 __it = _M_cached_begin._M_get(_M_base);
6421 else
6422 {
6423 __it = ranges::next(ranges::begin(_M_base), _M_n - 1, ranges::end(_M_base));
6424 _M_cached_begin._M_set(_M_base, __it);
6425 }
6426 return _Iterator<false>(ranges::begin(_M_base), std::move(__it), _M_n);
6427 }
6428 else
6429 return _Iterator<false>(ranges::begin(_M_base), _M_n);
6430 }
6431
6432 constexpr auto
6433 begin() const requires __detail::__slide_caches_nothing<const _Vp>
6434 { return _Iterator<true>(ranges::begin(_M_base), _M_n); }
6435
6436 constexpr auto
6437 end() requires (!(__detail::__simple_view<_Vp>
6438 && __detail::__slide_caches_nothing<const _Vp>))
6439 {
6440 if constexpr (__detail::__slide_caches_nothing<_Vp>)
6441 return _Iterator<false>(ranges::begin(_M_base) + range_difference_t<_Vp>(size()),
6442 _M_n);
6443 else if constexpr (__detail::__slide_caches_last<_Vp>)
6444 {
6445 iterator_t<_Vp> __it;
6446 if (_M_cached_end._M_has_value())
6447 __it = _M_cached_end._M_get(_M_base);
6448 else
6449 {
6450 __it = ranges::prev(ranges::end(_M_base), _M_n - 1, ranges::begin(_M_base));
6451 _M_cached_end._M_set(_M_base, __it);
6452 }
6453 return _Iterator<false>(std::move(__it), _M_n);
6454 }
6455 else if constexpr (common_range<_Vp>)
6456 return _Iterator<false>(ranges::end(_M_base), ranges::end(_M_base), _M_n);
6457 else
6458 return _Sentinel(ranges::end(_M_base));
6459 }
6460
6461 constexpr auto
6462 end() const requires __detail::__slide_caches_nothing<const _Vp>
6463 { return begin() + range_difference_t<const _Vp>(size()); }
6464
6465 constexpr auto
6466 size() requires sized_range<_Vp>
6467 {
6468 auto __sz = ranges::distance(_M_base) - _M_n + 1;
6469 if (__sz < 0)
6470 __sz = 0;
6471 return __detail::__to_unsigned_like(__sz);
6472 }
6473
6474 constexpr auto
6475 size() const requires sized_range<const _Vp>
6476 {
6477 auto __sz = ranges::distance(_M_base) - _M_n + 1;
6478 if (__sz < 0)
6479 __sz = 0;
6480 return __detail::__to_unsigned_like(__sz);
6481 }
6482 };
6483
6484 template<typename _Range>
6485 slide_view(_Range&&, range_difference_t<_Range>) -> slide_view<views::all_t<_Range>>;
6486
6487 template<typename _Vp>
6488 inline constexpr bool enable_borrowed_range<slide_view<_Vp>>
6489 = enable_borrowed_range<_Vp>;
6490
6491 template<forward_range _Vp>
6492 requires view<_Vp>
6493 template<bool _Const>
6494 class slide_view<_Vp>::_Iterator
6495 {
6496 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6497 static constexpr bool _S_last_elt_present
6498 = __detail::__slide_caches_first<_Base>;
6499
6500 iterator_t<_Base> _M_current = iterator_t<_Base>();
6501 [[no_unique_address]]
6502 __detail::__maybe_present_t<_S_last_elt_present, iterator_t<_Base>>
6503 _M_last_elt = decltype(_M_last_elt)();
6504 range_difference_t<_Base> _M_n = 0;
6505
6506 constexpr
6507 _Iterator(iterator_t<_Base> __current, range_difference_t<_Base> __n)
6508 requires (!_S_last_elt_present)
6509 : _M_current(__current), _M_n(__n)
6510 { }
6511
6512 constexpr
6513 _Iterator(iterator_t<_Base> __current, iterator_t<_Base> __last_elt,
6514 range_difference_t<_Base> __n)
6515 requires _S_last_elt_present
6516 : _M_current(__current), _M_last_elt(__last_elt), _M_n(__n)
6517 { }
6518
6519 static auto
6520 _S_iter_concept()
6521 {
6522 if constexpr (random_access_range<_Base>)
6523 return random_access_iterator_tag{};
6524 else if constexpr (bidirectional_range<_Base>)
6525 return bidirectional_iterator_tag{};
6526 else
6527 return forward_iterator_tag{};
6528 }
6529
6530 friend slide_view;
6531 friend slide_view::_Sentinel;
6532
6533 public:
6534 using iterator_category = input_iterator_tag;
6535 using iterator_concept = decltype(_S_iter_concept());
6536 using value_type = decltype(views::counted(_M_current, _M_n));
6537 using difference_type = range_difference_t<_Base>;
6538
6539 _Iterator() = default;
6540
6541 constexpr
6542 _Iterator(_Iterator<!_Const> __i)
6543 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
6544 : _M_current(std::move(__i._M_current)), _M_n(__i._M_n)
6545 { }
6546
6547 constexpr auto
6548 operator*() const
6549 { return views::counted(_M_current, _M_n); }
6550
6551 constexpr _Iterator&
6552 operator++()
6553 {
6554 ++_M_current;
6555 if constexpr (_S_last_elt_present)
6556 ++_M_last_elt;
6557 return *this;
6558 }
6559
6560 constexpr _Iterator
6561 operator++(int)
6562 {
6563 auto __tmp = *this;
6564 ++*this;
6565 return __tmp;
6566 }
6567
6568 constexpr _Iterator&
6569 operator--() requires bidirectional_range<_Base>
6570 {
6571 --_M_current;
6572 if constexpr (_S_last_elt_present)
6573 --_M_last_elt;
6574 return *this;
6575 }
6576
6577 constexpr _Iterator
6578 operator--(int) requires bidirectional_range<_Base>
6579 {
6580 auto __tmp = *this;
6581 --*this;
6582 return __tmp;
6583 }
6584
6585 constexpr _Iterator&
6586 operator+=(difference_type __x)
6587 requires random_access_range<_Base>
6588 {
6589 _M_current += __x;
6590 if constexpr (_S_last_elt_present)
6591 _M_last_elt += __x;
6592 return *this;
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 auto
6606 operator[](difference_type __n) const
6607 requires random_access_range<_Base>
6608 { return views::counted(_M_current + __n, _M_n); }
6609
6610 friend constexpr bool
6611 operator==(const _Iterator& __x, const _Iterator& __y)
6612 {
6613 if constexpr (_S_last_elt_present)
6614 return __x._M_last_elt == __y._M_last_elt;
6615 else
6616 return __x._M_current == __y._M_current;
6617 }
6618
6619 friend constexpr bool
6620 operator<(const _Iterator& __x, const _Iterator& __y)
6621 requires random_access_range<_Base>
6622 { return __x._M_current < __y._M_current; }
6623
6624 friend constexpr bool
6625 operator>(const _Iterator& __x, const _Iterator& __y)
6626 requires random_access_range<_Base>
6627 { return __y < __x; }
6628
6629 friend constexpr bool
6630 operator<=(const _Iterator& __x, const _Iterator& __y)
6631 requires random_access_range<_Base>
6632 { return !(__y < __x); }
6633
6634 friend constexpr bool
6635 operator>=(const _Iterator& __x, const _Iterator& __y)
6636 requires random_access_range<_Base>
6637 { return !(__x < __y); }
6638
6639 friend constexpr auto
6640 operator<=>(const _Iterator& __x, const _Iterator& __y)
6641 requires random_access_range<_Base>
6642 && three_way_comparable<iterator_t<_Base>>
6643 { return __x._M_current <=> __y._M_current; }
6644
6645 friend constexpr _Iterator
6646 operator+(const _Iterator& __i, difference_type __n)
6647 requires random_access_range<_Base>
6648 {
6649 auto __r = __i;
6650 __r += __n;
6651 return __r;
6652 }
6653
6654 friend constexpr _Iterator
6655 operator+(difference_type __n, const _Iterator& __i)
6656 requires random_access_range<_Base>
6657 {
6658 auto __r = __i;
6659 __r += __n;
6660 return __r;
6661 }
6662
6663 friend constexpr _Iterator
6664 operator-(const _Iterator& __i, difference_type __n)
6665 requires random_access_range<_Base>
6666 {
6667 auto __r = __i;
6668 __r -= __n;
6669 return __r;
6670 }
6671
6672 friend constexpr difference_type
6673 operator-(const _Iterator& __x, const _Iterator& __y)
6674 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
6675 {
6676 if constexpr (_S_last_elt_present)
6677 return __x._M_last_elt - __y._M_last_elt;
6678 else
6679 return __x._M_current - __y._M_current;
6680 }
6681 };
6682
6683 template<forward_range _Vp>
6684 requires view<_Vp>
6685 class slide_view<_Vp>::_Sentinel
6686 {
6687 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
6688
6689 constexpr explicit
6690 _Sentinel(sentinel_t<_Vp> __end)
6691 : _M_end(__end)
6692 { }
6693
6694 friend slide_view;
6695
6696 public:
6697 _Sentinel() = default;
6698
6699 friend constexpr bool
6700 operator==(const _Iterator<false>& __x, const _Sentinel& __y)
6701 { return __x._M_last_elt == __y._M_end; }
6702
6703 friend constexpr range_difference_t<_Vp>
6704 operator-(const _Iterator<false>& __x, const _Sentinel& __y)
6705 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6706 { return __x._M_last_elt - __y._M_end; }
6707
6708 friend constexpr range_difference_t<_Vp>
6709 operator-(const _Sentinel& __y, const _Iterator<false>& __x)
6710 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6711 { return __y._M_end -__x._M_last_elt; }
6712 };
6713
6714 namespace views
6715 {
6716 namespace __detail
6717 {
6718 template<typename _Range, typename _Dp>
6719 concept __can_slide_view
6720 = requires { slide_view(std::declval<_Range>(), std::declval<_Dp>()); };
6721 }
6722
6723 struct _Slide : __adaptor::_RangeAdaptor<_Slide>
6724 {
6725 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
6726 requires __detail::__can_slide_view<_Range, _Dp>
6727 constexpr auto
6728 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
6729 { return slide_view(std::forward<_Range>(__r), __n); }
6730
6731 using __adaptor::_RangeAdaptor<_Slide>::operator();
6732 static constexpr int _S_arity = 2;
6733 static constexpr bool _S_has_simple_extra_args = true;
6734 };
6735
6736 inline constexpr _Slide slide;
6737 }
6738
6739#define __cpp_lib_ranges_chunk_by 202202L
6740
6741 template<forward_range _Vp,
6742 indirect_binary_predicate<iterator_t<_Vp>, iterator_t<_Vp>> _Pred>
6743 requires view<_Vp> && is_object_v<_Pred>
6744 class chunk_by_view : public view_interface<chunk_by_view<_Vp, _Pred>>
6745 {
6746 _Vp _M_base = _Vp();
6747 __detail::__box<_Pred> _M_pred;
6748 __detail::_CachedPosition<_Vp> _M_cached_begin;
6749
6750 constexpr iterator_t<_Vp>
6751 _M_find_next(iterator_t<_Vp> __current)
6752 {
6753 __glibcxx_assert(_M_pred.has_value());
6754 auto __pred = [this]<typename _Tp, typename _Up>(_Tp&& __x, _Up&& __y) {
6755 return !bool((*_M_pred)(std::forward<_Tp>(__x), std::forward<_Up>(__y)));
6756 };
6757 auto __it = ranges::adjacent_find(__current, ranges::end(_M_base), __pred);
6758 return ranges::next(__it, 1, ranges::end(_M_base));
6759 }
6760
6761 constexpr iterator_t<_Vp>
6762 _M_find_prev(iterator_t<_Vp> __current) requires bidirectional_range<_Vp>
6763 {
6764 __glibcxx_assert(_M_pred.has_value());
6765 auto __pred = [this]<typename _Tp, typename _Up>(_Tp&& __x, _Up&& __y) {
6766 return !bool((*_M_pred)(std::forward<_Up>(__y), std::forward<_Tp>(__x)));
6767 };
6768 auto __rbegin = std::make_reverse_iterator(__current);
6769 auto __rend = std::make_reverse_iterator(ranges::begin(_M_base));
6770 __glibcxx_assert(__rbegin != __rend);
6771 auto __it = ranges::adjacent_find(__rbegin, __rend, __pred).base();
6772 return ranges::prev(__it, 1, ranges::begin(_M_base));
6773 }
6774
6775 class _Iterator;
6776
6777 public:
6778 chunk_by_view() requires (default_initializable<_Vp>
6779 && default_initializable<_Pred>)
6780 = default;
6781
6782 constexpr explicit
6783 chunk_by_view(_Vp __base, _Pred __pred)
6784 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
6785 { }
6786
6787 constexpr _Vp
6788 base() const & requires copy_constructible<_Vp>
6789 { return _M_base; }
6790
6791 constexpr _Vp
6792 base() &&
6793 { return std::move(_M_base); }
6794
6795 constexpr const _Pred&
6796 pred() const
6797 { return *_M_pred; }
6798
6799 constexpr _Iterator
6800 begin()
6801 {
6802 __glibcxx_assert(_M_pred.has_value());
6803 iterator_t<_Vp> __it;
6804 if (_M_cached_begin._M_has_value())
6805 __it = _M_cached_begin._M_get(_M_base);
6806 else
6807 {
6808 __it = _M_find_next(ranges::begin(_M_base));
6809 _M_cached_begin._M_set(_M_base, __it);
6810 }
6811 return _Iterator(*this, ranges::begin(_M_base), __it);
6812 }
6813
6814 constexpr auto
6815 end()
6816 {
6817 if constexpr (common_range<_Vp>)
6818 return _Iterator(*this, ranges::end(_M_base), ranges::end(_M_base));
6819 else
6820 return default_sentinel;
6821 }
6822 };
6823
6824 template<typename _Range, typename _Pred>
6825 chunk_by_view(_Range&&, _Pred) -> chunk_by_view<views::all_t<_Range>, _Pred>;
6826
6827 template<forward_range _Vp,
6828 indirect_binary_predicate<iterator_t<_Vp>, iterator_t<_Vp>> _Pred>
6829 requires view<_Vp> && is_object_v<_Pred>
6830 class chunk_by_view<_Vp, _Pred>::_Iterator
6831 {
6832 chunk_by_view* _M_parent = nullptr;
6833 iterator_t<_Vp> _M_current = iterator_t<_Vp>();
6834 iterator_t<_Vp> _M_next = iterator_t<_Vp>();
6835
6836 constexpr
6837 _Iterator(chunk_by_view& __parent, iterator_t<_Vp> __current, iterator_t<_Vp> __next)
6838 : _M_parent(std::__addressof(__parent)), _M_current(__current), _M_next(__next)
6839 { }
6840
6841 static auto
6842 _S_iter_concept()
6843 {
6844 if constexpr (bidirectional_range<_Vp>)
6845 return bidirectional_iterator_tag{};
6846 else
6847 return forward_iterator_tag{};
6848 }
6849
6850 friend chunk_by_view;
6851
6852 public:
6853 using value_type = subrange<iterator_t<_Vp>>;
6854 using difference_type = range_difference_t<_Vp>;
6855 using iterator_category = input_iterator_tag;
6856 using iterator_concept = decltype(_S_iter_concept());
6857
6858 _Iterator() = default;
6859
6860 constexpr value_type
6861 operator*() const
6862 {
6863 __glibcxx_assert(_M_current != _M_next);
6864 return ranges::subrange(_M_current, _M_next);
6865 }
6866
6867 constexpr _Iterator&
6868 operator++()
6869 {
6870 __glibcxx_assert(_M_current != _M_next);
6871 _M_current = _M_next;
6872 _M_next = _M_parent->_M_find_next(_M_current);
6873 return *this;
6874 }
6875
6876 constexpr _Iterator
6877 operator++(int)
6878 {
6879 auto __tmp = *this;
6880 ++*this;
6881 return __tmp;
6882 }
6883
6884 constexpr _Iterator&
6885 operator--() requires bidirectional_range<_Vp>
6886 {
6887 _M_next = _M_current;
6888 _M_current = _M_parent->_M_find_prev(_M_next);
6889 return *this;
6890 }
6891
6892 constexpr _Iterator
6893 operator--(int) requires bidirectional_range<_Vp>
6894 {
6895 auto __tmp = *this;
6896 --*this;
6897 return __tmp;
6898 }
6899
6900 friend constexpr bool
6901 operator==(const _Iterator& __x, const _Iterator& __y)
6902 { return __x._M_current == __y._M_current; }
6903
6904 friend constexpr bool
6905 operator==(const _Iterator& __x, default_sentinel_t)
6906 { return __x._M_current == __x._M_next; }
6907 };
6908
6909 namespace views
6910 {
6911 namespace __detail
6912 {
6913 template<typename _Range, typename _Pred>
6914 concept __can_chunk_by_view
6915 = requires { chunk_by_view(std::declval<_Range>(), std::declval<_Pred>()); };
6916 }
6917
6918 struct _ChunkBy : __adaptor::_RangeAdaptor<_ChunkBy>
6919 {
6920 template<viewable_range _Range, typename _Pred>
6921 requires __detail::__can_chunk_by_view<_Range, _Pred>
6922 constexpr auto
6923 operator() [[nodiscard]] (_Range&& __r, _Pred&& __pred) const
6924 { return chunk_by_view(std::forward<_Range>(__r), std::forward<_Pred>(__pred)); }
6925
6926 using __adaptor::_RangeAdaptor<_ChunkBy>::operator();
6927 static constexpr int _S_arity = 2;
6928 static constexpr bool _S_has_simple_extra_args = true;
6929 };
6930
6931 inline constexpr _ChunkBy chunk_by;
6932 }
6933
6934#define __cpp_lib_ranges_join_with 202202L
6935
6936 namespace __detail
6937 {
6938 template<typename _Range, typename _Pattern>
6939 concept __compatible_joinable_ranges
6940 = common_with<range_value_t<_Range>, range_value_t<_Pattern>>
6941 && common_reference_with<range_reference_t<_Range>,
6942 range_reference_t<_Pattern>>
6943 && common_reference_with<range_rvalue_reference_t<_Range>,
6944 range_rvalue_reference_t<_Pattern>>;
6945
6946 template<typename _Range>
6947 concept __bidirectional_common = bidirectional_range<_Range> && common_range<_Range>;
6948 }
6949
6950 template<input_range _Vp, forward_range _Pattern>
6951 requires view<_Vp> && view<_Pattern>
6952 && input_range<range_reference_t<_Vp>>
6953 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
6954 class join_with_view : public view_interface<join_with_view<_Vp, _Pattern>>
6955 {
6956 using _InnerRange = range_reference_t<_Vp>;
6957
6958 _Vp _M_base = _Vp();
6959 __detail::__non_propagating_cache<remove_cv_t<_InnerRange>> _M_inner;
6960 _Pattern _M_pattern = _Pattern();
6961
6962 template<bool _Const> using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6963 template<bool _Const> using _InnerBase = range_reference_t<_Base<_Const>>;
6964 template<bool _Const> using _PatternBase = __detail::__maybe_const_t<_Const, _Pattern>;
6965
6966 template<bool _Const> using _OuterIter = iterator_t<_Base<_Const>>;
6967 template<bool _Const> using _InnerIter = iterator_t<_InnerBase<_Const>>;
6968 template<bool _Const> using _PatternIter = iterator_t<_PatternBase<_Const>>;
6969
6970 template<bool _Const>
6971 static constexpr bool _S_ref_is_glvalue = is_reference_v<_InnerBase<_Const>>;
6972
6973 template<bool _Const>
6974 struct __iter_cat
6975 { };
6976
6977 template<bool _Const>
6978 requires _S_ref_is_glvalue<_Const>
6979 && forward_range<_Base<_Const>>
6980 && forward_range<_InnerBase<_Const>>
6981 struct __iter_cat<_Const>
6982 {
6983 private:
6984 static auto
6985 _S_iter_cat()
6986 {
6987 using _OuterIter = join_with_view::_OuterIter<_Const>;
6988 using _InnerIter = join_with_view::_InnerIter<_Const>;
6989 using _PatternIter = join_with_view::_PatternIter<_Const>;
6990 using _OuterCat = typename iterator_traits<_OuterIter>::iterator_category;
6991 using _InnerCat = typename iterator_traits<_InnerIter>::iterator_category;
6992 using _PatternCat = typename iterator_traits<_PatternIter>::iterator_category;
6993 if constexpr (!is_lvalue_reference_v<common_reference_t<iter_reference_t<_InnerIter>,
6994 iter_reference_t<_PatternIter>>>)
6995 return input_iterator_tag{};
6996 else if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag>
6997 && derived_from<_InnerCat, bidirectional_iterator_tag>
6998 && derived_from<_PatternCat, bidirectional_iterator_tag>
6999 && common_range<_InnerBase<_Const>>
7000 && common_range<_PatternBase<_Const>>)
7001 return bidirectional_iterator_tag{};
7002 else if constexpr (derived_from<_OuterCat, forward_iterator_tag>
7003 && derived_from<_InnerCat, forward_iterator_tag>
7004 && derived_from<_PatternCat, forward_iterator_tag>)
7005 return forward_iterator_tag{};
7006 else
7007 return input_iterator_tag{};
7008 }
7009 public:
7010 using iterator_category = decltype(_S_iter_cat());
7011 };
7012
7013 template<bool> struct _Iterator;
7014 template<bool> struct _Sentinel;
7015
7016 public:
7017 join_with_view() requires (default_initializable<_Vp>
7018 && default_initializable<_Pattern>)
7019 = default;
7020
7021 constexpr
7022 join_with_view(_Vp __base, _Pattern __pattern)
7023 : _M_base(std::move(__base)), _M_pattern(std::move(__pattern))
7024 { }
7025
7026 template<input_range _Range>
7027 requires constructible_from<_Vp, views::all_t<_Range>>
7028 && constructible_from<_Pattern, single_view<range_value_t<_InnerRange>>>
7029 constexpr
7030 join_with_view(_Range&& __r, range_value_t<_InnerRange> __e)
7031 : _M_base(views::all(std::forward<_Range>(__r))),
7032 _M_pattern(views::single(std::move(__e)))
7033 { }
7034
7035 constexpr _Vp
7036 base() const& requires copy_constructible<_Vp>
7037 { return _M_base; }
7038
7039 constexpr _Vp
7040 base() &&
7041 { return std::move(_M_base); }
7042
7043 constexpr auto
7044 begin()
7045 {
7046 constexpr bool __use_const = is_reference_v<_InnerRange>
7047 && __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
7048 return _Iterator<__use_const>{*this, ranges::begin(_M_base)};
7049 }
7050
7051 constexpr auto
7052 begin() const
7053 requires input_range<const _Vp>
7054 && forward_range<const _Pattern>
7055 && is_reference_v<range_reference_t<const _Vp>>
7056 { return _Iterator<true>{*this, ranges::begin(_M_base)}; }
7057
7058 constexpr auto
7059 end()
7060 {
7061 constexpr bool __use_const
7062 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
7063 if constexpr (is_reference_v<_InnerRange>
7064 && forward_range<_Vp> && common_range<_Vp>
7065 && forward_range<_InnerRange> && common_range<_InnerRange>)
7066 return _Iterator<__use_const>{*this, ranges::end(_M_base)};
7067 else
7068 return _Sentinel<__use_const>{*this};
7069 }
7070
7071 constexpr auto
7072 end() const
7073 requires input_range<const _Vp>
7074 && forward_range<const _Pattern>
7075 && is_reference_v<range_reference_t<const _Vp>>
7076 {
7077 using _InnerConstRange = range_reference_t<const _Vp>;
7078 if constexpr (forward_range<const _Vp>
7079 && forward_range<_InnerConstRange>
7080 && common_range<const _Vp>
7081 && common_range<_InnerConstRange>)
7082 return _Iterator<true>{*this, ranges::end(_M_base)};
7083 else
7084 return _Sentinel<true>{*this};
7085 }
7086 };
7087
7088 template<typename _Range, typename _Pattern>
7089 join_with_view(_Range&&, _Pattern&&)
7090 -> join_with_view<views::all_t<_Range>, views::all_t<_Pattern>>;
7091
7092 template<input_range _Range>
7093 join_with_view(_Range&&, range_value_t<range_reference_t<_Range>>)
7094 -> join_with_view<views::all_t<_Range>,
7095 single_view<range_value_t<range_reference_t<_Range>>>>;
7096
7097 template<input_range _Vp, forward_range _Pattern>
7098 requires view<_Vp> && view<_Pattern>
7099 && input_range<range_reference_t<_Vp>>
7100 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7101 template<bool _Const>
7102 class join_with_view<_Vp, _Pattern>::_Iterator : public __iter_cat<_Const>
7103 {
7104 using _Parent = __detail::__maybe_const_t<_Const, join_with_view>;
7105 using _Base = join_with_view::_Base<_Const>;
7106 using _InnerBase = join_with_view::_InnerBase<_Const>;
7107 using _PatternBase = join_with_view::_PatternBase<_Const>;
7108
7109 using _OuterIter = join_with_view::_OuterIter<_Const>;
7110 using _InnerIter = join_with_view::_InnerIter<_Const>;
7111 using _PatternIter = join_with_view::_PatternIter<_Const>;
7112
7113 static constexpr bool _S_ref_is_glvalue = join_with_view::_S_ref_is_glvalue<_Const>;
7114
7115 _Parent* _M_parent = nullptr;
7116 _OuterIter _M_outer_it = _OuterIter();
7117 variant<_PatternIter, _InnerIter> _M_inner_it;
7118
7119 constexpr
7120 _Iterator(_Parent& __parent, iterator_t<_Base> __outer)
7121 : _M_parent(std::__addressof(__parent)), _M_outer_it(std::move(__outer))
7122 {
7123 if (_M_outer_it != ranges::end(_M_parent->_M_base))
7124 {
7125 auto&& __inner = _M_update_inner(_M_outer_it);
7126 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7127 _M_satisfy();
7128 }
7129 }
7130
7131 constexpr auto&&
7132 _M_update_inner(const _OuterIter& __x)
7133 {
7134 if constexpr (_S_ref_is_glvalue)
7135 return *__x;
7136 else
7137 return _M_parent->_M_inner._M_emplace_deref(__x);
7138 }
7139
7140 constexpr auto&&
7141 _M_get_inner(const _OuterIter& __x)
7142 {
7143 if constexpr (_S_ref_is_glvalue)
7144 return *__x;
7145 else
7146 return *_M_parent->_M_inner;
7147 }
7148
7149 constexpr void
7150 _M_satisfy()
7151 {
7152 while (true)
7153 {
7154 if (_M_inner_it.index() == 0)
7155 {
7156 if (std::get<0>(_M_inner_it) != ranges::end(_M_parent->_M_pattern))
7157 break;
7158
7159 auto&& __inner = _M_update_inner(_M_outer_it);
7160 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7161 }
7162 else
7163 {
7164 auto&& __inner = _M_get_inner(_M_outer_it);
7165 if (std::get<1>(_M_inner_it) != ranges::end(__inner))
7166 break;
7167
7168 if (++_M_outer_it == ranges::end(_M_parent->_M_base))
7169 {
7170 if constexpr (_S_ref_is_glvalue)
7171 _M_inner_it.template emplace<0>();
7172 break;
7173 }
7174
7175 _M_inner_it.template emplace<0>(ranges::begin(_M_parent->_M_pattern));
7176 }
7177 }
7178 }
7179
7180 static auto
7181 _S_iter_concept()
7182 {
7183 if constexpr (_S_ref_is_glvalue
7184 && bidirectional_range<_Base>
7185 && __detail::__bidirectional_common<_InnerBase>
7186 && __detail::__bidirectional_common<_PatternBase>)
7187 return bidirectional_iterator_tag{};
7188 else if constexpr (_S_ref_is_glvalue
7189 && forward_range<_Base>
7190 && forward_range<_InnerBase>)
7191 return forward_iterator_tag{};
7192 else
7193 return input_iterator_tag{};
7194 }
7195
7196 friend join_with_view;
7197
7198 public:
7199 using iterator_concept = decltype(_S_iter_concept());
7200 // iterator_category defined in join_with_view::__iter_cat
7201 using value_type = common_type_t<iter_value_t<_InnerIter>,
7202 iter_value_t<_PatternIter>>;
7203 using difference_type = common_type_t<iter_difference_t<_OuterIter>,
7204 iter_difference_t<_InnerIter>,
7205 iter_difference_t<_PatternIter>>;
7206
7207 _Iterator() requires default_initializable<_OuterIter> = default;
7208
7209 constexpr
7210 _Iterator(_Iterator<!_Const> __i)
7211 requires _Const
7212 && convertible_to<iterator_t<_Vp>, _OuterIter>
7213 && convertible_to<iterator_t<_InnerRange>, _InnerIter>
7214 && convertible_to<iterator_t<_Pattern>, _PatternIter>
7215 : _M_parent(__i._M_parent),
7216 _M_outer_it(std::move(__i._M_outer_it))
7217 {
7218 if (__i._M_inner_it.index() == 0)
7219 _M_inner_it.template emplace<0>(std::get<0>(std::move(__i._M_inner_it)));
7220 else
7221 _M_inner_it.template emplace<1>(std::get<1>(std::move(__i._M_inner_it)));
7222 }
7223
7224 constexpr common_reference_t<iter_reference_t<_InnerIter>,
7225 iter_reference_t<_PatternIter>>
7226 operator*() const
7227 {
7228 if (_M_inner_it.index() == 0)
7229 return *std::get<0>(_M_inner_it);
7230 else
7231 return *std::get<1>(_M_inner_it);
7232 }
7233
7234 constexpr _Iterator&
7235 operator++()
7236 {
7237 if (_M_inner_it.index() == 0)
7238 ++std::get<0>(_M_inner_it);
7239 else
7240 ++std::get<1>(_M_inner_it);
7241 _M_satisfy();
7242 return *this;
7243 }
7244
7245 constexpr void
7246 operator++(int)
7247 { ++*this; }
7248
7249 constexpr _Iterator
7250 operator++(int)
7251 requires _S_ref_is_glvalue
7252 && forward_iterator<_OuterIter> && forward_iterator<_InnerIter>
7253 {
7254 _Iterator __tmp = *this;
7255 ++*this;
7256 return __tmp;
7257 }
7258
7259 constexpr _Iterator&
7260 operator--()
7261 requires _S_ref_is_glvalue
7262 && bidirectional_range<_Base>
7263 && __detail::__bidirectional_common<_InnerBase>
7264 && __detail::__bidirectional_common<_PatternBase>
7265 {
7266 if (_M_outer_it == ranges::end(_M_parent->_M_base))
7267 {
7268 auto&& __inner = *--_M_outer_it;
7269 _M_inner_it.template emplace<1>(ranges::end(__inner));
7270 }
7271
7272 while (true)
7273 {
7274 if (_M_inner_it.index() == 0)
7275 {
7276 auto& __it = std::get<0>(_M_inner_it);
7277 if (__it == ranges::begin(_M_parent->_M_pattern))
7278 {
7279 auto&& __inner = *--_M_outer_it;
7280 _M_inner_it.template emplace<1>(ranges::end(__inner));
7281 }
7282 else
7283 break;
7284 }
7285 else
7286 {
7287 auto& __it = std::get<1>(_M_inner_it);
7288 auto&& __inner = *_M_outer_it;
7289 if (__it == ranges::begin(__inner))
7290 _M_inner_it.template emplace<0>(ranges::end(_M_parent->_M_pattern));
7291 else
7292 break;
7293 }
7294 }
7295
7296 if (_M_inner_it.index() == 0)
7297 --std::get<0>(_M_inner_it);
7298 else
7299 --std::get<1>(_M_inner_it);
7300 return *this;
7301 }
7302
7303 constexpr _Iterator
7304 operator--(int)
7305 requires _S_ref_is_glvalue && bidirectional_range<_Base>
7306 && __detail::__bidirectional_common<_InnerBase>
7307 && __detail::__bidirectional_common<_PatternBase>
7308 {
7309 _Iterator __tmp = *this;
7310 --*this;
7311 return __tmp;
7312 }
7313
7314 friend constexpr bool
7315 operator==(const _Iterator& __x, const _Iterator& __y)
7316 requires _S_ref_is_glvalue
7317 && equality_comparable<_OuterIter> && equality_comparable<_InnerIter>
7318 { return __x._M_outer_it == __y._M_outer_it && __x._M_inner_it ==__y._M_inner_it; }
7319
7320 friend constexpr common_reference_t<iter_rvalue_reference_t<_InnerIter>,
7321 iter_rvalue_reference_t<_PatternIter>>
7322 iter_move(const _Iterator& __x)
7323 {
7324 if (__x._M_inner_it.index() == 0)
7325 return ranges::iter_move(std::get<0>(__x._M_inner_it));
7326 else
7327 return ranges::iter_move(std::get<1>(__x._M_inner_it));
7328 }
7329
7330 friend constexpr void
7331 iter_swap(const _Iterator& __x, const _Iterator& __y)
7332 requires indirectly_swappable<_InnerIter, _PatternIter>
7333 {
7334 if (__x._M_inner_it.index() == 0)
7335 {
7336 if (__y._M_inner_it.index() == 0)
7337 ranges::iter_swap(std::get<0>(__x._M_inner_it), std::get<0>(__y._M_inner_it));
7338 else
7339 ranges::iter_swap(std::get<0>(__x._M_inner_it), std::get<1>(__y._M_inner_it));
7340 }
7341 else
7342 {
7343 if (__y._M_inner_it.index() == 0)
7344 ranges::iter_swap(std::get<1>(__x._M_inner_it), std::get<0>(__y._M_inner_it));
7345 else
7346 ranges::iter_swap(std::get<1>(__x._M_inner_it), std::get<1>(__y._M_inner_it));
7347 }
7348 }
7349 };
7350
7351 template<input_range _Vp, forward_range _Pattern>
7352 requires view<_Vp> && view<_Pattern>
7353 && input_range<range_reference_t<_Vp>>
7354 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7355 template<bool _Const>
7356 class join_with_view<_Vp, _Pattern>::_Sentinel
7357 {
7358 using _Parent = __detail::__maybe_const_t<_Const, join_with_view>;
7359 using _Base = join_with_view::_Base<_Const>;
7360
7361 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
7362
7363 constexpr explicit
7364 _Sentinel(_Parent& __parent)
7365 : _M_end(ranges::end(__parent._M_base))
7366 { }
7367
7368 friend join_with_view;
7369
7370 public:
7371 _Sentinel() = default;
7372
7373 constexpr
7374 _Sentinel(_Sentinel<!_Const> __s)
7375 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
7376 : _M_end(std::move(__s._M_end))
7377 { }
7378
7379 template<bool _OtherConst>
7380 requires sentinel_for<sentinel_t<_Base>,
7381 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
7382 friend constexpr bool
7383 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
7384 { return __x._M_outer_it == __y._M_end; }
7385 };
7386
7387 namespace views
7388 {
7389 namespace __detail
7390 {
7391 template<typename _Range, typename _Pattern>
7392 concept __can_join_with_view
7393 = requires { join_with_view(std::declval<_Range>(), std::declval<_Pattern>()); };
7394 } // namespace __detail
7395
7396 struct _JoinWith : __adaptor::_RangeAdaptor<_JoinWith>
7397 {
7398 template<viewable_range _Range, typename _Pattern>
7399 requires __detail::__can_join_with_view<_Range, _Pattern>
7400 constexpr auto
7401 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f) const
7402 {
7403 return join_with_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
7404 }
7405
7406 using _RangeAdaptor<_JoinWith>::operator();
7407 static constexpr int _S_arity = 2;
7408 template<typename _Pattern>
7409 static constexpr bool _S_has_simple_extra_args
7410 = _LazySplit::_S_has_simple_extra_args<_Pattern>;
7411 };
7412
7413 inline constexpr _JoinWith join_with;
7414 } // namespace views
7415
7416#define __cpp_lib_ranges_repeat 202207L
7417
7418 template<copy_constructible _Tp, semiregular _Bound = unreachable_sentinel_t>
7419 requires is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>>
7420 && (__detail::__is_integer_like<_Bound> || same_as<_Bound, unreachable_sentinel_t>)
7421 class repeat_view : public view_interface<repeat_view<_Tp, _Bound>>
7422 {
7423 __detail::__box<_Tp> _M_value;
7424 [[no_unique_address]] _Bound _M_bound = _Bound();
7425
7426 struct _Iterator;
7427
7428 template<typename _Range>
7429 friend constexpr auto
7430 views::__detail::__take_of_repeat_view(_Range&&, range_difference_t<_Range>);
7431
7432 template<typename _Range>
7433 friend constexpr auto
7434 views::__detail::__drop_of_repeat_view(_Range&&, range_difference_t<_Range>);
7435
7436 public:
7437 repeat_view() requires default_initializable<_Tp> = default;
7438
7439 constexpr explicit
7440 repeat_view(const _Tp& __value, _Bound __bound = _Bound())
7441 : _M_value(__value), _M_bound(__bound)
7442 {
7443 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7444 __glibcxx_assert(__bound >= 0);
7445 }
7446
7447 constexpr explicit
7448 repeat_view(_Tp&& __value, _Bound __bound = _Bound())
7449 : _M_value(std::move(__value)), _M_bound(__bound)
7450 { }
7451
7452 template<typename... _Args, typename... _BoundArgs>
7453 requires constructible_from<_Tp, _Args...>
7454 && constructible_from<_Bound, _BoundArgs...>
7455 constexpr explicit
7456 repeat_view(piecewise_construct_t,
7457 tuple<_Args...> __args,
7458 tuple<_BoundArgs...> __bound_args = tuple<>{})
7459 : _M_value(std::make_from_tuple<_Tp>(std::move(__args))),
7460 _M_bound(std::make_from_tuple<_Bound>(std::move(__bound_args)))
7461 { }
7462
7463 constexpr _Iterator
7464 begin() const
7465 { return _Iterator(std::__addressof(*_M_value)); }
7466
7467 constexpr _Iterator
7468 end() const requires (!same_as<_Bound, unreachable_sentinel_t>)
7469 { return _Iterator(std::__addressof(*_M_value), _M_bound); }
7470
7471 constexpr unreachable_sentinel_t
7472 end() const noexcept
7473 { return unreachable_sentinel; }
7474
7475 constexpr auto
7476 size() const requires (!same_as<_Bound, unreachable_sentinel_t>)
7477 { return __detail::__to_unsigned_like(_M_bound); }
7478 };
7479
7480 template<typename _Tp, typename _Bound>
7481 repeat_view(_Tp, _Bound) -> repeat_view<_Tp, _Bound>;
7482
7483 template<copy_constructible _Tp, semiregular _Bound>
7484 requires is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>>
7485 && (__detail::__is_integer_like<_Bound> || same_as<_Bound, unreachable_sentinel_t>)
7486 class repeat_view<_Tp, _Bound>::_Iterator
7487 {
7488 using __index_type
7489 = __conditional_t<same_as<_Bound, unreachable_sentinel_t>, ptrdiff_t, _Bound>;
7490
7491 const _Tp* _M_value = nullptr;
7492 __index_type _M_current = __index_type();
7493
7494 constexpr explicit
7495 _Iterator(const _Tp* __value, __index_type __bound = __index_type())
7496 : _M_value(__value), _M_current(__bound)
7497 {
7498 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7499 __glibcxx_assert(__bound >= 0);
7500 }
7501
7502 friend repeat_view;
7503
7504 public:
7505 using iterator_concept = random_access_iterator_tag;
7506 using iterator_category = random_access_iterator_tag;
7507 using value_type = _Tp;
7508 using difference_type = __conditional_t<__detail::__is_signed_integer_like<__index_type>,
7509 __index_type,
7510 __detail::__iota_diff_t<__index_type>>;
7511
7512 _Iterator() = default;
7513
7514 constexpr const _Tp&
7515 operator*() const noexcept
7516 { return *_M_value; }
7517
7518 constexpr _Iterator&
7519 operator++()
7520 {
7521 ++_M_current;
7522 return *this;
7523 }
7524
7525 constexpr _Iterator
7526 operator++(int)
7527 {
7528 auto __tmp = *this;
7529 ++*this;
7530 return __tmp;
7531 }
7532
7533 constexpr _Iterator&
7534 operator--()
7535 {
7536 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7537 __glibcxx_assert(_M_current > 0);
7538 --_M_current;
7539 return *this;
7540 }
7541
7542 constexpr _Iterator
7543 operator--(int)
7544 {
7545 auto __tmp = *this;
7546 --*this;
7547 return __tmp;
7548 }
7549
7550 constexpr _Iterator&
7551 operator+=(difference_type __n)
7552 {
7553 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7554 __glibcxx_assert(_M_current + __n >= 0);
7555 _M_current += __n;
7556 return *this;
7557 }
7558
7559 constexpr _Iterator&
7560 operator-=(difference_type __n)
7561 {
7562 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7563 __glibcxx_assert(_M_current - __n >= 0);
7564 _M_current -= __n;
7565 return *this;
7566 }
7567
7568 constexpr const _Tp&
7569 operator[](difference_type __n) const noexcept
7570 { return *(*this + __n); }
7571
7572 friend constexpr bool
7573 operator==(const _Iterator& __x, const _Iterator& __y)
7574 { return __x._M_current == __y._M_current; }
7575
7576 friend constexpr auto
7577 operator<=>(const _Iterator& __x, const _Iterator& __y)
7578 { return __x._M_current <=> __y._M_current; }
7579
7580 friend constexpr _Iterator
7581 operator+(_Iterator __i, difference_type __n)
7582 {
7583 __i += __n;
7584 return __i;
7585 }
7586
7587 friend constexpr _Iterator
7588 operator+(difference_type __n, _Iterator __i)
7589 { return __i + __n; }
7590
7591 friend constexpr _Iterator
7592 operator-(_Iterator __i, difference_type __n)
7593 {
7594 __i -= __n;
7595 return __i;
7596 }
7597
7598 friend constexpr difference_type
7599 operator-(const _Iterator& __x, const _Iterator& __y)
7600 {
7601 return (static_cast<difference_type>(__x._M_current)
7602 - static_cast<difference_type>(__y._M_current));
7603 }
7604 };
7605
7606 namespace views
7607 {
7608 namespace __detail
7609 {
7610 template<typename _Tp, typename _Bound>
7611 inline constexpr bool __is_repeat_view<repeat_view<_Tp, _Bound>> = true;
7612
7613 template<typename _Tp>
7614 concept __can_repeat_view
7615 = requires { repeat_view(std::declval<_Tp>()); };
7616
7617 template<typename _Tp, typename _Bound>
7618 concept __can_bounded_repeat_view
7619 = requires { repeat_view(std::declval<_Tp>(), std::declval<_Bound>()); };
7620 }
7621
7622 struct _Repeat
7623 {
7624 template<typename _Tp>
7625 requires __detail::__can_repeat_view<_Tp>
7626 constexpr auto
7627 operator() [[nodiscard]] (_Tp&& __value) const
7628 { return repeat_view(std::forward<_Tp>(__value)); }
7629
7630 template<typename _Tp, typename _Bound>
7631 requires __detail::__can_bounded_repeat_view<_Tp, _Bound>
7632 constexpr auto
7633 operator() [[nodiscard]] (_Tp&& __value, _Bound __bound) const
7634 { return repeat_view(std::forward<_Tp>(__value), __bound); }
7635 };
7636
7637 inline constexpr _Repeat repeat;
7638
7639 namespace __detail
7640 {
7641 template<typename _Range>
7642 constexpr auto
7643 __take_of_repeat_view(_Range&& __r, range_difference_t<_Range> __n)
7644 {
7645 using _Tp = remove_cvref_t<_Range>;
7646 static_assert(__is_repeat_view<_Tp>);
7647 if constexpr (sized_range<_Tp>)
7648 return views::repeat(*__r._M_value, std::min(ranges::distance(__r), __n));
7649 else
7650 return views::repeat(*__r._M_value, __n);
7651 }
7652
7653 template<typename _Range>
7654 constexpr auto
7655 __drop_of_repeat_view(_Range&& __r, range_difference_t<_Range> __n)
7656 {
7657 using _Tp = remove_cvref_t<_Range>;
7658 static_assert(__is_repeat_view<_Tp>);
7659 if constexpr (sized_range<_Tp>)
7660 {
7661 auto __sz = ranges::distance(__r);
7662 return views::repeat(*__r._M_value, __sz - std::min(__sz, __n));
7663 }
7664 else
7665 return __r;
7666 }
7667 }
7668 }
7669
7670#define __cpp_lib_ranges_stride 202207L
7671
7672 template<input_range _Vp>
7673 requires view<_Vp>
7674 class stride_view : public view_interface<stride_view<_Vp>>
7675 {
7676 _Vp _M_base;
7677 range_difference_t<_Vp> _M_stride;
7678
7679 template<bool _Const> using _Base = __detail::__maybe_const_t<_Const, _Vp>;
7680
7681 template<bool _Const>
7682 struct __iter_cat
7683 { };
7684
7685 template<bool _Const>
7686 requires forward_range<_Base<_Const>>
7687 struct __iter_cat<_Const>
7688 {
7689 private:
7690 static auto
7691 _S_iter_cat()
7692 {
7693 using _Cat = typename iterator_traits<iterator_t<_Base<_Const>>>::iterator_category;
7694 if constexpr (derived_from<_Cat, random_access_iterator_tag>)
7695 return random_access_iterator_tag{};
7696 else
7697 return _Cat{};
7698 }
7699 public:
7700 using iterator_category = decltype(_S_iter_cat());
7701 };
7702
7703 template<bool> class _Iterator;
7704
7705 public:
7706 constexpr explicit
7707 stride_view(_Vp __base, range_difference_t<_Vp> __stride)
7708 : _M_base(std::move(__base)), _M_stride(__stride)
7709 { __glibcxx_assert(__stride > 0); }
7710
7711 constexpr _Vp
7712 base() const& requires copy_constructible<_Vp>
7713 { return _M_base; }
7714
7715 constexpr _Vp
7716 base() &&
7717 { return std::move(_M_base); }
7718
7719 constexpr range_difference_t<_Vp>
7720 stride() const noexcept
7721 { return _M_stride; }
7722
7723 constexpr auto
7724 begin() requires (!__detail::__simple_view<_Vp>)
7725 { return _Iterator<false>(this, ranges::begin(_M_base)); }
7726
7727 constexpr auto
7728 begin() const requires range<const _Vp>
7729 { return _Iterator<true>(this, ranges::begin(_M_base)); }
7730
7731 constexpr auto
7732 end() requires (!__detail::__simple_view<_Vp>)
7733 {
7734 if constexpr (common_range<_Vp> && sized_range<_Vp> && forward_range<_Vp>)
7735 {
7736 auto __missing = (_M_stride - ranges::distance(_M_base) % _M_stride) % _M_stride;
7737 return _Iterator<false>(this, ranges::end(_M_base), __missing);
7738 }
7739 else if constexpr (common_range<_Vp> && !bidirectional_range<_Vp>)
7740 return _Iterator<false>(this, ranges::end(_M_base));
7741 else
7742 return default_sentinel;
7743 }
7744
7745 constexpr auto
7746 end() const requires range<const _Vp>
7747 {
7748 if constexpr (common_range<const _Vp> && sized_range<const _Vp>
7749 && forward_range<const _Vp>)
7750 {
7751 auto __missing = (_M_stride - ranges::distance(_M_base) % _M_stride) % _M_stride;
7752 return _Iterator<true>(this, ranges::end(_M_base), __missing);
7753 }
7754 else if constexpr (common_range<const _Vp> && !bidirectional_range<const _Vp>)
7755 return _Iterator<true>(this, ranges::end(_M_base));
7756 else
7757 return default_sentinel;
7758 }
7759
7760 constexpr auto
7761 size() requires sized_range<_Vp>
7762 {
7763 return __detail::__to_unsigned_like
7764 (__detail::__div_ceil(ranges::distance(_M_base), _M_stride));
7765 }
7766
7767 constexpr auto
7768 size() const requires sized_range<const _Vp>
7769 {
7770 return __detail::__to_unsigned_like
7771 (__detail::__div_ceil(ranges::distance(_M_base), _M_stride));
7772 }
7773 };
7774
7775 template<typename _Range>
7776 stride_view(_Range&&, range_difference_t<_Range>) -> stride_view<views::all_t<_Range>>;
7777
7778 template<typename _Vp>
7779 inline constexpr bool enable_borrowed_range<stride_view<_Vp>>
7780 = enable_borrowed_range<_Vp>;
7781
7782 template<input_range _Vp>
7783 requires view<_Vp>
7784 template<bool _Const>
7785 class stride_view<_Vp>::_Iterator : public __iter_cat<_Const>
7786 {
7787 using _Parent = __detail::__maybe_const_t<_Const, stride_view>;
7788 using _Base = stride_view::_Base<_Const>;
7789
7790 iterator_t<_Base> _M_current = iterator_t<_Base>();
7791 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
7792 range_difference_t<_Base> _M_stride = 0;
7793 range_difference_t<_Base> _M_missing = 0;
7794
7795 constexpr
7796 _Iterator(_Parent* __parent, iterator_t<_Base> __current,
7797 range_difference_t<_Base> __missing = 0)
7798 : _M_current(std::move(__current)), _M_end(ranges::end(__parent->_M_base)),
7799 _M_stride(__parent->_M_stride), _M_missing(__missing)
7800 { }
7801
7802 static auto
7803 _S_iter_concept()
7804 {
7805 if constexpr (random_access_range<_Base>)
7806 return random_access_iterator_tag{};
7807 else if constexpr (bidirectional_range<_Base>)
7808 return bidirectional_iterator_tag{};
7809 else if constexpr (forward_range<_Base>)
7810 return forward_iterator_tag{};
7811 else
7812 return input_iterator_tag{};
7813 }
7814
7815 friend stride_view;
7816
7817 public:
7818 using difference_type = range_difference_t<_Base>;
7819 using value_type = range_value_t<_Base>;
7820 using iterator_concept = decltype(_S_iter_concept());
7821 // iterator_category defined in stride_view::__iter_cat
7822
7823 _Iterator() requires default_initializable<iterator_t<_Base>> = default;
7824
7825 constexpr
7826 _Iterator(_Iterator<!_Const> __other)
7827 requires _Const
7828 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
7829 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
7830 : _M_current(std::move(__other._M_current)), _M_end(std::move(__other._M_end)),
7831 _M_stride(__other._M_stride), _M_missing(__other._M_missing)
7832 { }
7833
7834 constexpr iterator_t<_Base>
7835 base() &&
7836 { return std::move(_M_current); }
7837
7838 constexpr const iterator_t<_Base>&
7839 base() const & noexcept
7840 { return _M_current; }
7841
7842 constexpr decltype(auto)
7843 operator*() const
7844 { return *_M_current; }
7845
7846 constexpr _Iterator&
7847 operator++()
7848 {
7849 __glibcxx_assert(_M_current != _M_end);
7850 _M_missing = ranges::advance(_M_current, _M_stride, _M_end);
7851 return *this;
7852 }
7853
7854 constexpr void
7855 operator++(int)
7856 { ++*this; }
7857
7858 constexpr _Iterator
7859 operator++(int) requires forward_range<_Base>
7860 {
7861 auto __tmp = *this;
7862 ++*this;
7863 return __tmp;
7864 }
7865
7866 constexpr _Iterator&
7867 operator--() requires bidirectional_range<_Base>
7868 {
7869 ranges::advance(_M_current, _M_missing - _M_stride);
7870 _M_missing = 0;
7871 return *this;
7872 }
7873
7874 constexpr _Iterator
7875 operator--(int) requires bidirectional_range<_Base>
7876 {
7877 auto __tmp = *this;
7878 --*this;
7879 return __tmp;
7880 }
7881
7882 constexpr _Iterator&
7883 operator+=(difference_type __n) requires random_access_range<_Base>
7884 {
7885 if (__n > 0)
7886 {
7887 __glibcxx_assert(ranges::distance(_M_current, _M_end) > _M_stride * (__n - 1));
7888 _M_missing = ranges::advance(_M_current, _M_stride * __n, _M_end);
7889 }
7890 else if (__n < 0)
7891 {
7892 ranges::advance(_M_current, _M_stride * __n + _M_missing);
7893 _M_missing = 0;
7894 }
7895 return *this;
7896 }
7897
7898 constexpr _Iterator&
7899 operator-=(difference_type __n) requires random_access_range<_Base>
7900 { return *this += -__n; }
7901
7902 constexpr decltype(auto) operator[](difference_type __n) const
7903 requires random_access_range<_Base>
7904 { return *(*this + __n); }
7905
7906 friend constexpr bool
7907 operator==(const _Iterator& __x, default_sentinel_t)
7908 { return __x._M_current == __x._M_end; }
7909
7910 friend constexpr bool
7911 operator==(const _Iterator& __x, const _Iterator& __y)
7912 requires equality_comparable<iterator_t<_Base>>
7913 { return __x._M_current == __y._M_current; }
7914
7915 friend constexpr bool
7916 operator<(const _Iterator& __x, const _Iterator& __y)
7917 requires random_access_range<_Base>
7918 { return __x._M_current < __y._M_current; }
7919
7920 friend constexpr bool
7921 operator>(const _Iterator& __x, const _Iterator& __y)
7922 requires random_access_range<_Base>
7923 { return __y._M_current < __x._M_current; }
7924
7925 friend constexpr bool
7926 operator<=(const _Iterator& __x, const _Iterator& __y)
7927 requires random_access_range<_Base>
7928 { return !(__y._M_current < __x._M_current); }
7929
7930 friend constexpr bool
7931 operator>=(const _Iterator& __x, const _Iterator& __y)
7932 requires random_access_range<_Base>
7933 { return !(__x._M_current < __y._M_current); }
7934
7935 friend constexpr auto
7936 operator<=>(const _Iterator& __x, const _Iterator& __y)
7937 requires random_access_range<_Base> && three_way_comparable<iterator_t<_Base>>
7938 { return __x._M_current <=> __y._M_current; }
7939
7940 friend constexpr _Iterator
7941 operator+(const _Iterator& __i, difference_type __n)
7942 requires random_access_range<_Base>
7943 {
7944 auto __r = __i;
7945 __r += __n;
7946 return __r;
7947 }
7948
7949 friend constexpr _Iterator
7950 operator+(difference_type __n, const _Iterator& __i)
7951 requires random_access_range<_Base>
7952 { return __i + __n; }
7953
7954 friend constexpr _Iterator
7955 operator-(const _Iterator& __i, difference_type __n)
7956 requires random_access_range<_Base>
7957 {
7958 auto __r = __i;
7959 __r -= __n;
7960 return __r;
7961 }
7962
7963 friend constexpr difference_type
7964 operator-(const _Iterator& __x, const _Iterator& __y)
7965 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
7966 {
7967 auto __n = __x._M_current - __y._M_current;
7968 if constexpr (forward_range<_Base>)
7969 return (__n + __x._M_missing - __y._M_missing) / __x._M_stride;
7970 else if (__n < 0)
7971 return -__detail::__div_ceil(-__n, __x._M_stride);
7972 else
7973 return __detail::__div_ceil(__n, __x._M_stride);
7974 }
7975
7976 friend constexpr difference_type
7977 operator-(default_sentinel_t __y, const _Iterator& __x)
7978 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
7979 { return __detail::__div_ceil(__x._M_end - __x._M_current, __x._M_stride); }
7980
7981 friend constexpr difference_type
7982 operator-(const _Iterator& __x, default_sentinel_t __y)
7983 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
7984 { return -(__y - __x); }
7985
7986 friend constexpr range_rvalue_reference_t<_Base>
7987 iter_move(const _Iterator& __i)
7988 noexcept(noexcept(ranges::iter_move(__i._M_current)))
7989 { return ranges::iter_move(__i._M_current); }
7990
7991 friend constexpr void
7992 iter_swap(const _Iterator& __x, const _Iterator& __y)
7993 noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
7994 requires indirectly_swappable<iterator_t<_Base>>
7995 { ranges::iter_swap(__x._M_current, __y._M_current); }
7996 };
7997
7998 namespace views
7999 {
8000 namespace __detail
8001 {
8002 template<typename _Range, typename _Dp>
8003 concept __can_stride_view
8004 = requires { stride_view(std::declval<_Range>(), std::declval<_Dp>()); };
8005 }
8006
8007 struct _Stride : __adaptor::_RangeAdaptor<_Stride>
8008 {
8009 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
8010 requires __detail::__can_stride_view<_Range, _Dp>
8011 constexpr auto
8012 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
8013 { return stride_view(std::forward<_Range>(__r), __n); }
8014
8015 using __adaptor::_RangeAdaptor<_Stride>::operator();
8016 static constexpr int _S_arity = 2;
8017 static constexpr bool _S_has_simple_extra_args = true;
8018 };
8019
8020 inline constexpr _Stride stride;
8021 }
8022
8023#define __cpp_lib_ranges_cartesian_product 202207L
8024
8025 namespace __detail
8026 {
8027 template<bool _Const, typename _First, typename... _Vs>
8028 concept __cartesian_product_is_random_access
8029 = (random_access_range<__maybe_const_t<_Const, _First>>
8030 && ...
8031 && (random_access_range<__maybe_const_t<_Const, _Vs>>
8032 && sized_range<__maybe_const_t<_Const, _Vs>>));
8033
8034 template<typename _Range>
8035 concept __cartesian_product_common_arg
8036 = common_range<_Range> || (sized_range<_Range> && random_access_range<_Range>);
8037
8038 template<bool _Const, typename _First, typename... _Vs>
8039 concept __cartesian_product_is_bidirectional
8040 = (bidirectional_range<__maybe_const_t<_Const, _First>>
8041 && ...
8042 && (bidirectional_range<__maybe_const_t<_Const, _Vs>>
8043 && __cartesian_product_common_arg<__maybe_const_t<_Const, _Vs>>));
8044
8045 template<typename _First, typename... _Vs>
8046 concept __cartesian_product_is_common = __cartesian_product_common_arg<_First>;
8047
8048 template<typename... _Vs>
8049 concept __cartesian_product_is_sized = (sized_range<_Vs> && ...);
8050
8051 template<bool _Const, template<typename> class FirstSent, typename _First, typename... _Vs>
8052 concept __cartesian_is_sized_sentinel
8053 = (sized_sentinel_for<FirstSent<__maybe_const_t<_Const, _First>>,
8054 iterator_t<__maybe_const_t<_Const, _First>>>
8055 && ...
8056 && (sized_range<__maybe_const_t<_Const, _Vs>>
8057 && sized_sentinel_for<iterator_t<__maybe_const_t<_Const, _Vs>>,
8058 iterator_t<__maybe_const_t<_Const, _Vs>>>));
8059
8060 template<__cartesian_product_common_arg _Range>
8061 constexpr auto
8062 __cartesian_common_arg_end(_Range& __r)
8063 {
8064 if constexpr (common_range<_Range>)
8065 return ranges::end(__r);
8066 else
8067 return ranges::begin(__r) + ranges::distance(__r);
8068 }
8069 } // namespace __detail
8070
8071 template<input_range _First, forward_range... _Vs>
8072 requires (view<_First> && ... && view<_Vs>)
8073 class cartesian_product_view : public view_interface<cartesian_product_view<_First, _Vs...>>
8074 {
8075 tuple<_First, _Vs...> _M_bases;
8076
8077 template<bool> class _Iterator;
8078
8079 static auto
8080 _S_difference_type()
8081 {
8082 // TODO: Implement the recommended practice of using the smallest
8083 // sufficiently wide type according to the maximum sizes of the
8084 // underlying ranges?
8085 return common_type_t<ptrdiff_t,
8086 range_difference_t<_First>,
8087 range_difference_t<_Vs>...>{};
8088 }
8089
8090 public:
8091 cartesian_product_view() = default;
8092
8093 constexpr explicit
8094 cartesian_product_view(_First __first, _Vs... __rest)
8095 : _M_bases(std::move(__first), std::move(__rest)...)
8096 { }
8097
8098 constexpr _Iterator<false>
8099 begin() requires (!__detail::__simple_view<_First> || ... || !__detail::__simple_view<_Vs>)
8100 { return _Iterator<false>(*this, __detail::__tuple_transform(ranges::begin, _M_bases)); }
8101
8102 constexpr _Iterator<true>
8103 begin() const requires (range<const _First> && ... && range<const _Vs>)
8104 { return _Iterator<true>(*this, __detail::__tuple_transform(ranges::begin, _M_bases)); }
8105
8106 constexpr _Iterator<false>
8107 end() requires ((!__detail::__simple_view<_First> || ... || !__detail::__simple_view<_Vs>)
8108 && __detail::__cartesian_product_is_common<_First, _Vs...>)
8109 {
8110 auto __its = [this]<size_t... _Is>(index_sequence<_Is...>) {
8111 using _Ret = __detail::__tuple_or_pair_t<iterator_t<_First>,
8112 iterator_t<_Vs>...>;
8113 bool __empty_tail = (ranges::empty(std::get<1 + _Is>(_M_bases)) || ...);
8114 auto& __first = std::get<0>(_M_bases);
8115 return _Ret{(__empty_tail
8116 ? ranges::begin(__first)
8117 : __detail::__cartesian_common_arg_end(__first)),
8118 ranges::begin(std::get<1 + _Is>(_M_bases))...};
8119 }(make_index_sequence<sizeof...(_Vs)>{});
8120
8121 return _Iterator<false>{*this, std::move(__its)};
8122 }
8123
8124 constexpr _Iterator<true>
8125 end() const requires __detail::__cartesian_product_is_common<const _First, const _Vs...>
8126 {
8127 auto __its = [this]<size_t... _Is>(index_sequence<_Is...>) {
8128 using _Ret = __detail::__tuple_or_pair_t<iterator_t<const _First>,
8129 iterator_t<const _Vs>...>;
8130 bool __empty_tail = (ranges::empty(std::get<1 + _Is>(_M_bases)) || ...);
8131 auto& __first = std::get<0>(_M_bases);
8132 return _Ret{(__empty_tail
8133 ? ranges::begin(__first)
8134 : __detail::__cartesian_common_arg_end(__first)),
8135 ranges::begin(std::get<1 + _Is>(_M_bases))...};
8136 }(make_index_sequence<sizeof...(_Vs)>{});
8137
8138 return _Iterator<true>{*this, std::move(__its)};
8139 }
8140
8141 constexpr default_sentinel_t
8142 end() const noexcept
8143 { return default_sentinel; }
8144
8145 constexpr auto
8146 size() requires __detail::__cartesian_product_is_sized<_First, _Vs...>
8147 {
8148 using _ST = __detail::__make_unsigned_like_t<decltype(_S_difference_type())>;
8149 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8150 auto __size = static_cast<_ST>(1);
8151#ifdef _GLIBCXX_ASSERTIONS
8152 if constexpr (integral<_ST>)
8153 {
8154 bool __overflow
8155 = (__builtin_mul_overflow(__size,
8156 static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))),
8157 &__size)
8158 || ...);
8159 __glibcxx_assert(!__overflow);
8160 }
8161 else
8162#endif
8163 __size = (static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))) * ...);
8164 return __size;
8165 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8166 }
8167
8168 constexpr auto
8169 size() const requires __detail::__cartesian_product_is_sized<const _First, const _Vs...>
8170 {
8171 using _ST = __detail::__make_unsigned_like_t<decltype(_S_difference_type())>;
8172 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8173 auto __size = static_cast<_ST>(1);
8174#ifdef _GLIBCXX_ASSERTIONS
8175 if constexpr (integral<_ST>)
8176 {
8177 bool __overflow
8178 = (__builtin_mul_overflow(__size,
8179 static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))),
8180 &__size)
8181 || ...);
8182 __glibcxx_assert(!__overflow);
8183 }
8184 else
8185#endif
8186 __size = (static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))) * ...);
8187 return __size;
8188 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8189 }
8190 };
8191
8192 template<typename... _Vs>
8193 cartesian_product_view(_Vs&&...) -> cartesian_product_view<views::all_t<_Vs>...>;
8194
8195 template<input_range _First, forward_range... _Vs>
8196 requires (view<_First> && ... && view<_Vs>)
8197 template<bool _Const>
8198 class cartesian_product_view<_First, _Vs...>::_Iterator
8199 {
8200 using _Parent = __maybe_const_t<_Const, cartesian_product_view>;
8201 _Parent* _M_parent = nullptr;
8202 __detail::__tuple_or_pair_t<iterator_t<__maybe_const_t<_Const, _First>>,
8203 iterator_t<__maybe_const_t<_Const, _Vs>>...> _M_current;
8204
8205 constexpr
8206 _Iterator(_Parent& __parent, decltype(_M_current) __current)
8207 : _M_parent(std::__addressof(__parent)),
8208 _M_current(std::move(__current))
8209 { }
8210
8211 static auto
8212 _S_iter_concept()
8213 {
8214 if constexpr (__detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>)
8215 return random_access_iterator_tag{};
8216 else if constexpr (__detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>)
8217 return bidirectional_iterator_tag{};
8218 else if constexpr (forward_range<__maybe_const_t<_Const, _First>>)
8219 return forward_iterator_tag{};
8220 else
8221 return input_iterator_tag{};
8222 }
8223
8224 friend cartesian_product_view;
8225
8226 public:
8227 using iterator_category = input_iterator_tag;
8228 using iterator_concept = decltype(_S_iter_concept());
8229 using value_type
8230 = __detail::__tuple_or_pair_t<range_value_t<__maybe_const_t<_Const, _First>>,
8231 range_value_t<__maybe_const_t<_Const, _Vs>>...>;
8232 using reference
8233 = __detail::__tuple_or_pair_t<range_reference_t<__maybe_const_t<_Const, _First>>,
8234 range_reference_t<__maybe_const_t<_Const, _Vs>>...>;
8235 using difference_type = decltype(cartesian_product_view::_S_difference_type());
8236
8237 _Iterator() = default;
8238
8239 constexpr
8240 _Iterator(_Iterator<!_Const> __i)
8241 requires _Const
8242 && (convertible_to<iterator_t<_First>, iterator_t<const _First>>
8243 && ... && convertible_to<iterator_t<_Vs>, iterator_t<const _Vs>>)
8244 : _M_parent(std::__addressof(__i._M_parent)),
8245 _M_current(std::move(__i._M_current))
8246 { }
8247
8248 constexpr auto
8249 operator*() const
8250 {
8251 auto __f = [](auto& __i) -> decltype(auto) {
8252 return *__i;
8253 };
8254 return __detail::__tuple_transform(__f, _M_current);
8255 }
8256
8257 constexpr _Iterator&
8258 operator++()
8259 {
8260 _M_next();
8261 return *this;
8262 }
8263
8264 constexpr void
8265 operator++(int)
8266 { ++*this; }
8267
8268 constexpr _Iterator
8269 operator++(int) requires forward_range<__maybe_const_t<_Const, _First>>
8270 {
8271 auto __tmp = *this;
8272 ++*this;
8273 return __tmp;
8274 }
8275
8276 constexpr _Iterator&
8277 operator--()
8278 requires __detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>
8279 {
8280 _M_prev();
8281 return *this;
8282 }
8283
8284 constexpr _Iterator
8285 operator--(int)
8286 requires __detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>
8287 {
8288 auto __tmp = *this;
8289 --*this;
8290 return __tmp;
8291 }
8292
8293 constexpr _Iterator&
8294 operator+=(difference_type __x)
8295 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8296 {
8297 _M_advance(__x);
8298 return *this;
8299 }
8300
8301 constexpr _Iterator&
8302 operator-=(difference_type __x)
8303 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8304 { return *this += -__x; }
8305
8306 constexpr reference
8307 operator[](difference_type __n) const
8308 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8309 { return *((*this) + __n); }
8310
8311 friend constexpr bool
8312 operator==(const _Iterator& __x, const _Iterator& __y)
8313 requires equality_comparable<iterator_t<__maybe_const_t<_Const, _First>>>
8314 { return __x._M_current == __y._M_current; }
8315
8316 friend constexpr bool
8317 operator==(const _Iterator& __x, default_sentinel_t)
8318 {
8319 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8320 return ((std::get<_Is>(__x._M_current)
8321 == ranges::end(std::get<_Is>(__x._M_parent->_M_bases)))
8322 || ...);
8323 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8324 }
8325
8326 friend constexpr auto
8327 operator<=>(const _Iterator& __x, const _Iterator& __y)
8328 requires __detail::__all_random_access<_Const, _First, _Vs...>
8329 { return __x._M_current <=> __y._M_current; }
8330
8331 friend constexpr _Iterator
8332 operator+(_Iterator __x, difference_type __y)
8333 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8334 { return __x += __y; }
8335
8336 friend constexpr _Iterator
8337 operator+(difference_type __x, _Iterator __y)
8338 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8339 { return __y += __x; }
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 difference_type
8347 operator-(const _Iterator& __x, const _Iterator& __y)
8348 requires __detail::__cartesian_is_sized_sentinel<_Const, iterator_t, _First, _Vs...>
8349 { return __x._M_distance_from(__y._M_current); }
8350
8351 friend constexpr difference_type
8352 operator-(const _Iterator& __i, default_sentinel_t)
8353 requires __detail::__cartesian_is_sized_sentinel<_Const, sentinel_t, _First, _Vs...>
8354 {
8355 tuple __end_tuple = [&]<size_t... _Is>(index_sequence<_Is...>) {
8356 return tuple{ranges::end(std::get<0>(__i._M_parent->_M_bases)),
8357 ranges::begin(std::get<1 + _Is>(__i._M_parent->_M_bases))...};
8358 }(make_index_sequence<sizeof...(_Vs)>{});
8359 return __i._M_distance_from(__end_tuple);
8360 }
8361
8362 friend constexpr difference_type
8363 operator-(default_sentinel_t, const _Iterator& __i)
8364 requires __detail::__cartesian_is_sized_sentinel<_Const, sentinel_t, _First, _Vs...>
8365 { return -(__i - default_sentinel); }
8366
8367 friend constexpr auto
8368 iter_move(const _Iterator& __i)
8369 { return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
8370
8371 friend constexpr void
8372 iter_swap(const _Iterator& __l, const _Iterator& __r)
8373 requires (indirectly_swappable<iterator_t<__maybe_const_t<_Const, _First>>>
8374 && ...
8375 && indirectly_swappable<iterator_t<__maybe_const_t<_Const, _Vs>>>)
8376 {
8377 [&]<size_t... _Is>(index_sequence<_Is...>) {
8378 (ranges::iter_swap(std::get<_Is>(__l._M_current), std::get<_Is>(__r._M_current)), ...);
8379 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8380 }
8381
8382 private:
8383 template<size_t _Nm = sizeof...(_Vs)>
8384 constexpr void
8385 _M_next()
8386 {
8387 auto& __it = std::get<_Nm>(_M_current);
8388 ++__it;
8389 if constexpr (_Nm > 0)
8390 if (__it == ranges::end(std::get<_Nm>(_M_parent->_M_bases)))
8391 {
8392 __it = ranges::begin(std::get<_Nm>(_M_parent->_M_bases));
8393 _M_next<_Nm - 1>();
8394 }
8395 }
8396
8397 template<size_t _Nm = sizeof...(_Vs)>
8398 constexpr void
8399 _M_prev()
8400 {
8401 auto& __it = std::get<_Nm>(_M_current);
8402 if constexpr (_Nm > 0)
8403 if (__it == ranges::begin(std::get<_Nm>(_M_parent->_M_bases)))
8404 {
8405 __it = __detail::__cartesian_common_arg_end(std::get<_Nm>(_M_parent->_M_bases));
8406 _M_prev<_Nm - 1>();
8407 }
8408 --__it;
8409 }
8410
8411 template<size_t _Nm = sizeof...(_Vs)>
8412 constexpr void
8413 _M_advance(difference_type __x)
8414 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8415 {
8416 if (__x == 1)
8417 _M_next<_Nm>();
8418 else if (__x == -1)
8419 _M_prev<_Nm>();
8420 else if (__x != 0)
8421 {
8422 // Constant time iterator advancement.
8423 auto& __r = std::get<_Nm>(_M_parent->_M_bases);
8424 auto& __it = std::get<_Nm>(_M_current);
8425 if constexpr (_Nm == 0)
8426 {
8427#ifdef _GLIBCXX_ASSERTIONS
8428 if constexpr (sized_range<__maybe_const_t<_Const, _First>>)
8429 {
8430 auto __size = ranges::ssize(__r);
8431 auto __begin = ranges::begin(__r);
8432 auto __offset = __it - __begin;
8433 __glibcxx_assert(__offset + __x >= 0 && __offset + __x <= __size);
8434 }
8435#endif
8436 __it += __x;
8437 }
8438 else
8439 {
8440 auto __size = ranges::ssize(__r);
8441 auto __begin = ranges::begin(__r);
8442 auto __offset = __it - __begin;
8443 __offset += __x;
8444 __x = __offset / __size;
8445 __offset %= __size;
8446 if (__offset < 0)
8447 {
8448 __offset = __size + __offset;
8449 --__x;
8450 }
8451 __it = __begin + __offset;
8452 _M_advance<_Nm - 1>(__x);
8453 }
8454 }
8455 }
8456
8457 template<typename _Tuple>
8458 constexpr difference_type
8459 _M_distance_from(const _Tuple& __t) const
8460 {
8461 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8462 auto __sum = static_cast<difference_type>(0);
8463#ifdef _GLIBCXX_ASSERTIONS
8464 if constexpr (integral<difference_type>)
8465 {
8466 bool __overflow
8467 = (__builtin_add_overflow(__sum, _M_scaled_distance<_Is>(__t), &__sum)
8468 || ...);
8469 __glibcxx_assert(!__overflow);
8470 }
8471 else
8472#endif
8473 __sum = (_M_scaled_distance<_Is>(__t) + ...);
8474 return __sum;
8475 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8476 }
8477
8478 template<size_t _Nm, typename _Tuple>
8479 constexpr difference_type
8480 _M_scaled_distance(const _Tuple& __t) const
8481 {
8482 auto __dist = static_cast<difference_type>(std::get<_Nm>(_M_current)
8483 - std::get<_Nm>(__t));
8484#ifdef _GLIBCXX_ASSERTIONS
8485 if constexpr (integral<difference_type>)
8486 {
8487 bool __overflow = __builtin_mul_overflow(__dist, _M_scaled_size<_Nm+1>(), &__dist);
8488 __glibcxx_assert(!__overflow);
8489 }
8490 else
8491#endif
8492 __dist *= _M_scaled_size<_Nm+1>();
8493 return __dist;
8494 }
8495
8496 template<size_t _Nm>
8497 constexpr difference_type
8498 _M_scaled_size() const
8499 {
8500 if constexpr (_Nm <= sizeof...(_Vs))
8501 {
8502 auto __size = static_cast<difference_type>(ranges::size
8503 (std::get<_Nm>(_M_parent->_M_bases)));
8504#ifdef _GLIBCXX_ASSERTIONS
8505 if constexpr (integral<difference_type>)
8506 {
8507 bool __overflow = __builtin_mul_overflow(__size, _M_scaled_size<_Nm+1>(), &__size);
8508 __glibcxx_assert(!__overflow);
8509 }
8510 else
8511#endif
8512 __size *= _M_scaled_size<_Nm+1>();
8513 return __size;
8514 }
8515 else
8516 return static_cast<difference_type>(1);
8517 }
8518 };
8519
8520 namespace views
8521 {
8522 namespace __detail
8523 {
8524 template<typename... _Ts>
8525 concept __can_cartesian_product_view
8526 = requires { cartesian_product_view<all_t<_Ts>...>(std::declval<_Ts>()...); };
8527 }
8528
8529 struct _CartesianProduct
8530 {
8531 template<typename... _Ts>
8532 requires (sizeof...(_Ts) == 0 || __detail::__can_cartesian_product_view<_Ts...>)
8533 constexpr auto
8534 operator() [[nodiscard]] (_Ts&&... __ts) const
8535 {
8536 if constexpr (sizeof...(_Ts) == 0)
8537 return views::empty<tuple<>>;
8538 else
8539 return cartesian_product_view<all_t<_Ts>...>(std::forward<_Ts>(__ts)...);
8540 }
8541 };
8542
8543 inline constexpr _CartesianProduct cartesian_product;
8544 }
8545
8546#define __cpp_lib_ranges_as_rvalue 202207L
8547
8548 template<input_range _Vp>
8549 requires view<_Vp>
8550 class as_rvalue_view : public view_interface<as_rvalue_view<_Vp>>
8551 {
8552 _Vp _M_base = _Vp();
8553
8554 public:
8555 as_rvalue_view() requires default_initializable<_Vp> = default;
8556
8557 constexpr explicit
8558 as_rvalue_view(_Vp __base)
8559 : _M_base(std::move(__base))
8560 { }
8561
8562 constexpr _Vp
8563 base() const& requires copy_constructible<_Vp>
8564 { return _M_base; }
8565
8566 constexpr _Vp
8567 base() &&
8568 { return std::move(_M_base); }
8569
8570 constexpr auto
8571 begin() requires (!__detail::__simple_view<_Vp>)
8572 { return move_iterator(ranges::begin(_M_base)); }
8573
8574 constexpr auto
8575 begin() const requires range<const _Vp>
8576 { return move_iterator(ranges::begin(_M_base)); }
8577
8578 constexpr auto
8579 end() requires (!__detail::__simple_view<_Vp>)
8580 {
8581 if constexpr (common_range<_Vp>)
8582 return move_iterator(ranges::end(_M_base));
8583 else
8584 return move_sentinel(ranges::end(_M_base));
8585 }
8586
8587 constexpr auto
8588 end() const requires range<const _Vp>
8589 {
8590 if constexpr (common_range<const _Vp>)
8591 return move_iterator(ranges::end(_M_base));
8592 else
8593 return move_sentinel(ranges::end(_M_base));
8594 }
8595
8596 constexpr auto
8597 size() requires sized_range<_Vp>
8598 { return ranges::size(_M_base); }
8599
8600 constexpr auto
8601 size() const requires sized_range<const _Vp>
8602 { return ranges::size(_M_base); }
8603 };
8604
8605 template<typename _Range>
8606 as_rvalue_view(_Range&&) -> as_rvalue_view<views::all_t<_Range>>;
8607
8608 template<typename _Tp>
8609 inline constexpr bool enable_borrowed_range<as_rvalue_view<_Tp>>
8610 = enable_borrowed_range<_Tp>;
8611
8612 namespace views
8613 {
8614 namespace __detail
8615 {
8616 template<typename _Tp>
8617 concept __can_as_rvalue_view = requires { as_rvalue_view(std::declval<_Tp>()); };
8618 }
8619
8620 struct _AsRvalue : __adaptor::_RangeAdaptorClosure
8621 {
8622 template<viewable_range _Range>
8623 requires __detail::__can_as_rvalue_view<_Range>
8624 constexpr auto
8625 operator() [[nodiscard]] (_Range&& __r) const
8626 {
8627 if constexpr (same_as<range_rvalue_reference_t<_Range>,
8628 range_reference_t<_Range>>)
8629 return views::all(std::forward<_Range>(__r));
8630 else
8631 return as_rvalue_view(std::forward<_Range>(__r));
8632 }
8633 };
8634
8635 inline constexpr _AsRvalue as_rvalue;
8636 }
8637
8638#define __cpp_lib_ranges_enumerate 202302L
8639
8640 namespace __detail
8641 {
8642 template<typename _Range>
8643 concept __range_with_movable_reference = input_range<_Range>
8644 && move_constructible<range_reference_t<_Range>>
8645 && move_constructible<range_rvalue_reference_t<_Range>>;
8646 }
8647
8648 template<view _Vp>
8649 requires __detail::__range_with_movable_reference<_Vp>
8650 class enumerate_view : public view_interface<enumerate_view<_Vp>>
8651 {
8652 _Vp _M_base = _Vp();
8653
8654 template<bool _Const> class _Iterator;
8655 template<bool _Const> class _Sentinel;
8656
8657 public:
8658 enumerate_view() requires default_initializable<_Vp> = default;
8659
8660 constexpr explicit
8661 enumerate_view(_Vp __base)
8662 : _M_base(std::move(__base))
8663 { }
8664
8665 constexpr auto
8666 begin() requires (!__detail::__simple_view<_Vp>)
8667 { return _Iterator<false>(ranges::begin(_M_base), 0); }
8668
8669 constexpr auto
8670 begin() const requires __detail::__range_with_movable_reference<const _Vp>
8671 { return _Iterator<true>(ranges::begin(_M_base), 0); }
8672
8673 constexpr auto
8674 end() requires (!__detail::__simple_view<_Vp>)
8675 {
8676 if constexpr (common_range<_Vp> && sized_range<_Vp>)
8677 return _Iterator<false>(ranges::end(_M_base), ranges::distance(_M_base));
8678 else
8679 return _Sentinel<false>(ranges::end(_M_base));
8680 }
8681
8682 constexpr auto
8683 end() const requires __detail::__range_with_movable_reference<const _Vp>
8684 {
8685 if constexpr (common_range<const _Vp> && sized_range<const _Vp>)
8686 return _Iterator<true>(ranges::end(_M_base), ranges::distance(_M_base));
8687 else
8688 return _Sentinel<true>(ranges::end(_M_base));
8689 }
8690
8691 constexpr auto
8692 size() requires sized_range<_Vp>
8693 { return ranges::size(_M_base); }
8694
8695 constexpr auto
8696 size() const requires sized_range<const _Vp>
8697 { return ranges::size(_M_base); }
8698
8699 constexpr _Vp
8700 base() const & requires copy_constructible<_Vp>
8701 { return _M_base; }
8702
8703 constexpr _Vp
8704 base() &&
8705 { return std::move(_M_base); }
8706 };
8707
8708 template<typename _Range>
8709 enumerate_view(_Range&&) -> enumerate_view<views::all_t<_Range>>;
8710
8711 template<typename _Tp>
8712 inline constexpr bool enable_borrowed_range<enumerate_view<_Tp>>
8713 = enable_borrowed_range<_Tp>;
8714
8715 template<view _Vp>
8716 requires __detail::__range_with_movable_reference<_Vp>
8717 template<bool _Const>
8718 class enumerate_view<_Vp>::_Iterator
8719 {
8720 using _Base = __maybe_const_t<_Const, _Vp>;
8721
8722 static auto
8723 _S_iter_concept()
8724 {
8725 if constexpr (random_access_range<_Base>)
8726 return random_access_iterator_tag{};
8727 else if constexpr (bidirectional_range<_Base>)
8728 return bidirectional_iterator_tag{};
8729 else if constexpr (forward_range<_Base>)
8730 return forward_iterator_tag{};
8731 else
8732 return input_iterator_tag{};
8733 }
8734
8735 friend enumerate_view;
8736
8737 public:
8738 using iterator_category = input_iterator_tag;
8739 using iterator_concept = decltype(_S_iter_concept());
8740 using difference_type = range_difference_t<_Base>;
8741 using value_type = tuple<difference_type, range_value_t<_Base>>;
8742
8743 private:
8744 using __reference_type = tuple<difference_type, range_reference_t<_Base>>;
8745
8746 iterator_t<_Base> _M_current = iterator_t<_Base>();
8747 difference_type _M_pos = 0;
8748
8749 constexpr explicit
8750 _Iterator(iterator_t<_Base> __current, difference_type __pos)
8751 : _M_current(std::move(__current)), _M_pos(__pos)
8752 { }
8753
8754 public:
8755 _Iterator() requires default_initializable<iterator_t<_Base>> = default;
8756
8757 constexpr
8758 _Iterator(_Iterator<!_Const> __i)
8759 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
8760 : _M_current(std::move(__i._M_current)), _M_pos(__i._M_pos)
8761 { }
8762
8763 constexpr const iterator_t<_Base> &
8764 base() const & noexcept
8765 { return _M_current; }
8766
8767 constexpr iterator_t<_Base>
8768 base() &&
8769 { return std::move(_M_current); }
8770
8771 constexpr difference_type
8772 index() const noexcept
8773 { return _M_pos; }
8774
8775 constexpr auto
8776 operator*() const
8777 { return __reference_type(_M_pos, *_M_current); }
8778
8779 constexpr _Iterator&
8780 operator++()
8781 {
8782 ++_M_current;
8783 ++_M_pos;
8784 return *this;
8785 }
8786
8787 constexpr void
8788 operator++(int)
8789 { ++*this; }
8790
8791 constexpr _Iterator
8792 operator++(int) requires forward_range<_Base>
8793 {
8794 auto __tmp = *this;
8795 ++*this;
8796 return __tmp;
8797 }
8798
8799 constexpr _Iterator&
8800 operator--() requires bidirectional_range<_Base>
8801 {
8802 --_M_current;
8803 --_M_pos;
8804 return *this;
8805 }
8806
8807 constexpr _Iterator
8808 operator--(int) requires bidirectional_range<_Base>
8809 {
8810 auto __tmp = *this;
8811 --*this;
8812 return __tmp;
8813 }
8814
8815 constexpr _Iterator&
8816 operator+=(difference_type __n) requires random_access_range<_Base>
8817 {
8818 _M_current += __n;
8819 _M_pos += __n;
8820 return *this;
8821 }
8822
8823 constexpr _Iterator&
8824 operator-=(difference_type __n) requires random_access_range<_Base>
8825 {
8826 _M_current -= __n;
8827 _M_pos -= __n;
8828 return *this;
8829 }
8830
8831 constexpr auto
8832 operator[](difference_type __n) const requires random_access_range<_Base>
8833 { return __reference_type(_M_pos + __n, _M_current[__n]); }
8834
8835 friend constexpr bool
8836 operator==(const _Iterator& __x, const _Iterator& __y) noexcept
8837 { return __x._M_pos == __y._M_pos; }
8838
8839 friend constexpr strong_ordering
8840 operator<=>(const _Iterator& __x, const _Iterator& __y) noexcept
8841 { return __x._M_pos <=> __y._M_pos; }
8842
8843 friend constexpr _Iterator
8844 operator+(const _Iterator& __x, difference_type __y)
8845 requires random_access_range<_Base>
8846 { return (auto(__x) += __y); }
8847
8848 friend constexpr _Iterator
8849 operator+(difference_type __x, const _Iterator& __y)
8850 requires random_access_range<_Base>
8851 { return auto(__y) += __x; }
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 difference_type
8859 operator-(const _Iterator& __x, const _Iterator& __y)
8860 { return __x._M_pos - __y._M_pos; }
8861
8862 friend constexpr auto
8863 iter_move(const _Iterator& __i)
8864 noexcept(noexcept(ranges::iter_move(__i._M_current))
8865 && is_nothrow_move_constructible_v<range_rvalue_reference_t<_Base>>)
8866 {
8867 return tuple<difference_type, range_rvalue_reference_t<_Base>>
8868 (__i._M_pos, ranges::iter_move(__i._M_current));
8869 }
8870 };
8871
8872 template<view _Vp>
8873 requires __detail::__range_with_movable_reference<_Vp>
8874 template<bool _Const>
8875 class enumerate_view<_Vp>::_Sentinel
8876 {
8877 using _Base = __maybe_const_t<_Const, _Vp>;
8878
8879 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
8880
8881 constexpr explicit
8882 _Sentinel(sentinel_t<_Base> __end)
8883 : _M_end(std::move(__end))
8884 { }
8885
8886 friend enumerate_view;
8887
8888 public:
8889 _Sentinel() = default;
8890
8891 constexpr
8892 _Sentinel(_Sentinel<!_Const> __other)
8893 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
8894 : _M_end(std::move(__other._M_end))
8895 { }
8896
8897 constexpr sentinel_t<_Base>
8898 base() const
8899 { return _M_end; }
8900
8901 template<bool _OtherConst>
8902 requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
8903 friend constexpr bool
8904 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
8905 { return __x._M_current == __y._M_end; }
8906
8907 template<bool _OtherConst>
8908 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
8909 friend constexpr range_difference_t<__maybe_const_t<_OtherConst, _Vp>>
8910 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
8911 { return __x._M_current - __y._M_end; }
8912
8913 template<bool _OtherConst>
8914 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
8915 friend constexpr range_difference_t<__maybe_const_t<_OtherConst, _Vp>>
8916 operator-(const _Sentinel& __x, const _Iterator<_OtherConst>& __y)
8917 { return __x._M_end - __y._M_current; }
8918 };
8919
8920 namespace views
8921 {
8922 namespace __detail
8923 {
8924 template<typename _Tp>
8925 concept __can_enumerate_view
8926 = requires { enumerate_view<all_t<_Tp>>(std::declval<_Tp>()); };
8927 }
8928
8929 struct _Enumerate : __adaptor::_RangeAdaptorClosure
8930 {
8931 template<viewable_range _Range>
8932 requires __detail::__can_enumerate_view<_Range>
8933 constexpr auto
8934 operator() [[nodiscard]] (_Range&& __r) const
8935 { return enumerate_view<all_t<_Range>>(std::forward<_Range>(__r)); }
8936 };
8937
8938 inline constexpr _Enumerate enumerate;
8939 }
8940
8941#define __cpp_lib_ranges_as_const 202207L
8942
8943 template<view _Vp>
8944 requires input_range<_Vp>
8945 class as_const_view : public view_interface<as_const_view<_Vp>>
8946 {
8947 _Vp _M_base = _Vp();
8948
8949 public:
8950 as_const_view() requires default_initializable<_Vp> = default;
8951
8952 constexpr explicit
8953 as_const_view(_Vp __base)
8954 noexcept(is_nothrow_move_constructible_v<_Vp>)
8955 : _M_base(std::move(__base))
8956 { }
8957
8958 constexpr _Vp
8959 base() const &
8960 noexcept(is_nothrow_copy_constructible_v<_Vp>)
8961 requires copy_constructible<_Vp>
8962 { return _M_base; }
8963
8964 constexpr _Vp
8965 base() &&
8966 noexcept(is_nothrow_move_constructible_v<_Vp>)
8967 { return std::move(_M_base); }
8968
8969 constexpr auto
8970 begin() requires (!__detail::__simple_view<_Vp>)
8971 { return ranges::cbegin(_M_base); }
8972
8973 constexpr auto
8974 begin() const requires range<const _Vp>
8975 { return ranges::cbegin(_M_base); }
8976
8977 constexpr auto
8978 end() requires (!__detail::__simple_view<_Vp>)
8979 { return ranges::cend(_M_base); }
8980
8981 constexpr auto
8982 end() const requires range<const _Vp>
8983 { return ranges::cend(_M_base); }
8984
8985 constexpr auto
8986 size() requires sized_range<_Vp>
8987 { return ranges::size(_M_base); }
8988
8989 constexpr auto
8990 size() const requires sized_range<const _Vp>
8991 { return ranges::size(_M_base); }
8992 };
8993
8994 template<typename _Range>
8995 as_const_view(_Range&&) -> as_const_view<views::all_t<_Range>>;
8996
8997 template<typename _Tp>
8998 inline constexpr bool enable_borrowed_range<as_const_view<_Tp>>
8999 = enable_borrowed_range<_Tp>;
9000
9001 namespace views
9002 {
9003 namespace __detail
9004 {
9005 template<typename _Tp>
9006 inline constexpr bool __is_ref_view = false;
9007
9008 template<typename _Range>
9009 inline constexpr bool __is_ref_view<ref_view<_Range>> = true;
9010
9011 template<typename _Range>
9012 concept __can_as_const_view = requires { as_const_view(std::declval<_Range>()); };
9013 }
9014
9015 struct _AsConst : __adaptor::_RangeAdaptorClosure
9016 {
9017 template<viewable_range _Range>
9018 constexpr auto
9019 operator()(_Range&& __r) const
9020 noexcept(noexcept(as_const_view(std::declval<_Range>())))
9021 requires __detail::__can_as_const_view<_Range>
9022 {
9023 using _Tp = remove_cvref_t<_Range>;
9024 using element_type = remove_reference_t<range_reference_t<_Range>>;
9025 if constexpr (constant_range<views::all_t<_Range>>)
9026 return views::all(std::forward<_Range>(__r));
9027 else if constexpr (__detail::__is_empty_view<_Tp>)
9028 return views::empty<const element_type>;
9029 else if constexpr (std::__detail::__is_span<_Tp>)
9030 return span<const element_type, _Tp::extent>(std::forward<_Range>(__r));
9031 else if constexpr (__detail::__is_ref_view<_Tp>
9032 && constant_range<const element_type>)
9033 return ref_view(static_cast<const element_type&>
9034 (std::forward<_Range>(__r).base()));
9035 else if constexpr (is_lvalue_reference_v<_Range>
9036 && constant_range<const _Tp>
9037 && !view<_Tp>)
9038 return ref_view(static_cast<const _Tp&>(__r));
9039 else
9040 return as_const_view(std::forward<_Range>(__r));
9041 }
9042 };
9043
9044 inline constexpr _AsConst as_const;
9045 }
9046#endif // C++23
9047} // namespace ranges
9048
9049 namespace views = ranges::views;
9050
9051_GLIBCXX_END_NAMESPACE_VERSION
9052} // namespace
9053#endif // library concepts
9054#endif // C++2a
9055#endif /* _GLIBCXX_RANGES */