Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
25.set.intersection.cpp
Go to the documentation of this file.
1
29#include <algorithm> // for set_intersection
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// disable explicit instantiation for compilers (like MSVC)
41// that can't handle it
42#ifndef _RWSTD_NO_EXPLICIT_INSTANTIATION
43
44template
46set_intersection (InputIter<lt_comp<assign<base<cpy_ctor> > > >,
51
52template
54set_intersection (InputIter<lt_comp<assign<base<cpy_ctor> > > >,
60
61#endif // _RWSTD_NO_EXPLICIT_INSTANTIATION
62
63} // namespace std
64
65
67struct Less
68{
69 static std::size_t funcalls_;
70
71 // dummy arguments provided to prevent the class from being
72 // default constructible and implicit conversion from int
73 Less (int /* dummy */, int /* dummy */) {
74 funcalls_ = 0;
75 }
76
77 // return a type other than bool but one that is implicitly
78 // convertible to bool to detect incorrect assumptions
80 const UserClass &y) /* non-const */ {
81 ++funcalls_;
82 return conv_to_bool::make (x.data_.val_ < y.data_.val_);
83 }
84
85private:
86 void operator= (Less&); // not assignable
87};
88
89std::size_t Less::funcalls_;
90
91
94{
96
97 const char* iter_names [3];
98
99 // pure virtual
100 virtual UserClass*
102 const UserClass*, UserClass*, UserClass*,
103 const Less*) const = 0;
104};
105
106template <class InputIterator1, class InputIterator2, class OutputIterator>
108{
110 iter_names [0] = type_name (InputIterator1 (0, 0, 0), (UserClass*)0);
111 iter_names [1] = type_name (InputIterator2 (0, 0, 0), (UserClass*)0);
112 iter_names [2] = type_name (OutputIterator (0, 0, 0), (UserClass*)0);
113 }
114
115 virtual UserClass*
116 set_intersection (const UserClass *xsrc1, const UserClass *xsrc1_end,
117 const UserClass *xsrc2, const UserClass *xsrc2_end,
118 UserClass *xdst, UserClass *xdst_end,
119 const Less *ppred) const {
120
121 const InputIterator1 first1 (xsrc1, xsrc1, xsrc1_end);
122 const InputIterator1 last1 (xsrc1_end, xsrc1, xsrc1_end);
123 const InputIterator2 first2 (xsrc2, xsrc2, xsrc2_end);
124 const InputIterator2 last2 (xsrc2_end, xsrc2, xsrc2_end);
125
126 const OutputIterator result (xdst, xdst, xdst_end);
127
128 const OutputIterator ret = ppred ?
129 std::set_intersection (first1, last1, first2,
130 last2, result, *ppred)
131 : std::set_intersection (first1, last1, first2,
132 last2, result);
133
134 // silence EDG eccp 3.7 and prior remark #550-D:
135 // variable was set but never used
136 _RWSTD_UNUSED (ret);
137
138 return ret.cur_;
139 }
140};
141
142
145 const char *src1,
146 std::size_t nsrc1,
147 const char *src2,
148 std::size_t nsrc2,
149 const char *res,
150 std::size_t ndst,
151 bool predicate,
152 const SetIntersectionBase &alg)
153{
154 const char* const it1name = alg.iter_names [0];
155 const char* const it2name = alg.iter_names [1];
156 const char* const outname = alg.iter_names [2];
157 const char* const fname = "set_intersection";
158 const char* const funname = predicate ? "Less" : 0;
159
160 UserClass* const xsrc1 = UserClass::from_char (src1, nsrc1,
161 true /* must be sorted */);
162 UserClass* const xsrc2 = UserClass::from_char (src2, nsrc2,
163 true /* must be sorted */);
164
165 // assert that the sequences have been successfully created
166 RW_ASSERT (0 == nsrc1 || xsrc1);
167 RW_ASSERT (0 == nsrc2 || xsrc2);
168
169 UserClass* const xdst = new UserClass [ndst];
170
171 const int max1_id = nsrc1 > 0 ? xsrc1[nsrc1 - 1].id_ : -1;
172
173 UserClass* const xsrc1_end = xsrc1 + nsrc1;
174 UserClass* const xsrc2_end = xsrc2 + nsrc2;
175 UserClass* const xdst_end = xdst + ndst;
176
177 const std::size_t last_n_op_lt = UserClass::n_total_op_lt_;
178
179 const Less pred (0, 0);
180 const Less* const ppred = predicate ? &pred : 0;
181
182 const UserClass* const xdst_res =
183 alg.set_intersection (xsrc1, xsrc1_end, xsrc2,
184 xsrc2_end, xdst, xdst_end, ppred);
185
186 // check the returned value
187 bool success = xdst_res == xdst_end;
188 rw_assert (success, 0, line,
189 "line %d: %s<%s, %s, %s%{?}, %s%{;}> (\"%s\", \"%s\", ...) "
190 "got res + %td, expected res + %zu",
191 __LINE__, fname, it1name, it2name, outname, predicate,
192 funname, src1, src2, xdst_res - xdst, ndst);
193
194 // quit here to avoid the running out of the array boundaries
195 if (!success) {
196 delete[] xsrc1;
197 delete[] xsrc2;
198 delete[] xdst;
199 return;
200 }
201
202 const std::size_t n_ops_lt = ppred ?
204
205 // check the algorithm correctness
206 std::size_t i = 0;
207 std::size_t n1 = 0;
208 std::size_t n2 = 0;
209 for ( ; i < ndst; i++) {
210 xdst[i].origin_ <= max1_id ? n1++ : n2++;
211 success = xdst[i].data_.val_ == res[i];
212 if (!success)
213 break;
214 }
215
216 // to avoid errors in --trace mode
217 i = i < ndst ? i : ndst - 1;
218
219 static const int cwidth = sizeof (*xdst);
220
221 rw_assert (success, 0, line,
222 "line %d: %s<%s, %s, %s%{?}, %s%{;}> (\"%s\", \"%s\", ...) "
223 " ==> \"%{X=*.*}\", expected \"%s\"",
224 __LINE__, fname, it1name, it2name, outname, predicate,
225 funname, src1, src2, cwidth, int (ndst), i, xdst, res);
226
227 // check that the operation is stable : for two equal elements
228 // one from the first sequence should be taken
229 success = n2 == 0;
230 rw_assert (success, 0, line,
231 "line %d: %s<%s, %s, %s%{?}, %s%{;}> (\"%s\", \"%s\", ...) "
232 " ==> \"%{X=*.*}\" got %zu elements from first sequence and "
233 "%zu from second, expected %zu from first and 0 from second",
234 __LINE__, fname, it1name, it2name, outname, predicate, funname,
235 src1, src2, cwidth, int (ndst), -1, xdst, n1, n2, ndst);
236
237 // check the complexity
238 const std::size_t n_exp_ops =
239 nsrc1 + nsrc2 > 0 ? 2 * (nsrc1 + nsrc2) - 1 : 0;
240
241 rw_assert (n_ops_lt <= n_exp_ops, 0, line,
242 "line %d: %s<%s, %s, %s%{?}, %s%{;}> (\"%s\", \"%s\", ...) "
243 "complexity: got %zu, expected no more than %zu",
244 __LINE__, fname, it1name, it2name, outname, predicate, funname,
245 src1, src2, n_ops_lt, n_exp_ops);
246
247 delete[] xsrc1;
248 delete[] xsrc2;
249 delete[] xdst;
250}
251
252
255 bool predicate)
256{
257 const char* const it1name = alg.iter_names [0];
258 const char* const it2name = alg.iter_names [1];
259 const char* const outname = alg.iter_names [2];
260 const char* const fname = "set_intersection";
261 const char* const funname = predicate ? "Less" : 0;
262
263 rw_info (0, 0, 0,
264 "%s std::%s(%s, %3$s, %s, %4$s, %1$s%{?}, %s%{;})",
265 outname, fname, it1name, it2name, predicate, funname);
266
267#define TEST(src1, src2, res) \
268 test_set_intersection (__LINE__, src1, sizeof src1 - 1, \
269 src2, sizeof src2 - 1, \
270 res, sizeof res - 1, \
271 predicate, alg)
272
273 TEST ("a", "", "");
274 TEST ("abcde", "", "");
275
276 TEST ("", "a", "");
277 TEST ("", "abcde", "");
278
279 TEST ("a", "b", "");
280 TEST ("b", "a", "");
281
282 TEST ("aa", "aa", "aa");
283 TEST ("ab", "ab", "ab");
284
285 TEST ("aa", "ab", "a");
286 TEST ("ab", "bb", "b");
287 TEST ("aa", "bb", "");
288 TEST ("ac", "bb", "");
289
290 TEST ("ace", "bdf", "");
291 TEST ("acf", "bdf", "f");
292 TEST ("ade", "bdf", "d");
293 TEST ("bce", "bdf", "b");
294
295 TEST ("aacee", "aacee", "aacee");
296 TEST ("aacee", "aaace", "aace");
297 TEST ("aacee", "aaaae", "aae");
298 TEST ("aacee", "aaaaa", "aa");
299 TEST ("aaaae", "aacee", "aae");
300 TEST ("aaaaa", "aacee", "aa");
301 TEST ("aacee", "aaabd", "aa");
302 TEST ("aaabd", "aacee", "aa");
303 TEST ("aacee", "aabee", "aaee");
304}
305
306
308/* extern */ int rw_opt_no_predicate; // --no-predicate
309/* extern */ int rw_opt_no_input_iter; // --no-InputIterator
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
317template <class InputIterator1, class InputIterator2, class OutputIterator>
318void gen_set_intersection_test (const InputIterator1&,
319 const InputIterator2&,
320 const OutputIterator&,
321 bool predicate)
322{
324
326}
327
328
330template <class InputIterator1, class InputIterator2>
331void gen_set_intersection_test (const InputIterator1 &it1,
332 const InputIterator2 &it2,
333 bool predicate)
334{
335 if (0 == rw_opt_no_output_iter)
337 it1, it2, OutputIter<UserClass>(0, 0, 0), predicate);
338 if (0 == rw_opt_no_fwd_iter)
340 it1, it2, FwdIter<UserClass>(0, 0, 0), predicate);
341 if (0 == rw_opt_no_bidir_iter)
343 it1, it2, BidirIter<UserClass>(0, 0, 0), predicate);
344 if (0 == rw_opt_no_rnd_iter)
346 it1, it2, RandomAccessIter<UserClass>(0, 0, 0), predicate);
347}
348
349template <class InputIterator1>
350void gen_set_intersection_test (const InputIterator1 &it1,
351 bool predicate)
352{
353 if (0 == rw_opt_no_input_iter)
355 it1, InputIter<UserClass>(0, 0, 0), predicate);
356 if (0 == rw_opt_no_fwd_iter)
358 it1, ConstFwdIter<UserClass>(0, 0, 0), predicate);
359 if (0 == rw_opt_no_bidir_iter)
361 it1, ConstBidirIter<UserClass>(0, 0, 0), predicate);
362 if (0 == rw_opt_no_rnd_iter)
365}
366
367// generates a specialization of the set_intersection test for each of
368// the required iterator categopries
369static void
371{
372 rw_info (0, 0, 0,
373 "template <class %s, class %s, class %s%{?}, class %s%{;}> %3$s "
374 "set_intersection(%1$s, %1$s, %2$s, %2$s, %3$s%{?}, %s%{;})",
375 "InputIterator1", "InputIterator2", "OutputIterator",
376 predicate, "Compare", predicate, "Compare");
377
379 rw_note (0, 0, 0, "OutputIterator test disabled");
380
382 rw_note (0, 0, 0, "InputIterator test disabled");
383 else
385
387 rw_note (0, 0, 0, "ForwardIterator test disabled");
388 else
390
392 rw_note (0, 0, 0, "BidirectionalIterator test disabled");
393 else
395 predicate);
396
398 rw_note (0, 0, 0, "RandomAccessIterator test disabled");
399 else
402}
403
404
406static int
407run_test (int, char*[])
408{
410 rw_note (0, 0, 0, "predicate test disabled");
411
412 const int niters = rw_opt_no_predicate ? 1 : 2;
413
415 for (int i = 0; i != niters; ++i) {
417 }
418
419 return 0;
420}
421
422
424int main (int argc, char *argv[])
425{
426 return rw_test (argc, argv, __FILE__,
427 "lib.set.intersection",
428 0 /* no comment */,
429 run_test,
430 "|-no-predicate#"
431 "|-no-InputIterator# "
432 "|-no-OutputIterator# "
433 "|-no-ForwardIterator# "
434 "|-no-BidirectionalIterator# "
435 "|-no-RandomAccessIterator#",
442}
#define i
Definition 17.names.cpp:126
#define y
Definition 17.names.cpp:141
#define line
Definition 17.names.cpp:490
#define res
Definition 17.names.cpp:531
#define n2
Definition 17.names.cpp:263
#define x
Definition 17.names.cpp:140
#define n1
Definition 17.names.cpp:237
#define OutputIterator
Definition 17.names.cpp:515
volatile int result
void run_test(const ForwardIterator &dummy, T *, Predicate *pred)
void gen_set_intersection_test(const InputIterator1 &, const InputIterator2 &, const OutputIterator &, bool predicate)
void test_set_intersection(int line, const char *src1, std::size_t nsrc1, const char *src2, std::size_t nsrc2, const char *res, std::size_t ndst, bool predicate, const SetIntersectionBase &alg)
int rw_opt_no_fwd_iter
#define TEST(src1, src2, res)
int rw_opt_no_rnd_iter
int rw_opt_no_bidir_iter
int rw_opt_no_input_iter
int rw_opt_no_predicate
int rw_opt_no_output_iter
const char * type_name()
#define main
#define _RWSTD_UNUSED(arg)
Definition _defs.h:972
#define _RWSTD_NAMESPACE(name)
Definition _defs.h:567
Definition json.h:5363
_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
#define RW_ASSERT(expr)
conv_to_bool operator()(const T &x, const T &y)
Definition 25.heap.cpp:114
static std::size_t funcalls_
Definition 25.heap.cpp:104
Less(int, int)
virtual UserClass * set_intersection(const UserClass *, const UserClass *, const UserClass *, const UserClass *, UserClass *, UserClass *, const Less *) const =0
virtual UserClass * set_intersection(const UserClass *xsrc1, const UserClass *xsrc1_end, const UserClass *xsrc2, const UserClass *xsrc2_end, UserClass *xdst, UserClass *xdst_end, const Less *ppred) const
int origin_
Definition rw_value.h:82
const int id_
Definition rw_value.h:81
static UserClass from_char(char c)
Definition rw_value.h:221
UserData data_
Definition rw_value.h:79
static _RWSTD_SIZE_T n_total_op_lt_
Definition rw_value.h:133
int val_
Definition rw_value.h:39
static conv_to_bool make(bool val)