Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
27.ostream.cpp
Go to the documentation of this file.
1
30#include <exception> // for uncaught_exception()
31#include <ostream> // for basic_ostream
32#include <climits> // for XXX_MAX and XXX_MIN
33#include <cstddef> // for ptrdiff_t
34#include <cstring> // for memset()
35
36#include <rw_any.h> // for rw_any_t()
37#include <rw_driver.h> // for rw_test()
38
39
41int rw_opt_sentry; // for --enable/disable-sentry
42int rw_opt_formatted; // for --enable/disable-formatted
43int rw_opt_unformatted; // for --enable/disable-unformatted
44int rw_opt_flush; // for --enable/disable-flush
45int rw_opt_exceptions; // for --enable/disable-exceptions
46
47
52};
53
54
55template <class charT>
56struct test_streambuf: std::basic_streambuf<charT, std::char_traits<charT> >
57{
59 typedef std::char_traits<charT> traits_type;
60 typedef std::basic_streambuf<char_type, traits_type> Streambuf;
61 typedef typename Streambuf::int_type int_type;
62 typedef typename Streambuf::off_type off_type;
63 typedef typename Streambuf::pos_type pos_type;
64
65 test_streambuf (std::basic_ios<char_type, traits_type> *pstrm)
66 : Streambuf (), buf_ (0), bufsize_ (0),
68 pstrm_ (pstrm) {
69 std::memset (ncalls_, 0, sizeof ncalls_);
70 this->setp (buf_, buf_);
71 }
72
73 test_streambuf (charT *buf, std::streamsize bufsize)
74 : Streambuf (), buf_ (buf), bufsize_ (bufsize),
76 std::memset (ncalls_, 0, sizeof ncalls_);
77 this->setp (buf_, buf_);
78 }
79
80 bool test (streambuf_failure) const;
81
82 virtual Streambuf* setbuf (char_type*, std::streamsize) {
83 return test (Setbuf) ? this : 0;
84 }
85
86 virtual pos_type
87 seekoff (off_type, std::ios_base::seekdir, std::ios_base::openmode) {
88 test (Seekoff);
89 return pos_type (off_type (-1));
90 }
91
92 virtual pos_type
93 seekpos (pos_type, std::ios_base::openmode) {
94 test (Seekpos);
95 return pos_type (off_type (-1));
96 }
97
98 virtual std::streamsize showmanyc () {
100 return 0;
101 }
102
103 virtual std::streamsize xsgetn (char_type*, std::streamsize) {
104 test (Xsgetn);
105 return 0;
106 }
107
108 virtual int_type underflow () {
109 test (Underflow);
110 return traits_type::eof ();
111 }
112
113 virtual int_type uflow () {
114 test (Uflow);
115 return traits_type::eof ();
116 }
117
118 virtual int_type
119 overflow (int_type = traits_type::eof ());
120
121 virtual int_type
122 pbackfail (int_type = traits_type::eof ()) {
123 test (Pbackfail);
124 return traits_type::eof ();
125 }
126
127 virtual std::streamsize
128 xsputn (const char_type *buf, std::streamsize bufsize) {
129 if (!test (Xsputn))
130 return 0;
131 return Streambuf::xsputn (buf, bufsize);
132 }
133
134 virtual int sync () {
135 if (!test (Sync))
136 return -1;
137
138 if (pstrm_)
139 pstrm_->setstate (std::ios_base::failbit);
140
141 return 0;
142 }
143
145 std::streamsize bufsize_;
146
147 int ncalls_ [Sync + 1]; // number of calls made to each function
148
149 streambuf_failure throws_; // exception value to throw
150 streambuf_failure fails_; // which function to fail
151
152 std::basic_ios<char_type, traits_type> *pstrm_;
153
154 static int fail_when_; // call number on which to fail
155};
156
157
158template <class charT>
160
161
162template <class charT>
163bool
165{
167
168 if (ncalls_ [which] == fail_when_ && throws_ == which)
169 throw which;
170
171 return fails_ != which || ncalls_ [which] != fail_when_;
172}
173
174
175template <class charT>
177test_streambuf<charT>::overflow (int_type c /* = traits_type::eof () */)
178{
179 if (!test (Overflow))
180 return traits_type::eof ();
181
182 if (traits_type::eq_int_type (c, traits_type::eof ()))
183 return traits_type::not_eof (c);
184
185 const std::ptrdiff_t pptr_off = this->pptr () - this->pbase ();
186
187 if ( this->pptr () == this->epptr ()
188 && this->epptr () < buf_ + bufsize_) {
189 this->setp (buf_, this->epptr () + 1);
190 this->pbump (pptr_off + 1);
191 *(this->pptr () - 1) = traits_type::to_char_type (c);
192 return c;
193 }
194
195 return traits_type::eof ();
196}
197
198
199
203
204
205#ifndef _RWSTD_NO_NATIVE_BOOL
206
208
209#endif // _RWSTD_NO_NATIVE_BOOL
210
211template <class T>
213
215num_put_overload select_overload (unsigned short) { return ULong; }
217num_put_overload select_overload (unsigned int) { return ULong; }
219num_put_overload select_overload (unsigned long) { return ULong; }
220
221#ifdef _RWSTD_LONG_LONG
222
225
226#endif
227
230
231#ifndef _RWSTD_NO_LONG_DOUBLE
232
233num_put_overload select_overload (long double) { return LDbl; }
234
235#endif // _RWSTD_NO_LONG_DOUBLE
236
237num_put_overload select_overload (const void*) { return PVoid; }
238
239
240template <class charT>
241struct test_num_put: std::num_put<charT, std::ostreambuf_iterator<charT> >
242{
244 typedef std::ostreambuf_iterator<charT> iter_type;
245 typedef std::num_put<charT, iter_type> NumPut;
246 typedef std::ios_base Ios;
247
248 explicit test_num_put (std::size_t refs = 0)
249 : NumPut (refs),
252 std::memset (ncalls_, 0, sizeof ncalls_);
253 }
254
256
257#define TEST(it, val) test (it, select_overload (val))
258
259#ifndef _RWSTD_NO_NATIVE_BOOL
260
261 virtual iter_type
262 do_put (iter_type it, Ios &fl, char_type fill, bool val) const {
263 return NumPut::do_put (TEST (it, val), fl, fill, val);
264 }
265
266#endif // _RWSTD_NO_NATIVE_BOOL
267
268 virtual iter_type
269 do_put (iter_type it, Ios &fl, char_type fill, long val) const {
270 return NumPut::do_put (TEST (it, val), fl, fill, val);
271 }
272
273 virtual iter_type
274 do_put (iter_type it, Ios &fl, char_type fill, unsigned long val) const {
275 return NumPut::do_put (TEST (it, val), fl, fill, val);
276 }
277
278 virtual iter_type
279 do_put (iter_type it, Ios &fl, char_type fill, double val) const {
280 return NumPut::do_put (TEST (it, val), fl, fill, val);
281 }
282
283 virtual iter_type
284 do_put (iter_type it, Ios &fl, char_type fill, long double val) const {
285 return NumPut::do_put (TEST (it, val), fl, fill, val);
286 }
287
288 virtual iter_type
289 do_put (iter_type it, Ios &fl, char_type fill, const void *val) const {
290 return NumPut::do_put (TEST (it, val), fl, fill, val);
291 }
292
293#ifdef _RWSTD_LONG_LONG
294
295 // extensions
296 virtual iter_type
298 _RWSTD_LONG_LONG val) const {
299 return NumPut::do_put (TEST (it, val), fl, fill, val);
300 }
301
302 virtual iter_type
304 unsigned _RWSTD_LONG_LONG val) const {
305 return NumPut::do_put (TEST (it, val), fl, fill, val);
306 }
307
308#endif // _RWSTD_LONG_LONG
309
310#undef TEST
311
312 int ncalls_ [ULLong + 1];
315};
316
317
318template <class charT>
321{
322 ++_RWSTD_CONST_CAST (test_num_put*, this)->ncalls_ [which];
323
324 if (throws_ == which)
325 throw which;
326
327 if (fails_ == which) {
328
329 // construct an iter_type object in a failed state
330 test_streambuf<charT> tsb (0, 0);
331 iter_type failed (&tsb);
332 failed = char_type ();
333
334 _RWSTD_ASSERT (failed.failed ());
335
336 return failed;
337 }
338
339 return it;
340}
341
342
344bool uncaught = false;
345
346
347template <class charT>
349{
350 typedef std::basic_ostream<charT, std::char_traits<charT> > Ostream;
351 typedef typename Ostream::sentry Sentry;
352
354
356
357#ifndef _RWSTD_UNCAUGHT_EXCEPTION
358
359 uncaught = std::uncaught_exception ();
360
361#endif // _RWSTD_UNCAUGHT_EXCEPTION
362
363 const Sentry guard (*pstrm_);
364 }
365};
366
367
368template <class charT>
370{
371 static const char* const cname = rw_any_t (charT ()).type_name ();
372
373 typedef std::basic_ostream<charT, std::char_traits<charT> > Ostream;
374 typedef typename Ostream::sentry Sentry;
375
376 const Sentry *pguard = 0;
377
378 {
379 rw_info (0, 0, __LINE__,
380 "std::basic_ostream<%s>::sentry::sentry "
381 "(basic_ostream&)", cname);
382
383 // verify that sentry ctor handles streams with rdbuf() == 0
384 static Ostream strm (0);
385
386 strm.setf (std::ios_base::unitbuf);
387
388 // pguard will be deleted in sentry dtor block
389 pguard = new Sentry (strm);
390 }
391
392 {
393 // verify 27.6.2.3, p2 and 3:
394 //
395 // explicit sentry(basic_ostream<charT,traits>& os);
396 //
397 // -2- If os.good() is nonzero, prepares for formatted or
398 // unformatted output. If os.tie() is not a null pointer,
399 // calls os.tie()->flush().
400 // -3- If, after any preparation is completed, os.good() is
401 // true, ok_ == true otherwise, ok_ == false.
402
403 // verify that sentry ctor calls stream.tie()->flush() once
404 // and that the object returns true when converted to bool
405 test_streambuf<charT> tsb_tied (0);
406 test_streambuf<charT> tsb_strm (0);
407
408 Ostream tied (&tsb_tied);
409 Ostream strm (&tsb_strm);
410
411 strm.tie (&tied);
412
413 int nsyncs = tsb_tied.ncalls_ [Sync];
414
415 const Sentry guard (strm);
416
417 rw_assert (1 + nsyncs == tsb_tied.ncalls_ [Sync], 0, __LINE__,
418 "std::basic_ostream<%s>::sentry::sentry "
419 "(basic_ostream &s) called s.tie ()->flush() once; "
420 "got %d times",
421 cname, tsb_tied.ncalls_ [Sync] - nsyncs);
422
423 rw_info (0, 0, __LINE__, "std::basic_ostream<%s>::sentry::operator "
424 "bool () const", cname);
425
426 rw_assert (bool (guard), 0, __LINE__,
427 "std::basic_ostream<%s>::sentry::operator bool() == true "
428 "after a successful construction", cname);
429 }
430
431 {
432 // verify 27.6.2.3, p3: i.e., same as above, but check that
433 // the ctor sets ok_ to false after the preparation fails
434 // (which is done by having stream.tie()->flush() call
435 // stream.setf (failbit))
436
437 test_streambuf<charT> tsb_strm (0);
438 Ostream strm (&tsb_strm);
439
440 // create a use-defined streambuf object and associate it
441 // with the stream object, strm, constructed above so that
442 // when the latter calls strm.tie()->flush() the former
443 // can set failbit in strm
444 test_streambuf<charT> tsb_tied (&strm);
445 Ostream tied (&tsb_tied);
446
447 // tie the two streams together
448 strm.tie (&tied);
449
450 // sentry ctor calls strm.tie()->flush() which sets failbit
451 // in strm's; the sentry ctor should detect this condition
452 const Sentry guard (strm);
453
454 rw_assert (!guard, 0, __LINE__,
455 "std::basic_ostream<%s>::sentry::operator bool() == "
456 "false after a failed construction (stream.rdstate() "
457 "== %{Is})", cname, strm.rdstate ());
458 }
459
460 {
461 // verify 27.6.2.3, p3: i.e., same as above, but check that
462 // stream.tie()->flush() is not called when stream.good() is
463 // false
464
465 test_streambuf<charT> tsb_strm (0);
466 Ostream strm (&tsb_strm);
467
468 // create a use-defined streambuf object and associate it
469 // with the stream object, strm, constructed above to keep
470 // track of the number of any calls to sync() from flush()
471 test_streambuf<charT> tsb_tied (&strm);
472 Ostream tied (&tsb_tied);
473
474 // tie the two streams together
475 strm.tie (&tied);
476
477 strm.setstate (std::ios_base::failbit);
478
479 // sentry ctor should not call strm.tie()->flush() if
480 // strm.good() returns false
481 const Sentry guard (strm);
482
483 rw_assert (!tsb_tied.ncalls_ [Sync], 0, __LINE__,
484 "std::basic_ostream<%s>::sentry::sentry(basic_ostream&) "
485 "unexpectedly called stream.tie()->flush() when "
486 "stream.good() == false", cname);
487
488 rw_assert (!guard, 0, __LINE__,
489 "std::basic_ostream<%s>::sentry::operator bool() == "
490 "false for a stream whose stream.rdstate() = %{Is}",
491 cname, strm.rdstate ());
492 }
493
494#ifndef _RWSTD_NO_EXCEPTIONS
495
496 if (0 <= rw_opt_exceptions) {
497
498 test_streambuf<charT> tsb_strm (0);
499 Ostream strm (&tsb_strm);
500
501 test_streambuf<charT> tsb_tied (&strm);
502 Ostream tied (&tsb_tied);
503
504 strm.tie (&tied);
505
506 tsb_tied.throws_ = Sync;
507
508 // verify that an exception thrown during the call to
509 // strm.tie()->flush() is caught and not propagated, and in
510 // response to it badbit is set in the tied stream, but that
511 // strm is not affected in any way
512 try {
513
514 // sentry ctor calls strm.tie()->flush() which should call
515 // strm.tie()->flush() (or its equivalent), which in turn
516 // calls rdbuf()->pubsync() which throws an exception (from
517 // the virtual overridden above)
518 // the sentry ctor must not prevent badbit from being set
519 // in the tied stream but it must not allow the exception
520 // to propagate to its caller
521 const Sentry guard (strm);
522
523 rw_assert (!!guard, 0, __LINE__,
524 "std::basic_ostream<%s>::sentry::operator bool() == "
525 "true after it failed to flush a tied stream due to "
526 "an exception (stream.rdstate() == %{Is})",
527 cname, strm.rdstate ());
528 }
529 catch (...) {
530 rw_assert (false, 0, __LINE__,
531 "std::basic_ostream<%s>::sentry::sentry(basic_ostream&)"
532 " unexpectedly allowed an exception to propagate",
533 cname);
534 }
535
536 // verify that the sentry ctor did not affect the state of the stream
537 // as a result of the exception thrown during the flushing of the tied
538 // stream
539 rw_assert (strm.good (), 0, __LINE__,
540 "std::basic_ostream<%s>::sentry::sentry(basic_ostream&) "
541 "unexpectedly affected the state of the stream as a result "
542 "pf an exception thrown during the flushing of a tied "
543 "stream; stream state = %{Is}", cname, strm.rdstate ());
544
545 // verify that the the tied stream object's state has set badbit
546 // in response to the exception thrown from its stream buffer
547 rw_assert (tied.bad (), 0, __LINE__,
548 "std::basic_ostream<%s>::sentry::sentry(basic_ostream&) "
549 "failed to cause badbit to be set in stream's tied object "
550 "after an exception; tied stream's state = %{Is}",
551 cname, tied.rdstate ());
552 }
553
554#endif // _RWSTD_NO_EXCEPTIONS
555
556 {
557 rw_info (0, 0, __LINE__,
558 "std::basic_ostream<%s>::sentry::~sentry()", cname);
559
560 // verify that sentry dtor handles streams with rdbuf() == 0
561
562 // pguard dynamically constructed in sentry ctor block
563 delete pguard;
564 }
565
566 {
567 // verify 27.6.2.3, p4:
568 //
569 // ~sentry();
570 //
571 // -4- If ((os.flags() & iose::unitbuf) && !uncaught_exception())
572 // is true, calls os.flush().
573
574 test_streambuf<charT> tsb (0);
575 Ostream strm (&tsb);
576
577 int nsyncs;
578
579 // verify that os.flush() is not called if ios::unitbuf is clear
580 {
581 const Sentry guard (strm);
582
583 nsyncs = tsb.ncalls_ [Sync];
584 }
585
586 rw_assert (nsyncs == tsb.ncalls_ [Sync], 0, __LINE__,
587 "std::basic_ostream<%s>::sentry::~sentry() unexpectedly "
588 "called stream.flush () when ios::unitbuf is clear",
589 cname);
590
591 // verify that os.flush() is called if ios::unitbuf is set
592 // (assuming uncaugt_exception() returns false
593 {
594 strm.setf (std::ios_base::unitbuf);
595
596 const Sentry guard (strm);
597
598 nsyncs = tsb.ncalls_ [Sync];
599 }
600
601 rw_assert (1 + nsyncs == tsb.ncalls_ [Sync], 0, __LINE__,
602 "std::basic_ostream<%s>::sentry::~sentry() failed to call "
603 "stream.flush () when ios::unitbuf is set",
604 cname);
605
606#ifndef _RWSTD_NO_EXCEPTIONS
607# ifndef _RWSTD_NO_UNCAUGHT_EXCEPTION
608
609 if (0 <= rw_opt_exceptions) {
610
611 // verify that os.flush() is not called if ios::unitbuf is set
612 // but uncaught_exception() returns true
613
614 nsyncs = tsb.ncalls_ [Sync];
615
616 try {
617 strm.setf (std::ios_base::unitbuf);
618
619 DtorChek<charT> to_be_destroyed;
620
621 to_be_destroyed.pstrm_ = &strm;
622
623 throw 0;
624 }
625 catch (...) {
626 }
627
628 rw_assert (nsyncs == tsb.ncalls_ [Sync], 0, __LINE__,
629 "std::basic_ostream<%s>::sentry::~sentry() "
630 "unexpectedly called stream.flush() when "
631 "ios::unitbuf is set but uncaught_exception() "
632 "returns true", cname);
633
634 rw_assert (uncaught, 0, __LINE__,
635 "std::uncaught_exception () == true when an exception "
636 "is pending (language runtime library error)");
637 }
638
639# endif // _RWSTD_NO_UNCAUGHT_EXCEPTION
640#endif // _RWSTD_NO_EXCEPTIONS
641
642 }
643}
644
645
646
649// for convenience
650#define Boolalpha std::ios_base::boolalpha
651#define Dec std::ios_base::dec
652#define Fixed std::ios_base::fixed
653#define Hex std::ios_base::hex
654#define Internal std::ios_base::internal
655#define Left std::ios_base::left
656#define Oct std::ios_base::oct
657#define Right std::ios_base::right
658#define Scientific std::ios_base::scientific
659#define Showbase std::ios_base::showbase
660#define Showpoint std::ios_base::showpoint
661#define Showpos std::ios_base::showpos
662#define Skipws std::ios_base::skipws
663#define Unitbuf std::ios_base::unitbuf
664#define Uppercase std::ios_base::uppercase
665#define Bin std::ios_base::bin
666#define Adjustfield std::ios_base::adjustfield
667#define Basefield std::ios_base::basefield
668#define Floatfield std::ios_base::floatfield
669#define Nolock std::ios_base::nolock
670#define Nolockbuf std::ios_base::nolockbuf
671
672#define Bad std::ios_base::badbit
673#define Eof std::ios_base::eofbit
674#define Fail std::ios_base::failbit
675#define Good std::ios_base::goodbit
676
677
678const int Throw = 1 << 16;
679
680
681template <class charT, class T>
682void test_formatted (charT, int line1, int line2,
683 T val,
684 const char *str,
685 int fmtflags,
686 int width,
687 int fill,
688 int rdstate,
689 int exceptions,
690 int failure = 0,
691 int fail_when = 1)
692{
693 static const char* const cname = rw_any_t (charT ()).type_name ();
694 static const char* const tname = rw_any_t (T ()).type_name ();
695
696 typedef std::basic_ostream<charT, std::char_traits<charT> > Ostream;
697
698 charT charbuf [256] = { 0 };
699
700 // define prior to the definition of `tsb' below
701 // to guarantee the proper order of destruction
702 test_num_put<charT> tnp (1);
703
704 test_streambuf<charT> tsb (charbuf, sizeof charbuf / sizeof *charbuf);
705
706 if (failure & Throw) {
707 failure &= ~Throw;
708
709 if (failure < Bool)
710 tsb.throws_ = streambuf_failure (failure);
711 else
712 tnp.throws_ = num_put_overload (failure);
713 }
714 else {
715 if (failure < Bool)
716 tsb.fails_ = streambuf_failure (failure);
717 else
718 tnp.fails_ = num_put_overload (failure);
719 }
720
721 tsb.fail_when_ = fail_when;
722
723 Ostream os (&tsb);
724
725 if (select_overload (T ())) {
726
727 // for arithmetic types and void*, imbue a custom num_put facet
728 os.imbue (std::locale (std::locale::classic (), &tnp));
729 }
730
731 os.flags (std::ios_base::fmtflags (fmtflags));
732 os.width (std::streamsize (width));
733 os.exceptions (std::ios_base::iostate (exceptions));
734
735 if (-1 != fill)
736 os.fill (charT (fill));
737
738 enum { E_unknown = 1, E_failure };
739 int caught = 0;
740
741 const char *caught_what = "none (none thrown)";
742
743 try {
744 os << val;
745 }
746 catch (streambuf_failure e) {
747 caught = e;
748 caught_what = "streambuf_failure";
749 }
750 catch (num_put_overload e) {
751 caught = e;
752 caught_what = "num_put_overload";
753 }
754 catch (const std::ios_base::failure&) {
755 caught = E_failure;
756 caught_what = "std::ios_base::failure";
757 }
758 catch (...) {
759 caught = E_unknown;
760 caught_what = "unknown exception";
761 }
762
763 if (str) {
764 char cbuf [256] = "";
765 for (std::size_t i = 0; i != sizeof cbuf && str [i]; ++i)
766 cbuf [i] = char (charbuf [i]);
767
768 rw_assert (0 == std::strcmp (cbuf, str), __FILE__, line1,
769 "%d. std::basic_ostream<%s>::operator<<(%s = %{#lc}) "
770 "inserted \"%s\", expected \"%s\"",
771 line2, cname, tname, cbuf, str);
772 }
773
774 // verify that stream is in the expected state
775 rw_assert (rdstate == os.rdstate (), __FILE__, line1,
776 "%d. std::basic_ostream<%s>::operator<<(%s = %{#lc})"
777 ".rdstate() == %{Is}, got %{Is}",
778 line2, cname, tname, val, rdstate, os.rdstate ());
779
780 if (!tsb.throws_ && !tnp.throws_) {
781
782 bool pass;
783
784#ifdef _RWSTD_NO_EXT_KEEP_WIDTH_ON_FAILURE
785 // verify that width(0) has been called (unless there are exceptions
786 // involved, in which case it's unspecified whether width(0) has or
787 // has not been called
788 pass = !((!exceptions || !tsb.fails_ && !tnp.fails_) && os.width ());
789
790 rw_assert (pass, __FILE__, line1,
791 "%d. std::basic_ostream<%s>::operator<<(%s = %{#lc})"
792 ".width () == 0, got %d",
793 line2, cname, tname, val, os.width ());
794#endif // _RWSTD_NO_EXT_KEEP_WIDTH_ON_FAILURE
795
796 // verify that ios_base::failure has been thrown (and caught)
797 // if badbit is set in exceptions
798 pass = !(exceptions & os.rdstate () && caught != E_failure);
799
800 rw_assert (pass, __FILE__, line1,
801 "%d. std::basic_ostream<%s>::operator<<(%s = %{#lc}) "
802 "set %{Is} but failed to throw ios_base::failure "
803 "when the same bit is set in exceptions",
804 line2, cname, tname, val, rdstate);
805 }
806
807 if (tsb.throws_) {
808
809 // verify that the same exception (and not ios_base::failure)
810 // as the one thrown from basic_filebuf has been propagated
811 // and caught when badbit is set in exceptions, and that no
812 // exception has been thrown if exceptions is clear
813 if (exceptions & Bad && caught != tsb.throws_) {
814
815 rw_assert (false, __FILE__, line1,
816 "%d. std::basic_ostream<%s>::operator<<(%s = %{#lc}) "
817 "failed to propagate an exception thrown by "
818 "basic_filebuf; caught %s instead",
819 line2, cname, tname, val, caught_what);
820 }
821 else {
822 rw_assert ((exceptions & Bad) || !caught, 0, line1,
823 "%d. std::basic_ostream<%s>::operator<<(%s = %{#lc}) "
824 "propagated an exception thrown by basic_filebuf "
825 "when ios_base::badbit is clear in exceptions",
826 line2, cname, tname, val);
827 }
828 }
829
830 if (tnp.throws_) {
831
832 // verify that the same exception (and not ios_base::failure)
833 // as the one thrown from num_put has been propagated and caught
834 // when badbit is set in exceptions, and that no exception has
835 // been thrown if exceptions is clear
836 if (exceptions & Bad)
837 rw_assert (caught == tnp.throws_, 0, line1,
838 "%d. std::basic_ostream<%s>::operator<<(%s = %{#lc}) "
839 "failed to propagate exception thrown by "
840 "basic_filebuf; caught %s instead",
841 line2, cname, tname, val, caught_what);
842 else
843 rw_assert (!caught, __FILE__, line1,
844 "%d. std::basic_ostream<%s>::operator<<(%s = %{#lc}) "
845 "propagated an exception thrown by basic_filebuf"
846 "when ios_base::badbit is clear in exceptions",
847 line2, cname, tname, val);
848 }
849}
850
851
853template <class charT>
854bool is_char (charT) { return false; }
855
856bool is_char (char) { return true; }
857bool is_char (signed char) { return true; }
858bool is_char (unsigned char) { return true; }
859
860bool is_char (const char*) { return true; }
861bool is_char (const signed char*) { return true; }
862bool is_char (const unsigned char*) { return true; }
863
864template <class charT>
865bool is_wchar_t (charT) { return false; }
866
867#ifndef _RWSTD_NO_WCHAR_T
868
869bool is_wchar_t (wchar_t) { return true; }
870bool is_wchar_t (const wchar_t*) { return true; }
871
872#endif // _RWSTD_NO_WCHAR_T
873
874
875template <class charT, class T>
877 int flags, int width, const char *str, int fill = -1)
878{
879 static const char* const cname = rw_any_t (charT ()).type_name ();
880 static const char* const tname = rw_any_t (T ()).type_name ();
881
882 static int done = 0;
883
884 if (!done++) {
885 // show message only the first time for each specialization
886
887 if (is_char (T ()) || is_wchar_t (T ()))
888 rw_info (0, 0, __LINE__,
889 "std::operator<<(basic_ostream<%s>&, %s)", cname, tname);
890 else
891 rw_info (0, 0, __LINE__,
892 "std::basic_ostream<%s>::operator<<(%s)", cname, tname);
893 }
894
895 // determine which overload of num_put::put() is expected
896 // to be called for a value of type T; 0 for non-numeric
897 const int npo = select_overload (val);
898
899 typedef std::basic_ostream<charT, std::char_traits<charT> > Ostream;
900
901#define T charT (), line, __LINE__
902#define TEST test_formatted
903
904 TEST (T, val, str, flags, width, fill, Good, 0, 0);
905
906 if (npo) {
907 // exercise the behavior of basic_ostream with exception bits
908 // clear when num_put fails by returning an ostreambuf_iterator
909 // in a failed state (expect ios::badbit to be set w/o throwing
910 // an exception)
911 TEST (T, val, "", flags, width, fill, Bad, 0, npo);
912
913 // exercise the behavior of basic_ostream with ios::badbit
914 // set in exceptions when num_put fails by returning an
915 // ostreambuf_iterator in a failed state (expect ios::badbit
916 // to be set and ios::failure to be thrown)
917 TEST (T, val, "", flags, width, fill, Bad, Bad, npo);
918
919 // exercise the behavior of basic_ostream with exceptions bits
920 // clear when num_put fails by throwing an exception (expect
921 // ios::badbit to be set and no exception to propagate)
922 TEST (T, val, "", flags, width, fill, Bad, 0, Throw | npo);
923
924 // exercise the behavior of basic_ostream with ios::badbit
925 // set in exceptions when num_put fails by throwing an exception
926 // (expect ios::badbit to be set and the original exception to
927 // propagate)
928 TEST (T, val, "", flags, width, fill, Bad, Bad, Throw | npo);
929 }
930
931 // exercise the behavior of basic_ostream with exception bits clear
932 // when basic_streambuf::overflow() fails by returning eof() (expect
933 // ios::badbit to be set w/o throwing an exception)
934 TEST (T, val, "", flags, width, fill, Bad, 0, Overflow);
935
936 // exercise the behavior of basic_ostream with ios::badbit set in
937 // exceptions when basic_streambuf::overlow() fails by returning
938 // eof() (expect ios::badbit to be set and ios::failure to be thrown)
939 TEST (T, val, "", flags, width, fill, Bad, Bad, Overflow);
940
941 // exercise the behavior of basic_ostream with exceptions bits clear
942 // when basic_streambuf::overlow() fails by throwing an exception
943 // (expect ios::badbit to be set and no exception to propagate)
944 TEST (T, val, "", flags, width, fill, Bad, 0, Throw | Overflow);
945
946 // exercise the behavior of basic_ostream with ios::badbit set in
947 // exceptions when basic_streambuf::overflow() fails by throwing
948 // an exception (expect ios::badbit to be set and the original
949 // exception to propagate)
950 TEST (T, val, "", flags, width, fill, Bad, Bad, Throw | Overflow);
951}
952
953
956template <class charT>
958{
959#undef T
960#define T(val) charT (), __LINE__, val
961
962#undef TEST
963#define TEST test_formatted
964
966 // exercise operator<< (basic_ostream, char)
967
968 // +------------ character to insert
969 // | +------- fmtflags
970 // | | +---- field width
971 // | | | +- expected output
972 // | | | |
973 // v v v v
974 TEST (T ('a'), 0, 0, "a");
975 TEST (T ('A'), 0, 0, "A");
976 TEST (T ('@'), 0, 1, "@");
977 TEST (T ('#'), 0, 2, " #");
978
979 if (is_wchar_t (charT ())) {
980
981#ifndef _RWSTD_NO_NATIVE_WCHAR_T
982
984 // exercise operator<< (basic_ostream, wchar_t)
985 TEST (T (L'b'), 0, 0, "b");
986 TEST (T (L'B'), 0, 0, "B");
987
988#endif // _RWSTD_NO_NATIVE_WCHAR_T
989
990 }
991 else {
992
993 // no operator<< (basic_ostream<wchar_t>, {signed,unsigned} char)
994
996 // exercise operator<< (basic_ostream, signed char)
997 typedef signed char SChar;
998
999 TEST (T (SChar ('b')), 0, 0, "b");
1000 TEST (T (SChar ('B')), 0, 0, "B");
1001
1003 // exercise operator<< (basic_ostream, signed char)
1004 typedef unsigned char UChar;
1005
1006 TEST (T (UChar ('c')), 0, 0, "c");
1007 TEST (T (UChar ('C')), 0, 0, "C");
1008 }
1009
1010
1011#ifndef _RWSTD_NO_NATIVE_BOOL
1012
1014 // exercise basic_ostream::operator<< (bool)
1015 TEST (T (false), 0, 0, "0");
1016 TEST (T (true), 0, 0, "1");
1017
1018 TEST (T (false), Hex | Showbase, 0, "0");
1019 TEST (T (true), Hex | Showbase, 0, "0x1");
1020
1021 TEST (T (false), Boolalpha, 0, "false");
1022 TEST (T (true), Boolalpha, 0, "true");
1023
1024#endif // _RWSTD_NO_NATIVE_BOOL
1025
1026
1028 // exercise basic_ostream::operator<< (short)
1029 TEST (T (short ( 0)), 0, 0, "0");
1030 TEST (T (short ( 1)), 0, 0, "1");
1031 TEST (T (short (-1)), 0, 0, "-1");
1032
1033#if SHRT_MAX == 32767
1034
1035 TEST (T (short (SHRT_MAX)), 0, 0, "32767");
1036 TEST (T (short (SHRT_MIN)), 0, 0, "-32768");
1037
1038 TEST (T (short (SHRT_MAX)), Hex, 0, "7fff");
1039 TEST (T (short (SHRT_MIN)), Hex, 0, "8000");
1040
1041#elif SHRT_MAX == 2147483647
1042
1043 TEST (T (short (SHRT_MAX)), 0, 0, "2147483647");
1044 TEST (T (short (SHRT_MIN)), 0, 0, "-2147483648");
1045
1046 TEST (T (short (SHRT_MAX)), Hex, 0, "ffffffff");
1047 TEST (T (short (SHRT_MIN)), Hex, 0, "80000000");
1048
1049#endif // SHRT_MAX
1050
1052 // exercise basic_ostream::operator<< (unsigned short)
1053 typedef unsigned short UShort;
1054
1055 TEST (T (UShort ( 0)), 0, 0, "0");
1056 TEST (T (UShort ( 1)), 0, 0, "1");
1057 TEST (T (UShort (255)), 0, 0, "255");
1058
1059#if USHRT_MAX == 0xffffU
1060
1061 TEST (T (UShort (USHRT_MAX)), 0, 0, "65535");
1062 TEST (T (UShort (USHRT_MAX)), Hex, 0, "ffff");
1063
1064#elif USHRT_MAX == 0xffffffffU
1065
1066 TEST (T (UShort (SHRT_MAX)), 0, 0, "4294967295");
1067 TEST (T (UShort (SHRT_MAX)), Hex, 0, "ffffffff");
1068
1069#endif // USHRT_MAX
1070
1072 // exercise basic_ostream::operator<< (int)
1073 TEST (T ( 0), 0, 0, "0");
1074 TEST (T ( 1), 0, 0, "1");
1075 TEST (T (-1), 0, 0, "-1");
1076
1077#if INT_MAX == 32767
1078
1079 TEST (T (INT_MAX), 0, 0, "32767");
1080 TEST (T (INT_MIN), 0, 0, "-32768");
1081
1082 TEST (T (INT_MAX), Hex, 0, "7fff");
1083 TEST (T (INT_MIN), Hex, 0, "8000");
1084
1085#elif INT_MAX == 2147483647
1086
1087 TEST (T (INT_MAX), 0, 0, "2147483647");
1088 TEST (T (INT_MIN), 0, 0, "-2147483648");
1089
1090 TEST (T (INT_MAX), Hex, 0, "7fffffff");
1091 TEST (T (INT_MIN), Hex, 0, "80000000");
1092
1093#elif INT_MAX == 9223372036854775807
1094
1095 TEST (T (INT_MAX), 0, 0, "9223372036854775807");
1096 TEST (T (INT_MIN), 0, 0, "-9223372036854775808");
1097
1098 TEST (T (INT_MAX), Hex, 0, "7fffffffffff");
1099 TEST (T (INT_MIN), Hex, 0, "800000000000");
1100
1101#endif // INT_MAX
1102
1104 // exercise basic_ostream::operator<< (unsigned int)
1105 TEST (T ( 0), 0, 0, "0");
1106 TEST (T ( 1), 0, 0, "1");
1107 TEST (T (255), 0, 0, "255");
1108
1109#if UINT_MAX == 0xffffU
1110
1111 TEST (T (UINT_MAX), 0, 0, "65535");
1112 TEST (T (UINT_MAX), Hex, 0, "ffff");
1113
1114#elif UINT_MAX == 0xffffffffU
1115
1116 TEST (T (UINT_MAX), 0, 0, "4294967295");
1117 TEST (T (UINT_MAX), Hex, 0, "ffffffff");
1118
1119#elif UINT_MAX == 0xffffffffffffffffU
1120
1121 TEST (T (UINT_MAX), 0, 0, "18446744073709551615");
1122 TEST (T (UINT_MAX), Hex, 0, "ffffffffffffffff");
1123
1124#endif // UINT_MAX
1125
1127 // exercise basic_ostream::operator<< (long)
1128 TEST (T ( 0L), 0, 0, "0");
1129 TEST (T ( 1L), 0, 0, "1");
1130 TEST (T (-1L), 0, 0, "-1");
1131
1132#if LONG_MAX == 32767L
1133
1134 TEST (T (LONG_MAX), 0, 0, "32767");
1135 TEST (T (LONG_MIN), 0, 0, "-32768");
1136
1137 TEST (T (LONG_MAX), Hex, 0, "7fff");
1138 TEST (T (LONG_MIN), Hex, 0, "8000");
1139
1140#elif LONG_MAX == 2147483647L
1141
1142 TEST (T (LONG_MAX), 0, 0, "2147483647");
1143 TEST (T (LONG_MIN), 0, 0, "-2147483648");
1144
1145 TEST (T (LONG_MAX), Hex, 0, "7fffffff");
1146 TEST (T (LONG_MIN), Hex, 0, "80000000");
1147
1148#elif LONG_MAX == 9223372036854775807L
1149
1150 TEST (T (LONG_MAX), 0, 0, "9223372036854775807");
1151 TEST (T (LONG_MIN), 0, 0, "-9223372036854775808");
1152
1153 TEST (T (LONG_MAX), Hex, 0, "7fffffffffff");
1154 TEST (T (LONG_MIN), Hex, 0, "800000000000");
1155
1156#endif // LONG_MAX
1157
1159 // exercise basic_ostream::operator<< (unsigned int)
1160
1161 TEST (T ( 0UL), 0, 0, "0");
1162 TEST (T ( 1UL), 0, 0, "1");
1163 TEST (T (257UL), 0, 0, "257");
1164
1165#if ULONG_MAX == 0xffffUL
1166
1167 TEST (T (ULONG_MAX), 0, 0, "65535");
1168 TEST (T (ULONG_MAX), Hex, 0, "ffff");
1169
1170#elif ULONG_MAX == 0xffffffffUL
1171
1172 TEST (T (ULONG_MAX), 0, 0, "4294967295");
1173 TEST (T (ULONG_MAX), Hex, 0, "ffffffff");
1174
1175#elif ULONG_MAX == 0xffffffffffffffffUL
1176
1177 TEST (T (ULONG_MAX), 0, 0, "18446744073709551615");
1178 TEST (T (ULONG_MAX), Hex, 0, "ffffffffffffffff");
1179
1180#endif // ULONG_MAX
1181
1182#ifdef _RWSTD_LONG_LONG
1183
1185 // exercise basic_ostream::operator<< (long long)
1186 typedef _RWSTD_LONG_LONG LongLong;
1187
1188 TEST (T (LongLong ( 0)), 0, 0, "0");
1189 TEST (T (LongLong ( 1)), 0, 0, "1");
1190 TEST (T (LongLong (-1)), 0, 0, "-1");
1191
1192 // avoid using the preprocessor here to prevent warnings
1193 // or errors about invalid preprocessor constants (e.g.,
1194 // PR #28595)
1195 if (_RWSTD_LLONG_MAX == 32767L) {
1196
1197 TEST (T (_RWSTD_LLONG_MAX), 0, 0, "32767");
1198 TEST (T (_RWSTD_LLONG_MIN), 0, 0, "-32768");
1199
1200 TEST (T (_RWSTD_LLONG_MAX), Hex, 0, "7fff");
1201 TEST (T (_RWSTD_LLONG_MIN), Hex, 0, "8000");
1202 }
1203 else if (_RWSTD_LLONG_MAX == 2147483647L) {
1204
1205 TEST (T (_RWSTD_LLONG_MAX), 0, 0, "2147483647");
1206 TEST (T (_RWSTD_LLONG_MIN), 0, 0, "-2147483648");
1207
1208 TEST (T (_RWSTD_LLONG_MAX), Hex, 0, "7fffffff");
1209 TEST (T (_RWSTD_LLONG_MIN), Hex, 0, "80000000");
1210
1211 }
1212 else if (_RWSTD_LLONG_MAX > 2147483647L) {
1213
1214 TEST (T (_RWSTD_LLONG_MAX), 0, 0, "9223372036854775807");
1215 TEST (T (_RWSTD_LLONG_MIN), 0, 0, "-9223372036854775808");
1216
1217 TEST (T (_RWSTD_LLONG_MAX), Hex, 0, "7fffffffffff");
1218 TEST (T (_RWSTD_LLONG_MIN), Hex, 0, "800000000000");
1219
1220 }
1221
1223 // exercise basic_ostream::operator<< (unsigned long long)
1224
1225 typedef unsigned _RWSTD_LONG_LONG ULongLong;
1226
1227 TEST (T (ULongLong ( 0)), 0, 0, "0");
1228 TEST (T (ULongLong ( 1)), 0, 0, "1");
1229 TEST (T (ULongLong (257)), 0, 0, "257");
1230
1231 if (_RWSTD_ULLONG_MAX == 0xffffUL) {
1232 TEST (T (_RWSTD_ULLONG_MAX), 0, 0, "65535");
1233 TEST (T (_RWSTD_ULLONG_MAX), Hex, 0, "ffff");
1234 }
1235 else if (_RWSTD_ULLONG_MAX == 0xffffffffUL) {
1236 TEST (T (_RWSTD_ULLONG_MAX), 0, 0, "4294967295");
1237 TEST (T (_RWSTD_ULLONG_MAX), Hex, 0, "ffffffff");
1238 }
1239 else if (_RWSTD_ULLONG_MAX > 0xffffffffUL) {
1240 TEST (T (_RWSTD_ULLONG_MAX), 0, 0, "18446744073709551615");
1241 TEST (T (_RWSTD_ULLONG_MAX), Hex, 0, "ffffffffffffffff");
1242 }
1243
1244#endif // _RWSTD_LONG_LONG
1245
1247 // exercise basic_ostream::operator<< (float)
1248 TEST (T ( 0.0f), 0, 0, "0");
1249 TEST (T ( 1.0f), 0, 0, "1");
1250 TEST (T (-2.1f), 0, 0, "-2.1");
1251
1252 // exercise the default precision of 6, which gives the maximum number
1253 // of significant digits for the "%g" or "%G" conversion, which is
1254 // the default for the default flags
1255 TEST (T (3.1415926f), 0, 0, "3.14159");
1256 TEST (T (3.1415926f), Scientific, 0, "3.14159");
1257
1258 // exercise the default precision of 6, which gives the number of
1259 // digits after the decimal point for the "%f" or "%F" conversion,
1260 // which is used for the fixed flag
1261 TEST (T (12.3456789f), Fixed, 0, "12.345679");
1262
1264 // exercise basic_ostream::operator<< (double)
1265 TEST (T ( 0.0), 0, 0, "0");
1266 TEST (T ( 2.0), 0, 0, "2");
1267 TEST (T (-4.2), 0, 0, "-4.2");
1268
1269 // exercise the default precision of 6, which gives the maximum number
1270 // of significant digits for the "%g" or "%G" conversion, which is
1271 // the default for the default flags
1272 TEST (T (1.23456789), 0, 0, "1.23457");
1273 TEST (T (9.87654321), Scientific, 0, "9.87654");
1274
1275 // exercise the default precision of 6, which gives the number of
1276 // digits after the decimal point for the "%f" or "%F" conversion,
1277 // which is used for the fixed flag
1278 TEST (T (12.3456789), Fixed, 0, "12.345679");
1279
1280#ifndef _RWSTD_NO_LONG_DOUBLE
1281
1283 // exercise basic_ostream::operator<< (long double)
1284 TEST (T ( 0.0L), 0, 0, "0");
1285 TEST (T ( 3.0L), 0, 0, "3");
1286 TEST (T (-5.3L), 0, 0, "-5.3");
1287
1288 // exercise the default precision of 6, which gives the maximum number
1289 // of significant digits for the "%g" or "%G" conversion, which is
1290 // the default for the default flags
1291 TEST (T (1.23456789L), 0, 0, "1.23457");
1292 TEST (T (9.87654321L), Scientific, 0, "9.87654");
1293
1294 // exercise the default precision of 6, which gives the number of
1295 // digits after the decimal point for the "%f" or "%F" conversion,
1296 // which is used for the fixed flag
1297 TEST (T (12.3456789L), Fixed, 0, "12.345679");
1298
1299#endif // _RWSTD_NO_LONG_DOUBLE
1300
1302 // exercise basic_ostream::operator<< (const void*)
1303 TEST (T ((void*)0), 0, 0, 0 /* format implementation-defined */);
1304 TEST (T ((void*)1), 0, 0, 0);
1305 TEST (T ((void*)0x2345), 0, 0, 0);
1306
1308 // exercise basic_ostream::operator<< (const char*)
1309 TEST (T ("a"), 0, 0, "a");
1310 TEST (T ("b"), 0, -1, "b");
1311 TEST (T ("ab"), 0, 0, "ab");
1312 TEST (T ("abc"), 0, 4, " abc");
1313 TEST (T ("def"), Left, 5, "def<<", '<');
1314 TEST (T ("ghi"), Right, 6, ">>>ghi", '>');
1315 TEST (T ("jklm"), Internal, 7, " jklm");
1316 TEST (T ("nopqr"), Left | Right, 8, " nopqr");
1317 TEST (T ("stuv"), Left | Internal, 9, " stuv");
1318 TEST (T ("wxy"), Right | Internal, 10, " wxy");
1319 TEST (T ("z"), Left | Right | Internal, 11, "__________z", '_');
1320
1321 if (is_char (charT ())) {
1322
1323 // inserters overloaded on signed and unsigned char*
1324 // defined only for basic_ostream<char>, not wchar_t
1325
1327 // exercise basic_ostream::operator<< (const signed char*)
1328
1329#undef SCH
1330#define SCH(val) charT (), __LINE__, (const signed char*)val
1331
1332 TEST (SCH ("A"), 0, 0, "A");
1333 TEST (SCH ("B"), 0, -1, "B");
1334 TEST (SCH ("AB"), 0, 0, "AB");
1335 TEST (SCH ("ABC"), 0, 4, " ABC");
1336 TEST (SCH ("DEF"), Left, 5, "DEF++", '+');
1337 TEST (SCH ("GHI"), Right, 6, "---GHI", '-');
1338 TEST (SCH ("JKLM"), Internal, 7, " JKLM");
1339 TEST (SCH ("NOPQR"), Left | Right, 8, " NOPQR");
1340 TEST (SCH ("STUV"), Left | Internal, 9, " STUV");
1341 TEST (SCH ("WXY"), Right | Internal, 10, " WXY");
1342 TEST (SCH ("Z"), Left | Right | Internal, 11, "##########Z", '#');
1343
1345 // exercise basic_ostream::operator<< (const unsigned char*)
1346
1347#undef UCH
1348#define UCH(val) charT (), __LINE__, (const unsigned char*)val
1349
1350 TEST (UCH ("Z"), 0, 0, "Z");
1351 TEST (UCH ("Y"), 0, -1, "Y");
1352 TEST (UCH ("YZ"), 0, 0, "YZ");
1353 TEST (UCH ("XYZ"), 0, 4, " XYZ");
1354 TEST (UCH ("UVW"), Left, 5, "UVW\\\\", '\\');
1355 TEST (UCH ("RST"), Right, 6, "///RST", '/');
1356 TEST (UCH ("OPQR"), Internal, 7, " OPQR");
1357 TEST (UCH ("JKLMN"), Left | Right, 8, " JKLMN");
1358 TEST (UCH ("FGHI"), Left | Internal, 9, " FGHI");
1359 TEST (UCH ("CDE"), Right | Internal, 10, " CDE");
1360 TEST (UCH ("AB"), Left | Right | Internal, 11, "^^^^^^^^^AB", '^');
1361
1362 }
1363}
1364
1365
1367template <class charT>
1369{
1370 static const char* const cname = rw_any_t (charT ()).type_name ();
1371
1372 rw_info (0, 0, __LINE__,
1373 "std::basic_ostream<%s>::flush() ", cname);
1374
1375 typedef std::basic_ostream<charT, std::char_traits<charT> > Ostream;
1376 typedef std::basic_streambuf<charT, std::char_traits<charT> > Streambuf;
1377
1378 {
1379 test_streambuf<charT> tsb (0);
1380 Ostream strm (&tsb);
1381
1382 const int nsyncs = tsb.ncalls_ [Sync];
1383
1384 strm.flush ();
1385
1386 rw_assert (1 + nsyncs == tsb.ncalls_ [Sync], 0, __LINE__,
1387 "std::basic_ostream<%s>::flush() called rdbuf()->sync() "
1388 "once; got %d times",
1389 cname, tsb.ncalls_ [Sync] - nsyncs);
1390 }
1391
1392 {
1393 test_streambuf<charT> tsb (0);
1394 Ostream strm (&tsb);
1395
1396 tsb.fails_ = Sync;
1397 tsb.fail_when_ = 1;
1398
1399 const int nsyncs = tsb.ncalls_ [Sync];
1400
1401 strm.flush ();
1402
1403 rw_assert (1 + nsyncs == tsb.ncalls_ [Sync], 0, __LINE__,
1404 "std::basic_ostream<%s>::flush() called rdbuf()->sync() "
1405 "once; got %zu times",
1406 cname, tsb.ncalls_ [Sync] - nsyncs);
1407
1408 rw_assert (std::ios_base::badbit == strm.rdstate (), 0, __LINE__,
1409 "std::basic_ostream<%s>::flush() failed to set badbit "
1410 "after rdbuf()->pubsync() failed; state = %{Is}",
1411 cname, strm.rdstate ());
1412 }
1413
1414 {
1415 // exercise LWG issue 581: flush() not unformatted function
1416
1417 test_streambuf<charT> tsb (0);
1418 Ostream strm (&tsb);
1419
1420 strm.setstate (std::ios_base::failbit);
1421
1422 const int nsyncs = tsb.ncalls_ [Sync];
1423
1424 strm.flush ();
1425
1426 rw_assert (nsyncs == tsb.ncalls_ [Sync], 0, __LINE__,
1427 "std::basic_ostream<%s>::flush() unexpectedly made "
1428 "%zu calls to rdbuf()->sync() when rdstate () == "
1429 "failbit",
1430 cname, tsb.ncalls_ [Sync] - nsyncs);
1431
1432 rw_assert (std::ios_base::failbit == strm.rdstate (), 0, __LINE__,
1433 "std::basic_ostream<%s>::flush() unexpectedly changed "
1434 "state from std::ios_base::failbit to %{Is}",
1435 cname, strm.rdstate ());
1436 }
1437}
1438
1439
1441template <class charT>
1443{
1444 // exercise ostream::sentry
1445 if (rw_opt_sentry < 0)
1446 rw_note (0, 0, __LINE__, "sentry tests disabled");
1447 else
1448 test_sentry (charT ());
1449
1450 // exercise formatted output functions
1451 if (rw_opt_formatted < 0)
1452 rw_note (0, 0, __LINE__, "tests of formatted functions disabled");
1453 else
1454 test_formatted (charT ());
1455
1456 // exercise formatted output functions
1457 if (rw_opt_unformatted < 0)
1458 rw_note (0, 0, __LINE__, "tests of unformatted functions disabled");
1459 else {
1460 // FIXME: implement this
1461 // test_unformatted (charT ());
1462 }
1463
1464 // exercise flush()
1465 if (rw_opt_flush < 0)
1466 rw_note (0, 0, __LINE__, "flush tests disabled");
1467 else
1468 test_flush (charT ());
1469}
1470
1471
1473static int
1474run_test (int, char**)
1475{
1476 run_test (char ());
1477
1478#ifndef _RWSTD_NO_WCHAR_T
1479
1480 run_test (wchar_t ());
1481
1482#endif // _RWSTD_NO_WCHAR_T
1483
1484 return 0;
1485}
1486
1487
1489int main (int argc, char *argv[])
1490{
1491 return rw_test (argc, argv, __FILE__,
1492 "lib.ostream",
1493 0 /* no comment */,
1494 run_test,
1495 "|-sentry~ "
1496 "|-formatted~ "
1497 "|-unformatted~ "
1498 "|-flush~ "
1499 "|-no-exceptions~ ",
1503 &rw_opt_flush,
1505}
#define i
Definition 17.names.cpp:126
#define e
Definition 17.names.cpp:118
#define os
Definition 17.names.cpp:511
#define line
Definition 17.names.cpp:490
#define which
Definition 17.names.cpp:575
#define buf
Definition 17.names.cpp:452
#define c
Definition 17.names.cpp:111
#define charT
Definition 17.names.cpp:456
#define strm
Definition 17.names.cpp:549
#define val
Definition 17.names.cpp:570
#define flags
#define TEST(it, val)
int rw_opt_flush
num_put_overload
@ Bool
@ ULong
@ Dbl
@ ULLong
@ LLong
@ LDbl
@ PVoid
@ Long
#define T
void test_sentry(charT)
#define Left
streambuf_failure
@ Pbackfail
@ Uflow
@ Overflow
@ Xsgetn
@ Shwomanyc
@ Seekoff
@ Sync
@ Seekpos
@ Underflow
@ Xsputn
@ Setbuf
#define SCH(val)
#define Showbase
#define UCH(val)
int rw_opt_sentry
void test_formatted(charT, int line1, int line2, T val, const char *str, int fmtflags, int width, int fill, int rdstate, int exceptions, int failure=0, int fail_when=1)
#define Internal
int rw_opt_unformatted
bool uncaught
#define Right
void run_test(charT)
#define Hex
#define Good
#define Boolalpha
num_put_overload select_overload(bool)
#define Fixed
#define Bad
const int Throw
void test_flush(charT)
bool is_wchar_t(charT)
int rw_opt_formatted
#define Scientific
int rw_opt_exceptions
#define main
int caught
#define _RWSTD_LONG_LONG
#define _RWSTD_ASSERT(ignore)
Definition _defs.h:1108
#define _RWSTD_CONST_CAST(T, x)
Definition _defs.h:536
const char * type_name() const
Definition any.cpp:310
const char * str
Definition exec.cpp:170
#define SHRT_MAX
Definition limits.h:64
#define INT_MIN
Definition limits.h:80
#define ULONG_MAX
Definition limits.h:96
#define LONG_MAX
Definition limits.h:88
#define USHRT_MAX
Definition limits.h:72
#define INT_MAX
Definition limits.h:76
#define UINT_MAX
Definition limits.h:84
#define SHRT_MIN
Definition limits.h:68
#define LONG_MIN
Definition limits.h:92
_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
unsigned char UChar
Definition collate.cpp:122
std::basic_ostream< charT, std::char_traits< charT > > Ostream
Ostream * pstrm_
Ostream::sentry Sentry
virtual iter_type do_put(iter_type it, std::ios_base &f, char_type fill, bool v) const
Base::int_type int_type
test_num_put(std::size_t refs=0)
int ncalls_[ULLong+1]
std::num_put< charT, iter_type > NumPut
std::ios_base Ios
std::ostreambuf_iterator< charT > iter_type
virtual iter_type do_put(iter_type it, Ios &fl, char_type fill, long double val) const
virtual iter_type do_put(iter_type it, Ios &fl, char_type fill, unsigned long val) const
virtual iter_type do_put(iter_type it, Ios &fl, char_type fill, const void *val) const
virtual iter_type do_put(iter_type it, Ios &fl, char_type fill, long val) const
virtual iter_type do_put(iter_type it, Ios &fl, char_type fill, double val) const
virtual iter_type do_put(iter_type it, Ios &fl, char_type fill, bool val) const
num_put_overload throws_
num_put_overload fails_
iter_type test(iter_type, num_put_overload) const
std::streamsize bufsize_
virtual std::streamsize xsputn(const char_type *buf, std::streamsize bufsize)
virtual std::streamsize showmanyc()
bool test(streambuf_failure) const
test_streambuf(charT *buf, std::streamsize bufsize)
virtual pos_type seekoff(off_type, std::ios_base::seekdir, std::ios_base::openmode)
Streambuf::int_type int_type
virtual int_type pbackfail(int_type=traits_type::eof())
std::char_traits< charT > traits_type
static int fail_when_
Streambuf::pos_type pos_type
virtual int_type underflow()
int ncalls_[Sync+1]
streambuf_failure throws_
std::basic_streambuf< char_type, traits_type > Streambuf
virtual pos_type seekpos(pos_type, std::ios_base::openmode)
virtual int sync()
std::basic_ios< char_type, traits_type > * pstrm_
test_streambuf(std::basic_ios< char_type, traits_type > *pstrm)
char_type * buf_
streambuf_failure fails_
virtual std::streamsize xsgetn(char_type *, std::streamsize)
Streambuf::off_type off_type
virtual int_type uflow()
virtual int_type overflow(int_type=traits_type::eof())
virtual Streambuf * setbuf(char_type *, std::streamsize)