libstdc++: ranges Source File

libstdc++

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