Horizon
reverse_iterator.hpp
Go to the documentation of this file.
1 // Range v3 library
3 //
4 // Copyright Eric Niebler 2014-present
5 //
6 // Use, modification and distribution is subject to the
7 // Boost Software License, Version 1.0. (See accompanying
8 // file LICENSE_1_0.txt or copy at
9 // http://www.boost.org/LICENSE_1_0.txt)
10 //
11 // Project home: https://github.com/ericniebler/range-v3
12 //
13 #ifndef RANGES_V3_ITERATOR_REVERSE_ITERATOR_HPP
14 #define RANGES_V3_ITERATOR_REVERSE_ITERATOR_HPP
15 
16 #include <utility>
17 
18 #include <range/v3/range_fwd.hpp>
19 
22 
23 #include <range/v3/detail/prologue.hpp>
24 
25 namespace ranges
26 {
29 
31  namespace detail
32  {
33  template<typename I>
34  struct reverse_cursor
35  {
36  private:
37  CPP_assert(bidirectional_iterator<I>);
38  friend range_access;
39 
40  using value_type = iter_value_t<I>;
41 
42  template<typename OtherI>
43  friend struct reverse_cursor;
44  struct mixin : basic_mixin<reverse_cursor>
45  {
46  mixin() = default;
47  #ifndef _MSC_VER
48  using basic_mixin<reverse_cursor>::basic_mixin;
49  #else
50  constexpr explicit mixin(reverse_cursor && cur)
51  : basic_mixin<reverse_cursor>(static_cast<reverse_cursor &&>(cur))
52  {}
53  constexpr explicit mixin(reverse_cursor const & cur)
54  : basic_mixin<reverse_cursor>(cur)
55  {}
56  #endif
57  constexpr mixin(I it)
58  : mixin{reverse_cursor{it}}
59  {}
60  constexpr I base() const
61  {
62  return this->get().base();
63  }
64  };
65 
66  I it_;
67 
68  constexpr reverse_cursor(I it)
69  : it_(std::move(it))
70  {}
71  constexpr iter_reference_t<I> read() const
72  {
73  return *arrow();
74  }
75  constexpr I arrow() const
76  {
77  auto tmp = it_;
78  --tmp;
79  return tmp;
80  }
81  constexpr I base() const
82  {
83  return it_;
84  }
85  template(typename J)(
86  requires sentinel_for<J, I>)
87  constexpr bool equal(reverse_cursor<J> const & that) const
88  {
89  return it_ == that.it_;
90  }
91  constexpr void next()
92  {
93  --it_;
94  }
95  constexpr void prev()
96  {
97  ++it_;
98  }
99  CPP_member
100  constexpr auto advance(iter_difference_t<I> n) //
101  -> CPP_ret(void)(
102  requires random_access_iterator<I>)
103  {
104  it_ -= n;
105  }
106  template(typename J)(
107  requires sized_sentinel_for<J, I>)
108  constexpr iter_difference_t<I> distance_to(reverse_cursor<J> const & that) //
109  const
110  {
111  return it_ - that.base();
112  }
113  constexpr iter_rvalue_reference_t<I> move() const
114  noexcept(noexcept((void)I(I(it_)), (void)--const_cast<I &>(it_),
115  iter_move(it_)))
116  {
117  auto tmp = it_;
118  --tmp;
119  return iter_move(tmp);
120  }
121 
122  public:
123  reverse_cursor() = default;
124  template(typename U)(
125  requires convertible_to<U, I>)
126  constexpr reverse_cursor(reverse_cursor<U> const & u)
127  : it_(u.base())
128  {}
129  };
130  } // namespace detail
132 
134  {
135  template(typename I)(
136  requires bidirectional_iterator<I>)
137  constexpr reverse_iterator<I> operator()(I i) const
138  {
139  return reverse_iterator<I>(i);
140  }
141  };
142 
143  RANGES_INLINE_VARIABLE(make_reverse_iterator_fn, make_reverse_iterator)
144 
145  namespace cpp20
146  {
147  using ranges::make_reverse_iterator;
149  } // namespace cpp20
151 } // namespace ranges
152 
153 #include <range/v3/detail/epilogue.hpp>
154 
155 #endif // RANGES_V3_ITERATOR_REVERSE_ITERATOR_HPP
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
Definition: basic_iterator.hpp:532
Definition: reverse_iterator.hpp:134