Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
25.binary.search.cpp
Go to the documentation of this file.
1
29#include <rw/_config.h>
30
31#if defined (__IBMCPP__) && !defined (_RWSTD_NO_IMPLICIT_INCLUSION)
32 // disable implicit inclusion to work around a limitation
33 // of IBM VisualAge 5.0 (see PR #26959)
34# define _RWSTD_NO_IMPLICIT_INCLUSION
35#endif
36
37#include <algorithm> // for binary_search()
38#include <cstring> // for strlen()
39
40#include <rw_alg_test.h> // for iterators
41#include <rw_value.h> // for UserClass
42#include <rw_driver.h> // for rw_test(), ...
43
44
46// meets requirements listed at 25.3, p2
47template <class T>
48struct compare {
49 bool operator() (const T &a, const T &b) const {
52 return true;
53 }
54};
55
57
58#ifndef _RWSTD_NO_EXPLICIT_INSTANTIATION
59
60template
61bool
62binary_search (FwdIter<lt_comp<assign<base<cpy_ctor> > > >,
64 const lt_comp<assign<base<cpy_ctor> > >&);
65
66template
67bool
68binary_search (FwdIter<lt_comp<assign<base<cpy_ctor> > > >,
70 const lt_comp<assign<base<cpy_ctor> > >&,
72
73#endif // _RWSTD_NO_EXPLICIT_INSTANTIATION
74
75} // namespace std
76
77
79// distinct and not Less-Than-Comparable with class T (except as
80// defined below) to detect unwarranted assumptions made by the
81// implementation of the algorithms
82struct Y
83{
85
86 // not Default-Constructible
87 Y (int /* dummy */, int /*dummy */): xval_ () { }
88
89 // CopyConstructible
90 Y (const Y &rhs): xval_ (rhs.xval_) { }
91
92private:
93
94 void operator=(Y&); // not Assignable
95};
96
97
98inline bool
99operator< (const UserClass &lhs, const Y &rhs)
100{
101 return lhs < rhs.xval_;
102}
103
104inline bool
105operator< (const Y &lhs, const UserClass &rhs)
106{
107 return lhs.xval_ < rhs;
108}
109
110// predicate used as the Compare argument to upper_bound()
112{
113 static std::size_t funcalls_;
114
115 LessThan (int /* dummy */, int /* dummy */) {
116 funcalls_ = 0;
117 }
118
119 // return a type other than bool but one that is implicitly
120 // convertible to bool to detect incorrect assumptions
121 bool operator() (const UserClass &lhs, const Y &rhs) {
122 ++funcalls_;
123 return lhs < rhs.xval_;
124 }
125
126 bool operator() (const Y &lhs, const UserClass &rhs) {
127 ++funcalls_;
128 return lhs.xval_ < rhs;
129 }
130
131private:
132 void operator= (LessThan&); // not assignable
133};
134
135std::size_t LessThan::funcalls_;
136
137
139template <class T, class ForwardIterator>
141 const char *src_str,
142 char val_char,
143 bool exp_res,
144 std::size_t ncomp,
145 const ForwardIterator &it,
146 const T*,
147 bool predicate)
148{
149 RW_ASSERT (0 != src_str);
150
151 const char* const tname = "UserClass";
152 const char* const itname = type_name (it, (T*)0);
153 const char* const funname = predicate ? "LessThan" : "operator<()";
154
155 const std::size_t nsrc = std::strlen (src_str);
156 T* const xsrc = T::from_char (src_str, nsrc);
157 T* const xsrc_end = xsrc + nsrc;
158
159 // construct the source range to pass to the algorithm
160 const ForwardIterator first = make_iter (xsrc, xsrc, xsrc_end, it);
161 const ForwardIterator last = make_iter (xsrc_end, xsrc, xsrc_end, it);
162
163 // construct the object to pass to the algorithm
164 // the type of the object is distinct from the iterator's value_type
165 // to detect unwarranted assumptions made by the implementation
166 Y value (0, 0 /* dummy arguments */);
167 value.xval_.data_.val_ = val_char;
168
169 // construct the Compare function object to pass to the algorithm
170 // when `predicate' is true
171 const LessThan comp (0, 0 /* dummy arguments */);
172
173 // reset the counter of invocations of T::operator<()
174 T::n_total_op_lt_ = 0;
175
176 // invoke the appropriate form of the algorithm, storing
177 // the resturned value
178 const bool result = predicate
179 ? std::binary_search (first, last, value, comp)
180 : std::binary_search (first, last, value);
181
182 // silence bogus EDG eccp 3.6 remark #550-D:
183 // variable was set but never used
185
186 rw_assert (result == exp_res, 0, line,
187 "binary_search <%s, const %s&%{?}, %s%{;}> (\"%s\", %#c, ...) "
188 "expected %s, got %s",
189 itname, tname, predicate, funname, src_str, val_char,
190 exp_res ? "true" : "false", result ? "true" : "false");
191
192 // verify complexity
193 const std::size_t n_ops = predicate
194 ? LessThan::funcalls_ : T::n_total_op_lt_;
195
196 rw_assert (n_ops <= ncomp, 0, line,
197 "binary_search <%s, const %s&%{?}, %s%{;}> (\"%s\", %#c, ...) "
198 "complexity: invoked %4$s at most %zu times, got %zu",
199 itname, tname, predicate, funname, src_str, val_char,
200 ncomp, n_ops);
201
202 delete[] xsrc;
203}
204
205
207template <class T, class ForwardIterator>
209 const T*,
210 bool predicate)
211{
212 const char* const itname = type_name (it, (T*)0);
213 const char* const funname = predicate ? "LessThan" : "operator<()";
214
215 rw_info (0, 0, 0,
216 "std::binary_search (%s, %1$s, const UserClass&%{?}, %s%{;})",
217 itname, predicate, funname);
218
219#define TEST(str, val, res, comp) \
220 test_binary_search (__LINE__, str, val, res, std::size_t (comp), \
221 it, (T*)0, predicate)
222
223 // +--------------- source sequence
224 // | +--------- value argument
225 // | | +----- expected result: true/false
226 // | | | +-- complexity: at most (log(last - first) + 2)
227 // | | | | comparisons (or applications of the predicate)
228 // | | | |
229 // V V V V
230 TEST ("", 'a', false, 0);
231 TEST ("a", 'a', true, 2);
232 TEST ("a", 'b', false, 2);
233 TEST ("b", 'a', false, 2);
234
235 TEST ("aa", 'a', true, 3);
236 TEST ("ab", 'a', true, 3);
237 TEST ("ab", 'b', true, 3);
238 TEST ("bb", 'a', false, 3);
239
240 TEST ("abcdefghij", 'a', true, 6);
241 TEST ("abcdefghij", 'c', true, 6);
242 TEST ("abcdefghij", 'f', true, 6);
243 TEST ("abcdefghij", 'h', true, 6);
244 TEST ("abcdefghij", 'j', true, 6);
245 TEST ("aacceeggii", 'c', true, 6);
246 TEST ("aacceeggii", 'g', true, 6);
247 TEST ("aacceeggii", 'b', false, 6);
248 TEST ("aacceeggii", 'f', false, 6);
249 TEST ("aacceeggii", 'j', false, 6);
250 TEST ("cccceeggii", 'a', false, 6);
251}
252
253
255/* extern */ int rw_opt_no_predicate; // --no-predicate
256/* extern */ int rw_opt_no_fwd_iter; // --no-ForwardIterator
257/* extern */ int rw_opt_no_bidir_iter; // --no-BidirectionalIterator
258/* extern */ int rw_opt_no_rnd_iter; // --no-RandomAccessIterator
259
260
262template <class T>
264 bool predicate)
265{
266 static const FwdIter<T> fwd_iter (0, 0, 0);
267 static const BidirIter<T> bidir_iter (0, 0, 0);
268 static const RandomAccessIter<T> rand_iter (0, 0, 0);
269
270 rw_info (0, 0, 0, "template <class %s, class %s%{?}, class %s%{;}> "
271 "bool std::binary_search (%1$s, %1$s, const %2$s&%{?}, %s%{;})",
272 "ForwardIterator", "UserClass", predicate, "Compare", predicate,
273 "Compare");
274
275 if (rw_opt_no_fwd_iter) {
276 rw_note (0, 0, 0, "ForwardIterator test disabled");
277 }
278 else {
279 test_binary_search (fwd_iter, (T*)0, predicate);
280 }
281
283 rw_note (0, 0, 0, "BidirectionalIterator test disabled");
284 }
285 else {
286 test_binary_search (bidir_iter, (T*)0, predicate);
287 }
288
289 if (rw_opt_no_fwd_iter) {
290 rw_note (0, 0, 0, "RandomAccessIterator test disabled");
291 }
292 else {
293 test_binary_search (rand_iter, (T*)0, predicate);
294 }
295}
296
297
299static int
300run_test (int, char*[])
301{
302 test_binary_search ((UserClass*)0, false);
303
305 rw_note (0, __FILE__, __LINE__,
306 "test of the Predicate form of std::binary_search disabled");
307 }
308 else {
309 test_binary_search ((UserClass*)0, true);
310 }
311
312 return 0;
313}
314
315
317int main (int argc, char *argv[])
318{
319 return rw_test (argc, argv, __FILE__,
320 "lib.binary.search",
321 0 /* no comment */,
322 run_test,
323 "|-no-Predicate# "
324 "|-no-ForwardIterator# "
325 "|-no-BidirectionalIterator# "
326 "|-no-RandomAccessIterator#",
331}
#define T
Definition 17.names.cpp:163
#define rhs
Definition 17.names.cpp:536
#define line
Definition 17.names.cpp:490
#define comp
Definition 17.names.cpp:461
#define last
Definition 17.names.cpp:487
#define a
Definition 17.names.cpp:109
#define lhs
Definition 17.names.cpp:489
#define b
Definition 17.names.cpp:110
#define ForwardIterator
Definition 17.names.cpp:469
volatile int result
const MyBuffer< char > nsrc[]
int rw_opt_no_fwd_iter
void test_binary_search(int line, const char *src_str, char val_char, bool exp_res, std::size_t ncomp, const ForwardIterator &it, const T *, bool predicate)
bool operator<(const UserClass &lhs, const Y &rhs)
int rw_opt_no_rnd_iter
int rw_opt_no_bidir_iter
int rw_opt_no_predicate
#define TEST(str, val, res, comp)
T value(const T &val)
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
#define RW_ASSERT(expr)
static std::size_t funcalls_
LessThan(int, int)
Y(int, int)
UserClass xval_
Y(const Y &rhs)
bool operator()(const T &a, const T &b) const