]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/stl_interfaces/reverse_iterator.hpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / boost / stl_interfaces / reverse_iterator.hpp
1 // Copyright (C) 2019 T. Zachary Laine
2 //
3 // Distributed under the Boost Software License, Version 1.0. (See
4 // accompanying file LICENSE_1_0.txt or copy at
5 // http://www.boost.org/LICENSE_1_0.txt)
6 #ifndef BOOST_STL_INTERFACES_REVERSE_ITERATOR_HPP
7 #define BOOST_STL_INTERFACES_REVERSE_ITERATOR_HPP
8
9 #include <boost/stl_interfaces/iterator_interface.hpp>
10
11
12 namespace boost { namespace stl_interfaces { BOOST_STL_INTERFACES_NAMESPACE_V1 {
13
14 namespace v1_dtl {
15 template<typename Iter>
16 constexpr auto ce_dist(Iter f, Iter l, std::random_access_iterator_tag)
17 -> decltype(l - f)
18 {
19 return l - f;
20 }
21 template<typename Iter, typename Tag>
22 constexpr auto ce_dist(Iter f, Iter l, Tag)
23 -> decltype(std::distance(f, l))
24 {
25 decltype(std::distance(f, l)) retval = 0;
26 for (; f != l; ++f) {
27 ++retval;
28 }
29 return retval;
30 }
31
32 template<typename Iter>
33 constexpr Iter ce_prev(Iter it)
34 {
35 return --it;
36 }
37
38 template<typename Iter, typename Offset>
39 constexpr void
40 ce_adv(Iter & f, Offset n, std::random_access_iterator_tag)
41 {
42 f += n;
43 }
44 template<typename Iter, typename Offset, typename Tag>
45 constexpr void ce_adv(Iter & f, Offset n, Tag)
46 {
47 if (0 < n) {
48 for (Offset i = 0; i < n; ++i) {
49 ++f;
50 }
51 } else {
52 for (Offset i = 0; i < -n; ++i) {
53 --f;
54 }
55 }
56 }
57 }
58
59 /** This type is very similar to the C++20 version of
60 `std::reverse_iterator`; it is `constexpr`-, `noexcept`-, and
61 proxy-friendly. */
62 template<typename BidiIter>
63 struct reverse_iterator
64 : iterator_interface<
65 reverse_iterator<BidiIter>,
66 #if BOOST_STL_INTERFACES_USE_CONCEPTS
67 typename boost::stl_interfaces::v2::v2_dtl::iter_concept_t<
68 BidiIter>,
69 #else
70 typename std::iterator_traits<BidiIter>::iterator_category,
71 #endif
72 typename std::iterator_traits<BidiIter>::value_type,
73 typename std::iterator_traits<BidiIter>::reference,
74 typename std::iterator_traits<BidiIter>::pointer,
75 typename std::iterator_traits<BidiIter>::difference_type>
76 {
77 constexpr reverse_iterator() noexcept(noexcept(BidiIter())) : it_() {}
78 constexpr reverse_iterator(BidiIter it) noexcept(
79 noexcept(BidiIter(it))) :
80 it_(it)
81 {}
82 template<
83 typename BidiIter2,
84 typename E = std::enable_if_t<
85 std::is_convertible<BidiIter2, BidiIter>::value>>
86 reverse_iterator(reverse_iterator<BidiIter2> const & it) : it_(it.it_)
87 {}
88
89 friend BOOST_STL_INTERFACES_HIDDEN_FRIEND_CONSTEXPR auto
90 operator-(reverse_iterator lhs, reverse_iterator rhs) noexcept(
91 noexcept(v1_dtl::ce_dist(
92 lhs.it_,
93 rhs.it_,
94 typename std::iterator_traits<BidiIter>::iterator_category{})))
95 {
96 return -v1_dtl::ce_dist(
97 rhs.it_,
98 lhs.it_,
99 typename std::iterator_traits<BidiIter>::iterator_category{});
100 }
101
102 constexpr typename std::iterator_traits<BidiIter>::reference
103 operator*() const noexcept(
104 noexcept(std::prev(v1_dtl::ce_prev(std::declval<BidiIter &>()))))
105 {
106 return *v1_dtl::ce_prev(it_);
107 }
108
109 constexpr reverse_iterator & operator+=(
110 typename std::iterator_traits<BidiIter>::difference_type
111 n) noexcept(noexcept(v1_dtl::
112 ce_adv(
113 std::declval<BidiIter &>(),
114 -n,
115 typename std::iterator_traits<
116 BidiIter>::
117 iterator_category{})))
118 {
119 v1_dtl::ce_adv(
120 it_,
121 -n,
122 typename std::iterator_traits<BidiIter>::iterator_category{});
123 return *this;
124 }
125
126 constexpr BidiIter base() const noexcept { return it_; }
127
128 private:
129 friend access;
130 constexpr BidiIter & base_reference() noexcept { return it_; }
131 constexpr BidiIter const & base_reference() const noexcept
132 {
133 return it_;
134 }
135
136 template<typename BidiIter2>
137 friend struct reverse_iterator;
138
139 BidiIter it_;
140 };
141
142 template<typename BidiIter>
143 constexpr auto operator==(
144 reverse_iterator<BidiIter> lhs,
145 reverse_iterator<BidiIter>
146 rhs) noexcept(noexcept(lhs.base() == rhs.base()))
147 -> decltype(rhs.base() == lhs.base())
148 {
149 return lhs.base() == rhs.base();
150 }
151
152 template<typename BidiIter1, typename BidiIter2>
153 constexpr auto operator==(
154 reverse_iterator<BidiIter1> lhs,
155 reverse_iterator<BidiIter2>
156 rhs) noexcept(noexcept(lhs.base() == rhs.base()))
157 -> decltype(rhs.base() == lhs.base())
158 {
159 return lhs.base() == rhs.base();
160 }
161
162 /** Makes a `reverse_iterator<BidiIter>` from an iterator of type
163 `Bidiiter`. */
164 template<typename BidiIter>
165 auto make_reverse_iterator(BidiIter it)
166 {
167 return reverse_iterator<BidiIter>(it);
168 }
169
170 }}}
171
172
173 #if defined(BOOST_STL_INTERFACES_DOXYGEN) || BOOST_STL_INTERFACES_USE_CONCEPTS
174
175 namespace boost { namespace stl_interfaces { BOOST_STL_INTERFACES_NAMESPACE_V2 {
176
177 /** A template alias for `std::reverse_iterator`. This only exists to
178 make migration from Boost.STLInterfaces to C++20 easier; switch to the
179 one in `std` as soon as you can. */
180 template<typename BidiIter>
181 using reverse_iterator = std::reverse_iterator<BidiIter>;
182
183
184 /** Makes a `reverse_iterator<BidiIter>` from an iterator of type
185 `Bidiiter`. This only exists to make migration from
186 Boost.STLInterfaces to C++20 easier; switch to the one in `std` as
187 soon as you can. */
188 template<typename BidiIter>
189 auto make_reverse_iterator(BidiIter it)
190 {
191 return reverse_iterator<BidiIter>(it);
192 }
193
194 }}}
195
196 #endif
197
198 #endif