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