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