Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
25.unique.cpp
Go to the documentation of this file.
1
29#include <algorithm> // for unique, unique_copy
30#include <cstring> // for strlen
31
32#include <rw_alg_test.h> // for BinaryPredicate
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
42// also exercise LWG issue 241:
43// http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#241
44
45template
47unique (FwdIter<eq_comp<assign<base<> > > >,
49
50template
52unique (FwdIter<eq_comp<assign<base<> > > >,
55
56template
58unique_copy (InputIter<eq_comp<assign<base<cpy_ctor> > > >,
61
62template
64unique_copy (InputIter<eq_comp<assign<base<cpy_ctor> > > >,
68
69#endif // _RWSTD_NO_EXPLICIT_INSTANTIATION
70
71} // namespace std
72
73
75// exercises std::unique and std::unique_copy()
76template <class FwdIterator, class FwdCopyIterator,
77 class OutIterator, class T, class Predicate>
78void test_unique (int line,
79 const char *src,
80 const char *dst,
81 const FwdIterator &it,
82 const FwdCopyIterator &itc,
83 const OutIterator &out,
84 const T*,
85 const Predicate *ppred,
86 bool use_copy)
87{
88 const char* const outname = type_name (out, (T*)0);
89 const char* const itname =
90 use_copy ? type_name (itc, (T*)0) : type_name (it, (T*)0);
91 const char* const fname =
92 use_copy ? "unique_copy" : "unique";
93 const char* const funname =
94 ppred ? "BinaryPredicate" : "operator==()";
95
96 const std::size_t nsrc = std::strlen (src);
97 const std::size_t ndst = std::strlen (dst);
98
99 T* const xsrc = T::from_char (src, nsrc);
100 T* xdst = use_copy ? T::from_char (dst, ndst) : xsrc;
101
102 T* const xsrc_end = xsrc + nsrc;
103 T* const xdst_end = xdst + ndst;
104
105 const FwdIterator first = make_iter (xsrc, xsrc, xsrc_end, it);
106 const FwdIterator last = make_iter (xsrc_end, xsrc, xsrc_end, it);
107
108 const FwdCopyIterator first_c = make_iter (xsrc, xsrc, xsrc_end, itc);
109 const FwdCopyIterator last_c = make_iter (xsrc_end, xsrc, xsrc_end, itc);
110
111 const OutIterator result = make_iter (xdst, xdst, xdst_end, out);
112
113 // compute the actual number of invocations of operator==() or predicate
114 std::size_t n_total_ops =
115 ppred ? Predicate::n_total_op_fcall_ : T::n_total_op_eq_;
116
117 OutIterator res_c (0, 0, 0);
118 FwdIterator res (0, 0, 0);
119
120 if (use_copy)
121 res_c = ppred ?
122 std::unique_copy (first_c, last_c, result, *ppred)
123 : std::unique_copy (first_c, last_c, result);
124 else
125 res = ppred ?
126 std::unique (first, last, *ppred)
127 : std::unique (first, last);
128
129 const T* const f_cur = use_copy ? result.cur_ : first.cur_;
130 const T* const r_cur = use_copy ? res_c.cur_ : res.cur_;
131
132 bool success = r_cur == f_cur + ndst;
133 rw_assert (success, 0, line,
134 "line %d: std::%s <%s%{?}, %s%{;}%{?}, %s%{;}>(\"%s\", ...) "
135 "== (res + %zu), got (res + %td)",
136 __LINE__, fname, itname, use_copy, outname, 0 != ppred,
137 funname, src, ndst, r_cur - f_cur);
138
139 // verify that the copied sequence matches the expected range
140 const T* const mismatch = T::mismatch (xdst, dst, ndst);
141
142 rw_assert (0 == mismatch, 0, line,
143 "line %d: std::%s <%s%{?}, %s%{;}%{?}, %s%{;}>(\"%s\", ...) "
144 "==> \"%s\", got \"%{X=*.@}\"", __LINE__, fname, itname,
145 use_copy, outname, 0 != ppred, funname, src, dst,
146 int (sizeof (*xdst)), int (ndst), mismatch, xdst);
147
148 if (ppred)
149 n_total_ops = ppred->n_total_op_fcall_ - n_total_ops;
150 else
151 n_total_ops = T::n_total_op_eq_ - n_total_ops;
152
153 // compute the expected number of invocations of operator==() or predicate
154 const std::size_t n_expect_ops = nsrc ? nsrc - 1 : 0;
155
156 // verify the number of applications of operator==() or predicate
157 rw_assert (n_total_ops <= n_expect_ops, 0, line,
158 "line %d: std::%s <%s%{?}, %s%{;}%{?}, %s%{;}>(\"%s\", ...) "
159 "%s called %zu times, %zu expected",
160 __LINE__, fname, itname, use_copy, outname, 0 != ppred,
161 funname, src, funname, n_total_ops, n_expect_ops);
162}
163
164
166template <class FwdIterator, class FwdCopyIterator,
167 class OutIterator, class T, class Predicate>
168void test_unique (const FwdIterator &it,
169 const FwdCopyIterator &itc,
170 const OutIterator &out,
171 const T*,
172 const Predicate *ppred,
173 bool use_copy)
174{
175 const char* const outname = type_name (out, (T*)0);
176 const char* const itname = use_copy ?
177 type_name (itc, (T*)0) : type_name (it, (T*)0);
178 const char* const fname = use_copy ? "unique_copy" : "unique";
179 const char* const funname = ppred ? "BinaryPredicate" : "operator==()";
180
181 rw_info (0, 0, 0,
182 "std::%s (%s, %2$s%{?}, %s%{;}%{?}, %s%{;})",
183 fname, itname, use_copy, outname, ppred, funname);
184
185#define TEST(src, dst) \
186 test_unique (__LINE__, src, dst, it, itc, out, (T*)0, \
187 ppred, use_copy)
188
189 // +---------------- source sequence
190 // | +- destination sequence
191 // | |
192 // v v
193 TEST ("", "");
194 TEST ("a", "a");
195 TEST ("ab", "ab");
196 TEST ("abc", "abc");
197 TEST ("abcd", "abcd");
198 TEST ("abcde", "abcde");
199 TEST ("abcdef", "abcdef");
200 TEST ("abcdefg", "abcdefg");
201 TEST ("abcdefgh", "abcdefgh");
202 TEST ("abcdefghi", "abcdefghi");
203 TEST ("abcdefghij", "abcdefghij");
204 TEST ("abcdefghijk", "abcdefghijk");
205
206 TEST ("abcabc", "abcabc");
207 TEST ("abcabcabc", "abcabcabc");
208 TEST ("abcdabcd", "abcdabcd");
209 TEST ("abcdabcdabcd","abcdabcdabcd");
210
211 TEST ("aa", "a");
212 TEST ("aaa", "a");
213 TEST ("aab", "ab");
214 TEST ("aaa", "a");
215 TEST ("aaaa", "a");
216 TEST ("aaabb", "ab");
217 TEST ("aaabbb", "ab");
218 TEST ("abba", "aba");
219 TEST ("abbba", "aba");
220 TEST ("aaabbba", "aba");
221 TEST ("aaabbbaa", "aba");
222 TEST ("aaabbbaaa", "aba");
223 TEST ("aaabbbaaab", "abab");
224 TEST ("aaabbbaaabb", "abab");
225 TEST ("abbbbbaaabb", "abab");
226 TEST ("abaaaaaaabb", "abab");
227 TEST ("ababbbbbbbb", "abab");
228}
229
230
232/* extern */ int rw_opt_no_unique; // --no-unique
233/* extern */ int rw_opt_no_unique_copy; // --no-unique_copy
234/* extern */ int rw_opt_no_predicate; // --no-predicate
235/* extern */ int rw_opt_no_input_iter; // --no-InputIterator
236/* extern */ int rw_opt_no_output_iter; // --no-OutputIterator
237/* extern */ int rw_opt_no_fwd_iter; // --no-ForwardIterator
238/* extern */ int rw_opt_no_bidir_iter; // --no-BidirectionalIterator
239/* extern */ int rw_opt_no_rnd_iter; // --no-RandomAccessIterator
240
241
242template <class T, class Predicate, class FwdIterator>
243void test_unique (const FwdIterator &it,
244 const T*,
245 const Predicate *ppred)
246{
247 static const InputIter<T> input_iter (0, 0, 0);
248 static const OutputIter<T> output_iter (0, 0, 0);
249 static const FwdIter<T> fwd_iter (0, 0, 0);
250 static const BidirIter<T> bidir_iter (0, 0, 0);
251 static const RandomAccessIter<T> rand_iter (0, 0, 0);
252
253 if (rw_opt_no_fwd_iter) {
254 rw_note (0, __FILE__, __LINE__, "ForwardIterator test disabled");
255 }
256 else {
257 test_unique (fwd_iter, it, fwd_iter, (T*)0, ppred, true);
258 }
259
261 rw_note (0, __FILE__, __LINE__, "BidirectionalIterator test disabled");
262 }
263 else {
264 test_unique (bidir_iter, it, bidir_iter, (T*)0, ppred, true);
265 }
266
267 if (rw_opt_no_rnd_iter) {
268 rw_note (0, __FILE__, __LINE__, "RandomAccessIterator test disabled");
269 }
270 else {
271 test_unique (rand_iter, it, rand_iter, (T*)0, ppred, true);
272 }
273
275 rw_note (0, __FILE__, __LINE__, "OutputIterator test disabled");
276 }
277 else {
278 test_unique (fwd_iter, it, output_iter, (T*)0, ppred, true);
279 }
280}
281
282
284template <class T, class Predicate>
285void test_unique (const T*,
286 const Predicate *ppred,
287 bool use_copy)
288{
289 static const InputIter<T> input_iter (0, 0, 0);
290 static const FwdIter<T> fwd_iter (0, 0, 0);
291 static const BidirIter<T> bidir_iter (0, 0, 0);
292 static const RandomAccessIter<T> rand_iter (0, 0, 0);
293
294 rw_info (0, 0, 0,
295 "template <class %s%{?}, class %s%{;}%{?}, class %s%{;}> "
296 "%s std::%s (%1$s, %1$s%{?}, %3$s%{;}%{?}, %5$s%{;})",
297 use_copy ? "InputIterator" : "ForwardIterator",
298 use_copy, "OutputIterator", 0 != ppred, "Predicate",
299 use_copy ? "OutputIterator" : "ForwardIterator",
300 use_copy ? "unique_copy" : "unique", use_copy, 0 != ppred);
301
302 if (use_copy)
303 {
305 rw_note (0, __FILE__, __LINE__, "InputIterator test disabled");
306 }
307 else {
308 test_unique (input_iter, (T*)0, ppred);
309 }
310 }
311
312 if (rw_opt_no_fwd_iter) {
313 rw_note (0, __FILE__, __LINE__, "ForwardIterator test disabled");
314 }
315 else {
316 if (use_copy)
317 test_unique (fwd_iter, (T*)0, ppred);
318 else
319 test_unique (fwd_iter, fwd_iter, fwd_iter, (T*)0, ppred, false);
320 }
321
323 rw_note (0, __FILE__, __LINE__, "BidirectionalIterator test disabled");
324 }
325 else {
326 if (use_copy)
327 test_unique (bidir_iter, (T*)0, ppred);
328 else
329 test_unique (bidir_iter, bidir_iter, bidir_iter,
330 (T*)0, ppred, false);
331 }
332
333 if (rw_opt_no_rnd_iter) {
334 rw_note (0, __FILE__, __LINE__, "RandomAccessIterator test disabled");
335 }
336 else {
337 if (use_copy)
338 test_unique (rand_iter, (T*)0, ppred);
339 else
340 test_unique (rand_iter, rand_iter, rand_iter,
341 (T*)0, ppred, false);
342 }
343}
344
345
347static int
348run_test (int, char*[])
349{
350 const BinaryPredicate pred (BinaryPredicate::op_equals);
351
352 if (rw_opt_no_unique) {
353 rw_note (0, __FILE__, __LINE__, "std::unique test disabled");
354 }
355 else {
356 test_unique ((UserClass*)0, (BinaryPredicate*)0, false);
357
359 rw_note (0, __FILE__, __LINE__,
360 "std::unique predicate test disabled");
361 }
362 else {
363 test_unique ((UserClass*)0, &pred, false);
364 }
365 }
366
368 rw_note (0, __FILE__, __LINE__, "std::unique_copy test disabled");
369 }
370 else {
371 test_unique ((UserClass*) 0, (BinaryPredicate*)0, true);
372
374 rw_note (0, __FILE__, __LINE__,
375 "std::unique_copy predicate test disabled");
376 }
377 else {
378 test_unique ((UserClass*)0, &pred, true);
379 }
380 }
381
382 return 0;
383}
384
385
387int main (int argc, char *argv[])
388{
389 return rw_test (argc, argv, __FILE__,
390 "lib.alg.unique",
391 0 /* no comment */, run_test,
392 "|-no-unique# "
393 "|-no-unique_copy# "
394 "|-no-InputIterator# "
395 "|-no-OutputIterator# "
396 "|-no-ForwardIterator# "
397 "|-no-BidirectionalIterator# "
398 "|-no-RandomAccessIterator# "
399 "|-no-predicate",
408}
#define T
Definition 17.names.cpp:163
#define line
Definition 17.names.cpp:490
#define res
Definition 17.names.cpp:531
#define last
Definition 17.names.cpp:487
volatile int result
const MyBuffer< char > nsrc[]
void run_test(const ForwardIterator &dummy, T *, Predicate *pred)
int rw_opt_no_fwd_iter
void test_unique(int line, const char *src, const char *dst, const FwdIterator &it, const FwdCopyIterator &itc, const OutIterator &out, const T *, const Predicate *ppred, bool use_copy)
Definition 25.unique.cpp:78
int rw_opt_no_rnd_iter
#define TEST(src, dst)
int rw_opt_no_bidir_iter
int rw_opt_no_input_iter
int rw_opt_no_predicate
int rw_opt_no_unique_copy
int rw_opt_no_output_iter
int rw_opt_no_unique
const char * type_name()
const int out
#define main
#define _RWSTD_NAMESPACE(name)
Definition _defs.h:567
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