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