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