1 // Copyright (C) 2019 T. Zachary Laine
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>
8 #include "ill_formed.hpp"
10 #include <boost/core/lightweight_test.hpp>
17 #include <type_traits>
20 struct basic_random_access_iter
: boost::stl_interfaces::iterator_interface
<
21 basic_random_access_iter
,
22 std::random_access_iterator_tag
,
25 basic_random_access_iter() {}
26 basic_random_access_iter(int * it
) : it_(it
) {}
28 int & operator*() const { return *it_
; }
29 basic_random_access_iter
& operator+=(std::ptrdiff_t i
)
34 friend std::ptrdiff_t operator-(
35 basic_random_access_iter lhs
, basic_random_access_iter rhs
) noexcept
37 return lhs
.it_
- rhs
.it_
;
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
,
56 boost::stl_interfaces::v1::v1_dtl::
57 plus_eq
<basic_random_access_iter
, std::ptrdiff_t>::value
,
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
,
66 basic_adapted_random_access_iter() {}
67 basic_adapted_random_access_iter(int * it
) : it_(it
) {}
70 friend boost::stl_interfaces::access
;
71 int *& base_reference() noexcept
{ return it_
; }
72 int * base_reference() const noexcept
{ return it_
; }
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
,
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
,
94 adapted_random_access_iter() {}
95 adapted_random_access_iter(ValueType
* it
) : it_(it
) {}
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
) :
105 template<typename ValueType2
>
106 friend struct adapted_random_access_iter
;
109 friend boost::stl_interfaces::access
;
110 ValueType
*& base_reference() noexcept
{ return it_
; }
111 ValueType
* base_reference() const noexcept
{ return it_
; }
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
,
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
,
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
,
143 random_access_iter() {}
144 random_access_iter(ValueType
* it
) : it_(it
) {}
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_
)
152 ValueType
& operator*() const { return *it_
; }
153 random_access_iter
& operator+=(std::ptrdiff_t i
)
158 friend std::ptrdiff_t
159 operator-(random_access_iter lhs
, random_access_iter rhs
) noexcept
161 return lhs
.it_
- rhs
.it_
;
167 template<typename ValueType2
>
168 friend struct random_access_iter
;
171 using random_access
= random_access_iter
<int>;
172 using const_random_access
= random_access_iter
<int const>;
174 BOOST_STL_INTERFACES_STATIC_ASSERT_CONCEPT(
175 random_access
, std::random_access_iterator
)
176 BOOST_STL_INTERFACES_STATIC_ASSERT_ITERATOR_TRAITS(
178 std::random_access_iterator_tag
,
179 std::random_access_iterator_tag
,
185 BOOST_STL_INTERFACES_STATIC_ASSERT_CONCEPT(
186 const_random_access
, std::random_access_iterator
)
187 BOOST_STL_INTERFACES_STATIC_ASSERT_ITERATOR_TRAITS(
189 std::random_access_iterator_tag
,
190 std::random_access_iterator_tag
,
196 struct zip_iter
: boost::stl_interfaces::proxy_iterator_interface
<
198 std::random_access_iterator_tag
,
199 std::tuple
<int, int>,
200 std::tuple
<int &, int &>>
202 zip_iter() : it1_(nullptr), it2_(nullptr) {}
203 zip_iter(int * it1
, int * it2
) : it1_(it1
), it2_(it2
) {}
205 std::tuple
<int &, int &> operator*() const
207 return std::tuple
<int &, int &>{*it1_
, *it2_
};
209 zip_iter
& operator+=(std::ptrdiff_t i
)
215 friend std::ptrdiff_t operator-(zip_iter lhs
, zip_iter rhs
) noexcept
217 return lhs
.it1_
- rhs
.it1_
;
225 using int_pair
= std::tuple
<int, int>;
226 using int_refs_pair
= std::tuple
<int &, int &>;
228 BOOST_STL_INTERFACES_STATIC_ASSERT_CONCEPT(
229 zip_iter
, std::random_access_iterator
)
230 BOOST_STL_INTERFACES_STATIC_ASSERT_ITERATOR_TRAITS(
232 std::random_access_iterator_tag
,
233 std::random_access_iterator_tag
,
236 boost::stl_interfaces::proxy_arrow_result
<int_refs_pair
>,
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_
; }
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
; }
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_
; }
256 struct udt_zip_iter
: boost::stl_interfaces::proxy_iterator_interface
<
258 std::random_access_iterator_tag
,
259 std::tuple
<int_t
, int>,
260 std::tuple
<int_t
&, int &>>
262 udt_zip_iter() : it1_(nullptr), it2_(nullptr) {}
263 udt_zip_iter(int_t
* it1
, int * it2
) : it1_(it1
), it2_(it2
) {}
265 std::tuple
<int_t
&, int &> operator*() const
267 return std::tuple
<int_t
&, int &>{*it1_
, *it2_
};
269 udt_zip_iter
& operator+=(std::ptrdiff_t i
)
275 friend std::ptrdiff_t operator-(udt_zip_iter lhs
, udt_zip_iter rhs
) noexcept
277 return lhs
.it1_
- rhs
.it1_
;
285 using int_t_int_pair
= std::tuple
<int_t
, int>;
286 using int_t_int_refs_pair
= std::tuple
<int_t
&, int &>;
288 BOOST_STL_INTERFACES_STATIC_ASSERT_CONCEPT(
289 udt_zip_iter
, std::random_access_iterator
)
290 BOOST_STL_INTERFACES_STATIC_ASSERT_ITERATOR_TRAITS(
292 std::random_access_iterator_tag
,
293 std::random_access_iterator_tag
,
296 boost::stl_interfaces::proxy_arrow_result
<int_t_int_refs_pair
>,
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
)
306 swap(std::get
<0>(lhs
), std::get
<0>(rhs
));
307 swap(std::get
<1>(lhs
), std::get
<1>(rhs
));
311 void swap(udt_zip_iter::reference
&& lhs
, udt_zip_iter::reference
&& rhs
)
314 swap(std::get
<0>(lhs
), std::get
<0>(rhs
));
315 swap(std::get
<1>(lhs
), std::get
<1>(rhs
));
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
= {{
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},
352 #include "view_tests.hpp"
354 #if !defined(__cpp_lib_concepts)
357 using data_t
= decltype(std::declval
<T
>().data());
363 basic_random_access_iter
,
364 basic_random_access_iter
,
365 boost::stl_interfaces::element_layout::discontiguous
>>::value
,
371 basic_random_access_iter
,
372 basic_random_access_iter
,
373 boost::stl_interfaces::element_layout::discontiguous
> const>::
378 using back_t
= decltype(std::declval
<T
>().back());
386 boost::stl_interfaces::element_layout::discontiguous
>>::value
,
394 boost::stl_interfaces::element_layout::discontiguous
> const>::
405 basic_random_access_iter
first(ints
.data());
406 basic_random_access_iter
last(ints
.data() + ints
.size());
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);
414 BOOST_TEST(first
[0] == 0);
415 BOOST_TEST(first
[1] == 1);
416 BOOST_TEST(first
[2] == 2);
418 BOOST_TEST(*(last
- 1) == 9);
419 BOOST_TEST(*(last
- 2) == 8);
420 BOOST_TEST(*(last
- 3) == 7);
422 BOOST_TEST(last
[-1] == 9);
423 BOOST_TEST(last
[-2] == 8);
424 BOOST_TEST(last
[-3] == 7);
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
);
437 auto first_copy
= first
;
439 BOOST_TEST(first_copy
== last
);
443 auto last_copy
= last
;
445 BOOST_TEST(last_copy
== first
);
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
);
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());
464 std::make_reverse_iterator(last
),
465 std::make_reverse_iterator(first
),
467 std::reverse(ints_copy
.begin(), ints_copy
.end());
468 BOOST_TEST(ints_copy
== ints
);
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
);
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());
484 std::make_reverse_iterator(last
),
485 std::make_reverse_iterator(first
),
487 std::reverse(iota_ints
.begin(), iota_ints
.end());
488 BOOST_TEST(iota_ints
== ints
);
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());
496 std::make_reverse_iterator(last
),
497 std::make_reverse_iterator(first
),
499 std::sort(first
, last
);
500 BOOST_TEST(iota_ints
== ints
);
506 basic_adapted_random_access_iter
first(ints
.data());
507 basic_adapted_random_access_iter
last(ints
.data() + ints
.size());
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);
515 BOOST_TEST(first
[0] == 0);
516 BOOST_TEST(first
[1] == 1);
517 BOOST_TEST(first
[2] == 2);
519 BOOST_TEST(*(last
- 1) == 9);
520 BOOST_TEST(*(last
- 2) == 8);
521 BOOST_TEST(*(last
- 3) == 7);
523 BOOST_TEST(last
[-1] == 9);
524 BOOST_TEST(last
[-2] == 8);
525 BOOST_TEST(last
[-3] == 7);
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
);
538 auto first_copy
= first
;
540 BOOST_TEST(first_copy
== last
);
544 auto last_copy
= last
;
546 BOOST_TEST(last_copy
== first
);
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
);
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());
565 std::make_reverse_iterator(last
),
566 std::make_reverse_iterator(first
),
568 std::reverse(ints_copy
.begin(), ints_copy
.end());
569 BOOST_TEST(ints_copy
== ints
);
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
);
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());
587 std::make_reverse_iterator(last
),
588 std::make_reverse_iterator(first
),
590 std::reverse(iota_ints
.begin(), iota_ints
.end());
591 BOOST_TEST(iota_ints
== ints
);
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());
600 std::make_reverse_iterator(last
),
601 std::make_reverse_iterator(first
),
603 std::sort(first
, last
);
604 BOOST_TEST(iota_ints
== ints
);
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
);
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
);
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
);
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
);
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
);
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
);
675 random_access
first(ints
.data());
676 random_access
last(ints
.data() + ints
.size());
677 while (first
!= last
)
682 random_access
first(ints
.data());
683 random_access
last(ints
.data() + ints
.size());
684 while (first
!= last
)
689 basic_random_access_iter
first(ints
.data());
690 basic_random_access_iter
last(ints
.data() + ints
.size());
691 while (first
!= last
)
696 basic_random_access_iter
first(ints
.data());
697 basic_random_access_iter
last(ints
.data() + ints
.size());
698 while (first
!= last
)
703 basic_adapted_random_access_iter
first(ints
.data());
704 basic_adapted_random_access_iter
last(ints
.data() + ints
.size());
705 while (first
!= last
)
710 basic_adapted_random_access_iter
first(ints
.data());
711 basic_adapted_random_access_iter
last(ints
.data() + ints
.size());
712 while (first
!= last
)
719 random_access
first(ints
.data());
720 random_access
last(ints
.data() + ints
.size());
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);
728 BOOST_TEST(first
[0] == 0);
729 BOOST_TEST(first
[1] == 1);
730 BOOST_TEST(first
[2] == 2);
732 BOOST_TEST(*(last
- 1) == 9);
733 BOOST_TEST(*(last
- 2) == 8);
734 BOOST_TEST(*(last
- 3) == 7);
736 BOOST_TEST(last
[-1] == 9);
737 BOOST_TEST(last
[-2] == 8);
738 BOOST_TEST(last
[-3] == 7);
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
);
751 auto first_copy
= first
;
753 BOOST_TEST(first_copy
== last
);
757 auto last_copy
= last
;
759 BOOST_TEST(last_copy
== first
);
765 random_access
first(ints
.data());
766 random_access
last(ints
.data() + ints
.size());
769 std::array
<int, 10> ints_copy
;
770 std::copy(first
, last
, ints_copy
.begin());
771 BOOST_TEST(ints_copy
== ints
);
775 std::array
<int, 10> ints_copy
;
777 std::make_reverse_iterator(last
),
778 std::make_reverse_iterator(first
),
780 std::reverse(ints_copy
.begin(), ints_copy
.end());
781 BOOST_TEST(ints_copy
== ints
);
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
);
793 std::array
<int, 10> iota_ints
;
794 random_access
first(iota_ints
.data());
795 random_access
last(iota_ints
.data() + iota_ints
.size());
797 std::make_reverse_iterator(last
),
798 std::make_reverse_iterator(first
),
800 std::reverse(iota_ints
.begin(), iota_ints
.end());
801 BOOST_TEST(iota_ints
== ints
);
805 std::array
<int, 10> iota_ints
;
806 random_access
first(iota_ints
.data());
807 random_access
last(iota_ints
.data() + iota_ints
.size());
809 std::make_reverse_iterator(last
),
810 std::make_reverse_iterator(first
),
812 std::sort(first
, last
);
813 BOOST_TEST(iota_ints
== ints
);
819 const_random_access
first(ints
.data());
820 const_random_access
last(ints
.data() + ints
.size());
823 std::array
<int, 10> ints_copy
;
824 std::copy(first
, last
, ints_copy
.begin());
825 BOOST_TEST(ints_copy
== ints
);
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
),
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()));
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());
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()));
860 udt_zip_iter
first(udts
.data(), ones
.data());
861 udt_zip_iter
last(udts
.data() + udts
.size(), ones
.data() + ones
.size());
863 std::equal(first
, last
, udt_tuples
.begin(), udt_tuples
.end()));
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());
872 udts_copy
.data() + udts_copy
.size(),
873 ones_copy
.data() + ones_copy
.size());
875 !std::equal(first
, last
, udt_tuples
.begin(), udt_tuples
.end()));
876 std::sort(first
, last
);
878 std::equal(first
, last
, udt_tuples
.begin(), udt_tuples
.end()));
883 basic_random_access_iter
first(ints
.data());
884 basic_random_access_iter
last(ints
.data() + ints
.size());
886 auto r
= range
<boost::stl_interfaces::element_layout::contiguous
>(
888 auto empty
= range
<boost::stl_interfaces::element_layout::contiguous
>(
893 std::array
<int, 10> ints_copy
;
894 std::copy(r
.begin(), r
.end(), ints_copy
.begin());
895 BOOST_TEST(ints_copy
== ints
);
897 BOOST_TEST(empty
.begin() == empty
.end());
902 BOOST_TEST(!r
.empty());
905 BOOST_TEST(empty
.empty());
909 BOOST_TEST(!cr
.empty());
912 auto const cempty
= empty
;
913 BOOST_TEST(cempty
.empty());
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)
923 BOOST_TEST(r
.data() != nullptr);
924 BOOST_TEST(r
.data()[2] == 2);
926 BOOST_TEST(empty
.data() != nullptr);
929 BOOST_TEST(cr
.data() != nullptr);
930 BOOST_TEST(cr
.data()[2] == 2);
932 auto const cempty
= empty
;
933 BOOST_TEST(cempty
.data() != nullptr);
939 BOOST_TEST(r
.size() == 10u);
941 BOOST_TEST(empty
.size() == 0u);
944 BOOST_TEST(cr
.size() == 10u);
946 auto const cempty
= empty
;
947 BOOST_TEST(cempty
.size() == 0u);
952 BOOST_TEST(r
.front() == 0);
953 BOOST_TEST(r
.back() == 9);
956 BOOST_TEST(cr
.front() == 0);
957 BOOST_TEST(cr
.back() == 9);
962 BOOST_TEST(r
[2] == 2);
965 BOOST_TEST(cr
[2] == 2);
971 zip_iter
first(ints
.data(), ones
.data());
972 zip_iter
last(ints
.data() + ints
.size(), ones
.data() + ones
.size());
974 auto r
= range
<boost::stl_interfaces::element_layout::discontiguous
>(
977 range
<boost::stl_interfaces::element_layout::discontiguous
>(
982 BOOST_TEST(std::equal(first
, last
, tuples
.begin(), tuples
.end()));
987 BOOST_TEST(!r
.empty());
990 BOOST_TEST(empty
.empty());
994 BOOST_TEST(!cr
.empty());
997 auto const cempty
= empty
;
998 BOOST_TEST(cempty
.empty());
1004 BOOST_TEST(r
.size() == 10u);
1006 BOOST_TEST(empty
.size() == 0u);
1009 BOOST_TEST(cr
.size() == 10u);
1011 auto const cempty
= empty
;
1012 BOOST_TEST(cempty
.size() == 0u);
1017 BOOST_TEST(r
.front() == (std::tuple
<int, int>(0, 1)));
1018 BOOST_TEST(r
.back() == (std::tuple
<int, int>(9, 1)));
1021 BOOST_TEST(cr
.front() == (std::tuple
<int, int>(0, 1)));
1022 BOOST_TEST(cr
.back() == (std::tuple
<int, int>(9, 1)));
1027 BOOST_TEST(r
[2] == (std::tuple
<int, int>(2, 1)));
1030 BOOST_TEST(cr
[2] == (std::tuple
<int, int>(2, 1)));
1034 return boost::report_errors();