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