Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
20.specialized.cpp
Go to the documentation of this file.
1
29#include <memory>
30
31#include <rw_alg_test.h>
32#include <rw_driver.h>
33
34
36#ifndef _RWSTD_NO_EXCEPTIONS
37
38struct Y
39{
40 static int count_;
41 static int ctor_;
42 static int dtor_;
43 static int throw_at_;
44
45 int val_;
46
47 Y (const Y &rhs) : val_ (rhs.val_) {
48 ++ctor_;
49 if (count_ + 1 == throw_at_)
50 throw 0;
51 ++count_;
52 }
53
54 Y (int val) : val_ (val) {
55 ++ctor_;
56 if (count_ + 1 == throw_at_)
57 throw 0;
58 ++count_;
59 }
60
61 ~Y () {
62 ++dtor_;
63 val_ = -2;
64 --count_;
65 }
66
67private:
68 void operator= (const Y&); // not Assignable
69};
70
71
72int Y::count_;
73int Y::ctor_;
74int Y::dtor_;
75int Y::throw_at_;
76
77
79template <class T>
80const char* type_name (volatile T*, T*) { return "volatile T*"; }
81
82template <class T>
83const char* type_name (const volatile T*, T*) { return "const volatile T*"; }
84
85// defined as ordinary functions (as opposed to templates)
86// to avoid tripping up broken compilers on argument deduction
87inline const volatile int*
88make_iter (const int *beg, const int*, const int*, const volatile int*)
89{
90 return beg;
91}
92
93inline volatile Y*
94make_iter (Y *beg, Y*, Y*, volatile Y*)
95{
96 return beg;
97}
98
99
101// exercises uninitialized_copy [lib.uninitialized.copy]
102// with emphasis on exception safety - the function is to have no effect
103// if an exception is thrown
104template <class InputIterator, class ForwardIterator>
106 const ForwardIterator*)
107{
108 const char* const i1name = type_name (dummy, (int*)0);
109 const char* const i2name = type_name (ForwardIterator (), (Y*)0);
110
111 rw_info (0, 0, __LINE__, "std::uninitialized_copy(%s, %1$s, %s)",
112 i1name, i2name);
113
114 static const int a[] = {
115 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
116 };
117
118 const unsigned N = sizeof a / sizeof *a;
119
120 // allocate an uninitialized buffer
121 Y *buf = _RWSTD_STATIC_CAST (Y*, ::operator new (N * sizeof (Y)));
122
123 for (unsigned i = 0; i != N; ++i) {
124
125 Y::count_ = Y::ctor_ = Y::dtor_ = 0;
126
127 // throw during the copy construction of the i-th elem
128 Y::throw_at_ = i;
129
130 try {
131 // constructs i elements, the last ctor throws
132 const InputIterator first =
133 make_iter (a, a, a + i, dummy);
134 const InputIterator last =
135 make_iter (a + i, a, a + i, first);
136
137 const ForwardIterator result =
139
140 std::uninitialized_copy (first, last, result);
141
142 rw_assert (i == 0, 0, __LINE__,
143 "%zu. expected exception not thrown", i);
144 }
145 catch (int) {
146 // ctor throws an int, this is what's expected
147 }
148 catch (...) {
149 rw_assert (0, 0, __LINE__,
150 "%zu. exception of an unexpected type thrown", i);
151 }
152
153 // verify that all constructed elements were destroyed
154 rw_assert (Y::count_ == 0, 0, __LINE__,
155 "%zu. %d elements not destroyed", i, Y::count_);
156
157 // verify that the expected number of ctor and dtor calls were made
158 rw_assert (Y::ctor_ == Y::throw_at_, 0, __LINE__,
159 "%zu. %d ctor calls expected, got %d",
160 i, Y::throw_at_, Y::ctor_);
161 rw_assert (i ? Y::dtor_ + 1 == Y::throw_at_ : true, 0, __LINE__,
162 "%zu. %d dtor calls expected, got %d",
163 i, Y::throw_at_ - 1, Y::dtor_);
164 }
165
166 ::operator delete (buf);
167}
168
169
171// exercises 20.4.4.2 and 3 - uninitialized_fill [lib.uninitialized.fill]
172// and uninitialized_fill_n [lib.uninitialized.fill_n] with emphasis on
173// exception safety - the function is to have no effect if an exception
174// is thrown
175template <class ForwardIterator>
176void test_uninitialized_fill (const ForwardIterator*, bool test_count)
177{
178 const char* const itname = type_name (ForwardIterator (), (Y*)0);
179
180 rw_info (0, 0, __LINE__,
181 "std::uninitialized_fill%{?}_n%{;}(%s, %{?}size_t%{:}%2$s%{;}, "
182 "const int&)", test_count, itname, test_count);
183
184 const unsigned N = 32;
185
186 // allocate an uninitialized buffer
187 Y *buf = _RWSTD_STATIC_CAST (Y*, ::operator new (N * sizeof (Y)));
188
189 for (unsigned i = 0; i != N; ++i) {
190
191 // prevent ctor below from throwing
192 Y::throw_at_ = -1;
193
194 // create a temporary and reset counters (in that order)
195 Y val (i);
196
197 Y::count_ = Y::ctor_ = Y::dtor_ = 0;
198
199 // throw during the copy construction of the i-th elem
200 Y::throw_at_ = i;
201
202 try {
203 // copy-constructs i elements, the last copy ctor throws
204 const ForwardIterator first =
206
207 if (test_count) {
208 std::uninitialized_fill_n (first, i, val);
209 }
210 else {
211 const ForwardIterator last =
212 make_iter (buf + i, buf, buf + i, first);
213
214 std::uninitialized_fill (first, last, val);
215 }
216
217 rw_assert (i == 0, 0, __LINE__,
218 "%zu. expected exception not thrown", i);
219 }
220 catch (int) {
221 // ctor throws an int, this is what's expected
222 }
223 catch (...) {
224 rw_assert (0, 0, __LINE__,
225 "%zu. exception of an unexpected type thrown", i);
226 }
227
228 // verify that all constructed elements were destroyed
229 rw_assert (Y::count_ == 0, 0, __LINE__,
230 "%zu. %d elements not destroyed", i, Y::count_);
231
232 // verify that the expected number of ctor and dtor calls were made
233 rw_assert (Y::ctor_ == Y::throw_at_, 0, __LINE__,
234 "%zu. %d ctor calls expected, got %d",
235 i, Y::throw_at_, Y::ctor_);
236 rw_assert (i ? Y::dtor_ + 1 == Y::throw_at_ : true, 0, __LINE__,
237 "%d. %d dtor calls expected, got %d",
238 i, Y::throw_at_ - 1, Y::dtor_);
239 }
240
241 ::operator delete (buf);
242}
243
244
249
255
256
257template <class InputIterator>
259{
260 if (-1 < opt_fwd_iter)
262 else
263 rw_note (-1 > opt_fwd_iter--, 0, __LINE__,
264 "ForwardIterator tests disabled");
265
266 if (-1 < opt_bidir_iter)
268 else
269 rw_note (-1 > opt_bidir_iter--, 0, __LINE__,
270 "BidirectionalIterator tests disabled");
271
272 if (-1 < opt_rnd_iter)
274 else
275 rw_note (-1 > opt_rnd_iter--, 0, __LINE__,
276 "RandomAccessIterator tests disabled");
277
278 if (-1 < opt_volatile_ptr) {
279 typedef volatile Y* VolatilePointer;
280 test_uninitialized_copy (dummy, (VolatilePointer*)0);
281 }
282 else
283 rw_note (-1 > opt_volatile_ptr--, 0, __LINE__,
284 "volatile T* tests disabled");
285}
286
287
289static int
290run_test (int, char**)
291{
292 typedef const volatile int* ConstVolatilePointer;
293 typedef /* */ volatile Y* VolatilePointer;
294
295 if (-1 < opt_copy) {
296 if (-1 < opt_input_iter)
298 else
299 rw_note (-1 > opt_input_iter--, 0, __LINE__,
300 "InputIterator tests disabled");
301
302 if (-1 < opt_fwd_iter)
304 else
305 rw_note (-1 > opt_fwd_iter--, 0, __LINE__,
306 "ForwardIterator tests disabled");
307
308 if (-1 < opt_bidir_iter)
310 else
311 rw_note (-1 > opt_bidir_iter--, 0, __LINE__,
312 "BidirectionalIterator tests disabled");
313
314 if (-1 < opt_rnd_iter)
316 else
317 rw_note (-1 > opt_rnd_iter--, 0, __LINE__,
318 "RandomAccessIterator tests disabled");
319
320 if (-1 < opt_volatile_ptr)
321 test_uninitialized_copy (ConstVolatilePointer ());
322 else
323 rw_note (-1 > opt_volatile_ptr--, 0, __LINE__,
324 "volatile T* tests disabled");
325 }
326 else
327 rw_note (0, 0, 0, "tests of std::uninitialized_copy disabled");
328
330
331 if (-1 < opt_fill) {
332 if (-1 < opt_fwd_iter)
334 else
335 rw_note (-1 > opt_fwd_iter--, 0, __LINE__,
336 "ForwardIterator tests disabled");
337
338 if (-1 < opt_bidir_iter)
340 else
341 rw_note (-1 > opt_bidir_iter--, 0, __LINE__,
342 "BidirectionalIterator tests disabled");
343
344 if (-1 < opt_bidir_iter)
346 else
347 rw_note (-1 > opt_bidir_iter--, 0, __LINE__,
348 "RandomAccessIterator tests disabled");
349
350 if (-1 < opt_volatile_ptr) {
351 test_uninitialized_fill ((VolatilePointer*)0, false);
352 }
353 else
355 0, 0, "volatile T* tests disabled");
356 }
357 else
358 rw_note (0, 0, 0, "tests of std::uninitialized_fill disabled");
359
361 if (-1 < opt_fill) {
362 if (-1 < opt_fwd_iter)
364 else
365 rw_note (-1 > opt_fwd_iter--, 0, __LINE__,
366 "ForwardIterator tests disabled");
367
368 if (-1 < opt_bidir_iter)
370 else
371 rw_note (-1 > opt_bidir_iter--, 0, __LINE__,
372 "BidirectionalIterator tests disabled");
373
374 if (-1 < opt_bidir_iter)
376 else
377 rw_note (-1 > opt_bidir_iter--, 0, __LINE__,
378 "RandomAccessIterator tests disabled");
379
380 if (-1 < opt_volatile_ptr) {
381 test_uninitialized_fill ((VolatilePointer*)0, true);
382 }
383 else
384 rw_note (-1 > opt_volatile_ptr--, 0, __LINE__,
385 "volatile T* tests disabled");
386 }
387 else
388 rw_note (0, 0, 0, "tests of std::uninitialized_fill disabled");
389
390 return 0;
391}
392
393#else // _RWSTD_NO_EXCEPTIONS
394
395static int
396run_test (int, char**)
397{
398 rw_note (0, 0, 0,
399 "exceptions disabled (_RWSTD_NO_EXCEPTIONS #defined), "
400 "cannot test");
401
402 return 0;
403}
404
405#endif // _RWSTD_NO_EXCEPTIONS
406
407
409int main (int argc, char *argv[])
410{
411 return rw_test (argc, argv, __FILE__,
412 "lib.specialized.algorithms",
413 0 /* no comment */,
414 run_test,
415 "|-uninitialized_copy~ "
416 "|-uninitialized_fill~ "
417 "|-uninitialized_fill_n~ "
418 "|-InputIterator~ "
419 "|-ForwardIterator~ "
420 "|-BidirectionalIterator~ "
421 "|-RandomAccessIterator~ "
422 "|-volatile-pointer",
423 &opt_copy,
424 &opt_fill,
425 &opt_fill_n,
431}
#define N
Definition 17.names.cpp:157
#define i
Definition 17.names.cpp:126
#define T
Definition 17.names.cpp:163
#define rhs
Definition 17.names.cpp:536
#define last
Definition 17.names.cpp:487
#define a
Definition 17.names.cpp:109
#define buf
Definition 17.names.cpp:452
#define val
Definition 17.names.cpp:570
#define ForwardIterator
Definition 17.names.cpp:469
volatile int result
void test_uninitialized_copy(const InputIterator &dummy, const ForwardIterator *)
int opt_fill_n
int opt_fwd_iter
int opt_fill
int opt_volatile_ptr
int opt_bidir_iter
int opt_copy
int opt_input_iter
const volatile int * make_iter(const int *beg, const int *, const int *, const volatile int *)
void test_uninitialized_fill(const ForwardIterator *, bool test_count)
int opt_rnd_iter
void run_test(const ForwardIterator &dummy, T *, Predicate *pred)
const char * type_name()
#define main
#define _RWSTD_STATIC_CAST(T, x)
Definition _defs.h:534
_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
Y(int val)
static int ctor_
static int count_
int val_
static int throw_at_
Y(const Y &rhs)
static int dtor_