Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
25.rotate.cpp
Go to the documentation of this file.
1
29#include <algorithm> // for rotate, rotate_copy
30#include <cstring> // for size_t, strlen()
31
32#include <rw_alg_test.h>
33#include <rw_value.h> // for UserClass
34#include <rw_driver.h> // for rw_test()
35
36
38
39// disable explicit instantiation for compilers (like MSVC)
40// that can't handle it
41#ifndef _RWSTD_NO_EXPLICIT_INSTANTIATION
42
43template
44void
45rotate (FwdIter<assign<base<cpy_ctor> > >,
48
49template
51rotate_copy (FwdIter<assign<base<cpy_ctor> > >,
55
56#endif // _RWSTD_NO_EXPLICIT_INSTANTIATION
57
58} // namespace std
59
60
62// tags to select rotate or rotate_copy at compile time
63struct RotateTag {
64 enum { fname_inx = 0 };
65 int dummy;
66};
67
69 enum { fname_inx = 1 };
70 int dummy;
71};
72
73// used as a dummy template argument to test functions exercising rotate()
74// (to differentiate from rotate_copy())
75struct NoIterator { };
76const char* type_name (NoIterator, const UserClass*)
77{
78 return 0;
79}
80
81
82
85
87
90{
92
93 const int tmp = (*i).data_.val_;
94
95 (*i).data_.val_ = (*j).data_.val_;
96 (*j).data_.val_ = tmp;
97}
98
99
102{
104
105 const int tmp = (*i).data_.val_;
106
107 (*i).data_.val_ = (*j).data_.val_;
108 (*j).data_.val_ = tmp;
109}
110
111
114{
116
117 const int tmp = (*i).data_.val_;
118
119 (*i).data_.val_ = (*j).data_.val_;
120 (*j).data_.val_ = tmp;
121}
122
123} // namespace std
124
125
127// exercises std::rotate()
128template <class Iterator, class T>
130 const char *src,
131 std::size_t midnsrc,
132 Iterator it, NoIterator, const T*, RotateTag)
133{
134 static const char* const itname = type_name (it, (T*)0);
135 const char* const fname = "rotate";
136
137 // compute the length of the source sequence
138 const std::size_t nsrc = std::strlen (src);
139
140 // construct a sequence of `nsrc' elements to pass to reverse
141 T* const xsrc = T::from_char (src, nsrc);
142
143 // construct iterators pointing to the beginning and end
144 // of the source sequence
145 const Iterator first = make_iter (xsrc, xsrc, xsrc + nsrc, it);
146 const Iterator middle = make_iter (xsrc + midnsrc, xsrc, xsrc + nsrc, it);
147 const Iterator last = make_iter (xsrc + nsrc, xsrc, xsrc + nsrc, it);
148
149 // zero out the iter_swap() call counter
150 iter_swap_calls = 0;
151
152 // call rotate()
153 std::rotate (first, middle, last);
154
155 bool success = true;
156 std::size_t i = 0;
157 std::size_t xpos = 0;
158
159 // verify that the sequence was correctly reversed and that it was
160 // done by swapping elements i.e., not simply by copying them over
161 for ( ; i != nsrc; ++i) {
162
163 xpos = (i + (nsrc - midnsrc)) % nsrc;
164
165 typedef unsigned char UChar;
166
167 success = UChar (src [i]) == xsrc [xpos].data_.val_;
168 if (!success)
169 break;
170 }
171
172 rw_assert (success, 0, line,
173 "line %d: %s<%s>(\"%s\", %zu, ...) ==> "
174 "\"%{X=*.*}\"; unexpected element value %#c at %zu",
175 __LINE__, fname, itname, src, midnsrc,
176 int (sizeof (*xsrc)), int (nsrc), int (i), xsrc,
177 xsrc [xpos].data_.val_, i);
178
179 success = iter_swap_calls <= nsrc;
180 rw_assert (success, 0, line,
181 "line %d: %s<%s>(\"%s\", %zu, ...); called iter_swap() "
182 "%zu times, expected no more than %zu",
183 __LINE__, fname, itname, src, midnsrc,
185
186 delete[] xsrc;
187}
188
189
191// exercises std::rotate_copy()
192template <class Iterator, class OutputIterator, class T>
194 const char *src,
195 std::size_t midnsrc,
196 Iterator it, OutputIterator dummy,
197 const T*, RotateCopyTag)
198{
199 static const char* const it1name = type_name (it, (T*)0);
200 static const char* const it2name = type_name (dummy, (T*)0);
201 const char* const fname = "rotate_copy";
202
203 const std::size_t nsrc = std::strlen (src);
204
205 T* const xsrc = T::from_char (src, nsrc);
206 T* const xdst = T::from_char (src, nsrc);
207
208 const Iterator first (xsrc, xsrc, xsrc + nsrc);
209 const Iterator middle (xsrc + midnsrc, xsrc, xsrc + nsrc);
210 const Iterator last (xsrc + nsrc, xsrc, xsrc + nsrc);
211
212 const OutputIterator result (xdst, xdst, xdst + nsrc);
213
214 std::size_t last_n_op_assign = T::n_total_op_assign_;
215
216 const OutputIterator end = std::rotate_copy (first, middle, last, result);
217
218 // verify that the returned iterator is set as expected
219 bool success = end.cur_ == result.cur_ + nsrc;
220 rw_assert (success, 0, line,
221 "line %d: %s<%s, %s>(\"%s\", %zu, ...) == result + %zu, got %td",
222 __LINE__, fname, it1name, it2name, src, midnsrc,
223 nsrc, end.cur_ - xdst);
224
225 // verify that the sequence was correctly rotated
226 std::size_t i = 0;
227 std::size_t xpos = 0;
228 for ( ; i != nsrc; ++i) {
229
230 xpos = (i + (nsrc - midnsrc)) % nsrc;
231
232 typedef unsigned char UChar;
233
234 success = UChar (src [i]) == xdst [xpos].data_.val_;
235 if (!success)
236 break;
237 }
238
239 rw_assert (success, 0, line,
240 "line %d: %s<%s, %s>(\"%s\", %zu, ...) ==> "
241 "\"%{X=*.*}\"; unexpected element value %#c at %zu",
242 __LINE__, fname, it1name, it2name, src, midnsrc,
243 int (sizeof (*xsrc)), int (nsrc), int (i), xsrc,
244 xdst [xpos].data_.val_, i);
245
246 success = T::n_total_op_assign_ - last_n_op_assign == nsrc;
247 rw_assert (success, 0, line,
248 "line %d: %s<%s, %s>(\"%s\", %zu, ...); called operator=() "
249 "%zu times, %zu expected",
250 __LINE__, fname, it1name, it2name, src, midnsrc,
251 T::n_total_op_assign_ - last_n_op_assign, nsrc);
252
253 delete[] xsrc;
254 delete[] xdst;
255}
256
257
259// exercises all two function templates
260template <class Iterator1, class Iterator2, class T, class Tag>
261void test_rotate (Iterator1 it1, Iterator2 it2, const T*, Tag tag)
262{
263 static const char* const it1name = type_name (it1, (T*)0);
264 static const char* const it2name = type_name (it2, (T*)0);
265
266 if (tag.fname_inx) { // rotate_copy()
267 rw_info (0, 0, 0,
268 "std::rotate_copy (%s, %1$s, %1$s, %s)",
269 it1name, it2name);
270 }
271 else { // reverse, rotate()
272 rw_info (0, 0, 0,
273 "std::rotate (%s, %1$s, %1$s)",
274 it1name);
275 }
276
277
278#define TEST(src, middle) \
279 test_rotate (__LINE__, src, middle, it1, it2, (T*)0, tag)
280
281 TEST ("", 0);
282 TEST ("a", 0);
283 TEST ("ab", 1);
284 TEST ("abc", 1);
285 TEST ("abcd", 2);
286 TEST ("abcde", 2);
287 TEST ("abcdef", 3);
288 TEST ("abcdefg", 3);
289 TEST ("abcdefgh", 4);
290 TEST ("abcdefghi", 4);
291 TEST ("abcdefghij", 5);
292
293 TEST ("abcdefghijk", 0);
294 TEST ("abcdefghijk", 1);
295 TEST ("abcdefghijk", 2);
296 TEST ("abcdefghijk", 3);
297 TEST ("abcdefghijk", 4);
298 TEST ("abcdefghijk", 5);
299 TEST ("abcdefghijk", 6);
300 TEST ("abcdefghijk", 7);
301 TEST ("abcdefghijk", 8);
302 TEST ("abcdefghijk", 9);
303 TEST ("abcdefghijk", 10);
304}
305
306
308/* extern */ int rw_opt_no_rotate; // --no-rotate
309/* extern */ int rw_opt_no_rotate_copy; // --no-rotate_copy
310/* extern */ int rw_opt_no_output_iter; // --no-OutputIterator
311/* extern */ int rw_opt_no_fwd_iter; // --no-ForwardIterator
312/* extern */ int rw_opt_no_bidir_iter; // --no-BidirectionalIterator
313/* extern */ int rw_opt_no_rnd_iter; // --no-RandomAccessIterator
314
315
316template <class T, class Tag>
317void test_rotate (const T*, Tag tag)
318{
319 rw_info (0, 0, 0,
320 "template <class %s> std::rotate (%1$s, %1$s, %1$s)",
321 "ForwardIterator");
322
323 if (rw_opt_no_fwd_iter) {
324 rw_note (0, __FILE__, __LINE__, "ForwardIterator test disabled");
325 }
326 else {
327 test_rotate (FwdIter<T>(), NoIterator (), (T*)0, tag);
328 }
329
331 rw_note (0, __FILE__, __LINE__, "BidirectionalIterator test disabled");
332 }
333 else {
335 }
336
337 if (rw_opt_no_rnd_iter) {
338 rw_note (0, __FILE__, __LINE__, "RandomAccessIterator test disabled");
339 }
340 else {
342 }
343}
344
345
347template <class RotateIterator, class T, class Tag>
348void test_rotate_copy (RotateIterator it, const T*, Tag tag)
349{
351 rw_note (0, __FILE__, __LINE__, "OutputIterator test disabled");
352 }
353 else {
354 test_rotate (it, OutputIter<T>(0, 0, 0), (T*)0, tag);
355 }
356
357 if (rw_opt_no_fwd_iter) {
358 rw_note (0, __FILE__, __LINE__, "ForwardIterator test disabled");
359 }
360 else {
361 test_rotate (it, FwdIter<T>(), (T*)0, tag);
362 }
363
365 rw_note (0, __FILE__, __LINE__, "BidirectionalIterator test disabled");
366 }
367 else {
368 test_rotate (it, BidirIter<T>(), (T*)0, tag);
369 }
370
371 if (rw_opt_no_rnd_iter) {
372 rw_note (0, __FILE__, __LINE__, "RandomAccessIterator test disabled");
373 }
374 else {
375 test_rotate (it, RandomAccessIter<T>(), (T*)0, tag);
376 }
377}
378
379
381template <class T, class Tag>
382void test_rotate_copy(const T*, Tag tag)
383{
384 rw_info (0, 0, 0,
385 "template <class %s, class %s> %2$s "
386 "std::rotate_copy (%1$s, %1$s, %1$s, %2$s)",
387 "ForwardIterator", "OutputIterator");
388
389 if (rw_opt_no_fwd_iter) {
390 rw_note (0, __FILE__, __LINE__, "ForwardIterator test disabled");
391 }
392 else {
394 }
395
397 rw_note (0, __FILE__, __LINE__, "BidirectionalIterator test disabled");
398 }
399 else {
401 }
402
403 if (rw_opt_no_rnd_iter) {
404 rw_note (0, __FILE__, __LINE__, "RandomAccessIterator test disabled");
405 }
406 else {
408 }
409}
410
411
413static int
414run_test (int, char*[])
415{
416 const RotateTag rotate_tag = { false };
417 const RotateCopyTag rotate_copy_tag = { true };
418
419 if (rw_opt_no_rotate) {
420 rw_note (0, __FILE__, __LINE__, "std::rotate test disabled");
421 }
422 else {
423 test_rotate((UserClass*)0, rotate_tag);
424 }
425
427 rw_note (0, __FILE__, __LINE__, "std::rotate_copy test disabled");
428 }
429 else {
430 test_rotate_copy((UserClass*)0, rotate_copy_tag);
431 }
432
433 return 0;
434}
435
436
438int main (int argc, char *argv[])
439{
440 return rw_test (argc, argv, __FILE__,
441 "lib.alg.rotate",
442 0 /* no comment */, run_test,
443 "|-no-rotate# "
444 "|-no-rotate_copy# "
445 "|-no-OutputIterator# "
446 "|-no-ForwardIterator# "
447 "|-no-BidirectionalIterator# "
448 "|-no-RandomAccessIterator#",
455}
#define i
Definition 17.names.cpp:126
#define T
Definition 17.names.cpp:163
#define middle
Definition 17.names.cpp:496
#define line
Definition 17.names.cpp:490
#define last
Definition 17.names.cpp:487
#define j
Definition 17.names.cpp:127
#define tmp
Definition 17.names.cpp:553
#define OutputIterator
Definition 17.names.cpp:515
#define xpos
Definition 17.names.cpp:576
#define tag
Definition 17.names.cpp:551
volatile int result
const MyBuffer< char > nsrc[]
void run_test(const ForwardIterator &dummy, T *, Predicate *pred)
void test_rotate_copy(RotateIterator it, const T *, Tag tag)
unsigned iter_swap_calls
Definition 25.rotate.cpp:84
int rw_opt_no_rotate
int rw_opt_no_fwd_iter
void test_rotate(int line, const char *src, std::size_t midnsrc, Iterator it, NoIterator, const T *, RotateTag)
int rw_opt_no_rotate_copy
int rw_opt_no_rnd_iter
int rw_opt_no_bidir_iter
#define TEST(src, middle)
int rw_opt_no_output_iter
const char * type_name()
const int end
#define main
#define _RWSTD_NAMESPACE(name)
Definition _defs.h:567
#define _RWSTD_SPECIALIZED_FUNCTION
Definition _defs.h:556
Definition json.h:5363
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_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
unsigned char UChar
Definition collate.cpp:122