1 // Copyright (C) 2020-2023 Free Software Foundation, Inc.
2 // This file is part of the GNU ISO C++ Library. This library is free
3 // software; you can redistribute it and/or modify it under the
4 // terms of the GNU General Public License as published by the
5 // Free Software Foundation; either version 3, or (at your option)
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU General Public License for more details.
13 // You should have received a copy of the GNU General Public License along
14 // with this library; see the file COPYING3. If not see
15 // <http://www.gnu.org/licenses/>.
17 // { dg-options "-std=gnu++2a" }
18 // { dg-do run { target c++2a } }
30 #include <testsuite_hooks.h>
31 #include <testsuite_iterators.h>
33 using __gnu_test::test_input_range
;
34 using __gnu_test::test_forward_range
;
35 using __gnu_test::test_range
;
36 using __gnu_test::test_sized_range_sized_sent
;
37 using __gnu_test::input_iterator_wrapper_nocopy
;
39 namespace ranges
= std::ranges
;
43 test01(std::vector
<T
> ix
)
45 static_assert(std::move_constructible
<T
>);
46 static_assert(std::equality_comparable
<T
>);
48 const auto saved_ix
= ix
;
50 for (int k
= 0; k
< 7; k
++)
55 auto buffer
= std::unique_ptr
<char[]>(new char[sizeof(T
)*size
]);
56 std::span
<T
> rx((T
*)buffer
.get(), size
);
58 ranges::uninitialized_move_result res
= {ix
.begin(), rx
.begin()};
60 res
= ranges::uninitialized_move(ix
.begin(), ix
.end(),
61 rx
.begin(), rx
.end());
63 res
= ranges::uninitialized_move(ix
, rx
);
65 res
= ranges::uninitialized_move_n(ix
.begin(), size
,
66 rx
.begin(), rx
.end());
68 res
= ranges::uninitialized_move(ix
.begin(), ix
.end(),
69 rx
.begin(), rx
.end());
71 res
= ranges::uninitialized_move(ix
, std::as_const(rx
));
73 res
= ranges::uninitialized_move_n(ix
.begin(), size
,
74 rx
.begin(), rx
.end());
76 res
= ranges::uninitialized_move_n(ix
.begin(), size
/2,
77 rx
.begin(), rx
.end());
79 res
= ranges::uninitialized_move_n(ix
.begin(), size
,
80 rx
.begin(), rx
.begin()+size
/2);
86 VERIFY( ranges::distance(ix
.begin(), res
.in
) == size
/2 );
87 VERIFY( ranges::distance(rx
.begin(), res
.out
) == size
/2 );
88 VERIFY( ranges::equal(saved_ix
.begin(), saved_ix
.begin()+size
/2,
89 rx
.begin(), rx
.begin()+size
/2) );
90 ranges::destroy(rx
.begin(), rx
.begin()+size
/2);
94 VERIFY( res
.in
== ix
.end() );
95 VERIFY( res
.out
== rx
.end() );
96 VERIFY( ranges::equal(saved_ix
, rx
) );
104 static constexpr int limit
= 67;
105 static inline int move_construct_count
= 0;
106 static inline int destruct_count
= 0;
111 bool moved_from
= false;
114 { live
= true; moved_from
= false; }
116 X
& operator=(const X
&) = delete;
117 X(const X
&) = delete;
119 X
&& operator=(X
&&) = delete;
123 VERIFY( !other
.moved_from
);
124 other
.moved_from
= true;
126 if (move_construct_count
>= limit
)
128 move_construct_count
++;
139 template<bool test_sized
>
143 constexpr int size
= 100;
145 // FIXME: Should be test_input_range?
146 test_forward_range
<X
> ix(x
);
148 auto buffer
= std::unique_ptr
<char[]>(new char[sizeof(X
)*size
]);
149 test_forward_range
<X
> rx((X
*)buffer
.get(), (X
*)buffer
.get() + size
);
152 X::move_construct_count
= 0;
153 X::destruct_count
= 0;
154 if constexpr (test_sized
)
155 ranges::uninitialized_move_n(ix
.begin(), size
, rx
.begin(), rx
.end());
157 ranges::uninitialized_move(ix
, rx
);
158 VERIFY( false && "exception not thrown" );
160 catch (const X::exception
&)
162 VERIFY( X::move_construct_count
== X::limit
);
163 VERIFY( X::destruct_count
== X::limit
);
174 test_sized_range_sized_sent
<int, input_iterator_wrapper_nocopy
> rx(x
);
175 ranges::uninitialized_move(rx
, y
);
176 ranges::uninitialized_move_n(rx
.begin(), 3, y
, y
+3);
182 test_range
<int, input_iterator_wrapper_nocopy
> rx(x
);
183 test_forward_range
<int> ry(y
);
184 ranges::uninitialized_move(rx
, y
);
185 ranges::uninitialized_move_n(rx
.begin(), 3, ry
.begin(), ry
.end());
192 test01
<char>({1,2,3,4,5});
193 test01
<int>({1,2,3,4,5});
194 test01
<long long>({1,2,3,4,5});
195 test01
<float>({1.1,2.1,3.1,4.1});
196 test01
<double>({1.1,2.1,3.1,4.1});
197 test01
<std::vector
<char>>({{'a','b'}, {'c','d'}, {'e','f'}});
198 test01
<std::string
>({"the", "quick", "brown", "fox"});