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