# ostream.tcc

Go to the documentation of this file.

    00001 // ostream classes -*- C++ -*-
    00002
    00003 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
    00004 // 2006, 2007, 2008, 2009
    00005 // Free Software Foundation, Inc.
    00006 //
    00007 // This file is part of the GNU ISO C++ Library.  This library is free
    00008 // software; you can redistribute it and/or modify it under the
    00009 // terms of the GNU General Public License as published by the
    00010 // Free Software Foundation; either version 3, or (at your option)
    00011 // any later version.
    00012
    00013 // This library is distributed in the hope that it will be useful,
    00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of
    00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    00016 // GNU General Public License for more details.
    00017
    00018 // Under Section 7 of GPL version 3, you are granted additional
    00019 // permissions described in the GCC Runtime Library Exception, version
    00020 // 3.1, as published by the Free Software Foundation.
    00021
    00022 // You should have received a copy of the GNU General Public License and
    00023 // a copy of the GCC Runtime Library Exception along with this program;
    00024 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
    00025 // <http://www.gnu.org/licenses/>.
    00026
    00027 /** @file ostream.tcc
    00028  *  This is an internal header file, included by other library headers.
    00029  *  You should not attempt to use it directly.
    00030  */
    00031
    00032 //
    00033 // ISO C++ 14882: 27.6.2  Output streams
    00034 //
    00035
    00036 #ifndef _OSTREAM_TCC
    00037 #define _OSTREAM_TCC 1
    00038
    00039 #pragma GCC system_header
    00040
    00041 #include <cxxabi-forced.h>
    00042
    00043 _GLIBCXX_BEGIN_NAMESPACE(std)
    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   // NB:  This syntax is a GNU extension.
    00359 #if _GLIBCXX_EXTERN_TEMPLATE
    00360   extern template class basic_ostream<char>;
    00361   extern template ostream& endl(ostream&);
    00362   extern template ostream& ends(ostream&);
    00363   extern template ostream& flush(ostream&);
    00364   extern template ostream& operator<<(ostream&, char);
    00365   extern template ostream& operator<<(ostream&, unsigned char);
    00366   extern template ostream& operator<<(ostream&, signed char);
    00367   extern template ostream& operator<<(ostream&, const char*);
    00368   extern template ostream& operator<<(ostream&, const unsigned char*);
    00369   extern template ostream& operator<<(ostream&, const signed char*);
    00370
    00371   extern template ostream& ostream::_M_insert(long);
    00372   extern template ostream& ostream::_M_insert(unsigned long);
    00373   extern template ostream& ostream::_M_insert(bool);
    00374 #ifdef _GLIBCXX_USE_LONG_LONG
    00375   extern template ostream& ostream::_M_insert(long long);
    00376   extern template ostream& ostream::_M_insert(unsigned long long);
    00377 #endif
    00378   extern template ostream& ostream::_M_insert(double);
    00379   extern template ostream& ostream::_M_insert(long double);
    00380   extern template ostream& ostream::_M_insert(const void*);
    00381
    00382 #ifdef _GLIBCXX_USE_WCHAR_T
    00383   extern template class basic_ostream<wchar_t>;
    00384   extern template wostream& endl(wostream&);
    00385   extern template wostream& ends(wostream&);
    00386   extern template wostream& flush(wostream&);
    00387   extern template wostream& operator<<(wostream&, wchar_t);
    00388   extern template wostream& operator<<(wostream&, char);
    00389   extern template wostream& operator<<(wostream&, const wchar_t*);
    00390   extern template wostream& operator<<(wostream&, const char*);
    00391
    00392   extern template wostream& wostream::_M_insert(long);
    00393   extern template wostream& wostream::_M_insert(unsigned long);
    00394   extern template wostream& wostream::_M_insert(bool);
    00395 #ifdef _GLIBCXX_USE_LONG_LONG
    00396   extern template wostream& wostream::_M_insert(long long);
    00397   extern template wostream& wostream::_M_insert(unsigned long long);
    00398 #endif
    00399   extern template wostream& wostream::_M_insert(double);
    00400   extern template wostream& wostream::_M_insert(long double);
    00401   extern template wostream& wostream::_M_insert(const void*);
    00402 #endif
    00403 #endif
    00404
    00405 _GLIBCXX_END_NAMESPACE
    00406
    00407 #endif