Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
25.upper.bound.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 upper_bound()
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// distinct and not Less-Than-Comparable with class UserClass (except as
47// defined below) to detect unwarranted assumptions made by the
48// implementation of the algorithms
49struct Y
50{
52
53 // not Default-Constructible
54 Y (int /* dummy */, int /*dummy */): xval_ () { }
55
56 // CopyConstructible
57 Y (const Y &rhs): xval_ (rhs.xval_) { }
58
59private:
60
61 void operator=(Y&); // not Assignable
62};
63
64
66operator< (const UserClass &lhs, const Y &rhs)
67{
68 return conv_to_bool::make (lhs < rhs.xval_);
69}
70
72operator< (const Y &lhs, const UserClass &rhs)
73{
74 return conv_to_bool::make (lhs.xval_ < rhs);
75}
76
77// predicate used as the Compare argument to upper_bound()
78struct LessThan
79{
80 static std::size_t funcalls_;
81
82 LessThan (int /* dummy */, int /* dummy */) {
83 funcalls_ = 0;
84 }
85
86 // return a type other than bool but one that is implicitly
87 // convertible to bool to detect incorrect assumptions
89 ++funcalls_;
90 return conv_to_bool::make (lhs < rhs.xval_);
91 }
92
94 ++funcalls_;
95 return conv_to_bool::make (lhs.xval_ < rhs);
96 }
97
98private:
99 void operator= (LessThan&); // not assignable
100};
101
102std::size_t LessThan::funcalls_;
103
104
106template <class ForwardIterator>
108 const char *src_str,
109 char val_char,
110 std::size_t result_off,
111 std::size_t ncomp,
112 const ForwardIterator*,
113 const char *itname,
114 bool predicate)
115{
116 RW_ASSERT (0 != src_str);
117
118 const std::size_t nsrc = std::strlen (src_str);
119 UserClass* const xsrc = UserClass::from_char (src_str, nsrc);
120
121 if (nsrc < result_off)
122 result_off = nsrc;
123
124 // construct the source range to pass to the algorithm
125 const ForwardIterator first (xsrc, xsrc, xsrc + nsrc);
126 const ForwardIterator last (xsrc + nsrc, xsrc + nsrc, xsrc + nsrc);
127
128 // construct the object to pass to the algorithm
129 // the type of the object is distinct from the iterator's value_type
130 // to detect unwarranted assumptions made by the implementation
131 Y value (0, 0 /* dummy arguments */);
132 value.xval_.data_.val_ = val_char;
133
134 // construct the Compare function object to pass to the algorithm
135 // when `predicate' is true
136 const LessThan comp (0, 0 /* dummy arguments */);
137
138 // reset the counter of invocations of UserClass::operator<()
140
141 // invoke the appropriate form of the algorithm, storing
142 // the resturned value
144 ? std::upper_bound (first, last, value, comp)
145 : std::upper_bound (first, last, value);
146
147 // silence bogus EDG eccp 3.6 remark #550-D:
148 // variable was set but never used
150
151 // verify correctness
152 const std::size_t off = std::size_t (result.cur_ - xsrc);
153
154 rw_assert (off == result_off, 0, line,
155 "upper_bound(%s = \"%s\", ...%{?}%#c%{;}) ==> "
156 "first + %zu, got %zu",
157 itname, src_str, !predicate, val_char,
158 off, result_off);
159
160 // verify complexity
161 const std::size_t funcalls = predicate
163
164 rw_assert (funcalls <= ncomp, 0, line,
165 "upper_bound(%s = \"%s\", ...%{?}%#c%{;}) complexity: "
166 "invoked predicate at most %zu times, got %zu",
167 itname, src_str, !predicate, val_char,
168 ncomp, funcalls);
169
170 delete[] xsrc;
171}
172
173
175template <class ForwardIterator>
177 const char *itname,
178 bool predicate)
179{
180#define TEST(str, val, off, comp) \
181 test_upper_bound (__LINE__, str, val, std::size_t (off), \
182 std::size_t (comp), (ForwardIterator*)0, \
183 itname, predicate)
184
185 rw_info (0, 0, 0,
186 "std::upper_bound (%s, %1$s, const UserClass&%{?}, %s%{;})",
187 itname, predicate, "LessThan");
188
189 // +--------------- source sequence
190 // | +--------- value argument
191 // | | +----- offset of the resturned iterator, -1 for end
192 // | | | +-- complexity: at most (log(last - first) + 1)
193 // | | | | comparisons (or applications of the predicate)
194 // | | | |
195 // V V V V
196 TEST ("", 'a', 0, 0);
197 TEST ("a", 'a', 1, 1);
198 TEST ("a", 'b', 1, 1);
199 TEST ("b", 'a', 0, 1);
200
201 TEST ("aa", 'a', 2, 2);
202 TEST ("ab", 'a', 1, 2);
203 TEST ("ab", 'b', 2, 2);
204 TEST ("bb", 'a', 0, 2);
205
206 TEST ("ace", 'a', 1, 3);
207 TEST ("ace", 'b', 1, 3);
208 TEST ("ace", 'c', 2, 3);
209 TEST ("ace", 'd', 2, 3);
210 TEST ("ace", 'e', 3, 3);
211 TEST ("ace", 'f', 3, 3);
212
213 TEST ("aceg", 'a', 1, 3);
214 TEST ("aceg", 'b', 1, 3);
215 TEST ("aceg", 'c', 2, 3);
216 TEST ("aceg", 'd', 2, 3);
217 TEST ("aceg", 'e', 3, 3);
218 TEST ("aceg", 'f', 3, 3);
219 TEST ("aceg", 'g', 4, 3);
220 TEST ("aceg", 'h', 4, 3);
221}
222
223
225static int rw_opt_no_fwd_iter;
226static int rw_opt_no_bidir_iter;
227static int rw_opt_no_rnd_iter;
228static int rw_opt_no_predicate;
229
230
231static void
233{
234 rw_info (0, 0, 0, "template <class %s, class %s%{?}, class %s%{;}> "
235 "std::upper_bound (%1$s, %1$s, const UserClass&%{?}, %4$s%{;})",
236 "ForwardIterator", "UserClass", predicate, "Compare", predicate);
237
238 if (rw_opt_no_fwd_iter) {
239 rw_note (0, 0, 0, "ForwardIterator test disabled");
240 }
241 else {
242 test_upper_bound ((FwdIter<UserClass>*)0, "ForwardIterator", predicate);
243 }
244
245 if (rw_opt_no_bidir_iter) {
246 rw_note (0, 0, 0, "BidirectionalIterator test disabled");
247 }
248 else {
249 test_upper_bound ((BidirIter<UserClass>*)0, "BidirectionalIterator",
250 predicate);
251 }
252
253 if (rw_opt_no_fwd_iter) {
254 rw_note (0, 0, 0, "RandomAccessIterator test disabled");
255 }
256 else {
258 "RandomAccessIterator",
259 predicate);
260 }
261}
262
263
265static int
266run_test (int, char*[])
267{
268 test_upper_bound (false);
269
270 if (rw_opt_no_predicate) {
271 rw_note (0, __FILE__, __LINE__,
272 "test of the Predicate form of std::upper_bound disabled");
273 }
274 else {
275 test_upper_bound (true);
276 }
277
278 return 0;
279}
280
281
283int main (int argc, char *argv[])
284{
285 return rw_test (argc, argv, __FILE__,
286 "lib.upper.bound",
287 0 /* no comment */,
288 run_test,
289 "|-no-Predicate# "
290 "|-no-ForwardIterator# "
291 "|-no-BidirectionalIterator# "
292 "|-no-RandomAccessIterator#",
297}
#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 lhs
Definition 17.names.cpp:489
#define off
Definition 17.names.cpp:507
#define ForwardIterator
Definition 17.names.cpp:469
volatile int result
const MyBuffer< char > nsrc[]
int rw_opt_no_fwd_iter
int rw_opt_no_rnd_iter
int rw_opt_no_bidir_iter
int rw_opt_no_predicate
void run_test(const ForwardIterator &dummy, T *, Predicate *pred)
#define TEST(str, val, off, comp)
void test_upper_bound(int line, const char *src_str, char val_char, std::size_t result_off, std::size_t ncomp, const ForwardIterator *, const char *itname, bool predicate)
conv_to_bool operator<(const UserClass &lhs, const Y &rhs)
T value(const T &val)
#define main
#define _RWSTD_UNUSED(arg)
Definition _defs.h:972
_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_
bool operator()(const UserClass &lhs, const Y &rhs)
LessThan(int, int)
static UserClass from_char(char c)
Definition rw_value.h:221
static _RWSTD_SIZE_T n_total_op_lt_
Definition rw_value.h:133
Y(int, int)
UserClass xval_
Y(const Y &rhs)
static conv_to_bool make(bool val)