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