Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
25.find.end.cpp
Go to the documentation of this file.
1
29#include <algorithm> // for find_end()
30#include <functional> // for equal_to
31#include <cstring> // for size_t, strlen()
32
33#include <rw_alg_test.h>
34#include <rw_value.h> // for UserClass
35#include <rw_driver.h> // for rw_test()
36
37
40
41#ifndef _RWSTD_NO_EXPLICIT_INSTANTIATION
42
43template
45find_end (FwdIter<eq_comp<base<> > >, FwdIter<eq_comp<base<> > >,
47
48template
50find_end (FwdIter<eq_comp<base<> > >, FwdIter<eq_comp<base<> > >,
53
54#endif // _RWSTD_NO_EXPLICIT_INSTANTIATION
55
56} // namespace std
57
58
60// used to initialize an array of objects of type T
61static const char *tinit_begin;
62
63int tinit ()
64{
65 typedef unsigned char UChar;
66
67 return UChar (*tinit_begin++);
68}
69
70
71// exercises std::find_end()
72template <class ForwardIterator1, class ForwardIterator2, class T>
73void do_test (int line, // line number of test case
74 const char *src, // source sequence
75 const char *fseq, // sequence to be found
76 std::size_t resoff, // offset of result
77 ForwardIterator1 &dummy_iter1,
78 ForwardIterator2 &dummy_iter2,
79 const T*,
80 const char *predicate)
81{
82 static const char* const it1name = type_name (dummy_iter1, (T*)0);
83 static const char* const it2name = type_name (dummy_iter2, (T*)0);
84
85 const std::size_t nsrc = std::strlen (src);
86 const std::size_t nfseq = std::strlen (fseq);
87
88 if (std::size_t (-1) == resoff)
89 resoff = nsrc;
90
91 // have the T default ctor initialize objects from `src'
92 tinit_begin = src;
93 T::gen_ = tinit;
94
95 T* const tsrc = new T [nsrc];
96
97 T* const src_begin = tsrc;
98 T* const src_end = tsrc + nsrc;
99
100 // have the T default ctor initialize sequence to be found
101 tinit_begin = fseq;
102
103 T* const tfseq = new T [nfseq];
104
105 T* const fseq_begin = tfseq;
106 T* const fseq_end = tfseq + nfseq;
107
108 // create iterators
109 const ForwardIterator1 first1 =
110 make_iter (src_begin, src_begin, src_end, dummy_iter1);
111
112 const ForwardIterator1 last1 =
113 make_iter (src_end, src_begin, src_end, dummy_iter1);
114
115 const ForwardIterator2 first2 =
116 make_iter (fseq_begin, fseq_begin, fseq_end, dummy_iter2);
117
118 const ForwardIterator2 last2 =
119 make_iter (fseq_end, fseq_begin, fseq_end, dummy_iter2);
120
121 // compute the number of invocations of the predicate
122 std::size_t last_n_op_assign = T::n_total_op_assign_;
123
124 const ForwardIterator1 res = predicate ?
125 std::find_end (first1, last1, first2, last2, std::equal_to<T>())
126 : std::find_end (first1, last1, first2, last2);
127
128 // silence a bogus EDG eccp remark #550-D:
129 // variable "res" was set but never used
131
132 bool success = res.cur_ == first1.cur_ + resoff;
133 rw_assert (success, 0, line,
134 "line %d: find_end<%s, %s>(it = \"%s\", \"%s\")"
135 " == (it + %zu), got (it + %td)",
136 __LINE__, it1name, it2name, src, fseq,
137 resoff, res.cur_ - first1.cur_);
138
139 if (!success) {
140 delete[] tsrc;
141 delete[] tfseq;
142 return;
143 }
144
145 if (res.cur_ != last1.cur_) {
146 std::size_t j = 0;
147 for ( ; j < nfseq; ++j) {
148 success = (res.cur_ + j)->data_.val_ == fseq[j];
149 if (!success)
150 break;
151 }
152
153 rw_assert (success, 0, line,
154 "line %d: find_end<%s, %s>(it = \"%s\", \"%s\")"
155 " expected value %c got %c at %zu position",
156 __LINE__, it1name, it2name, src, fseq,
157 fseq[j], (res.cur_ + j)->data_.val_, j);
158
159 if (!success) {
160 delete[] tsrc;
161 delete[] tfseq;
162 return;
163 }
164 }
165
166 success =
167 T::n_total_op_assign_ - last_n_op_assign <= nfseq * (nsrc - nfseq + 1);
168 rw_assert (success, 0, line,
169 "line %d: find_end<%s, %s>(it = \"%s\", \"%s\")"
170 " %s invoked %zu times, expected no more than %td",
171 __LINE__, it1name, it2name, src, fseq,
172 predicate ? predicate : "comparison operator",
173 T::n_total_op_eq_, nfseq * (nsrc - nfseq + 1));
174
175 delete[] tsrc;
176 delete[] tfseq;
177}
178
179
181template <class ForwardIterator1, class ForwardIterator2, class T>
182void run_tests (const ForwardIterator1& dummy_iter1,
183 const ForwardIterator2& dummy_iter2,
184 const T*, const char* predicate)
185{
186 static const char* const it1name = type_name (dummy_iter1, (T*)0);
187 static const char* const it2name = type_name (dummy_iter2, (T*)0);
188
189 rw_info (0, 0, 0, "%s std::find_end (%1$s, %1$s, %s, %2$s%{?}, %s%{;})",
190 it1name, it2name, 0 != predicate, predicate);
191
192#define TEST(src, fnd, off_res) \
193 do_test (__LINE__, src, fnd, std::size_t (off_res), \
194 dummy_iter1, dummy_iter2, (UserClass*)0, predicate)
195
196 // +------------------ subject sequence
197 // | +--- sequence to be found
198 // | |
199 // | | +-- offset of returned iterator,
200 // | | | -1 denotes the end of sequence
201 // v v v
202 TEST ("abcdefghijk", "ab", 0);
203 TEST ("abcdefghijk", "bc", 1);
204 TEST ("abcdefghijk", "cd", 2);
205 TEST ("abcdefghijk", "de", 3);
206 TEST ("abcdefghijk", "ef", 4);
207 TEST ("abcdefghijk", "fg", 5);
208 TEST ("abcdefghijk", "gh", 6);
209 TEST ("abcdefghijk", "hi", 7);
210 TEST ("abcdefghijk", "ij", 8);
211 TEST ("abcdefghijk", "jk", 9);
212
213 TEST ("ababcdefghij", "ab", 2);
214 TEST ("abcbcdefghij", "bc", 3);
215 TEST ("abcdcdefghij", "cd", 4);
216 TEST ("abcdedefghij", "de", 5);
217 TEST ("abcdefefghij", "ef", 6);
218 TEST ("abcdefgfghij", "fg", 7);
219 TEST ("abcdefghghij", "gh", 8);
220 TEST ("abcdefghihij", "hi", 9);
221 TEST ("bcdefghijijk", "ij", 9);
222 TEST ("bcdefghijkjk", "jk", 10);
223
224 TEST ("", "a", -1);
225 TEST ("a", "ab", -1);
226 TEST ("ab", "abc", -1);
227 TEST ("abc", "abcd", -1);
228 TEST ("abcd", "abcde", -1);
229 TEST ("abcde", "abcdef", -1);
230 TEST ("abcdef", "abcdefg", -1);
231 TEST ("abcdefg", "abcdefgh", -1);
232
233 TEST ("abcdefghijk", "ba", -1);
234 TEST ("abcdefghijk", "cb", -1);
235 TEST ("abcdefghijk", "dc", -1);
236 TEST ("abcdefghijk", "ed", -1);
237 TEST ("abcdefghijk", "fe", -1);
238 TEST ("abcdefghijk", "gf", -1);
239 TEST ("abcdefghijk", "hg", -1);
240 TEST ("abcdefghijk", "ih", -1);
241 TEST ("abcdefghijk", "ji", -1);
242}
243
244
246/* extern */ int rw_opt_no_fwd_iter; // --no-ForwardIterator
247/* extern */ int rw_opt_no_bidir_iter; // --no-BidirectionalIterator
248/* extern */ int rw_opt_no_rnd_iter; // --no-RandomAccessIterator
249/* extern */ int rw_opt_no_predicate; // --no-Predicate
250
251
252template <class ForwardIterator, class T>
253void run_test_find_end (const ForwardIterator& dummy, T*,
254 const char* predicate)
255{
256 if (rw_opt_no_fwd_iter) {
257 rw_note (0, __FILE__, __LINE__, "ForwardIterator test disabled");
258 }
259 else {
260 run_tests (dummy, FwdIter<T>(), (T*)0, predicate);
261 }
262
264 rw_note (0, __FILE__, __LINE__, "BidirectionalIterator test disabled");
265 }
266 else {
267 run_tests (dummy, BidirIter<T>(), (T*)0, predicate);
268 }
269
270 if (rw_opt_no_rnd_iter) {
271 rw_note (0, __FILE__, __LINE__, "RandomAccessIterator test disabled");
272 }
273 else {
274 run_tests (dummy, RandomAccessIter<T>(), (T*)0, predicate);
275 }
276}
277
278
280static void
281test_find_end (const char* predicate)
282{
283 rw_info (0, 0, 0,
284 "template <class %s, class %s> "
285 "%1$s std::find_end (%1$s, %1$s, %2$s, %2$s%{?}, %s%{;})",
286 "ForwardIterator1", "ForwardIterator2",
287 0 != predicate, predicate);
288
289 if (rw_opt_no_fwd_iter) {
290 rw_note (0, __FILE__, __LINE__, "ForwardIterator test disabled");
291 }
292 else {
294 }
295
297 rw_note (0, __FILE__, __LINE__, "BidirectionalIterator test disabled");
298 }
299 else {
301 }
302
303 if (rw_opt_no_rnd_iter) {
304 rw_note (0, __FILE__, __LINE__, "RandomAccessIterator test disabled");
305 }
306 else {
308 predicate);
309 }
310}
311
312
314static int
315run_test (int, char*[])
316{
317 test_find_end (0);
318
320 rw_note (0, __FILE__, __LINE__, "Predicate test disabled");
321 }
322 else {
323 test_find_end ("std::equal_to<UserClass>");
324 }
325
326 return 0;
327}
328
329
331int main (int argc, char *argv[])
332{
333 return rw_test (argc, argv, __FILE__,
334 "lib.alg.find.end",
335 0 /* no comment */, run_test,
336 "|-no-ForwardIterator#"
337 "|-no-BidirectionalIterator#"
338 "|-no-RandomAccessIterator#"
339 "|-no-Predicate#",
344}
#define T
Definition 17.names.cpp:163
#define line
Definition 17.names.cpp:490
#define res
Definition 17.names.cpp:531
#define j
Definition 17.names.cpp:127
#define ForwardIterator
Definition 17.names.cpp:469
const MyBuffer< char > nsrc[]
void do_test(int line, const char *src, std::size_t resoff, ForwardIterator dummy_iter, const T *, const char *predname)
int rw_opt_no_fwd_iter
void run_test_find_end(const ForwardIterator &dummy, T *, const char *predicate)
int rw_opt_no_rnd_iter
#define TEST(src, fnd, off_res)
int rw_opt_no_bidir_iter
int rw_opt_no_predicate
int tinit()
void run_tests(const ForwardIterator1 &dummy_iter1, const ForwardIterator2 &dummy_iter2, const T *, const char *predicate)
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
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