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