Horizon
basic_iterator.hpp
Go to the documentation of this file.
1 // Range v3 library
3 //
4 // Copyright Eric Niebler 2014-present
5 // Copyright Casey Carter 2016
6 //
7 // Use, modification and distribution is subject to the
8 // Boost Software License, Version 1.0. (See accompanying
9 // file LICENSE_1_0.txt or copy at
10 // http://www.boost.org/LICENSE_1_0.txt)
11 //
12 // Project home: https://github.com/ericniebler/range-v3
13 //
14 #ifndef RANGES_V3_ITERATOR_BASIC_ITERATOR_HPP
15 #define RANGES_V3_ITERATOR_BASIC_ITERATOR_HPP
16 
17 #include <type_traits>
18 #include <utility>
19 
20 #include <meta/meta.hpp>
21 
22 #include <concepts/concepts.hpp>
23 
24 #include <range/v3/range_fwd.hpp>
25 
29 #include <range/v3/utility/addressof.hpp>
30 #include <range/v3/utility/box.hpp>
33 #include <range/v3/utility/static_const.hpp>
34 
35 #include <range/v3/detail/prologue.hpp>
36 
37 RANGES_DIAGNOSTIC_PUSH
38 RANGES_DIAGNOSTIC_IGNORE_MULTIPLE_ASSIGNMENT_OPERATORS
39 
40 namespace ranges
41 {
45  template<typename T>
46  struct basic_mixin : private box<T>
47  {
48  CPP_member
49  constexpr CPP_ctor(basic_mixin)()( //
50  noexcept(std::is_nothrow_default_constructible<T>::value) //
51  requires default_constructible<T>)
52  : box<T>{}
53  {}
54  CPP_member
55  constexpr explicit CPP_ctor(basic_mixin)(T && t)( //
56  noexcept(std::is_nothrow_move_constructible<T>::value) //
57  requires move_constructible<T>)
58  : box<T>(detail::move(t))
59  {}
60  CPP_member
61  constexpr explicit CPP_ctor(basic_mixin)(T const & t)( //
62  noexcept(std::is_nothrow_copy_constructible<T>::value) //
63  requires copy_constructible<T>)
64  : box<T>(t)
65  {}
66 
67  protected:
68  using box<T>::get;
69  };
70 
72  namespace detail
73  {
74  template<typename Cur>
75  using cursor_reference_t =
76  decltype(range_access::read(std::declval<Cur const &>()));
77 
78  // Compute the rvalue reference type of a cursor
79  template<typename Cur>
80  auto cursor_move(Cur const & cur, int) -> decltype(range_access::move(cur));
81  template<typename Cur>
82  auto cursor_move(Cur const & cur, long) -> aux::move_t<cursor_reference_t<Cur>>;
83 
84  template<typename Cur>
85  using cursor_rvalue_reference_t =
86  decltype(detail::cursor_move(std::declval<Cur const &>(), 42));
87 
88  // Define conversion operators from the proxy reference type
89  // to the common reference types, so that basic_iterator can model readable
90  // even with getters/setters.
91  template<typename Derived, typename Head>
92  struct proxy_reference_conversion
93  {
94  operator Head() const
95  noexcept(noexcept(Head(Head(std::declval<Derived const &>().read_()))))
96  {
97  return Head(static_cast<Derived const *>(this)->read_());
98  }
99  };
100 
101  // Collect the reference types associated with cursors
102  template<typename Cur, bool IsReadable>
103  struct cursor_traits_
104  {
105  private:
106  struct private_
107  {};
108 
109  public:
110  using value_t_ = private_;
111  using reference_t_ = private_;
112  using rvalue_reference_t_ = private_;
113  using common_refs = meta::list<>;
114  };
115 
116  template<typename Cur>
117  struct cursor_traits_<Cur, true>
118  {
119  using value_t_ = range_access::cursor_value_t<Cur>;
120  using reference_t_ = cursor_reference_t<Cur>;
121  using rvalue_reference_t_ = cursor_rvalue_reference_t<Cur>;
122 
123  private:
124  using R1 = reference_t_;
125  using R2 = common_reference_t<reference_t_, value_t_ &>;
126  using R3 = common_reference_t<reference_t_, rvalue_reference_t_>;
127  using tmp1 = meta::list<value_t_, R1>;
128  using tmp2 =
130  using tmp3 =
132 
133  public:
134  using common_refs = meta::unique<meta::pop_front<tmp3>>;
135  };
136 
137  template<typename Cur>
138  using cursor_traits = cursor_traits_<Cur, (bool)readable_cursor<Cur>>;
139 
140  template<typename Cur>
141  using cursor_value_t = typename cursor_traits<Cur>::value_t_;
142 
143  template<typename Cur, bool IsReadable>
144  struct basic_proxy_reference_;
145  template<typename Cur>
146  using basic_proxy_reference =
147  basic_proxy_reference_<Cur, (bool)readable_cursor<Cur>>;
148 
149  // The One Proxy Reference type to rule them all. basic_iterator uses this
150  // as the return type of operator* when the cursor type has a set() member
151  // function of the correct signature (i.e., if it can accept a value_type &&).
152  template<typename Cur, bool IsReadable /*= (bool) readable_cursor<Cur>*/>
153  struct RANGES_EMPTY_BASES basic_proxy_reference_
154  : cursor_traits<Cur>
155  // The following adds conversion operators to the common reference
156  // types, so that basic_proxy_reference can model readable
157  , meta::inherit<meta::transform<
158  typename cursor_traits<Cur>::common_refs,
159  meta::bind_front<meta::quote<proxy_reference_conversion>,
160  basic_proxy_reference_<Cur, IsReadable>>>>
161  {
162  private:
163  Cur * cur_;
164  template<typename, bool>
165  friend struct basic_proxy_reference_;
166  template<typename, typename>
167  friend struct proxy_reference_conversion;
168  using typename cursor_traits<Cur>::value_t_;
169  using typename cursor_traits<Cur>::reference_t_;
170  using typename cursor_traits<Cur>::rvalue_reference_t_;
171  static_assert((bool)common_reference_with<value_t_ &, reference_t_>,
172  "Your readable and writable cursor must have a value type and "
173  "a reference type that share a common reference type. See the "
174  "ranges::common_reference type trait.");
175  // BUGBUG make these private:
176  public:
177  constexpr reference_t_ read_() const noexcept(
178  noexcept(reference_t_(range_access::read(std::declval<Cur const &>()))))
179  {
180  return range_access::read(*cur_);
181  }
182  template<typename T>
183  constexpr void write_(T && t) const
184  {
185  range_access::write(*cur_, (T &&) t);
186  }
187  // public:
188  basic_proxy_reference_() = default;
189  basic_proxy_reference_(basic_proxy_reference_ const &) = default;
190  template(typename OtherCur)(
191  requires convertible_to<OtherCur *, Cur *>)
192  constexpr basic_proxy_reference_(
193  basic_proxy_reference<OtherCur> const & that) noexcept
194  : cur_(that.cur_)
195  {}
196  constexpr explicit basic_proxy_reference_(Cur & cur) noexcept
197  : cur_(&cur)
198  {}
199  CPP_member
200  constexpr auto operator=(basic_proxy_reference_ && that)
201  -> CPP_ret(basic_proxy_reference_ &)(
202  requires readable_cursor<Cur>)
203  {
204  return *this = that;
205  }
206  CPP_member
207  constexpr auto operator=(basic_proxy_reference_ const & that)
208  -> CPP_ret(basic_proxy_reference_ &)(
209  requires readable_cursor<Cur>)
210  {
211  this->write_(that.read_());
212  return *this;
213  }
214  CPP_member
215  constexpr auto operator=(basic_proxy_reference_ && that) const
216  -> CPP_ret(basic_proxy_reference_ const &)(
217  requires readable_cursor<Cur>)
218  {
219  return *this = that;
220  }
221  CPP_member
222  constexpr auto operator=(basic_proxy_reference_ const & that) const
223  -> CPP_ret(basic_proxy_reference_ const &)(
224  requires readable_cursor<Cur>)
225  {
226  this->write_(that.read_());
227  return *this;
228  }
229  template(typename OtherCur)(
230  requires readable_cursor<OtherCur> AND
231  writable_cursor<Cur, cursor_reference_t<OtherCur>>)
232  constexpr basic_proxy_reference_ & //
233  operator=(basic_proxy_reference<OtherCur> && that)
234  {
235  return *this = that;
236  }
237  template(typename OtherCur)(
238  requires readable_cursor<OtherCur> AND
239  writable_cursor<Cur, cursor_reference_t<OtherCur>>)
240  constexpr basic_proxy_reference_ & //
241  operator=(basic_proxy_reference<OtherCur> const & that)
242  {
243  this->write_(that.read_());
244  return *this;
245  }
246  template(typename OtherCur)(
247  requires readable_cursor<OtherCur> AND
248  writable_cursor<Cur, cursor_reference_t<OtherCur>>)
249  constexpr basic_proxy_reference_ const & //
250  operator=(basic_proxy_reference<OtherCur> && that) const
251  {
252  return *this = that;
253  }
254  template(typename OtherCur)(
255  requires readable_cursor<OtherCur> AND
256  writable_cursor<Cur, cursor_reference_t<OtherCur>>)
257  constexpr basic_proxy_reference_ const & //
258  operator=(basic_proxy_reference<OtherCur> const & that) const
259  {
260  this->write_(that.read_());
261  return *this;
262  }
263  template(typename T)(
264  requires writable_cursor<Cur, T>)
265  constexpr basic_proxy_reference_ & operator=(T && t) //
266  {
267  this->write_((T &&) t);
268  return *this;
269  }
270  template(typename T)(
271  requires writable_cursor<Cur, T>)
272  constexpr basic_proxy_reference_ const & operator=(T && t) const
273  {
274  this->write_((T &&) t);
275  return *this;
276  }
277  };
278 
279  template(typename Cur, bool IsReadable)(
280  requires readable_cursor<Cur> AND equality_comparable<cursor_value_t<Cur>>)
281  constexpr bool operator==(basic_proxy_reference_<Cur, IsReadable> const & x,
282  cursor_value_t<Cur> const & y)
283  {
284  return x.read_() == y;
285  }
286  template(typename Cur, bool IsReadable)(
287  requires readable_cursor<Cur> AND equality_comparable<cursor_value_t<Cur>>)
288  constexpr bool operator!=(basic_proxy_reference_<Cur, IsReadable> const & x,
289  cursor_value_t<Cur> const & y)
290  {
291  return !(x == y);
292  }
293  template(typename Cur, bool IsReadable)(
294  requires readable_cursor<Cur> AND equality_comparable<cursor_value_t<Cur>>)
295  constexpr bool operator==(cursor_value_t<Cur> const & x,
296  basic_proxy_reference_<Cur, IsReadable> const & y)
297  {
298  return x == y.read_();
299  }
300  template(typename Cur, bool IsReadable)(
301  requires readable_cursor<Cur> AND equality_comparable<cursor_value_t<Cur>>)
302  constexpr bool operator!=(cursor_value_t<Cur> const & x,
303  basic_proxy_reference_<Cur, IsReadable> const & y)
304  {
305  return !(x == y);
306  }
307  template(typename Cur, bool IsReadable)(
308  requires readable_cursor<Cur> AND equality_comparable<cursor_value_t<Cur>>)
309  constexpr bool operator==(basic_proxy_reference_<Cur, IsReadable> const & x,
310  basic_proxy_reference_<Cur, IsReadable> const & y)
311  {
312  return x.read_() == y.read_();
313  }
314  template(typename Cur, bool IsReadable)(
315  requires readable_cursor<Cur> AND equality_comparable<cursor_value_t<Cur>>)
316  constexpr bool operator!=(basic_proxy_reference_<Cur, IsReadable> const & x,
317  basic_proxy_reference_<Cur, IsReadable> const & y)
318  {
319  return !(x == y);
320  }
321 
322  template<typename Cur>
323  using cpp20_iter_cat_of_t = //
324  std::enable_if_t< //
325  input_cursor<Cur>, //
327  contiguous_cursor<Cur>, //
330  random_access_cursor<Cur>, //
331  std::random_access_iterator_tag, //
333  bidirectional_cursor<Cur>, //
334  std::bidirectional_iterator_tag, //
336  forward_cursor<Cur>, //
337  std::forward_iterator_tag, //
338  std::input_iterator_tag>>>>>;
339 
340  // clang-format off
343  template(typename C)(
344  concept (cpp17_input_cursor_)(C),
345  // Either it is not single-pass, or else we can create a
346  // proxy for postfix increment.
347  !range_access::single_pass_t<uncvref_t<C>>::value ||
348  (move_constructible<range_access::cursor_value_t<C>> &&
349  constructible_from<range_access::cursor_value_t<C>, cursor_reference_t<C>>)
350  );
351 
354  template<typename C>
355  CPP_concept cpp17_input_cursor =
356  input_cursor<C> &&
357  sentinel_for_cursor<C, C> &&
358  CPP_concept_ref(cpp17_input_cursor_, C);
359 
362  template(typename C)(
363  concept (cpp17_forward_cursor_)(C),
364  std::is_reference<cursor_reference_t<C>>::value
365  );
366 
369  template<typename C>
370  CPP_concept cpp17_forward_cursor =
371  forward_cursor<C> &&
372  CPP_concept_ref(cpp17_forward_cursor_, C);
373  // clang-format on
374 
375  template<typename Category, typename Base = void>
376  struct with_iterator_category : Base
377  {
378  using iterator_category = Category;
379  };
380 
381  template<typename Category>
382  struct with_iterator_category<Category>
383  {
384  using iterator_category = Category;
385  };
386 
387  template<typename Cur>
388  using cpp17_iter_cat_of_t = //
389  std::enable_if_t< //
390  cpp17_input_cursor<Cur>, //
392  random_access_cursor<Cur>, //
393  std::random_access_iterator_tag, //
395  bidirectional_cursor<Cur>, //
396  std::bidirectional_iterator_tag, //
398  cpp17_forward_cursor<Cur>, //
399  std::forward_iterator_tag, //
400  std::input_iterator_tag>>>>;
401 
402  template<typename Cur, typename = void>
403  struct readable_iterator_associated_types_base : range_access::mixin_base_t<Cur>
404  {
405  readable_iterator_associated_types_base() = default;
406  using range_access::mixin_base_t<Cur>::mixin_base_t;
407  readable_iterator_associated_types_base(Cur && cur)
408  : range_access::mixin_base_t<Cur>(static_cast<Cur &&>(cur))
409  {}
410  readable_iterator_associated_types_base(Cur const & cur)
411  : range_access::mixin_base_t<Cur>(cur)
412  {}
413  };
414 
415  template<typename Cur>
416  struct readable_iterator_associated_types_base<
417  Cur, always_<void, cpp17_iter_cat_of_t<Cur>>>
418  : range_access::mixin_base_t<Cur>
419  {
420  using iterator_category = cpp17_iter_cat_of_t<Cur>;
421  readable_iterator_associated_types_base() = default;
422  using range_access::mixin_base_t<Cur>::mixin_base_t;
423  readable_iterator_associated_types_base(Cur && cur)
424  : range_access::mixin_base_t<Cur>(static_cast<Cur &&>(cur))
425  {}
426  readable_iterator_associated_types_base(Cur const & cur)
427  : range_access::mixin_base_t<Cur>(cur)
428  {}
429  };
430 
431  template<typename Cur, bool IsReadable /*= (bool) readable_cursor<Cur>*/>
432  struct iterator_associated_types_base_ : range_access::mixin_base_t<Cur>
433  {
434  // BUGBUG
435  // protected:
436  using iter_reference_t = basic_proxy_reference<Cur>;
437  using const_reference_t = basic_proxy_reference<Cur const>;
438 
439  public:
440  using reference = void;
441  using difference_type = range_access::cursor_difference_t<Cur>;
442 
443  iterator_associated_types_base_() = default;
444  using range_access::mixin_base_t<Cur>::mixin_base_t;
445  iterator_associated_types_base_(Cur && cur)
446  : range_access::mixin_base_t<Cur>(static_cast<Cur &&>(cur))
447  {}
448  iterator_associated_types_base_(Cur const & cur)
449  : range_access::mixin_base_t<Cur>(cur)
450  {}
451  };
452 
453  template<typename Cur>
454  using cursor_arrow_t = decltype(range_access::arrow(std::declval<Cur const &>()));
455 
456  template<typename Cur>
457  struct iterator_associated_types_base_<Cur, true>
458  : readable_iterator_associated_types_base<Cur>
459  {
460  // BUGBUG
461  // protected:
462  using iter_reference_t =
464  basic_proxy_reference<Cur const>,
466  basic_proxy_reference<Cur>, cursor_reference_t<Cur>>>;
467  using const_reference_t =
469  basic_proxy_reference<Cur const>, cursor_reference_t<Cur>>;
470 
471  public:
472  using difference_type = range_access::cursor_difference_t<Cur>;
473  using value_type = range_access::cursor_value_t<Cur>;
474  using reference = iter_reference_t;
475  using iterator_concept = cpp20_iter_cat_of_t<Cur>;
476  using pointer = meta::_t<
478  (bool)has_cursor_arrow<Cur>,
480  std::add_pointer<reference>>>;
481  using common_reference = common_reference_t<reference, value_type &>;
482 
483  iterator_associated_types_base_() = default;
484  using readable_iterator_associated_types_base<
485  Cur>::readable_iterator_associated_types_base;
486  iterator_associated_types_base_(Cur && cur)
487  : readable_iterator_associated_types_base<Cur>(static_cast<Cur &&>(cur))
488  {}
489  iterator_associated_types_base_(Cur const & cur)
490  : readable_iterator_associated_types_base<Cur>(cur)
491  {}
492  };
493 
494  template<typename Cur>
495  using iterator_associated_types_base =
496  iterator_associated_types_base_<Cur, (bool)readable_cursor<Cur>>;
497 
498  template<typename Value>
499  struct postfix_increment_proxy
500  {
501  private:
502  Value cache_;
503 
504  public:
505  template<typename T>
506  constexpr postfix_increment_proxy(T && t)
507  : cache_(static_cast<T &&>(t))
508  {}
509  constexpr Value const & operator*() const noexcept
510  {
511  return cache_;
512  }
513  };
514  } // namespace detail
516 
517 #if RANGES_BROKEN_CPO_LOOKUP
518  namespace _basic_iterator_
519  {
520  template<typename>
521  struct adl_hook
522  {};
523  } // namespace _basic_iterator_
524 #endif
525 
526  template<typename Cur>
527  struct RANGES_EMPTY_BASES basic_iterator
528  : detail::iterator_associated_types_base<Cur>
529 #if RANGES_BROKEN_CPO_LOOKUP
530  , private _basic_iterator_::adl_hook<basic_iterator<Cur>>
531 #endif
532  {
533  private:
534  template<typename>
535  friend struct basic_iterator;
536  friend range_access;
537  using base_t = detail::iterator_associated_types_base<Cur>;
538  using mixin_t = range_access::mixin_base_t<Cur>;
539  static_assert((bool)detail::cursor<Cur>, "");
540  using assoc_types_ = detail::iterator_associated_types_base<Cur>;
541  using typename assoc_types_::const_reference_t;
542  using typename assoc_types_::iter_reference_t;
543  constexpr Cur & pos() noexcept
544  {
545  return this->mixin_t::basic_mixin::get();
546  }
547  constexpr Cur const & pos() const noexcept
548  {
549  return this->mixin_t::basic_mixin::get();
550  }
551 
552  public:
553  using typename assoc_types_::difference_type;
554  constexpr basic_iterator() = default;
555  template(typename OtherCur)(
556  requires (!same_as<OtherCur, Cur>) AND convertible_to<OtherCur, Cur> AND
557  constructible_from<mixin_t, OtherCur>)
559  : base_t{std::move(that.pos())}
560  {}
561  // Mix in any additional constructors provided by the mixin
562  using base_t::base_t;
563 
564  explicit basic_iterator(Cur && cur)
565  : base_t(static_cast<Cur &&>(cur))
566  {}
567 
568  explicit basic_iterator(Cur const & cur)
569  : base_t(cur)
570  {}
571 
572  template(typename OtherCur)(
573  requires (!same_as<OtherCur, Cur>) AND convertible_to<OtherCur, Cur>)
574  constexpr basic_iterator & operator=(basic_iterator<OtherCur> that)
575  {
576  pos() = std::move(that.pos());
577  return *this;
578  }
579 
580  CPP_member
581  constexpr auto operator*() const
582  noexcept(noexcept(range_access::read(std::declval<Cur const &>())))
583  -> CPP_ret(const_reference_t)(
584  requires detail::readable_cursor<Cur> &&
585  (!detail::is_writable_cursor_v<Cur>))
586  {
587  return range_access::read(pos());
588  }
589  CPP_member
590  constexpr auto operator*() //
591  noexcept(noexcept(iter_reference_t{std::declval<Cur &>()})) //
592  -> CPP_ret(iter_reference_t)(
593  requires detail::has_cursor_next<Cur> &&
594  detail::is_writable_cursor_v<Cur>)
595  {
596  return iter_reference_t{pos()};
597  }
598  CPP_member
599  constexpr auto operator*() const
600  noexcept(noexcept(const_reference_t{std::declval<Cur const &>()}))
601  -> CPP_ret(const_reference_t)(
602  requires detail::has_cursor_next<Cur> &&
603  detail::is_writable_cursor_v<Cur const>)
604  {
605  return const_reference_t{pos()};
606  }
607  CPP_member
608  constexpr auto operator*() noexcept //
609  -> CPP_ret(basic_iterator &)(
610  requires (!detail::has_cursor_next<Cur>))
611  {
612  return *this;
613  }
614 
615  // Use cursor's arrow() member, if any.
616  template(typename C = Cur)(
617  requires detail::has_cursor_arrow<C>)
618  constexpr detail::cursor_arrow_t<C> operator-> () const
619  noexcept(noexcept(range_access::arrow(std::declval<C const &>())))
620  {
621  return range_access::arrow(pos());
622  }
623  // Otherwise, if iter_reference_t is an lvalue reference to cv-qualified
624  // iter_value_t, return the address of **this.
625  template(typename C = Cur)(
626  requires (!detail::has_cursor_arrow<C>) AND detail::readable_cursor<C> AND
627  std::is_lvalue_reference<const_reference_t>::value AND
628  same_as<typename detail::iterator_associated_types_base<C>::value_type,
629  uncvref_t<const_reference_t>>)
630  constexpr std::add_pointer_t<const_reference_t> operator-> () const
631  noexcept(noexcept(*std::declval<basic_iterator const &>()))
632  {
633  return detail::addressof(**this);
634  }
635 
636  CPP_member
637  constexpr auto operator++() //
638  -> CPP_ret(basic_iterator &)(
639  requires detail::has_cursor_next<Cur>)
640  {
641  range_access::next(pos());
642  return *this;
643  }
644  CPP_member
645  constexpr auto operator++() noexcept //
646  -> CPP_ret(basic_iterator &)(
647  requires (!detail::has_cursor_next<Cur>))
648  {
649  return *this;
650  }
651 
652  private:
653  constexpr basic_iterator post_increment_(std::false_type, int)
654  {
655  basic_iterator tmp{*this};
656  ++*this;
657  return tmp;
658  }
659  // Attempt to satisfy the C++17 iterator requirements by returning a
660  // proxy from postfix increment:
661  template(typename A = assoc_types_, typename V = typename A::value_type)(
662  requires constructible_from<V, typename A::reference> AND
663  move_constructible<V>)
664  constexpr auto post_increment_(std::true_type, int) //
665  -> detail::postfix_increment_proxy<V>
666  {
667  detail::postfix_increment_proxy<V> p{**this};
668  ++*this;
669  return p;
670  }
671  constexpr void post_increment_(std::true_type, long)
672  {
673  ++*this;
674  }
675 
676  public:
677  CPP_member
678  constexpr auto operator++(int)
679  {
680  return this->post_increment_(meta::bool_ < detail::input_cursor<Cur> &&
681  !detail::forward_cursor<Cur>> {},
682  0);
683  }
684 
685  CPP_member
686  constexpr auto operator--()
687  -> CPP_ret(basic_iterator &)(
688  requires detail::bidirectional_cursor<Cur>)
689  {
690  range_access::prev(pos());
691  return *this;
692  }
693  CPP_member
694  constexpr auto operator--(int) //
695  -> CPP_ret(basic_iterator)(
696  requires detail::bidirectional_cursor<Cur>)
697  {
698  basic_iterator tmp(*this);
699  --*this;
700  return tmp;
701  }
702  CPP_member
703  constexpr auto operator+=(difference_type n) //
704  -> CPP_ret(basic_iterator &)(
705  requires detail::random_access_cursor<Cur>)
706  {
707  range_access::advance(pos(), n);
708  return *this;
709  }
710  CPP_member
711  constexpr auto operator-=(difference_type n) //
712  -> CPP_ret(basic_iterator &)(
713  requires detail::random_access_cursor<Cur>)
714  {
715  range_access::advance(pos(), (difference_type)-n);
716  return *this;
717  }
718  CPP_member
719  constexpr auto operator[](difference_type n) const //
720  -> CPP_ret(const_reference_t)(
721  requires detail::random_access_cursor<Cur>)
722  {
723  return *(*this + n);
724  }
725 
726 #if !RANGES_BROKEN_CPO_LOOKUP
727  // Optionally support hooking iter_move when the cursor sports a
728  // move() member function.
729  template<typename C = Cur>
730  friend constexpr auto iter_move(basic_iterator const & it) noexcept(
731  noexcept(range_access::move(std::declval<C const &>())))
732  -> CPP_broken_friend_ret(
733  decltype(range_access::move(std::declval<C const &>())))(
734  requires same_as<C, Cur> && detail::input_cursor<Cur>)
735  {
736  return range_access::move(it.pos());
737  }
738 #endif
739  };
740 
741  template(typename Cur, typename Cur2)(
742  requires detail::sentinel_for_cursor<Cur2, Cur>)
743  constexpr bool operator==(basic_iterator<Cur> const & left,
744  basic_iterator<Cur2> const & right)
745  {
746  return range_access::equal(range_access::pos(left), range_access::pos(right));
747  }
748  template(typename Cur, typename Cur2)(
749  requires detail::sentinel_for_cursor<Cur2, Cur>)
750  constexpr bool operator!=(basic_iterator<Cur> const & left,
751  basic_iterator<Cur2> const & right)
752  {
753  return !(left == right);
754  }
755  template(typename Cur, typename S)(
756  requires detail::sentinel_for_cursor<S, Cur>)
757  constexpr bool operator==(basic_iterator<Cur> const & left,
758  S const & right)
759  {
760  return range_access::equal(range_access::pos(left), right);
761  }
762  template(typename Cur, typename S)(
763  requires detail::sentinel_for_cursor<S, Cur>)
764  constexpr bool operator!=(basic_iterator<Cur> const & left,
765  S const & right)
766  {
767  return !(left == right);
768  }
769  template(typename S, typename Cur)(
770  requires detail::sentinel_for_cursor<S, Cur>)
771  constexpr bool operator==(S const & left,
772  basic_iterator<Cur> const & right)
773  {
774  return right == left;
775  }
776  template(typename S, typename Cur)(
777  requires detail::sentinel_for_cursor<S, Cur>)
778  constexpr bool operator!=(S const & left,
779  basic_iterator<Cur> const & right)
780  {
781  return right != left;
782  }
783 
784  template(typename Cur)(
785  requires detail::random_access_cursor<Cur>)
786  constexpr basic_iterator<Cur> //
787  operator+(basic_iterator<Cur> left, typename basic_iterator<Cur>::difference_type n)
788  {
789  left += n;
790  return left;
791  }
792  template(typename Cur)(
793  requires detail::random_access_cursor<Cur>)
794  constexpr basic_iterator<Cur> //
795  operator+(typename basic_iterator<Cur>::difference_type n, basic_iterator<Cur> right)
796  {
797  right += n;
798  return right;
799  }
800  template(typename Cur)(
801  requires detail::random_access_cursor<Cur>)
802  constexpr basic_iterator<Cur> //
803  operator-(basic_iterator<Cur> left, typename basic_iterator<Cur>::difference_type n)
804  {
805  left -= n;
806  return left;
807  }
808  template(typename Cur2, typename Cur)(
809  requires detail::sized_sentinel_for_cursor<Cur2, Cur>)
810  constexpr typename basic_iterator<Cur>::difference_type //
811  operator-(basic_iterator<Cur2> const & left, basic_iterator<Cur> const & right)
812  {
813  return range_access::distance_to(range_access::pos(right),
814  range_access::pos(left));
815  }
816  template(typename S, typename Cur)(
817  requires detail::sized_sentinel_for_cursor<S, Cur>)
818  constexpr typename basic_iterator<Cur>::difference_type //
819  operator-(S const & left, basic_iterator<Cur> const & right)
820  {
821  return range_access::distance_to(range_access::pos(right), left);
822  }
823  template(typename Cur, typename S)(
824  requires detail::sized_sentinel_for_cursor<S, Cur>)
825  constexpr typename basic_iterator<Cur>::difference_type //
826  operator-(basic_iterator<Cur> const & left, S const & right)
827  {
828  return -(right - left);
829  }
830  // Asymmetric comparisons
831  template(typename Left, typename Right)(
832  requires detail::sized_sentinel_for_cursor<Right, Left>)
833  constexpr bool operator<(basic_iterator<Left> const & left,
834  basic_iterator<Right> const & right)
835  {
836  return 0 < (right - left);
837  }
838  template(typename Left, typename Right)(
839  requires detail::sized_sentinel_for_cursor<Right, Left>)
840  constexpr bool operator<=(basic_iterator<Left> const & left,
841  basic_iterator<Right> const & right)
842  {
843  return 0 <= (right - left);
844  }
845  template(typename Left, typename Right)(
846  requires detail::sized_sentinel_for_cursor<Right, Left>)
847  constexpr bool operator>(basic_iterator<Left> const & left,
848  basic_iterator<Right> const & right)
849  {
850  return (right - left) < 0;
851  }
852  template(typename Left, typename Right)(
853  requires detail::sized_sentinel_for_cursor<Right, Left>)
854  constexpr bool operator>=(basic_iterator<Left> const & left,
855  basic_iterator<Right> const & right)
856  {
857  return (right - left) <= 0;
858  }
859 
860 #if RANGES_BROKEN_CPO_LOOKUP
861  namespace _basic_iterator_
862  {
863  // Optionally support hooking iter_move when the cursor sports a
864  // move() member function.
865  template<typename Cur>
866  constexpr auto iter_move(basic_iterator<Cur> const & it) noexcept(
867  noexcept(range_access::move(std::declval<Cur const &>())))
868  -> CPP_broken_friend_ret(
869  decltype(range_access::move(std::declval<Cur const &>())))(
870  requires detail::input_cursor<Cur>)
871  {
872  return range_access::move(range_access::pos(it));
873  }
874  } // namespace _basic_iterator_
875 #endif
876 
879  {
880  template<typename Cur>
881  constexpr Cur & operator()(basic_iterator<Cur> & it) const noexcept
882  {
883  return range_access::pos(it);
884  }
885  template<typename Cur>
886  constexpr Cur const & operator()(basic_iterator<Cur> const & it) const noexcept
887  {
888  return range_access::pos(it);
889  }
890  template<typename Cur>
891  constexpr Cur operator()(basic_iterator<Cur> && it) const
892  noexcept(std::is_nothrow_move_constructible<Cur>::value)
893  {
894  return range_access::pos(std::move(it));
895  }
896  };
897 
901 } // namespace ranges
902 
904 namespace concepts
905 {
906  // common_reference specializations for basic_proxy_reference
907  template<typename Cur, typename U, template<typename> class TQual,
908  template<typename> class UQual>
909  struct basic_common_reference<::ranges::detail::basic_proxy_reference_<Cur, true>, U,
910  TQual, UQual>
911  : basic_common_reference<::ranges::detail::cursor_reference_t<Cur>, U, TQual, UQual>
912  {};
913  template<typename T, typename Cur, template<typename> class TQual,
914  template<typename> class UQual>
915  struct basic_common_reference<T, ::ranges::detail::basic_proxy_reference_<Cur, true>,
916  TQual, UQual>
917  : basic_common_reference<T, ::ranges::detail::cursor_reference_t<Cur>, TQual, UQual>
918  {};
919  template<typename Cur1, typename Cur2, template<typename> class TQual,
920  template<typename> class UQual>
921  struct basic_common_reference<::ranges::detail::basic_proxy_reference_<Cur1, true>,
922  ::ranges::detail::basic_proxy_reference_<Cur2, true>,
923  TQual, UQual>
924  : basic_common_reference<::ranges::detail::cursor_reference_t<Cur1>,
925  ::ranges::detail::cursor_reference_t<Cur2>, TQual, UQual>
926  {};
927 
928  // common_type specializations for basic_proxy_reference
929  template<typename Cur, typename U>
930  struct common_type<::ranges::detail::basic_proxy_reference_<Cur, true>, U>
931  : common_type<::ranges::range_access::cursor_value_t<Cur>, U>
932  {};
933  template<typename T, typename Cur>
934  struct common_type<T, ::ranges::detail::basic_proxy_reference_<Cur, true>>
935  : common_type<T, ::ranges::range_access::cursor_value_t<Cur>>
936  {};
937  template<typename Cur1, typename Cur2>
938  struct common_type<::ranges::detail::basic_proxy_reference_<Cur1, true>,
939  ::ranges::detail::basic_proxy_reference_<Cur2, true>>
940  : common_type<::ranges::range_access::cursor_value_t<Cur1>,
941  ::ranges::range_access::cursor_value_t<Cur2>>
942  {};
943 } // namespace concepts
944 
945 #if RANGES_CXX_VER > RANGES_CXX_STD_17
946 RANGES_DIAGNOSTIC_PUSH
947 RANGES_DIAGNOSTIC_IGNORE_MISMATCHED_TAGS
948 RANGES_BEGIN_NAMESPACE_STD
949 RANGES_BEGIN_NAMESPACE_VERSION
950  template<typename, typename, template <typename> class, template<typename> class>
951  struct basic_common_reference;
952 
953  // common_reference specializations for basic_proxy_reference
954  template<typename Cur, typename U, template<typename> class TQual,
955  template<typename> class UQual>
956  struct basic_common_reference<::ranges::detail::basic_proxy_reference_<Cur, true>, U,
957  TQual, UQual>
958  : basic_common_reference<::ranges::detail::cursor_reference_t<Cur>, U, TQual, UQual>
959  {};
960  template<typename T, typename Cur, template<typename> class TQual,
961  template<typename> class UQual>
962  struct basic_common_reference<T, ::ranges::detail::basic_proxy_reference_<Cur, true>,
963  TQual, UQual>
964  : basic_common_reference<T, ::ranges::detail::cursor_reference_t<Cur>, TQual, UQual>
965  {};
966  template<typename Cur1, typename Cur2, template<typename> class TQual,
967  template<typename> class UQual>
968  struct basic_common_reference<::ranges::detail::basic_proxy_reference_<Cur1, true>,
969  ::ranges::detail::basic_proxy_reference_<Cur2, true>,
970  TQual, UQual>
971  : basic_common_reference<::ranges::detail::cursor_reference_t<Cur1>,
972  ::ranges::detail::cursor_reference_t<Cur2>, TQual, UQual>
973  {};
974 
975  template<typename...>
976  struct common_type;
977 
978  // common_type specializations for basic_proxy_reference
979  template<typename Cur, typename U>
980  struct common_type<::ranges::detail::basic_proxy_reference_<Cur, true>, U>
981  : common_type<::ranges::range_access::cursor_value_t<Cur>, U>
982  {};
983  template<typename T, typename Cur>
984  struct common_type<T, ::ranges::detail::basic_proxy_reference_<Cur, true>>
985  : common_type<T, ::ranges::range_access::cursor_value_t<Cur>>
986  {};
987  template<typename Cur1, typename Cur2>
988  struct common_type<::ranges::detail::basic_proxy_reference_<Cur1, true>,
989  ::ranges::detail::basic_proxy_reference_<Cur2, true>>
990  : common_type<::ranges::range_access::cursor_value_t<Cur1>,
991  ::ranges::range_access::cursor_value_t<Cur2>>
992  {};
993 RANGES_END_NAMESPACE_VERSION
994 RANGES_END_NAMESPACE_STD
995 RANGES_DIAGNOSTIC_POP
996 #endif // RANGES_CXX_VER > RANGES_CXX_STD_17
997 
998 namespace ranges
999 {
1001  namespace detail
1002  {
1003  template<typename Cur, bool IsReadable>
1004  struct std_iterator_traits_
1005  {
1006  using difference_type =
1007  typename iterator_associated_types_base<Cur>::difference_type;
1008  using value_type = void;
1009  using reference = void;
1010  using pointer = void;
1011  using iterator_category = std::output_iterator_tag;
1012  using iterator_concept = std::output_iterator_tag;
1013  };
1014 
1015  template<typename Cur>
1016  struct std_iterator_traits_<Cur, true> : iterator_associated_types_base<Cur>
1017  {};
1018 
1019  template<typename Cur>
1020  using std_iterator_traits = std_iterator_traits_<Cur, (bool)readable_cursor<Cur>>;
1021  } // namespace detail
1023 } // namespace ranges
1024 
1025 namespace std
1026 {
1027  template<typename Cur>
1028  struct iterator_traits<::ranges::basic_iterator<Cur>>
1029  : ::ranges::detail::std_iterator_traits<Cur>
1030  {};
1031 } // namespace std
1033 
1034 RANGES_DIAGNOSTIC_POP
1035 
1036 #include <range/v3/detail/epilogue.hpp>
1037 
1038 #endif
Definition: box.hpp:163
meta::_t< detail::inherit_< L > > inherit
A type that inherits from all the types in the list.
Definition: meta.hpp:3114
RANGES_INLINE_VARIABLE(detail::to_container_fn< detail::from_range< std::vector >>, to_vector) template< template< typename... > class ContT > auto to(RANGES_HIDDEN_DETAIL(detail
For initializing a container of the specified type with the elements of an Range.
Definition: conversion.hpp:399
meta::if_c< std::is_reference< R >::value, meta::_t< std::remove_reference< R > > &&, detail::decay_t< R > > move_t
Definition: move.hpp:59
std::integral_constant< bool, B > bool_
An integral constant wrapper for bool.
Definition: meta.hpp:168
typename T::type _t
Type alias for T::type.
Definition: meta.hpp:141
_t< detail::_if_< list< Args... > >> if_
Select one type or another depending on a compile-time Boolean.
Definition: meta.hpp:1247
typename detail::_cond< If >::template invoke< Then, Else > conditional_t
Select one type or another depending on a compile-time Boolean.
Definition: meta.hpp:1148
fold< L, list<>, quote_trait< detail::insert_back_ > > unique
Return a new meta::list where all duplicate elements have been removed.
Definition: meta.hpp:3157
apply< bind_back< quote< list >, Ts... >, L > push_back
Return a new meta::list by adding the element T to the back of L.
Definition: meta.hpp:2173
Tiny meta-programming library.
Point operator*(double s, const Point &a)
Multiply point by scalar.
Definition: shapes.h:250
Point operator-(const Point &a, const Point &b)
Subtract two points_ component-wise.
Definition: shapes.h:244
A wrapper that defers the instantiation of a template C with type parameters Ts in a lambda or let ex...
Definition: meta.hpp:787
A list of types.
Definition: meta.hpp:1684
Definition: basic_iterator.hpp:532
Definition: basic_iterator.hpp:47
Definition: traits.hpp:48
Get a cursor from a basic_iterator.
Definition: basic_iterator.hpp:879