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