99#include < ranges>
1010#include < span>
1111#include < utility>
12+ #include < vector>
1213
1314#include < range_algorithm_support.hpp>
1415
@@ -66,39 +67,77 @@ struct holder {
6667 }
6768};
6869
69- template <class R >
70- void not_ranges_destroy (R&& r) { // TRANSITION, ranges::destroy
71- for (auto & e : r) {
72- destroy_at (&e);
73- }
74- }
75-
7670struct instantiator {
77- static constexpr int expected_output[] = {13 , 55 , 12345 };
78- static constexpr int expected_input[] = {13 , 55 , 12345 };
71+ static constexpr int expected_output[] = {13 , 55 , 12345 };
72+ static constexpr int expected_output_long[] = {13 , 55 , 12345 , -1 };
73+ static constexpr int expected_input[] = {13 , 55 , 12345 };
74+ static constexpr int expected_input_long[] = {13 , 55 , 12345 , 42 };
7975
8076 template <ranges::input_range Read, ranges::forward_range Write>
8177 static void call () {
82- using ranges::uninitialized_copy_n, ranges::uninitialized_copy_n_result, ranges::equal, ranges::equal_to,
83- ranges::iterator_t ;
78+ using ranges::destroy, ranges::uninitialized_copy_n, ranges::uninitialized_copy_n_result, ranges::equal,
79+ ranges::equal_to, ranges::iterator_t ;
80+
81+ { // Validate equal ranges
82+ int_wrapper input[3 ] = {13 , 55 , 12345 };
83+ Read wrapped_input{input};
84+ holder<int_wrapper, 3 > mem;
85+ Write wrapped_output{mem.as_span ()};
86+
87+ int_wrapper::clear_counts ();
88+ const same_as<uninitialized_copy_n_result<iterator_t <Read>, iterator_t <Write>>> auto result =
89+ uninitialized_copy_n (wrapped_input.begin (), 3 , wrapped_output.begin (), wrapped_output.end ());
90+ assert (int_wrapper::constructions == 3 );
91+ assert (int_wrapper::destructions == 0 );
92+ assert (result.in == wrapped_input.end ());
93+ assert (result.out == wrapped_output.end ());
94+ assert (equal (wrapped_output, expected_output, equal_to{}, &int_wrapper::val));
95+ assert (equal (input, expected_input, equal_to{}, &int_wrapper::val));
96+ destroy (wrapped_output);
97+ assert (int_wrapper::constructions == 3 );
98+ assert (int_wrapper::destructions == 3 );
99+ }
84100
85- int_wrapper input[3 ] = {13 , 55 , 12345 };
86- Read wrapped_input{input};
87- holder<int_wrapper, 3 > mem;
88- Write wrapped_output{mem.as_span ()};
101+ { // Validate shorter output
102+ int_wrapper input[4 ] = {13 , 55 , 12345 , 42 };
103+ Read wrapped_input{input};
104+ holder<int_wrapper, 3 > mem;
105+ Write wrapped_output{mem.as_span ()};
106+
107+ int_wrapper::clear_counts ();
108+ same_as<uninitialized_copy_n_result<iterator_t <Read>, iterator_t <Write>>> auto result =
109+ uninitialized_copy_n (wrapped_input.begin (), 3 , wrapped_output.begin (), wrapped_output.end ());
110+ assert (int_wrapper::constructions == 3 );
111+ assert (int_wrapper::destructions == 0 );
112+ assert (++result.in == wrapped_input.end ());
113+ assert (result.out == wrapped_output.end ());
114+ assert (equal (wrapped_output, expected_output, equal_to{}, &int_wrapper::val));
115+ assert (equal (input, expected_input_long, equal_to{}, &int_wrapper::val));
116+ destroy (wrapped_output);
117+ assert (int_wrapper::constructions == 3 );
118+ assert (int_wrapper::destructions == 3 );
119+ }
89120
90- int_wrapper::clear_counts ();
91- const same_as<uninitialized_copy_n_result<iterator_t <Read>, iterator_t <Write>>> auto result =
92- uninitialized_copy_n (wrapped_input.begin (), 3 , wrapped_output.begin (), wrapped_output.end ());
93- assert (int_wrapper::constructions == 3 );
94- assert (int_wrapper::destructions == 0 );
95- assert (result.in == wrapped_input.end ());
96- assert (result.out == wrapped_output.end ());
97- assert (equal (wrapped_output, expected_output, equal_to{}, &int_wrapper::val));
98- assert (equal (input, expected_input, equal_to{}, &int_wrapper::val));
99- not_ranges_destroy (wrapped_output);
100- assert (int_wrapper::constructions == 3 );
101- assert (int_wrapper::destructions == 3 );
121+ { // Validate shorter input
122+ int_wrapper input[3 ] = {13 , 55 , 12345 };
123+ Read wrapped_input{input};
124+ holder<int_wrapper, 4 > mem;
125+ Write wrapped_output{mem.as_span ()};
126+
127+ int_wrapper::clear_counts ();
128+ same_as<uninitialized_copy_n_result<iterator_t <Read>, iterator_t <Write>>> auto result =
129+ uninitialized_copy_n (wrapped_input.begin (), 3 , wrapped_output.begin (), wrapped_output.end ());
130+ assert (int_wrapper::constructions == 3 );
131+ assert (int_wrapper::destructions == 0 );
132+ assert (result.in == wrapped_input.end ());
133+ construct_at (addressof (*result.out ), -1 ); // Need to construct non written element for comparison
134+ assert (++result.out == wrapped_output.end ());
135+ assert (equal (wrapped_output, expected_output_long, equal_to{}, &int_wrapper::val));
136+ assert (equal (input, expected_input, equal_to{}, &int_wrapper::val));
137+ destroy (wrapped_output);
138+ assert (int_wrapper::constructions == 4 );
139+ assert (int_wrapper::destructions == 4 );
140+ }
102141 }
103142};
104143
@@ -126,6 +165,53 @@ struct throwing_test {
126165 }
127166};
128167
168+ struct memcpy_test {
169+ static constexpr int expected_output[] = {13 , 55 , 12345 , -1 };
170+ static constexpr int expected_output_long[] = {13 , 55 , -1 , -1 };
171+ static constexpr int expected_input[] = {13 , 55 , 12345 , 42 };
172+ static constexpr int expected_input_short[] = {13 , 55 };
173+ static constexpr int expected_input_long[] = {13 , 55 , 12345 , 42 };
174+
175+ static void call () {
176+ using ranges::uninitialized_copy_n, ranges::uninitialized_copy_n_result, ranges::equal, ranges::iterator_t ;
177+ { // Validate range overload
178+ vector<int > input = {13 , 55 , 12345 , 42 };
179+ vector<int > output = {-1 , -1 , -1 , -1 };
180+
181+ const same_as<uninitialized_copy_n_result<iterator_t <vector<int >>, iterator_t <vector<int >>>> auto result =
182+ uninitialized_copy_n (input.begin (), 3 , output.begin (), output.end ());
183+ assert (next (result.in ) == input.end ());
184+ assert (next (result.out ) == output.end ());
185+ assert (equal (input, expected_input));
186+ assert (equal (output, expected_output));
187+ }
188+
189+ { // Validate shorter input
190+ vector<int > input = {13 , 55 };
191+ vector<int > output = {-1 , -1 , -1 , -1 };
192+
193+ const same_as<uninitialized_copy_n_result<iterator_t <vector<int >>, iterator_t <vector<int >>>> auto result =
194+ uninitialized_copy_n (input.begin (), 2 , output.begin (), output.end ());
195+ assert (result.in == input.end ());
196+ assert (next (result.out , 2 ) == output.end ());
197+ assert (equal (input, expected_input_short));
198+ assert (equal (output, expected_output_long));
199+ }
200+
201+ { // Validate shorter output
202+ vector<int > input = {13 , 55 , 12345 , 42 };
203+ vector<int > output = {-1 , -1 };
204+
205+ const same_as<uninitialized_copy_n_result<iterator_t <vector<int >>, iterator_t <vector<int >>>> auto result =
206+ uninitialized_copy_n (input.begin (), 2 , output.begin (), output.end ());
207+ assert (next (result.in , 2 ) == input.end ());
208+ assert (result.out == output.end ());
209+ assert (equal (input, expected_input));
210+ assert (equal (output, expected_input_short));
211+ }
212+ }
213+ };
214+
129215template <test::ProxyRef IsProxy>
130216using test_input = test::range<test::input, int_wrapper, test::Sized::no, test::CanDifference::no, test::Common::no,
131217 test::CanCompare::yes, IsProxy>;
@@ -140,4 +226,5 @@ int main() {
140226 instantiator::call<test_input<test::ProxyRef::yes>, test_output>();
141227 throwing_test::call<test_input<test::ProxyRef::no>, test_output>();
142228 throwing_test::call<test_input<test::ProxyRef::yes>, test_output>();
229+ memcpy_test::call ();
143230}
0 commit comments