Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
25.copy.cpp
Go to the documentation of this file.
1
29#include <algorithm> // for copy
30#include <cstddef> // for size_t
31
32#include <rw_alg_test.h>
33#include <rw_value.h> // for UserClass
34#include <rw_driver.h> // for rw_test()...
35
36
39
40#ifndef _RWSTD_NO_EXPLICIT_INSTANTIATION
41
42template
47
48template
50copy_backward (BidirIter<const_cvt<base<>, assign<base<> > > >,
53
54#endif // _RWSTD_NO_EXPLICIT_INSTANTIATION
55
56} // namespace std
57
58
59
61// exercises std::copy()
62template <class InputIterator, class OutputIterator, class T>
63void test_copy (std::size_t N,
64 const InputIterator &input_iter,
65 const OutputIterator &output_iter,
66 const T* )
67{
68 static const char* const it1name = type_name (input_iter, (T*) 0);
69 static const char* const it2name = type_name (output_iter, (T*) 0);
70
71 rw_info (0, 0, 0, "std::copy (%s, %1$s, %s)", it1name, it2name);
72
73 // generate sequential values for each default constructed T
74 T::gen_ = gen_seq;
75
76 // create separate buffers for src and dst to ensure 25.2.1, p3
77 T* const src = new T [N];
78 T* const dst = new T [N];
79
80 for (std::size_t i = 0; i != N; ++i) {
81
82 T* const src_end = src + i + 1;
83 T* const dst_end = dst + i + 1;
84
85 // exercise 25.2.1 - std::copy()
86 std::size_t last_n_op_assign = T::n_total_op_assign_;
87
88 const InputIterator begin =
89 make_iter (src, src, src_end, input_iter);
90
91 const InputIterator end =
92 make_iter (src_end, src_end, src_end, input_iter);
93
94 const OutputIterator dest =
95 make_iter (dst, dst, dst_end, output_iter);
96
98 std::copy (begin, end, dest);
99
100 T* const resptr = result.cur_;
101
102 // verify 25.2.1, p2
103 bool success = resptr == dst_end;
104 rw_assert (success, 0, __LINE__,
105 "%zu. copy(%p, %p, %p) == %p, got %p",
106 i, src, src_end, dst, dst_end, resptr);
107
108 if (!success)
109 break;
110
111 // check that algjrithm works correctly
112 std::size_t j = 0;
113 for (; j != i + 1; ++j) {
114 success = src[j].data_.val_ == dst[j].data_.val_;
115 if (!success)
116 break;
117 }
118
119 rw_assert (success, 0, __LINE__,
120 "%zu. copy(%p, %p, %p) mismatch at "
121 "offset %zu: expected %d, got %d: (%p, %p, %zu)",
122 i, src, src_end, dst,
123 j, src[j].data_.val_, dst[j].data_.val_,
124 dst, dst_end, j);
125
126 if (!success)
127 break;
128
129 // verify 25.2.1, p4
130 success = T::n_total_op_assign_ - last_n_op_assign == i + 1;
131 rw_assert (success, 0, __LINE__,
132 "%zu. copy(%p, %p, %p) complexity: ",
133 "%zu != %zu", i + 1, src, src_end, dst,
134 T::n_total_op_assign_ - last_n_op_assign, i + 1);
135
136 if (!success)
137 break;
138 }
139
140 delete[] src;
141 delete[] dst;
142}
143
144
146// exercises std::copy_backward()
147template <class BidirIterator1, class BidirIterator2, class T>
148void test_copy_backward (std::size_t N,
149 const BidirIterator1 &bidir_iter1,
150 const BidirIterator2 &bidir_iter2,
151 const T*)
152{
153 static const char* const it1name = type_name (bidir_iter1, (T*) 0);
154 static const char* const it2name = type_name (bidir_iter2, (T*) 0);
155
156 rw_info (0, 0, 0, "std::copy_backward (%s, %1$s, %s)", it1name, it2name);
157
158 // generate sequential values for each default constructed T
159 T::gen_ = gen_seq;
160
161 // create separate buffers for src and dst to ensure 25.2.1, p3
162 T* const src = new T [N];
163 T* const dst = new T [N];
164
165 for (std::size_t i = 0; i != N; ++i) {
166
167 // default-construct a new T at the end of each sequence
168 new (src + i) T ();
169 new (dst + i) T ();
170
171 // exercise 25.2.1 - std::copy_backward()
172 std::size_t last_n_op_assign = T::n_total_op_assign_;
173
174 T* const src_end = src + i + 1;
175 T* const dst_end = dst + i + 1;
176
177 const BidirIterator1 begin =
178 make_iter (src, src, src_end, bidir_iter1);
179
180 const BidirIterator1 end =
181 make_iter (src_end, src, src_end, bidir_iter1);
182
183 const BidirIterator2 dest =
184 make_iter (dst_end, dst, dst_end, bidir_iter2);
185
186 const BidirIterator2 result =
187 std::copy_backward (begin, end, dest);
188
189 const T* const resptr = result.cur_;
190
191 // verify 25.2.1, p7
192 bool success = resptr == dst;
193 rw_assert (success, 0, __LINE__,
194 "%zu. copy_backward(%p, %p, %p) == %p, got %p",
195 i, src, src_end, dst_end, dst, resptr);
196
197 if (!success)
198 break;
199
200 // verify 25.2.1, p5
201 std::size_t j = 0;
202 for (; j != i + 1; ++j) {
203 success = src[j].data_.val_ == dst[j].data_.val_;
204 if (!success)
205 break;
206 }
207
208 rw_assert (success, 0, __LINE__,
209 "%zu. copy_backward(%p, %p, %p) mismatch at "
210 "offset %zu: expected %d, got %d: (%p, %p, %zu)",
211 i, src, src_end, dst_end,
212 j, src[j].data_.val_, dst[j].data_.val_,
213 dst, dst_end, j);
214
215 if (!success)
216 break;
217
218 // verify 25.2.1, p8
219 success = T::n_total_op_assign_ - last_n_op_assign == i + 1;
220 rw_assert (success, 0, __LINE__,
221 "%zu. copy_backward(%p, %p, %p) complexity: "
222 "%zu != %zu", i + 1, src, src_end, dst_end,
223 T::n_total_op_assign_ - last_n_op_assign, i + 1);
224
225 if (!success)
226 break;
227 }
228
229 delete[] src;
230 delete[] dst;
231}
232
233
235/* extern */ int rw_opt_nloops = 32; // --nloops
236/* extern */ int rw_opt_no_input_iter; // --no-InputIterator
237/* extern */ int rw_opt_no_output_iter; // --no-OutputIterator
238/* extern */ int rw_opt_no_fwd_iter; // --no-ForwardIterator
239/* extern */ int rw_opt_no_bidir_iter; // --no-BidirectionalIterator
240/* extern */ int rw_opt_no_rnd_iter; // --no-RandomAccessIterator
241
242template <class InputIterator, class T>
243void test_copy (const std::size_t N, const InputIterator &dummy, T*)
244{
246 rw_note (0, __FILE__, __LINE__, "OutputIterator test disabled");
247 }
248 else {
250 (UserClass*)0, (UserClass*)0), (UserClass*)0);
251 }
252
253 if (rw_opt_no_fwd_iter) {
254 rw_note (0, __FILE__, __LINE__, "ForwardIterator test disabled");
255 }
256 else {
257 test_copy (N, dummy, FwdIter<UserClass>(), (UserClass*)0);
258 }
259
261 rw_note (0, __FILE__, __LINE__,
262 "BidirectionalIterator test disabled");
263 }
264 else {
265 test_copy (N, dummy, BidirIter<UserClass>(), (UserClass*)0);
266 }
267
268 if (rw_opt_no_rnd_iter) {
269 rw_note (0, __FILE__, __LINE__,
270 "RandomAccessIterator test disabled");
271 }
272 else {
274 }
275}
276
277
279static void
280test_copy (const std::size_t N)
281{
282 rw_info (0, 0, 0,
283 "template <class %s, class %s> "
284 "%2$s std::copy (%1$s, %1$s, %2$s)",
285 "InputIterator", "OutputIterator");
286
288 rw_note (0, __FILE__, __LINE__, "InputIterator test disabled");
289 }
290 else {
292 (UserClass*)0), (UserClass*)0);
293 }
294
295 if (rw_opt_no_fwd_iter) {
296 rw_note (0, __FILE__, __LINE__, "ForwardIterator test disabled");
297 }
298 else {
300 }
301
303 rw_note (0, __FILE__, __LINE__,
304 "BidirectionalIterator test disabled");
305 }
306 else {
308 }
309
310 if (rw_opt_no_rnd_iter) {
311 rw_note (0, __FILE__, __LINE__,
312 "RandomAccessIterator test disabled");
313 }
314 else {
316 }
317}
318
319
321template <class InputIterator, class T>
322void test_copy_backward (const std::size_t N, const InputIterator &dummy, T*)
323{
325 rw_note (0, __FILE__, __LINE__,
326 "BidirectionalIterator test disabled");
327 }
328 else {
330 }
331
332 if (rw_opt_no_rnd_iter) {
333 rw_note (0, __FILE__, __LINE__,
334 "RandomAccessIterator test disabled");
335 }
336 else {
338 (UserClass*)0);
339 }
340}
341
342
344static void
345test_copy_backward (const std::size_t N)
346{
347 rw_info (0, 0, 0,
348 "template <class %s, class %s> %2$s "
349 "std::copy_backward (%1$s, %1$s, %2$s)",
350 "BidirectionalIterator1", "BidirectionalIterator2");
351
353 rw_note (0, __FILE__, __LINE__,
354 "BidirectionalIterator test disabled");
355 }
356 else {
358 }
359
360 if (rw_opt_no_rnd_iter) {
361 rw_note (0, __FILE__, __LINE__,
362 "RandomAccessIterator test disabled");
363 }
364 else {
366 }
367}
368
369
371static int
372run_test (int, char*[])
373{
374 // check that the number of loops is non-negative
375 rw_fatal (-1 < rw_opt_nloops, 0, 0,
376 "number of loops must be non-negative, got %d",
378
379 const std::size_t N = std::size_t (rw_opt_nloops);
380
381 test_copy (N);
382
384
385 return 0;
386}
387
388
390int main (int argc, char *argv[])
391{
392 return rw_test (argc, argv, __FILE__,
393 "lib.alg.copy",
394 0 /* no comment */, run_test,
395 "|-nloops#"
396 "|-no-InputIterator#"
397 "|-no-OutputIterator#"
398 "|-no-ForwardIterator#"
399 "|-no-BidirectionalIterator#"
400 "|-no-RandomAccessIterator#",
407}
408
#define N
Definition 17.names.cpp:157
#define i
Definition 17.names.cpp:126
#define T
Definition 17.names.cpp:163
#define j
Definition 17.names.cpp:127
#define OutputIterator
Definition 17.names.cpp:515
volatile int result
void test_copy_backward(std::size_t N, const BidirIterator1 &bidir_iter1, const BidirIterator2 &bidir_iter2, const T *)
Definition 25.copy.cpp:148
int rw_opt_no_fwd_iter
Definition 25.copy.cpp:238
void test_copy(std::size_t N, const InputIterator &input_iter, const OutputIterator &output_iter, const T *)
Definition 25.copy.cpp:63
int rw_opt_no_rnd_iter
Definition 25.copy.cpp:240
int rw_opt_no_bidir_iter
Definition 25.copy.cpp:239
int rw_opt_no_input_iter
Definition 25.copy.cpp:236
int rw_opt_no_output_iter
Definition 25.copy.cpp:237
int rw_opt_nloops
Definition 25.copy.cpp:235
const char * type_name()
const int end
#define main
#define _RWSTD_NAMESPACE(name)
Definition _defs.h:567
Definition json.h:5363
_TEST_EXPORT int gen_seq()
Definition alg_test.cpp:38
T * make_iter(T *cur, const T *, const T *, T *)
_TEST_EXPORT int rw_test(int argc, char *argv[], const char *filename, const char *clause, const char *comment, int(*testfun)(int, char **), const char *optspec,...)
_TEST_EXPORT int rw_info(int, const char *, int, const char *,...)
Definition driver.cpp:1681
_TEST_EXPORT int rw_fatal(int expr, const char *filename, int line, const char *fmtspec,...)
Definition driver.cpp:1596
_TEST_EXPORT int rw_note(int, const char *, int, const char *,...)
Definition driver.cpp:1664
_TEST_EXPORT int rw_assert(int, const char *, int, const char *,...)
Definition driver.cpp:1630