Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
25.adjacent.find.cpp
Go to the documentation of this file.
1
29#include <algorithm> // for adjacent_find()
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>
35
36
38// used to initialize an array of objects of type UserClass
39static const char *xinit_begin;
40
41int xinit ()
42{
43 typedef unsigned char UChar;
44
45 static const char *cur = 0;
46
47 if (!cur || !*cur)
48 cur = xinit_begin;
49
50 return UChar (*cur++);
51}
52
53
55template <class T, class U>
57{
58 static std::size_t funcalls_;
59
60 // dummy arguments provided to prevent the class
61 // from being default constructible
62 EqualityPredicate (T* /* dummy */, U* /* dummy */) {
63 funcalls_ = 0;
64 }
65
66 // return a type other than bool but one that is implicitly
67 // convertible to bool to detect incorrect assumptions
69 bool result_;
70 public:
71 ConvertibleToBool (bool res): result_ (res) { /* empty */ }
72 operator bool() const { return result_; }
73 };
74
75 ConvertibleToBool operator() (const T &x, const U &y) /* non-const */ {
76 ++funcalls_;
77 return x == y;
78 }
79};
80
81template <class T, class U>
83
84
86// exercises std::adjacent_find()
87template <class ForwardIterator, class T>
88void do_test (int line, // line number of test case
89 const char *src, // source sequence
90 std::size_t resoff, // offset of result
91 ForwardIterator dummy_iter,
92 const T*,
93 const char* predname)
94{
95 static const char* const itname = type_name (dummy_iter, (T*)0);
96
97 const std::size_t nsrc = std::strlen (src);
98
99 if (std::size_t (-1) == resoff)
100 resoff = nsrc;
101
102 // have the UserClass default ctor initialize objects from `src'
103 xinit_begin = src;
105
106 UserClass* const xsrc = new UserClass [nsrc];
107
108 const ForwardIterator first =
109 make_iter (xsrc, xsrc, xsrc + nsrc, dummy_iter);
110
111 const ForwardIterator last =
112 make_iter (xsrc + nsrc, xsrc, xsrc + nsrc, dummy_iter);
113
114 // reset predicate counters
117
118 // construct a predicate object
119 const EqualityPredicate<T, T> pred (0, 0);
120
121 const ForwardIterator res = predname ?
122 std::adjacent_find (first, last, pred)
123 : std::adjacent_find (first, last);
124
125 // silence a bogus EDG eccp remark #550-D:
126 // variable "res" was set but never used
128
129 const std::size_t n_total_pred = predname ?
132
133 // verify that the returned iterator is set as expected
134 int success = res.cur_ == first.cur_ + resoff;
135 rw_assert (success, 0, line,
136 "line %d: adjacent_find<%s>(it = \"%s\", ...)"
137 " == (it + %zu), got (it + %td)",
138 __LINE__, itname, src,
139 resoff, res.cur_ - first.cur_);
140
141 // verify the number of applications of the predicate (lwg issue 240):
142 // Complexity: For a nonempty range, exactly
143 // min((i - first) + 1, (last - first) - 1)
144 // applications of the corresponding predicate, where i is
145 // adjacent_find's return value.
146
147 // compute the expected number of invocations of the predicate
148 std::size_t n_expect_pred = 0;
149
150 if (nsrc) {
151 // test iterators are guaranteed to be in range
152 _RWSTD_ASSERT (first.cur_ <= res.cur_ && res.cur_ <= last.cur_);
153
154 n_expect_pred = std::size_t (res.cur_ - first.cur_) + 1;
155 const std::size_t tmp = std::size_t (last.cur_ - first.cur_) - 1;
156 if (tmp < n_expect_pred)
157 n_expect_pred = tmp;
158 }
159
160 success = std::size_t (n_expect_pred) == n_total_pred;
161 rw_assert (success, 0, line,
162 "line %d: adjacent_find<%s>(\"%s\", ...) "
163 "invoked %s %zu times, expected %td",
164 __LINE__, itname, src,
165 predname ? predname : "operator==()",
166 n_total_pred, n_expect_pred);
167}
168
169
171template <class ForwardIterator, class T>
172void run_tests (ForwardIterator dummy_iter, const T*, const char* predname)
173{
174 static const char* const itname = type_name (dummy_iter, (T*)0);
175
176 rw_info (0, 0, 0, "std::adjacent_find (%s, %1$s%{?}, %s%{;})",
177 itname, 0 != predname, predname);
178
179#define TEST(src, off) \
180 do_test (__LINE__, src, std::size_t (off), dummy_iter, \
181 (UserClass*)0, predname)
182
183 // +------------------ subject sequence
184 // | +-- offset of returned iterator,
185 // | | -1 denotes the end of sequence
186 // v v
187 TEST ("", -1);
188 TEST ("a", -1);
189 TEST ("ab", -1);
190 TEST ("abc", -1);
191 TEST ("abcd", -1);
192 TEST ("abcde", -1);
193 TEST ("abcdef", -1);
194 TEST ("abcdefg", -1);
195 TEST ("abcdefgh", -1);
196 TEST ("abcdefghi", -1);
197 TEST ("abcdefghij", -1);
198 TEST ("abcdefghijk", -1);
199
200 TEST ("aabcdefghij", 0);
201 TEST ("abbcdefghij", 1);
202 TEST ("abccdefghij", 2);
203 TEST ("abcddefghij", 3);
204 TEST ("abcdeefghij", 4);
205 TEST ("abcdeffghij", 5);
206 TEST ("abcdefgghij", 6);
207 TEST ("abcdefghhij", 7);
208 TEST ("abcdefghiij", 8);
209 TEST ("abcdefghijj", 9);
210
211 TEST ("aaabcdefghi", 0);
212 TEST ("abbbcdefghi", 1);
213 TEST ("abcccdefghi", 2);
214 TEST ("abcdddefghi", 3);
215 TEST ("abcdeeefghi", 4);
216 TEST ("abcdefffghi", 5);
217 TEST ("abcdefggghi", 6);
218 TEST ("abcdefghhhi", 7);
219 TEST ("abcdefghiii", 8);
220 TEST ("abcdefghijjj", 9);
221
222}
223
224
226/* extern */ int rw_opt_no_fwd_iter; // --no-ForwardIterator
227/* extern */ int rw_opt_no_bidir_iter; // --no-BidirectionalIterator
228/* extern */ int rw_opt_no_rnd_iter; // --no-RandomAccessIterator
229/* extern */ int rw_opt_no_predicate; // --no-Predicate
230
231static
232void test_adjacent_find (const char* predname)
233{
234 rw_info (0, 0, 0,
235 "template <class %s%{?}, class %s%{;}> "
236 "%1$s std::adjacent_find (%1$s, %1$s%{?}, %3$s%{;})",
237 "ForwardIterator", 0 != predname, "BinaryPredicate",
238 0 != predname);
239
240 if (rw_opt_no_fwd_iter) {
241 rw_note (0, __FILE__, __LINE__, "ForwardIterator test disabled");
242 }
243 else {
244 run_tests (FwdIter<UserClass>(), (UserClass*)0, predname);
245 }
246
248 rw_note (0, __FILE__, __LINE__, "BidirectionalIterator test disabled");
249 }
250 else {
251 run_tests (BidirIter<UserClass>(), (UserClass*)0, predname);
252 }
253
254 if (rw_opt_no_rnd_iter) {
255 rw_note (0, __FILE__, __LINE__, "RandomAccessIterator test disabled");
256 }
257 else {
259 }
260}
261
262
264static int
265run_test (int, char*[])
266{
267 test_adjacent_find (0);
268
270 rw_note (0, __FILE__, __LINE__, "Predicate test disabled");
271 }
272 else {
273 test_adjacent_find ("EqualityPredicate<UserClass, UserClass>");
274 }
275
276 return 0;
277}
278
279
281int main (int argc, char *argv[])
282{
283 return rw_test (argc, argv, __FILE__,
284 "lib.alg.adjacent.find",
285 0 /* no comment */, run_test,
286 "|-no-ForwardIterator#"
287 "|-no-BidirectionalIterator#"
288 "|-no-RandomAccessIterator#"
289 "|-no-Predicate#",
294}
#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 tmp
Definition 17.names.cpp:553
#define ForwardIterator
Definition 17.names.cpp:469
#define U
Definition 17.names.cpp:164
const MyBuffer< char > nsrc[]
void run_tests(ForwardIterator dummy_iter, const T *, const char *predname)
int rw_opt_no_fwd_iter
void do_test(int line, const char *src, std::size_t resoff, ForwardIterator dummy_iter, const T *, const char *predname)
int rw_opt_no_rnd_iter
int xinit()
int rw_opt_no_bidir_iter
int rw_opt_no_predicate
#define TEST(src, off)
const char * type_name()
const int cur
#define main
#define _RWSTD_UNUSED(arg)
Definition _defs.h:972
#define _RWSTD_ASSERT(ignore)
Definition _defs.h:1108
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
#define bool
Definition stdbool.h:24
ConvertibleToBool operator()(const T &x, const U &y)
static std::size_t funcalls_
static _RWSTD_SIZE_T n_total_op_eq_
Definition rw_value.h:132
static int(* gen_)()
Definition rw_value.h:122