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#include <boost/stl_interfaces/iterator_interface.hpp>
7#include <boost/stl_interfaces/reverse_iterator.hpp>
8
9#include <boost/core/lightweight_test.hpp>
10
11#include <algorithm>
12#include <array>
13#include <list>
14#include <tuple>
15#include <vector>
16
17
18struct zip_iter : boost::stl_interfaces::proxy_iterator_interface<
19#if !BOOST_STL_INTERFACES_USE_DEDUCED_THIS
20 zip_iter,
21#endif
22 std::random_access_iterator_tag,
23 std::tuple<int, int>,
24 std::tuple<int &, int &>>
25{
26 zip_iter() : it1_(nullptr), it2_(nullptr) {}
27 zip_iter(int * it1, int * it2) : it1_(it1), it2_(it2) {}
28
29 std::tuple<int &, int &> operator*() const
30 {
31 return std::tuple<int &, int &>{*it1_, *it2_};
32 }
33 zip_iter & operator+=(std::ptrdiff_t i)
34 {
35 it1_ += i;
36 it2_ += i;
37 return *this;
38 }
39 friend std::ptrdiff_t operator-(zip_iter lhs, zip_iter rhs) noexcept
40 {
41 return lhs.it1_ - rhs.it1_;
42 }
43
44private:
45 int * it1_;
46 int * it2_;
47};
48
49
50int main()
51{
52
53{
54 std::list<int> ints = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
55
56 auto first = boost::stl_interfaces::make_reverse_iterator(it: ints.end());
57 auto last = boost::stl_interfaces::make_reverse_iterator(it: ints.begin());
58
59 {
60 auto cfirst = boost::stl_interfaces::reverse_iterator<
61 std::list<int>::const_iterator>(first);
62 auto clast = boost::stl_interfaces::reverse_iterator<
63 std::list<int>::const_iterator>(last);
64 BOOST_TEST(std::equal(first, last, cfirst, clast));
65 }
66
67 {
68 auto ints_copy = ints;
69 std::reverse(first: ints_copy.begin(), last: ints_copy.end());
70 BOOST_TEST(
71 std::equal(first, last, ints_copy.begin(), ints_copy.end()));
72 }
73
74 {
75 std::list<int> ints_copy;
76 std::reverse_copy(first: first, last: last, result: std::back_inserter(x&: ints_copy));
77 BOOST_TEST(ints_copy == ints);
78 }
79
80 {
81 std::size_t count = 0;
82 for (auto it = first; it != last; ++it) {
83 ++count;
84 }
85 BOOST_TEST(count == ints.size());
86 }
87
88 {
89 std::size_t count = 0;
90 for (auto it = first; it != last; it++) {
91 ++count;
92 }
93 BOOST_TEST(count == ints.size());
94 }
95
96 {
97 std::size_t count = 0;
98 for (auto it = last; it != first; --it) {
99 ++count;
100 }
101 BOOST_TEST(count == ints.size());
102 }
103
104 {
105 std::size_t count = 0;
106 for (auto it = last; it != first; it--) {
107 ++count;
108 }
109 BOOST_TEST(count == ints.size());
110 }
111}
112
113
114{
115 std::vector<int> ints = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
116
117 auto first = boost::stl_interfaces::make_reverse_iterator(it: ints.end());
118 auto last = boost::stl_interfaces::make_reverse_iterator(it: ints.begin());
119
120 {
121 auto cfirst = boost::stl_interfaces::reverse_iterator<
122 std::vector<int>::const_iterator>(first);
123 auto clast = boost::stl_interfaces::reverse_iterator<
124 std::vector<int>::const_iterator>(last);
125 BOOST_TEST(std::equal(first, last, cfirst, clast));
126 }
127
128 {
129 auto ints_copy = ints;
130 std::reverse(first: ints_copy.begin(), last: ints_copy.end());
131 BOOST_TEST(first - last == ints_copy.begin() - ints_copy.end());
132 BOOST_TEST(
133 std::equal(first, last, ints_copy.begin(), ints_copy.end()));
134 }
135
136 {
137 std::vector<int> ints_copy;
138 std::reverse_copy(first: first, last: last, result: std::back_inserter(x&: ints_copy));
139 BOOST_TEST(ints_copy == ints);
140 }
141
142 {
143 std::size_t count = 0;
144 for (auto it = first; it != last; ++it) {
145 ++count;
146 }
147 BOOST_TEST(count == ints.size());
148 }
149
150 {
151 std::size_t count = 0;
152 for (auto it = first; it != last; it++) {
153 ++count;
154 }
155 BOOST_TEST(count == ints.size());
156 }
157
158 {
159 std::size_t count = 0;
160 for (auto it = last; it != first; --it) {
161 ++count;
162 }
163 BOOST_TEST(count == ints.size());
164 }
165
166 {
167 std::size_t count = 0;
168 for (auto it = last; it != first; it--) {
169 ++count;
170 }
171 BOOST_TEST(count == ints.size());
172 }
173}
174
175
176{
177 std::array<int, 10> ints = {._M_elems: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}};
178 std::array<int, 10> ones = {._M_elems: {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}};
179 std::array<std::tuple<int, int>, 10> tuples = {._M_elems: {
180 {0, 1},
181 {1, 1},
182 {2, 1},
183 {3, 1},
184 {4, 1},
185 {5, 1},
186 {6, 1},
187 {7, 1},
188 {8, 1},
189 {9, 1},
190 }};
191
192 auto first = boost::stl_interfaces::make_reverse_iterator(
193 it: zip_iter(ints.data() + ints.size(), ones.data() + ones.size()));
194 auto last = boost::stl_interfaces::make_reverse_iterator(
195 it: zip_iter(ints.data(), ones.data()));
196
197 {
198 auto tuples_copy = tuples;
199 std::reverse(first: tuples_copy.begin(), last: tuples_copy.end());
200 BOOST_TEST(first - last == tuples_copy.begin() - tuples_copy.end());
201 BOOST_TEST(
202 std::equal(first, last, tuples_copy.begin(), tuples_copy.end()));
203 }
204
205 {
206 std::array<std::tuple<int, int>, 10> tuples_copy;
207 std::reverse_copy(first: first, last: last, result: tuples_copy.begin());
208 BOOST_TEST(tuples_copy == tuples);
209 }
210
211 {
212 std::size_t count = 0;
213 for (auto it = first; it != last; ++it) {
214 ++count;
215 }
216 BOOST_TEST(count == tuples.size());
217 }
218
219 {
220 std::size_t count = 0;
221 for (auto it = first; it != last; it++) {
222 ++count;
223 }
224 BOOST_TEST(count == tuples.size());
225 }
226
227 {
228 std::size_t count = 0;
229 for (auto it = last; it != first; --it) {
230 ++count;
231 }
232 BOOST_TEST(count == tuples.size());
233 }
234
235 {
236 std::size_t count = 0;
237 for (auto it = last; it != first; it--) {
238 ++count;
239 }
240 BOOST_TEST(count == tuples.size());
241 }
242}
243
244 return boost::report_errors();
245}
246

source code of boost/libs/stl_interfaces/test/reverse_iter.cpp