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