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