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