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