Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
25.min.max.cpp
Go to the documentation of this file.
1
29#include <algorithm> // for min, max, min_element, max_element
30#include <cstring> // for strlen, 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
46min (const lt_comp<base<cpy_ctor> >&,
47 const lt_comp<base<cpy_ctor> >&);
48
49template
51min (const lt_comp<base<cpy_ctor> >&,
52 const lt_comp<base<cpy_ctor> >&,
54
55template
57max (const lt_comp<base<cpy_ctor> >&,
58 const lt_comp<base<cpy_ctor> >&);
59
60template
62max (const lt_comp<base<cpy_ctor> >&,
63 const lt_comp<base<cpy_ctor> >&,
65
66template
68min_element (FwdIter<lt_comp<base<cpy_ctor> > >,
70
71template
73min_element (FwdIter<lt_comp<base<cpy_ctor> > >,
76
77template
79max_element (FwdIter<lt_comp<base<cpy_ctor> > >,
81
82template
84max_element (FwdIter<lt_comp<base<cpy_ctor> > >,
87
88#endif // _RWSTD_NO_EXPLICIT_INSTANTIATION
89
90} // namespace std
91
92
94template <class T>
95struct Less
96{
97 static std::size_t funcalls_;
98
99 // dummy arguments provided to prevent the class from being
100 // default constructible and implicit conversion from int
101 Less (int /* dummy */, int /* dummy */) {
102 funcalls_ = 0;
103 }
104
105 // return a type other than bool but one that is implicitly
106 // convertible to bool to detect incorrect assumptions
107 conv_to_bool operator() (const T &x, const T &y) /* non-const */ {
108 ++funcalls_;
109 return conv_to_bool::make (x.data_.val_ < y.data_.val_);
110 }
111
112 static const char* name () { return "Less"; }
113
114private:
115 void operator= (Less&); // not assignable
116};
117
118template<class T> std::size_t Less<T>::funcalls_;
119
120
122// exercises min, max: 25.3.7
123template <class T, class Predicate>
125 const char a,
126 const char b,
127 const T*,
128 const Predicate *ppred,
129 bool test_min)
130{
131 const char* const tname = "UserClass";
132 const char* const fname = test_min ? "min" : "max";
133 const char* const funname = Predicate::name();
134
135 T ta, tb;
136 ta.data_.val_ = a;
137 tb.data_.val_ = b;
138
139 const int exp_id =
140 test_min ? b < a ? tb.id_ : ta.id_ : b > a ? tb.id_ : ta.id_;
141
142 const char exp_res = test_min ? b < a ? b : a : b > a ? b : a;
143
144 const Predicate pred (0, 0); // dummy arguments
145
146 const T& res = ppred ?
147 test_min ? std::min (ta, tb, pred) : std::max (ta, tb, pred)
148 : test_min ? std::min (ta, tb) : std::max (ta, tb);
149
150 // verify 25.3.7 p2, p3, p5, p6
151 rw_assert (exp_res == res.data_.val_ && exp_id == res.origin_, 0, line,
152 "line %d %s <%s%{?}, %s%{;}> (%#c, %#c) returned "
153 "value %#c, id %d; expected value %#c, id %d",
154 __LINE__, fname, tname, 0 != ppred, funname, a, b,
155 res.data_.val_, res.origin_, exp_res, exp_id);
156}
157
158
160// exrcises min_element, max_element: 25.3.7
161template <class T, class ForwardIterator, class Predicate>
163 const char *src,
164 const std::size_t min_off,
165 const std::size_t max_off,
166 const ForwardIterator &it,
167 const T*,
168 const Predicate *ppred,
169 bool test_min)
170{
171 const char* const itname = type_name (it, (T*)0);
172 const char* const fname = test_min ? "min_element" : "max_element";
173 const char* const funname = Predicate::name();
174
175 const std::size_t nsrc = std::strlen (src);
176
177 T* const xsrc = T::from_char (src, nsrc);
178 T* const xsrc_end = xsrc + nsrc;
179
180 const ForwardIterator first = make_iter (xsrc, xsrc, xsrc_end, it);
181 const ForwardIterator last = make_iter (xsrc_end, xsrc, xsrc_end, it);
182
183 Predicate pred (0, 0);
184
185 const std::size_t last_n_op_lt = T::n_total_op_lt_;
186
187 ForwardIterator res (0, 0, 0);
188
189 if (ppred) {
190 res = test_min ?
191 std::min_element (first, last, pred)
192 : std::max_element (first, last, pred);
193 }
194 else {
195 res = test_min ?
196 std::min_element (first, last)
197 : std::max_element (first, last);
198 }
199
200 // verify the returned value: 25.3.7 p7, p9
201 const std::size_t off = test_min ? min_off : max_off;
202 rw_assert (res.cur_ == xsrc + off, 0, line,
203 "line %d: %s<%s%{?}, %s%{;}> (\"%s\", %zu, ...) "
204 "got first + %td, expected first + %zu",
205 __LINE__, fname, itname, 0 != ppred, funname, src, off,
206 res.cur_ - xsrc, off);
207
208 const std::size_t n_ops_lt = ppred ?
209 Predicate::funcalls_ : T::n_total_op_lt_ - last_n_op_lt;
210
211 // verify the complexity: 25.3.7 p8, p10
212 std::size_t n_exp_ops = nsrc > 0 ? nsrc - 1 : 0;
213 rw_assert (n_ops_lt == n_exp_ops, 0, line,
214 "line %d: %s<%s%{?}, %s%{;}> (\"%s\", %zu, ...) "
215 "complexity: got %zu, expected %zu",
216 __LINE__, fname, itname, 0 != ppred, funname, src, off,
217 n_ops_lt, n_exp_ops);
218
219 delete[] xsrc;
220}
221
222
223
225template <class T, class Predicate>
226void test_min_max (const T*,
227 const Predicate *ppred,
228 bool test_min)
229{
230 const char* const tname = "UserClass";
231 const char* const fname = test_min ? "min" : "max";
232 const char* const funname = Predicate::name();
233
234 rw_info (0, 0, 0,
235 "const %s& std::%s(const %1$s&, const %1$s&%{?}, %s%{;})",
236 tname, fname, 0 != ppred, funname);
237
238#define TEST(a, b) \
239 test_min_max (__LINE__, a, b, (T*)0, ppred, test_min)
240
241 TEST ('a', 'a');
242 TEST ('a', 'b');
243 TEST ('b', 'a');
244 TEST ('b', 'b');
245
246 TEST ('a', 'e');
247 TEST ('e', 'a');
248
249#undef TEST
250}
251
252
254template <class T, class ForwardIterator, class Predicate>
256 const T*,
257 const Predicate *ppred,
258 bool test_min)
259{
260 const char* const itname = type_name (it, (T*)0);
261 const char* const fname = test_min ? "min_element" : "max_element";
262 const char* const funname = Predicate::name();
263
264 rw_info (0, 0, 0,
265 "%s std::%s(%1$s, %1$s%{?}, %s%{;})",
266 itname, fname, 0 != ppred, funname);
267
268#define TEST(src, min_off, max_off) \
269 test_min_max_element (__LINE__, src, min_off, max_off, it, \
270 (T*)0, ppred, test_min)
271
272 TEST ("", 0, 0);
273 TEST ("a", 0, 0);
274 TEST ("ab", 0, 1);
275 TEST ("aa", 0, 0);
276 TEST ("ba", 1, 0);
277
278 TEST ("abcdefghij", 0, 9);
279 TEST ("bacdefghji", 1, 8);
280 TEST ("bcadefgjhi", 2, 7);
281 TEST ("bcdaefjghi", 3, 6);
282 TEST ("bcdeajfghi", 4, 5);
283 TEST ("bcdejafghi", 5, 4);
284 TEST ("bcdjefaghi", 6, 3);
285 TEST ("bcjdefgahi", 7, 2);
286 TEST ("bjcdefghai", 8, 1);
287 TEST ("jbcdefghia", 9, 0);
288
289 TEST ("jihgfedcba", 9, 0);
290
291 TEST ("aaaaaaaaaa", 0, 0);
292 TEST ("ababababab", 0, 1);
293 TEST ("bababababa", 1, 0);
294 TEST ("aaaaabaaaa", 0, 5);
295 TEST ("bbbbbabbbb", 5, 0);
296
297#undef TEST
298}
299
300
302/* extern */ int rw_opt_no_min; // --no-min
303/* extern */ int rw_opt_no_max; // --no-max
304/* extern */ int rw_opt_no_min_element; // --no-min_element
305/* extern */ int rw_opt_no_max_element; // --no-max_element
306/* extern */ int rw_opt_no_predicate; // --no-predicate
307/* extern */ int rw_opt_no_fwd_iter; // --no-ForwardIterator
308/* extern */ int rw_opt_no_bidir_iter; // --no-BidirectionalIterator
309/* extern */ int rw_opt_no_rnd_iter; // --no-RandomAccessIterator
310
311
313template <class T, class Predicate>
315 const Predicate *ppred,
316 bool test_min)
317{
318 static const FwdIter<T> fwd_iter (0, 0, 0);
319 static const BidirIter<T> bidir_iter (0, 0, 0);
320 static const RandomAccessIter<T> rand_iter (0, 0, 0);
321
322 rw_info (0, 0, 0,
323 "template <class %s%{?}, class %s%{;}> "
324 "%1$s std::%s (%1$s, %1$s%{?}, %s%{;})",
325 "ForwardIterator", ppred, "Compare",
326 test_min ? "min_element" : "max_element", ppred, "Compare");
327
328 if (rw_opt_no_fwd_iter) {
329 rw_note (0, 0, __LINE__, "ForwardIterator test disabled");
330 }
331 else {
332 test_min_max_element (fwd_iter, (T*)0, ppred, test_min);
333 }
334
336 rw_note (0, 0, __LINE__, "BidirectionalIterator test disabled");
337 }
338 else {
339 test_min_max_element (bidir_iter, (T*)0, ppred, test_min);
340 }
341
342 if (rw_opt_no_rnd_iter) {
343 rw_note (0, 0, __LINE__, "RandomAccessIterator test disabled");
344 }
345 else {
346 test_min_max_element (rand_iter, (T*)0, ppred, test_min);
347 }
348}
349
350
352template <class T, class Predicate>
353void test_alg_min_max (const T*,
354 const Predicate *ppred)
355{
356 if (rw_opt_no_min) {
357 rw_note (0, 0, __LINE__, "std::min test disabled");
358 }
359 else {
360 test_min_max ((T*)0, ppred, true);
361 }
362
363 if (rw_opt_no_max) {
364 rw_note (0, 0, __LINE__, "std::max test disabled");
365 }
366 else {
367 test_min_max ((T*)0, ppred, false);
368 }
369
371 rw_note (0, 0, __LINE__, "std::min_element test disabled");
372 }
373 else {
374 test_min_max_element ((T*)0, ppred, true);
375 }
376
378 rw_note (0, 0, __LINE__, "std::max_element test disabled");
379 }
380 else {
381 test_min_max_element ((T*)0, ppred, false);
382 }
383}
384
385
387static int run_test (int, char*[])
388{
390
392 rw_note (0, 0, __LINE__, "std.alg.min.max predicate tests disabled");
393 }
394 else {
396 }
397
398 return 0;
399}
400
401
402
404int main (int argc, char *argv[])
405{
406 return rw_test (argc, argv, __FILE__,
407 "lib.alg.min.max",
408 0 /* no comment */, run_test,
409 "|-no-min#"
410 "|-no-max#"
411 "|-no-min_element#"
412 "|-no-max_element#"
413 "|-no-predicate#"
414 "|-no-ForwardIterator# "
415 "|-no-BidirectionalIterator# "
416 "|-no-RandomAccessIterator",
425}
#define T
Definition 17.names.cpp:163
#define y
Definition 17.names.cpp:141
#define line
Definition 17.names.cpp:490
#define res
Definition 17.names.cpp:531
#define last
Definition 17.names.cpp:487
#define x
Definition 17.names.cpp:140
#define a
Definition 17.names.cpp:109
#define off
Definition 17.names.cpp:507
#define b
Definition 17.names.cpp:110
#define ForwardIterator
Definition 17.names.cpp:469
const MyBuffer< char > nsrc[]
void run_test(const ForwardIterator &dummy, T *, Predicate *pred)
int rw_opt_no_max
int rw_opt_no_fwd_iter
#define TEST(a, b)
int rw_opt_no_rnd_iter
int rw_opt_no_bidir_iter
int rw_opt_no_predicate
int rw_opt_no_max_element
int rw_opt_no_min_element
void test_min_max(int line, const char a, const char b, const T *, const Predicate *ppred, bool test_min)
int rw_opt_no_min
void test_alg_min_max(const T *, const Predicate *ppred)
void test_min_max_element(int line, const char *src, const std::size_t min_off, const std::size_t max_off, const ForwardIterator &it, const T *, const Predicate *ppred, bool test_min)
const char * type_name()
#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
static const char * name()
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)
static conv_to_bool make(bool val)
#define min(a, b)
#define max(a, b)