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