libstdc++
|
00001 // ostream classes -*- C++ -*- 00002 00003 // Copyright (C) 1997-2013 Free Software Foundation, Inc. 00004 // 00005 // This file is part of the GNU ISO C++ Library. This library is free 00006 // software; you can redistribute it and/or modify it under the 00007 // terms of the GNU General Public License as published by the 00008 // Free Software Foundation; either version 3, or (at your option) 00009 // any later version. 00010 00011 // This library is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 // GNU General Public License for more details. 00015 00016 // Under Section 7 of GPL version 3, you are granted additional 00017 // permissions described in the GCC Runtime Library Exception, version 00018 // 3.1, as published by the Free Software Foundation. 00019 00020 // You should have received a copy of the GNU General Public License and 00021 // a copy of the GCC Runtime Library Exception along with this program; 00022 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 00023 // <http://www.gnu.org/licenses/>. 00024 00025 /** @file bits/ostream.tcc 00026 * This is an internal header file, included by other library headers. 00027 * Do not attempt to use it directly. @headername{ostream} 00028 */ 00029 00030 // 00031 // ISO C++ 14882: 27.6.2 Output streams 00032 // 00033 00034 #ifndef _OSTREAM_TCC 00035 #define _OSTREAM_TCC 1 00036 00037 #pragma GCC system_header 00038 00039 #include <bits/cxxabi_forced.h> 00040 00041 namespace std _GLIBCXX_VISIBILITY(default) 00042 { 00043 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00044 00045 template<typename _CharT, typename _Traits> 00046 basic_ostream<_CharT, _Traits>::sentry:: 00047 sentry(basic_ostream<_CharT, _Traits>& __os) 00048 : _M_ok(false), _M_os(__os) 00049 { 00050 // XXX MT 00051 if (__os.tie() && __os.good()) 00052 __os.tie()->flush(); 00053 00054 if (__os.good()) 00055 _M_ok = true; 00056 else 00057 __os.setstate(ios_base::failbit); 00058 } 00059 00060 template<typename _CharT, typename _Traits> 00061 template<typename _ValueT> 00062 basic_ostream<_CharT, _Traits>& 00063 basic_ostream<_CharT, _Traits>:: 00064 _M_insert(_ValueT __v) 00065 { 00066 sentry __cerb(*this); 00067 if (__cerb) 00068 { 00069 ios_base::iostate __err = ios_base::goodbit; 00070 __try 00071 { 00072 const __num_put_type& __np = __check_facet(this->_M_num_put); 00073 if (__np.put(*this, *this, this->fill(), __v).failed()) 00074 __err |= ios_base::badbit; 00075 } 00076 __catch(__cxxabiv1::__forced_unwind&) 00077 { 00078 this->_M_setstate(ios_base::badbit); 00079 __throw_exception_again; 00080 } 00081 __catch(...) 00082 { this->_M_setstate(ios_base::badbit); } 00083 if (__err) 00084 this->setstate(__err); 00085 } 00086 return *this; 00087 } 00088 00089 template<typename _CharT, typename _Traits> 00090 basic_ostream<_CharT, _Traits>& 00091 basic_ostream<_CharT, _Traits>:: 00092 operator<<(short __n) 00093 { 00094 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00095 // 117. basic_ostream uses nonexistent num_put member functions. 00096 const ios_base::fmtflags __fmt = this->flags() & ios_base::basefield; 00097 if (__fmt == ios_base::oct || __fmt == ios_base::hex) 00098 return _M_insert(static_cast<long>(static_cast<unsigned short>(__n))); 00099 else 00100 return _M_insert(static_cast<long>(__n)); 00101 } 00102 00103 template<typename _CharT, typename _Traits> 00104 basic_ostream<_CharT, _Traits>& 00105 basic_ostream<_CharT, _Traits>:: 00106 operator<<(int __n) 00107 { 00108 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00109 // 117. basic_ostream uses nonexistent num_put member functions. 00110 const ios_base::fmtflags __fmt = this->flags() & ios_base::basefield; 00111 if (__fmt == ios_base::oct || __fmt == ios_base::hex) 00112 return _M_insert(static_cast<long>(static_cast<unsigned int>(__n))); 00113 else 00114 return _M_insert(static_cast<long>(__n)); 00115 } 00116 00117 template<typename _CharT, typename _Traits> 00118 basic_ostream<_CharT, _Traits>& 00119 basic_ostream<_CharT, _Traits>:: 00120 operator<<(__streambuf_type* __sbin) 00121 { 00122 ios_base::iostate __err = ios_base::goodbit; 00123 sentry __cerb(*this); 00124 if (__cerb && __sbin) 00125 { 00126 __try 00127 { 00128 if (!__copy_streambufs(__sbin, this->rdbuf())) 00129 __err |= ios_base::failbit; 00130 } 00131 __catch(__cxxabiv1::__forced_unwind&) 00132 { 00133 this->_M_setstate(ios_base::badbit); 00134 __throw_exception_again; 00135 } 00136 __catch(...) 00137 { this->_M_setstate(ios_base::failbit); } 00138 } 00139 else if (!__sbin) 00140 __err |= ios_base::badbit; 00141 if (__err) 00142 this->setstate(__err); 00143 return *this; 00144 } 00145 00146 template<typename _CharT, typename _Traits> 00147 basic_ostream<_CharT, _Traits>& 00148 basic_ostream<_CharT, _Traits>:: 00149 put(char_type __c) 00150 { 00151 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00152 // DR 60. What is a formatted input function? 00153 // basic_ostream::put(char_type) is an unformatted output function. 00154 // DR 63. Exception-handling policy for unformatted output. 00155 // Unformatted output functions should catch exceptions thrown 00156 // from streambuf members. 00157 sentry __cerb(*this); 00158 if (__cerb) 00159 { 00160 ios_base::iostate __err = ios_base::goodbit; 00161 __try 00162 { 00163 const int_type __put = this->rdbuf()->sputc(__c); 00164 if (traits_type::eq_int_type(__put, traits_type::eof())) 00165 __err |= ios_base::badbit; 00166 } 00167 __catch(__cxxabiv1::__forced_unwind&) 00168 { 00169 this->_M_setstate(ios_base::badbit); 00170 __throw_exception_again; 00171 } 00172 __catch(...) 00173 { this->_M_setstate(ios_base::badbit); } 00174 if (__err) 00175 this->setstate(__err); 00176 } 00177 return *this; 00178 } 00179 00180 template<typename _CharT, typename _Traits> 00181 basic_ostream<_CharT, _Traits>& 00182 basic_ostream<_CharT, _Traits>:: 00183 write(const _CharT* __s, streamsize __n) 00184 { 00185 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00186 // DR 60. What is a formatted input function? 00187 // basic_ostream::write(const char_type*, streamsize) is an 00188 // unformatted output function. 00189 // DR 63. Exception-handling policy for unformatted output. 00190 // Unformatted output functions should catch exceptions thrown 00191 // from streambuf members. 00192 sentry __cerb(*this); 00193 if (__cerb) 00194 { 00195 __try 00196 { _M_write(__s, __n); } 00197 __catch(__cxxabiv1::__forced_unwind&) 00198 { 00199 this->_M_setstate(ios_base::badbit); 00200 __throw_exception_again; 00201 } 00202 __catch(...) 00203 { this->_M_setstate(ios_base::badbit); } 00204 } 00205 return *this; 00206 } 00207 00208 template<typename _CharT, typename _Traits> 00209 basic_ostream<_CharT, _Traits>& 00210 basic_ostream<_CharT, _Traits>:: 00211 flush() 00212 { 00213 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00214 // DR 60. What is a formatted input function? 00215 // basic_ostream::flush() is *not* an unformatted output function. 00216 ios_base::iostate __err = ios_base::goodbit; 00217 __try 00218 { 00219 if (this->rdbuf() && this->rdbuf()->pubsync() == -1) 00220 __err |= ios_base::badbit; 00221 } 00222 __catch(__cxxabiv1::__forced_unwind&) 00223 { 00224 this->_M_setstate(ios_base::badbit); 00225 __throw_exception_again; 00226 } 00227 __catch(...) 00228 { this->_M_setstate(ios_base::badbit); } 00229 if (__err) 00230 this->setstate(__err); 00231 return *this; 00232 } 00233 00234 template<typename _CharT, typename _Traits> 00235 typename basic_ostream<_CharT, _Traits>::pos_type 00236 basic_ostream<_CharT, _Traits>:: 00237 tellp() 00238 { 00239 pos_type __ret = pos_type(-1); 00240 __try 00241 { 00242 if (!this->fail()) 00243 __ret = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::out); 00244 } 00245 __catch(__cxxabiv1::__forced_unwind&) 00246 { 00247 this->_M_setstate(ios_base::badbit); 00248 __throw_exception_again; 00249 } 00250 __catch(...) 00251 { this->_M_setstate(ios_base::badbit); } 00252 return __ret; 00253 } 00254 00255 template<typename _CharT, typename _Traits> 00256 basic_ostream<_CharT, _Traits>& 00257 basic_ostream<_CharT, _Traits>:: 00258 seekp(pos_type __pos) 00259 { 00260 ios_base::iostate __err = ios_base::goodbit; 00261 __try 00262 { 00263 if (!this->fail()) 00264 { 00265 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00266 // 136. seekp, seekg setting wrong streams? 00267 const pos_type __p = this->rdbuf()->pubseekpos(__pos, 00268 ios_base::out); 00269 00270 // 129. Need error indication from seekp() and seekg() 00271 if (__p == pos_type(off_type(-1))) 00272 __err |= ios_base::failbit; 00273 } 00274 } 00275 __catch(__cxxabiv1::__forced_unwind&) 00276 { 00277 this->_M_setstate(ios_base::badbit); 00278 __throw_exception_again; 00279 } 00280 __catch(...) 00281 { this->_M_setstate(ios_base::badbit); } 00282 if (__err) 00283 this->setstate(__err); 00284 return *this; 00285 } 00286 00287 template<typename _CharT, typename _Traits> 00288 basic_ostream<_CharT, _Traits>& 00289 basic_ostream<_CharT, _Traits>:: 00290 seekp(off_type __off, ios_base::seekdir __dir) 00291 { 00292 ios_base::iostate __err = ios_base::goodbit; 00293 __try 00294 { 00295 if (!this->fail()) 00296 { 00297 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00298 // 136. seekp, seekg setting wrong streams? 00299 const pos_type __p = this->rdbuf()->pubseekoff(__off, __dir, 00300 ios_base::out); 00301 00302 // 129. Need error indication from seekp() and seekg() 00303 if (__p == pos_type(off_type(-1))) 00304 __err |= ios_base::failbit; 00305 } 00306 } 00307 __catch(__cxxabiv1::__forced_unwind&) 00308 { 00309 this->_M_setstate(ios_base::badbit); 00310 __throw_exception_again; 00311 } 00312 __catch(...) 00313 { this->_M_setstate(ios_base::badbit); } 00314 if (__err) 00315 this->setstate(__err); 00316 return *this; 00317 } 00318 00319 template<typename _CharT, typename _Traits> 00320 basic_ostream<_CharT, _Traits>& 00321 operator<<(basic_ostream<_CharT, _Traits>& __out, const char* __s) 00322 { 00323 if (!__s) 00324 __out.setstate(ios_base::badbit); 00325 else 00326 { 00327 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00328 // 167. Improper use of traits_type::length() 00329 const size_t __clen = char_traits<char>::length(__s); 00330 __try 00331 { 00332 struct __ptr_guard 00333 { 00334 _CharT *__p; 00335 __ptr_guard (_CharT *__ip): __p(__ip) { } 00336 ~__ptr_guard() { delete[] __p; } 00337 _CharT* __get() { return __p; } 00338 } __pg (new _CharT[__clen]); 00339 00340 _CharT *__ws = __pg.__get(); 00341 for (size_t __i = 0; __i < __clen; ++__i) 00342 __ws[__i] = __out.widen(__s[__i]); 00343 __ostream_insert(__out, __ws, __clen); 00344 } 00345 __catch(__cxxabiv1::__forced_unwind&) 00346 { 00347 __out._M_setstate(ios_base::badbit); 00348 __throw_exception_again; 00349 } 00350 __catch(...) 00351 { __out._M_setstate(ios_base::badbit); } 00352 } 00353 return __out; 00354 } 00355 00356 // Inhibit implicit instantiations for required instantiations, 00357 // which are defined via explicit instantiations elsewhere. 00358 #if _GLIBCXX_EXTERN_TEMPLATE 00359 extern template class basic_ostream<char>; 00360 extern template ostream& endl(ostream&); 00361 extern template ostream& ends(ostream&); 00362 extern template ostream& flush(ostream&); 00363 extern template ostream& operator<<(ostream&, char); 00364 extern template ostream& operator<<(ostream&, unsigned char); 00365 extern template ostream& operator<<(ostream&, signed char); 00366 extern template ostream& operator<<(ostream&, const char*); 00367 extern template ostream& operator<<(ostream&, const unsigned char*); 00368 extern template ostream& operator<<(ostream&, const signed char*); 00369 00370 extern template ostream& ostream::_M_insert(long); 00371 extern template ostream& ostream::_M_insert(unsigned long); 00372 extern template ostream& ostream::_M_insert(bool); 00373 #ifdef _GLIBCXX_USE_LONG_LONG 00374 extern template ostream& ostream::_M_insert(long long); 00375 extern template ostream& ostream::_M_insert(unsigned long long); 00376 #endif 00377 extern template ostream& ostream::_M_insert(double); 00378 extern template ostream& ostream::_M_insert(long double); 00379 extern template ostream& ostream::_M_insert(const void*); 00380 00381 #ifdef _GLIBCXX_USE_WCHAR_T 00382 extern template class basic_ostream<wchar_t>; 00383 extern template wostream& endl(wostream&); 00384 extern template wostream& ends(wostream&); 00385 extern template wostream& flush(wostream&); 00386 extern template wostream& operator<<(wostream&, wchar_t); 00387 extern template wostream& operator<<(wostream&, char); 00388 extern template wostream& operator<<(wostream&, const wchar_t*); 00389 extern template wostream& operator<<(wostream&, const char*); 00390 00391 extern template wostream& wostream::_M_insert(long); 00392 extern template wostream& wostream::_M_insert(unsigned long); 00393 extern template wostream& wostream::_M_insert(bool); 00394 #ifdef _GLIBCXX_USE_LONG_LONG 00395 extern template wostream& wostream::_M_insert(long long); 00396 extern template wostream& wostream::_M_insert(unsigned long long); 00397 #endif 00398 extern template wostream& wostream::_M_insert(double); 00399 extern template wostream& wostream::_M_insert(long double); 00400 extern template wostream& wostream::_M_insert(const void*); 00401 #endif 00402 #endif 00403 00404 _GLIBCXX_END_NAMESPACE_VERSION 00405 } // namespace std 00406 00407 #endif