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