Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
25.reverse.cpp
Go to the documentation of this file.
1
29#include <algorithm> // for reverse, reverse_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
39
40// disable explicit instantiation for compilers (like MSVC)
41// that can't handle it
42#ifndef _RWSTD_NO_EXPLICIT_INSTANTIATION
43
44template
45void reverse (BidirIter<assign<base<cpy_ctor> > >,
47
48template
50reverse_copy (BidirIter<eq_comp<assign<base<> > > >,
53
54#endif // _RWSTD_NO_EXPLICIT_INSTANTIATION
55
56} // namespace std
57
58
60// tags to select reverse or reverse_copy at compile time
61struct ReverseTag {
62 enum { fname_inx = 0 };
63 int dummy;
64};
65
67 enum { fname_inx = 1 };
68 int dummy;
69};
70
71// used as a dummy template argument to test functions exercising reverse()
72// and reverse_if() (to differentiate from reverse_copy() and reverse_copy_if())
73struct NoIterator { };
74const char* type_name (NoIterator, const UserClass*)
75{
76 return 0;
77}
78
79
82
84
87{
89
90 const int tmp = (*i).data_.val_;
91
92 (*i).data_.val_ = (*j).data_.val_;
93 (*j).data_.val_ = tmp;
94}
95
98{
100
101 const int tmp = (*i).data_.val_;
102
103 (*i).data_.val_ = (*j).data_.val_;
104 (*j).data_.val_ = tmp;
105}
106
107} // namespace std
108
109
110
112// exercises std::reverse()
113template <class Iterator, class T>
115 const char *src,
116 Iterator dummy, NoIterator, const T*, ReverseTag)
117{
118 static const char* const itname = type_name (dummy, (T*)0);
119 const char* const fname = "reverse";
120
121 // compute the length of the source sequence
122 const std::size_t nsrc = std::strlen (src);
123
124 // construct a sequence of `nsrc' elements to pass to reverse
125 T* const xsrc = T::from_char (src, nsrc);
126
127 // construct iterators pointing to the beginning and end
128 // of the source sequence
129 const Iterator first = make_iter (xsrc, xsrc, xsrc + nsrc, dummy);
130 const Iterator last = make_iter (xsrc + nsrc, xsrc, xsrc + nsrc, dummy);
131
132 // zero out the iter_swap() call counter
133 iter_swap_calls = 0;
134
135 // call reverse()
136 std::reverse (first, last);
137
138 bool success = true;
139 std::size_t i = 0;
140
141 // verify that the sequence was correctly reversed and that it was
142 // done by swapping elements i.e., not simply by copying them over
143 for ( ; i != nsrc; ++i) {
144
145 typedef unsigned char UChar;
146
147 success = UChar (src [i]) == xsrc [nsrc - i - 1].data_.val_;
148 if (!success)
149 break;
150 }
151
152 rw_assert (success, 0, line,
153 "line %d: %s<%s>(\"%s\", ...) ==> "
154 "\"%{X=*.*}\"; unexpected element value %#c at offset %zu",
155 __LINE__, fname, itname, src,
156 int (sizeof (*xsrc)), int (nsrc), int (i), xsrc,
157 xsrc [nsrc - i - 1].data_.val_, i);
158
159 const std::size_t iter_swap_expect = nsrc / 2;
160 success = iter_swap_calls == iter_swap_expect;
161 rw_assert (success, 0, line,
162 "line %d: %s<%s>(\"%s\", ...); called iter_swap() "
163 "%zu times, %zu expected",
164 __LINE__, fname, itname, src,
165 iter_swap_calls, iter_swap_expect);
166
167 delete[] xsrc;
168}
169
170
172// exercises std::reverse_copy()
173template <class Iterator, class OutputIterator, class T>
175 const char *src,
177 const T*, ReverseCopyTag)
178{
179 static const char* const itname = type_name (it, (T*)0);
180 const char* const fname = "reverse_copy";
181
182 const std::size_t nsrc = std::strlen (src);
183
184 T* const xsrc = T::from_char (src, nsrc);
185 T* const xdst = T::from_char (src, nsrc);
186
187 const Iterator first (xsrc, xsrc, xsrc + nsrc);
188 const Iterator last (xsrc + nsrc, xsrc, xsrc + nsrc);
189
190 const OutputIterator result (xdst, xdst, xdst + nsrc);
191
192 std::size_t last_n_op_assign = T::n_total_op_assign_;
193
194 const OutputIterator end = std::reverse_copy (first, last, result);
195
196 // verify that the returned iterator is set as expected
197 bool success = end.cur_ == result.cur_ + nsrc;
198 rw_assert (success, 0, line,
199 "line %d: %s<%s>(\"%s\", ...) == result + %zu, got %td",
200 __LINE__, fname, itname, src, nsrc, end.cur_ - xdst);
201
202 // verify that the sequence was correctly reversed
203 std::size_t i = 0;
204 for ( ; i != nsrc; ++i) {
205
206 typedef unsigned char UChar;
207
208 success = UChar (src [i]) == xdst [nsrc - i - 1].data_.val_;
209 if (!success)
210 break;
211 }
212
213 rw_assert (success, 0, line,
214 "line %d: %s<%s>(\"%s\", ...) ==> "
215 "\"%{X=*.*}\"; unexpected element value %#c at offset %zu",
216 __LINE__, fname, itname, src,
217 int (sizeof (*xsrc)), int (nsrc), int (i), xsrc,
218 xdst [nsrc - i - 1].data_.val_, i);
219
220 success = T::n_total_op_assign_ - last_n_op_assign == nsrc;
221 rw_assert (success, 0, line,
222 "line %d: %s<%s>(\"%s\", ...); called operator=() "
223 "%zu times, %zu expected",
224 __LINE__, fname, itname, src,
225 T::n_total_op_assign_ - last_n_op_assign, nsrc);
226
227 delete[] xsrc;
228 delete[] xdst;
229}
230
231
233// exercises all four function templates
234template <class Iterator1, class Iterator2, class T, class Tag>
235void test_reverse (Iterator1 it1, Iterator2 it2, const T*, Tag tag)
236{
237 static const char* const it1name = type_name (it1, (T*)0);
238 static const char* const it2name = type_name (it2, (T*)0);
239
240 if (tag.fname_inx) { // reverse_copy()
241 rw_info (0, 0, 0, "std::reverse_copy (%s, %1$s, %s)", it1name, it2name);
242 }
243 else { // reverse()
244 rw_info (0, 0, 0, "std::reverse (%s, %1$s)", it1name);
245 }
246
247
248#define TEST(src) \
249 test_reverse (__LINE__, src, it1, it2, (T*)0, tag)
250
251 TEST ("");
252 TEST ("a");
253 TEST ("ab");
254 TEST ("abc");
255 TEST ("abcd");
256 TEST ("abcde");
257 TEST ("abcdef");
258 TEST ("abcdefg");
259 TEST ("abcdefgh");
260 TEST ("abcdefghi");
261 TEST ("abcdefghij");
262 TEST ("abcdefghijk");
263 TEST ("abcdefghijkl");
264 TEST ("abcdefghijklm");
265 TEST ("abcdefghijklmn");
266 TEST ("abcdefghijklmno");
267 TEST ("abcdefghijklmnop");
268 TEST ("abcdefghijklmnopq");
269 TEST ("abcdefghijklmnopqr");
270 TEST ("abcdefghijklmnopqrs");
271 TEST ("abcdefghijklmnopqrst");
272 TEST ("abcdefghijklmnopqrstu");
273 TEST ("abcdefghijklmnopqrstuv");
274 TEST ("abcdefghijklmnopqrstuvw");
275 TEST ("abcdefghijklmnopqrstuvwx");
276 TEST ("abcdefghijklmnopqrstuvwxy");
277 TEST ("abcdefghijklmnopqrstuvwxyz");
278}
279
280
282/* extern */ int rw_opt_no_reverse; // --no-reverse
283/* extern */ int rw_opt_no_reverse_copy; // --no-reverse_copy
284/* extern */ int rw_opt_no_output_iter; // --no-OutputIterator
285/* extern */ int rw_opt_no_fwd_iter; // --no-ForwardIterator
286/* extern */ int rw_opt_no_bidir_iter; // --no-BidirectionalIterator
287/* extern */ int rw_opt_no_rnd_iter; // --no-RandomAccessIterator
288
289
290template <class T, class Tag>
291void test_reverse(const T*, Tag tag)
292{
293 rw_info (0, 0, 0,
294 "template <class %s> %1$s std::reverse (%1$s, %1$s)",
295 "BidirectionalIterator");
296
298 rw_note (0, __FILE__, __LINE__, "BidirectionalIterator test disabled");
299 }
300 else {
302 }
303
304 if (rw_opt_no_rnd_iter) {
305 rw_note (0, __FILE__, __LINE__, "RandomAccessIterator test disabled");
306 }
307 else {
309 }
310}
311
312
314template <class ReverseIterator, class T, class Tag>
315void test_reverse_copy (ReverseIterator it, const T*, Tag tag)
316{
318 rw_note (0, __FILE__, __LINE__, "OutputIterator test disabled");
319 }
320 else {
321 test_reverse (it, OutputIter<T>(0, 0, 0), (T*)0, tag);
322 }
323
324 if (rw_opt_no_fwd_iter) {
325 rw_note (0, __FILE__, __LINE__, "ForwardIterator test disabled");
326 }
327 else {
328 test_reverse (it, FwdIter<T>(), (T*)0, tag);
329 }
330
332 rw_note (0, __FILE__, __LINE__, "BidirectionalIterator test disabled");
333 }
334 else {
335 test_reverse (it, BidirIter<T>(), (T*)0, tag);
336 }
337
338 if (rw_opt_no_rnd_iter) {
339 rw_note (0, __FILE__, __LINE__, "RandomAccessIterator test disabled");
340 }
341 else {
343 }
344}
345
346
348template <class T, class Tag>
349void test_reverse_copy (const T*, Tag tag)
350{
351 rw_info (0, 0, 0,
352 "template <class %s, class %s> %2$s "
353 "std::reverse_copy (%1$s, %1$s, %2$s)",
354 "BidirectionalIterator", "OutputIterator");
355
357 rw_note (0, __FILE__, __LINE__, "BidirectionalIterator test disabled");
358 }
359 else {
361 }
362
363 if (rw_opt_no_rnd_iter) {
364 rw_note (0, __FILE__, __LINE__, "RandomAccessIterator test disabled");
365 }
366 else {
368 }
369}
370
371
373static int
374run_test (int, char*[])
375{
376 const ReverseTag reverse_tag = { false };
377 const ReverseCopyTag reverse_copy_tag = { true };
378
379 if (rw_opt_no_reverse) {
380 rw_note (0, __FILE__, __LINE__, "std::reverse test disabled");
381 }
382 else {
383 test_reverse((UserClass*)0, reverse_tag);
384 }
385
387 rw_note (0, __FILE__, __LINE__, "std::reverse_copy test disabled");
388 }
389 else {
390 test_reverse_copy((UserClass*)0, reverse_copy_tag);
391 }
392
393 return 0;
394}
395
396
398int main (int argc, char *argv[])
399{
400 return rw_test (argc, argv, __FILE__,
401 "lib.alg.reverse",
402 0 /* no comment */, run_test,
403 "|-no-reverse# "
404 "|-no-reverse_copy# "
405 "|-no-OutputIterator# "
406 "|-no-ForwardIterator# "
407 "|-no-BidirectionalIterator# "
408 "|-no-RandomAccessIterator#",
415}
#define i
Definition 17.names.cpp:126
#define T
Definition 17.names.cpp:163
#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 tag
Definition 17.names.cpp:551
volatile int result
const MyBuffer< char > nsrc[]
void run_test(const ForwardIterator &dummy, T *, Predicate *pred)
unsigned iter_swap_calls
int rw_opt_no_fwd_iter
int rw_opt_no_rnd_iter
int rw_opt_no_reverse_copy
int rw_opt_no_bidir_iter
void test_reverse_copy(ReverseIterator it, const T *, Tag tag)
int rw_opt_no_output_iter
#define TEST(src)
void test_reverse(int line, const char *src, Iterator dummy, NoIterator, const T *, ReverseTag)
int rw_opt_no_reverse
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