Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
25.generate.cpp
Go to the documentation of this file.
1
29#include <algorithm> // for generate
30#include <cstddef> // for size_t
31
32#include <rw_alg_test.h>
33#include <rw_value.h> // for UserClass
34#include <rw_driver.h> // for rw_test()
35
36
38template <class T>
40{
41 // return a const reference to avoid requiring
42 // that T be copy-constructible
43 const T& operator() () const {
44 static const union {
45 void* align_;
46 unsigned char buf_ [sizeof (T)];
47 } u = { 0 };
48 return *(const T*)(const void*)&u;
49 }
50};
51
52
55{
56 // dummy arguments provided to prevent Generator
57 // from being DefaultConstructible
58 Generator (int, int /* dummy */) {
59 // use the generator of sequential values
61 }
62
63 UserClass operator() () /* non-const */ {
64 // return a default-constructed UserClass intialized
65 // to the next sequential value
66 return UserClass ();
67 }
68};
69
70
73
74// disable explicit instantiation for compilers (like MSVC)
75// that can't handle it
76#ifndef _RWSTD_NO_EXPLICIT_INSTANTIATION
77
78template
79void generate (FwdIter<assign<base<> > >, FwdIter<assign<base<> > >,
81
82template
83void generate_n (OutputIter<assign<base<> > >, std::size_t,
85
86#endif // _RWSTD_NO_EXPLICIT_INSTANTIATION
87
88} // namespace std
89
90
92// exercises std::generate()
93template <class ForwardIterator, class T>
94void test_generate (std::size_t N,
95 const ForwardIterator& gen_iter,
96 const T* )
97{
98 static const char* const itname = type_name (gen_iter, (T*) 0);
99 static const char* const genname = "Generator";
100
101 rw_info (0, 0, 0,
102 "void std::generate (%s, %1$s, %s)", itname, genname);
103
104 // generate sequential values for each default constructed T
105 T::gen_ = gen_seq;
106
107 T *buf = new UserClass [N];
108
109 for (std::size_t i = 0; i < N; ++i) {
110
111 // exercise 25.2.6, std::generate<> ()
112 std::size_t last_n_op_assign = T::n_total_op_assign_;
113
114 T* const buf_end = buf + i + 1;
115
116 const ForwardIterator begin =
117 make_iter (buf, buf, buf_end, gen_iter);
118
119 const ForwardIterator end =
120 make_iter (buf_end, buf_end, buf_end, gen_iter);
121
122 const Generator<T> gen (0, 0);
123
124 // store the value of the next element
125 const int last_val = Generator<T>(0, 0)().data_.val_;
126
127 std::generate (begin, end, gen);
128
129 bool success = true;
130
131 // verify 25.2.6, p2
132 std::size_t j = 0;
133 for ( ; j != i; ++j) {
134 success = (begin.cur_ + j)->data_.val_ == int (last_val + j + 1);
135 if (!success)
136 break;
137 }
138
139 rw_assert (success, 0, __LINE__,
140 "%zu. generate (): buf[%zu]: %d != %d",
141 i + 1, j, last_val + j + 1, (begin.cur_ + j)->data_.val_ );
142
143 if (!success)
144 break;
145
146 // verify 25.2.6, p3
147 success = T::n_total_op_assign_ - last_n_op_assign == i + 1;
148 rw_assert (success, 0, __LINE__,
149 "%zu. generate (): complexity: %zu != %zu",
150 i + 1, T::n_total_op_assign_ - last_n_op_assign, i + 1);
151
152 if (!success)
153 break;
154 }
155
156 delete[] (buf);
157}
158
159
161// exercises std::generate_n()
162template <class ForwardIterator, class Size, class T>
163void test_generate_n (std::size_t N,
164 const ForwardIterator &gen_iter,
165 const Size*,
166 const T*)
167{
168 static const char* const itname = type_name (gen_iter, (T*) 0);
169 static const char* const szname = "Size<int>";
170 static const char* const genname = "Generator";
171
172 rw_info (0, 0, 0,
173 "void std::generate_n (%s, %s, %s)", itname, szname, genname);
174
175 // generate sequential values for each default constructed T
176 T::gen_ = gen_seq;
177
178 T *buf = new UserClass [N];
179
180 for (std::size_t i = 0; i <= N; ++i) {
181
182 std::size_t last_n_op_assign = T::n_total_op_assign_;
183
184 T* const buf_end = buf + i + 1;
185
186 const ForwardIterator begin =
187 make_iter (buf, buf, buf_end, gen_iter);
188
189 const Size n (typename Size::IntegralType (i), 0);
190 const Generator<T> gen (0, 0);
191
192 // store the value of the next element
193 const int last_val = Generator<T>(0, 0)().data_.val_;
194
195 std::generate_n (begin, n, gen);
196
197 bool success = true;
198
199 // verify 25.2.6, p2
200 std::size_t j = 0;
201 for ( ; j != i; ++j) {
202 success = (begin.cur_ + j)->data_.val_ == int (last_val + j + 1);
203 if (!success)
204 break;
205 }
206
207 rw_assert (success, 0, __LINE__,
208 "%zu. generate_n (): buf[%zu]: %d != %d",
209 i + 1, j, last_val + j + 1, (begin.cur_ + j)->data_.val_ );
210
211 if (!success)
212 break;
213
214 // verify 25.2.6, p3
215 success = T::n_total_op_assign_ - last_n_op_assign == i;
216 rw_assert (success, 0, __LINE__,
217 "%zu. generate_n (): complexity: %zu != %zu",
218 i + 1, T::n_total_op_assign_ - last_n_op_assign, i);
219
220 if (!success)
221 break;
222 }
223
224 delete[] (buf);
225}
226
227
229/* extern */ int rw_opt_nloops = 32; // --nloops
230/* extern */ int rw_opt_no_generate; // --no-generate
231/* extern */ int rw_opt_no_generate_n; // --no-generate_n
232/* extern */ int rw_opt_no_output_iter; // --no-OutputIterator
233/* extern */ int rw_opt_no_fwd_iter; // --no-ForwardIterator
234/* extern */ int rw_opt_no_bidir_iter; // --no-BidirectionalIterator
235/* extern */ int rw_opt_no_rnd_iter; // --no-RandomAccessIterator
236
237static void
238test_generate (const std::size_t N)
239{
240 rw_info (0, 0, 0,
241 "template <class %s, class %s> "
242 "void std::generate (%1$s, %1$s, %2$s&)",
243 "ForwardIterator", "Generator");
244
245 if (rw_opt_no_fwd_iter) {
246 rw_note (0, __FILE__, __LINE__, "ForwardIterator test disabled");
247 }
248 else {
250 }
251
253 rw_note (0, __FILE__, __LINE__, "BidirectionalIterator test disabled");
254 }
255 else {
257 }
258
259 if (rw_opt_no_rnd_iter) {
260 rw_note (0, __FILE__, __LINE__, "RandomAccessIterator test disabled");
261 }
262 else {
264 }
265}
266
267
269static void
270test_generate_n (const std::size_t N)
271{
272 rw_info (0, 0, 0,
273 "template <class %s, class %s, class %s> "
274 "void std::generate_n (%1$s, %2$s, const %3$s&)",
275 "OutputIterator", "Size", "Generator");
276
278 rw_note (0, __FILE__, __LINE__, "OutputIterator test disabled");
279 }
280 else {
282 (UserClass*)0);
283 }
284
285 if (rw_opt_no_fwd_iter) {
286 rw_note (0, __FILE__, __LINE__, "ForwardIterator test disabled");
287 }
288 else {
290 }
291
293 rw_note (0, __FILE__, __LINE__, "BidirectionalIterator test disabled");
294 }
295 else {
297 (UserClass*)0);
298 }
299
300 if (rw_opt_no_rnd_iter) {
301 rw_note (0, __FILE__, __LINE__, "RandomAccessIterator test disabled");
302 }
303 else {
305 (UserClass*)0);
306 }
307}
308
309
311static int
312run_test (int, char*[])
313{
315
316 const std::size_t N = std::size_t (rw_opt_nloops);
317
318 if (rw_opt_no_generate) {
319 rw_note (0, __FILE__, __LINE__, "std::generate test disabled");
320 }
321 else {
323 }
324
326 rw_note (0, __FILE__, __LINE__, "std::generate_n test disabled");
327 }
328 else {
330 }
331
332 return 0;
333}
334
335
337int main (int argc, char *argv[])
338{
339 return rw_test (argc, argv, __FILE__,
340 "lib.alg.generate",
341 0 /* no comment */, run_test,
342 "|-nloops#0 " // argument must be non-negative
343 "|-no-generate# "
344 "|-no-generate_n# "
345 "|-no-OutputIterator# "
346 "|-no-ForwardIterator# "
347 "|-no-BidirectionalIterator# "
348 "|-no-RandomAccessIterator#",
356}
#define N
Definition 17.names.cpp:157
#define i
Definition 17.names.cpp:126
#define T
Definition 17.names.cpp:163
#define u
Definition 17.names.cpp:137
#define gen
Definition 17.names.cpp:474
#define buf
Definition 17.names.cpp:452
#define j
Definition 17.names.cpp:127
#define n
Definition 17.names.cpp:130
#define ForwardIterator
Definition 17.names.cpp:469
void run_test(const ForwardIterator &dummy, T *, Predicate *pred)
int rw_opt_no_generate
int rw_opt_no_generate_n
int rw_opt_no_fwd_iter
int rw_opt_no_rnd_iter
int rw_opt_no_bidir_iter
int rw_opt_no_output_iter
void test_generate_n(std::size_t N, const ForwardIterator &gen_iter, const Size *, const T *)
void test_generate(std::size_t N, const ForwardIterator &gen_iter, const T *)
int rw_opt_nloops
const char * type_name()
const int end
#define main
#define _RWSTD_SPECIALIZED_CLASS
#define _RWSTD_NAMESPACE(name)
Definition _defs.h:567
Definition json.h:5363
_TEST_EXPORT int gen_seq()
Definition alg_test.cpp:38
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 int(* gen_)()
Definition rw_value.h:122