1// ostream classes -*- C++ -*- 2 3// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 4// 2006, 2007, 2008, 2009, 2010, 2011 5// Free Software Foundation, Inc. 6// 7// This file is part of the GNU ISO C++ Library. This library is free 8// software; you can redistribute it and/or modify it under the 9// terms of the GNU General Public License as published by the 10// Free Software Foundation; either version 3, or (at your option) 11// any later version. 12 13// This library is distributed in the hope that it will be useful, 14// but WITHOUT ANY WARRANTY; without even the implied warranty of 15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16// GNU General Public License for more details. 17 18// Under Section 7 of GPL version 3, you are granted additional 19// permissions described in the GCC Runtime Library Exception, version 20// 3.1, as published by the Free Software Foundation. 21 22// You should have received a copy of the GNU General Public License and 23// a copy of the GCC Runtime Library Exception along with this program; 24// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 25// <http://www.gnu.org/licenses/>. 26 27/** @file bits/ostream.tcc 28 * This is an internal header file, included by other library headers. 29 * Do not attempt to use it directly. @headername{ostream} 30 */ 31 32// 33// ISO C++ 14882: 27.6.2 Output streams 34// 35 36#ifndef _OSTREAM_TCC 37#define _OSTREAM_TCC 1 38 39#pragma GCC system_header 40 41#include <bits/cxxabi_forced.h> 42 43namespace std _GLIBCXX_VISIBILITY(default) 44{ 45_GLIBCXX_BEGIN_NAMESPACE_VERSION 46 47 template<typename _CharT, typename _Traits> 48 basic_ostream<_CharT, _Traits>::sentry:: 49 sentry(basic_ostream<_CharT, _Traits>& __os) 50 : _M_ok(false), _M_os(__os) 51 { 52 // XXX MT 53 if (__os.tie() && __os.good()) 54 __os.tie()->flush(); 55 56 if (__os.good()) 57 _M_ok = true; 58 else 59 __os.setstate(ios_base::failbit); 60 } 61 62 template<typename _CharT, typename _Traits> 63 template<typename _ValueT> 64 basic_ostream<_CharT, _Traits>& 65 basic_ostream<_CharT, _Traits>:: 66 _M_insert(_ValueT __v) 67 { 68 sentry __cerb(*this); 69 if (__cerb) 70 { 71 ios_base::iostate __err = ios_base::goodbit; 72 __try 73 { 74 const __num_put_type& __np = __check_facet(this->_M_num_put); 75 if (__np.put(*this, *this, this->fill(), __v).failed()) 76 __err |= ios_base::badbit; 77 } 78 __catch(__cxxabiv1::__forced_unwind&) 79 { 80 this->_M_setstate(ios_base::badbit); 81 __throw_exception_again; 82 } 83 __catch(...) 84 { this->_M_setstate(ios_base::badbit); } 85 if (__err) 86 this->setstate(__err); 87 } 88 return *this; 89 } 90 91 template<typename _CharT, typename _Traits> 92 basic_ostream<_CharT, _Traits>& 93 basic_ostream<_CharT, _Traits>:: 94 operator<<(short __n) 95 { 96 // _GLIBCXX_RESOLVE_LIB_DEFECTS 97 // 117. basic_ostream uses nonexistent num_put member functions. 98 const ios_base::fmtflags __fmt = this->flags() & ios_base::basefield; 99 if (__fmt == ios_base::oct || __fmt == ios_base::hex) 100 return _M_insert(static_cast<long>(static_cast<unsigned short>(__n))); 101 else 102 return _M_insert(static_cast<long>(__n)); 103 } 104 105 template<typename _CharT, typename _Traits> 106 basic_ostream<_CharT, _Traits>& 107 basic_ostream<_CharT, _Traits>:: 108 operator<<(int __n) 109 { 110 // _GLIBCXX_RESOLVE_LIB_DEFECTS 111 // 117. basic_ostream uses nonexistent num_put member functions. 112 const ios_base::fmtflags __fmt = this->flags() & ios_base::basefield; 113 if (__fmt == ios_base::oct || __fmt == ios_base::hex) 114 return _M_insert(static_cast<long>(static_cast<unsigned int>(__n))); 115 else 116 return _M_insert(static_cast<long>(__n)); 117 } 118 119 template<typename _CharT, typename _Traits> 120 basic_ostream<_CharT, _Traits>& 121 basic_ostream<_CharT, _Traits>:: 122 operator<<(__streambuf_type* __sbin) 123 { 124 ios_base::iostate __err = ios_base::goodbit; 125 sentry __cerb(*this); 126 if (__cerb && __sbin) 127 { 128 __try 129 { 130 if (!__copy_streambufs(__sbin, this->rdbuf())) 131 __err |= ios_base::failbit; 132 } 133 __catch(__cxxabiv1::__forced_unwind&) 134 { 135 this->_M_setstate(ios_base::badbit); 136 __throw_exception_again; 137 } 138 __catch(...) 139 { this->_M_setstate(ios_base::failbit); } 140 } 141 else if (!__sbin) 142 __err |= ios_base::badbit; 143 if (__err) 144 this->setstate(__err); 145 return *this; 146 } 147 148 template<typename _CharT, typename _Traits> 149 basic_ostream<_CharT, _Traits>& 150 basic_ostream<_CharT, _Traits>:: 151 put(char_type __c) 152 { 153 // _GLIBCXX_RESOLVE_LIB_DEFECTS 154 // DR 60. What is a formatted input function? 155 // basic_ostream::put(char_type) is an unformatted output function. 156 // DR 63. Exception-handling policy for unformatted output. 157 // Unformatted output functions should catch exceptions thrown 158 // from streambuf members. 159 sentry __cerb(*this); 160 if (__cerb) 161 { 162 ios_base::iostate __err = ios_base::goodbit; 163 __try 164 { 165 const int_type __put = this->rdbuf()->sputc(__c); 166 if (traits_type::eq_int_type(__put, traits_type::eof())) 167 __err |= ios_base::badbit; 168 } 169 __catch(__cxxabiv1::__forced_unwind&) 170 { 171 this->_M_setstate(ios_base::badbit); 172 __throw_exception_again; 173 } 174 __catch(...) 175 { this->_M_setstate(ios_base::badbit); } 176 if (__err) 177 this->setstate(__err); 178 } 179 return *this; 180 } 181 182 template<typename _CharT, typename _Traits> 183 basic_ostream<_CharT, _Traits>& 184 basic_ostream<_CharT, _Traits>:: 185 write(const _CharT* __s, streamsize __n) 186 { 187 // _GLIBCXX_RESOLVE_LIB_DEFECTS 188 // DR 60. What is a formatted input function? 189 // basic_ostream::write(const char_type*, streamsize) is an 190 // unformatted output function. 191 // DR 63. Exception-handling policy for unformatted output. 192 // Unformatted output functions should catch exceptions thrown 193 // from streambuf members. 194 sentry __cerb(*this); 195 if (__cerb) 196 { 197 __try 198 { _M_write(__s, __n); } 199 __catch(__cxxabiv1::__forced_unwind&) 200 { 201 this->_M_setstate(ios_base::badbit); 202 __throw_exception_again; 203 } 204 __catch(...) 205 { this->_M_setstate(ios_base::badbit); } 206 } 207 return *this; 208 } 209 210 template<typename _CharT, typename _Traits> 211 basic_ostream<_CharT, _Traits>& 212 basic_ostream<_CharT, _Traits>:: 213 flush() 214 { 215 // _GLIBCXX_RESOLVE_LIB_DEFECTS 216 // DR 60. What is a formatted input function? 217 // basic_ostream::flush() is *not* an unformatted output function. 218 ios_base::iostate __err = ios_base::goodbit; 219 __try 220 { 221 if (this->rdbuf() && this->rdbuf()->pubsync() == -1) 222 __err |= ios_base::badbit; 223 } 224 __catch(__cxxabiv1::__forced_unwind&) 225 { 226 this->_M_setstate(ios_base::badbit); 227 __throw_exception_again; 228 } 229 __catch(...) 230 { this->_M_setstate(ios_base::badbit); } 231 if (__err) 232 this->setstate(__err); 233 return *this; 234 } 235 236 template<typename _CharT, typename _Traits> 237 typename basic_ostream<_CharT, _Traits>::pos_type 238 basic_ostream<_CharT, _Traits>:: 239 tellp() 240 { 241 pos_type __ret = pos_type(-1); 242 __try 243 { 244 if (!this->fail()) 245 __ret = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::out); 246 } 247 __catch(__cxxabiv1::__forced_unwind&) 248 { 249 this->_M_setstate(ios_base::badbit); 250 __throw_exception_again; 251 } 252 __catch(...) 253 { this->_M_setstate(ios_base::badbit); } 254 return __ret; 255 } 256 257 template<typename _CharT, typename _Traits> 258 basic_ostream<_CharT, _Traits>& 259 basic_ostream<_CharT, _Traits>:: 260 seekp(pos_type __pos) 261 { 262 ios_base::iostate __err = ios_base::goodbit; 263 __try 264 { 265 if (!this->fail()) 266 { 267 // _GLIBCXX_RESOLVE_LIB_DEFECTS 268 // 136. seekp, seekg setting wrong streams? 269 const pos_type __p = this->rdbuf()->pubseekpos(__pos, 270 ios_base::out); 271 272 // 129. Need error indication from seekp() and seekg() 273 if (__p == pos_type(off_type(-1))) 274 __err |= ios_base::failbit; 275 } 276 } 277 __catch(__cxxabiv1::__forced_unwind&) 278 { 279 this->_M_setstate(ios_base::badbit); 280 __throw_exception_again; 281 } 282 __catch(...) 283 { this->_M_setstate(ios_base::badbit); } 284 if (__err) 285 this->setstate(__err); 286 return *this; 287 } 288 289 template<typename _CharT, typename _Traits> 290 basic_ostream<_CharT, _Traits>& 291 basic_ostream<_CharT, _Traits>:: 292 seekp(off_type __off, ios_base::seekdir __dir) 293 { 294 ios_base::iostate __err = ios_base::goodbit; 295 __try 296 { 297 if (!this->fail()) 298 { 299 // _GLIBCXX_RESOLVE_LIB_DEFECTS 300 // 136. seekp, seekg setting wrong streams? 301 const pos_type __p = this->rdbuf()->pubseekoff(__off, __dir, 302 ios_base::out); 303 304 // 129. Need error indication from seekp() and seekg() 305 if (__p == pos_type(off_type(-1))) 306 __err |= ios_base::failbit; 307 } 308 } 309 __catch(__cxxabiv1::__forced_unwind&) 310 { 311 this->_M_setstate(ios_base::badbit); 312 __throw_exception_again; 313 } 314 __catch(...) 315 { this->_M_setstate(ios_base::badbit); } 316 if (__err) 317 this->setstate(__err); 318 return *this; 319 } 320 321 template<typename _CharT, typename _Traits> 322 basic_ostream<_CharT, _Traits>& 323 operator<<(basic_ostream<_CharT, _Traits>& __out, const char* __s) 324 { 325 if (!__s) 326 __out.setstate(ios_base::badbit); 327 else 328 { 329 // _GLIBCXX_RESOLVE_LIB_DEFECTS 330 // 167. Improper use of traits_type::length() 331 const size_t __clen = char_traits<char>::length(__s); 332 __try 333 { 334 struct __ptr_guard 335 { 336 _CharT *__p; 337 __ptr_guard (_CharT *__ip): __p(__ip) { } 338 ~__ptr_guard() { delete[] __p; } 339 _CharT* __get() { return __p; } 340 } __pg (new _CharT[__clen]); 341 342 _CharT *__ws = __pg.__get(); 343 for (size_t __i = 0; __i < __clen; ++__i) 344 __ws[__i] = __out.widen(__s[__i]); 345 __ostream_insert(__out, __ws, __clen); 346 } 347 __catch(__cxxabiv1::__forced_unwind&) 348 { 349 __out._M_setstate(ios_base::badbit); 350 __throw_exception_again; 351 } 352 __catch(...) 353 { __out._M_setstate(ios_base::badbit); } 354 } 355 return __out; 356 } 357 358 // Inhibit implicit instantiations for required instantiations, 359 // which are defined via explicit instantiations elsewhere. 360#if _GLIBCXX_EXTERN_TEMPLATE 361 extern template class basic_ostream<char>; 362 extern template ostream& endl(ostream&); 363 extern template ostream& ends(ostream&); 364 extern template ostream& flush(ostream&); 365 extern template ostream& operator<<(ostream&, char); 366 extern template ostream& operator<<(ostream&, unsigned char); 367 extern template ostream& operator<<(ostream&, signed char); 368 extern template ostream& operator<<(ostream&, const char*); 369 extern template ostream& operator<<(ostream&, const unsigned char*); 370 extern template ostream& operator<<(ostream&, const signed char*); 371 372 extern template ostream& ostream::_M_insert(long); 373 extern template ostream& ostream::_M_insert(unsigned long); 374 extern template ostream& ostream::_M_insert(bool); 375#ifdef _GLIBCXX_USE_LONG_LONG 376 extern template ostream& ostream::_M_insert(long long); 377 extern template ostream& ostream::_M_insert(unsigned long long); 378#endif 379 extern template ostream& ostream::_M_insert(double); 380 extern template ostream& ostream::_M_insert(long double); 381 extern template ostream& ostream::_M_insert(const void*); 382 383#ifdef _GLIBCXX_USE_WCHAR_T 384 extern template class basic_ostream<wchar_t>; 385 extern template wostream& endl(wostream&); 386 extern template wostream& ends(wostream&); 387 extern template wostream& flush(wostream&); 388 extern template wostream& operator<<(wostream&, wchar_t); 389 extern template wostream& operator<<(wostream&, char); 390 extern template wostream& operator<<(wostream&, const wchar_t*); 391 extern template wostream& operator<<(wostream&, const char*); 392 393 extern template wostream& wostream::_M_insert(long); 394 extern template wostream& wostream::_M_insert(unsigned long); 395 extern template wostream& wostream::_M_insert(bool); 396#ifdef _GLIBCXX_USE_LONG_LONG 397 extern template wostream& wostream::_M_insert(long long); 398 extern template wostream& wostream::_M_insert(unsigned long long); 399#endif 400 extern template wostream& wostream::_M_insert(double); 401 extern template wostream& wostream::_M_insert(long double); 402 extern template wostream& wostream::_M_insert(const void*); 403#endif 404#endif 405 406_GLIBCXX_END_NAMESPACE_VERSION 407} // namespace std 408 409#endif 410