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