ostream.tcc revision 97403
1// ostream classes -*- C++ -*- 2 3// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 4// Free Software Foundation, Inc. 5// 6// This file is part of the GNU ISO C++ Library. This library is free 7// software; you can redistribute it and/or modify it under the 8// terms of the GNU General Public License as published by the 9// Free Software Foundation; either version 2, or (at your option) 10// any later version. 11 12// This library is distributed in the hope that it will be useful, 13// but WITHOUT ANY WARRANTY; without even the implied warranty of 14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15// GNU General Public License for more details. 16 17// You should have received a copy of the GNU General Public License along 18// with this library; see the file COPYING. If not, write to the Free 19// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 20// USA. 21 22// As a special exception, you may use this file as part of a free software 23// library without restriction. Specifically, if other files instantiate 24// templates or use macros or inline functions from this file, or you compile 25// this file and link it with other files to produce an executable, this 26// file does not by itself cause the resulting executable to be covered by 27// the GNU General Public License. This exception does not however 28// invalidate any other reasons why the executable file might be covered by 29// the GNU General Public License. 30 31// 32// ISO C++ 14882: 27.6.2 Output streams 33// 34 35#pragma GCC system_header 36 37#include <locale> 38 39namespace std 40{ 41 template<typename _CharT, typename _Traits> 42 basic_ostream<_CharT, _Traits>::sentry:: 43 sentry(basic_ostream<_CharT,_Traits>& __os) 44 : _M_ok(__os.good()), _M_os(__os) 45 { 46 // XXX MT 47 if (_M_ok && __os.tie()) 48 __os.tie()->flush(); 49 } 50 51 template<typename _CharT, typename _Traits> 52 basic_ostream<_CharT, _Traits>& 53 basic_ostream<_CharT, _Traits>:: 54 operator<<(__ostream_type& (*__pf)(__ostream_type&)) 55 { 56 sentry __cerb(*this); 57 if (__cerb) 58 { 59 try 60 { __pf(*this); } 61 catch(exception& __fail) 62 { 63 // 27.6.2.5.1 Common requirements. 64 // Turn this on without causing an ios::failure to be thrown. 65 this->setstate(ios_base::badbit); 66 if ((this->exceptions() & ios_base::badbit) != 0) 67 __throw_exception_again; 68 } 69 } 70 return *this; 71 } 72 73 template<typename _CharT, typename _Traits> 74 basic_ostream<_CharT, _Traits>& 75 basic_ostream<_CharT, _Traits>:: 76 operator<<(__ios_type& (*__pf)(__ios_type&)) 77 { 78 sentry __cerb(*this); 79 if (__cerb) 80 { 81 try 82 { __pf(*this); } 83 catch(exception& __fail) 84 { 85 // 27.6.2.5.1 Common requirements. 86 // Turn this on without causing an ios::failure to be thrown. 87 this->setstate(ios_base::badbit); 88 if ((this->exceptions() & ios_base::badbit) != 0) 89 __throw_exception_again; 90 } 91 } 92 return *this; 93 } 94 95 template<typename _CharT, typename _Traits> 96 basic_ostream<_CharT, _Traits>& 97 basic_ostream<_CharT, _Traits>:: 98 operator<<(ios_base& (*__pf)(ios_base&)) 99 { 100 sentry __cerb(*this); 101 if (__cerb) 102 { 103 try 104 { __pf(*this); } 105 catch(exception& __fail) 106 { 107 // 27.6.2.5.1 Common requirements. 108 // Turn this on without causing an ios::failure to be thrown. 109 this->setstate(ios_base::badbit); 110 if ((this->exceptions() & ios_base::badbit) != 0) 111 __throw_exception_again; 112 } 113 } 114 return *this; 115 } 116 117 template<typename _CharT, typename _Traits> 118 basic_ostream<_CharT, _Traits>& 119 basic_ostream<_CharT, _Traits>::operator<<(__streambuf_type* __sbin) 120 { 121 sentry __cerb(*this); 122 if (__cerb) 123 { 124 try 125 { 126 streamsize __xtrct = 0; 127 if (__sbin) 128 { 129 __streambuf_type* __sbout = this->rdbuf(); 130 __xtrct = __copy_streambufs(*this, __sbin, __sbout); 131 } 132 else 133 this->setstate(ios_base::badbit); 134 if (!__xtrct) 135 this->setstate(ios_base::failbit); 136 } 137 catch(exception& __fail) 138 { 139 // 27.6.2.5.1 Common requirements. 140 // Turn this on without causing an ios::failure to be thrown. 141 this->setstate(ios_base::badbit); 142 if ((this->exceptions() & ios_base::badbit) != 0) 143 __throw_exception_again; 144 } 145 } 146 return *this; 147 } 148 149 template<typename _CharT, typename _Traits> 150 basic_ostream<_CharT, _Traits>& 151 basic_ostream<_CharT, _Traits>::operator<<(bool __n) 152 { 153 sentry __cerb(*this); 154 if (__cerb) 155 { 156 try 157 { 158 if (_M_check_facet(_M_fnumput)) 159 if (_M_fnumput->put(*this, *this, this->fill(), __n).failed()) 160 this->setstate(ios_base::badbit); 161 } 162 catch(exception& __fail) 163 { 164 // 27.6.1.2.1 Common requirements. 165 // Turn this on without causing an ios::failure to be thrown. 166 this->setstate(ios_base::badbit); 167 if ((this->exceptions() & ios_base::badbit) != 0) 168 __throw_exception_again; 169 } 170 } 171 return *this; 172 } 173 174 template<typename _CharT, typename _Traits> 175 basic_ostream<_CharT, _Traits>& 176 basic_ostream<_CharT, _Traits>::operator<<(long __n) 177 { 178 sentry __cerb(*this); 179 if (__cerb) 180 { 181 try 182 { 183 char_type __c = this->fill(); 184 ios_base::fmtflags __fmt = this->flags() & ios_base::basefield; 185 if (_M_check_facet(_M_fnumput)) 186 { 187 bool __b = false; 188 if ((__fmt & ios_base::oct) || (__fmt & ios_base::hex)) 189 { 190 unsigned long __l = static_cast<unsigned long>(__n); 191 __b = _M_fnumput->put(*this, *this, __c, __l).failed(); 192 } 193 else 194 __b = _M_fnumput->put(*this, *this, __c, __n).failed(); 195 if (__b) 196 this->setstate(ios_base::badbit); 197 } 198 } 199 catch(exception& __fail) 200 { 201 // 27.6.1.2.1 Common requirements. 202 // Turn this on without causing an ios::failure to be thrown. 203 this->setstate(ios_base::badbit); 204 if ((this->exceptions() & ios_base::badbit) != 0) 205 __throw_exception_again; 206 } 207 } 208 return *this; 209 } 210 211 template<typename _CharT, typename _Traits> 212 basic_ostream<_CharT, _Traits>& 213 basic_ostream<_CharT, _Traits>::operator<<(unsigned long __n) 214 { 215 sentry __cerb(*this); 216 if (__cerb) 217 { 218 try 219 { 220 if (_M_check_facet(_M_fnumput)) 221 if (_M_fnumput->put(*this, *this, this->fill(), __n).failed()) 222 this->setstate(ios_base::badbit); 223 } 224 catch(exception& __fail) 225 { 226 // 27.6.1.2.1 Common requirements. 227 // Turn this on without causing an ios::failure to be thrown. 228 this->setstate(ios_base::badbit); 229 if ((this->exceptions() & ios_base::badbit) != 0) 230 __throw_exception_again; 231 } 232 } 233 return *this; 234 } 235 236#ifdef _GLIBCPP_USE_LONG_LONG 237 template<typename _CharT, typename _Traits> 238 basic_ostream<_CharT, _Traits>& 239 basic_ostream<_CharT, _Traits>::operator<<(long long __n) 240 { 241 sentry __cerb(*this); 242 if (__cerb) 243 { 244 try 245 { 246 char_type __c = this->fill(); 247 ios_base::fmtflags __fmt = this->flags() & ios_base::basefield; 248 if (_M_check_facet(_M_fnumput)) 249 { 250 bool __b = false; 251 if ((__fmt & ios_base::oct) || (__fmt & ios_base::hex)) 252 { 253 unsigned long long __l; 254 __l = static_cast<unsigned long long>(__n); 255 __b = _M_fnumput->put(*this, *this, __c, __l).failed(); 256 } 257 else 258 __b = _M_fnumput->put(*this, *this, __c, __n).failed(); 259 if (__b) 260 this->setstate(ios_base::badbit); 261 } 262 } 263 catch(exception& __fail) 264 { 265 // 27.6.1.2.1 Common requirements. 266 // Turn this on without causing an ios::failure to be thrown. 267 this->setstate(ios_base::badbit); 268 if ((this->exceptions() & ios_base::badbit) != 0) 269 __throw_exception_again; 270 } 271 } 272 return *this; 273 } 274 275 template<typename _CharT, typename _Traits> 276 basic_ostream<_CharT, _Traits>& 277 basic_ostream<_CharT, _Traits>::operator<<(unsigned long long __n) 278 { 279 sentry __cerb(*this); 280 if (__cerb) 281 { 282 try 283 { 284 if (_M_check_facet(_M_fnumput)) 285 if (_M_fnumput->put(*this, *this, this->fill(), __n).failed()) 286 this->setstate(ios_base::badbit); 287 } 288 catch(exception& __fail) 289 { 290 // 27.6.1.2.1 Common requirements. 291 // Turn this on without causing an ios::failure to be thrown. 292 this->setstate(ios_base::badbit); 293 if ((this->exceptions() & ios_base::badbit) != 0) 294 __throw_exception_again; 295 } 296 } 297 return *this; 298 } 299#endif 300 301 template<typename _CharT, typename _Traits> 302 basic_ostream<_CharT, _Traits>& 303 basic_ostream<_CharT, _Traits>::operator<<(double __n) 304 { 305 sentry __cerb(*this); 306 if (__cerb) 307 { 308 try 309 { 310 if (_M_check_facet(_M_fnumput)) 311 if (_M_fnumput->put(*this, *this, this->fill(), __n).failed()) 312 this->setstate(ios_base::badbit); 313 } 314 catch(exception& __fail) 315 { 316 // 27.6.1.2.1 Common requirements. 317 // Turn this on without causing an ios::failure to be thrown. 318 this->setstate(ios_base::badbit); 319 if ((this->exceptions() & ios_base::badbit) != 0) 320 __throw_exception_again; 321 } 322 } 323 return *this; 324 } 325 326 template<typename _CharT, typename _Traits> 327 basic_ostream<_CharT, _Traits>& 328 basic_ostream<_CharT, _Traits>::operator<<(long double __n) 329 { 330 sentry __cerb(*this); 331 if (__cerb) 332 { 333 try 334 { 335 if (_M_check_facet(_M_fnumput)) 336 if (_M_fnumput->put(*this, *this, this->fill(), __n).failed()) 337 this->setstate(ios_base::badbit); 338 } 339 catch(exception& __fail) 340 { 341 // 27.6.1.2.1 Common requirements. 342 // Turn this on without causing an ios::failure to be thrown. 343 this->setstate(ios_base::badbit); 344 if ((this->exceptions() & ios_base::badbit) != 0) 345 __throw_exception_again; 346 } 347 } 348 return *this; 349 } 350 351 template<typename _CharT, typename _Traits> 352 basic_ostream<_CharT, _Traits>& 353 basic_ostream<_CharT, _Traits>::operator<<(const void* __n) 354 { 355 sentry __cerb(*this); 356 if (__cerb) 357 { 358 try 359 { 360 if (_M_check_facet(_M_fnumput)) 361 if (_M_fnumput->put(*this, *this, this->fill(), __n).failed()) 362 this->setstate(ios_base::badbit); 363 } 364 catch(exception& __fail) 365 { 366 // 27.6.1.2.1 Common requirements. 367 // Turn this on without causing an ios::failure to be thrown. 368 this->setstate(ios_base::badbit); 369 if ((this->exceptions() & ios_base::badbit) != 0) 370 __throw_exception_again; 371 } 372 } 373 return *this; 374 } 375 376 template<typename _CharT, typename _Traits> 377 basic_ostream<_CharT, _Traits>& 378 basic_ostream<_CharT, _Traits>::put(char_type __c) 379 { 380 sentry __cerb(*this); 381 if (__cerb) 382 { 383 int_type __put = rdbuf()->sputc(__c); 384 if (traits_type::eq_int_type(__put, traits_type::eof())) 385 this->setstate(ios_base::badbit); 386 } 387 return *this; 388 } 389 390 template<typename _CharT, typename _Traits> 391 basic_ostream<_CharT, _Traits>& 392 basic_ostream<_CharT, _Traits>::write(const _CharT* __s, streamsize __n) 393 { 394 sentry __cerb(*this); 395 if (__cerb) 396 { 397 streamsize __put = this->rdbuf()->sputn(__s, __n); 398 if ( __put != __n) 399 this->setstate(ios_base::badbit); 400 } 401 return *this; 402 } 403 404 template<typename _CharT, typename _Traits> 405 basic_ostream<_CharT, _Traits>& 406 basic_ostream<_CharT, _Traits>::flush() 407 { 408 sentry __cerb(*this); 409 if (__cerb) 410 { 411 if (this->rdbuf() && this->rdbuf()->pubsync() == -1) 412 this->setstate(ios_base::badbit); 413 } 414 return *this; 415 } 416 417 template<typename _CharT, typename _Traits> 418 typename basic_ostream<_CharT, _Traits>::pos_type 419 basic_ostream<_CharT, _Traits>::tellp() 420 { 421 pos_type __ret = pos_type(-1); 422 if (!this->fail()) 423 __ret = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::out); 424 return __ret; 425 } 426 427 428 template<typename _CharT, typename _Traits> 429 basic_ostream<_CharT, _Traits>& 430 basic_ostream<_CharT, _Traits>::seekp(pos_type __pos) 431 { 432 if (!this->fail()) 433 { 434#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS 435// 136. seekp, seekg setting wrong streams? 436 pos_type __err = this->rdbuf()->pubseekpos(__pos, ios_base::out); 437 438// 129. Need error indication from seekp() and seekg() 439 if (__err == pos_type(off_type(-1))) 440 this->setstate(ios_base::failbit); 441#endif 442 } 443 return *this; 444 } 445 446 template<typename _CharT, typename _Traits> 447 basic_ostream<_CharT, _Traits>& 448 basic_ostream<_CharT, _Traits>:: 449 seekp(off_type __off, ios_base::seekdir __d) 450 { 451 if (!this->fail()) 452 { 453#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS 454// 136. seekp, seekg setting wrong streams? 455 pos_type __err = this->rdbuf()->pubseekoff(__off, __d, 456 ios_base::out); 457 458// 129. Need error indication from seekp() and seekg() 459 if (__err == pos_type(off_type(-1))) 460 this->setstate(ios_base::failbit); 461#endif 462 } 463 return *this; 464 } 465 466 // 27.6.2.5.4 Character inserters. 467 template<typename _CharT, typename _Traits> 468 basic_ostream<_CharT, _Traits>& 469 operator<<(basic_ostream<_CharT, _Traits>& __out, _CharT __c) 470 { 471 typedef basic_ostream<_CharT, _Traits> __ostream_type; 472 typename __ostream_type::sentry __cerb(__out); 473 if (__cerb) 474 { 475 try 476 { 477 streamsize __w = __out.width(); 478 _CharT* __pads = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * (__w + 1))); 479 __pads[0] = __c; 480 streamsize __len = 1; 481 if (__w > __len) 482 { 483 __pad(__out, __out.fill(), __pads, &__c, __w, __len, false); 484 __len = __w; 485 } 486 __out.write(__pads, __len); 487 __out.width(0); 488 } 489 catch(exception& __fail) 490 { 491 // 27.6.1.2.1 Common requirements. 492 // Turn this on without causing an ios::failure to be thrown. 493 __out.setstate(ios_base::badbit); 494 if ((__out.exceptions() & ios_base::badbit) != 0) 495 __throw_exception_again; 496 } 497 } 498 return __out; 499 } 500 501 // Specializations. 502 template <class _Traits> 503 basic_ostream<char, _Traits>& 504 operator<<(basic_ostream<char, _Traits>& __out, char __c) 505 { 506 typedef basic_ostream<char, _Traits> __ostream_type; 507 typename __ostream_type::sentry __cerb(__out); 508 if (__cerb) 509 { 510 try 511 { 512 streamsize __w = __out.width(); 513 char* __pads = static_cast<char*>(__builtin_alloca(__w + 1)); 514 __pads[0] = __c; 515 streamsize __len = 1; 516 if (__w > __len) 517 { 518 __pad(__out, __out.fill(), __pads, &__c, __w, __len, false); 519 __len = __w; 520 } 521 __out.write(__pads, __len); 522 __out.width(0); 523 } 524 catch(exception& __fail) 525 { 526 // 27.6.1.2.1 Common requirements. 527 // Turn this on without causing an ios::failure to be thrown. 528 __out.setstate(ios_base::badbit); 529 if ((__out.exceptions() & ios_base::badbit) != 0) 530 __throw_exception_again; 531 } 532 } 533 return __out; 534 } 535 536 template<typename _CharT, typename _Traits> 537 basic_ostream<_CharT, _Traits>& 538 operator<<(basic_ostream<_CharT, _Traits>& __out, const _CharT* __s) 539 { 540 typedef basic_ostream<_CharT, _Traits> __ostream_type; 541 typename __ostream_type::sentry __cerb(__out); 542 if (__cerb) 543 { 544 try 545 { 546 streamsize __w = __out.width(); 547 _CharT* __pads = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __w)); 548 streamsize __len = static_cast<streamsize>(_Traits::length(__s)); 549 if (__w > __len) 550 { 551 __pad(__out, __out.fill(), __pads, __s, __w, __len, false); 552 __s = __pads; 553 __len = __w; 554 } 555 __out.write(__s, __len); 556 __out.width(0); 557 } 558 catch(exception& __fail) 559 { 560 // 27.6.1.2.1 Common requirements. 561 // Turn this on without causing an ios::failure to be thrown. 562 __out.setstate(ios_base::badbit); 563 if ((__out.exceptions() & ios_base::badbit) != 0) 564 __throw_exception_again; 565 } 566 } 567 return __out; 568 } 569 570 template<typename _CharT, typename _Traits> 571 basic_ostream<_CharT, _Traits>& 572 operator<<(basic_ostream<_CharT, _Traits>& __out, const char* __s) 573 { 574 typedef basic_ostream<_CharT, _Traits> __ostream_type; 575#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS 576// 167. Improper use of traits_type::length() 577// Note that this is only in 'Review' status. 578 typedef char_traits<char> __ctraits_type; 579#endif 580 typename __ostream_type::sentry __cerb(__out); 581 if (__cerb) 582 { 583 size_t __clen = __ctraits_type::length(__s); 584 _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * (__clen + 1))); 585 for (size_t __i = 0; __i <= __clen; ++__i) 586 __ws[__i] = __out.widen(__s[__i]); 587 _CharT* __str = __ws; 588 589 try 590 { 591 streamsize __len = static_cast<streamsize>(__clen); 592 streamsize __w = __out.width(); 593 _CharT* __pads = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __w)); 594 595 if (__w > __len) 596 { 597 __pad(__out, __out.fill(), __pads, __ws, __w, __len, false); 598 __str = __pads; 599 __len = __w; 600 } 601 __out.write(__str, __len); 602 __out.width(0); 603 } 604 catch(exception& __fail) 605 { 606 // 27.6.1.2.1 Common requirements. 607 // Turn this on without causing an ios::failure to be thrown. 608 __out.setstate(ios_base::badbit); 609 if ((__out.exceptions() & ios_base::badbit) != 0) 610 __throw_exception_again; 611 } 612 } 613 return __out; 614 } 615 616 // Partial specializations. 617 template<class _Traits> 618 basic_ostream<char, _Traits>& 619 operator<<(basic_ostream<char, _Traits>& __out, const char* __s) 620 { 621 typedef basic_ostream<char, _Traits> __ostream_type; 622 typename __ostream_type::sentry __cerb(__out); 623 if (__cerb) 624 { 625 try 626 { 627 streamsize __w = __out.width(); 628 char* __pads = static_cast<char*>(__builtin_alloca(__w)); 629 streamsize __len = static_cast<streamsize>(_Traits::length(__s)); 630 if (__w > __len) 631 { 632 __pad(__out, __out.fill(), __pads, __s, __w, __len, false); 633 __s = __pads; 634 __len = __w; 635 } 636 __out.write(__s, __len); 637 __out.width(0); 638 } 639 catch(exception& __fail) 640 { 641 // 27.6.1.2.1 Common requirements. 642 // Turn this on without causing an ios::failure to be thrown. 643 __out.setstate(ios_base::badbit); 644 if ((__out.exceptions() & ios_base::badbit) != 0) 645 __throw_exception_again; 646 } 647 } 648 return __out; 649 } 650 651 // 21.3.7.9 basic_string::operator<< 652 template<typename _CharT, typename _Traits, typename _Alloc> 653 basic_ostream<_CharT, _Traits>& 654 operator<<(basic_ostream<_CharT, _Traits>& __out, 655 const basic_string<_CharT, _Traits, _Alloc>& __str) 656 { 657 typedef basic_ostream<_CharT, _Traits> __ostream_type; 658 typename __ostream_type::sentry __cerb(__out); 659 if (__cerb) 660 { 661 const _CharT* __s = __str.data(); 662 streamsize __w = __out.width(); 663 _CharT* __pads = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __w)); 664 streamsize __len = static_cast<streamsize>(__str.size()); 665#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS 666 // 25. String operator<< uses width() value wrong 667#endif 668 if (__w > __len) 669 { 670 __pad(__out, __out.fill(), __pads, __s, __w, __len, false); 671 __s = __pads; 672 __len = __w; 673 } 674 streamsize __res = __out.rdbuf()->sputn(__s, __len); 675 __out.width(0); 676 if (__res != __len) 677 __out.setstate(ios_base::failbit); 678 } 679 return __out; 680 } 681 682 // Inhibit implicit instantiations for required instantiations, 683 // which are defined via explicit instantiations elsewhere. 684 // NB: This syntax is a GNU extension. 685 extern template class basic_ostream<char>; 686 extern template ostream& endl(ostream&); 687 extern template ostream& ends(ostream&); 688 extern template ostream& flush(ostream&); 689 extern template ostream& operator<<(ostream&, char); 690 extern template ostream& operator<<(ostream&, unsigned char); 691 extern template ostream& operator<<(ostream&, signed char); 692 extern template ostream& operator<<(ostream&, const char*); 693 extern template ostream& operator<<(ostream&, const unsigned char*); 694 extern template ostream& operator<<(ostream&, const signed char*); 695 696 extern template class basic_ostream<wchar_t>; 697 extern template wostream& endl(wostream&); 698 extern template wostream& ends(wostream&); 699 extern template wostream& flush(wostream&); 700 extern template wostream& operator<<(wostream&, wchar_t); 701 extern template wostream& operator<<(wostream&, char); 702 extern template wostream& operator<<(wostream&, const wchar_t*); 703 extern template wostream& operator<<(wostream&, const char*); 704} // namespace std 705