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

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