Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
27.objects.cpp
Go to the documentation of this file.
1
29#include <rw_driver.h>
30
31// If the following macro is defined, then new header provides
32// an implementation for operator new [] & delete []; undef them here
33// so that the test can provide its own implementation for these operators
34#undef _RWSTD_NO_OPERATOR_NEW_ARRAY
35#undef _RWSTD_NO_OPERATOR_DELETE_ARRAY
36
37
38#if defined (__IBMCPP__) && !defined (_RWSTD_NO_IMPLICIT_INCLUSION)
39 // disable implicit inclusion to work around
40 // a limitation in IBM VisualAge 5.0.2.0 (PR #26959)
41
42# define _RWSTD_NO_IMPLICIT_INCLUSION
43#endif
44
45#if !defined (_MSC_VER) || _MSC_VER > 1300
46 // prevent out-of-line template definitions in .cc files from being
47 // explicitly #included during the processing of library headers (faster
48 // compilation) assumes that the test doesn't instantiate those templates
49 // on types other than those they were explcitly instantiated on (will
50 // have no effect if explicit instantiation is disabled or unsupported)
51# define _RWSTD_NO_TEMPLATE_DEFINITIONS
52#endif // !defined (_MSC_VER) || _MSC_VER > 1300
53
54
56{
58
60
62
63
64#ifdef _WIN32
65 // bring in <windows.h> as a compilation test to exercise
66 // any potential collisions with our declarations
67# include <windows.h>
68#endif
69
70// include <iostream> *after* the definition of the global
71// lifetime_checker object to exercise initialization and
72// lifetime dependencies
73#include <iostream> // for cin, cout, ...
74#include <cstdlib> // for free(), malloc()
75
76// make sure using declarations work (the test doesn't actually exploit
77// the fact that the names are introduced into the global namespace)
78
79_USING (std::cin);
80_USING (std::cout);
81_USING (std::cerr);
82_USING (std::clog);
83
84#ifndef _RWSTD_NO_WCHAR_T
85
86_USING (std::wcin);
87_USING (std::wcout);
88_USING (std::wcerr);
89_USING (std::wclog);
90
91#endif // _RWSTD_NO_WCHAR_T
92
93
95int init_new_calls; // number of calls to operator new during initialization
96int init_delete_calls; // and operator delete
97int new_calls; // total number of calls to operator new
98int delete_calls; // and operator delete
99
100int rw_opt_no_global_dtors; // for --no-global-dtors
101int rw_opt_no_replacement_new; // for --no-replacement-new
102int rw_opt_no_replacement_delete; // for --no-replacement-delete
103
104
107{
108 // iostreams not yet initialized here
109 // <iostream> must be included before the definition of any
110 // global object whose ctor uses any of the standard objects
111}
112
113
115{
117 rw_note (0, 0, __LINE__, "test of global dtors disabled");
118 }
119 else {
120 // objects must not be destroyed during program lifetime
121 // try to use them in the destructor of a global object...
122 std::cout << "[output from the dtor of a global object]";
123
124 std::cout << "[cout]";
125 std::cerr << "[cerr]";
126 std::clog << "[clog]";
127
128#ifndef _RWSTD_NO_WCHAR_T
129
130 std::wcout << "[wcout]";
131 std::wcerr << "[wcerr]";
132 std::wclog << "[wclog]";
133
134#endif // _RWSTD_NO_WCHAR_T
135
136 }
137}
138
139
141template <class charT>
143{
144 rw_info (0, 0, 0, "checking whether objects are initialized");
145
146 // objects must exist
147 rw_assert ( 0 != &std::cin && 0 != &std::cout
148 && 0 != &std::cerr && 0 != &std::clog,
149 0, __LINE__, "std::cin, cout, cerr, or clog address 0");
150
151 rw_info (0, 0, __LINE__, "checking tied stream objects");
152
153 int new_0 = new_calls;
154
155 // exercise 27.3.1, p2
156 rw_assert (&std::cout == std::cin.tie (&std::cout), 0, __LINE__,
157 "&std::cout == std::cin.tie (&std::cout)");
158 rw_assert (0 == std::cout.tie (), 0, __LINE__,
159 "0 == std::cout.tie ()");
160 rw_assert (0 == std::cerr.tie (), 0, __LINE__,
161 "0 == std::cerr.tie ()");
162 rw_assert (0 == std::clog.tie (), 0, __LINE__,
163 "0 == std::clog.tie ()");
164
165 rw_assert (0 == new_calls - new_0, 0, __LINE__,
166 "unexpected dynamic memory allocation");
167
168 rw_info (0, 0, __LINE__, "checking for std::ios_base::unitbuf in flags");
169
170 new_0 = new_calls;
171
172 // exercise 27.3.1, p3
173 rw_assert (!(std::ios::unitbuf & std::cout.flags ()), 0, __LINE__,
174 "std::ios::unitbuf & std::cout.flags ()");
175
176 // exercise 27.3.1, p5
177 rw_assert (!!(std::ios::unitbuf & std::cerr.flags ()), 0, __LINE__,
178 "std::ios::unitbuf & std::cerr.flags ()");
179
180 // exercise 27.3.1, p6
181 rw_assert (!(std::ios::unitbuf & std::clog.flags ()), 0, __LINE__,
182 "std::ios::unitbuf & std::clog.flags ()");
183
184 rw_assert (0 == new_calls - new_0, 0, __LINE__,
185 "unexpected dynamic memory allocation");
186
187#ifndef _RWSTD_NO_WCHAR_T
188
189 rw_assert ( 0 != &std::wcin && 0 != &std::wcout
190 && 0 != &std::wcerr && 0 != &std::wclog,
191 0, __LINE__, "std::wcin, wcout, wcerr, or wclog address 0");
192
193 new_0 = new_calls;
194
195 // exercise 27.3.2, p2
196 rw_assert (&std::wcout == std::wcin.tie (&std::wcout), 0, __LINE__,
197 "&std::wcout == std::wcin.tie (&std::wcout)");
198 rw_assert (0 == std::wcout.tie (), 0, __LINE__,
199 "0 == std::wcout.tie ()");
200 rw_assert (0 == std::wcerr.tie (), 0, __LINE__,
201 "0 == std::wcerr.tie ()");
202 rw_assert (0 == std::wclog.tie (), 0, __LINE__,
203 "0 == std::wclog.tie ()");
204
205 rw_assert (0 == new_calls - new_0, 0, __LINE__,
206 "unexpected dynamic memory allocation");
207
208 new_0 = new_calls;
209
210 // exercise 27.3.2, p3
211 rw_assert (!(std::wios::unitbuf & std::wcout.flags ()), 0, __LINE__,
212 "std::wios::unitbuf & std::wcout.flags ()");
213
214 // exercise 27.3.2, p5
215 rw_assert (!!(std::wios::unitbuf & std::wcerr.flags ()), 0, __LINE__,
216 "std::wios::unitbuf & std::wcerr.flags ()");
217
218 // exercise 27.3.2, p6
219 rw_assert (!(std::wios::unitbuf & std::wclog.flags ()), 0, __LINE__,
220 "std::wios::unitbuf & std::wclog.flags ()");
221
222 rw_assert (0 == new_calls - new_0, 0, __LINE__,
223 "unexpected dynamic memory allocation");
224
225#endif // _RWSTD_NO_WCHAR_T
226
227 std::cout << 0.0;
228 std::cerr << 0.0;
229 std::clog << 0.0;
230
231#ifndef _RWSTD_NO_WCHAR_T
232
233 std::wcout << 0.0;
234 std::wcerr << 0.0;
235 std::wclog << 0.0;
236
237#endif // _RWSTD_NO_WCHAR_T
238
239 std::cout << std::endl;
240
241
242 rw_info (0, 0, __LINE__, "exercising the ability to tie each stream "
243 "to itself without causing a deadlock");
244
245 std::cout.tie (&std::cout);
246 std::cout << std::cout.tie () << ' ';
247
248 std::cerr.tie (&std::cerr);
249 std::cerr << std::cerr.tie () << ' ';
250
251 std::clog.tie (&std::clog);
252 std::clog << std::clog.tie () << ' ';
253
254#ifndef _RWSTD_NO_WCHAR_T
255
256 std::wcout.tie (&std::wcout);
257 std::wcout << std::wcout.tie () << ' ';
258
259 std::wcerr.tie (&std::wcerr);
260 std::wcerr << std::wcerr.tie () << ' ';
261
262 std::wclog.tie (&std::wclog);
263 std::wclog << std::wclog.tie () << ' ';
264
265#endif // _RWSTD_NO_WCHAR_T
266
267
268 rw_info (0, 0, __LINE__, "exercising the ability to tie stream objects "
269 "together without causing a deadlock");
270
271 std::cout.tie (&std::cerr);
272 std::cout << std::cout.tie () << ' ';
273
274 std::cerr.tie (&std::cout);
275 std::cerr << std::cerr.tie () << ' ';
276
277 std::clog.tie (&std::cout);
278 std::clog << std::clog.tie () << ' ';
279
280 // untie all streams to free any memory dynamically
281 // allocated by calling tie (p) with (p != 0)
282 std::cin.tie (0);
283 std::cout.tie (0);
284 std::cerr.tie (0);
285 std::clog.tie (0);
286
287#ifndef _RWSTD_NO_WCHAR_T
288
289 std::wcout.tie (&std::wcerr);
290 std::wcout << std::wcout.tie () << ' ';
291
292 std::wcerr.tie (&std::wcout);
293 std::wcerr << std::wcerr.tie () << ' ';
294
295 std::wclog.tie (&std::wcout);
296 std::wclog << std::wclog.tie () << ' ';
297
298 // untie all streams to free any memory dynamically
299 // allocated by calling tie (p) with (p != 0)
300 std::wcin.tie (0);
301 std::wcout.tie (0);
302 std::wcerr.tie (0);
303 std::wclog.tie (0);
304
305#endif // _RWSTD_NO_WCHAR_T
306
307 std::cout << std::endl;
308}
309
310
312static int
313run_test (int, char*[])
314{
315 const int new_0 = new_calls;
316 const int delete_0 = delete_calls;
317
318 do_test (char ());
319
320 const int new_1 = new_calls - new_0;
321 const int delete_1 = delete_calls - delete_0;
322
323 // verify that test doesn't leak any dynamically allocated storage
324 rw_assert (0 == new_1 - delete_1, 0, __LINE__,
325 "test leaked %d blocks of memory", new_1 - delete_1);
326 rw_assert (0 == init_new_calls, 0, __LINE__,
327 "iostream initialization called operator new() %d times, "
328 "0 expected", init_new_calls);
329
330#ifdef _RWSTD_NO_REPLACEABLE_NEW_DELETE
331
332 rw_warn (0, 0, __LINE__,
333 "replacement operators new and delete not tested: "
334 "_RWSTD_NO_REPLACEABLE_NEW_DELETE #defined");
335
336#endif // _RWSTD_NO_REPLACEABLE_NEW_DELETE
337
338 return 0;
339}
340
341
343#ifndef _RWSTD_NO_REPLACEABLE_NEW_DELETE
344
345# include <new>
346
347# ifndef _RWSTD_BAD_ALLOC
348 // #define if not #defined by <new> (SunPro #includes its
349 // own <new> regardless of the preprocessor search path)
350# define _RWSTD_BAD_ALLOC _STD::bad_alloc
351# endif // _RWSTD_BAD_ALLOC
352
353
354void* operator new (std::size_t n) _THROWS ((_RWSTD_BAD_ALLOC))
355{
356 static int recursion;
357
358 ++recursion;
359
361 static int noted; // prevent multiple notes
362
363 rw_note (noted++, 0, __LINE__,
364 "test of replacement operator new disabled");
365 }
366 else if (1 != recursion) {
367 // avoid calling rw_warn() except when it has something
368 // to warn about in case operator new() is being called
369 // by the compiler's C++ runtime (e.g., HP aCC 6.16)
370 // when the driver hasn't been initialized yet (otherwise
371 // the driver aborts)
372 rw_warn (1 == recursion, 0, __LINE__,
373 "recursive call to replacement operator new()");
374 }
375 else {
376 // initialize iostreams (verifies that initialization
377 // succeeds and is complete even if it occurs recursively)
378 static std::ios_base::Init io_initializer;
379
380 // use cout from within new to verify that the static local
381 // ios_base::Init properly initializes iostream objects
382 std::cout << "[replacement operator new (" << n << ")]\n";
383 }
384
385 ++new_calls;
386
387 --recursion;
388
389 void* const ptr = std::malloc (n);
390 if (!ptr)
392
393 return ptr;
394}
395
396
397void operator delete (void *ptr) _THROWS (())
398{
399 static int recursion;
400
401 ++recursion;
402
404 static int noted; // prevent multiple notes
405
406 rw_note (noted++, 0, __LINE__,
407 "test of replacement operator delete disabled");
408 }
409 else if (rw_warn (1 == recursion, 0, __LINE__,
410 "recursive call to replacement operator delete()")) {
411 std::cout << "[replacement operator delete (" << ptr << ")]\n";
412 }
413
414 --recursion;
415
416 if (ptr)
417 ++delete_calls;
418
419 std::free (ptr);
420}
421
422
423void* operator new[] (std::size_t n) _THROWS ((_RWSTD_BAD_ALLOC))
424{
425 return operator new (n);
426}
427
428
429void operator delete[] (void *p) _THROWS (())
430{
431 operator delete (p);
432}
433
434#endif // _RWSTD_NO_REPLACEABLE_NEW_DELETE
435
436
438int main (int argc, char *argv[])
439{
442
443 return rw_test (argc, argv, __FILE__,
444 "lib.iostream.objects",
445 0, // no comment
446 run_test,
447 "|-no-global-dtors# "
448 "|-no-replacement-new# "
449 "|-no-replacement-delete#",
453}
#define ptr
Definition 17.names.cpp:525
#define charT
Definition 17.names.cpp:456
#define n
Definition 17.names.cpp:130
#define p
Definition 17.names.cpp:132
#define flags
void do_test(int line, const char *src, std::size_t resoff, ForwardIterator dummy_iter, const T *, const char *predname)
void run_test(const ForwardIterator &dummy, T *, Predicate *pred)
void tie(std::ostringstream *ps, std::size_t n)
#define _RWSTD_BAD_ALLOC
int rw_opt_no_replacement_new
int rw_opt_no_replacement_delete
int new_calls
struct LifetimeChecker lifetime_check
int rw_opt_no_global_dtors
int init_new_calls
int delete_calls
int init_delete_calls
#define main
#define _THROWS()
#define _THROW(ex)
Definition _defs.h:852
#define _USING(name)
Definition _defs.h:568
_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
_TEST_EXPORT int rw_warn(int, const char *, int, const char *,...)
Definition driver.cpp:1647