]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/stl_interfaces/test/random_access.cpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / libs / stl_interfaces / test / random_access.cpp
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 <functional>
15 #include <numeric>
16 #include <tuple>
17 #include <type_traits>
18
19
20 struct basic_random_access_iter : boost::stl_interfaces::iterator_interface<
21 basic_random_access_iter,
22 std::random_access_iterator_tag,
23 int>
24 {
25 basic_random_access_iter() {}
26 basic_random_access_iter(int * it) : it_(it) {}
27
28 int & operator*() const { return *it_; }
29 basic_random_access_iter & operator+=(std::ptrdiff_t i)
30 {
31 it_ += i;
32 return *this;
33 }
34 friend std::ptrdiff_t operator-(
35 basic_random_access_iter lhs, basic_random_access_iter rhs) noexcept
36 {
37 return lhs.it_ - rhs.it_;
38 }
39
40 private:
41 int * it_;
42 };
43
44 BOOST_STL_INTERFACES_STATIC_ASSERT_CONCEPT(
45 basic_random_access_iter, std::random_access_iterator)
46 BOOST_STL_INTERFACES_STATIC_ASSERT_ITERATOR_TRAITS(
47 basic_random_access_iter,
48 std::random_access_iterator_tag,
49 std::random_access_iterator_tag,
50 int,
51 int &,
52 int *,
53 std::ptrdiff_t)
54
55 static_assert(
56 boost::stl_interfaces::v1::v1_dtl::
57 plus_eq<basic_random_access_iter, std::ptrdiff_t>::value,
58 "");
59
60 struct basic_adapted_random_access_iter
61 : boost::stl_interfaces::iterator_interface<
62 basic_adapted_random_access_iter,
63 std::random_access_iterator_tag,
64 int>
65 {
66 basic_adapted_random_access_iter() {}
67 basic_adapted_random_access_iter(int * it) : it_(it) {}
68
69 private:
70 friend boost::stl_interfaces::access;
71 int *& base_reference() noexcept { return it_; }
72 int * base_reference() const noexcept { return it_; }
73
74 int * it_;
75 };
76
77 BOOST_STL_INTERFACES_STATIC_ASSERT_CONCEPT(
78 basic_adapted_random_access_iter, std::random_access_iterator)
79 BOOST_STL_INTERFACES_STATIC_ASSERT_ITERATOR_TRAITS(
80 basic_adapted_random_access_iter,
81 std::random_access_iterator_tag,
82 std::random_access_iterator_tag,
83 int,
84 int &,
85 int *,
86 std::ptrdiff_t)
87
88 template<typename ValueType>
89 struct adapted_random_access_iter : boost::stl_interfaces::iterator_interface<
90 adapted_random_access_iter<ValueType>,
91 std::random_access_iterator_tag,
92 ValueType>
93 {
94 adapted_random_access_iter() {}
95 adapted_random_access_iter(ValueType * it) : it_(it) {}
96
97 template<
98 typename ValueType2,
99 typename Enable = std::enable_if_t<
100 std::is_convertible<ValueType2 *, ValueType *>::value>>
101 adapted_random_access_iter(adapted_random_access_iter<ValueType2> other) :
102 it_(other.it_)
103 {}
104
105 template<typename ValueType2>
106 friend struct adapted_random_access_iter;
107
108 private:
109 friend boost::stl_interfaces::access;
110 ValueType *& base_reference() noexcept { return it_; }
111 ValueType * base_reference() const noexcept { return it_; }
112
113 ValueType * it_;
114 };
115
116 BOOST_STL_INTERFACES_STATIC_ASSERT_CONCEPT(
117 adapted_random_access_iter<int>, std::random_access_iterator)
118 BOOST_STL_INTERFACES_STATIC_ASSERT_ITERATOR_TRAITS(
119 adapted_random_access_iter<int>,
120 std::random_access_iterator_tag,
121 std::random_access_iterator_tag,
122 int,
123 int &,
124 int *,
125 std::ptrdiff_t)
126 BOOST_STL_INTERFACES_STATIC_ASSERT_CONCEPT(
127 adapted_random_access_iter<int const>, std::random_access_iterator)
128 BOOST_STL_INTERFACES_STATIC_ASSERT_ITERATOR_TRAITS(
129 adapted_random_access_iter<int const>,
130 std::random_access_iterator_tag,
131 std::random_access_iterator_tag,
132 int,
133 int const &,
134 int const *,
135 std::ptrdiff_t)
136
137 template<typename ValueType>
138 struct random_access_iter : boost::stl_interfaces::iterator_interface<
139 random_access_iter<ValueType>,
140 std::random_access_iterator_tag,
141 ValueType>
142 {
143 random_access_iter() {}
144 random_access_iter(ValueType * it) : it_(it) {}
145 template<
146 typename ValueType2,
147 typename E = std::enable_if_t<
148 std::is_convertible<ValueType2 *, ValueType *>::value>>
149 random_access_iter(random_access_iter<ValueType2> it) : it_(it.it_)
150 {}
151
152 ValueType & operator*() const { return *it_; }
153 random_access_iter & operator+=(std::ptrdiff_t i)
154 {
155 it_ += i;
156 return *this;
157 }
158 friend std::ptrdiff_t
159 operator-(random_access_iter lhs, random_access_iter rhs) noexcept
160 {
161 return lhs.it_ - rhs.it_;
162 }
163
164 private:
165 ValueType * it_;
166
167 template<typename ValueType2>
168 friend struct random_access_iter;
169 };
170
171 using random_access = random_access_iter<int>;
172 using const_random_access = random_access_iter<int const>;
173
174 BOOST_STL_INTERFACES_STATIC_ASSERT_CONCEPT(
175 random_access, std::random_access_iterator)
176 BOOST_STL_INTERFACES_STATIC_ASSERT_ITERATOR_TRAITS(
177 random_access,
178 std::random_access_iterator_tag,
179 std::random_access_iterator_tag,
180 int,
181 int &,
182 int *,
183 std::ptrdiff_t)
184
185 BOOST_STL_INTERFACES_STATIC_ASSERT_CONCEPT(
186 const_random_access, std::random_access_iterator)
187 BOOST_STL_INTERFACES_STATIC_ASSERT_ITERATOR_TRAITS(
188 const_random_access,
189 std::random_access_iterator_tag,
190 std::random_access_iterator_tag,
191 int,
192 int const &,
193 int const *,
194 std::ptrdiff_t)
195
196 struct zip_iter : boost::stl_interfaces::proxy_iterator_interface<
197 zip_iter,
198 std::random_access_iterator_tag,
199 std::tuple<int, int>,
200 std::tuple<int &, int &>>
201 {
202 zip_iter() : it1_(nullptr), it2_(nullptr) {}
203 zip_iter(int * it1, int * it2) : it1_(it1), it2_(it2) {}
204
205 std::tuple<int &, int &> operator*() const
206 {
207 return std::tuple<int &, int &>{*it1_, *it2_};
208 }
209 zip_iter & operator+=(std::ptrdiff_t i)
210 {
211 it1_ += i;
212 it2_ += i;
213 return *this;
214 }
215 friend std::ptrdiff_t operator-(zip_iter lhs, zip_iter rhs) noexcept
216 {
217 return lhs.it1_ - rhs.it1_;
218 }
219
220 private:
221 int * it1_;
222 int * it2_;
223 };
224
225 using int_pair = std::tuple<int, int>;
226 using int_refs_pair = std::tuple<int &, int &>;
227
228 BOOST_STL_INTERFACES_STATIC_ASSERT_CONCEPT(
229 zip_iter, std::random_access_iterator)
230 BOOST_STL_INTERFACES_STATIC_ASSERT_ITERATOR_TRAITS(
231 zip_iter,
232 std::random_access_iterator_tag,
233 std::random_access_iterator_tag,
234 int_pair,
235 int_refs_pair,
236 boost::stl_interfaces::proxy_arrow_result<int_refs_pair>,
237 std::ptrdiff_t)
238
239 struct int_t
240 {
241 int value_;
242
243 bool operator==(int_t other) const { return value_ == other.value_; }
244 bool operator!=(int_t other) const { return value_ != other.value_; }
245 bool operator<(int_t other) const { return value_ < other.value_; }
246
247 bool operator==(int other) const { return value_ == other; }
248 bool operator!=(int other) const { return value_ != other; }
249 bool operator<(int other) const { return value_ < other; }
250
251 friend bool operator==(int lhs, int_t rhs) { return lhs == rhs.value_; }
252 friend bool operator!=(int lhs, int_t rhs) { return lhs != rhs.value_; }
253 friend bool operator<(int lhs, int_t rhs) { return lhs < rhs.value_; }
254 };
255
256 struct udt_zip_iter : boost::stl_interfaces::proxy_iterator_interface<
257 udt_zip_iter,
258 std::random_access_iterator_tag,
259 std::tuple<int_t, int>,
260 std::tuple<int_t &, int &>>
261 {
262 udt_zip_iter() : it1_(nullptr), it2_(nullptr) {}
263 udt_zip_iter(int_t * it1, int * it2) : it1_(it1), it2_(it2) {}
264
265 std::tuple<int_t &, int &> operator*() const
266 {
267 return std::tuple<int_t &, int &>{*it1_, *it2_};
268 }
269 udt_zip_iter & operator+=(std::ptrdiff_t i)
270 {
271 it1_ += i;
272 it2_ += i;
273 return *this;
274 }
275 friend std::ptrdiff_t operator-(udt_zip_iter lhs, udt_zip_iter rhs) noexcept
276 {
277 return lhs.it1_ - rhs.it1_;
278 }
279
280 private:
281 int_t * it1_;
282 int * it2_;
283 };
284
285 using int_t_int_pair = std::tuple<int_t, int>;
286 using int_t_int_refs_pair = std::tuple<int_t &, int &>;
287
288 BOOST_STL_INTERFACES_STATIC_ASSERT_CONCEPT(
289 udt_zip_iter, std::random_access_iterator)
290 BOOST_STL_INTERFACES_STATIC_ASSERT_ITERATOR_TRAITS(
291 udt_zip_iter,
292 std::random_access_iterator_tag,
293 std::random_access_iterator_tag,
294 int_t_int_pair,
295 int_t_int_refs_pair,
296 boost::stl_interfaces::proxy_arrow_result<int_t_int_refs_pair>,
297 std::ptrdiff_t)
298
299 namespace std {
300 // Required for std::sort to work with zip_iter. If zip_iter::reference
301 // were not a std::tuple with builtin types as its template parameters, we
302 // could have put this in another namespace.
303 void swap(zip_iter::reference && lhs, zip_iter::reference && rhs)
304 {
305 using std::swap;
306 swap(std::get<0>(lhs), std::get<0>(rhs));
307 swap(std::get<1>(lhs), std::get<1>(rhs));
308 }
309 }
310
311 void swap(udt_zip_iter::reference && lhs, udt_zip_iter::reference && rhs)
312 {
313 using std::swap;
314 swap(std::get<0>(lhs), std::get<0>(rhs));
315 swap(std::get<1>(lhs), std::get<1>(rhs));
316 }
317
318 std::array<int, 10> ints = {{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}};
319 std::array<int, 10> ones = {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1}};
320 std::array<std::tuple<int, int>, 10> tuples = {{
321 {0, 1},
322 {1, 1},
323 {2, 1},
324 {3, 1},
325 {4, 1},
326 {5, 1},
327 {6, 1},
328 {7, 1},
329 {8, 1},
330 {9, 1},
331 }};
332
333 std::array<int_t, 10> udts = {
334 {{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}}};
335 std::array<std::tuple<int_t, int>, 10> udt_tuples = {{
336 std::tuple<int_t, int>{{0}, 1},
337 std::tuple<int_t, int>{{1}, 1},
338 std::tuple<int_t, int>{{2}, 1},
339 std::tuple<int_t, int>{{3}, 1},
340 std::tuple<int_t, int>{{4}, 1},
341 std::tuple<int_t, int>{{5}, 1},
342 std::tuple<int_t, int>{{6}, 1},
343 std::tuple<int_t, int>{{7}, 1},
344 std::tuple<int_t, int>{{8}, 1},
345 std::tuple<int_t, int>{{9}, 1},
346 }};
347
348
349 ////////////////////
350 // view_interface //
351 ////////////////////
352 #include "view_tests.hpp"
353
354 #if !defined(__cpp_lib_concepts)
355
356 template<typename T>
357 using data_t = decltype(std::declval<T>().data());
358
359 static_assert(
360 ill_formed<
361 data_t,
362 subrange<
363 basic_random_access_iter,
364 basic_random_access_iter,
365 boost::stl_interfaces::element_layout::discontiguous>>::value,
366 "");
367 static_assert(
368 ill_formed<
369 data_t,
370 subrange<
371 basic_random_access_iter,
372 basic_random_access_iter,
373 boost::stl_interfaces::element_layout::discontiguous> const>::
374 value,
375 "");
376
377 template<typename T>
378 using back_t = decltype(std::declval<T>().back());
379
380 static_assert(
381 ill_formed<
382 back_t,
383 subrange<
384 int *,
385 int const *,
386 boost::stl_interfaces::element_layout::discontiguous>>::value,
387 "");
388 static_assert(
389 ill_formed<
390 back_t,
391 subrange<
392 int *,
393 int const *,
394 boost::stl_interfaces::element_layout::discontiguous> const>::
395 value,
396 "");
397
398 #endif
399
400
401 int main()
402 {
403
404 {
405 basic_random_access_iter first(ints.data());
406 basic_random_access_iter last(ints.data() + ints.size());
407
408 BOOST_TEST(*first == 0);
409 BOOST_TEST(*(first + 1) == 1);
410 BOOST_TEST(*(first + 2) == 2);
411 BOOST_TEST(*(1 + first) == 1);
412 BOOST_TEST(*(2 + first) == 2);
413
414 BOOST_TEST(first[0] == 0);
415 BOOST_TEST(first[1] == 1);
416 BOOST_TEST(first[2] == 2);
417
418 BOOST_TEST(*(last - 1) == 9);
419 BOOST_TEST(*(last - 2) == 8);
420 BOOST_TEST(*(last - 3) == 7);
421
422 BOOST_TEST(last[-1] == 9);
423 BOOST_TEST(last[-2] == 8);
424 BOOST_TEST(last[-3] == 7);
425
426 BOOST_TEST(last - first == 10);
427 BOOST_TEST(first == first);
428 BOOST_TEST(first != last);
429 BOOST_TEST(first < last);
430 BOOST_TEST(first <= last);
431 BOOST_TEST(first <= first);
432 BOOST_TEST(last > first);
433 BOOST_TEST(last >= first);
434 BOOST_TEST(last >= last);
435
436 {
437 auto first_copy = first;
438 first_copy += 10;
439 BOOST_TEST(first_copy == last);
440 }
441
442 {
443 auto last_copy = last;
444 last_copy -= 10;
445 BOOST_TEST(last_copy == first);
446 }
447 }
448
449
450 {
451 {
452 std::array<int, 10> ints_copy;
453 basic_random_access_iter first(ints.data());
454 basic_random_access_iter last(ints.data() + ints.size());
455 std::copy(first, last, ints_copy.begin());
456 BOOST_TEST(ints_copy == ints);
457 }
458
459 {
460 std::array<int, 10> ints_copy;
461 basic_random_access_iter first(ints.data());
462 basic_random_access_iter last(ints.data() + ints.size());
463 std::copy(
464 std::make_reverse_iterator(last),
465 std::make_reverse_iterator(first),
466 ints_copy.begin());
467 std::reverse(ints_copy.begin(), ints_copy.end());
468 BOOST_TEST(ints_copy == ints);
469 }
470
471 {
472 std::array<int, 10> iota_ints;
473 basic_random_access_iter first(iota_ints.data());
474 basic_random_access_iter last(iota_ints.data() + iota_ints.size());
475 std::iota(first, last, 0);
476 BOOST_TEST(iota_ints == ints);
477 }
478
479 {
480 std::array<int, 10> iota_ints;
481 basic_random_access_iter first(iota_ints.data());
482 basic_random_access_iter last(iota_ints.data() + iota_ints.size());
483 std::iota(
484 std::make_reverse_iterator(last),
485 std::make_reverse_iterator(first),
486 0);
487 std::reverse(iota_ints.begin(), iota_ints.end());
488 BOOST_TEST(iota_ints == ints);
489 }
490
491 {
492 std::array<int, 10> iota_ints;
493 basic_random_access_iter first(iota_ints.data());
494 basic_random_access_iter last(iota_ints.data() + iota_ints.size());
495 std::iota(
496 std::make_reverse_iterator(last),
497 std::make_reverse_iterator(first),
498 0);
499 std::sort(first, last);
500 BOOST_TEST(iota_ints == ints);
501 }
502 }
503
504
505 {
506 basic_adapted_random_access_iter first(ints.data());
507 basic_adapted_random_access_iter last(ints.data() + ints.size());
508
509 BOOST_TEST(*first == 0);
510 BOOST_TEST(*(first + 1) == 1);
511 BOOST_TEST(*(first + 2) == 2);
512 BOOST_TEST(*(1 + first) == 1);
513 BOOST_TEST(*(2 + first) == 2);
514
515 BOOST_TEST(first[0] == 0);
516 BOOST_TEST(first[1] == 1);
517 BOOST_TEST(first[2] == 2);
518
519 BOOST_TEST(*(last - 1) == 9);
520 BOOST_TEST(*(last - 2) == 8);
521 BOOST_TEST(*(last - 3) == 7);
522
523 BOOST_TEST(last[-1] == 9);
524 BOOST_TEST(last[-2] == 8);
525 BOOST_TEST(last[-3] == 7);
526
527 BOOST_TEST(last - first == 10);
528 BOOST_TEST(first == first);
529 BOOST_TEST(first != last);
530 BOOST_TEST(first < last);
531 BOOST_TEST(first <= last);
532 BOOST_TEST(first <= first);
533 BOOST_TEST(last > first);
534 BOOST_TEST(last >= first);
535 BOOST_TEST(last >= last);
536
537 {
538 auto first_copy = first;
539 first_copy += 10;
540 BOOST_TEST(first_copy == last);
541 }
542
543 {
544 auto last_copy = last;
545 last_copy -= 10;
546 BOOST_TEST(last_copy == first);
547 }
548 }
549
550
551 {
552 {
553 std::array<int, 10> ints_copy;
554 basic_adapted_random_access_iter first(ints.data());
555 basic_adapted_random_access_iter last(ints.data() + ints.size());
556 std::copy(first, last, ints_copy.begin());
557 BOOST_TEST(ints_copy == ints);
558 }
559
560 {
561 std::array<int, 10> ints_copy;
562 basic_adapted_random_access_iter first(ints.data());
563 basic_adapted_random_access_iter last(ints.data() + ints.size());
564 std::copy(
565 std::make_reverse_iterator(last),
566 std::make_reverse_iterator(first),
567 ints_copy.begin());
568 std::reverse(ints_copy.begin(), ints_copy.end());
569 BOOST_TEST(ints_copy == ints);
570 }
571
572 {
573 std::array<int, 10> iota_ints;
574 basic_adapted_random_access_iter first(iota_ints.data());
575 basic_adapted_random_access_iter last(
576 iota_ints.data() + iota_ints.size());
577 std::iota(first, last, 0);
578 BOOST_TEST(iota_ints == ints);
579 }
580
581 {
582 std::array<int, 10> iota_ints;
583 basic_adapted_random_access_iter first(iota_ints.data());
584 basic_adapted_random_access_iter last(
585 iota_ints.data() + iota_ints.size());
586 std::iota(
587 std::make_reverse_iterator(last),
588 std::make_reverse_iterator(first),
589 0);
590 std::reverse(iota_ints.begin(), iota_ints.end());
591 BOOST_TEST(iota_ints == ints);
592 }
593
594 {
595 std::array<int, 10> iota_ints;
596 basic_adapted_random_access_iter first(iota_ints.data());
597 basic_adapted_random_access_iter last(
598 iota_ints.data() + iota_ints.size());
599 std::iota(
600 std::make_reverse_iterator(last),
601 std::make_reverse_iterator(first),
602 0);
603 std::sort(first, last);
604 BOOST_TEST(iota_ints == ints);
605 }
606 }
607
608
609 {
610 {
611 random_access first(ints.data());
612 random_access last(ints.data() + ints.size());
613 const_random_access first_copy(first);
614 const_random_access last_copy(last);
615 std::equal(first, last, first_copy, last_copy);
616 }
617
618 {
619 adapted_random_access_iter<int> first(ints.data());
620 adapted_random_access_iter<int> last(ints.data() + ints.size());
621 adapted_random_access_iter<int const> first_copy(
622 (int const *)ints.data());
623 adapted_random_access_iter<int const> last_copy(
624 (int const *)ints.data() + ints.size());
625 std::equal(first, last, first_copy, last_copy);
626 }
627 }
628
629
630 {
631 {
632 random_access first(ints.data());
633 random_access last(ints.data() + ints.size());
634 const_random_access first_const(first);
635 const_random_access last_const(last);
636
637 BOOST_TEST(first == first_const);
638 BOOST_TEST(first_const == first);
639 BOOST_TEST(first != last_const);
640 BOOST_TEST(last_const != first);
641 BOOST_TEST(first <= first_const);
642 BOOST_TEST(first_const <= first);
643 BOOST_TEST(first >= first_const);
644 BOOST_TEST(first_const >= first);
645 BOOST_TEST(last_const > first);
646 BOOST_TEST(last > first_const);
647 BOOST_TEST(first_const < last);
648 BOOST_TEST(first < last_const);
649 }
650
651 {
652 adapted_random_access_iter<int> first(ints.data());
653 adapted_random_access_iter<int> last(ints.data() + ints.size());
654 adapted_random_access_iter<int const> first_const(first);
655 adapted_random_access_iter<int const> last_const(last);
656
657 BOOST_TEST(first == first_const);
658 BOOST_TEST(first_const == first);
659 BOOST_TEST(first != last_const);
660 BOOST_TEST(last_const != first);
661 BOOST_TEST(first <= first_const);
662 BOOST_TEST(first_const <= first);
663 BOOST_TEST(first >= first_const);
664 BOOST_TEST(first_const >= first);
665 BOOST_TEST(last_const > first);
666 BOOST_TEST(last > first_const);
667 BOOST_TEST(first_const < last);
668 BOOST_TEST(first < last_const);
669 }
670 }
671
672
673 {
674 {
675 random_access first(ints.data());
676 random_access last(ints.data() + ints.size());
677 while (first != last)
678 first++;
679 }
680
681 {
682 random_access first(ints.data());
683 random_access last(ints.data() + ints.size());
684 while (first != last)
685 last--;
686 }
687
688 {
689 basic_random_access_iter first(ints.data());
690 basic_random_access_iter last(ints.data() + ints.size());
691 while (first != last)
692 first++;
693 }
694
695 {
696 basic_random_access_iter first(ints.data());
697 basic_random_access_iter last(ints.data() + ints.size());
698 while (first != last)
699 last--;
700 }
701
702 {
703 basic_adapted_random_access_iter first(ints.data());
704 basic_adapted_random_access_iter last(ints.data() + ints.size());
705 while (first != last)
706 first++;
707 }
708
709 {
710 basic_adapted_random_access_iter first(ints.data());
711 basic_adapted_random_access_iter last(ints.data() + ints.size());
712 while (first != last)
713 last--;
714 }
715 }
716
717
718 {
719 random_access first(ints.data());
720 random_access last(ints.data() + ints.size());
721
722 BOOST_TEST(*first == 0);
723 BOOST_TEST(*(first + 1) == 1);
724 BOOST_TEST(*(first + 2) == 2);
725 BOOST_TEST(*(1 + first) == 1);
726 BOOST_TEST(*(2 + first) == 2);
727
728 BOOST_TEST(first[0] == 0);
729 BOOST_TEST(first[1] == 1);
730 BOOST_TEST(first[2] == 2);
731
732 BOOST_TEST(*(last - 1) == 9);
733 BOOST_TEST(*(last - 2) == 8);
734 BOOST_TEST(*(last - 3) == 7);
735
736 BOOST_TEST(last[-1] == 9);
737 BOOST_TEST(last[-2] == 8);
738 BOOST_TEST(last[-3] == 7);
739
740 BOOST_TEST(last - first == 10);
741 BOOST_TEST(first == first);
742 BOOST_TEST(first != last);
743 BOOST_TEST(first < last);
744 BOOST_TEST(first <= last);
745 BOOST_TEST(first <= first);
746 BOOST_TEST(last > first);
747 BOOST_TEST(last >= first);
748 BOOST_TEST(last >= last);
749
750 {
751 auto first_copy = first;
752 first_copy += 10;
753 BOOST_TEST(first_copy == last);
754 }
755
756 {
757 auto last_copy = last;
758 last_copy -= 10;
759 BOOST_TEST(last_copy == first);
760 }
761 }
762
763
764 {
765 random_access first(ints.data());
766 random_access last(ints.data() + ints.size());
767
768 {
769 std::array<int, 10> ints_copy;
770 std::copy(first, last, ints_copy.begin());
771 BOOST_TEST(ints_copy == ints);
772 }
773
774 {
775 std::array<int, 10> ints_copy;
776 std::copy(
777 std::make_reverse_iterator(last),
778 std::make_reverse_iterator(first),
779 ints_copy.begin());
780 std::reverse(ints_copy.begin(), ints_copy.end());
781 BOOST_TEST(ints_copy == ints);
782 }
783
784 {
785 std::array<int, 10> iota_ints;
786 random_access first(iota_ints.data());
787 random_access last(iota_ints.data() + iota_ints.size());
788 std::iota(first, last, 0);
789 BOOST_TEST(iota_ints == ints);
790 }
791
792 {
793 std::array<int, 10> iota_ints;
794 random_access first(iota_ints.data());
795 random_access last(iota_ints.data() + iota_ints.size());
796 std::iota(
797 std::make_reverse_iterator(last),
798 std::make_reverse_iterator(first),
799 0);
800 std::reverse(iota_ints.begin(), iota_ints.end());
801 BOOST_TEST(iota_ints == ints);
802 }
803
804 {
805 std::array<int, 10> iota_ints;
806 random_access first(iota_ints.data());
807 random_access last(iota_ints.data() + iota_ints.size());
808 std::iota(
809 std::make_reverse_iterator(last),
810 std::make_reverse_iterator(first),
811 0);
812 std::sort(first, last);
813 BOOST_TEST(iota_ints == ints);
814 }
815 }
816
817
818 {
819 const_random_access first(ints.data());
820 const_random_access last(ints.data() + ints.size());
821
822 {
823 std::array<int, 10> ints_copy;
824 std::copy(first, last, ints_copy.begin());
825 BOOST_TEST(ints_copy == ints);
826 }
827
828 {
829 BOOST_TEST(std::binary_search(first, last, 3));
830 BOOST_TEST(std::binary_search(
831 std::make_reverse_iterator(last),
832 std::make_reverse_iterator(first),
833 3,
834 std::greater<>{}));
835 }
836 }
837
838
839 {
840 {
841 zip_iter first(ints.data(), ones.data());
842 zip_iter last(ints.data() + ints.size(), ones.data() + ones.size());
843 BOOST_TEST(std::equal(first, last, tuples.begin(), tuples.end()));
844 }
845
846 {
847 auto ints_copy = ints;
848 std::reverse(ints_copy.begin(), ints_copy.end());
849 auto ones_copy = ones;
850 zip_iter first(ints_copy.data(), ones_copy.data());
851 zip_iter last(
852 ints_copy.data() + ints_copy.size(),
853 ones_copy.data() + ones_copy.size());
854 BOOST_TEST(!std::equal(first, last, tuples.begin(), tuples.end()));
855 std::sort(first, last);
856 BOOST_TEST(std::equal(first, last, tuples.begin(), tuples.end()));
857 }
858
859 {
860 udt_zip_iter first(udts.data(), ones.data());
861 udt_zip_iter last(udts.data() + udts.size(), ones.data() + ones.size());
862 BOOST_TEST(
863 std::equal(first, last, udt_tuples.begin(), udt_tuples.end()));
864 }
865
866 {
867 auto udts_copy = udts;
868 std::reverse(udts_copy.begin(), udts_copy.end());
869 auto ones_copy = ones;
870 udt_zip_iter first(udts_copy.data(), ones_copy.data());
871 udt_zip_iter last(
872 udts_copy.data() + udts_copy.size(),
873 ones_copy.data() + ones_copy.size());
874 BOOST_TEST(
875 !std::equal(first, last, udt_tuples.begin(), udt_tuples.end()));
876 std::sort(first, last);
877 BOOST_TEST(
878 std::equal(first, last, udt_tuples.begin(), udt_tuples.end()));
879 }
880 }
881
882 {
883 basic_random_access_iter first(ints.data());
884 basic_random_access_iter last(ints.data() + ints.size());
885
886 auto r = range<boost::stl_interfaces::element_layout::contiguous>(
887 first, last);
888 auto empty = range<boost::stl_interfaces::element_layout::contiguous>(
889 first, first);
890
891 // range begin/end
892 {
893 std::array<int, 10> ints_copy;
894 std::copy(r.begin(), r.end(), ints_copy.begin());
895 BOOST_TEST(ints_copy == ints);
896
897 BOOST_TEST(empty.begin() == empty.end());
898 }
899
900 // empty/op bool
901 {
902 BOOST_TEST(!r.empty());
903 BOOST_TEST(r);
904
905 BOOST_TEST(empty.empty());
906 BOOST_TEST(!empty);
907
908 auto const cr = r;
909 BOOST_TEST(!cr.empty());
910 BOOST_TEST(cr);
911
912 auto const cempty = empty;
913 BOOST_TEST(cempty.empty());
914 BOOST_TEST(!cempty);
915 }
916
917 // TODO: Disabled for now, because std::to_address() appears to be broken
918 // in GCC10, which breaks the contiguous_iterator concept.
919 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96416
920 #if !defined(__cpp_lib_concepts)
921 // data
922 {
923 BOOST_TEST(r.data() != nullptr);
924 BOOST_TEST(r.data()[2] == 2);
925
926 BOOST_TEST(empty.data() != nullptr);
927
928 auto const cr = r;
929 BOOST_TEST(cr.data() != nullptr);
930 BOOST_TEST(cr.data()[2] == 2);
931
932 auto const cempty = empty;
933 BOOST_TEST(cempty.data() != nullptr);
934 }
935 #endif
936
937 // size
938 {
939 BOOST_TEST(r.size() == 10u);
940
941 BOOST_TEST(empty.size() == 0u);
942
943 auto const cr = r;
944 BOOST_TEST(cr.size() == 10u);
945
946 auto const cempty = empty;
947 BOOST_TEST(cempty.size() == 0u);
948 }
949
950 // front/back
951 {
952 BOOST_TEST(r.front() == 0);
953 BOOST_TEST(r.back() == 9);
954
955 auto const cr = r;
956 BOOST_TEST(cr.front() == 0);
957 BOOST_TEST(cr.back() == 9);
958 }
959
960 // op[]
961 {
962 BOOST_TEST(r[2] == 2);
963
964 auto const cr = r;
965 BOOST_TEST(cr[2] == 2);
966 }
967 }
968
969
970 {
971 zip_iter first(ints.data(), ones.data());
972 zip_iter last(ints.data() + ints.size(), ones.data() + ones.size());
973
974 auto r = range<boost::stl_interfaces::element_layout::discontiguous>(
975 first, last);
976 auto empty =
977 range<boost::stl_interfaces::element_layout::discontiguous>(
978 first, first);
979
980 // range begin/end
981 {
982 BOOST_TEST(std::equal(first, last, tuples.begin(), tuples.end()));
983 }
984
985 // empty/op bool
986 {
987 BOOST_TEST(!r.empty());
988 BOOST_TEST(r);
989
990 BOOST_TEST(empty.empty());
991 BOOST_TEST(!empty);
992
993 auto const cr = r;
994 BOOST_TEST(!cr.empty());
995 BOOST_TEST(cr);
996
997 auto const cempty = empty;
998 BOOST_TEST(cempty.empty());
999 BOOST_TEST(!cempty);
1000 }
1001
1002 // size
1003 {
1004 BOOST_TEST(r.size() == 10u);
1005
1006 BOOST_TEST(empty.size() == 0u);
1007
1008 auto const cr = r;
1009 BOOST_TEST(cr.size() == 10u);
1010
1011 auto const cempty = empty;
1012 BOOST_TEST(cempty.size() == 0u);
1013 }
1014
1015 // front/back
1016 {
1017 BOOST_TEST(r.front() == (std::tuple<int, int>(0, 1)));
1018 BOOST_TEST(r.back() == (std::tuple<int, int>(9, 1)));
1019
1020 auto const cr = r;
1021 BOOST_TEST(cr.front() == (std::tuple<int, int>(0, 1)));
1022 BOOST_TEST(cr.back() == (std::tuple<int, int>(9, 1)));
1023 }
1024
1025 // op[]
1026 {
1027 BOOST_TEST(r[2] == (std::tuple<int, int>(2, 1)));
1028
1029 auto const cr = r;
1030 BOOST_TEST(cr[2] == (std::tuple<int, int>(2, 1)));
1031 }
1032 }
1033
1034 return boost::report_errors();
1035 }