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