Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
25.find.cpp
Go to the documentation of this file.
1
29#include <algorithm> // for 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> // for rw_test()
35
36
39
40#ifndef _RWSTD_NO_EXPLICIT_INSTANTIATION
41
42template
45 const eq_comp<base<> >&);
46
47template
51
52#endif // _RWSTD_NO_EXPLICIT_INSTANTIATION
53
54} // namespace std
55
56
57
59template <class T>
61{
62 static std::size_t funcalls_;
63
64 Predicate (const T &val, int /* dummy */)
65 : val_ (val) {
66 funcalls_ = 0;
67 }
68
70 bool result_;
71 public:
72 ConvertibleToBool (bool res): result_ (res) { /* empty */ }
73 operator bool() const { return result_; }
74 };
75
76 // return a type other than bool but one that is implicitly
77 // convertible to bool to detect incorrect assumptions
78 ConvertibleToBool operator() (T obj) /* not const */ {
79 ++funcalls_;
80 return ConvertibleToBool (obj == val_);
81 }
82
83private:
84 void operator= (Predicate&);
85 const T &val_;
86};
87
88template <class T>
89std::size_t Predicate<T>::funcalls_;
90
91
93template <class InputIterator>
94void test_find (int line, // line number of test case
95 const char *src, // source sequence
96 std::size_t findoff, // offset of the element to find
97 InputIterator dummy_iter,
98 bool test_pred)
99{
100 static const char* const itname = type_name (dummy_iter, (UserClass*)0);
101 static const char* const pname = test_pred ? "Predicate" : "operator==";
102
103 const std::size_t nsrc = std::strlen (src);
104
105 // normalize offset
106 if (nsrc < findoff)
107 findoff = nsrc;
108
109 // create always at least 1 element (used to test failed searches)
110 UserClass* const tsrc = UserClass::from_char (src, nsrc + 1);
111 UserClass* const src_begin = tsrc;
112 UserClass* const src_end = tsrc + nsrc;
113
114 // current [first, last)
115 const InputIterator first (src_begin, src_begin, src_end);
116 const InputIterator last (src_end, src_begin, src_end);
117
118 // get a reference to the object to find (when findoff == nsrc
119 // the sought for element is outside the source range and won't
120 // be found)
121 const UserClass &to_find = tsrc [findoff];
122
123 // construct a predicate object to use with find_if
124 const Predicate<UserClass> pred (to_find, 0 /* dummy */);
125
126 // reset the operator==() counter
128
129 // invoke find() or find_if(), depending on the predicate flag
130 const InputIterator res = test_pred ?
131 std::find_if (first, last, pred) : std::find (first, last, to_find);
132
133 // silence a bogus EDG eccp remark #550-D:
134 // variable "res" was set but never used
136
137 // verify 25.1.5 p2
138 if (!rw_assert (res.cur_ == first.cur_ + findoff, 0, line,
139 "line %d: find%{?}_if%{;} (%s = \"%s\", ..., '%c')"
140 " == (it + %zu), got (it + %td)",
141 __LINE__, test_pred, itname, src, to_find.data_.val_,
142 findoff, res.cur_ - first.cur_)) {
143 delete[] tsrc;
144 return;
145 }
146
147 // verify 25.1.5 p3
148 // Complexity: At most last - first applications
149 // of the corresponding predicate.
150 // The complexity when find is successful is actually
151 // (res - first) applications of the corresponding predicate.
152
153 const std::size_t npreds =
154 test_pred ? pred.funcalls_ : UserClass::n_total_op_eq_;
155
156 rw_assert (npreds <= findoff + 1, 0, line,
157 "line %d: find%{?}_if%{;} (%s = \"%s\", ..., '%c') "
158 "invoked %s %zu times, expected no more than %zu",
159 __LINE__, test_pred, itname, src, to_find.data_.val_,
160 pname, npreds, findoff + 1);
161
162 delete[] tsrc;
163}
164
165
167template <class InputIterator>
168void test_find (InputIterator dummy_iter, bool test_pred)
169{
170 static const char* const itname = type_name (dummy_iter, (UserClass*)0);
171
172 rw_info (0, 0, 0, "std::find%{?}_if%{;} (%s, %2$s, "
173 "%{?}Predicate%{:}const UserClass&%{;})",
174 test_pred, itname, test_pred);
175
176#define TEST(src, off_find) \
177 test_find (__LINE__, src, std::size_t (off_find), \
178 dummy_iter, test_pred)
179
180 // +------------------ subject sequence
181 // | +--- offset of the value to find (-1 for none)
182 // | | also the offset of the returned iterator
183 // | |
184 // | |
185 // v v
186 TEST ("", -1);
187 TEST ("a", 0);
188 TEST ("aa", 0);
189 TEST ("ab", 1);
190 TEST ("aaa", 0);
191 TEST ("abb", 1);
192 TEST ("abc", 2);
193 TEST ("abcc", 2);
194 TEST ("abcd", 3);
195 TEST ("abcde", 4);
196 TEST ("abcdef", 5);
197 TEST ("abcdefg", 6);
198 TEST ("abcdefgh", 7);
199 TEST ("abcdefghi", 8);
200 TEST ("abcdefghij", 9);
201 TEST ("abcdefghijk", 10);
202 TEST ("abcdefghijk", -1);
203}
204
205
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/* extern */ int rw_opt_no_predicate; // --no-Predicate
212
213static void
214test_find (bool test_pred)
215{
216 rw_info (0, 0, 0,
217 "template <class %s, class %s> "
218 "%1$s std::find%{?}_if%{;} (%1$s, %1$s, "
219 "%{?}%2$s%{:}const %2$s&%{;})",
220 "InputIterator", test_pred ? "Predicate" : "T",
221 test_pred);
222
224 rw_note (0, __FILE__, __LINE__, "InputIterator test disabled");
225 }
226 else {
227 test_find (InputIter<UserClass>(0, 0, 0), test_pred);
228 }
229
230 if (rw_opt_no_fwd_iter) {
231 rw_note (0, __FILE__, __LINE__, "ForwardIterator test disabled");
232 }
233 else {
234 test_find (ConstFwdIter<UserClass>(), test_pred);
235 test_find (FwdIter<UserClass>(), test_pred);
236 }
237
239 rw_note (0, __FILE__, __LINE__, "BidirectionalIterator test disabled");
240 }
241 else {
243 test_find (BidirIter<UserClass>(), test_pred);
244 }
245
246 if (rw_opt_no_rnd_iter) {
247 rw_note (0, __FILE__, __LINE__, "RandomAccessIterator test disabled");
248 }
249 else {
252 }
253}
254
255
257static int
258run_test (int, char*[])
259{
260 test_find (false);
261
263 rw_note (0, __FILE__, __LINE__, "Predicate test disabled");
264 }
265 else {
266 test_find (true);
267 }
268
269 return 0;
270}
271
272
274int main (int argc, char *argv[])
275{
276 return rw_test (argc, argv, __FILE__,
277 "lib.alg.find",
278 0 /* no comment */, run_test,
279 "|-no-InputIterator#"
280 "|-no-ForwardIterator#"
281 "|-no-BidirectionalIterator#"
282 "|-no-RandomAccessIterator#"
283 "|-no-Predicate#",
289}
#define T
Definition 17.names.cpp:163
#define line
Definition 17.names.cpp:490
#define res
Definition 17.names.cpp:531
#define last
Definition 17.names.cpp:487
#define val
Definition 17.names.cpp:570
const MyBuffer< char > nsrc[]
#define TEST(src, off_find)
int rw_opt_no_fwd_iter
Definition 25.find.cpp:208
int rw_opt_no_rnd_iter
Definition 25.find.cpp:210
int rw_opt_no_bidir_iter
Definition 25.find.cpp:209
void test_find(int line, const char *src, std::size_t findoff, InputIterator dummy_iter, bool test_pred)
Definition 25.find.cpp:94
int rw_opt_no_input_iter
Definition 25.find.cpp:207
int rw_opt_no_predicate
Definition 25.find.cpp:211
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 bool
Definition stdbool.h:24
static std::size_t funcalls_
Definition 25.find.cpp:62
Predicate(const T &val, int)
Definition 25.find.cpp:64
static _RWSTD_SIZE_T n_total_op_eq_
Definition rw_value.h:132
static UserClass from_char(char c)
Definition rw_value.h:221
UserData data_
Definition rw_value.h:79
int val_
Definition rw_value.h:39