libstdc++
ranges
Go to the documentation of this file.
1 // <ranges> -*- C++ -*-
2 
3 // Copyright (C) 2019 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 <limits>
45 #include <optional>
46 
47 /**
48  * @defgroup ranges Ranges
49  *
50  * Components for dealing with ranges of elements.
51  */
52 
53 namespace std _GLIBCXX_VISIBILITY(default)
54 {
55 _GLIBCXX_BEGIN_NAMESPACE_VERSION
56 namespace ranges
57 {
58  // [range.range] The range concept.
59  // [range.sized] The sized_range concept.
60  // Defined in <bits/range_access.h>
61 
62  // [range.refinements]
63  // Defined in <bits/range_access.h>
64 
65  struct view_base { };
66 
67  namespace __detail
68  {
69  template<typename _Tp>
70  concept __deep_const_range = range<_Tp> && range<const _Tp>
71  && same_as<range_reference_t<_Tp>, range_reference_t<const _Tp>>;
72 
73  template<typename _Tp>
74  inline constexpr bool __enable_view_impl
75  = derived_from<_Tp, view_base> || (!__deep_const_range<_Tp>);
76 
77  template<typename _Tp>
78  inline constexpr bool __enable_view_impl<std::initializer_list<_Tp>>
79  = false;
80 
81  } // namespace __detail
82 
83  template<typename _Tp>
84  inline constexpr bool enable_view
85  = __detail::__enable_view_impl<remove_cv_t<_Tp>>;
86 
87  template<typename _Tp>
88  concept view
89  = range<_Tp> && movable<_Tp> && default_initializable<_Tp>
90  && enable_view<_Tp>;
91 
92  /// A range which can be safely converted to a view.
93  template<typename _Tp>
94  concept viewable_range = range<_Tp>
95  && (safe_range<_Tp> || view<decay_t<_Tp>>);
96 
97  namespace __detail
98  {
99  template<typename _Range>
100  concept __simple_view = view<_Range> && range<const _Range>
101  && same_as<iterator_t<_Range>, iterator_t<const _Range>>
102  && same_as<sentinel_t<_Range>, sentinel_t<const _Range>>;
103 
104  template<typename _It>
105  concept __has_arrow = input_iterator<_It>
106  && (is_pointer_v<_It> || requires(_It __it) { __it.operator->(); });
107 
108  template<typename _Tp, typename _Up>
109  concept __not_same_as
110  = !same_as<remove_cvref_t<_Tp>, remove_cvref_t<_Up>>;
111  } // namespace __detail
112 
113  template<typename _Derived>
114  requires is_class_v<_Derived> && same_as<_Derived, remove_cv_t<_Derived>>
115  class view_interface : public view_base
116  {
117  private:
118  constexpr _Derived& _M_derived() noexcept
119  {
120  static_assert(derived_from<_Derived, view_interface<_Derived>>);
121  static_assert(view<_Derived>);
122  return static_cast<_Derived&>(*this);
123  }
124 
125  constexpr const _Derived& _M_derived() const noexcept
126  {
127  static_assert(derived_from<_Derived, view_interface<_Derived>>);
128  static_assert(view<_Derived>);
129  return static_cast<const _Derived&>(*this);
130  }
131 
132  public:
133  constexpr bool
134  empty() requires forward_range<_Derived>
135  { return ranges::begin(_M_derived()) == ranges::end(_M_derived()); }
136 
137  constexpr bool
138  empty() const requires forward_range<const _Derived>
139  { return ranges::begin(_M_derived()) == ranges::end(_M_derived()); }
140 
141  constexpr explicit
142  operator bool() requires requires { ranges::empty(_M_derived()); }
143  { return !ranges::empty(_M_derived()); }
144 
145  constexpr explicit
146  operator bool() const requires requires { ranges::empty(_M_derived()); }
147  { return !ranges::empty(_M_derived()); }
148 
149  constexpr auto
150  data() requires contiguous_iterator<iterator_t<_Derived>>
151  { return to_address(ranges::begin(_M_derived())); }
152 
153  constexpr auto
154  data() const
155  requires range<const _Derived>
156  && contiguous_iterator<iterator_t<const _Derived>>
157  { return to_address(ranges::begin(_M_derived())); }
158 
159  constexpr auto
160  size()
161  requires forward_range<_Derived>
162  && sized_sentinel_for<sentinel_t<_Derived>, iterator_t<_Derived>>
163  { return ranges::end(_M_derived()) - ranges::begin(_M_derived()); }
164 
165  constexpr auto
166  size() const
167  requires forward_range<const _Derived>
168  && sized_sentinel_for<sentinel_t<const _Derived>,
169  iterator_t<const _Derived>>
170  { return ranges::end(_M_derived()) - ranges::begin(_M_derived()); }
171 
172  constexpr decltype(auto)
173  front() requires forward_range<_Derived>
174  {
175  __glibcxx_assert(!empty());
176  return *ranges::begin(_M_derived());
177  }
178 
179  constexpr decltype(auto)
180  front() const requires forward_range<const _Derived>
181  {
182  __glibcxx_assert(!empty());
183  return *ranges::begin(_M_derived());
184  }
185 
186  constexpr decltype(auto)
187  back()
188  requires bidirectional_range<_Derived> && common_range<_Derived>
189  {
190  __glibcxx_assert(!empty());
191  return *ranges::prev(ranges::end(_M_derived()));
192  }
193 
194  constexpr decltype(auto)
195  back() const
196  requires bidirectional_range<const _Derived>
197  && common_range<const _Derived>
198  {
199  __glibcxx_assert(!empty());
200  return *ranges::prev(ranges::end(_M_derived()));
201  }
202 
203  template<random_access_range _Range = _Derived>
204  constexpr decltype(auto)
205  operator[](range_difference_t<_Range> __n)
206  { return ranges::begin(_M_derived())[__n]; }
207 
208  template<random_access_range _Range = const _Derived>
209  constexpr decltype(auto)
210  operator[](range_difference_t<_Range> __n) const
211  { return ranges::begin(_M_derived())[__n]; }
212  };
213 
214  namespace __detail
215  {
216  template<typename _Tp>
217  concept __pair_like
218  = !is_reference_v<_Tp> && requires(_Tp __t)
219  {
220  typename tuple_size<_Tp>::type;
221  requires derived_from<tuple_size<_Tp>, integral_constant<size_t, 2>>;
222  typename tuple_element_t<0, remove_const_t<_Tp>>;
223  typename tuple_element_t<1, remove_const_t<_Tp>>;
224  { get<0>(__t) } -> convertible_to<const tuple_element_t<0, _Tp>&>;
225  { get<1>(__t) } -> convertible_to<const tuple_element_t<1, _Tp>&>;
226  };
227 
228  template<typename _Tp, typename _Up, typename _Vp>
229  concept __pair_like_convertible_to
230  = !range<_Tp> && __pair_like<remove_reference_t<_Tp>>
231  && requires(_Tp&& __t)
232  {
233  { get<0>(std::forward<_Tp>(__t)) } -> convertible_to<_Up>;
234  { get<1>(std::forward<_Tp>(__t)) } -> convertible_to<_Vp>;
235  };
236 
237  template<typename _Tp, typename _Up, typename _Vp>
238  concept __pair_like_convertible_from
239  = !range<_Tp> && __pair_like<_Tp>
240  && constructible_from<_Tp, _Up, _Vp>;
241 
242  template<typename _Tp>
243  concept __iterator_sentinel_pair
244  = !range<_Tp> && __pair_like<_Tp>
245  && sentinel_for<tuple_element_t<1, _Tp>, tuple_element_t<0, _Tp>>;
246 
247  template<typename _Tp, bool _MaxDiff = same_as<_Tp, __max_diff_type>>
248  using __make_unsigned_like_t
249  = conditional_t<_MaxDiff, __max_size_type, make_unsigned_t<_Tp>>;
250 
251  } // namespace __detail
252 
253  enum class subrange_kind : bool { unsized, sized };
254 
255  template<input_or_output_iterator _It, sentinel_for<_It> _Sent = _It,
256  subrange_kind _Kind = sized_sentinel_for<_Sent, _It>
257  ? subrange_kind::sized : subrange_kind::unsized>
258  requires (_Kind == subrange_kind::sized || !sized_sentinel_for<_Sent, _It>)
259  class subrange : public view_interface<subrange<_It, _Sent, _Kind>>
260  {
261  private:
262  static constexpr bool _S_store_size
263  = _Kind == subrange_kind::sized && !sized_sentinel_for<_Sent, _It>;
264 
265  _It _M_begin = _It();
266  _Sent _M_end = _Sent();
267 
268  template<typename, bool = _S_store_size>
269  struct _Size
270  { };
271 
272  template<typename _Tp>
273  struct _Size<_Tp, true>
274  { __detail::__make_unsigned_like_t<_Tp> _M_size; };
275 
276  [[no_unique_address]] _Size<iter_difference_t<_It>> _M_size = {};
277 
278  public:
279  subrange() = default;
280 
281  constexpr
282  subrange(_It __i, _Sent __s) requires (!_S_store_size)
283  : _M_begin(std::move(__i)), _M_end(__s)
284  { }
285 
286  constexpr
287  subrange(_It __i, _Sent __s,
288  __detail::__make_unsigned_like_t<iter_difference_t<_It>> __n)
289  requires (_Kind == subrange_kind::sized)
290  : _M_begin(std::move(__i)), _M_end(__s)
291  {
292  using __detail::__to_unsigned_like;
293  __glibcxx_assert(__n == __to_unsigned_like(ranges::distance(__i, __s)));
294  if constexpr (_S_store_size)
295  _M_size._M_size = __n;
296  }
297 
298  template<__detail::__not_same_as<subrange> _Rng>
299  requires safe_range<_Rng>
300  && convertible_to<iterator_t<_Rng>, _It>
301  && convertible_to<sentinel_t<_Rng>, _Sent>
302  constexpr
303  subrange(_Rng&& __r) requires (!_S_store_size || sized_range<_Rng>)
304  : subrange{ranges::begin(__r), ranges::end(__r)}
305  {
306  if constexpr (_S_store_size)
307  _M_size._M_size = ranges::size(__r);
308  }
309 
310  template<safe_range _Rng>
311  requires convertible_to<iterator_t<_Rng>, _It>
312  && convertible_to<sentinel_t<_Rng>, _Sent>
313  constexpr
314  subrange(_Rng&& __r,
315  __detail::__make_unsigned_like_t<iter_difference_t<_It>> __n)
316  requires (_Kind == subrange_kind::sized)
317  : subrange{ranges::begin(__r), ranges::end(__r), __n}
318  { }
319 
320  template<__detail::__not_same_as<subrange> _PairLike>
321  requires __detail::__pair_like_convertible_to<_PairLike, _It, _Sent>
322  constexpr
323  subrange(_PairLike&& __r) requires (!_S_store_size)
324  : subrange{std::get<0>(std::forward<_PairLike>(__r)),
325  std::get<1>(std::forward<_PairLike>(__r))}
326  { }
327 
328  template<__detail::__pair_like_convertible_to<_It, _Sent> _PairLike>
329  constexpr
330  subrange(_PairLike&& __r,
331  __detail::__make_unsigned_like_t<iter_difference_t<_It>> __n)
332  requires (_Kind == subrange_kind::sized)
333  : subrange{std::get<0>(std::forward<_PairLike>(__r)),
334  std::get<1>(std::forward<_PairLike>(__r)), __n}
335  { }
336 
337  template<__detail::__not_same_as<subrange> _PairLike>
338  requires __detail::__pair_like_convertible_from<_PairLike, const _It&,
339  const _Sent&>
340  constexpr
341  operator _PairLike() const
342  { return _PairLike(_M_begin, _M_end); }
343 
344  constexpr _It
345  begin() const requires copyable<_It>
346  { return _M_begin; }
347 
348  [[nodiscard]] constexpr _It
349  begin() requires (!copyable<_It>)
350  { return std::move(_M_begin); }
351 
352  constexpr _Sent end() const { return _M_end; }
353 
354  constexpr bool empty() const { return _M_begin == _M_end; }
355 
356  constexpr __detail::__make_unsigned_like_t<iter_difference_t<_It>>
357  size() const requires (_Kind == subrange_kind::sized)
358  {
359  if constexpr (_S_store_size)
360  return _M_size._M_size;
361  else
362  return __detail::__to_unsigned_like(_M_end - _M_begin);
363  }
364 
365  [[nodiscard]] constexpr subrange
366  next(iter_difference_t<_It> __n = 1) const &
367  requires forward_iterator<_It>
368  {
369  auto __tmp = *this;
370  __tmp.advance(__n);
371  return __tmp;
372  }
373 
374  [[nodiscard]] constexpr subrange
375  next(iter_difference_t<_It> __n = 1) &&
376  {
377  advance(__n);
378  return std::move(*this);
379  }
380 
381  [[nodiscard]] constexpr subrange
382  prev(iter_difference_t<_It> __n = 1) const
383  requires bidirectional_iterator<_It>
384  {
385  auto __tmp = *this;
386  __tmp.advance(--__n);
387  return __tmp;
388  }
389 
390  constexpr subrange&
391  advance(iter_difference_t<_It> __n)
392  {
393  if constexpr (_S_store_size)
394  {
395  auto __d = __n - ranges::advance(_M_begin, __n, _M_end);
396  if (__d >= 0)
397  _M_size._M_size -= __detail::__to_unsigned_like(__d);
398  else
399  _M_size._M_size += __detail::__to_unsigned_like(-__d);
400  }
401  else
402  ranges::advance(_M_begin, __n, _M_end);
403  return *this;
404  }
405  };
406 
407  template<input_or_output_iterator _It, sentinel_for<_It> _Sent>
408  subrange(_It, _Sent,
409  __detail::__make_unsigned_like_t<iter_difference_t<_It>>)
410  -> subrange<_It, _Sent, subrange_kind::sized>;
411 
412  template<__detail::__iterator_sentinel_pair _Pr>
413  subrange(_Pr)
414  -> subrange<tuple_element_t<0, _Pr>, tuple_element_t<1, _Pr>>;
415 
416  template<__detail::__iterator_sentinel_pair _Pr>
417  subrange(_Pr, __detail::__make_unsigned_like_t<iter_difference_t<
418  tuple_element_t<0, _Pr>>>)
419  -> subrange<tuple_element_t<0, _Pr>, tuple_element_t<1, _Pr>,
420  subrange_kind::sized>;
421 
422  template<safe_range _Rng>
423  subrange(_Rng&&)
424  -> subrange<iterator_t<_Rng>, sentinel_t<_Rng>,
425  (sized_range<_Rng>
426  || sized_sentinel_for<sentinel_t<_Rng>, iterator_t<_Rng>>)
427  ? subrange_kind::sized : subrange_kind::unsized>;
428 
429  template<safe_range _Rng>
430  subrange(_Rng&&,
431  __detail::__make_unsigned_like_t<range_difference_t<_Rng>>)
432  -> subrange<iterator_t<_Rng>, sentinel_t<_Rng>, subrange_kind::sized>;
433 
434  template<size_t _Num, class _It, class _Sent, subrange_kind _Kind>
435  requires (_Num < 2)
436  constexpr auto
437  get(const subrange<_It, _Sent, _Kind>& __r)
438  {
439  if constexpr (_Num == 0)
440  return __r.begin();
441  else
442  return __r.end();
443  }
444 
445  template<size_t _Num, class _It, class _Sent, subrange_kind _Kind>
446  requires (_Num < 2)
447  constexpr auto
448  get(subrange<_It, _Sent, _Kind>&& __r)
449  {
450  if constexpr (_Num == 0)
451  return __r.begin();
452  else
453  return __r.end();
454  }
455 
456  template<input_or_output_iterator _It, sentinel_for<_It> _Sent,
457  subrange_kind _Kind>
458  inline constexpr bool
459  enable_safe_range<subrange<_It, _Sent, _Kind>> = true;
460 
461 } // namespace ranges
462 
463  using ranges::get;
464 
465 namespace ranges
466 {
467  /// Type returned by algorithms instead of a dangling iterator or subrange.
468  struct dangling
469  {
470  constexpr dangling() noexcept = default;
471  template<typename... _Args>
472  constexpr dangling(_Args&&...) noexcept { }
473  };
474 
475  template<range _Range>
476  using safe_iterator_t = conditional_t<safe_range<_Range>,
477  iterator_t<_Range>,
478  dangling>;
479 
480  template<range _Range>
481  using safe_subrange_t = conditional_t<safe_range<_Range>,
482  subrange<iterator_t<_Range>>,
483  dangling>;
484 
485  template<typename _Tp> requires is_object_v<_Tp>
486  class empty_view
487  : public view_interface<empty_view<_Tp>>
488  {
489  public:
490  static constexpr _Tp* begin() noexcept { return nullptr; }
491  static constexpr _Tp* end() noexcept { return nullptr; }
492  static constexpr _Tp* data() noexcept { return nullptr; }
493  static constexpr size_t size() noexcept { return 0; }
494  static constexpr bool empty() noexcept { return true; }
495  };
496 
497  template<typename _Tp>
498  inline constexpr bool enable_safe_range<empty_view<_Tp>> = true;
499 
500  namespace __detail
501  {
502  template<copy_constructible _Tp> requires is_object_v<_Tp>
503  struct __box : std::optional<_Tp>
504  {
505  using std::optional<_Tp>::optional;
506 
507  constexpr
508  __box()
509  noexcept(is_nothrow_default_constructible_v<_Tp>)
510  requires default_initializable<_Tp>
511  : std::optional<_Tp>{std::in_place}
512  { }
513 
514  using std::optional<_Tp>::operator=;
515 
516  __box&
517  operator=(const __box& __that)
518  noexcept(is_nothrow_copy_constructible_v<_Tp>)
519  requires (!assignable_from<_Tp&, const _Tp&>)
520  {
521  if ((bool)__that)
522  this->emplace(*__that);
523  else
524  this->reset();
525  return *this;
526  }
527 
528  __box&
529  operator=(__box&& __that)
530  noexcept(is_nothrow_move_constructible_v<_Tp>)
531  requires (!assignable_from<_Tp&, _Tp>)
532  {
533  if ((bool)__that)
534  this->emplace(std::move(*__that));
535  else
536  this->reset();
537  return *this;
538  }
539  };
540 
541  } // namespace __detail
542 
543  /// A view that contains exactly one element.
544  template<copy_constructible _Tp> requires is_object_v<_Tp>
545  class single_view : public view_interface<single_view<_Tp>>
546  {
547  public:
548  single_view() = default;
549 
550  constexpr explicit
551  single_view(const _Tp& __t)
552  : _M_value(__t)
553  { }
554 
555  constexpr explicit
556  single_view(_Tp&& __t)
557  : _M_value(std::move(__t))
558  { }
559 
560  template<typename... _Args>
561  requires constructible_from<_Tp, _Args...>
562  constexpr
563  single_view(in_place_t, _Args&&... __args)
564  : _M_value{in_place, std::forward<_Args>(__args)...}
565  { }
566 
567  constexpr _Tp*
568  begin() noexcept
569  { return data(); }
570 
571  constexpr const _Tp*
572  begin() const noexcept
573  { return data(); }
574 
575  constexpr _Tp*
576  end() noexcept
577  { return data() + 1; }
578 
579  constexpr const _Tp*
580  end() const noexcept
581  { return data() + 1; }
582 
583  static constexpr size_t
584  size() noexcept
585  { return 1; }
586 
587  constexpr _Tp*
588  data() noexcept
589  { return _M_value.operator->(); }
590 
591  constexpr const _Tp*
592  data() const noexcept
593  { return _M_value.operator->(); }
594 
595  private:
596  __detail::__box<_Tp> _M_value;
597  };
598 
599  namespace __detail
600  {
601  template<typename _Wp>
602  constexpr auto __to_signed_like(_Wp __w) noexcept
603  {
604  if constexpr (!integral<_Wp>)
605  return iter_difference_t<_Wp>();
606  else if constexpr (sizeof(iter_difference_t<_Wp>) > sizeof(_Wp))
607  return iter_difference_t<_Wp>(__w);
608  else if constexpr (sizeof(ptrdiff_t) > sizeof(_Wp))
609  return ptrdiff_t(__w);
610  else if constexpr (sizeof(long long) > sizeof(_Wp))
611  return (long long)(__w);
612 #ifdef __SIZEOF_INT128__
613  else if constexpr (__SIZEOF_INT128__ > sizeof(_Wp))
614  return __int128(__w);
615 #endif
616  else
617  return __max_diff_type(__w);
618  }
619 
620  template<typename _Wp>
621  using __iota_diff_t = decltype(__to_signed_like(std::declval<_Wp>()));
622 
623  template<typename _It>
624  concept __decrementable = incrementable<_It>
625  && requires(_It __i)
626  {
627  { --__i } -> same_as<_It&>;
628  { __i-- } -> same_as<_It>;
629  };
630 
631  template<typename _It>
632  concept __advanceable = __decrementable<_It> && totally_ordered<_It>
633  && requires( _It __i, const _It __j, const __iota_diff_t<_It> __n)
634  {
635  { __i += __n } -> same_as<_It&>;
636  { __i -= __n } -> same_as<_It&>;
637  _It(__j + __n);
638  _It(__n + __j);
639  _It(__j - __n);
640  { __j - __j } -> convertible_to<__iota_diff_t<_It>>;
641  };
642 
643  } // namespace __detail
644 
645  template<weakly_incrementable _Winc,
646  semiregular _Bound = unreachable_sentinel_t>
647  requires std::__detail::__weakly_eq_cmp_with<_Winc, _Bound>
648  class iota_view : public view_interface<iota_view<_Winc, _Bound>>
649  {
650  private:
651  struct _Iterator
652  {
653  private:
654  static auto
655  _S_iter_cat()
656  {
657  using namespace __detail;
658  if constexpr (__advanceable<_Winc>)
659  return random_access_iterator_tag{};
660  else if constexpr (__decrementable<_Winc>)
661  return bidirectional_iterator_tag{};
662  else if constexpr (incrementable<_Winc>)
663  return forward_iterator_tag{};
664  else
665  return input_iterator_tag{};
666  }
667 
668  public:
669  using iterator_category = decltype(_S_iter_cat());
670  using value_type = _Winc;
671  using difference_type = __detail::__iota_diff_t<_Winc>;
672 
673  _Iterator() = default;
674 
675  constexpr explicit
676  _Iterator(_Winc __value)
677  : _M_value(__value) { }
678 
679  constexpr _Winc
680  operator*() const noexcept(is_nothrow_copy_constructible_v<_Winc>)
681  { return _M_value; }
682 
683  constexpr _Iterator&
684  operator++()
685  {
686  ++_M_value;
687  return *this;
688  }
689 
690  constexpr void
691  operator++(int)
692  { ++*this; }
693 
694  constexpr _Iterator
695  operator++(int) requires incrementable<_Winc>
696  {
697  auto __tmp = *this;
698  ++*this;
699  return __tmp;
700  }
701 
702  constexpr _Iterator&
703  operator--() requires __detail::__decrementable<_Winc>
704  {
705  --_M_value;
706  return *this;
707  }
708 
709  constexpr _Iterator
710  operator--(int) requires __detail::__decrementable<_Winc>
711  {
712  auto __tmp = *this;
713  --*this;
714  return __tmp;
715  }
716 
717  constexpr _Iterator&
718  operator+=(difference_type __n) requires __detail::__advanceable<_Winc>
719  {
720  using namespace __detail;
721  if constexpr (__is_integer_like<_Winc>
722  && !__is_signed_integer_like<_Winc>)
723  {
724  if (__n >= difference_type(0))
725  _M_value += static_cast<_Winc>(__n);
726  else
727  _M_value -= static_cast<_Winc>(-__n);
728  }
729  else
730  _M_value += __n;
731  return *this;
732  }
733 
734  constexpr _Iterator&
735  operator-=(difference_type __n) requires __detail::__advanceable<_Winc>
736  {
737  using namespace __detail;
738  if constexpr (__is_integer_like<_Winc>
739  && !__is_signed_integer_like<_Winc>)
740  {
741  if (__n >= difference_type(0))
742  _M_value -= static_cast<_Winc>(__n);
743  else
744  _M_value += static_cast<_Winc>(-__n);
745  }
746  else
747  _M_value -= __n;
748  return *this;
749  }
750 
751  constexpr _Winc
752  operator[](difference_type __n) const
753  requires __detail::__advanceable<_Winc>
754  { return _Winc(_M_value + __n); }
755 
756  friend constexpr bool
757  operator==(const _Iterator& __x, const _Iterator& __y)
758  requires equality_comparable<_Winc>
759  { return __x._M_value == __y._M_value; }
760 
761  friend constexpr bool
762  operator<(const _Iterator& __x, const _Iterator& __y)
763  requires totally_ordered<_Winc>
764  { return __x._M_value < __y._M_value; }
765 
766  friend constexpr bool
767  operator>(const _Iterator& __x, const _Iterator& __y)
768  requires totally_ordered<_Winc>
769  { return __y < __x; }
770 
771  friend constexpr bool
772  operator<=(const _Iterator& __x, const _Iterator& __y)
773  requires totally_ordered<_Winc>
774  { return !(__y < __x); }
775 
776  friend constexpr bool
777  operator>=(const _Iterator& __x, const _Iterator& __y)
778  requires totally_ordered<_Winc>
779  { return !(__x < __y); }
780 
781 #ifdef __cpp_lib_threeway_comparison
782  friend constexpr compare_three_way_result_t<_Winc>
783  operator<=>(const _Iterator& __x, const _Iterator& __y)
784  requires totally_ordered<_Winc> && three_way_comparable<_Winc>
785  { return __x._M_value <=> __y._M_value; }
786 #endif
787 
788  friend constexpr _Iterator
789  operator+(_Iterator __i, difference_type __n)
790  requires __detail::__advanceable<_Winc>
791  { return __i += __n; }
792 
793  friend constexpr _Iterator
794  operator+(difference_type __n, _Iterator __i)
795  requires __detail::__advanceable<_Winc>
796  { return __i += __n; }
797 
798  friend constexpr _Iterator
799  operator-(_Iterator __i, difference_type __n)
800  requires __detail::__advanceable<_Winc>
801  { return __i -= __n; }
802 
803  friend constexpr difference_type
804  operator-(const _Iterator& __x, const _Iterator& __y)
805  requires __detail::__advanceable<_Winc>
806  {
807  using namespace __detail;
808  using _Dt = difference_type;
809  if constexpr (__is_integer_like<_Winc>)
810  {
811  if constexpr (__is_signed_integer_like<_Winc>)
812  return _Dt(_Dt(__x._M_value) - _Dt(__y._M_value));
813  else
814  return (__y._M_value > __x._M_value)
815  ? _Dt(-_Dt(__y._M_value - __x._M_value))
816  : _Dt(__x._M_value - __y._M_value);
817  }
818  else
819  return __x._M_value - __y._M_value;
820  }
821 
822  private:
823  _Winc _M_value = _Winc();
824  };
825 
826  struct _Sentinel
827  {
828  private:
829  _Bound _M_bound = _Bound();
830 
831  public:
832  _Sentinel() = default;
833 
834  constexpr explicit
835  _Sentinel(_Bound __bound)
836  : _M_bound(__bound) { }
837 
838  friend constexpr bool
839  operator==(const _Iterator& __x, const _Sentinel& __y)
840  { return __x._M_value == __y._M_bound; }
841 
842  friend constexpr iter_difference_t<_Winc>
843  operator-(const _Iterator& __x, const _Sentinel& __y)
844  requires sized_sentinel_for<_Bound, _Winc>
845  { return __x._M_value - __y._M_bound; }
846 
847  friend constexpr iter_difference_t<_Winc>
848  operator-(const _Sentinel& __x, const _Iterator& __y)
849  requires sized_sentinel_for<_Bound, _Winc>
850  { return -(__y - __x); }
851  };
852 
853  _Winc _M_value = _Winc();
854  _Bound _M_bound = _Bound();
855 
856  public:
857  iota_view() = default;
858 
859  constexpr explicit
860  iota_view(_Winc __value)
861  : _M_value(__value)
862  { }
863 
864  constexpr
865  iota_view(type_identity_t<_Winc> __value,
866  type_identity_t<_Bound> __bound)
867  : _M_value(__value), _M_bound(__bound)
868  {
869  if constexpr (totally_ordered_with<_Winc, _Bound>)
870  __glibcxx_assert( bool(__value <= __bound) );
871  }
872 
873  constexpr _Iterator
874  begin() const { return _Iterator{_M_value}; }
875 
876  constexpr auto
877  end() const
878  {
879  if constexpr (same_as<_Bound, unreachable_sentinel_t>)
880  return unreachable_sentinel;
881  else
882  return _Sentinel{_M_bound};
883  }
884 
885  constexpr _Iterator
886  end() const requires same_as<_Winc, _Bound>
887  { return _Iterator{_M_bound}; }
888 
889  constexpr auto
890  size() const
891  requires (same_as<_Winc, _Bound> && __detail::__advanceable<_Winc>)
892  || (integral<_Winc> && integral<_Bound>)
893  || sized_sentinel_for<_Bound, _Winc>
894  {
895  using namespace __detail;
896  if constexpr (__is_integer_like<_Winc> && __is_integer_like<_Bound>)
897  return (_M_value < 0)
898  ? ((_M_bound < 0)
899  ? __to_unsigned_like(-_M_value) - __to_unsigned_like(-_M_bound)
900  : __to_unsigned_like(_M_bound) + __to_unsigned_like(-_M_value))
901  : __to_unsigned_like(_M_bound) - __to_unsigned_like(_M_value);
902  else
903  return __to_unsigned_like(_M_bound - _M_value);
904  }
905  };
906 
907  template<typename _Winc, typename _Bound>
908  requires (!__detail::__is_integer_like<_Winc>
909  || !__detail::__is_integer_like<_Bound>
910  || (__detail::__is_signed_integer_like<_Winc>
911  == __detail::__is_signed_integer_like<_Bound>))
912  iota_view(_Winc, _Bound) -> iota_view<_Winc, _Bound>;
913 
914  template<weakly_incrementable _Winc, semiregular _Bound>
915  inline constexpr bool enable_safe_range<iota_view<_Winc, _Bound>> = true;
916 
917 namespace views
918 {
919  template<typename _Tp>
920  inline constexpr empty_view<_Tp> empty{};
921 
922  struct _Single
923  {
924  template<typename _Tp>
925  auto
926  operator()(_Tp&& __e) const
927  { return single_view{std::forward<_Tp>(__e)}; }
928  };
929 
930  inline constexpr _Single single{};
931 
932  struct _Iota
933  {
934  template<typename _Tp>
935  auto
936  operator()(_Tp&& __e) const
937  { return iota_view{std::forward<_Tp>(__e)}; }
938 
939  template<typename _Tp, typename _Up>
940  auto
941  operator()(_Tp&& __e, _Up&& __f) const
942  { return iota_view{std::forward<_Tp>(__e), std::forward<_Tp>(__f)}; }
943  };
944 
945  inline constexpr _Iota iota{};
946 
947 } // namespace views
948 } // namespace ranges
949 _GLIBCXX_END_NAMESPACE_VERSION
950 } // namespace
951 #endif // library concepts
952 #endif // C++2a
953 #endif /* _GLIBCXX_RANGES */
std::operator-
constexpr complex< _Tp > operator-(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x minus y.
Definition: complex:361
std::end
_Tp * end(valarray< _Tp > &__va)
Return an iterator pointing to one past the last element of the valarray.
Definition: valarray:1234
std::begin
_Tp * begin(valarray< _Tp > &__va)
Return an iterator pointing to the first element of the valarray.
Definition: valarray:1214
std::experimental::fundamentals_v1::in_place
constexpr in_place_t in_place
Tag for in-place construction.
Definition: experimental/optional:77
std
ISO C++ entities toplevel namespace is std.
std::iota
void iota(_ForwardIterator __first, _ForwardIterator __last, _Tp __value)
Create a range of sequentially increasing values.
Definition: stl_numeric.h:87
std::advance
constexpr void advance(_InputIterator &__i, _Distance __n)
A generalization of pointer arithmetic.
Definition: stl_iterator_base_funcs.h:202
limits
initializer_list
std::operator*
constexpr complex< _Tp > operator*(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x times y.
Definition: complex:391
std::operator+
constexpr complex< _Tp > operator+(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x plus y.
Definition: complex:331
std::move
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
Definition: move.h:101
concepts
std::distance
constexpr iterator_traits< _InputIterator >::difference_type distance(_InputIterator __first, _InputIterator __last)
A generalization of pointer arithmetic.
Definition: stl_iterator_base_funcs.h:138
compare