1 // Copyright (C) 2020-2025 Free Software Foundation, Inc.
3 // This file is part of the GNU ISO C++ Library. This library is free
4 // software; you can redistribute it and/or modify it under the
5 // terms of the GNU General Public License as published by the
6 // Free Software Foundation; either version 3, or (at your option)
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License along
15 // with this library; see the file COPYING3. If not see
16 // <http://www.gnu.org/licenses/>.
18 // { dg-do run { target c++20 } }
22 #include <testsuite_hooks.h>
23 #include <testsuite_iterators.h>
25 using __gnu_test::test_container
;
26 using __gnu_test::test_range
;
27 using __gnu_test::bidirectional_iterator_wrapper
;
29 namespace ranges
= std::ranges
;
35 int x
[7] = { 1, 2, 3, 4, 5, 6, 7 };
37 int z
[7] = { 1, 2, 3, 4, 5, 6, 7 };
38 auto [in
, out
] = ranges::copy_backward(x
, ranges::end(y
));
39 VERIFY( ranges::equal(x
, y
) && in
== x
+7 && out
== y
);
40 VERIFY( ranges::equal(x
, z
) );
44 int x
[3] = { 1, 2, 3 };
46 int z
[3] = { 1, 2, 3 };
47 test_container
<int, bidirectional_iterator_wrapper
> cx(x
);
48 test_container
<char, bidirectional_iterator_wrapper
> cy(y
);
49 auto [in
, out
] = ranges::copy_backward(cx
, ranges::end(cy
));
50 VERIFY( ranges::equal(x
, x
+3, y
+1, y
+4) && in
.ptr
== x
+3 && out
.ptr
== y
+1 );
51 VERIFY( ranges::equal(x
, z
) );
55 std::vector
<char> x
= {1,2,3};
56 std::vector
<int> y(3);
57 const int z
[3] = { 1, 2, 3 };
58 auto [in
, out
] = ranges::copy_backward(x
, ranges::end(y
));
59 VERIFY( in
== x
.begin()+3 );
60 VERIFY( out
== y
.begin() );
61 VERIFY( ranges::equal(y
, z
) && ranges::equal(x
, z
) );
66 std::vector
<int> x
= {1,2,3};
67 std::vector
<int> y(3);
68 const int z
[3] = { 1, 2, 3 };
69 auto [in
, out
] = ranges::copy_backward(x
, ranges::end(y
));
70 VERIFY( in
== x
.begin()+3 );
71 VERIFY( out
== y
.begin() );
72 VERIFY( ranges::equal(y
, z
) && ranges::equal(x
, z
) );
76 std::vector
<int> x
= {1,2,3};
77 std::vector
<int> y(3);
78 const int z
[3] = { 1, 2, 3 };
79 auto [in
,out
] = ranges::copy_backward(make_reverse_iterator(x
.end()),
80 make_reverse_iterator(x
.begin()),
81 make_reverse_iterator(y
.begin()));
82 VERIFY( in
.base() == x
.begin()+3 );
83 VERIFY( out
.base() == y
.begin()+3 );
84 VERIFY( ranges::equal(y
, z
) && ranges::equal(x
, z
) );
88 std::vector
<char> x
= {1,2,3};
89 std::vector
<int> y(3);
90 const int z
[3] = { 1, 2, 3 };
91 auto [in
,out
] = ranges::copy_backward(make_reverse_iterator(x
.end()),
92 make_reverse_iterator(x
.begin()),
93 make_reverse_iterator(y
.begin()));
94 VERIFY( in
.base() == x
.begin()+3 );
95 VERIFY( out
.base() == y
.begin()+3 );
96 VERIFY( ranges::equal(y
, z
) && ranges::equal(x
, z
) );
104 int x
[] = { {2}, {2}, {6}, {8}, {10} };
105 int y
[] = { {2}, {6}, {8}, {10}, {11}, {2} };
106 const int z
[] = { {2}, {2}, {6}, {8}, {10} };
107 auto [in
, out
] = ranges::copy_backward(x
, ranges::end(y
));
108 ok
&= ranges::equal(x
, x
+5, y
+1, y
+6);
112 ok
&= ranges::equal(x
, z
);
116 /* move_iterators are always input_iterators and therefore do not model
117 * bidirectional_iterator, so I think the following tests are rightly invalid.
124 constexpr Y(int a) : i(a) { }
126 constexpr Y(const Y&) = delete;
127 constexpr Y& operator=(const Y&) = delete;
129 constexpr Y(Y&& other)
131 *this = std::move(other);
142 friend constexpr bool
143 operator==(const Y& a, const Y& b)
144 { return a.i == b.i; }
150 Y x[7] = { 1, 2, 3, 4, 5, 6, 7 };
151 Y y[7] = { 0, 0, 0, 0, 0, 0, 0 };
152 Y z[7] = { 1, 2, 3, 4, 5, 6, 7 };
153 test_range<Y, bidirectional_iterator_wrapper> rx(x);
154 auto [in, out] = ranges::copy_backward(std::move_iterator{ranges::begin(rx)},
155 std::move_sentinel{ranges::end(rx)},
157 VERIFY( ranges::equal(x, y) && std::move(in).base().ptr == x+7 && out == y );
158 VERIFY( ranges::equal(x, z) );
159 for (const auto& v : x)
160 VERIFY( v.moved == 1 );
161 for (const auto& v : y)
162 VERIFY( v.moved == 0 );
169 Y x[7] = { 1, 2, 3, 4, 5, 6, 7 };
170 Y y[7] = { 0, 0, 0, 0, 0, 0, 0 };
171 Y z[7] = { 1, 2, 3, 4, 5, 6, 7 };
172 auto [in, out] = ranges::copy_backward(std::move_iterator{ranges::begin(x)},
173 std::move_sentinel{ranges::end(x)},
175 ok &= ranges::equal(x, y);
176 ok &= in.base() == x+7;
178 ok &= ranges::equal(x, z);
179 for (const auto& v : x)
181 for (const auto& v : y)
191 static_assert(test02());