]>
Commit | Line | Data |
---|---|---|
20effc67 TL |
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 | ||
8 | #include "ill_formed.hpp" | |
9 | ||
10 | #include <boost/core/lightweight_test.hpp> | |
11 | ||
12 | #include <algorithm> | |
13 | #include <array> | |
14 | #include <numeric> | |
15 | #include <type_traits> | |
16 | ||
17 | ||
18 | template<typename T> | |
19 | using decrementable_t = decltype(--std::declval<T &>()); | |
20 | ||
21 | struct basic_forward_iter | |
22 | : boost::stl_interfaces:: | |
23 | iterator_interface<basic_forward_iter, std::forward_iterator_tag, int> | |
24 | { | |
25 | basic_forward_iter() : it_(nullptr) {} | |
26 | basic_forward_iter(int * it) : it_(it) {} | |
27 | ||
28 | int & operator*() const { return *it_; } | |
29 | basic_forward_iter & operator++() | |
30 | { | |
31 | ++it_; | |
32 | return *this; | |
33 | } | |
34 | friend bool | |
35 | operator==(basic_forward_iter lhs, basic_forward_iter rhs) noexcept | |
36 | { | |
37 | return lhs.it_ == rhs.it_; | |
38 | } | |
39 | ||
40 | using base_type = boost::stl_interfaces:: | |
41 | iterator_interface<basic_forward_iter, std::forward_iterator_tag, int>; | |
42 | using base_type::operator++; | |
43 | ||
44 | private: | |
45 | int * it_; | |
46 | }; | |
47 | ||
48 | BOOST_STL_INTERFACES_STATIC_ASSERT_CONCEPT( | |
49 | basic_forward_iter, std::forward_iterator) | |
50 | BOOST_STL_INTERFACES_STATIC_ASSERT_ITERATOR_TRAITS( | |
51 | basic_forward_iter, | |
52 | std::forward_iterator_tag, | |
53 | std::forward_iterator_tag, | |
54 | int, | |
55 | int &, | |
56 | int *, | |
57 | std::ptrdiff_t) | |
58 | ||
59 | static_assert(ill_formed<decrementable_t, basic_forward_iter>::value, ""); | |
60 | ||
61 | template<typename ValueType> | |
62 | struct forward_iter : boost::stl_interfaces::iterator_interface< | |
63 | forward_iter<ValueType>, | |
64 | std::forward_iterator_tag, | |
65 | ValueType> | |
66 | { | |
67 | forward_iter() : it_(nullptr) {} | |
68 | forward_iter(ValueType * it) : it_(it) {} | |
69 | template< | |
70 | typename ValueType2, | |
71 | typename E = std::enable_if_t< | |
72 | std::is_convertible<ValueType2 *, ValueType *>::value>> | |
73 | forward_iter(forward_iter<ValueType2> it) : it_(it.it_) | |
74 | {} | |
75 | ||
76 | ValueType & operator*() const { return *it_; } | |
77 | forward_iter & operator++() | |
78 | { | |
79 | ++it_; | |
80 | return *this; | |
81 | } | |
82 | friend bool operator==(forward_iter lhs, forward_iter rhs) noexcept | |
83 | { | |
84 | return lhs.it_ == rhs.it_; | |
85 | } | |
86 | ||
87 | using base_type = boost::stl_interfaces::iterator_interface< | |
88 | forward_iter<ValueType>, | |
89 | std::forward_iterator_tag, | |
90 | ValueType>; | |
91 | using base_type::operator++; | |
92 | ||
93 | private: | |
94 | ValueType * it_; | |
95 | ||
96 | template<typename ValueType2> | |
97 | friend struct forward_iter; | |
98 | }; | |
99 | ||
100 | using forward = forward_iter<int>; | |
101 | using const_forward = forward_iter<int const>; | |
102 | ||
103 | static_assert(ill_formed<decrementable_t, forward>::value, ""); | |
104 | static_assert(ill_formed<decrementable_t, const_forward>::value, ""); | |
105 | ||
106 | BOOST_STL_INTERFACES_STATIC_ASSERT_CONCEPT(forward, std::forward_iterator) | |
107 | BOOST_STL_INTERFACES_STATIC_ASSERT_ITERATOR_TRAITS( | |
108 | forward, | |
109 | std::forward_iterator_tag, | |
110 | std::forward_iterator_tag, | |
111 | int, | |
112 | int &, | |
113 | int *, | |
114 | std::ptrdiff_t) | |
115 | ||
116 | BOOST_STL_INTERFACES_STATIC_ASSERT_CONCEPT(const_forward, std::forward_iterator) | |
117 | BOOST_STL_INTERFACES_STATIC_ASSERT_ITERATOR_TRAITS( | |
118 | const_forward, | |
119 | std::forward_iterator_tag, | |
120 | std::forward_iterator_tag, | |
121 | int, | |
122 | int const &, | |
123 | int const *, | |
124 | std::ptrdiff_t) | |
125 | ||
126 | ||
127 | std::array<int, 10> ints = {{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}}; | |
128 | ||
129 | ||
130 | ||
131 | //////////////////// | |
132 | // view_interface // | |
133 | //////////////////// | |
134 | #include "view_tests.hpp" | |
135 | ||
136 | template<typename T> | |
137 | using data_t = decltype(std::declval<T>().data()); | |
138 | ||
139 | static_assert( | |
140 | ill_formed< | |
141 | data_t, | |
142 | subrange< | |
143 | basic_forward_iter, | |
144 | basic_forward_iter, | |
1e59de90 | 145 | boost::stl_interfaces::element_layout::discontiguous>>::value, |
20effc67 TL |
146 | ""); |
147 | static_assert( | |
148 | ill_formed< | |
149 | data_t, | |
150 | subrange< | |
151 | basic_forward_iter, | |
152 | basic_forward_iter, | |
1e59de90 | 153 | boost::stl_interfaces::element_layout::discontiguous> const>:: |
20effc67 TL |
154 | value, |
155 | ""); | |
156 | ||
157 | template<typename T> | |
158 | using size_t_ = decltype(std::declval<T>().size()); | |
159 | ||
160 | static_assert( | |
161 | ill_formed< | |
162 | size_t_, | |
163 | subrange< | |
164 | basic_forward_iter, | |
165 | basic_forward_iter, | |
1e59de90 | 166 | boost::stl_interfaces::element_layout::discontiguous>>::value, |
20effc67 TL |
167 | ""); |
168 | static_assert( | |
169 | ill_formed< | |
170 | size_t_, | |
171 | subrange< | |
172 | basic_forward_iter, | |
173 | basic_forward_iter, | |
1e59de90 | 174 | boost::stl_interfaces::element_layout::discontiguous> const>:: |
20effc67 TL |
175 | value, |
176 | ""); | |
177 | ||
178 | template<typename T> | |
179 | using back_t_ = decltype(std::declval<T>().back()); | |
180 | ||
181 | static_assert( | |
182 | ill_formed< | |
183 | back_t_, | |
184 | subrange< | |
185 | basic_forward_iter, | |
186 | basic_forward_iter, | |
1e59de90 | 187 | boost::stl_interfaces::element_layout::discontiguous>>::value, |
20effc67 TL |
188 | ""); |
189 | static_assert( | |
190 | ill_formed< | |
191 | back_t_, | |
192 | subrange< | |
193 | basic_forward_iter, | |
194 | basic_forward_iter, | |
1e59de90 | 195 | boost::stl_interfaces::element_layout::discontiguous> const>:: |
20effc67 TL |
196 | value, |
197 | ""); | |
198 | ||
199 | template<typename T> | |
200 | using index_operator_t = decltype(std::declval<T>()[0]); | |
201 | ||
202 | static_assert( | |
203 | ill_formed< | |
204 | index_operator_t, | |
205 | subrange< | |
206 | basic_forward_iter, | |
207 | basic_forward_iter, | |
1e59de90 | 208 | boost::stl_interfaces::element_layout::discontiguous>>::value, |
20effc67 TL |
209 | ""); |
210 | static_assert( | |
211 | ill_formed< | |
212 | index_operator_t, | |
213 | subrange< | |
214 | basic_forward_iter, | |
215 | basic_forward_iter, | |
1e59de90 | 216 | boost::stl_interfaces::element_layout::discontiguous> const>:: |
20effc67 TL |
217 | value, |
218 | ""); | |
219 | ||
220 | ||
221 | int main() | |
222 | { | |
223 | ||
224 | { | |
225 | basic_forward_iter first(ints.data()); | |
226 | basic_forward_iter last(ints.data() + ints.size()); | |
227 | ||
228 | { | |
229 | std::array<int, 10> ints_copy; | |
230 | std::copy(first, last, ints_copy.begin()); | |
231 | BOOST_TEST(ints_copy == ints); | |
232 | } | |
233 | ||
234 | { | |
235 | std::array<int, 10> iota_ints; | |
236 | basic_forward_iter first(iota_ints.data()); | |
237 | basic_forward_iter last(iota_ints.data() + iota_ints.size()); | |
238 | std::iota(first, last, 0); | |
239 | BOOST_TEST(iota_ints == ints); | |
240 | } | |
241 | } | |
242 | ||
243 | ||
244 | { | |
245 | forward first(ints.data()); | |
246 | forward last(ints.data() + ints.size()); | |
247 | const_forward first_copy(first); | |
248 | const_forward last_copy(last); | |
249 | std::equal(first, last, first_copy, last_copy); | |
250 | } | |
251 | ||
252 | ||
253 | { | |
254 | forward first(ints.data()); | |
255 | forward last(ints.data() + ints.size()); | |
256 | while (first != last) | |
257 | first++; | |
258 | } | |
259 | ||
260 | ||
261 | { | |
262 | forward first(ints.data()); | |
263 | forward last(ints.data() + ints.size()); | |
264 | ||
265 | { | |
266 | std::array<int, 10> ints_copy; | |
267 | std::copy(first, last, ints_copy.begin()); | |
268 | BOOST_TEST(ints_copy == ints); | |
269 | } | |
270 | ||
271 | { | |
272 | std::array<int, 10> iota_ints; | |
273 | forward first(iota_ints.data()); | |
274 | forward last(iota_ints.data() + iota_ints.size()); | |
275 | std::iota(first, last, 0); | |
276 | BOOST_TEST(iota_ints == ints); | |
277 | } | |
278 | } | |
279 | ||
280 | ||
281 | { | |
282 | const_forward first(ints.data()); | |
283 | const_forward last(ints.data() + ints.size()); | |
284 | ||
285 | { | |
286 | std::array<int, 10> ints_copy; | |
287 | std::copy(first, last, ints_copy.begin()); | |
288 | BOOST_TEST(ints_copy == ints); | |
289 | } | |
290 | ||
291 | { | |
292 | BOOST_TEST(std::binary_search(first, last, 3)); | |
293 | } | |
294 | } | |
295 | ||
296 | { | |
297 | basic_forward_iter first(ints.data()); | |
298 | basic_forward_iter last(ints.data() + ints.size()); | |
299 | ||
1e59de90 | 300 | auto r = range<boost::stl_interfaces::element_layout::discontiguous>( |
20effc67 TL |
301 | first, last); |
302 | auto empty = | |
1e59de90 | 303 | range<boost::stl_interfaces::element_layout::discontiguous>( |
20effc67 TL |
304 | first, first); |
305 | ||
306 | // range begin/end | |
307 | { | |
308 | std::array<int, 10> ints_copy; | |
309 | std::copy(r.begin(), r.end(), ints_copy.begin()); | |
310 | BOOST_TEST(ints_copy == ints); | |
311 | ||
312 | BOOST_TEST(empty.begin() == empty.end()); | |
313 | } | |
314 | ||
315 | // empty/op bool | |
316 | { | |
317 | BOOST_TEST(!r.empty()); | |
318 | BOOST_TEST(r); | |
319 | ||
320 | BOOST_TEST(empty.empty()); | |
321 | BOOST_TEST(!empty); | |
322 | ||
323 | auto const cr = r; | |
324 | BOOST_TEST(!cr.empty()); | |
325 | BOOST_TEST(cr); | |
326 | ||
327 | auto const cempty = empty; | |
328 | BOOST_TEST(cempty.empty()); | |
329 | BOOST_TEST(!cempty); | |
330 | } | |
331 | ||
332 | // front/back | |
333 | { | |
334 | BOOST_TEST(r.front() == 0); | |
335 | ||
336 | auto const cr = r; | |
337 | BOOST_TEST(cr.front() == 0); | |
338 | } | |
339 | } | |
340 | ||
341 | return boost::report_errors(); | |
342 | } |