ostream.tcc revision 102782
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 && __sbin) 123 { 124 try 125 { 126 if (!__copy_streambufs(*this, __sbin, this->rdbuf())) 127 this->setstate(ios_base::failbit); 128 } 129 catch(exception& __fail) 130 { 131 // 27.6.2.5.1 Common requirements. 132 // Turn this on without causing an ios::failure to be thrown. 133 this->setstate(ios_base::badbit); 134 if ((this->exceptions() & ios_base::badbit) != 0) 135 __throw_exception_again; 136 } 137 } 138 else if (!__sbin) 139 this->setstate(ios_base::badbit); 140 return *this; 141 } 142 143 template<typename _CharT, typename _Traits> 144 basic_ostream<_CharT, _Traits>& 145 basic_ostream<_CharT, _Traits>::operator<<(bool __n) 146 { 147 sentry __cerb(*this); 148 if (__cerb) 149 { 150 try 151 { 152 if (_M_check_facet(_M_fnumput)) 153 if (_M_fnumput->put(*this, *this, this->fill(), __n).failed()) 154 this->setstate(ios_base::badbit); 155 } 156 catch(exception& __fail) 157 { 158 // 27.6.1.2.1 Common requirements. 159 // Turn this on without causing an ios::failure to be thrown. 160 this->setstate(ios_base::badbit); 161 if ((this->exceptions() & ios_base::badbit) != 0) 162 __throw_exception_again; 163 } 164 } 165 return *this; 166 } 167 168 template<typename _CharT, typename _Traits> 169 basic_ostream<_CharT, _Traits>& 170 basic_ostream<_CharT, _Traits>::operator<<(long __n) 171 { 172 sentry __cerb(*this); 173 if (__cerb) 174 { 175 try 176 { 177 char_type __c = this->fill(); 178 ios_base::fmtflags __fmt = this->flags() & ios_base::basefield; 179 if (_M_check_facet(_M_fnumput)) 180 { 181 bool __b = false; 182 if ((__fmt & ios_base::oct) || (__fmt & ios_base::hex)) 183 { 184 unsigned long __l = static_cast<unsigned long>(__n); 185 __b = _M_fnumput->put(*this, *this, __c, __l).failed(); 186 } 187 else 188 __b = _M_fnumput->put(*this, *this, __c, __n).failed(); 189 if (__b) 190 this->setstate(ios_base::badbit); 191 } 192 } 193 catch(exception& __fail) 194 { 195 // 27.6.1.2.1 Common requirements. 196 // Turn this on without causing an ios::failure to be thrown. 197 this->setstate(ios_base::badbit); 198 if ((this->exceptions() & ios_base::badbit) != 0) 199 __throw_exception_again; 200 } 201 } 202 return *this; 203 } 204 205 template<typename _CharT, typename _Traits> 206 basic_ostream<_CharT, _Traits>& 207 basic_ostream<_CharT, _Traits>::operator<<(unsigned long __n) 208 { 209 sentry __cerb(*this); 210 if (__cerb) 211 { 212 try 213 { 214 if (_M_check_facet(_M_fnumput)) 215 if (_M_fnumput->put(*this, *this, this->fill(), __n).failed()) 216 this->setstate(ios_base::badbit); 217 } 218 catch(exception& __fail) 219 { 220 // 27.6.1.2.1 Common requirements. 221 // Turn this on without causing an ios::failure to be thrown. 222 this->setstate(ios_base::badbit); 223 if ((this->exceptions() & ios_base::badbit) != 0) 224 __throw_exception_again; 225 } 226 } 227 return *this; 228 } 229 230#ifdef _GLIBCPP_USE_LONG_LONG 231 template<typename _CharT, typename _Traits> 232 basic_ostream<_CharT, _Traits>& 233 basic_ostream<_CharT, _Traits>::operator<<(long long __n) 234 { 235 sentry __cerb(*this); 236 if (__cerb) 237 { 238 try 239 { 240 char_type __c = this->fill(); 241 ios_base::fmtflags __fmt = this->flags() & ios_base::basefield; 242 if (_M_check_facet(_M_fnumput)) 243 { 244 bool __b = false; 245 if ((__fmt & ios_base::oct) || (__fmt & ios_base::hex)) 246 { 247 unsigned long long __l; 248 __l = static_cast<unsigned long long>(__n); 249 __b = _M_fnumput->put(*this, *this, __c, __l).failed(); 250 } 251 else 252 __b = _M_fnumput->put(*this, *this, __c, __n).failed(); 253 if (__b) 254 this->setstate(ios_base::badbit); 255 } 256 } 257 catch(exception& __fail) 258 { 259 // 27.6.1.2.1 Common requirements. 260 // Turn this on without causing an ios::failure to be thrown. 261 this->setstate(ios_base::badbit); 262 if ((this->exceptions() & ios_base::badbit) != 0) 263 __throw_exception_again; 264 } 265 } 266 return *this; 267 } 268 269 template<typename _CharT, typename _Traits> 270 basic_ostream<_CharT, _Traits>& 271 basic_ostream<_CharT, _Traits>::operator<<(unsigned long long __n) 272 { 273 sentry __cerb(*this); 274 if (__cerb) 275 { 276 try 277 { 278 if (_M_check_facet(_M_fnumput)) 279 if (_M_fnumput->put(*this, *this, this->fill(), __n).failed()) 280 this->setstate(ios_base::badbit); 281 } 282 catch(exception& __fail) 283 { 284 // 27.6.1.2.1 Common requirements. 285 // Turn this on without causing an ios::failure to be thrown. 286 this->setstate(ios_base::badbit); 287 if ((this->exceptions() & ios_base::badbit) != 0) 288 __throw_exception_again; 289 } 290 } 291 return *this; 292 } 293#endif 294 295 template<typename _CharT, typename _Traits> 296 basic_ostream<_CharT, _Traits>& 297 basic_ostream<_CharT, _Traits>::operator<<(double __n) 298 { 299 sentry __cerb(*this); 300 if (__cerb) 301 { 302 try 303 { 304 if (_M_check_facet(_M_fnumput)) 305 if (_M_fnumput->put(*this, *this, this->fill(), __n).failed()) 306 this->setstate(ios_base::badbit); 307 } 308 catch(exception& __fail) 309 { 310 // 27.6.1.2.1 Common requirements. 311 // Turn this on without causing an ios::failure to be thrown. 312 this->setstate(ios_base::badbit); 313 if ((this->exceptions() & ios_base::badbit) != 0) 314 __throw_exception_again; 315 } 316 } 317 return *this; 318 } 319 320 template<typename _CharT, typename _Traits> 321 basic_ostream<_CharT, _Traits>& 322 basic_ostream<_CharT, _Traits>::operator<<(long double __n) 323 { 324 sentry __cerb(*this); 325 if (__cerb) 326 { 327 try 328 { 329 if (_M_check_facet(_M_fnumput)) 330 if (_M_fnumput->put(*this, *this, this->fill(), __n).failed()) 331 this->setstate(ios_base::badbit); 332 } 333 catch(exception& __fail) 334 { 335 // 27.6.1.2.1 Common requirements. 336 // Turn this on without causing an ios::failure to be thrown. 337 this->setstate(ios_base::badbit); 338 if ((this->exceptions() & ios_base::badbit) != 0) 339 __throw_exception_again; 340 } 341 } 342 return *this; 343 } 344 345 template<typename _CharT, typename _Traits> 346 basic_ostream<_CharT, _Traits>& 347 basic_ostream<_CharT, _Traits>::operator<<(const void* __n) 348 { 349 sentry __cerb(*this); 350 if (__cerb) 351 { 352 try 353 { 354 if (_M_check_facet(_M_fnumput)) 355 if (_M_fnumput->put(*this, *this, this->fill(), __n).failed()) 356 this->setstate(ios_base::badbit); 357 } 358 catch(exception& __fail) 359 { 360 // 27.6.1.2.1 Common requirements. 361 // Turn this on without causing an ios::failure to be thrown. 362 this->setstate(ios_base::badbit); 363 if ((this->exceptions() & ios_base::badbit) != 0) 364 __throw_exception_again; 365 } 366 } 367 return *this; 368 } 369 370 template<typename _CharT, typename _Traits> 371 basic_ostream<_CharT, _Traits>& 372 basic_ostream<_CharT, _Traits>::put(char_type __c) 373 { 374 sentry __cerb(*this); 375 if (__cerb) 376 { 377 int_type __put = rdbuf()->sputc(__c); 378 if (traits_type::eq_int_type(__put, traits_type::eof())) 379 this->setstate(ios_base::badbit); 380 } 381 return *this; 382 } 383 384 template<typename _CharT, typename _Traits> 385 basic_ostream<_CharT, _Traits>& 386 basic_ostream<_CharT, _Traits>::write(const _CharT* __s, streamsize __n) 387 { 388 sentry __cerb(*this); 389 if (__cerb) 390 { 391 streamsize __put = this->rdbuf()->sputn(__s, __n); 392 if ( __put != __n) 393 this->setstate(ios_base::badbit); 394 } 395 return *this; 396 } 397 398 template<typename _CharT, typename _Traits> 399 basic_ostream<_CharT, _Traits>& 400 basic_ostream<_CharT, _Traits>::flush() 401 { 402 sentry __cerb(*this); 403 if (__cerb) 404 { 405 if (this->rdbuf() && this->rdbuf()->pubsync() == -1) 406 this->setstate(ios_base::badbit); 407 } 408 return *this; 409 } 410 411 template<typename _CharT, typename _Traits> 412 typename basic_ostream<_CharT, _Traits>::pos_type 413 basic_ostream<_CharT, _Traits>::tellp() 414 { 415 pos_type __ret = pos_type(-1); 416 if (!this->fail()) 417 __ret = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::out); 418 return __ret; 419 } 420 421 422 template<typename _CharT, typename _Traits> 423 basic_ostream<_CharT, _Traits>& 424 basic_ostream<_CharT, _Traits>::seekp(pos_type __pos) 425 { 426 if (!this->fail()) 427 { 428#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS 429// 136. seekp, seekg setting wrong streams? 430 pos_type __err = this->rdbuf()->pubseekpos(__pos, ios_base::out); 431 432// 129. Need error indication from seekp() and seekg() 433 if (__err == pos_type(off_type(-1))) 434 this->setstate(ios_base::failbit); 435#endif 436 } 437 return *this; 438 } 439 440 template<typename _CharT, typename _Traits> 441 basic_ostream<_CharT, _Traits>& 442 basic_ostream<_CharT, _Traits>:: 443 seekp(off_type __off, ios_base::seekdir __d) 444 { 445 if (!this->fail()) 446 { 447#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS 448// 136. seekp, seekg setting wrong streams? 449 pos_type __err = this->rdbuf()->pubseekoff(__off, __d, 450 ios_base::out); 451 452// 129. Need error indication from seekp() and seekg() 453 if (__err == pos_type(off_type(-1))) 454 this->setstate(ios_base::failbit); 455#endif 456 } 457 return *this; 458 } 459 460 // 27.6.2.5.4 Character inserters. 461 template<typename _CharT, typename _Traits> 462 basic_ostream<_CharT, _Traits>& 463 operator<<(basic_ostream<_CharT, _Traits>& __out, _CharT __c) 464 { 465 typedef basic_ostream<_CharT, _Traits> __ostream_type; 466 typename __ostream_type::sentry __cerb(__out); 467 if (__cerb) 468 { 469 try 470 { 471 streamsize __w = __out.width(); 472 _CharT* __pads = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * (__w + 1))); 473 __pads[0] = __c; 474 streamsize __len = 1; 475 if (__w > __len) 476 { 477 __pad<_CharT, _Traits>::_S_pad(__out, __out.fill(), __pads, 478 &__c, __w, __len, false); 479 __len = __w; 480 } 481 __out.write(__pads, __len); 482 __out.width(0); 483 } 484 catch(exception& __fail) 485 { 486 // 27.6.1.2.1 Common requirements. 487 // Turn this on without causing an ios::failure to be thrown. 488 __out.setstate(ios_base::badbit); 489 if ((__out.exceptions() & ios_base::badbit) != 0) 490 __throw_exception_again; 491 } 492 } 493 return __out; 494 } 495 496 // Specializations. 497 template <class _Traits> 498 basic_ostream<char, _Traits>& 499 operator<<(basic_ostream<char, _Traits>& __out, char __c) 500 { 501 typedef basic_ostream<char, _Traits> __ostream_type; 502 typename __ostream_type::sentry __cerb(__out); 503 if (__cerb) 504 { 505 try 506 { 507 streamsize __w = __out.width(); 508 char* __pads = static_cast<char*>(__builtin_alloca(__w + 1)); 509 __pads[0] = __c; 510 streamsize __len = 1; 511 if (__w > __len) 512 { 513 __pad<char, _Traits>::_S_pad(__out, __out.fill(), __pads, 514 &__c, __w, __len, false); 515 __len = __w; 516 } 517 __out.write(__pads, __len); 518 __out.width(0); 519 } 520 catch(exception& __fail) 521 { 522 // 27.6.1.2.1 Common requirements. 523 // Turn this on without causing an ios::failure to be thrown. 524 __out.setstate(ios_base::badbit); 525 if ((__out.exceptions() & ios_base::badbit) != 0) 526 __throw_exception_again; 527 } 528 } 529 return __out; 530 } 531 532 template<typename _CharT, typename _Traits> 533 basic_ostream<_CharT, _Traits>& 534 operator<<(basic_ostream<_CharT, _Traits>& __out, const _CharT* __s) 535 { 536 typedef basic_ostream<_CharT, _Traits> __ostream_type; 537 typename __ostream_type::sentry __cerb(__out); 538 if (__cerb && __s) 539 { 540 try 541 { 542 streamsize __w = __out.width(); 543 _CharT* __pads = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __w)); 544 streamsize __len = static_cast<streamsize>(_Traits::length(__s)); 545 if (__w > __len) 546 { 547 __pad<_CharT, _Traits>::_S_pad(__out, __out.fill(), __pads, 548 __s, __w, __len, false); 549 __s = __pads; 550 __len = __w; 551 } 552 __out.write(__s, __len); 553 __out.width(0); 554 } 555 catch(exception& __fail) 556 { 557 // 27.6.1.2.1 Common requirements. 558 // Turn this on without causing an ios::failure to be thrown. 559 __out.setstate(ios_base::badbit); 560 if ((__out.exceptions() & ios_base::badbit) != 0) 561 __throw_exception_again; 562 } 563 } 564 else if (!__s) 565 __out.setstate(ios_base::badbit); 566 return __out; 567 } 568 569 template<typename _CharT, typename _Traits> 570 basic_ostream<_CharT, _Traits>& 571 operator<<(basic_ostream<_CharT, _Traits>& __out, const char* __s) 572 { 573 typedef basic_ostream<_CharT, _Traits> __ostream_type; 574#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS 575// 167. Improper use of traits_type::length() 576// Note that this is only in 'Review' status. 577 typedef char_traits<char> __traits_type; 578#endif 579 typename __ostream_type::sentry __cerb(__out); 580 if (__cerb && __s) 581 { 582 size_t __clen = __traits_type::length(__s); 583 _CharT* __ws = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * (__clen + 1))); 584 for (size_t __i = 0; __i < __clen; ++__i) 585 __ws[__i] = __out.widen(__s[__i]); 586 _CharT* __str = __ws; 587 588 try 589 { 590 streamsize __len = static_cast<streamsize>(__clen); 591 streamsize __w = __out.width(); 592 _CharT* __pads = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __w)); 593 594 if (__w > __len) 595 { 596 __pad<_CharT, _Traits>::_S_pad(__out, __out.fill(), __pads, 597 __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 else if (!__s) 614 __out.setstate(ios_base::badbit); 615 return __out; 616 } 617 618 // Partial specializations. 619 template<class _Traits> 620 basic_ostream<char, _Traits>& 621 operator<<(basic_ostream<char, _Traits>& __out, const char* __s) 622 { 623 typedef basic_ostream<char, _Traits> __ostream_type; 624 typename __ostream_type::sentry __cerb(__out); 625 if (__cerb && __s) 626 { 627 try 628 { 629 streamsize __w = __out.width(); 630 char* __pads = static_cast<char*>(__builtin_alloca(__w)); 631 streamsize __len = static_cast<streamsize>(_Traits::length(__s)); 632 633 if (__w > __len) 634 { 635 __pad<char, _Traits>::_S_pad(__out, __out.fill(), __pads, 636 __s, __w, __len, false); 637 __s = __pads; 638 __len = __w; 639 } 640 __out.write(__s, __len); 641 __out.width(0); 642 } 643 catch(exception& __fail) 644 { 645 // 27.6.1.2.1 Common requirements. 646 // Turn this on without causing an ios::failure to be thrown. 647 __out.setstate(ios_base::badbit); 648 if ((__out.exceptions() & ios_base::badbit) != 0) 649 __throw_exception_again; 650 } 651 } 652 else if (!__s) 653 __out.setstate(ios_base::badbit); 654 return __out; 655 } 656 657 // 21.3.7.9 basic_string::operator<< 658 template<typename _CharT, typename _Traits, typename _Alloc> 659 basic_ostream<_CharT, _Traits>& 660 operator<<(basic_ostream<_CharT, _Traits>& __out, 661 const basic_string<_CharT, _Traits, _Alloc>& __str) 662 { 663 typedef basic_ostream<_CharT, _Traits> __ostream_type; 664 typename __ostream_type::sentry __cerb(__out); 665 if (__cerb) 666 { 667 const _CharT* __s = __str.data(); 668 streamsize __w = __out.width(); 669 _CharT* __pads = static_cast<_CharT*>(__builtin_alloca(sizeof(_CharT) * __w)); 670 streamsize __len = static_cast<streamsize>(__str.size()); 671#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS 672 // 25. String operator<< uses width() value wrong 673#endif 674 if (__w > __len) 675 { 676 __pad<_CharT, _Traits>::_S_pad(__out, __out.fill(), __pads, __s, 677 __w, __len, false); 678 __s = __pads; 679 __len = __w; 680 } 681 streamsize __res = __out.rdbuf()->sputn(__s, __len); 682 __out.width(0); 683 if (__res != __len) 684 __out.setstate(ios_base::failbit); 685 } 686 return __out; 687 } 688 689 // Inhibit implicit instantiations for required instantiations, 690 // which are defined via explicit instantiations elsewhere. 691 // NB: This syntax is a GNU extension. 692 extern template class basic_ostream<char>; 693 extern template ostream& endl(ostream&); 694 extern template ostream& ends(ostream&); 695 extern template ostream& flush(ostream&); 696 extern template ostream& operator<<(ostream&, char); 697 extern template ostream& operator<<(ostream&, unsigned char); 698 extern template ostream& operator<<(ostream&, signed char); 699 extern template ostream& operator<<(ostream&, const char*); 700 extern template ostream& operator<<(ostream&, const unsigned char*); 701 extern template ostream& operator<<(ostream&, const signed char*); 702 703#ifdef _GLIBCPP_USE_WCHAR_T 704 extern template class basic_ostream<wchar_t>; 705 extern template wostream& endl(wostream&); 706 extern template wostream& ends(wostream&); 707 extern template wostream& flush(wostream&); 708 extern template wostream& operator<<(wostream&, wchar_t); 709 extern template wostream& operator<<(wostream&, char); 710 extern template wostream& operator<<(wostream&, const wchar_t*); 711 extern template wostream& operator<<(wostream&, const char*); 712#endif 713} // namespace std 714