Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
25.lex.comparison.cpp
Go to the documentation of this file.
1
29#include <algorithm> // for lexicographical_compare
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#ifndef _RWSTD_NO_EXPLICIT_INSTANTIATION
41
42// explicitly instantiate on types with minimum features
43// to verify that the algorithm imposes no requirements
44// beyond those specified
45template
46bool lexicographical_compare (InputIter<lt_comp<base<> > >,
50template
51bool lexicographical_compare (InputIter<base<> >,
56
57#endif // _RWSTD_NO_EXPLICIT_INSTANTIATION
58
59} // namespace std
60
61
63template <class T>
64struct Less
65{
66 static std::size_t funcalls_;
67
68 // dummy arguments provided to prevent the class from being
69 // default constructible and implicit conversion from int
70 Less (int /* dummy */, int /* dummy */) {
71 funcalls_ = 0;
72 }
73
74 // return a type other than bool but one that is implicitly
75 // convertible to bool to detect incorrect assumptions
76 conv_to_bool operator() (const T &x, const T &y) /* non-const */ {
77 ++funcalls_;
78 return conv_to_bool::make (x.data_.val_ < y.data_.val_);
79 }
80
81 static const char* name () { return "Less"; }
82
83private:
84 void operator= (Less&); // not assignable
85};
86
87template<class T> std::size_t Less<T>::funcalls_;
88
89
91// exercise lexicographical_compare 25.3.8
92template
93<class T, class InputIterator1, class InputIterator2, class Predicate>
95 const char *src1,
96 const char *src2,
97 bool res,
98 const InputIterator1 &it1,
99 const InputIterator2 &it2,
100 const T*,
101 const Predicate *ppred)
102{
103 const char* const it1name = type_name (it1, (T*)0);
104 const char* const it2name = type_name (it2, (T*)0);
105 const char* const fname = "lexicographical_compare";
106 const char* const funname = Predicate::name ();
107
108 const std::size_t nsrc1 = std::strlen (src1);
109 const std::size_t nsrc2 = std::strlen (src2);
110
111 T* const xsrc1 = T::from_char (src1, nsrc1);
112 T* const xsrc2 = T::from_char (src2, nsrc2);
113
114 T* const xsrc1_end = xsrc1 + nsrc1;
115 T* const xsrc2_end = xsrc2 + nsrc2;
116
117 const InputIterator1 first1 = make_iter (xsrc1, xsrc1, xsrc1_end, it1);
118 const InputIterator1 last1 = make_iter (xsrc1_end, xsrc1, xsrc1_end, it1);
119 const InputIterator2 first2 = make_iter (xsrc2, xsrc2, xsrc2_end, it2);
120 const InputIterator2 last2 = make_iter (xsrc2_end, xsrc2, xsrc2_end, it2);
121
122 const Predicate pred (0, 0);
123
124 const std::size_t last_n_op_lt = T::n_total_op_lt_;
125
126 const bool result = ppred ?
127 std::lexicographical_compare (first1, last1, first2, last2, pred)
128 : std::lexicographical_compare (first1, last1, first2, last2);
129
130 // verify the returned value 25.3.8, p1 and p3: If two sequences have
131 // the same number of elements and their corresponding elements are
132 // equivalent, then neither sequence is lexicographically less than
133 // the other.
134 rw_assert (res == result, 0, line,
135 "line %d: %s<%s, %s%{?}, %s%{;}> (\"%s\", \"%s\", ...) "
136 "== %b, got %b",
137 __LINE__, fname, it1name, it2name, 0 != ppred, funname,
138 src1, src2, res, result);
139
140 const std::size_t n_ops_lt = ppred ?
141 Predicate::funcalls_ : T::n_total_op_lt_ - last_n_op_lt;
142
143 // verify the complexity 25.3.8, p2
144 const std::size_t n_exp_ops = 2 * (nsrc1 < nsrc2 ? nsrc1 : nsrc2);
145 rw_assert (n_ops_lt <= n_exp_ops, 0, line,
146 "line %d: %s<%s, %s%{?}, %s%{;}> (\"%s\", \"%s\", ...) "
147 "complexity: got %zu, expected no more than %zu",
148 __LINE__, fname, it1name, it2name, 0 != ppred, funname,
149 src1, src2, n_ops_lt, n_exp_ops);
150
151 delete[] xsrc1;
152 delete[] xsrc2;
153}
154
155template
156<class T, class InputIterator1, class InputIterator2, class Predicate>
157void test_lex_compare (const InputIterator1 &it1,
158 const InputIterator2 &it2,
159 const T*,
160 const Predicate *ppred)
161{
162 const char* const it1name = type_name (it1, (T*)0);
163 const char* const it2name = type_name (it2, (T*)0);
164 const char* const fname = "lexicographical_compare";
165 const char* const funname = Predicate::name();
166
167 rw_info (0, 0, 0,
168 "std::%s(%s, %2$s, %s, %3$s%{?}, %s%{;})",
169 fname, it1name, it2name, 0 != ppred, funname);
170
171#define TEST(src1, src2, res) \
172 test_lex_compare (__LINE__, src1, src2, res, it1, it2, (T*)0, ppred)
173
174 TEST ("", "", false);
175 TEST ("a", "", false);
176 TEST ("", "a", true);
177 TEST ("a", "a", false);
178
179 TEST ("aa", "aa", false);
180 TEST ("aa", "ab", true);
181 TEST ("ba", "ab", false);
182 TEST ("ba", "ba", false);
183 TEST ("ba", "bc", true);
184
185 TEST ("a", "abc", true);
186 TEST ("a", "bcd", true);
187 TEST ("a", "baed", true);
188
189 TEST ("abcde", "abcdefghij", true);
190 TEST ("fghij", "fghijabcde", true);
191 TEST ("fghij", "abcdefghij", false);
192 TEST ("cabed", "abcdeabcde", false);
193
194 TEST ("abcdefghij", "abcdefghij", false);
195 TEST ("fghijfghij", "abcdefghij", false);
196 TEST ("fghijabcde", "abcdeabcde", false);
197
198 TEST ("abcdefghij", "bacdfeghji", true);
199 TEST ("bacdefghij", "bacdfeghji", true);
200 TEST ("bacdfeghij", "bacdfeghji", true);
201 TEST ("bacdfeghja", "bacdfeghji", true);
202}
203
204
206/* extern */ int rw_opt_no_predicate; // --no-predicate
207/* extern */ int rw_opt_no_input_iter; // --no-InputIterator
208/* extern */ int rw_opt_no_fwd_iter; // --no-ForwardIterator
209/* extern */ int rw_opt_no_bidir_iter; // --no-BidirectionalIterator
210/* extern */ int rw_opt_no_rnd_iter; // --no-RandomAccessIterator
211
212
214template <class T, class InputIterator1, class Predicate>
215void test_lex_compare (const InputIterator1 &it1,
216 const T*,
217 const Predicate *ppred)
218{
219 static const InputIter<T> input_iter (0, 0, 0);
220 static const FwdIter<T> fwd_iter (0, 0, 0);
221 static const BidirIter<T> bidir_iter (0, 0, 0);
222 static const RandomAccessIter<T> rand_iter (0, 0, 0);
223
225 rw_note (0, __FILE__, __LINE__, "InputIterator test disabled");
226 }
227 else {
228 test_lex_compare (it1, input_iter, (T*)0, ppred);
229 }
230
231 if (rw_opt_no_fwd_iter) {
232 rw_note (0, __FILE__, __LINE__, "ForwardIterator test disabled");
233 }
234 else {
235 test_lex_compare (it1, fwd_iter, (T*)0, ppred);
236 }
237
239 rw_note (0, __FILE__, __LINE__, "BidirectionalIterator test disabled");
240 }
241 else {
242 test_lex_compare (it1, bidir_iter, (T*)0, ppred);
243 }
244
245 if (rw_opt_no_rnd_iter) {
246 rw_note (0, __FILE__, __LINE__, "RandomAccessIterator test disabled");
247 }
248 else {
249 test_lex_compare (it1, rand_iter, (T*)0, ppred);
250 }
251}
252
253template <class T, class Predicate>
254void test_lex_compare (const T*,
255 const Predicate *ppred)
256{
257 static const InputIter<T> input_iter (0, 0, 0);
258 static const FwdIter<T> fwd_iter (0, 0, 0);
259 static const BidirIter<T> bidir_iter (0, 0, 0);
260 static const RandomAccessIter<T> rand_iter (0, 0, 0);
261
262 rw_info (0, 0, 0,
263 "template <class %s, class %s%{?}, class %s%{;}> "
264 "bool std::lexicographical_compare (%1$s, %1$s, %2$s, "
265 "%2$s%{?}, %s%{;})",
266 "InputIterator1", "InputIterator2", ppred, "Compare",
267 0 != ppred, "Compare");
268
270 rw_note (0, __FILE__, __LINE__, "InputIterator test disabled");
271 }
272 else {
273 test_lex_compare (input_iter, (T*)0, ppred);
274 }
275
276 if (rw_opt_no_fwd_iter) {
277 rw_note (0, __FILE__, __LINE__, "ForwardIterator test disabled");
278 }
279 else {
280 test_lex_compare (fwd_iter, (T*)0, ppred);
281 }
282
284 rw_note (0, __FILE__, __LINE__, "BidirectionalIterator test disabled");
285 }
286 else {
287 test_lex_compare (bidir_iter, (T*)0, ppred);
288 }
289
290 if (rw_opt_no_rnd_iter) {
291 rw_note (0, __FILE__, __LINE__, "RandomAccessIterator test disabled");
292 }
293 else {
294 test_lex_compare (rand_iter, (T*)0, ppred);
295 }
296}
297
298
300static int run_test (int, char*[])
301{
303
305 rw_note (0, __FILE__, __LINE__,
306 "std::lexicographical_compare predicate test disabled");
307 }
308 else {
310 }
311
312 return 0;
313}
314
315
316
318int main (int argc, char *argv[])
319{
320 return rw_test (argc, argv, __FILE__,
321 "lib.lex.comparison",
322 0 /* no comment */,
323 run_test,
324 "|-no-predicate#"
325 "|-no-InputIterator# "
326 "|-no-ForwardIterator# "
327 "|-no-BidirectionalIterator# "
328 "|-no-RandomAccessIterator#",
334}
#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 x
Definition 17.names.cpp:140
volatile int result
void run_test(const ForwardIterator &dummy, T *, Predicate *pred)
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
void test_lex_compare(int line, const char *src1, const char *src2, bool res, const InputIterator1 &it1, const InputIterator2 &it2, const T *, const Predicate *ppred)
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()
Less(int, int)
static conv_to_bool make(bool val)