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