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