31
|
1 |
|
|
2 |
|
|
3 |
/***************************************************************************
|
|
4 |
*
|
|
5 |
* 25.generate.cpp - test exercising 25.2.6 [lib.alg.generate]
|
|
6 |
*
|
|
7 |
* $Id: 25.generate.cpp 354939 2005-12-08 02:28:44Z sebor $
|
|
8 |
*
|
|
9 |
***************************************************************************
|
|
10 |
*
|
|
11 |
* Copyright (c) 1994-2005 Quovadx, Inc., acting through its Rogue Wave
|
|
12 |
* Software division. Licensed under the Apache License, Version 2.0 (the
|
|
13 |
* "License"); you may not use this file except in compliance with the
|
|
14 |
* License. You may obtain a copy of the License at
|
|
15 |
* http://www.apache.org/licenses/LICENSE-2.0. Unless required by
|
|
16 |
* applicable law or agreed to in writing, software distributed under
|
|
17 |
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
18 |
* CONDITIONS OF ANY KIND, either express or implied. See the License
|
|
19 |
* for the specific language governing permissions and limitations under
|
|
20 |
* the License.
|
|
21 |
*
|
|
22 |
**************************************************************************/
|
|
23 |
|
|
24 |
#include <algorithm> // for generate
|
|
25 |
#include <cstddef> // for size_t
|
|
26 |
|
|
27 |
#include <alg_test.h>
|
|
28 |
#include <driver.h> // for rw_test()
|
|
29 |
#include"std_log_result.h"
|
|
30 |
#define LOG_FILENAME_LINE __FILE__, __LINE__
|
|
31 |
int failures=0;
|
|
32 |
|
|
33 |
/**************************************************************************/
|
|
34 |
|
|
35 |
template <class T>
|
|
36 |
struct Generator
|
|
37 |
{
|
|
38 |
// return a const reference to avoid requiring
|
|
39 |
// that T be copy-constructible
|
|
40 |
const T& operator() () const {
|
|
41 |
static const union {
|
|
42 |
void* align_;
|
|
43 |
unsigned char buf_ [sizeof (T)];
|
|
44 |
} u = { 0 };
|
|
45 |
return *(const T*)(const void*)&u;
|
|
46 |
}
|
|
47 |
};
|
|
48 |
|
|
49 |
|
|
50 |
_RWSTD_SPECIALIZED_CLASS
|
|
51 |
struct Generator<X>
|
|
52 |
{
|
|
53 |
// dummy arguments provided to prevent Generator
|
|
54 |
// from being DefaultConstructible
|
|
55 |
Generator (int, int /* dummy */) {
|
|
56 |
// use the generator of sequential values
|
|
57 |
// X::gen_ = gen_seq;
|
|
58 |
gen_ = gen_seq;
|
|
59 |
}
|
|
60 |
|
|
61 |
X operator() () /* non-const */ {
|
|
62 |
// return a default-constructed X intialized
|
|
63 |
// to the next sequential value
|
|
64 |
return X();
|
|
65 |
}
|
|
66 |
};
|
|
67 |
|
|
68 |
|
|
69 |
// Size template argument to generate_n()
|
|
70 |
struct Size
|
|
71 |
{
|
|
72 |
// dummy argument provided to prevent Size from being constructible
|
|
73 |
// by conversion from size_t
|
|
74 |
Size (int val, int /* dummy */ )
|
|
75 |
: val_ (val) { /* empty */ }
|
|
76 |
|
|
77 |
// Size must be convertible to an integral type
|
|
78 |
operator int () const { return val_; }
|
|
79 |
int operator++()
|
|
80 |
{
|
|
81 |
return ++val_;
|
|
82 |
}
|
|
83 |
int operator--()
|
|
84 |
{
|
|
85 |
return --val_;
|
|
86 |
}
|
|
87 |
private:
|
|
88 |
|
|
89 |
int val_;
|
|
90 |
};
|
|
91 |
|
|
92 |
/**************************************************************************/
|
|
93 |
/*
|
|
94 |
_RWSTD_NAMESPACE (std) {
|
|
95 |
|
|
96 |
// disable explicit instantiation for compilers (like MSVC)
|
|
97 |
// that can't handle it
|
|
98 |
#ifndef _RWSTD_NO_EXPLICIT_INSTANTIATION
|
|
99 |
|
|
100 |
template
|
|
101 |
void generate (FwdIter<assign<base<> > >, FwdIter<assign<base<> > >,
|
|
102 |
Generator<assign<base<> > >);
|
|
103 |
|
|
104 |
template
|
|
105 |
void generate_n (OutputIter<assign<base<> > >, std::size_t,
|
|
106 |
Generator<assign<base<> > >);
|
|
107 |
#endif // _RWSTD_NO_EXPLICIT_INSTANTIATION
|
|
108 |
|
|
109 |
} // namespace std
|
|
110 |
*/
|
|
111 |
/**************************************************************************/
|
|
112 |
|
|
113 |
// exercises std::generate()
|
|
114 |
template <class ForwardIterator, class T>
|
|
115 |
void test_generate (std::size_t N,
|
|
116 |
const ForwardIterator& gen_iter,
|
|
117 |
const T* )
|
|
118 |
{
|
|
119 |
static const char* const itname = type_name (gen_iter, (T*) 0);
|
|
120 |
static const char* const genname = "Generator";
|
|
121 |
|
|
122 |
rw_info (0, 0, 0,
|
|
123 |
"void std::generate (%s, %1$s, %s)", itname, genname);
|
|
124 |
|
|
125 |
// generate sequential values for each default constructed T
|
|
126 |
#ifndef __SYMBIAN32__
|
|
127 |
T::gen_ = gen_seq;
|
|
128 |
#else
|
|
129 |
gen_ = gen_seq;
|
|
130 |
#endif
|
|
131 |
|
|
132 |
T *buf = new X [N];
|
|
133 |
|
|
134 |
for (std::size_t i = 0; i < N; ++i) {
|
|
135 |
|
|
136 |
// exercise 25.2.6, std::generate<> ()
|
|
137 |
#ifndef __SYMBIAN32__
|
|
138 |
std::size_t last_n_op_assign = T::n_total_op_assign_;
|
|
139 |
#else
|
|
140 |
std::size_t last_n_op_assign = n_total_op_assign_;
|
|
141 |
#endif
|
|
142 |
T* const buf_end = buf + i + 1;
|
|
143 |
|
|
144 |
const ForwardIterator begin =
|
|
145 |
make_iter (buf, buf, buf_end, gen_iter);
|
|
146 |
|
|
147 |
const ForwardIterator end =
|
|
148 |
make_iter (buf_end, buf_end, buf_end, gen_iter);
|
|
149 |
|
|
150 |
const Generator<T> gen (0, 0);
|
|
151 |
|
|
152 |
// store the value of the next element
|
|
153 |
const int last_val = Generator<T>(0, 0)().val_;
|
|
154 |
|
|
155 |
std::generate (begin, end, gen);
|
|
156 |
|
|
157 |
bool success = true;
|
|
158 |
|
|
159 |
// verify 25.2.6, p2
|
|
160 |
std::size_t j = 0;
|
|
161 |
for ( ; j != i; ++j) {
|
|
162 |
success = (begin.cur_ + j)->val_ == int (last_val + j + 1);
|
|
163 |
if (!success)
|
|
164 |
break;
|
|
165 |
}
|
|
166 |
|
|
167 |
if(!success)
|
|
168 |
{
|
|
169 |
failures++;
|
|
170 |
std_log(LOG_FILENAME_LINE,"Reason: Failing");
|
|
171 |
}
|
|
172 |
|
|
173 |
rw_assert (success, 0, __LINE__,
|
|
174 |
"%zu. generate (): buf[%zu]: %d != %d",
|
|
175 |
i + 1, j, last_val + j + 1, (begin.cur_ + j)->val_ );
|
|
176 |
|
|
177 |
if (!success)
|
|
178 |
break;
|
|
179 |
|
|
180 |
// verify 25.2.6, p3
|
|
181 |
#ifndef __SYMBIAN32__
|
|
182 |
success = T::n_total_op_assign_ - last_n_op_assign == i + 1;
|
|
183 |
rw_assert (success, 0, __LINE__,
|
|
184 |
"%zu. generate (): complexity: %zu != %zu",
|
|
185 |
i + 1, T::n_total_op_assign_ - last_n_op_assign, i + 1);
|
|
186 |
#else
|
|
187 |
success = n_total_op_assign_ - last_n_op_assign == i + 1;
|
|
188 |
rw_assert (success, 0, __LINE__,
|
|
189 |
"%zu. generate (): complexity: %zu != %zu",
|
|
190 |
i + 1, n_total_op_assign_ - last_n_op_assign, i + 1);
|
|
191 |
if(!success)
|
|
192 |
{
|
|
193 |
failures++;
|
|
194 |
std_log(LOG_FILENAME_LINE,"Reason: Failing");
|
|
195 |
}
|
|
196 |
#endif
|
|
197 |
|
|
198 |
|
|
199 |
if (!success)
|
|
200 |
break;
|
|
201 |
}
|
|
202 |
delete[] buf;
|
|
203 |
|
|
204 |
}
|
|
205 |
|
|
206 |
/**************************************************************************/
|
|
207 |
|
|
208 |
// exercises std::generate_n()
|
|
209 |
template <class ForwardIterator, class Size, class T>
|
|
210 |
void test_generate_n (std::size_t N,
|
|
211 |
const ForwardIterator &gen_iter,
|
|
212 |
const Size*,
|
|
213 |
const T*)
|
|
214 |
{
|
|
215 |
static const char* const itname = type_name (gen_iter, (T*) 0);
|
|
216 |
static const char* const szname = "Size";
|
|
217 |
static const char* const genname = "Generator";
|
|
218 |
|
|
219 |
rw_info (0, 0, 0,
|
|
220 |
"void std::generate_n (%s, %s, %s)", itname, szname, genname);
|
|
221 |
|
|
222 |
// generate sequential values for each default constructed T
|
|
223 |
#ifndef __SYMBIAN32__
|
|
224 |
T::gen_ = gen_seq;
|
|
225 |
#else
|
|
226 |
gen_ = gen_seq;
|
|
227 |
#endif
|
|
228 |
|
|
229 |
T *buf = new X [N];
|
|
230 |
|
|
231 |
for (std::size_t i = 0; i <= N; ++i) {
|
|
232 |
|
|
233 |
#ifndef __SYMBIAN32__
|
|
234 |
std::size_t last_n_op_assign = T::n_total_op_assign_;
|
|
235 |
#else
|
|
236 |
std::size_t last_n_op_assign = n_total_op_assign_;
|
|
237 |
#endif
|
|
238 |
|
|
239 |
T* const buf_end = buf + i + 1;
|
|
240 |
|
|
241 |
const ForwardIterator begin =
|
|
242 |
make_iter (buf, buf, buf_end, gen_iter);
|
|
243 |
|
|
244 |
const Size sz (i, 0);
|
|
245 |
const Generator<T> gen (0, 0);
|
|
246 |
|
|
247 |
// store the value of the next element
|
|
248 |
const int last_val = Generator<T>(0, 0)().val_;
|
|
249 |
|
|
250 |
std::generate_n (begin, sz, gen);
|
|
251 |
|
|
252 |
bool success = true;
|
|
253 |
|
|
254 |
// verify 25.2.6, p2
|
|
255 |
std::size_t j = 0;
|
|
256 |
for ( ; j != i; ++j) {
|
|
257 |
success = (begin.cur_ + j)->val_ == int (last_val + j + 1);
|
|
258 |
if (!success)
|
|
259 |
break;
|
|
260 |
}
|
|
261 |
if(!success)
|
|
262 |
{
|
|
263 |
failures++;
|
|
264 |
std_log(LOG_FILENAME_LINE,"Reason: Failing");
|
|
265 |
}
|
|
266 |
|
|
267 |
rw_assert (success, 0, __LINE__,
|
|
268 |
"%zu. generate_n (): buf[%zu]: %d != %d",
|
|
269 |
i + 1, j, last_val + j + 1, (begin.cur_ + j)->val_ );
|
|
270 |
|
|
271 |
if (!success)
|
|
272 |
break;
|
|
273 |
|
|
274 |
// verify 25.2.6, p3
|
|
275 |
#ifndef __SYMBIAN32__
|
|
276 |
success = T::n_total_op_assign_ - last_n_op_assign == i;
|
|
277 |
rw_assert (success, 0, __LINE__,
|
|
278 |
"%zu. generate_n (): complexity: %zu != %zu",
|
|
279 |
i + 1, T::n_total_op_assign_ - last_n_op_assign, i);
|
|
280 |
#else
|
|
281 |
success = n_total_op_assign_ - last_n_op_assign == i;
|
|
282 |
rw_assert (success, 0, __LINE__,
|
|
283 |
"%zu. generate_n (): complexity: %zu != %zu",
|
|
284 |
i + 1, n_total_op_assign_ - last_n_op_assign, i);
|
|
285 |
|
|
286 |
if(!success)
|
|
287 |
{
|
|
288 |
failures++;
|
|
289 |
std_log(LOG_FILENAME_LINE,"Reason: Failing");
|
|
290 |
}
|
|
291 |
#endif
|
|
292 |
if (!success)
|
|
293 |
break;
|
|
294 |
}
|
|
295 |
|
|
296 |
// #ifndef __SYNBIAN32__
|
|
297 |
// ::operator delete(buf);
|
|
298 |
//#else
|
|
299 |
delete[] buf;
|
|
300 |
//#endif
|
|
301 |
}
|
|
302 |
|
|
303 |
/**************************************************************************/
|
|
304 |
|
|
305 |
/* extern */ int rw_opt_nloops = 32; // --nloops
|
|
306 |
/* extern */ int rw_opt_no_output_iter; // --no-OutputIterator
|
|
307 |
/* extern */ int rw_opt_no_fwd_iter; // --no-ForwardIterator
|
|
308 |
/* extern */ int rw_opt_no_bidir_iter; // --no-BidirectionalIterator
|
|
309 |
/* extern */ int rw_opt_no_rnd_iter; // --no-RandomAccessIterator
|
|
310 |
|
|
311 |
static void
|
|
312 |
test_generate (const std::size_t N)
|
|
313 |
{
|
|
314 |
rw_info (0, 0, 0,
|
|
315 |
"template <class %s, class %s> "
|
|
316 |
"void std::generate (%1$s, %1$s, %2$s&)",
|
|
317 |
"ForwardIterator", "Generator");
|
|
318 |
|
|
319 |
if (rw_opt_no_fwd_iter) {
|
|
320 |
rw_note (0, __FILE__, __LINE__, "ForwardIterator test disabled");
|
|
321 |
}
|
|
322 |
else {
|
|
323 |
test_generate (N, FwdIter<X>(), (X*)0);
|
|
324 |
}
|
|
325 |
|
|
326 |
if (rw_opt_no_bidir_iter) {
|
|
327 |
rw_note (0, __FILE__, __LINE__, "BidirectionalIterator test disabled");
|
|
328 |
}
|
|
329 |
else {
|
|
330 |
test_generate (N, BidirIter<X>(), (X*)0);
|
|
331 |
}
|
|
332 |
|
|
333 |
if (rw_opt_no_rnd_iter) {
|
|
334 |
rw_note (0, __FILE__, __LINE__, "RandomAccessIterator test disabled");
|
|
335 |
}
|
|
336 |
else {
|
|
337 |
test_generate (N, RandomAccessIter<X>(), (X*)0);
|
|
338 |
}
|
|
339 |
}
|
|
340 |
|
|
341 |
/**************************************************************************/
|
|
342 |
|
|
343 |
static void
|
|
344 |
test_generate_n (const std::size_t N)
|
|
345 |
{
|
|
346 |
rw_info (0, 0, 0,
|
|
347 |
"template <class %s, class %s, class %s> "
|
|
348 |
"void std::generate_n (%1$s, %2$s, const %3$s&)",
|
|
349 |
"OutputIterator", "Size", "Generator");
|
|
350 |
|
|
351 |
if (rw_opt_no_output_iter) {
|
|
352 |
rw_note (0, __FILE__, __LINE__, "OutputIterator test disabled");
|
|
353 |
}
|
|
354 |
else {
|
|
355 |
test_generate_n (N, OutputIter<X>(0, 0, 0), (Size*)0, (X*)0);
|
|
356 |
}
|
|
357 |
|
|
358 |
if (rw_opt_no_fwd_iter) {
|
|
359 |
rw_note (0, __FILE__, __LINE__, "ForwardIterator test disabled");
|
|
360 |
}
|
|
361 |
else {
|
|
362 |
test_generate_n (N, FwdIter<X>(), (Size*)0, (X*)0);
|
|
363 |
}
|
|
364 |
|
|
365 |
if (rw_opt_no_bidir_iter) {
|
|
366 |
rw_note (0, __FILE__, __LINE__, "BidirectionalIterator test disabled");
|
|
367 |
}
|
|
368 |
else {
|
|
369 |
test_generate_n (N, BidirIter<X>(), (Size*)0, (X*)0);
|
|
370 |
}
|
|
371 |
|
|
372 |
if (rw_opt_no_rnd_iter) {
|
|
373 |
rw_note (0, __FILE__, __LINE__, "RandomAccessIterator test disabled");
|
|
374 |
}
|
|
375 |
else {
|
|
376 |
test_generate_n (N, RandomAccessIter<X>(), (Size*)0, (X*)0);
|
|
377 |
}
|
|
378 |
}
|
|
379 |
|
|
380 |
/**************************************************************************/
|
|
381 |
|
|
382 |
static int
|
|
383 |
run_test (int, char*[])
|
|
384 |
{
|
|
385 |
// check that the number of loops is non-negative
|
|
386 |
rw_fatal (-1 < rw_opt_nloops, 0, 0,
|
|
387 |
"number of loops must be non-negative, got %d",
|
|
388 |
rw_opt_nloops);
|
|
389 |
|
|
390 |
const std::size_t N = std::size_t (rw_opt_nloops);
|
|
391 |
|
|
392 |
test_generate (N);
|
|
393 |
|
|
394 |
test_generate_n (N);
|
|
395 |
|
|
396 |
return 0;
|
|
397 |
}
|
|
398 |
|
|
399 |
/**************************************************************************/
|
|
400 |
|
|
401 |
int main (int argc, char *argv[])
|
|
402 |
{
|
|
403 |
std_log(LOG_FILENAME_LINE,"[Test Case for generate]");
|
|
404 |
#ifndef __SYMBIAN32__
|
|
405 |
return rw_test (argc, argv, __FILE__,
|
|
406 |
"lib.alg.generate",
|
|
407 |
0 /* no comment */, run_test,
|
|
408 |
"|-nloops# "
|
|
409 |
"|-no-OutputIterator# "
|
|
410 |
"|-no-ForwardIterator# "
|
|
411 |
"|-no-BidirectionalIterator# "
|
|
412 |
"|-no-RandomAccessIterator#",
|
|
413 |
&rw_opt_nloops,
|
|
414 |
&rw_opt_no_output_iter,
|
|
415 |
&rw_opt_no_fwd_iter,
|
|
416 |
&rw_opt_no_bidir_iter,
|
|
417 |
&rw_opt_no_rnd_iter);
|
|
418 |
#else
|
|
419 |
rw_test (argc, argv, __FILE__,
|
|
420 |
"lib.alg.generate",
|
|
421 |
0 /* no comment */, run_test,
|
|
422 |
"|-nloops# "
|
|
423 |
"|-no-OutputIterator# "
|
|
424 |
"|-no-ForwardIterator# "
|
|
425 |
"|-no-BidirectionalIterator# "
|
|
426 |
"|-no-RandomAccessIterator#",
|
|
427 |
&rw_opt_nloops,
|
|
428 |
&rw_opt_no_output_iter,
|
|
429 |
&rw_opt_no_fwd_iter,
|
|
430 |
&rw_opt_no_bidir_iter,
|
|
431 |
&rw_opt_no_rnd_iter);
|
|
432 |
if(failures)
|
|
433 |
{
|
|
434 |
assert_failed = true;
|
|
435 |
std_log(LOG_FILENAME_LINE,"Result: Failed");
|
|
436 |
}
|
|
437 |
else
|
|
438 |
{
|
|
439 |
|
|
440 |
std_log(LOG_FILENAME_LINE,"Result: Passed");
|
|
441 |
}
|
|
442 |
|
|
443 |
std_log(LOG_FILENAME_LINE,"[End Test Case]");
|
|
444 |
|
|
445 |
testResultXml("25_generate");
|
|
446 |
close_log_file();
|
|
447 |
return failures;
|
|
448 |
#endif
|
|
449 |
|
|
450 |
}
|