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