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