libstdc++
ranges
Go to the documentation of this file.
1// <ranges> -*- C++ -*-
2
3// Copyright (C) 2019-2022 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#pragma GCC system_header
36
37#include <concepts>
38
39#if __cpp_lib_concepts
40
41#include <compare>
42#include <initializer_list>
43#include <iterator>
44#include <optional>
45#include <span>
46#include <tuple>
47#include <bits/ranges_util.h>
48#include <bits/refwrap.h>
49
50/**
51 * @defgroup ranges Ranges
52 *
53 * Components for dealing with ranges of elements.
54 */
55
56namespace std _GLIBCXX_VISIBILITY(default)
57{
58_GLIBCXX_BEGIN_NAMESPACE_VERSION
59namespace ranges
60{
61 // [range.access] customization point objects
62 // [range.req] range and view concepts
63 // [range.dangling] dangling iterator handling
64 // Defined in <bits/ranges_base.h>
65
66 // [view.interface] View interface
67 // [range.subrange] Sub-ranges
68 // Defined in <bits/ranges_util.h>
69
70 // C++20 24.6 [range.factories] Range factories
71
72 /// A view that contains no elements.
73 template<typename _Tp> requires is_object_v<_Tp>
74 class empty_view
75 : public view_interface<empty_view<_Tp>>
76 {
77 public:
78 static constexpr _Tp* begin() noexcept { return nullptr; }
79 static constexpr _Tp* end() noexcept { return nullptr; }
80 static constexpr _Tp* data() noexcept { return nullptr; }
81 static constexpr size_t size() noexcept { return 0; }
82 static constexpr bool empty() noexcept { return true; }
83 };
84
85 template<typename _Tp>
86 inline constexpr bool enable_borrowed_range<empty_view<_Tp>> = true;
87
88 namespace __detail
89 {
90 template<typename _Tp>
91 concept __boxable = copy_constructible<_Tp> && is_object_v<_Tp>;
92
93 template<__boxable _Tp>
94 struct __box : std::optional<_Tp>
95 {
96 using std::optional<_Tp>::optional;
97
98 constexpr
99 __box()
100 noexcept(is_nothrow_default_constructible_v<_Tp>)
101 requires default_initializable<_Tp>
102 : std::optional<_Tp>{std::in_place}
103 { }
104
105 __box(const __box&) = default;
106 __box(__box&&) = default;
107
108 using std::optional<_Tp>::operator=;
109
110 // _GLIBCXX_RESOLVE_LIB_DEFECTS
111 // 3477. Simplify constraints for semiregular-box
112 // 3572. copyable-box should be fully constexpr
113 constexpr __box&
114 operator=(const __box& __that)
115 noexcept(is_nothrow_copy_constructible_v<_Tp>)
116 requires (!copyable<_Tp>)
117 {
118 if (this != std::__addressof(__that))
119 {
120 if ((bool)__that)
121 this->emplace(*__that);
122 else
123 this->reset();
124 }
125 return *this;
126 }
127
128 constexpr __box&
129 operator=(__box&& __that)
130 noexcept(is_nothrow_move_constructible_v<_Tp>)
131 requires (!movable<_Tp>)
132 {
133 if (this != std::__addressof(__that))
134 {
135 if ((bool)__that)
136 this->emplace(std::move(*__that));
137 else
138 this->reset();
139 }
140 return *this;
141 }
142 };
143
144 // For types which are already copyable, this specialization of the
145 // copyable wrapper stores the object directly without going through
146 // std::optional. It provides just the subset of the primary template's
147 // API that we currently use.
148 template<__boxable _Tp>
149 requires copyable<_Tp> || (is_nothrow_move_constructible_v<_Tp>
150 && is_nothrow_copy_constructible_v<_Tp>)
151 struct __box<_Tp>
152 {
153 private:
154 [[no_unique_address]] _Tp _M_value = _Tp();
155
156 public:
157 __box() requires default_initializable<_Tp> = default;
158
159 constexpr explicit
160 __box(const _Tp& __t)
161 noexcept(is_nothrow_copy_constructible_v<_Tp>)
162 : _M_value(__t)
163 { }
164
165 constexpr explicit
166 __box(_Tp&& __t)
167 noexcept(is_nothrow_move_constructible_v<_Tp>)
168 : _M_value(std::move(__t))
169 { }
170
171 template<typename... _Args>
172 requires constructible_from<_Tp, _Args...>
173 constexpr explicit
174 __box(in_place_t, _Args&&... __args)
175 noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
176 : _M_value(std::forward<_Args>(__args)...)
177 { }
178
179 __box(const __box&) = default;
180 __box(__box&&) = default;
181 __box& operator=(const __box&) requires copyable<_Tp> = default;
182 __box& operator=(__box&&) requires copyable<_Tp> = default;
183
184 // When _Tp is nothrow_copy_constructible but not copy_assignable,
185 // copy assignment is implemented via destroy-then-copy-construct.
186 constexpr __box&
187 operator=(const __box& __that) noexcept
188 {
189 static_assert(is_nothrow_copy_constructible_v<_Tp>);
190 if (this != std::__addressof(__that))
191 {
192 _M_value.~_Tp();
193 std::construct_at(std::__addressof(_M_value), *__that);
194 }
195 return *this;
196 }
197
198 // Likewise for move assignment.
199 constexpr __box&
200 operator=(__box&& __that) noexcept
201 {
202 static_assert(is_nothrow_move_constructible_v<_Tp>);
203 if (this != std::__addressof(__that))
204 {
205 _M_value.~_Tp();
206 std::construct_at(std::__addressof(_M_value), std::move(*__that));
207 }
208 return *this;
209 }
210
211 constexpr bool
212 has_value() const noexcept
213 { return true; };
214
215 constexpr _Tp&
216 operator*() noexcept
217 { return _M_value; }
218
219 constexpr const _Tp&
220 operator*() const noexcept
221 { return _M_value; }
222
223 constexpr _Tp*
224 operator->() noexcept
225 { return std::__addressof(_M_value); }
226
227 constexpr const _Tp*
228 operator->() const noexcept
229 { return std::__addressof(_M_value); }
230 };
231 } // namespace __detail
232
233 /// A view that contains exactly one element.
234 template<copy_constructible _Tp> requires is_object_v<_Tp>
235 class single_view : public view_interface<single_view<_Tp>>
236 {
237 public:
238 single_view() requires default_initializable<_Tp> = default;
239
240 constexpr explicit
241 single_view(const _Tp& __t)
242 noexcept(is_nothrow_copy_constructible_v<_Tp>)
243 : _M_value(__t)
244 { }
245
246 constexpr explicit
247 single_view(_Tp&& __t)
248 noexcept(is_nothrow_move_constructible_v<_Tp>)
249 : _M_value(std::move(__t))
250 { }
251
252 // _GLIBCXX_RESOLVE_LIB_DEFECTS
253 // 3428. single_view's in place constructor should be explicit
254 template<typename... _Args>
255 requires constructible_from<_Tp, _Args...>
256 constexpr explicit
257 single_view(in_place_t, _Args&&... __args)
258 noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
259 : _M_value{in_place, std::forward<_Args>(__args)...}
260 { }
261
262 constexpr _Tp*
263 begin() noexcept
264 { return data(); }
265
266 constexpr const _Tp*
267 begin() const noexcept
268 { return data(); }
269
270 constexpr _Tp*
271 end() noexcept
272 { return data() + 1; }
273
274 constexpr const _Tp*
275 end() const noexcept
276 { return data() + 1; }
277
278 static constexpr size_t
279 size() noexcept
280 { return 1; }
281
282 constexpr _Tp*
283 data() noexcept
284 { return _M_value.operator->(); }
285
286 constexpr const _Tp*
287 data() const noexcept
288 { return _M_value.operator->(); }
289
290 private:
291 [[no_unique_address]] __detail::__box<_Tp> _M_value;
292 };
293
294 template<typename _Tp>
295 single_view(_Tp) -> single_view<_Tp>;
296
297 namespace __detail
298 {
299 template<typename _Wp>
300 constexpr auto __to_signed_like(_Wp __w) noexcept
301 {
302 if constexpr (!integral<_Wp>)
303 return iter_difference_t<_Wp>();
304 else if constexpr (sizeof(iter_difference_t<_Wp>) > sizeof(_Wp))
305 return iter_difference_t<_Wp>(__w);
306 else if constexpr (sizeof(ptrdiff_t) > sizeof(_Wp))
307 return ptrdiff_t(__w);
308 else if constexpr (sizeof(long long) > sizeof(_Wp))
309 return (long long)(__w);
310#ifdef __SIZEOF_INT128__
311 else if constexpr (__SIZEOF_INT128__ > sizeof(_Wp))
312 return __int128(__w);
313#endif
314 else
315 return __max_diff_type(__w);
316 }
317
318 template<typename _Wp>
319 using __iota_diff_t = decltype(__to_signed_like(std::declval<_Wp>()));
320
321 template<typename _It>
322 concept __decrementable = incrementable<_It>
323 && requires(_It __i)
324 {
325 { --__i } -> same_as<_It&>;
326 { __i-- } -> same_as<_It>;
327 };
328
329 template<typename _It>
330 concept __advanceable = __decrementable<_It> && totally_ordered<_It>
331 && requires( _It __i, const _It __j, const __iota_diff_t<_It> __n)
332 {
333 { __i += __n } -> same_as<_It&>;
334 { __i -= __n } -> same_as<_It&>;
335 _It(__j + __n);
336 _It(__n + __j);
337 _It(__j - __n);
338 { __j - __j } -> convertible_to<__iota_diff_t<_It>>;
339 };
340
341 template<typename _Winc>
342 struct __iota_view_iter_cat
343 { };
344
345 template<incrementable _Winc>
346 struct __iota_view_iter_cat<_Winc>
347 { using iterator_category = input_iterator_tag; };
348 } // namespace __detail
349
350 template<weakly_incrementable _Winc,
351 semiregular _Bound = unreachable_sentinel_t>
352 requires std::__detail::__weakly_eq_cmp_with<_Winc, _Bound>
353 && copyable<_Winc>
354 class iota_view : public view_interface<iota_view<_Winc, _Bound>>
355 {
356 private:
357 struct _Sentinel;
358
359 struct _Iterator : __detail::__iota_view_iter_cat<_Winc>
360 {
361 private:
362 static auto
363 _S_iter_concept()
364 {
365 using namespace __detail;
366 if constexpr (__advanceable<_Winc>)
367 return random_access_iterator_tag{};
368 else if constexpr (__decrementable<_Winc>)
369 return bidirectional_iterator_tag{};
370 else if constexpr (incrementable<_Winc>)
371 return forward_iterator_tag{};
372 else
373 return input_iterator_tag{};
374 }
375
376 public:
377 using iterator_concept = decltype(_S_iter_concept());
378 // iterator_category defined in __iota_view_iter_cat
379 using value_type = _Winc;
380 using difference_type = __detail::__iota_diff_t<_Winc>;
381
382 _Iterator() requires default_initializable<_Winc> = default;
383
384 constexpr explicit
385 _Iterator(_Winc __value)
386 : _M_value(__value) { }
387
388 constexpr _Winc
389 operator*() const noexcept(is_nothrow_copy_constructible_v<_Winc>)
390 { return _M_value; }
391
392 constexpr _Iterator&
393 operator++()
394 {
395 ++_M_value;
396 return *this;
397 }
398
399 constexpr void
400 operator++(int)
401 { ++*this; }
402
403 constexpr _Iterator
404 operator++(int) requires incrementable<_Winc>
405 {
406 auto __tmp = *this;
407 ++*this;
408 return __tmp;
409 }
410
411 constexpr _Iterator&
412 operator--() requires __detail::__decrementable<_Winc>
413 {
414 --_M_value;
415 return *this;
416 }
417
418 constexpr _Iterator
419 operator--(int) requires __detail::__decrementable<_Winc>
420 {
421 auto __tmp = *this;
422 --*this;
423 return __tmp;
424 }
425
426 constexpr _Iterator&
427 operator+=(difference_type __n) requires __detail::__advanceable<_Winc>
428 {
429 using __detail::__is_integer_like;
430 using __detail::__is_signed_integer_like;
431 if constexpr (__is_integer_like<_Winc>
432 && !__is_signed_integer_like<_Winc>)
433 {
434 if (__n >= difference_type(0))
435 _M_value += static_cast<_Winc>(__n);
436 else
437 _M_value -= static_cast<_Winc>(-__n);
438 }
439 else
440 _M_value += __n;
441 return *this;
442 }
443
444 constexpr _Iterator&
445 operator-=(difference_type __n) requires __detail::__advanceable<_Winc>
446 {
447 using __detail::__is_integer_like;
448 using __detail::__is_signed_integer_like;
449 if constexpr (__is_integer_like<_Winc>
450 && !__is_signed_integer_like<_Winc>)
451 {
452 if (__n >= difference_type(0))
453 _M_value -= static_cast<_Winc>(__n);
454 else
455 _M_value += static_cast<_Winc>(-__n);
456 }
457 else
458 _M_value -= __n;
459 return *this;
460 }
461
462 constexpr _Winc
463 operator[](difference_type __n) const
464 requires __detail::__advanceable<_Winc>
465 { return _Winc(_M_value + __n); }
466
467 friend constexpr bool
468 operator==(const _Iterator& __x, const _Iterator& __y)
469 requires equality_comparable<_Winc>
470 { return __x._M_value == __y._M_value; }
471
472 friend constexpr bool
473 operator<(const _Iterator& __x, const _Iterator& __y)
474 requires totally_ordered<_Winc>
475 { return __x._M_value < __y._M_value; }
476
477 friend constexpr bool
478 operator>(const _Iterator& __x, const _Iterator& __y)
479 requires totally_ordered<_Winc>
480 { return __y < __x; }
481
482 friend constexpr bool
483 operator<=(const _Iterator& __x, const _Iterator& __y)
484 requires totally_ordered<_Winc>
485 { return !(__y < __x); }
486
487 friend constexpr bool
488 operator>=(const _Iterator& __x, const _Iterator& __y)
489 requires totally_ordered<_Winc>
490 { return !(__x < __y); }
491
492#ifdef __cpp_lib_three_way_comparison
493 friend constexpr auto
494 operator<=>(const _Iterator& __x, const _Iterator& __y)
495 requires totally_ordered<_Winc> && three_way_comparable<_Winc>
496 { return __x._M_value <=> __y._M_value; }
497#endif
498
499 friend constexpr _Iterator
500 operator+(_Iterator __i, difference_type __n)
501 requires __detail::__advanceable<_Winc>
502 {
503 __i += __n;
504 return __i;
505 }
506
507 friend constexpr _Iterator
508 operator+(difference_type __n, _Iterator __i)
509 requires __detail::__advanceable<_Winc>
510 { return __i += __n; }
511
512 friend constexpr _Iterator
513 operator-(_Iterator __i, difference_type __n)
514 requires __detail::__advanceable<_Winc>
515 {
516 __i -= __n;
517 return __i;
518 }
519
520 friend constexpr difference_type
521 operator-(const _Iterator& __x, const _Iterator& __y)
522 requires __detail::__advanceable<_Winc>
523 {
524 using __detail::__is_integer_like;
525 using __detail::__is_signed_integer_like;
526 using _Dt = difference_type;
527 if constexpr (__is_integer_like<_Winc>)
528 {
529 if constexpr (__is_signed_integer_like<_Winc>)
530 return _Dt(_Dt(__x._M_value) - _Dt(__y._M_value));
531 else
532 return (__y._M_value > __x._M_value)
533 ? _Dt(-_Dt(__y._M_value - __x._M_value))
534 : _Dt(__x._M_value - __y._M_value);
535 }
536 else
537 return __x._M_value - __y._M_value;
538 }
539
540 private:
541 _Winc _M_value = _Winc();
542
543 friend iota_view;
544 friend _Sentinel;
545 };
546
547 struct _Sentinel
548 {
549 private:
550 constexpr bool
551 _M_equal(const _Iterator& __x) const
552 { return __x._M_value == _M_bound; }
553
554 constexpr auto
555 _M_distance_from(const _Iterator& __x) const
556 { return _M_bound - __x._M_value; }
557
558 _Bound _M_bound = _Bound();
559
560 public:
561 _Sentinel() = default;
562
563 constexpr explicit
564 _Sentinel(_Bound __bound)
565 : _M_bound(__bound) { }
566
567 friend constexpr bool
568 operator==(const _Iterator& __x, const _Sentinel& __y)
569 { return __y._M_equal(__x); }
570
571 friend constexpr iter_difference_t<_Winc>
572 operator-(const _Iterator& __x, const _Sentinel& __y)
573 requires sized_sentinel_for<_Bound, _Winc>
574 { return -__y._M_distance_from(__x); }
575
576 friend constexpr iter_difference_t<_Winc>
577 operator-(const _Sentinel& __x, const _Iterator& __y)
578 requires sized_sentinel_for<_Bound, _Winc>
579 { return __x._M_distance_from(__y); }
580
581 friend iota_view;
582 };
583
584 _Winc _M_value = _Winc();
585 [[no_unique_address]] _Bound _M_bound = _Bound();
586
587 public:
588 iota_view() requires default_initializable<_Winc> = default;
589
590 constexpr explicit
591 iota_view(_Winc __value)
592 : _M_value(__value)
593 { }
594
595 constexpr
596 iota_view(type_identity_t<_Winc> __value,
597 type_identity_t<_Bound> __bound)
598 : _M_value(__value), _M_bound(__bound)
599 {
600 if constexpr (totally_ordered_with<_Winc, _Bound>)
601 __glibcxx_assert( bool(__value <= __bound) );
602 }
603
604 constexpr
605 iota_view(_Iterator __first, _Iterator __last)
606 requires same_as<_Winc, _Bound>
607 : iota_view(__first._M_value, __last._M_value)
608 { }
609
610 constexpr
611 iota_view(_Iterator __first, unreachable_sentinel_t __last)
612 requires same_as<_Bound, unreachable_sentinel_t>
613 : iota_view(__first._M_value, __last)
614 { }
615
616 constexpr
617 iota_view(_Iterator __first, _Sentinel __last)
618 requires (!same_as<_Winc, _Bound>) && (!same_as<_Bound, unreachable_sentinel_t>)
619 : iota_view(__first._M_value, __last._M_bound)
620 { }
621
622 constexpr _Iterator
623 begin() const { return _Iterator{_M_value}; }
624
625 constexpr auto
626 end() const
627 {
628 if constexpr (same_as<_Bound, unreachable_sentinel_t>)
629 return unreachable_sentinel;
630 else
631 return _Sentinel{_M_bound};
632 }
633
634 constexpr _Iterator
635 end() const requires same_as<_Winc, _Bound>
636 { return _Iterator{_M_bound}; }
637
638 constexpr auto
639 size() const
640 requires (same_as<_Winc, _Bound> && __detail::__advanceable<_Winc>)
641 || (integral<_Winc> && integral<_Bound>)
642 || sized_sentinel_for<_Bound, _Winc>
643 {
644 using __detail::__is_integer_like;
645 using __detail::__to_unsigned_like;
646 if constexpr (integral<_Winc> && integral<_Bound>)
647 {
648 using _Up = make_unsigned_t<decltype(_M_bound - _M_value)>;
649 return _Up(_M_bound) - _Up(_M_value);
650 }
651 else if constexpr (__is_integer_like<_Winc>)
652 return __to_unsigned_like(_M_bound) - __to_unsigned_like(_M_value);
653 else
654 return __to_unsigned_like(_M_bound - _M_value);
655 }
656 };
657
658 template<typename _Winc, typename _Bound>
659 requires (!__detail::__is_integer_like<_Winc>
660 || !__detail::__is_integer_like<_Bound>
661 || (__detail::__is_signed_integer_like<_Winc>
662 == __detail::__is_signed_integer_like<_Bound>))
663 iota_view(_Winc, _Bound) -> iota_view<_Winc, _Bound>;
664
665 template<typename _Winc, typename _Bound>
666 inline constexpr bool
667 enable_borrowed_range<iota_view<_Winc, _Bound>> = true;
668
669namespace views
670{
671 template<typename _Tp>
672 inline constexpr empty_view<_Tp> empty{};
673
674 struct _Single
675 {
676 template<typename _Tp>
677 [[nodiscard]]
678 constexpr auto
679 operator()(_Tp&& __e) const
680 noexcept(noexcept(single_view<decay_t<_Tp>>(std::forward<_Tp>(__e))))
681 { return single_view<decay_t<_Tp>>(std::forward<_Tp>(__e)); }
682 };
683
684 inline constexpr _Single single{};
685
686 struct _Iota
687 {
688 template<typename _Tp>
689 [[nodiscard]]
690 constexpr auto
691 operator()(_Tp&& __e) const
692 { return iota_view(std::forward<_Tp>(__e)); }
693
694 template<typename _Tp, typename _Up>
695 [[nodiscard]]
696 constexpr auto
697 operator()(_Tp&& __e, _Up&& __f) const
698 { return iota_view(std::forward<_Tp>(__e), std::forward<_Up>(__f)); }
699 };
700
701 inline constexpr _Iota iota{};
702} // namespace views
703
704 namespace __detail
705 {
706 template<typename _Val, typename _CharT, typename _Traits>
707 concept __stream_extractable
708 = requires(basic_istream<_CharT, _Traits>& is, _Val& t) { is >> t; };
709 } // namespace __detail
710
711 template<movable _Val, typename _CharT,
712 typename _Traits = char_traits<_CharT>>
713 requires default_initializable<_Val>
714 && __detail::__stream_extractable<_Val, _CharT, _Traits>
715 class basic_istream_view
716 : public view_interface<basic_istream_view<_Val, _CharT, _Traits>>
717 {
718 public:
719 constexpr explicit
720 basic_istream_view(basic_istream<_CharT, _Traits>& __stream)
721 : _M_stream(std::__addressof(__stream))
722 { }
723
724 constexpr auto
725 begin()
726 {
727 *_M_stream >> _M_object;
728 return _Iterator{this};
729 }
730
731 constexpr default_sentinel_t
732 end() const noexcept
733 { return default_sentinel; }
734
735 private:
736 basic_istream<_CharT, _Traits>* _M_stream;
737 _Val _M_object = _Val();
738
739 struct _Iterator
740 {
741 public:
742 using iterator_concept = input_iterator_tag;
743 using difference_type = ptrdiff_t;
744 using value_type = _Val;
745
746 constexpr explicit
747 _Iterator(basic_istream_view* __parent) noexcept
748 : _M_parent(__parent)
749 { }
750
751 _Iterator(const _Iterator&) = delete;
752 _Iterator(_Iterator&&) = default;
753 _Iterator& operator=(const _Iterator&) = delete;
754 _Iterator& operator=(_Iterator&&) = default;
755
756 _Iterator&
757 operator++()
758 {
759 *_M_parent->_M_stream >> _M_parent->_M_object;
760 return *this;
761 }
762
763 void
764 operator++(int)
765 { ++*this; }
766
767 _Val&
768 operator*() const
769 { return _M_parent->_M_object; }
770
771 friend bool
772 operator==(const _Iterator& __x, default_sentinel_t)
773 { return __x._M_at_end(); }
774
775 private:
776 basic_istream_view* _M_parent;
777
778 bool
779 _M_at_end() const
780 { return !*_M_parent->_M_stream; }
781 };
782
783 friend _Iterator;
784 };
785
786 template<typename _Val>
787 using istream_view = basic_istream_view<_Val, char>;
788
789 template<typename _Val>
790 using wistream_view = basic_istream_view<_Val, wchar_t>;
791
792namespace views
793{
794 template<typename _Tp>
795 struct _Istream
796 {
797 template<typename _CharT, typename _Traits>
798 [[nodiscard]]
799 constexpr auto
800 operator()(basic_istream<_CharT, _Traits>& __e) const
801 { return basic_istream_view<_Tp, _CharT, _Traits>(__e); }
802 };
803
804 template<typename _Tp>
805 inline constexpr _Istream<_Tp> istream;
806}
807
808 // C++20 24.7 [range.adaptors] Range adaptors
809
810namespace __detail
811{
812 struct _Empty { };
813
814 // Alias for a type that is conditionally present
815 // (and is an empty type otherwise).
816 // Data members using this alias should use [[no_unique_address]] so that
817 // they take no space when not needed.
818 template<bool _Present, typename _Tp>
819 using __maybe_present_t = __conditional_t<_Present, _Tp, _Empty>;
820
821 // Alias for a type that is conditionally const.
822 template<bool _Const, typename _Tp>
823 using __maybe_const_t = __conditional_t<_Const, const _Tp, _Tp>;
824
825} // namespace __detail
826
827namespace views::__adaptor
828{
829 // True if the range adaptor _Adaptor can be applied with _Args.
830 template<typename _Adaptor, typename... _Args>
831 concept __adaptor_invocable
832 = requires { std::declval<_Adaptor>()(declval<_Args>()...); };
833
834 // True if the range adaptor non-closure _Adaptor can be partially applied
835 // with _Args.
836 template<typename _Adaptor, typename... _Args>
837 concept __adaptor_partial_app_viable = (_Adaptor::_S_arity > 1)
838 && (sizeof...(_Args) == _Adaptor::_S_arity - 1)
839 && (constructible_from<decay_t<_Args>, _Args> && ...);
840
841 template<typename _Adaptor, typename... _Args>
842 struct _Partial;
843
844 template<typename _Lhs, typename _Rhs>
845 struct _Pipe;
846
847 // The base class of every range adaptor closure.
848 //
849 // The derived class should define the optional static data member
850 // _S_has_simple_call_op to true if the behavior of this adaptor is
851 // independent of the constness/value category of the adaptor object.
852 struct _RangeAdaptorClosure
853 {
854 // range | adaptor is equivalent to adaptor(range).
855 template<typename _Self, typename _Range>
856 requires derived_from<remove_cvref_t<_Self>, _RangeAdaptorClosure>
857 && __adaptor_invocable<_Self, _Range>
858 friend constexpr auto
859 operator|(_Range&& __r, _Self&& __self)
860 { return std::forward<_Self>(__self)(std::forward<_Range>(__r)); }
861
862 // Compose the adaptors __lhs and __rhs into a pipeline, returning
863 // another range adaptor closure object.
864 template<typename _Lhs, typename _Rhs>
865 requires derived_from<_Lhs, _RangeAdaptorClosure>
866 && derived_from<_Rhs, _RangeAdaptorClosure>
867 friend constexpr auto
868 operator|(_Lhs __lhs, _Rhs __rhs)
869 { return _Pipe<_Lhs, _Rhs>{std::move(__lhs), std::move(__rhs)}; }
870 };
871
872 // The base class of every range adaptor non-closure.
873 //
874 // The static data member _Derived::_S_arity must contain the total number of
875 // arguments that the adaptor takes, and the class _Derived must introduce
876 // _RangeAdaptor::operator() into the class scope via a using-declaration.
877 //
878 // The optional static data member _Derived::_S_has_simple_extra_args should
879 // be defined to true if the behavior of this adaptor is independent of the
880 // constness/value category of the extra arguments. This data member could
881 // also be defined as a variable template parameterized by the types of the
882 // extra arguments.
883 template<typename _Derived>
884 struct _RangeAdaptor
885 {
886 // Partially apply the arguments __args to the range adaptor _Derived,
887 // returning a range adaptor closure object.
888 template<typename... _Args>
889 requires __adaptor_partial_app_viable<_Derived, _Args...>
890 constexpr auto
891 operator()(_Args&&... __args) const
892 {
893 return _Partial<_Derived, decay_t<_Args>...>{std::forward<_Args>(__args)...};
894 }
895 };
896
897 // True if the range adaptor closure _Adaptor has a simple operator(), i.e.
898 // one that's not overloaded according to constness or value category of the
899 // _Adaptor object.
900 template<typename _Adaptor>
901 concept __closure_has_simple_call_op = _Adaptor::_S_has_simple_call_op;
902
903 // True if the behavior of the range adaptor non-closure _Adaptor is
904 // independent of the value category of its extra arguments _Args.
905 template<typename _Adaptor, typename... _Args>
906 concept __adaptor_has_simple_extra_args = _Adaptor::_S_has_simple_extra_args
907 || _Adaptor::template _S_has_simple_extra_args<_Args...>;
908
909 // A range adaptor closure that represents partial application of
910 // the range adaptor _Adaptor with arguments _Args.
911 template<typename _Adaptor, typename... _Args>
912 struct _Partial : _RangeAdaptorClosure
913 {
914 tuple<_Args...> _M_args;
915
916 constexpr
917 _Partial(_Args... __args)
918 : _M_args(std::move(__args)...)
919 { }
920
921 // Invoke _Adaptor with arguments __r, _M_args... according to the
922 // value category of this _Partial object.
923 template<typename _Range>
924 requires __adaptor_invocable<_Adaptor, _Range, const _Args&...>
925 constexpr auto
926 operator()(_Range&& __r) const &
927 {
928 auto __forwarder = [&__r] (const auto&... __args) {
929 return _Adaptor{}(std::forward<_Range>(__r), __args...);
930 };
931 return std::apply(__forwarder, _M_args);
932 }
933
934 template<typename _Range>
935 requires __adaptor_invocable<_Adaptor, _Range, _Args...>
936 constexpr auto
937 operator()(_Range&& __r) &&
938 {
939 auto __forwarder = [&__r] (auto&... __args) {
940 return _Adaptor{}(std::forward<_Range>(__r), std::move(__args)...);
941 };
942 return std::apply(__forwarder, _M_args);
943 }
944
945 template<typename _Range>
946 constexpr auto
947 operator()(_Range&& __r) const && = delete;
948 };
949
950 // A lightweight specialization of the above primary template for
951 // the common case where _Adaptor accepts a single extra argument.
952 template<typename _Adaptor, typename _Arg>
953 struct _Partial<_Adaptor, _Arg> : _RangeAdaptorClosure
954 {
955 _Arg _M_arg;
956
957 constexpr
958 _Partial(_Arg __arg)
959 : _M_arg(std::move(__arg))
960 { }
961
962 template<typename _Range>
963 requires __adaptor_invocable<_Adaptor, _Range, const _Arg&>
964 constexpr auto
965 operator()(_Range&& __r) const &
966 { return _Adaptor{}(std::forward<_Range>(__r), _M_arg); }
967
968 template<typename _Range>
969 requires __adaptor_invocable<_Adaptor, _Range, _Arg>
970 constexpr auto
971 operator()(_Range&& __r) &&
972 { return _Adaptor{}(std::forward<_Range>(__r), std::move(_M_arg)); }
973
974 template<typename _Range>
975 constexpr auto
976 operator()(_Range&& __r) const && = delete;
977 };
978
979 // Partial specialization of the primary template for the case where the extra
980 // arguments of the adaptor can always be safely and efficiently forwarded by
981 // const reference. This lets us get away with a single operator() overload,
982 // which makes overload resolution failure diagnostics more concise.
983 template<typename _Adaptor, typename... _Args>
984 requires __adaptor_has_simple_extra_args<_Adaptor, _Args...>
985 && (is_trivially_copyable_v<_Args> && ...)
986 struct _Partial<_Adaptor, _Args...> : _RangeAdaptorClosure
987 {
988 tuple<_Args...> _M_args;
989
990 constexpr
991 _Partial(_Args... __args)
992 : _M_args(std::move(__args)...)
993 { }
994
995 // Invoke _Adaptor with arguments __r, const _M_args&... regardless
996 // of the value category of this _Partial object.
997 template<typename _Range>
998 requires __adaptor_invocable<_Adaptor, _Range, const _Args&...>
999 constexpr auto
1000 operator()(_Range&& __r) const
1001 {
1002 auto __forwarder = [&__r] (const auto&... __args) {
1003 return _Adaptor{}(std::forward<_Range>(__r), __args...);
1004 };
1005 return std::apply(__forwarder, _M_args);
1006 }
1007
1008 static constexpr bool _S_has_simple_call_op = true;
1009 };
1010
1011 // A lightweight specialization of the above template for the common case
1012 // where _Adaptor accepts a single extra argument.
1013 template<typename _Adaptor, typename _Arg>
1014 requires __adaptor_has_simple_extra_args<_Adaptor, _Arg>
1015 && is_trivially_copyable_v<_Arg>
1016 struct _Partial<_Adaptor, _Arg> : _RangeAdaptorClosure
1017 {
1018 _Arg _M_arg;
1019
1020 constexpr
1021 _Partial(_Arg __arg)
1022 : _M_arg(std::move(__arg))
1023 { }
1024
1025 template<typename _Range>
1026 requires __adaptor_invocable<_Adaptor, _Range, const _Arg&>
1027 constexpr auto
1028 operator()(_Range&& __r) const
1029 { return _Adaptor{}(std::forward<_Range>(__r), _M_arg); }
1030
1031 static constexpr bool _S_has_simple_call_op = true;
1032 };
1033
1034 template<typename _Lhs, typename _Rhs, typename _Range>
1035 concept __pipe_invocable
1036 = requires { std::declval<_Rhs>()(std::declval<_Lhs>()(std::declval<_Range>())); };
1037
1038 // A range adaptor closure that represents composition of the range
1039 // adaptor closures _Lhs and _Rhs.
1040 template<typename _Lhs, typename _Rhs>
1041 struct _Pipe : _RangeAdaptorClosure
1042 {
1043 [[no_unique_address]] _Lhs _M_lhs;
1044 [[no_unique_address]] _Rhs _M_rhs;
1045
1046 constexpr
1047 _Pipe(_Lhs __lhs, _Rhs __rhs)
1048 : _M_lhs(std::move(__lhs)), _M_rhs(std::move(__rhs))
1049 { }
1050
1051 // Invoke _M_rhs(_M_lhs(__r)) according to the value category of this
1052 // range adaptor closure object.
1053 template<typename _Range>
1054 requires __pipe_invocable<const _Lhs&, const _Rhs&, _Range>
1055 constexpr auto
1056 operator()(_Range&& __r) const &
1057 { return _M_rhs(_M_lhs(std::forward<_Range>(__r))); }
1058
1059 template<typename _Range>
1060 requires __pipe_invocable<_Lhs, _Rhs, _Range>
1061 constexpr auto
1062 operator()(_Range&& __r) &&
1063 { return std::move(_M_rhs)(std::move(_M_lhs)(std::forward<_Range>(__r))); }
1064
1065 template<typename _Range>
1066 constexpr auto
1067 operator()(_Range&& __r) const && = delete;
1068 };
1069
1070 // A partial specialization of the above primary template for the case where
1071 // both adaptor operands have a simple operator(). This in turn lets us
1072 // implement composition using a single simple operator(), which makes
1073 // overload resolution failure diagnostics more concise.
1074 template<typename _Lhs, typename _Rhs>
1075 requires __closure_has_simple_call_op<_Lhs>
1076 && __closure_has_simple_call_op<_Rhs>
1077 struct _Pipe<_Lhs, _Rhs> : _RangeAdaptorClosure
1078 {
1079 [[no_unique_address]] _Lhs _M_lhs;
1080 [[no_unique_address]] _Rhs _M_rhs;
1081
1082 constexpr
1083 _Pipe(_Lhs __lhs, _Rhs __rhs)
1084 : _M_lhs(std::move(__lhs)), _M_rhs(std::move(__rhs))
1085 { }
1086
1087 template<typename _Range>
1088 requires __pipe_invocable<const _Lhs&, const _Rhs&, _Range>
1089 constexpr auto
1090 operator()(_Range&& __r) const
1091 { return _M_rhs(_M_lhs(std::forward<_Range>(__r))); }
1092
1093 static constexpr bool _S_has_simple_call_op = true;
1094 };
1095} // namespace views::__adaptor
1096
1097 template<range _Range> requires is_object_v<_Range>
1098 class ref_view : public view_interface<ref_view<_Range>>
1099 {
1100 private:
1101 _Range* _M_r;
1102
1103 static void _S_fun(_Range&); // not defined
1104 static void _S_fun(_Range&&) = delete;
1105
1106 public:
1107 template<__detail::__different_from<ref_view> _Tp>
1108 requires convertible_to<_Tp, _Range&>
1109 && requires { _S_fun(declval<_Tp>()); }
1110 constexpr
1111 ref_view(_Tp&& __t)
1112 noexcept(noexcept(static_cast<_Range&>(std::declval<_Tp>())))
1113 : _M_r(std::__addressof(static_cast<_Range&>(std::forward<_Tp>(__t))))
1114 { }
1115
1116 constexpr _Range&
1117 base() const
1118 { return *_M_r; }
1119
1120 constexpr iterator_t<_Range>
1121 begin() const
1122 { return ranges::begin(*_M_r); }
1123
1124 constexpr sentinel_t<_Range>
1125 end() const
1126 { return ranges::end(*_M_r); }
1127
1128 constexpr bool
1129 empty() const requires requires { ranges::empty(*_M_r); }
1130 { return ranges::empty(*_M_r); }
1131
1132 constexpr auto
1133 size() const requires sized_range<_Range>
1134 { return ranges::size(*_M_r); }
1135
1136 constexpr auto
1137 data() const requires contiguous_range<_Range>
1138 { return ranges::data(*_M_r); }
1139 };
1140
1141 template<typename _Range>
1142 ref_view(_Range&) -> ref_view<_Range>;
1143
1144 template<typename _Tp>
1145 inline constexpr bool enable_borrowed_range<ref_view<_Tp>> = true;
1146
1147 template<range _Range>
1148 requires movable<_Range>
1149 && (!__detail::__is_initializer_list<remove_cv_t<_Range>>)
1150 class owning_view : public view_interface<owning_view<_Range>>
1151 {
1152 private:
1153 _Range _M_r = _Range();
1154
1155 public:
1156 owning_view() requires default_initializable<_Range> = default;
1157
1158 constexpr
1159 owning_view(_Range&& __t)
1160 noexcept(is_nothrow_move_constructible_v<_Range>)
1161 : _M_r(std::move(__t))
1162 { }
1163
1164 owning_view(owning_view&&) = default;
1165 owning_view& operator=(owning_view&&) = default;
1166
1167 constexpr _Range&
1168 base() & noexcept
1169 { return _M_r; }
1170
1171 constexpr const _Range&
1172 base() const& noexcept
1173 { return _M_r; }
1174
1175 constexpr _Range&&
1176 base() && noexcept
1177 { return std::move(_M_r); }
1178
1179 constexpr const _Range&&
1180 base() const&& noexcept
1181 { return std::move(_M_r); }
1182
1183 constexpr iterator_t<_Range>
1184 begin()
1185 { return ranges::begin(_M_r); }
1186
1187 constexpr sentinel_t<_Range>
1188 end()
1189 { return ranges::end(_M_r); }
1190
1191 constexpr auto
1192 begin() const requires range<const _Range>
1193 { return ranges::begin(_M_r); }
1194
1195 constexpr auto
1196 end() const requires range<const _Range>
1197 { return ranges::end(_M_r); }
1198
1199 constexpr bool
1200 empty() requires requires { ranges::empty(_M_r); }
1201 { return ranges::empty(_M_r); }
1202
1203 constexpr bool
1204 empty() const requires requires { ranges::empty(_M_r); }
1205 { return ranges::empty(_M_r); }
1206
1207 constexpr auto
1208 size() requires sized_range<_Range>
1209 { return ranges::size(_M_r); }
1210
1211 constexpr auto
1212 size() const requires sized_range<const _Range>
1213 { return ranges::size(_M_r); }
1214
1215 constexpr auto
1216 data() requires contiguous_range<_Range>
1217 { return ranges::data(_M_r); }
1218
1219 constexpr auto
1220 data() const requires contiguous_range<const _Range>
1221 { return ranges::data(_M_r); }
1222 };
1223
1224 template<typename _Tp>
1225 inline constexpr bool enable_borrowed_range<owning_view<_Tp>>
1226 = enable_borrowed_range<_Tp>;
1227
1228 namespace views
1229 {
1230 namespace __detail
1231 {
1232 template<typename _Range>
1233 concept __can_ref_view = requires { ref_view{std::declval<_Range>()}; };
1234
1235 template<typename _Range>
1236 concept __can_owning_view = requires { owning_view{std::declval<_Range>()}; };
1237 } // namespace __detail
1238
1239 struct _All : __adaptor::_RangeAdaptorClosure
1240 {
1241 template<typename _Range>
1242 static constexpr bool
1243 _S_noexcept()
1244 {
1245 if constexpr (view<decay_t<_Range>>)
1246 return is_nothrow_constructible_v<decay_t<_Range>, _Range>;
1247 else if constexpr (__detail::__can_ref_view<_Range>)
1248 return true;
1249 else
1250 return noexcept(owning_view{std::declval<_Range>()});
1251 }
1252
1253 template<viewable_range _Range>
1254 requires view<decay_t<_Range>>
1255 || __detail::__can_ref_view<_Range>
1256 || __detail::__can_owning_view<_Range>
1257 constexpr auto
1258 operator() [[nodiscard]] (_Range&& __r) const
1259 noexcept(_S_noexcept<_Range>())
1260 {
1261 if constexpr (view<decay_t<_Range>>)
1262 return std::forward<_Range>(__r);
1263 else if constexpr (__detail::__can_ref_view<_Range>)
1264 return ref_view{std::forward<_Range>(__r)};
1265 else
1266 return owning_view{std::forward<_Range>(__r)};
1267 }
1268
1269 static constexpr bool _S_has_simple_call_op = true;
1270 };
1271
1272 inline constexpr _All all;
1273
1274 template<viewable_range _Range>
1275 using all_t = decltype(all(std::declval<_Range>()));
1276 } // namespace views
1277
1278 namespace __detail
1279 {
1280 template<typename _Tp>
1281 struct __non_propagating_cache
1282 {
1283 // When _Tp is not an object type (e.g. is a reference type), we make
1284 // __non_propagating_cache<_Tp> empty rather than ill-formed so that
1285 // users can easily conditionally declare data members with this type
1286 // (such as join_view::_M_inner).
1287 };
1288
1289 template<typename _Tp>
1290 requires is_object_v<_Tp>
1291 struct __non_propagating_cache<_Tp>
1292 : protected _Optional_base<_Tp>
1293 {
1294 __non_propagating_cache() = default;
1295
1296 constexpr
1297 __non_propagating_cache(const __non_propagating_cache&) noexcept
1298 { }
1299
1300 constexpr
1301 __non_propagating_cache(__non_propagating_cache&& __other) noexcept
1302 { __other._M_reset(); }
1303
1304 constexpr __non_propagating_cache&
1305 operator=(const __non_propagating_cache& __other) noexcept
1306 {
1307 if (std::__addressof(__other) != this)
1308 this->_M_reset();
1309 return *this;
1310 }
1311
1312 constexpr __non_propagating_cache&
1313 operator=(__non_propagating_cache&& __other) noexcept
1314 {
1315 this->_M_reset();
1316 __other._M_reset();
1317 return *this;
1318 }
1319
1320 constexpr __non_propagating_cache&
1321 operator=(_Tp __val)
1322 {
1323 this->_M_reset();
1324 this->_M_payload._M_construct(std::move(__val));
1325 return *this;
1326 }
1327
1328 constexpr explicit
1329 operator bool() const noexcept
1330 { return this->_M_is_engaged(); }
1331
1332 constexpr _Tp&
1333 operator*() noexcept
1334 { return this->_M_get(); }
1335
1336 constexpr const _Tp&
1337 operator*() const noexcept
1338 { return this->_M_get(); }
1339
1340 template<typename _Iter>
1341 constexpr _Tp&
1342 _M_emplace_deref(const _Iter& __i)
1343 {
1344 this->_M_reset();
1345 auto __f = [] (auto& __x) { return *__x; };
1346 this->_M_payload._M_apply(_Optional_func{__f}, __i);
1347 return this->_M_get();
1348 }
1349 };
1350
1351 template<range _Range>
1352 struct _CachedPosition
1353 {
1354 constexpr bool
1355 _M_has_value() const
1356 { return false; }
1357
1358 constexpr iterator_t<_Range>
1359 _M_get(const _Range&) const
1360 {
1361 __glibcxx_assert(false);
1362 __builtin_unreachable();
1363 }
1364
1365 constexpr void
1366 _M_set(const _Range&, const iterator_t<_Range>&) const
1367 { }
1368 };
1369
1370 template<forward_range _Range>
1371 struct _CachedPosition<_Range>
1372 : protected __non_propagating_cache<iterator_t<_Range>>
1373 {
1374 constexpr bool
1375 _M_has_value() const
1376 { return this->_M_is_engaged(); }
1377
1378 constexpr iterator_t<_Range>
1379 _M_get(const _Range&) const
1380 {
1381 __glibcxx_assert(_M_has_value());
1382 return **this;
1383 }
1384
1385 constexpr void
1386 _M_set(const _Range&, const iterator_t<_Range>& __it)
1387 {
1388 __glibcxx_assert(!_M_has_value());
1389 std::construct_at(std::__addressof(this->_M_payload._M_payload),
1390 in_place, __it);
1391 this->_M_payload._M_engaged = true;
1392 }
1393 };
1394
1395 template<random_access_range _Range>
1396 requires (sizeof(range_difference_t<_Range>)
1397 <= sizeof(iterator_t<_Range>))
1398 struct _CachedPosition<_Range>
1399 {
1400 private:
1401 range_difference_t<_Range> _M_offset = -1;
1402
1403 public:
1404 _CachedPosition() = default;
1405
1406 constexpr
1407 _CachedPosition(const _CachedPosition&) = default;
1408
1409 constexpr
1410 _CachedPosition(_CachedPosition&& __other) noexcept
1411 { *this = std::move(__other); }
1412
1413 constexpr _CachedPosition&
1414 operator=(const _CachedPosition&) = default;
1415
1416 constexpr _CachedPosition&
1417 operator=(_CachedPosition&& __other) noexcept
1418 {
1419 // Propagate the cached offset, but invalidate the source.
1420 _M_offset = __other._M_offset;
1421 __other._M_offset = -1;
1422 return *this;
1423 }
1424
1425 constexpr bool
1426 _M_has_value() const
1427 { return _M_offset >= 0; }
1428
1429 constexpr iterator_t<_Range>
1430 _M_get(_Range& __r) const
1431 {
1432 __glibcxx_assert(_M_has_value());
1433 return ranges::begin(__r) + _M_offset;
1434 }
1435
1436 constexpr void
1437 _M_set(_Range& __r, const iterator_t<_Range>& __it)
1438 {
1439 __glibcxx_assert(!_M_has_value());
1440 _M_offset = __it - ranges::begin(__r);
1441 }
1442 };
1443 } // namespace __detail
1444
1445 namespace __detail
1446 {
1447 template<typename _Base>
1448 struct __filter_view_iter_cat
1449 { };
1450
1451 template<forward_range _Base>
1452 struct __filter_view_iter_cat<_Base>
1453 {
1454 private:
1455 static auto
1456 _S_iter_cat()
1457 {
1458 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
1459 if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
1460 return bidirectional_iterator_tag{};
1461 else if constexpr (derived_from<_Cat, forward_iterator_tag>)
1462 return forward_iterator_tag{};
1463 else
1464 return _Cat{};
1465 }
1466 public:
1467 using iterator_category = decltype(_S_iter_cat());
1468 };
1469 } // namespace __detail
1470
1471 template<input_range _Vp,
1472 indirect_unary_predicate<iterator_t<_Vp>> _Pred>
1473 requires view<_Vp> && is_object_v<_Pred>
1474 class filter_view : public view_interface<filter_view<_Vp, _Pred>>
1475 {
1476 private:
1477 struct _Sentinel;
1478
1479 struct _Iterator : __detail::__filter_view_iter_cat<_Vp>
1480 {
1481 private:
1482 static constexpr auto
1483 _S_iter_concept()
1484 {
1485 if constexpr (bidirectional_range<_Vp>)
1486 return bidirectional_iterator_tag{};
1487 else if constexpr (forward_range<_Vp>)
1488 return forward_iterator_tag{};
1489 else
1490 return input_iterator_tag{};
1491 }
1492
1493 friend filter_view;
1494
1495 using _Vp_iter = iterator_t<_Vp>;
1496
1497 _Vp_iter _M_current = _Vp_iter();
1498 filter_view* _M_parent = nullptr;
1499
1500 public:
1501 using iterator_concept = decltype(_S_iter_concept());
1502 // iterator_category defined in __filter_view_iter_cat
1503 using value_type = range_value_t<_Vp>;
1504 using difference_type = range_difference_t<_Vp>;
1505
1506 _Iterator() requires default_initializable<_Vp_iter> = default;
1507
1508 constexpr
1509 _Iterator(filter_view* __parent, _Vp_iter __current)
1510 : _M_current(std::move(__current)),
1511 _M_parent(__parent)
1512 { }
1513
1514 constexpr const _Vp_iter&
1515 base() const & noexcept
1516 { return _M_current; }
1517
1518 constexpr _Vp_iter
1519 base() &&
1520 { return std::move(_M_current); }
1521
1522 constexpr range_reference_t<_Vp>
1523 operator*() const
1524 { return *_M_current; }
1525
1526 constexpr _Vp_iter
1527 operator->() const
1528 requires __detail::__has_arrow<_Vp_iter>
1529 && copyable<_Vp_iter>
1530 { return _M_current; }
1531
1532 constexpr _Iterator&
1533 operator++()
1534 {
1535 _M_current = ranges::find_if(std::move(++_M_current),
1536 ranges::end(_M_parent->_M_base),
1537 std::ref(*_M_parent->_M_pred));
1538 return *this;
1539 }
1540
1541 constexpr void
1542 operator++(int)
1543 { ++*this; }
1544
1545 constexpr _Iterator
1546 operator++(int) requires forward_range<_Vp>
1547 {
1548 auto __tmp = *this;
1549 ++*this;
1550 return __tmp;
1551 }
1552
1553 constexpr _Iterator&
1554 operator--() requires bidirectional_range<_Vp>
1555 {
1556 do
1557 --_M_current;
1558 while (!std::__invoke(*_M_parent->_M_pred, *_M_current));
1559 return *this;
1560 }
1561
1562 constexpr _Iterator
1563 operator--(int) requires bidirectional_range<_Vp>
1564 {
1565 auto __tmp = *this;
1566 --*this;
1567 return __tmp;
1568 }
1569
1570 friend constexpr bool
1571 operator==(const _Iterator& __x, const _Iterator& __y)
1572 requires equality_comparable<_Vp_iter>
1573 { return __x._M_current == __y._M_current; }
1574
1575 friend constexpr range_rvalue_reference_t<_Vp>
1576 iter_move(const _Iterator& __i)
1577 noexcept(noexcept(ranges::iter_move(__i._M_current)))
1578 { return ranges::iter_move(__i._M_current); }
1579
1580 friend constexpr void
1581 iter_swap(const _Iterator& __x, const _Iterator& __y)
1582 noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
1583 requires indirectly_swappable<_Vp_iter>
1584 { ranges::iter_swap(__x._M_current, __y._M_current); }
1585 };
1586
1587 struct _Sentinel
1588 {
1589 private:
1590 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
1591
1592 constexpr bool
1593 __equal(const _Iterator& __i) const
1594 { return __i._M_current == _M_end; }
1595
1596 public:
1597 _Sentinel() = default;
1598
1599 constexpr explicit
1600 _Sentinel(filter_view* __parent)
1601 : _M_end(ranges::end(__parent->_M_base))
1602 { }
1603
1604 constexpr sentinel_t<_Vp>
1605 base() const
1606 { return _M_end; }
1607
1608 friend constexpr bool
1609 operator==(const _Iterator& __x, const _Sentinel& __y)
1610 { return __y.__equal(__x); }
1611 };
1612
1613 _Vp _M_base = _Vp();
1614 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
1615 [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;
1616
1617 public:
1618 filter_view() requires (default_initializable<_Vp>
1619 && default_initializable<_Pred>)
1620 = default;
1621
1622 constexpr
1623 filter_view(_Vp __base, _Pred __pred)
1624 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
1625 { }
1626
1627 constexpr _Vp
1628 base() const& requires copy_constructible<_Vp>
1629 { return _M_base; }
1630
1631 constexpr _Vp
1632 base() &&
1633 { return std::move(_M_base); }
1634
1635 constexpr const _Pred&
1636 pred() const
1637 { return *_M_pred; }
1638
1639 constexpr _Iterator
1640 begin()
1641 {
1642 if (_M_cached_begin._M_has_value())
1643 return {this, _M_cached_begin._M_get(_M_base)};
1644
1645 __glibcxx_assert(_M_pred.has_value());
1646 auto __it = ranges::find_if(ranges::begin(_M_base),
1647 ranges::end(_M_base),
1648 std::ref(*_M_pred));
1649 _M_cached_begin._M_set(_M_base, __it);
1650 return {this, std::move(__it)};
1651 }
1652
1653 constexpr auto
1654 end()
1655 {
1656 if constexpr (common_range<_Vp>)
1657 return _Iterator{this, ranges::end(_M_base)};
1658 else
1659 return _Sentinel{this};
1660 }
1661 };
1662
1663 template<typename _Range, typename _Pred>
1664 filter_view(_Range&&, _Pred) -> filter_view<views::all_t<_Range>, _Pred>;
1665
1666 namespace views
1667 {
1668 namespace __detail
1669 {
1670 template<typename _Range, typename _Pred>
1671 concept __can_filter_view
1672 = requires { filter_view(std::declval<_Range>(), std::declval<_Pred>()); };
1673 } // namespace __detail
1674
1675 struct _Filter : __adaptor::_RangeAdaptor<_Filter>
1676 {
1677 template<viewable_range _Range, typename _Pred>
1678 requires __detail::__can_filter_view<_Range, _Pred>
1679 constexpr auto
1680 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p) const
1681 {
1682 return filter_view(std::forward<_Range>(__r), std::forward<_Pred>(__p));
1683 }
1684
1685 using _RangeAdaptor<_Filter>::operator();
1686 static constexpr int _S_arity = 2;
1687 static constexpr bool _S_has_simple_extra_args = true;
1688 };
1689
1690 inline constexpr _Filter filter;
1691 } // namespace views
1692
1693 template<input_range _Vp, copy_constructible _Fp>
1694 requires view<_Vp> && is_object_v<_Fp>
1695 && regular_invocable<_Fp&, range_reference_t<_Vp>>
1696 && std::__detail::__can_reference<invoke_result_t<_Fp&,
1697 range_reference_t<_Vp>>>
1698 class transform_view : public view_interface<transform_view<_Vp, _Fp>>
1699 {
1700 private:
1701 template<bool _Const>
1702 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
1703
1704 template<bool _Const>
1705 struct __iter_cat
1706 { };
1707
1708 template<bool _Const>
1709 requires forward_range<_Base<_Const>>
1710 struct __iter_cat<_Const>
1711 {
1712 private:
1713 static auto
1714 _S_iter_cat()
1715 {
1716 using _Base = transform_view::_Base<_Const>;
1717 using _Res = invoke_result_t<_Fp&, range_reference_t<_Base>>;
1718 if constexpr (is_lvalue_reference_v<_Res>)
1719 {
1720 using _Cat
1721 = typename iterator_traits<iterator_t<_Base>>::iterator_category;
1722 if constexpr (derived_from<_Cat, contiguous_iterator_tag>)
1723 return random_access_iterator_tag{};
1724 else
1725 return _Cat{};
1726 }
1727 else
1728 return input_iterator_tag{};
1729 }
1730 public:
1731 using iterator_category = decltype(_S_iter_cat());
1732 };
1733
1734 template<bool _Const>
1735 struct _Sentinel;
1736
1737 template<bool _Const>
1738 struct _Iterator : __iter_cat<_Const>
1739 {
1740 private:
1741 using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
1742 using _Base = transform_view::_Base<_Const>;
1743
1744 static auto
1745 _S_iter_concept()
1746 {
1747 if constexpr (random_access_range<_Base>)
1748 return random_access_iterator_tag{};
1749 else if constexpr (bidirectional_range<_Base>)
1750 return bidirectional_iterator_tag{};
1751 else if constexpr (forward_range<_Base>)
1752 return forward_iterator_tag{};
1753 else
1754 return input_iterator_tag{};
1755 }
1756
1757 using _Base_iter = iterator_t<_Base>;
1758
1759 _Base_iter _M_current = _Base_iter();
1760 _Parent* _M_parent = nullptr;
1761
1762 public:
1763 using iterator_concept = decltype(_S_iter_concept());
1764 // iterator_category defined in __transform_view_iter_cat
1765 using value_type
1766 = remove_cvref_t<invoke_result_t<_Fp&, range_reference_t<_Base>>>;
1767 using difference_type = range_difference_t<_Base>;
1768
1769 _Iterator() requires default_initializable<_Base_iter> = default;
1770
1771 constexpr
1772 _Iterator(_Parent* __parent, _Base_iter __current)
1773 : _M_current(std::move(__current)),
1774 _M_parent(__parent)
1775 { }
1776
1777 constexpr
1778 _Iterator(_Iterator<!_Const> __i)
1779 requires _Const
1780 && convertible_to<iterator_t<_Vp>, _Base_iter>
1781 : _M_current(std::move(__i._M_current)), _M_parent(__i._M_parent)
1782 { }
1783
1784 constexpr const _Base_iter&
1785 base() const & noexcept
1786 { return _M_current; }
1787
1788 constexpr _Base_iter
1789 base() &&
1790 { return std::move(_M_current); }
1791
1792 constexpr decltype(auto)
1793 operator*() const
1794 noexcept(noexcept(std::__invoke(*_M_parent->_M_fun, *_M_current)))
1795 { return std::__invoke(*_M_parent->_M_fun, *_M_current); }
1796
1797 constexpr _Iterator&
1798 operator++()
1799 {
1800 ++_M_current;
1801 return *this;
1802 }
1803
1804 constexpr void
1805 operator++(int)
1806 { ++_M_current; }
1807
1808 constexpr _Iterator
1809 operator++(int) requires forward_range<_Base>
1810 {
1811 auto __tmp = *this;
1812 ++*this;
1813 return __tmp;
1814 }
1815
1816 constexpr _Iterator&
1817 operator--() requires bidirectional_range<_Base>
1818 {
1819 --_M_current;
1820 return *this;
1821 }
1822
1823 constexpr _Iterator
1824 operator--(int) requires bidirectional_range<_Base>
1825 {
1826 auto __tmp = *this;
1827 --*this;
1828 return __tmp;
1829 }
1830
1831 constexpr _Iterator&
1832 operator+=(difference_type __n) requires random_access_range<_Base>
1833 {
1834 _M_current += __n;
1835 return *this;
1836 }
1837
1838 constexpr _Iterator&
1839 operator-=(difference_type __n) requires random_access_range<_Base>
1840 {
1841 _M_current -= __n;
1842 return *this;
1843 }
1844
1845 constexpr decltype(auto)
1846 operator[](difference_type __n) const
1847 requires random_access_range<_Base>
1848 { return std::__invoke(*_M_parent->_M_fun, _M_current[__n]); }
1849
1850 friend constexpr bool
1851 operator==(const _Iterator& __x, const _Iterator& __y)
1852 requires equality_comparable<_Base_iter>
1853 { return __x._M_current == __y._M_current; }
1854
1855 friend constexpr bool
1856 operator<(const _Iterator& __x, const _Iterator& __y)
1857 requires random_access_range<_Base>
1858 { return __x._M_current < __y._M_current; }
1859
1860 friend constexpr bool
1861 operator>(const _Iterator& __x, const _Iterator& __y)
1862 requires random_access_range<_Base>
1863 { return __y < __x; }
1864
1865 friend constexpr bool
1866 operator<=(const _Iterator& __x, const _Iterator& __y)
1867 requires random_access_range<_Base>
1868 { return !(__y < __x); }
1869
1870 friend constexpr bool
1871 operator>=(const _Iterator& __x, const _Iterator& __y)
1872 requires random_access_range<_Base>
1873 { return !(__x < __y); }
1874
1875#ifdef __cpp_lib_three_way_comparison
1876 friend constexpr auto
1877 operator<=>(const _Iterator& __x, const _Iterator& __y)
1878 requires random_access_range<_Base>
1879 && three_way_comparable<_Base_iter>
1880 { return __x._M_current <=> __y._M_current; }
1881#endif
1882
1883 friend constexpr _Iterator
1884 operator+(_Iterator __i, difference_type __n)
1885 requires random_access_range<_Base>
1886 { return {__i._M_parent, __i._M_current + __n}; }
1887
1888 friend constexpr _Iterator
1889 operator+(difference_type __n, _Iterator __i)
1890 requires random_access_range<_Base>
1891 { return {__i._M_parent, __i._M_current + __n}; }
1892
1893 friend constexpr _Iterator
1894 operator-(_Iterator __i, difference_type __n)
1895 requires random_access_range<_Base>
1896 { return {__i._M_parent, __i._M_current - __n}; }
1897
1898 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1899 // 3483. transform_view::iterator's difference is overconstrained
1900 friend constexpr difference_type
1901 operator-(const _Iterator& __x, const _Iterator& __y)
1902 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
1903 { return __x._M_current - __y._M_current; }
1904
1905 friend constexpr decltype(auto)
1906 iter_move(const _Iterator& __i) noexcept(noexcept(*__i))
1907 {
1908 if constexpr (is_lvalue_reference_v<decltype(*__i)>)
1909 return std::move(*__i);
1910 else
1911 return *__i;
1912 }
1913
1914 friend _Iterator<!_Const>;
1915 template<bool> friend struct _Sentinel;
1916 };
1917
1918 template<bool _Const>
1919 struct _Sentinel
1920 {
1921 private:
1922 using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
1923 using _Base = transform_view::_Base<_Const>;
1924
1925 template<bool _Const2>
1926 constexpr auto
1927 __distance_from(const _Iterator<_Const2>& __i) const
1928 { return _M_end - __i._M_current; }
1929
1930 template<bool _Const2>
1931 constexpr bool
1932 __equal(const _Iterator<_Const2>& __i) const
1933 { return __i._M_current == _M_end; }
1934
1935 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
1936
1937 public:
1938 _Sentinel() = default;
1939
1940 constexpr explicit
1941 _Sentinel(sentinel_t<_Base> __end)
1942 : _M_end(__end)
1943 { }
1944
1945 constexpr
1946 _Sentinel(_Sentinel<!_Const> __i)
1947 requires _Const
1948 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
1949 : _M_end(std::move(__i._M_end))
1950 { }
1951
1952 constexpr sentinel_t<_Base>
1953 base() const
1954 { return _M_end; }
1955
1956 template<bool _Const2>
1957 requires sentinel_for<sentinel_t<_Base>,
1958 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
1959 friend constexpr bool
1960 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
1961 { return __y.__equal(__x); }
1962
1963 template<bool _Const2,
1964 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
1965 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
1966 friend constexpr range_difference_t<_Base2>
1967 operator-(const _Iterator<_Const2>& __x, const _Sentinel& __y)
1968 { return -__y.__distance_from(__x); }
1969
1970 template<bool _Const2,
1971 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
1972 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
1973 friend constexpr range_difference_t<_Base2>
1974 operator-(const _Sentinel& __y, const _Iterator<_Const2>& __x)
1975 { return __y.__distance_from(__x); }
1976
1977 friend _Sentinel<!_Const>;
1978 };
1979
1980 _Vp _M_base = _Vp();
1981 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
1982
1983 public:
1984 transform_view() requires (default_initializable<_Vp>
1985 && default_initializable<_Fp>)
1986 = default;
1987
1988 constexpr
1989 transform_view(_Vp __base, _Fp __fun)
1990 : _M_base(std::move(__base)), _M_fun(std::move(__fun))
1991 { }
1992
1993 constexpr _Vp
1994 base() const& requires copy_constructible<_Vp>
1995 { return _M_base ; }
1996
1997 constexpr _Vp
1998 base() &&
1999 { return std::move(_M_base); }
2000
2001 constexpr _Iterator<false>
2002 begin()
2003 { return _Iterator<false>{this, ranges::begin(_M_base)}; }
2004
2005 constexpr _Iterator<true>
2006 begin() const
2007 requires range<const _Vp>
2008 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2009 { return _Iterator<true>{this, ranges::begin(_M_base)}; }
2010
2011 constexpr _Sentinel<false>
2012 end()
2013 { return _Sentinel<false>{ranges::end(_M_base)}; }
2014
2015 constexpr _Iterator<false>
2016 end() requires common_range<_Vp>
2017 { return _Iterator<false>{this, ranges::end(_M_base)}; }
2018
2019 constexpr _Sentinel<true>
2020 end() const
2021 requires range<const _Vp>
2022 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2023 { return _Sentinel<true>{ranges::end(_M_base)}; }
2024
2025 constexpr _Iterator<true>
2026 end() const
2027 requires common_range<const _Vp>
2028 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2029 { return _Iterator<true>{this, ranges::end(_M_base)}; }
2030
2031 constexpr auto
2032 size() requires sized_range<_Vp>
2033 { return ranges::size(_M_base); }
2034
2035 constexpr auto
2036 size() const requires sized_range<const _Vp>
2037 { return ranges::size(_M_base); }
2038 };
2039
2040 template<typename _Range, typename _Fp>
2041 transform_view(_Range&&, _Fp) -> transform_view<views::all_t<_Range>, _Fp>;
2042
2043 namespace views
2044 {
2045 namespace __detail
2046 {
2047 template<typename _Range, typename _Fp>
2048 concept __can_transform_view
2049 = requires { transform_view(std::declval<_Range>(), std::declval<_Fp>()); };
2050 } // namespace __detail
2051
2052 struct _Transform : __adaptor::_RangeAdaptor<_Transform>
2053 {
2054 template<viewable_range _Range, typename _Fp>
2055 requires __detail::__can_transform_view<_Range, _Fp>
2056 constexpr auto
2057 operator() [[nodiscard]] (_Range&& __r, _Fp&& __f) const
2058 {
2059 return transform_view(std::forward<_Range>(__r), std::forward<_Fp>(__f));
2060 }
2061
2062 using _RangeAdaptor<_Transform>::operator();
2063 static constexpr int _S_arity = 2;
2064 static constexpr bool _S_has_simple_extra_args = true;
2065 };
2066
2067 inline constexpr _Transform transform;
2068 } // namespace views
2069
2070 template<view _Vp>
2071 class take_view : public view_interface<take_view<_Vp>>
2072 {
2073 private:
2074 template<bool _Const>
2075 using _CI = counted_iterator<
2076 iterator_t<__detail::__maybe_const_t<_Const, _Vp>>>;
2077
2078 template<bool _Const>
2079 struct _Sentinel
2080 {
2081 private:
2082 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2083 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2084
2085 public:
2086 _Sentinel() = default;
2087
2088 constexpr explicit
2089 _Sentinel(sentinel_t<_Base> __end)
2090 : _M_end(__end)
2091 { }
2092
2093 constexpr
2094 _Sentinel(_Sentinel<!_Const> __s)
2095 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2096 : _M_end(std::move(__s._M_end))
2097 { }
2098
2099 constexpr sentinel_t<_Base>
2100 base() const
2101 { return _M_end; }
2102
2103 friend constexpr bool
2104 operator==(const _CI<_Const>& __y, const _Sentinel& __x)
2105 { return __y.count() == 0 || __y.base() == __x._M_end; }
2106
2107 template<bool _OtherConst = !_Const,
2108 typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
2109 requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2110 friend constexpr bool
2111 operator==(const _CI<_OtherConst>& __y, const _Sentinel& __x)
2112 { return __y.count() == 0 || __y.base() == __x._M_end; }
2113
2114 friend _Sentinel<!_Const>;
2115 };
2116
2117 _Vp _M_base = _Vp();
2118 range_difference_t<_Vp> _M_count = 0;
2119
2120 public:
2121 take_view() requires default_initializable<_Vp> = default;
2122
2123 constexpr
2124 take_view(_Vp base, range_difference_t<_Vp> __count)
2125 : _M_base(std::move(base)), _M_count(std::move(__count))
2126 { }
2127
2128 constexpr _Vp
2129 base() const& requires copy_constructible<_Vp>
2130 { return _M_base; }
2131
2132 constexpr _Vp
2133 base() &&
2134 { return std::move(_M_base); }
2135
2136 constexpr auto
2137 begin() requires (!__detail::__simple_view<_Vp>)
2138 {
2139 if constexpr (sized_range<_Vp>)
2140 {
2141 if constexpr (random_access_range<_Vp>)
2142 return ranges::begin(_M_base);
2143 else
2144 {
2145 auto __sz = size();
2146 return counted_iterator(ranges::begin(_M_base), __sz);
2147 }
2148 }
2149 else
2150 return counted_iterator(ranges::begin(_M_base), _M_count);
2151 }
2152
2153 constexpr auto
2154 begin() const requires range<const _Vp>
2155 {
2156 if constexpr (sized_range<const _Vp>)
2157 {
2158 if constexpr (random_access_range<const _Vp>)
2159 return ranges::begin(_M_base);
2160 else
2161 {
2162 auto __sz = size();
2163 return counted_iterator(ranges::begin(_M_base), __sz);
2164 }
2165 }
2166 else
2167 return counted_iterator(ranges::begin(_M_base), _M_count);
2168 }
2169
2170 constexpr auto
2171 end() requires (!__detail::__simple_view<_Vp>)
2172 {
2173 if constexpr (sized_range<_Vp>)
2174 {
2175 if constexpr (random_access_range<_Vp>)
2176 return ranges::begin(_M_base) + size();
2177 else
2178 return default_sentinel;
2179 }
2180 else
2181 return _Sentinel<false>{ranges::end(_M_base)};
2182 }
2183
2184 constexpr auto
2185 end() const requires range<const _Vp>
2186 {
2187 if constexpr (sized_range<const _Vp>)
2188 {
2189 if constexpr (random_access_range<const _Vp>)
2190 return ranges::begin(_M_base) + size();
2191 else
2192 return default_sentinel;
2193 }
2194 else
2195 return _Sentinel<true>{ranges::end(_M_base)};
2196 }
2197
2198 constexpr auto
2199 size() requires sized_range<_Vp>
2200 {
2201 auto __n = ranges::size(_M_base);
2202 return std::min(__n, static_cast<decltype(__n)>(_M_count));
2203 }
2204
2205 constexpr auto
2206 size() const requires sized_range<const _Vp>
2207 {
2208 auto __n = ranges::size(_M_base);
2209 return std::min(__n, static_cast<decltype(__n)>(_M_count));
2210 }
2211 };
2212
2213 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2214 // 3447. Deduction guides for take_view and drop_view have different
2215 // constraints
2216 template<typename _Range>
2217 take_view(_Range&&, range_difference_t<_Range>)
2218 -> take_view<views::all_t<_Range>>;
2219
2220 template<typename _Tp>
2221 inline constexpr bool enable_borrowed_range<take_view<_Tp>>
2222 = enable_borrowed_range<_Tp>;
2223
2224 namespace views
2225 {
2226 namespace __detail
2227 {
2228 template<typename _Range>
2229 inline constexpr bool __is_empty_view = false;
2230
2231 template<typename _Tp>
2232 inline constexpr bool __is_empty_view<empty_view<_Tp>> = true;
2233
2234 template<typename _Range>
2235 inline constexpr bool __is_basic_string_view = false;
2236
2237 template<typename _CharT, typename _Traits>
2238 inline constexpr bool __is_basic_string_view<basic_string_view<_CharT, _Traits>>
2239 = true;
2240
2241 template<typename _Range>
2242 inline constexpr bool __is_subrange = false;
2243
2244 template<typename _Iter, typename _Sent, subrange_kind _Kind>
2245 inline constexpr bool __is_subrange<subrange<_Iter, _Sent, _Kind>> = true;
2246
2247 template<typename _Range>
2248 inline constexpr bool __is_iota_view = false;
2249
2250 template<typename _Winc, typename _Bound>
2251 inline constexpr bool __is_iota_view<iota_view<_Winc, _Bound>> = true;
2252
2253 template<typename _Range, typename _Dp>
2254 concept __can_take_view
2255 = requires { take_view(std::declval<_Range>(), std::declval<_Dp>()); };
2256 } // namespace __detail
2257
2258 struct _Take : __adaptor::_RangeAdaptor<_Take>
2259 {
2260 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
2261 requires __detail::__can_take_view<_Range, _Dp>
2262 constexpr auto
2263 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
2264 {
2265 using _Tp = remove_cvref_t<_Range>;
2266 if constexpr (__detail::__is_empty_view<_Tp>)
2267 return _Tp();
2268 else if constexpr (random_access_range<_Tp>
2269 && sized_range<_Tp>
2270 && (std::__detail::__is_span<_Tp>
2271 || __detail::__is_basic_string_view<_Tp>
2272 || __detail::__is_subrange<_Tp>
2273 || __detail::__is_iota_view<_Tp>))
2274 {
2275 __n = std::min<_Dp>(ranges::distance(__r), __n);
2276 auto __begin = ranges::begin(__r);
2277 auto __end = __begin + __n;
2278 if constexpr (std::__detail::__is_span<_Tp>)
2279 return span<typename _Tp::element_type>(__begin, __end);
2280 else if constexpr (__detail::__is_basic_string_view<_Tp>)
2281 return _Tp(__begin, __end);
2282 else if constexpr (__detail::__is_subrange<_Tp>)
2283 return subrange<iterator_t<_Tp>>(__begin, __end);
2284 else
2285 return iota_view(*__begin, *__end);
2286 }
2287 else
2288 return take_view(std::forward<_Range>(__r), __n);
2289 }
2290
2291 using _RangeAdaptor<_Take>::operator();
2292 static constexpr int _S_arity = 2;
2293 // The count argument of views::take is not always simple -- it can be
2294 // e.g. a move-only class that's implicitly convertible to the difference
2295 // type. But an integer-like count argument is surely simple.
2296 template<typename _Tp>
2297 static constexpr bool _S_has_simple_extra_args
2298 = ranges::__detail::__is_integer_like<_Tp>;
2299 };
2300
2301 inline constexpr _Take take;
2302 } // namespace views
2303
2304 template<view _Vp, typename _Pred>
2305 requires input_range<_Vp> && is_object_v<_Pred>
2306 && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
2307 class take_while_view : public view_interface<take_while_view<_Vp, _Pred>>
2308 {
2309 template<bool _Const>
2310 struct _Sentinel
2311 {
2312 private:
2313 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2314
2315 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2316 const _Pred* _M_pred = nullptr;
2317
2318 public:
2319 _Sentinel() = default;
2320
2321 constexpr explicit
2322 _Sentinel(sentinel_t<_Base> __end, const _Pred* __pred)
2323 : _M_end(__end), _M_pred(__pred)
2324 { }
2325
2326 constexpr
2327 _Sentinel(_Sentinel<!_Const> __s)
2328 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2329 : _M_end(__s._M_end), _M_pred(__s._M_pred)
2330 { }
2331
2332 constexpr sentinel_t<_Base>
2333 base() const { return _M_end; }
2334
2335 friend constexpr bool
2336 operator==(const iterator_t<_Base>& __x, const _Sentinel& __y)
2337 { return __y._M_end == __x || !std::__invoke(*__y._M_pred, *__x); }
2338
2339 template<bool _OtherConst = !_Const,
2340 typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
2341 requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2342 friend constexpr bool
2343 operator==(const iterator_t<_Base2>& __x, const _Sentinel& __y)
2344 { return __y._M_end == __x || !std::__invoke(*__y._M_pred, *__x); }
2345
2346 friend _Sentinel<!_Const>;
2347 };
2348
2349 _Vp _M_base = _Vp();
2350 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
2351
2352 public:
2353 take_while_view() requires (default_initializable<_Vp>
2354 && default_initializable<_Pred>)
2355 = default;
2356
2357 constexpr
2358 take_while_view(_Vp base, _Pred __pred)
2359 : _M_base(std::move(base)), _M_pred(std::move(__pred))
2360 { }
2361
2362 constexpr _Vp
2363 base() const& requires copy_constructible<_Vp>
2364 { return _M_base; }
2365
2366 constexpr _Vp
2367 base() &&
2368 { return std::move(_M_base); }
2369
2370 constexpr const _Pred&
2371 pred() const
2372 { return *_M_pred; }
2373
2374 constexpr auto
2375 begin() requires (!__detail::__simple_view<_Vp>)
2376 { return ranges::begin(_M_base); }
2377
2378 constexpr auto
2379 begin() const requires range<const _Vp>
2380 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
2381 { return ranges::begin(_M_base); }
2382
2383 constexpr auto
2384 end() requires (!__detail::__simple_view<_Vp>)
2385 { return _Sentinel<false>(ranges::end(_M_base),
2386 std::__addressof(*_M_pred)); }
2387
2388 constexpr auto
2389 end() const requires range<const _Vp>
2390 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
2391 { return _Sentinel<true>(ranges::end(_M_base),
2392 std::__addressof(*_M_pred)); }
2393 };
2394
2395 template<typename _Range, typename _Pred>
2396 take_while_view(_Range&&, _Pred)
2397 -> take_while_view<views::all_t<_Range>, _Pred>;
2398
2399 namespace views
2400 {
2401 namespace __detail
2402 {
2403 template<typename _Range, typename _Pred>
2404 concept __can_take_while_view
2405 = requires { take_while_view(std::declval<_Range>(), std::declval<_Pred>()); };
2406 } // namespace __detail
2407
2408 struct _TakeWhile : __adaptor::_RangeAdaptor<_TakeWhile>
2409 {
2410 template<viewable_range _Range, typename _Pred>
2411 requires __detail::__can_take_while_view<_Range, _Pred>
2412 constexpr auto
2413 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p) const
2414 {
2415 return take_while_view(std::forward<_Range>(__r), std::forward<_Pred>(__p));
2416 }
2417
2418 using _RangeAdaptor<_TakeWhile>::operator();
2419 static constexpr int _S_arity = 2;
2420 static constexpr bool _S_has_simple_extra_args = true;
2421 };
2422
2423 inline constexpr _TakeWhile take_while;
2424 } // namespace views
2425
2426 template<view _Vp>
2427 class drop_view : public view_interface<drop_view<_Vp>>
2428 {
2429 private:
2430 _Vp _M_base = _Vp();
2431 range_difference_t<_Vp> _M_count = 0;
2432
2433 // ranges::next(begin(base), count, end(base)) is O(1) if _Vp satisfies
2434 // both random_access_range and sized_range. Otherwise, cache its result.
2435 static constexpr bool _S_needs_cached_begin
2436 = !(random_access_range<const _Vp> && sized_range<const _Vp>);
2437 [[no_unique_address]]
2438 __detail::__maybe_present_t<_S_needs_cached_begin,
2439 __detail::_CachedPosition<_Vp>>
2440 _M_cached_begin;
2441
2442 public:
2443 drop_view() requires default_initializable<_Vp> = default;
2444
2445 constexpr
2446 drop_view(_Vp __base, range_difference_t<_Vp> __count)
2447 : _M_base(std::move(__base)), _M_count(__count)
2448 { __glibcxx_assert(__count >= 0); }
2449
2450 constexpr _Vp
2451 base() const& requires copy_constructible<_Vp>
2452 { return _M_base; }
2453
2454 constexpr _Vp
2455 base() &&
2456 { return std::move(_M_base); }
2457
2458 // This overload is disabled for simple views with constant-time begin().
2459 constexpr auto
2460 begin()
2461 requires (!(__detail::__simple_view<_Vp>
2462 && random_access_range<const _Vp>
2463 && sized_range<const _Vp>))
2464 {
2465 if constexpr (_S_needs_cached_begin)
2466 if (_M_cached_begin._M_has_value())
2467 return _M_cached_begin._M_get(_M_base);
2468
2469 auto __it = ranges::next(ranges::begin(_M_base),
2470 _M_count, ranges::end(_M_base));
2471 if constexpr (_S_needs_cached_begin)
2472 _M_cached_begin._M_set(_M_base, __it);
2473 return __it;
2474 }
2475
2476 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2477 // 3482. drop_view's const begin should additionally require sized_range
2478 constexpr auto
2479 begin() const
2480 requires random_access_range<const _Vp> && sized_range<const _Vp>
2481 {
2482 return ranges::next(ranges::begin(_M_base), _M_count,
2483 ranges::end(_M_base));
2484 }
2485
2486 constexpr auto
2487 end() requires (!__detail::__simple_view<_Vp>)
2488 { return ranges::end(_M_base); }
2489
2490 constexpr auto
2491 end() const requires range<const _Vp>
2492 { return ranges::end(_M_base); }
2493
2494 constexpr auto
2495 size() requires sized_range<_Vp>
2496 {
2497 const auto __s = ranges::size(_M_base);
2498 const auto __c = static_cast<decltype(__s)>(_M_count);
2499 return __s < __c ? 0 : __s - __c;
2500 }
2501
2502 constexpr auto
2503 size() const requires sized_range<const _Vp>
2504 {
2505 const auto __s = ranges::size(_M_base);
2506 const auto __c = static_cast<decltype(__s)>(_M_count);
2507 return __s < __c ? 0 : __s - __c;
2508 }
2509 };
2510
2511 template<typename _Range>
2512 drop_view(_Range&&, range_difference_t<_Range>)
2513 -> drop_view<views::all_t<_Range>>;
2514
2515 template<typename _Tp>
2516 inline constexpr bool enable_borrowed_range<drop_view<_Tp>>
2517 = enable_borrowed_range<_Tp>;
2518
2519 namespace views
2520 {
2521 namespace __detail
2522 {
2523 template<typename _Range, typename _Dp>
2524 concept __can_drop_view
2525 = requires { drop_view(std::declval<_Range>(), std::declval<_Dp>()); };
2526 } // namespace __detail
2527
2528 struct _Drop : __adaptor::_RangeAdaptor<_Drop>
2529 {
2530 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
2531 requires __detail::__can_drop_view<_Range, _Dp>
2532 constexpr auto
2533 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
2534 {
2535 using _Tp = remove_cvref_t<_Range>;
2536 if constexpr (__detail::__is_empty_view<_Tp>)
2537 return _Tp();
2538 else if constexpr (random_access_range<_Tp>
2539 && sized_range<_Tp>
2540 && (std::__detail::__is_span<_Tp>
2541 || __detail::__is_basic_string_view<_Tp>
2542 || __detail::__is_iota_view<_Tp>
2543 || __detail::__is_subrange<_Tp>))
2544 {
2545 __n = std::min<_Dp>(ranges::distance(__r), __n);
2546 auto __begin = ranges::begin(__r) + __n;
2547 auto __end = ranges::end(__r);
2548 if constexpr (std::__detail::__is_span<_Tp>)
2549 return span<typename _Tp::element_type>(__begin, __end);
2550 else if constexpr (__detail::__is_subrange<_Tp>)
2551 {
2552 if constexpr (_Tp::_S_store_size)
2553 {
2554 using ranges::__detail::__to_unsigned_like;
2555 auto __m = ranges::distance(__r) - __n;
2556 return _Tp(__begin, __end, __to_unsigned_like(__m));
2557 }
2558 else
2559 return _Tp(__begin, __end);
2560 }
2561 else
2562 return _Tp(__begin, __end);
2563 }
2564 else
2565 return drop_view(std::forward<_Range>(__r), __n);
2566 }
2567
2568 using _RangeAdaptor<_Drop>::operator();
2569 static constexpr int _S_arity = 2;
2570 template<typename _Tp>
2571 static constexpr bool _S_has_simple_extra_args
2572 = _Take::_S_has_simple_extra_args<_Tp>;
2573 };
2574
2575 inline constexpr _Drop drop;
2576 } // namespace views
2577
2578 template<view _Vp, typename _Pred>
2579 requires input_range<_Vp> && is_object_v<_Pred>
2580 && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
2581 class drop_while_view : public view_interface<drop_while_view<_Vp, _Pred>>
2582 {
2583 private:
2584 _Vp _M_base = _Vp();
2585 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
2586 [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;
2587
2588 public:
2589 drop_while_view() requires (default_initializable<_Vp>
2590 && default_initializable<_Pred>)
2591 = default;
2592
2593 constexpr
2594 drop_while_view(_Vp __base, _Pred __pred)
2595 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
2596 { }
2597
2598 constexpr _Vp
2599 base() const& requires copy_constructible<_Vp>
2600 { return _M_base; }
2601
2602 constexpr _Vp
2603 base() &&
2604 { return std::move(_M_base); }
2605
2606 constexpr const _Pred&
2607 pred() const
2608 { return *_M_pred; }
2609
2610 constexpr auto
2611 begin()
2612 {
2613 if (_M_cached_begin._M_has_value())
2614 return _M_cached_begin._M_get(_M_base);
2615
2616 __glibcxx_assert(_M_pred.has_value());
2617 auto __it = ranges::find_if_not(ranges::begin(_M_base),
2618 ranges::end(_M_base),
2619 std::cref(*_M_pred));
2620 _M_cached_begin._M_set(_M_base, __it);
2621 return __it;
2622 }
2623
2624 constexpr auto
2625 end()
2626 { return ranges::end(_M_base); }
2627 };
2628
2629 template<typename _Range, typename _Pred>
2630 drop_while_view(_Range&&, _Pred)
2631 -> drop_while_view<views::all_t<_Range>, _Pred>;
2632
2633 template<typename _Tp, typename _Pred>
2634 inline constexpr bool enable_borrowed_range<drop_while_view<_Tp, _Pred>>
2635 = enable_borrowed_range<_Tp>;
2636
2637 namespace views
2638 {
2639 namespace __detail
2640 {
2641 template<typename _Range, typename _Pred>
2642 concept __can_drop_while_view
2643 = requires { drop_while_view(std::declval<_Range>(), std::declval<_Pred>()); };
2644 } // namespace __detail
2645
2646 struct _DropWhile : __adaptor::_RangeAdaptor<_DropWhile>
2647 {
2648 template<viewable_range _Range, typename _Pred>
2649 requires __detail::__can_drop_while_view<_Range, _Pred>
2650 constexpr auto
2651 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p) const
2652 {
2653 return drop_while_view(std::forward<_Range>(__r),
2654 std::forward<_Pred>(__p));
2655 }
2656
2657 using _RangeAdaptor<_DropWhile>::operator();
2658 static constexpr int _S_arity = 2;
2659 static constexpr bool _S_has_simple_extra_args = true;
2660 };
2661
2662 inline constexpr _DropWhile drop_while;
2663 } // namespace views
2664
2665 template<input_range _Vp>
2666 requires view<_Vp> && input_range<range_reference_t<_Vp>>
2667 class join_view : public view_interface<join_view<_Vp>>
2668 {
2669 private:
2670 using _InnerRange = range_reference_t<_Vp>;
2671
2672 template<bool _Const>
2673 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2674
2675 template<bool _Const>
2676 using _Outer_iter = iterator_t<_Base<_Const>>;
2677
2678 template<bool _Const>
2679 using _Inner_iter = iterator_t<range_reference_t<_Base<_Const>>>;
2680
2681 template<bool _Const>
2682 static constexpr bool _S_ref_is_glvalue
2683 = is_reference_v<range_reference_t<_Base<_Const>>>;
2684
2685 template<bool _Const>
2686 struct __iter_cat
2687 { };
2688
2689 template<bool _Const>
2690 requires _S_ref_is_glvalue<_Const>
2691 && forward_range<_Base<_Const>>
2692 && forward_range<range_reference_t<_Base<_Const>>>
2693 struct __iter_cat<_Const>
2694 {
2695 private:
2696 static constexpr auto
2697 _S_iter_cat()
2698 {
2699 using _Outer_iter = join_view::_Outer_iter<_Const>;
2700 using _Inner_iter = join_view::_Inner_iter<_Const>;
2701 using _OuterCat = typename iterator_traits<_Outer_iter>::iterator_category;
2702 using _InnerCat = typename iterator_traits<_Inner_iter>::iterator_category;
2703 if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag>
2704 && derived_from<_InnerCat, bidirectional_iterator_tag>
2705 && common_range<range_reference_t<_Base<_Const>>>)
2706 return bidirectional_iterator_tag{};
2707 else if constexpr (derived_from<_OuterCat, forward_iterator_tag>
2708 && derived_from<_InnerCat, forward_iterator_tag>)
2709 return forward_iterator_tag{};
2710 else
2711 return input_iterator_tag{};
2712 }
2713 public:
2714 using iterator_category = decltype(_S_iter_cat());
2715 };
2716
2717 template<bool _Const>
2718 struct _Sentinel;
2719
2720 template<bool _Const>
2721 struct _Iterator : __iter_cat<_Const>
2722 {
2723 private:
2724 using _Parent = __detail::__maybe_const_t<_Const, join_view>;
2725 using _Base = join_view::_Base<_Const>;
2726
2727 static constexpr bool _S_ref_is_glvalue
2728 = join_view::_S_ref_is_glvalue<_Const>;
2729
2730 constexpr void
2731 _M_satisfy()
2732 {
2733 auto __update_inner = [this] (const iterator_t<_Base>& __x) -> auto&& {
2734 if constexpr (_S_ref_is_glvalue)
2735 return *__x;
2736 else
2737 return _M_parent->_M_inner._M_emplace_deref(__x);
2738 };
2739
2740 for (; _M_outer != ranges::end(_M_parent->_M_base); ++_M_outer)
2741 {
2742 auto&& __inner = __update_inner(_M_outer);
2743 _M_inner = ranges::begin(__inner);
2744 if (_M_inner != ranges::end(__inner))
2745 return;
2746 }
2747
2748 if constexpr (_S_ref_is_glvalue)
2749 _M_inner = _Inner_iter();
2750 }
2751
2752 static constexpr auto
2753 _S_iter_concept()
2754 {
2755 if constexpr (_S_ref_is_glvalue
2756 && bidirectional_range<_Base>
2757 && bidirectional_range<range_reference_t<_Base>>
2758 && common_range<range_reference_t<_Base>>)
2759 return bidirectional_iterator_tag{};
2760 else if constexpr (_S_ref_is_glvalue
2761 && forward_range<_Base>
2762 && forward_range<range_reference_t<_Base>>)
2763 return forward_iterator_tag{};
2764 else
2765 return input_iterator_tag{};
2766 }
2767
2768 using _Outer_iter = join_view::_Outer_iter<_Const>;
2769 using _Inner_iter = join_view::_Inner_iter<_Const>;
2770
2771 _Outer_iter _M_outer = _Outer_iter();
2772 _Inner_iter _M_inner = _Inner_iter();
2773 _Parent* _M_parent = nullptr;
2774
2775 public:
2776 using iterator_concept = decltype(_S_iter_concept());
2777 // iterator_category defined in __join_view_iter_cat
2778 using value_type = range_value_t<range_reference_t<_Base>>;
2779 using difference_type
2780 = common_type_t<range_difference_t<_Base>,
2781 range_difference_t<range_reference_t<_Base>>>;
2782
2783 _Iterator() requires (default_initializable<_Outer_iter>
2784 && default_initializable<_Inner_iter>)
2785 = default;
2786
2787 constexpr
2788 _Iterator(_Parent* __parent, _Outer_iter __outer)
2789 : _M_outer(std::move(__outer)),
2790 _M_parent(__parent)
2791 { _M_satisfy(); }
2792
2793 constexpr
2794 _Iterator(_Iterator<!_Const> __i)
2795 requires _Const
2796 && convertible_to<iterator_t<_Vp>, _Outer_iter>
2797 && convertible_to<iterator_t<_InnerRange>, _Inner_iter>
2798 : _M_outer(std::move(__i._M_outer)), _M_inner(std::move(__i._M_inner)),
2799 _M_parent(__i._M_parent)
2800 { }
2801
2802 constexpr decltype(auto)
2803 operator*() const
2804 { return *_M_inner; }
2805
2806 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2807 // 3500. join_view::iterator::operator->() is bogus
2808 constexpr _Inner_iter
2809 operator->() const
2810 requires __detail::__has_arrow<_Inner_iter>
2811 && copyable<_Inner_iter>
2812 { return _M_inner; }
2813
2814 constexpr _Iterator&
2815 operator++()
2816 {
2817 auto&& __inner_range = [this] () -> auto&& {
2818 if constexpr (_S_ref_is_glvalue)
2819 return *_M_outer;
2820 else
2821 return *_M_parent->_M_inner;
2822 }();
2823 if (++_M_inner == ranges::end(__inner_range))
2824 {
2825 ++_M_outer;
2826 _M_satisfy();
2827 }
2828 return *this;
2829 }
2830
2831 constexpr void
2832 operator++(int)
2833 { ++*this; }
2834
2835 constexpr _Iterator
2836 operator++(int)
2837 requires _S_ref_is_glvalue && forward_range<_Base>
2838 && forward_range<range_reference_t<_Base>>
2839 {
2840 auto __tmp = *this;
2841 ++*this;
2842 return __tmp;
2843 }
2844
2845 constexpr _Iterator&
2846 operator--()
2847 requires _S_ref_is_glvalue && bidirectional_range<_Base>
2848 && bidirectional_range<range_reference_t<_Base>>
2849 && common_range<range_reference_t<_Base>>
2850 {
2851 if (_M_outer == ranges::end(_M_parent->_M_base))
2852 _M_inner = ranges::end(*--_M_outer);
2853 while (_M_inner == ranges::begin(*_M_outer))
2854 _M_inner = ranges::end(*--_M_outer);
2855 --_M_inner;
2856 return *this;
2857 }
2858
2859 constexpr _Iterator
2860 operator--(int)
2861 requires _S_ref_is_glvalue && bidirectional_range<_Base>
2862 && bidirectional_range<range_reference_t<_Base>>
2863 && common_range<range_reference_t<_Base>>
2864 {
2865 auto __tmp = *this;
2866 --*this;
2867 return __tmp;
2868 }
2869
2870 friend constexpr bool
2871 operator==(const _Iterator& __x, const _Iterator& __y)
2872 requires _S_ref_is_glvalue
2873 && equality_comparable<_Outer_iter>
2874 && equality_comparable<_Inner_iter>
2875 {
2876 return (__x._M_outer == __y._M_outer
2877 && __x._M_inner == __y._M_inner);
2878 }
2879
2880 friend constexpr decltype(auto)
2881 iter_move(const _Iterator& __i)
2882 noexcept(noexcept(ranges::iter_move(__i._M_inner)))
2883 { return ranges::iter_move(__i._M_inner); }
2884
2885 friend constexpr void
2886 iter_swap(const _Iterator& __x, const _Iterator& __y)
2887 noexcept(noexcept(ranges::iter_swap(__x._M_inner, __y._M_inner)))
2888 requires indirectly_swappable<_Inner_iter>
2889 { return ranges::iter_swap(__x._M_inner, __y._M_inner); }
2890
2891 friend _Iterator<!_Const>;
2892 template<bool> friend struct _Sentinel;
2893 };
2894
2895 template<bool _Const>
2896 struct _Sentinel
2897 {
2898 private:
2899 using _Parent = __detail::__maybe_const_t<_Const, join_view>;
2900 using _Base = join_view::_Base<_Const>;
2901
2902 template<bool _Const2>
2903 constexpr bool
2904 __equal(const _Iterator<_Const2>& __i) const
2905 { return __i._M_outer == _M_end; }
2906
2907 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2908
2909 public:
2910 _Sentinel() = default;
2911
2912 constexpr explicit
2913 _Sentinel(_Parent* __parent)
2914 : _M_end(ranges::end(__parent->_M_base))
2915 { }
2916
2917 constexpr
2918 _Sentinel(_Sentinel<!_Const> __s)
2919 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2920 : _M_end(std::move(__s._M_end))
2921 { }
2922
2923 template<bool _Const2>
2924 requires sentinel_for<sentinel_t<_Base>,
2925 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
2926 friend constexpr bool
2927 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
2928 { return __y.__equal(__x); }
2929
2930 friend _Sentinel<!_Const>;
2931 };
2932
2933 _Vp _M_base = _Vp();
2934 [[no_unique_address]]
2935 __detail::__non_propagating_cache<remove_cv_t<_InnerRange>> _M_inner;
2936
2937 public:
2938 join_view() requires default_initializable<_Vp> = default;
2939
2940 constexpr explicit
2941 join_view(_Vp __base)
2942 : _M_base(std::move(__base))
2943 { }
2944
2945 constexpr _Vp
2946 base() const& requires copy_constructible<_Vp>
2947 { return _M_base; }
2948
2949 constexpr _Vp
2950 base() &&
2951 { return std::move(_M_base); }
2952
2953 constexpr auto
2954 begin()
2955 {
2956 constexpr bool __use_const
2957 = (__detail::__simple_view<_Vp>
2958 && is_reference_v<range_reference_t<_Vp>>);
2959 return _Iterator<__use_const>{this, ranges::begin(_M_base)};
2960 }
2961
2962 constexpr auto
2963 begin() const
2964 requires input_range<const _Vp>
2965 && is_reference_v<range_reference_t<const _Vp>>
2966 {
2967 return _Iterator<true>{this, ranges::begin(_M_base)};
2968 }
2969
2970 constexpr auto
2971 end()
2972 {
2973 if constexpr (forward_range<_Vp> && is_reference_v<_InnerRange>
2974 && forward_range<_InnerRange>
2975 && common_range<_Vp> && common_range<_InnerRange>)
2976 return _Iterator<__detail::__simple_view<_Vp>>{this,
2977 ranges::end(_M_base)};
2978 else
2979 return _Sentinel<__detail::__simple_view<_Vp>>{this};
2980 }
2981
2982 constexpr auto
2983 end() const
2984 requires input_range<const _Vp>
2985 && is_reference_v<range_reference_t<const _Vp>>
2986 {
2987 if constexpr (forward_range<const _Vp>
2988 && is_reference_v<range_reference_t<const _Vp>>
2989 && forward_range<range_reference_t<const _Vp>>
2990 && common_range<const _Vp>
2991 && common_range<range_reference_t<const _Vp>>)
2992 return _Iterator<true>{this, ranges::end(_M_base)};
2993 else
2994 return _Sentinel<true>{this};
2995 }
2996 };
2997
2998 template<typename _Range>
2999 explicit join_view(_Range&&) -> join_view<views::all_t<_Range>>;
3000
3001 namespace views
3002 {
3003 namespace __detail
3004 {
3005 template<typename _Range>
3006 concept __can_join_view
3007 = requires { join_view<all_t<_Range>>{std::declval<_Range>()}; };
3008 } // namespace __detail
3009
3010 struct _Join : __adaptor::_RangeAdaptorClosure
3011 {
3012 template<viewable_range _Range>
3013 requires __detail::__can_join_view<_Range>
3014 constexpr auto
3015 operator() [[nodiscard]] (_Range&& __r) const
3016 {
3017 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3018 // 3474. Nesting join_views is broken because of CTAD
3019 return join_view<all_t<_Range>>{std::forward<_Range>(__r)};
3020 }
3021
3022 static constexpr bool _S_has_simple_call_op = true;
3023 };
3024
3025 inline constexpr _Join join;
3026 } // namespace views
3027
3028 namespace __detail
3029 {
3030 template<auto>
3031 struct __require_constant;
3032
3033 template<typename _Range>
3034 concept __tiny_range = sized_range<_Range>
3035 && requires
3036 { typename __require_constant<remove_reference_t<_Range>::size()>; }
3037 && (remove_reference_t<_Range>::size() <= 1);
3038
3039 template<typename _Base>
3040 struct __lazy_split_view_outer_iter_cat
3041 { };
3042
3043 template<forward_range _Base>
3044 struct __lazy_split_view_outer_iter_cat<_Base>
3045 { using iterator_category = input_iterator_tag; };
3046
3047 template<typename _Base>
3048 struct __lazy_split_view_inner_iter_cat
3049 { };
3050
3051 template<forward_range _Base>
3052 struct __lazy_split_view_inner_iter_cat<_Base>
3053 {
3054 private:
3055 static constexpr auto
3056 _S_iter_cat()
3057 {
3058 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
3059 if constexpr (derived_from<_Cat, forward_iterator_tag>)
3060 return forward_iterator_tag{};
3061 else
3062 return _Cat{};
3063 }
3064 public:
3065 using iterator_category = decltype(_S_iter_cat());
3066 };
3067 }
3068
3069 template<input_range _Vp, forward_range _Pattern>
3070 requires view<_Vp> && view<_Pattern>
3071 && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
3072 ranges::equal_to>
3073 && (forward_range<_Vp> || __detail::__tiny_range<_Pattern>)
3074 class lazy_split_view : public view_interface<lazy_split_view<_Vp, _Pattern>>
3075 {
3076 private:
3077 template<bool _Const>
3078 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
3079
3080 template<bool _Const>
3081 struct _InnerIter;
3082
3083 template<bool _Const>
3084 struct _OuterIter
3085 : __detail::__lazy_split_view_outer_iter_cat<_Base<_Const>>
3086 {
3087 private:
3088 using _Parent = __detail::__maybe_const_t<_Const, lazy_split_view>;
3089 using _Base = lazy_split_view::_Base<_Const>;
3090
3091 constexpr bool
3092 __at_end() const
3093 { return __current() == ranges::end(_M_parent->_M_base) && !_M_trailing_empty; }
3094
3095 // [range.lazy.split.outer] p1
3096 // Many of the following specifications refer to the notional member
3097 // current of outer-iterator. current is equivalent to current_ if
3098 // V models forward_range, and parent_->current_ otherwise.
3099 constexpr auto&
3100 __current() noexcept
3101 {
3102 if constexpr (forward_range<_Vp>)
3103 return _M_current;
3104 else
3105 return *_M_parent->_M_current;
3106 }
3107
3108 constexpr auto&
3109 __current() const noexcept
3110 {
3111 if constexpr (forward_range<_Vp>)
3112 return _M_current;
3113 else
3114 return *_M_parent->_M_current;
3115 }
3116
3117 _Parent* _M_parent = nullptr;
3118
3119 // XXX: _M_current is present only if "V models forward_range"
3120 [[no_unique_address]]
3121 __detail::__maybe_present_t<forward_range<_Vp>,
3122 iterator_t<_Base>> _M_current;
3123 bool _M_trailing_empty = false;
3124
3125 public:
3126 using iterator_concept = __conditional_t<forward_range<_Base>,
3127 forward_iterator_tag,
3128 input_iterator_tag>;
3129 // iterator_category defined in __lazy_split_view_outer_iter_cat
3130 using difference_type = range_difference_t<_Base>;
3131
3132 struct value_type : view_interface<value_type>
3133 {
3134 private:
3135 _OuterIter _M_i = _OuterIter();
3136
3137 public:
3138 value_type() = default;
3139
3140 constexpr explicit
3141 value_type(_OuterIter __i)
3142 : _M_i(std::move(__i))
3143 { }
3144
3145 constexpr _InnerIter<_Const>
3146 begin() const
3147 { return _InnerIter<_Const>{_M_i}; }
3148
3149 constexpr default_sentinel_t
3150 end() const noexcept
3151 { return default_sentinel; }
3152 };
3153
3154 _OuterIter() = default;
3155
3156 constexpr explicit
3157 _OuterIter(_Parent* __parent) requires (!forward_range<_Base>)
3158 : _M_parent(__parent)
3159 { }
3160
3161 constexpr
3162 _OuterIter(_Parent* __parent, iterator_t<_Base> __current)
3163 requires forward_range<_Base>
3164 : _M_parent(__parent),
3165 _M_current(std::move(__current))
3166 { }
3167
3168 constexpr
3169 _OuterIter(_OuterIter<!_Const> __i)
3170 requires _Const
3171 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
3172 : _M_parent(__i._M_parent), _M_current(std::move(__i._M_current))
3173 { }
3174
3175 constexpr value_type
3176 operator*() const
3177 { return value_type{*this}; }
3178
3179 constexpr _OuterIter&
3180 operator++()
3181 {
3182 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3183 // 3505. lazy_split_view::outer-iterator::operator++ misspecified
3184 const auto __end = ranges::end(_M_parent->_M_base);
3185 if (__current() == __end)
3186 {
3187 _M_trailing_empty = false;
3188 return *this;
3189 }
3190 const auto [__pbegin, __pend] = subrange{_M_parent->_M_pattern};
3191 if (__pbegin == __pend)
3192 ++__current();
3193 else if constexpr (__detail::__tiny_range<_Pattern>)
3194 {
3195 __current() = ranges::find(std::move(__current()), __end,
3196 *__pbegin);
3197 if (__current() != __end)
3198 {
3199 ++__current();
3200 if (__current() == __end)
3201 _M_trailing_empty = true;
3202 }
3203 }
3204 else
3205 do
3206 {
3207 auto [__b, __p]
3208 = ranges::mismatch(__current(), __end, __pbegin, __pend);
3209 if (__p == __pend)
3210 {
3211 __current() = __b;
3212 if (__current() == __end)
3213 _M_trailing_empty = true;
3214 break;
3215 }
3216 } while (++__current() != __end);
3217 return *this;
3218 }
3219
3220 constexpr decltype(auto)
3221 operator++(int)
3222 {
3223 if constexpr (forward_range<_Base>)
3224 {
3225 auto __tmp = *this;
3226 ++*this;
3227 return __tmp;
3228 }
3229 else
3230 ++*this;
3231 }
3232
3233 friend constexpr bool
3234 operator==(const _OuterIter& __x, const _OuterIter& __y)
3235 requires forward_range<_Base>
3236 {
3237 return __x._M_current == __y._M_current
3238 && __x._M_trailing_empty == __y._M_trailing_empty;
3239 }
3240
3241 friend constexpr bool
3242 operator==(const _OuterIter& __x, default_sentinel_t)
3243 { return __x.__at_end(); };
3244
3245 friend _OuterIter<!_Const>;
3246 friend _InnerIter<_Const>;
3247 };
3248
3249 template<bool _Const>
3250 struct _InnerIter
3251 : __detail::__lazy_split_view_inner_iter_cat<_Base<_Const>>
3252 {
3253 private:
3254 using _Base = lazy_split_view::_Base<_Const>;
3255
3256 constexpr bool
3257 __at_end() const
3258 {
3259 auto [__pcur, __pend] = subrange{_M_i._M_parent->_M_pattern};
3260 auto __end = ranges::end(_M_i._M_parent->_M_base);
3261 if constexpr (__detail::__tiny_range<_Pattern>)
3262 {
3263 const auto& __cur = _M_i_current();
3264 if (__cur == __end)
3265 return true;
3266 if (__pcur == __pend)
3267 return _M_incremented;
3268 return *__cur == *__pcur;
3269 }
3270 else
3271 {
3272 auto __cur = _M_i_current();
3273 if (__cur == __end)
3274 return true;
3275 if (__pcur == __pend)
3276 return _M_incremented;
3277 do
3278 {
3279 if (*__cur != *__pcur)
3280 return false;
3281 if (++__pcur == __pend)
3282 return true;
3283 } while (++__cur != __end);
3284 return false;
3285 }
3286 }
3287
3288 constexpr auto&
3289 _M_i_current() noexcept
3290 { return _M_i.__current(); }
3291
3292 constexpr auto&
3293 _M_i_current() const noexcept
3294 { return _M_i.__current(); }
3295
3296 _OuterIter<_Const> _M_i = _OuterIter<_Const>();
3297 bool _M_incremented = false;
3298
3299 public:
3300 using iterator_concept
3301 = typename _OuterIter<_Const>::iterator_concept;
3302 // iterator_category defined in __lazy_split_view_inner_iter_cat
3303 using value_type = range_value_t<_Base>;
3304 using difference_type = range_difference_t<_Base>;
3305
3306 _InnerIter() = default;
3307
3308 constexpr explicit
3309 _InnerIter(_OuterIter<_Const> __i)
3310 : _M_i(std::move(__i))
3311 { }
3312
3313 constexpr const iterator_t<_Base>&
3314 base() const& noexcept
3315 { return _M_i_current(); }
3316
3317 constexpr iterator_t<_Base>
3318 base() && requires forward_range<_Vp>
3319 { return std::move(_M_i_current()); }
3320
3321 constexpr decltype(auto)
3322 operator*() const
3323 { return *_M_i_current(); }
3324
3325 constexpr _InnerIter&
3326 operator++()
3327 {
3328 _M_incremented = true;
3329 if constexpr (!forward_range<_Base>)
3330 if constexpr (_Pattern::size() == 0)
3331 return *this;
3332 ++_M_i_current();
3333 return *this;
3334 }
3335
3336 constexpr decltype(auto)
3337 operator++(int)
3338 {
3339 if constexpr (forward_range<_Base>)
3340 {
3341 auto __tmp = *this;
3342 ++*this;
3343 return __tmp;
3344 }
3345 else
3346 ++*this;
3347 }
3348
3349 friend constexpr bool
3350 operator==(const _InnerIter& __x, const _InnerIter& __y)
3351 requires forward_range<_Base>
3352 { return __x._M_i == __y._M_i; }
3353
3354 friend constexpr bool
3355 operator==(const _InnerIter& __x, default_sentinel_t)
3356 { return __x.__at_end(); }
3357
3358 friend constexpr decltype(auto)
3359 iter_move(const _InnerIter& __i)
3360 noexcept(noexcept(ranges::iter_move(__i._M_i_current())))
3361 { return ranges::iter_move(__i._M_i_current()); }
3362
3363 friend constexpr void
3364 iter_swap(const _InnerIter& __x, const _InnerIter& __y)
3365 noexcept(noexcept(ranges::iter_swap(__x._M_i_current(),
3366 __y._M_i_current())))
3367 requires indirectly_swappable<iterator_t<_Base>>
3368 { ranges::iter_swap(__x._M_i_current(), __y._M_i_current()); }
3369 };
3370
3371 _Vp _M_base = _Vp();
3372 _Pattern _M_pattern = _Pattern();
3373 // XXX: _M_current is "present only if !forward_range<V>"
3374 [[no_unique_address]]
3375 __detail::__maybe_present_t<!forward_range<_Vp>,
3376 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_current;
3377
3378
3379 public:
3380 lazy_split_view() requires (default_initializable<_Vp>
3381 && default_initializable<_Pattern>)
3382 = default;
3383
3384 constexpr
3385 lazy_split_view(_Vp __base, _Pattern __pattern)
3386 : _M_base(std::move(__base)), _M_pattern(std::move(__pattern))
3387 { }
3388
3389 template<input_range _Range>
3390 requires constructible_from<_Vp, views::all_t<_Range>>
3391 && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
3392 constexpr
3393 lazy_split_view(_Range&& __r, range_value_t<_Range> __e)
3394 : _M_base(views::all(std::forward<_Range>(__r))),
3395 _M_pattern(views::single(std::move(__e)))
3396 { }
3397
3398 constexpr _Vp
3399 base() const& requires copy_constructible<_Vp>
3400 { return _M_base; }
3401
3402 constexpr _Vp
3403 base() &&
3404 { return std::move(_M_base); }
3405
3406 constexpr auto
3407 begin()
3408 {
3409 if constexpr (forward_range<_Vp>)
3410 {
3411 constexpr bool __simple
3412 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
3413 return _OuterIter<__simple>{this, ranges::begin(_M_base)};
3414 }
3415 else
3416 {
3417 _M_current = ranges::begin(_M_base);
3418 return _OuterIter<false>{this};
3419 }
3420 }
3421
3422 constexpr auto
3423 begin() const requires forward_range<_Vp> && forward_range<const _Vp>
3424 {
3425 return _OuterIter<true>{this, ranges::begin(_M_base)};
3426 }
3427
3428 constexpr auto
3429 end() requires forward_range<_Vp> && common_range<_Vp>
3430 {
3431 constexpr bool __simple
3432 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
3433 return _OuterIter<__simple>{this, ranges::end(_M_base)};
3434 }
3435
3436 constexpr auto
3437 end() const
3438 {
3439 if constexpr (forward_range<_Vp>
3440 && forward_range<const _Vp>
3441 && common_range<const _Vp>)
3442 return _OuterIter<true>{this, ranges::end(_M_base)};
3443 else
3444 return default_sentinel;
3445 }
3446 };
3447
3448 template<typename _Range, typename _Pattern>
3449 lazy_split_view(_Range&&, _Pattern&&)
3450 -> lazy_split_view<views::all_t<_Range>, views::all_t<_Pattern>>;
3451
3452 template<input_range _Range>
3453 lazy_split_view(_Range&&, range_value_t<_Range>)
3454 -> lazy_split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;
3455
3456 namespace views
3457 {
3458 namespace __detail
3459 {
3460 template<typename _Range, typename _Pattern>
3461 concept __can_lazy_split_view
3462 = requires { lazy_split_view(std::declval<_Range>(), std::declval<_Pattern>()); };
3463 } // namespace __detail
3464
3465 struct _LazySplit : __adaptor::_RangeAdaptor<_LazySplit>
3466 {
3467 template<viewable_range _Range, typename _Pattern>
3468 requires __detail::__can_lazy_split_view<_Range, _Pattern>
3469 constexpr auto
3470 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f) const
3471 {
3472 return lazy_split_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
3473 }
3474
3475 using _RangeAdaptor<_LazySplit>::operator();
3476 static constexpr int _S_arity = 2;
3477 // The pattern argument of views::lazy_split is not always simple -- it can be
3478 // a non-view range, the value category of which affects whether the call
3479 // is well-formed. But a scalar or a view pattern argument is surely
3480 // simple.
3481 template<typename _Pattern>
3482 static constexpr bool _S_has_simple_extra_args
3483 = is_scalar_v<_Pattern> || (view<_Pattern>
3484 && copy_constructible<_Pattern>);
3485 };
3486
3487 inline constexpr _LazySplit lazy_split;
3488 } // namespace views
3489
3490 template<forward_range _Vp, forward_range _Pattern>
3491 requires view<_Vp> && view<_Pattern>
3492 && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
3493 ranges::equal_to>
3494 class split_view : public view_interface<split_view<_Vp, _Pattern>>
3495 {
3496 private:
3497 _Vp _M_base = _Vp();
3498 _Pattern _M_pattern = _Pattern();
3499 __detail::__non_propagating_cache<subrange<iterator_t<_Vp>>> _M_cached_begin;
3500
3501 struct _Iterator;
3502 struct _Sentinel;
3503
3504 public:
3505 split_view() requires (default_initializable<_Vp>
3506 && default_initializable<_Pattern>)
3507 = default;
3508
3509 constexpr
3510 split_view(_Vp __base, _Pattern __pattern)
3511 : _M_base(std::move(__base)), _M_pattern(std::move(__pattern))
3512 { }
3513
3514 template<forward_range _Range>
3515 requires constructible_from<_Vp, views::all_t<_Range>>
3516 && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
3517 constexpr
3518 split_view(_Range&& __r, range_value_t<_Range> __e)
3519 : _M_base(views::all(std::forward<_Range>(__r))),
3520 _M_pattern(views::single(std::move(__e)))
3521 { }
3522
3523 constexpr _Vp
3524 base() const& requires copy_constructible<_Vp>
3525 { return _M_base; }
3526
3527 constexpr _Vp
3528 base() &&
3529 { return std::move(_M_base); }
3530
3531 constexpr _Iterator
3532 begin()
3533 {
3534 if (!_M_cached_begin)
3535 _M_cached_begin = _M_find_next(ranges::begin(_M_base));
3536 return {this, ranges::begin(_M_base), *_M_cached_begin};
3537 }
3538
3539 constexpr auto
3540 end()
3541 {
3542 if constexpr (common_range<_Vp>)
3543 return _Iterator{this, ranges::end(_M_base), {}};
3544 else
3545 return _Sentinel{this};
3546 }
3547
3548 constexpr subrange<iterator_t<_Vp>>
3549 _M_find_next(iterator_t<_Vp> __it)
3550 {
3551 auto [__b, __e] = ranges::search(subrange(__it, ranges::end(_M_base)), _M_pattern);
3552 if (__b != ranges::end(_M_base) && ranges::empty(_M_pattern))
3553 {
3554 ++__b;
3555 ++__e;
3556 }
3557 return {__b, __e};
3558 }
3559
3560 private:
3561 struct _Iterator
3562 {
3563 private:
3564 split_view* _M_parent = nullptr;
3565 iterator_t<_Vp> _M_cur = iterator_t<_Vp>();
3566 subrange<iterator_t<_Vp>> _M_next = subrange<iterator_t<_Vp>>();
3567 bool _M_trailing_empty = false;
3568
3569 friend struct _Sentinel;
3570
3571 public:
3572 using iterator_concept = forward_iterator_tag;
3573 using iterator_category = input_iterator_tag;
3574 using value_type = subrange<iterator_t<_Vp>>;
3575 using difference_type = range_difference_t<_Vp>;
3576
3577 _Iterator() = default;
3578
3579 constexpr
3580 _Iterator(split_view* __parent,
3581 iterator_t<_Vp> __current,
3582 subrange<iterator_t<_Vp>> __next)
3583 : _M_parent(__parent),
3584 _M_cur(std::move(__current)),
3585 _M_next(std::move(__next))
3586 { }
3587
3588 constexpr iterator_t<_Vp>
3589 base() const
3590 { return _M_cur; }
3591
3592 constexpr value_type
3593 operator*() const
3594 { return {_M_cur, _M_next.begin()}; }
3595
3596 constexpr _Iterator&
3597 operator++()
3598 {
3599 _M_cur = _M_next.begin();
3600 if (_M_cur != ranges::end(_M_parent->_M_base))
3601 {
3602 _M_cur = _M_next.end();
3603 if (_M_cur == ranges::end(_M_parent->_M_base))
3604 {
3605 _M_trailing_empty = true;
3606 _M_next = {_M_cur, _M_cur};
3607 }
3608 else
3609 _M_next = _M_parent->_M_find_next(_M_cur);
3610 }
3611 else
3612 _M_trailing_empty = false;
3613 return *this;
3614 }
3615
3616 constexpr _Iterator
3617 operator++(int)
3618 {
3619 auto __tmp = *this;
3620 ++*this;
3621 return __tmp;
3622 }
3623
3624 friend constexpr bool
3625 operator==(const _Iterator& __x, const _Iterator& __y)
3626 {
3627 return __x._M_cur == __y._M_cur
3628 && __x._M_trailing_empty == __y._M_trailing_empty;
3629 }
3630 };
3631
3632 struct _Sentinel
3633 {
3634 private:
3635 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
3636
3637 constexpr bool
3638 _M_equal(const _Iterator& __x) const
3639 { return __x._M_cur == _M_end && !__x._M_trailing_empty; }
3640
3641 public:
3642 _Sentinel() = default;
3643
3644 constexpr explicit
3645 _Sentinel(split_view* __parent)
3646 : _M_end(ranges::end(__parent->_M_base))
3647 { }
3648
3649 friend constexpr bool
3650 operator==(const _Iterator& __x, const _Sentinel& __y)
3651 { return __y._M_equal(__x); }
3652 };
3653 };
3654
3655 template<typename _Range, typename _Pattern>
3656 split_view(_Range&&, _Pattern&&)
3657 -> split_view<views::all_t<_Range>, views::all_t<_Pattern>>;
3658
3659 template<forward_range _Range>
3660 split_view(_Range&&, range_value_t<_Range>)
3661 -> split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;
3662
3663 namespace views
3664 {
3665 namespace __detail
3666 {
3667 template<typename _Range, typename _Pattern>
3668 concept __can_split_view
3669 = requires { split_view(std::declval<_Range>(), std::declval<_Pattern>()); };
3670 } // namespace __detail
3671
3672 struct _Split : __adaptor::_RangeAdaptor<_Split>
3673 {
3674 template<viewable_range _Range, typename _Pattern>
3675 requires __detail::__can_split_view<_Range, _Pattern>
3676 constexpr auto
3677 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f) const
3678 {
3679 return split_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
3680 }
3681
3682 using _RangeAdaptor<_Split>::operator();
3683 static constexpr int _S_arity = 2;
3684 template<typename _Pattern>
3685 static constexpr bool _S_has_simple_extra_args
3686 = _LazySplit::_S_has_simple_extra_args<_Pattern>;
3687 };
3688
3689 inline constexpr _Split split;
3690 } // namespace views
3691
3692 namespace views
3693 {
3694 struct _Counted
3695 {
3696 template<input_or_output_iterator _Iter>
3697 constexpr auto
3698 operator() [[nodiscard]] (_Iter __i, iter_difference_t<_Iter> __n) const
3699 {
3700 if constexpr (contiguous_iterator<_Iter>)
3701 return span(std::__to_address(__i), __n);
3702 else if constexpr (random_access_iterator<_Iter>)
3703 return subrange(__i, __i + __n);
3704 else
3705 return subrange(counted_iterator(std::move(__i), __n),
3706 default_sentinel);
3707 }
3708 };
3709
3710 inline constexpr _Counted counted{};
3711 } // namespace views
3712
3713 template<view _Vp>
3714 requires (!common_range<_Vp>) && copyable<iterator_t<_Vp>>
3715 class common_view : public view_interface<common_view<_Vp>>
3716 {
3717 private:
3718 _Vp _M_base = _Vp();
3719
3720 public:
3721 common_view() requires default_initializable<_Vp> = default;
3722
3723 constexpr explicit
3724 common_view(_Vp __r)
3725 : _M_base(std::move(__r))
3726 { }
3727
3728 /* XXX: LWG 3280 didn't remove this constructor, but I think it should?
3729 template<viewable_range _Range>
3730 requires (!common_range<_Range>)
3731 && constructible_from<_Vp, views::all_t<_Range>>
3732 constexpr explicit
3733 common_view(_Range&& __r)
3734 : _M_base(views::all(std::forward<_Range>(__r)))
3735 { }
3736 */
3737
3738 constexpr _Vp
3739 base() const& requires copy_constructible<_Vp>
3740 { return _M_base; }
3741
3742 constexpr _Vp
3743 base() &&
3744 { return std::move(_M_base); }
3745
3746 constexpr auto
3747 begin()
3748 {
3749 if constexpr (random_access_range<_Vp> && sized_range<_Vp>)
3750 return ranges::begin(_M_base);
3751 else
3752 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
3753 (ranges::begin(_M_base));
3754 }
3755
3756 constexpr auto
3757 begin() const requires range<const _Vp>
3758 {
3759 if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>)
3760 return ranges::begin(_M_base);
3761 else
3762 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
3763 (ranges::begin(_M_base));
3764 }
3765
3766 constexpr auto
3767 end()
3768 {
3769 if constexpr (random_access_range<_Vp> && sized_range<_Vp>)
3770 return ranges::begin(_M_base) + ranges::size(_M_base);
3771 else
3772 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
3773 (ranges::end(_M_base));
3774 }
3775
3776 constexpr auto
3777 end() const requires range<const _Vp>
3778 {
3779 if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>)
3780 return ranges::begin(_M_base) + ranges::size(_M_base);
3781 else
3782 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
3783 (ranges::end(_M_base));
3784 }
3785
3786 constexpr auto
3787 size() requires sized_range<_Vp>
3788 { return ranges::size(_M_base); }
3789
3790 constexpr auto
3791 size() const requires sized_range<const _Vp>
3792 { return ranges::size(_M_base); }
3793 };
3794
3795 template<typename _Range>
3796 common_view(_Range&&) -> common_view<views::all_t<_Range>>;
3797
3798 template<typename _Tp>
3799 inline constexpr bool enable_borrowed_range<common_view<_Tp>>
3800 = enable_borrowed_range<_Tp>;
3801
3802 namespace views
3803 {
3804 namespace __detail
3805 {
3806 template<typename _Range>
3807 concept __already_common = common_range<_Range>
3808 && requires { views::all(std::declval<_Range>()); };
3809
3810 template<typename _Range>
3811 concept __can_common_view
3812 = requires { common_view{std::declval<_Range>()}; };
3813 } // namespace __detail
3814
3815 struct _Common : __adaptor::_RangeAdaptorClosure
3816 {
3817 template<viewable_range _Range>
3818 requires __detail::__already_common<_Range>
3819 || __detail::__can_common_view<_Range>
3820 constexpr auto
3821 operator() [[nodiscard]] (_Range&& __r) const
3822 {
3823 if constexpr (__detail::__already_common<_Range>)
3824 return views::all(std::forward<_Range>(__r));
3825 else
3826 return common_view{std::forward<_Range>(__r)};
3827 }
3828
3829 static constexpr bool _S_has_simple_call_op = true;
3830 };
3831
3832 inline constexpr _Common common;
3833 } // namespace views
3834
3835 template<view _Vp>
3836 requires bidirectional_range<_Vp>
3837 class reverse_view : public view_interface<reverse_view<_Vp>>
3838 {
3839 private:
3840 static constexpr bool _S_needs_cached_begin
3841 = !common_range<_Vp> && !(random_access_range<_Vp>
3842 && sized_sentinel_for<sentinel_t<_Vp>,
3843 iterator_t<_Vp>>);
3844
3845 _Vp _M_base = _Vp();
3846 [[no_unique_address]]
3847 __detail::__maybe_present_t<_S_needs_cached_begin,
3848 __detail::_CachedPosition<_Vp>>
3849 _M_cached_begin;
3850
3851 public:
3852 reverse_view() requires default_initializable<_Vp> = default;
3853
3854 constexpr explicit
3855 reverse_view(_Vp __r)
3856 : _M_base(std::move(__r))
3857 { }
3858
3859 constexpr _Vp
3860 base() const& requires copy_constructible<_Vp>
3861 { return _M_base; }
3862
3863 constexpr _Vp
3864 base() &&
3865 { return std::move(_M_base); }
3866
3867 constexpr reverse_iterator<iterator_t<_Vp>>
3868 begin()
3869 {
3870 if constexpr (_S_needs_cached_begin)
3871 if (_M_cached_begin._M_has_value())
3872 return std::make_reverse_iterator(_M_cached_begin._M_get(_M_base));
3873
3874 auto __it = ranges::next(ranges::begin(_M_base), ranges::end(_M_base));
3875 if constexpr (_S_needs_cached_begin)
3876 _M_cached_begin._M_set(_M_base, __it);
3877 return std::make_reverse_iterator(std::move(__it));
3878 }
3879
3880 constexpr auto
3881 begin() requires common_range<_Vp>
3882 { return std::make_reverse_iterator(ranges::end(_M_base)); }
3883
3884 constexpr auto
3885 begin() const requires common_range<const _Vp>
3886 { return std::make_reverse_iterator(ranges::end(_M_base)); }
3887
3888 constexpr reverse_iterator<iterator_t<_Vp>>
3889 end()
3890 { return std::make_reverse_iterator(ranges::begin(_M_base)); }
3891
3892 constexpr auto
3893 end() const requires common_range<const _Vp>
3894 { return std::make_reverse_iterator(ranges::begin(_M_base)); }
3895
3896 constexpr auto
3897 size() requires sized_range<_Vp>
3898 { return ranges::size(_M_base); }
3899
3900 constexpr auto
3901 size() const requires sized_range<const _Vp>
3902 { return ranges::size(_M_base); }
3903 };
3904
3905 template<typename _Range>
3906 reverse_view(_Range&&) -> reverse_view<views::all_t<_Range>>;
3907
3908 template<typename _Tp>
3909 inline constexpr bool enable_borrowed_range<reverse_view<_Tp>>
3910 = enable_borrowed_range<_Tp>;
3911
3912 namespace views
3913 {
3914 namespace __detail
3915 {
3916 template<typename>
3917 inline constexpr bool __is_reversible_subrange = false;
3918
3919 template<typename _Iter, subrange_kind _Kind>
3920 inline constexpr bool
3921 __is_reversible_subrange<subrange<reverse_iterator<_Iter>,
3922 reverse_iterator<_Iter>,
3923 _Kind>> = true;
3924
3925 template<typename>
3926 inline constexpr bool __is_reverse_view = false;
3927
3928 template<typename _Vp>
3929 inline constexpr bool __is_reverse_view<reverse_view<_Vp>> = true;
3930
3931 template<typename _Range>
3932 concept __can_reverse_view
3933 = requires { reverse_view{std::declval<_Range>()}; };
3934 } // namespace __detail
3935
3936 struct _Reverse : __adaptor::_RangeAdaptorClosure
3937 {
3938 template<viewable_range _Range>
3939 requires __detail::__is_reverse_view<remove_cvref_t<_Range>>
3940 || __detail::__is_reversible_subrange<remove_cvref_t<_Range>>
3941 || __detail::__can_reverse_view<_Range>
3942 constexpr auto
3943 operator() [[nodiscard]] (_Range&& __r) const
3944 {
3945 using _Tp = remove_cvref_t<_Range>;
3946 if constexpr (__detail::__is_reverse_view<_Tp>)
3947 return std::forward<_Range>(__r).base();
3948 else if constexpr (__detail::__is_reversible_subrange<_Tp>)
3949 {
3950 using _Iter = decltype(ranges::begin(__r).base());
3951 if constexpr (sized_range<_Tp>)
3952 return subrange<_Iter, _Iter, subrange_kind::sized>
3953 {__r.end().base(), __r.begin().base(), __r.size()};
3954 else
3955 return subrange<_Iter, _Iter, subrange_kind::unsized>
3956 {__r.end().base(), __r.begin().base()};
3957 }
3958 else
3959 return reverse_view{std::forward<_Range>(__r)};
3960 }
3961
3962 static constexpr bool _S_has_simple_call_op = true;
3963 };
3964
3965 inline constexpr _Reverse reverse;
3966 } // namespace views
3967
3968 namespace __detail
3969 {
3970 template<typename _Tp, size_t _Nm>
3971 concept __has_tuple_element = requires(_Tp __t)
3972 {
3973 typename tuple_size<_Tp>::type;
3974 requires _Nm < tuple_size_v<_Tp>;
3975 typename tuple_element_t<_Nm, _Tp>;
3976 { std::get<_Nm>(__t) }
3977 -> convertible_to<const tuple_element_t<_Nm, _Tp>&>;
3978 };
3979
3980 template<typename _Tp, size_t _Nm>
3981 concept __returnable_element
3982 = is_reference_v<_Tp> || move_constructible<tuple_element_t<_Nm, _Tp>>;
3983 }
3984
3985 template<input_range _Vp, size_t _Nm>
3986 requires view<_Vp>
3987 && __detail::__has_tuple_element<range_value_t<_Vp>, _Nm>
3988 && __detail::__has_tuple_element<remove_reference_t<range_reference_t<_Vp>>,
3989 _Nm>
3990 && __detail::__returnable_element<range_reference_t<_Vp>, _Nm>
3991 class elements_view : public view_interface<elements_view<_Vp, _Nm>>
3992 {
3993 public:
3994 elements_view() requires default_initializable<_Vp> = default;
3995
3996 constexpr explicit
3997 elements_view(_Vp base)
3998 : _M_base(std::move(base))
3999 { }
4000
4001 constexpr _Vp
4002 base() const& requires copy_constructible<_Vp>
4003 { return _M_base; }
4004
4005 constexpr _Vp
4006 base() &&
4007 { return std::move(_M_base); }
4008
4009 constexpr auto
4010 begin() requires (!__detail::__simple_view<_Vp>)
4011 { return _Iterator<false>(ranges::begin(_M_base)); }
4012
4013 constexpr auto
4014 begin() const requires range<const _Vp>
4015 { return _Iterator<true>(ranges::begin(_M_base)); }
4016
4017 constexpr auto
4018 end() requires (!__detail::__simple_view<_Vp> && !common_range<_Vp>)
4019 { return _Sentinel<false>{ranges::end(_M_base)}; }
4020
4021 constexpr auto
4022 end() requires (!__detail::__simple_view<_Vp> && common_range<_Vp>)
4023 { return _Iterator<false>{ranges::end(_M_base)}; }
4024
4025 constexpr auto
4026 end() const requires range<const _Vp>
4027 { return _Sentinel<true>{ranges::end(_M_base)}; }
4028
4029 constexpr auto
4030 end() const requires common_range<const _Vp>
4031 { return _Iterator<true>{ranges::end(_M_base)}; }
4032
4033 constexpr auto
4034 size() requires sized_range<_Vp>
4035 { return ranges::size(_M_base); }
4036
4037 constexpr auto
4038 size() const requires sized_range<const _Vp>
4039 { return ranges::size(_M_base); }
4040
4041 private:
4042 template<bool _Const>
4043 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
4044
4045 template<bool _Const>
4046 struct __iter_cat
4047 { };
4048
4049 template<bool _Const>
4050 requires forward_range<_Base<_Const>>
4051 struct __iter_cat<_Const>
4052 {
4053 private:
4054 static auto _S_iter_cat()
4055 {
4056 using _Base = elements_view::_Base<_Const>;
4057 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
4058 using _Res = decltype((std::get<_Nm>(*std::declval<iterator_t<_Base>>())));
4059 if constexpr (!is_lvalue_reference_v<_Res>)
4060 return input_iterator_tag{};
4061 else if constexpr (derived_from<_Cat, random_access_iterator_tag>)
4062 return random_access_iterator_tag{};
4063 else
4064 return _Cat{};
4065 }
4066 public:
4067 using iterator_category = decltype(_S_iter_cat());
4068 };
4069
4070 template<bool _Const>
4071 struct _Sentinel;
4072
4073 template<bool _Const>
4074 struct _Iterator : __iter_cat<_Const>
4075 {
4076 private:
4077 using _Base = elements_view::_Base<_Const>;
4078
4079 iterator_t<_Base> _M_current = iterator_t<_Base>();
4080
4081 static constexpr decltype(auto)
4082 _S_get_element(const iterator_t<_Base>& __i)
4083 {
4084 if constexpr (is_reference_v<range_reference_t<_Base>>)
4085 return std::get<_Nm>(*__i);
4086 else
4087 {
4088 using _Et = remove_cv_t<tuple_element_t<_Nm, range_reference_t<_Base>>>;
4089 return static_cast<_Et>(std::get<_Nm>(*__i));
4090 }
4091 }
4092
4093 static auto
4094 _S_iter_concept()
4095 {
4096 if constexpr (random_access_range<_Base>)
4097 return random_access_iterator_tag{};
4098 else if constexpr (bidirectional_range<_Base>)
4099 return bidirectional_iterator_tag{};
4100 else if constexpr (forward_range<_Base>)
4101 return forward_iterator_tag{};
4102 else
4103 return input_iterator_tag{};
4104 }
4105
4106 friend _Iterator<!_Const>;
4107
4108 public:
4109 using iterator_concept = decltype(_S_iter_concept());
4110 // iterator_category defined in elements_view::__iter_cat
4111 using value_type
4112 = remove_cvref_t<tuple_element_t<_Nm, range_value_t<_Base>>>;
4113 using difference_type = range_difference_t<_Base>;
4114
4115 _Iterator() requires default_initializable<iterator_t<_Base>> = default;
4116
4117 constexpr explicit
4118 _Iterator(iterator_t<_Base> current)
4119 : _M_current(std::move(current))
4120 { }
4121
4122 constexpr
4123 _Iterator(_Iterator<!_Const> i)
4124 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
4125 : _M_current(std::move(i._M_current))
4126 { }
4127
4128 constexpr const iterator_t<_Base>&
4129 base() const& noexcept
4130 { return _M_current; }
4131
4132 constexpr iterator_t<_Base>
4133 base() &&
4134 { return std::move(_M_current); }
4135
4136 constexpr decltype(auto)
4137 operator*() const
4138 { return _S_get_element(_M_current); }
4139
4140 constexpr _Iterator&
4141 operator++()
4142 {
4143 ++_M_current;
4144 return *this;
4145 }
4146
4147 constexpr void
4148 operator++(int)
4149 { ++_M_current; }
4150
4151 constexpr _Iterator
4152 operator++(int) requires forward_range<_Base>
4153 {
4154 auto __tmp = *this;
4155 ++_M_current;
4156 return __tmp;
4157 }
4158
4159 constexpr _Iterator&
4160 operator--() requires bidirectional_range<_Base>
4161 {
4162 --_M_current;
4163 return *this;
4164 }
4165
4166 constexpr _Iterator
4167 operator--(int) requires bidirectional_range<_Base>
4168 {
4169 auto __tmp = *this;
4170 --_M_current;
4171 return __tmp;
4172 }
4173
4174 constexpr _Iterator&
4175 operator+=(difference_type __n)
4176 requires random_access_range<_Base>
4177 {
4178 _M_current += __n;
4179 return *this;
4180 }
4181
4182 constexpr _Iterator&
4183 operator-=(difference_type __n)
4184 requires random_access_range<_Base>
4185 {
4186 _M_current -= __n;
4187 return *this;
4188 }
4189
4190 constexpr decltype(auto)
4191 operator[](difference_type __n) const
4192 requires random_access_range<_Base>
4193 { return _S_get_element(_M_current + __n); }
4194
4195 friend constexpr bool
4196 operator==(const _Iterator& __x, const _Iterator& __y)
4197 requires equality_comparable<iterator_t<_Base>>
4198 { return __x._M_current == __y._M_current; }
4199
4200 friend constexpr bool
4201 operator<(const _Iterator& __x, const _Iterator& __y)
4202 requires random_access_range<_Base>
4203 { return __x._M_current < __y._M_current; }
4204
4205 friend constexpr bool
4206 operator>(const _Iterator& __x, const _Iterator& __y)
4207 requires random_access_range<_Base>
4208 { return __y._M_current < __x._M_current; }
4209
4210 friend constexpr bool
4211 operator<=(const _Iterator& __x, const _Iterator& __y)
4212 requires random_access_range<_Base>
4213 { return !(__y._M_current > __x._M_current); }
4214
4215 friend constexpr bool
4216 operator>=(const _Iterator& __x, const _Iterator& __y)
4217 requires random_access_range<_Base>
4218 { return !(__x._M_current > __y._M_current); }
4219
4220#ifdef __cpp_lib_three_way_comparison
4221 friend constexpr auto
4222 operator<=>(const _Iterator& __x, const _Iterator& __y)
4223 requires random_access_range<_Base>
4224 && three_way_comparable<iterator_t<_Base>>
4225 { return __x._M_current <=> __y._M_current; }
4226#endif
4227
4228 friend constexpr _Iterator
4229 operator+(const _Iterator& __x, difference_type __y)
4230 requires random_access_range<_Base>
4231 { return _Iterator{__x} += __y; }
4232
4233 friend constexpr _Iterator
4234 operator+(difference_type __x, const _Iterator& __y)
4235 requires random_access_range<_Base>
4236 { return __y + __x; }
4237
4238 friend constexpr _Iterator
4239 operator-(const _Iterator& __x, difference_type __y)
4240 requires random_access_range<_Base>
4241 { return _Iterator{__x} -= __y; }
4242
4243 // _GLIBCXX_RESOLVE_LIB_DEFECTS
4244 // 3483. transform_view::iterator's difference is overconstrained
4245 friend constexpr difference_type
4246 operator-(const _Iterator& __x, const _Iterator& __y)
4247 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
4248 { return __x._M_current - __y._M_current; }
4249
4250 template <bool> friend struct _Sentinel;
4251 };
4252
4253 template<bool _Const>
4254 struct _Sentinel
4255 {
4256 private:
4257 template<bool _Const2>
4258 constexpr bool
4259 _M_equal(const _Iterator<_Const2>& __x) const
4260 { return __x._M_current == _M_end; }
4261
4262 template<bool _Const2>
4263 constexpr auto
4264 _M_distance_from(const _Iterator<_Const2>& __i) const
4265 { return _M_end - __i._M_current; }
4266
4267 using _Base = elements_view::_Base<_Const>;
4268 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
4269
4270 public:
4271 _Sentinel() = default;
4272
4273 constexpr explicit
4274 _Sentinel(sentinel_t<_Base> __end)
4275 : _M_end(std::move(__end))
4276 { }
4277
4278 constexpr
4279 _Sentinel(_Sentinel<!_Const> __other)
4280 requires _Const
4281 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
4282 : _M_end(std::move(__other._M_end))
4283 { }
4284
4285 constexpr sentinel_t<_Base>
4286 base() const
4287 { return _M_end; }
4288
4289 template<bool _Const2>
4290 requires sentinel_for<sentinel_t<_Base>,
4291 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
4292 friend constexpr bool
4293 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
4294 { return __y._M_equal(__x); }
4295
4296 template<bool _Const2,
4297 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
4298 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
4299 friend constexpr range_difference_t<_Base2>
4300 operator-(const _Iterator<_Const2>& __x, const _Sentinel& __y)
4301 { return -__y._M_distance_from(__x); }
4302
4303 template<bool _Const2,
4304 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
4305 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
4306 friend constexpr range_difference_t<_Base2>
4307 operator-(const _Sentinel& __x, const _Iterator<_Const2>& __y)
4308 { return __x._M_distance_from(__y); }
4309
4310 friend _Sentinel<!_Const>;
4311 };
4312
4313 _Vp _M_base = _Vp();
4314 };
4315
4316 template<typename _Tp, size_t _Nm>
4317 inline constexpr bool enable_borrowed_range<elements_view<_Tp, _Nm>>
4318 = enable_borrowed_range<_Tp>;
4319
4320 template<typename _Range>
4321 using keys_view = elements_view<views::all_t<_Range>, 0>;
4322
4323 template<typename _Range>
4324 using values_view = elements_view<views::all_t<_Range>, 1>;
4325
4326 namespace views
4327 {
4328 namespace __detail
4329 {
4330 template<size_t _Nm, typename _Range>
4331 concept __can_elements_view
4332 = requires { elements_view<all_t<_Range>, _Nm>{std::declval<_Range>()}; };
4333 } // namespace __detail
4334
4335 template<size_t _Nm>
4336 struct _Elements : __adaptor::_RangeAdaptorClosure
4337 {
4338 template<viewable_range _Range>
4339 requires __detail::__can_elements_view<_Nm, _Range>
4340 constexpr auto
4341 operator() [[nodiscard]] (_Range&& __r) const
4342 {
4343 return elements_view<all_t<_Range>, _Nm>{std::forward<_Range>(__r)};
4344 }
4345
4346 static constexpr bool _S_has_simple_call_op = true;
4347 };
4348
4349 template<size_t _Nm>
4350 inline constexpr _Elements<_Nm> elements;
4351 inline constexpr auto keys = elements<0>;
4352 inline constexpr auto values = elements<1>;
4353 } // namespace views
4354
4355} // namespace ranges
4356
4357 namespace views = ranges::views;
4358
4359_GLIBCXX_END_NAMESPACE_VERSION
4360} // namespace
4361#endif // library concepts
4362#endif // C++2a
4363#endif /* _GLIBCXX_RANGES */