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 <locale>
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(...)
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::iostate(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(...)
00132         { this->_M_setstate(ios_base::failbit); }
00133     }
00134       else if (!__sbin)
00135     __err |= ios_base::badbit;
00136       if (__err)
00137     this->setstate(__err);
00138       return *this;
00139     }
00140 
00141   template<typename _CharT, typename _Traits>
00142     basic_ostream<_CharT, _Traits>&
00143     basic_ostream<_CharT, _Traits>::
00144     put(char_type __c)
00145     {
00146       // _GLIBCXX_RESOLVE_LIB_DEFECTS
00147       // DR 60. What is a formatted input function?
00148       // basic_ostream::put(char_type) is an unformatted output function.
00149       // DR 63. Exception-handling policy for unformatted output.
00150       // Unformatted output functions should catch exceptions thrown
00151       // from streambuf members.
00152       sentry __cerb(*this);
00153       if (__cerb)
00154     {
00155       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
00156       try
00157         {
00158           const int_type __put = this->rdbuf()->sputc(__c);
00159           if (traits_type::eq_int_type(__put, traits_type::eof()))
00160         __err |= ios_base::badbit;
00161         }
00162       catch (...)
00163         { this->_M_setstate(ios_base::badbit); }
00164       if (__err)
00165         this->setstate(__err);
00166     }
00167       return *this;
00168     }
00169 
00170   template<typename _CharT, typename _Traits>
00171     basic_ostream<_CharT, _Traits>&
00172     basic_ostream<_CharT, _Traits>::
00173     write(const _CharT* __s, streamsize __n)
00174     {
00175       // _GLIBCXX_RESOLVE_LIB_DEFECTS
00176       // DR 60. What is a formatted input function?
00177       // basic_ostream::write(const char_type*, streamsize) is an
00178       // unformatted output function.
00179       // DR 63. Exception-handling policy for unformatted output.
00180       // Unformatted output functions should catch exceptions thrown
00181       // from streambuf members.
00182       sentry __cerb(*this);
00183       if (__cerb)
00184     {
00185       try
00186         { _M_write(__s, __n); }
00187       catch (...)
00188         { this->_M_setstate(ios_base::badbit); }
00189     }
00190       return *this;
00191     }
00192 
00193   template<typename _CharT, typename _Traits>
00194     basic_ostream<_CharT, _Traits>&
00195     basic_ostream<_CharT, _Traits>::
00196     flush()
00197     {
00198       // _GLIBCXX_RESOLVE_LIB_DEFECTS
00199       // DR 60. What is a formatted input function?
00200       // basic_ostream::flush() is *not* an unformatted output function.
00201       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
00202       try
00203     {
00204       if (this->rdbuf() && this->rdbuf()->pubsync() == -1)
00205         __err |= ios_base::badbit;
00206     }
00207       catch(...)
00208     { this->_M_setstate(ios_base::badbit); }
00209       if (__err)
00210     this->setstate(__err);
00211       return *this;
00212     }
00213 
00214   template<typename _CharT, typename _Traits>
00215     typename basic_ostream<_CharT, _Traits>::pos_type
00216     basic_ostream<_CharT, _Traits>::
00217     tellp()
00218     {
00219       pos_type __ret = pos_type(-1);
00220       try
00221     {
00222       if (!this->fail())
00223         __ret = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::out);
00224     }
00225       catch(...)
00226     { this->_M_setstate(ios_base::badbit); }
00227       return __ret;
00228     }
00229 
00230   template<typename _CharT, typename _Traits>
00231     basic_ostream<_CharT, _Traits>&
00232     basic_ostream<_CharT, _Traits>::
00233     seekp(pos_type __pos)
00234     {
00235       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
00236       try
00237     {
00238       if (!this->fail())
00239         {
00240           // _GLIBCXX_RESOLVE_LIB_DEFECTS
00241           // 136.  seekp, seekg setting wrong streams?
00242           const pos_type __p = this->rdbuf()->pubseekpos(__pos,
00243                                  ios_base::out);
00244 
00245           // 129. Need error indication from seekp() and seekg()
00246           if (__p == pos_type(off_type(-1)))
00247         __err |= ios_base::failbit;
00248         }
00249     }
00250       catch(...)
00251     { this->_M_setstate(ios_base::badbit); }
00252       if (__err)
00253     this->setstate(__err);
00254       return *this;
00255     }
00256 
00257   template<typename _CharT, typename _Traits>
00258     basic_ostream<_CharT, _Traits>&
00259     basic_ostream<_CharT, _Traits>::
00260     seekp(off_type __off, ios_base::seekdir __dir)
00261     {
00262       ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
00263       try
00264     {
00265       if (!this->fail())
00266         {
00267           // _GLIBCXX_RESOLVE_LIB_DEFECTS
00268           // 136.  seekp, seekg setting wrong streams?
00269           const pos_type __p = this->rdbuf()->pubseekoff(__off, __dir,
00270                                  ios_base::out);
00271 
00272           // 129. Need error indication from seekp() and seekg()
00273           if (__p == pos_type(off_type(-1)))
00274         __err |= ios_base::failbit;
00275         }
00276     }
00277       catch(...)
00278     { this->_M_setstate(ios_base::badbit); }
00279       if (__err)
00280     this->setstate(__err);
00281       return *this;
00282     }
00283 
00284   template<typename _CharT, typename _Traits>
00285     basic_ostream<_CharT, _Traits>&
00286     operator<<(basic_ostream<_CharT, _Traits>& __out, const char* __s)
00287     {
00288       if (!__s)
00289     __out.setstate(ios_base::badbit);
00290       else
00291     {
00292       // _GLIBCXX_RESOLVE_LIB_DEFECTS
00293       // 167.  Improper use of traits_type::length()
00294       const size_t __clen = char_traits<char>::length(__s);      
00295       _CharT* __ws = 0;
00296       try
00297         { 
00298           __ws = new _CharT[__clen];
00299           for (size_t  __i = 0; __i < __clen; ++__i)
00300         __ws[__i] = __out.widen(__s[__i]);
00301         }
00302       catch(...)
00303         {
00304           delete [] __ws;
00305           __out._M_setstate(ios_base::badbit);
00306           return __out;
00307         }
00308 
00309       try
00310         {
00311           __ostream_insert(__out, __ws, __clen);
00312           delete [] __ws;
00313         }
00314       catch(...)
00315         {
00316           delete [] __ws;
00317           __throw_exception_again;
00318         }
00319     }
00320       return __out;
00321     }
00322 
00323   // Inhibit implicit instantiations for required instantiations,
00324   // which are defined via explicit instantiations elsewhere.
00325   // NB:  This syntax is a GNU extension.
00326 #if _GLIBCXX_EXTERN_TEMPLATE
00327   extern template class basic_ostream<char>;
00328   extern template ostream& endl(ostream&);
00329   extern template ostream& ends(ostream&);
00330   extern template ostream& flush(ostream&);
00331   extern template ostream& operator<<(ostream&, char);
00332   extern template ostream& operator<<(ostream&, unsigned char);
00333   extern template ostream& operator<<(ostream&, signed char);
00334   extern template ostream& operator<<(ostream&, const char*);
00335   extern template ostream& operator<<(ostream&, const unsigned char*);
00336   extern template ostream& operator<<(ostream&, const signed char*);
00337 
00338   extern template ostream& ostream::_M_insert(long);
00339   extern template ostream& ostream::_M_insert(unsigned long);
00340   extern template ostream& ostream::_M_insert(bool);
00341 #ifdef _GLIBCXX_USE_LONG_LONG
00342   extern template ostream& ostream::_M_insert(long long);
00343   extern template ostream& ostream::_M_insert(unsigned long long);
00344 #endif
00345   extern template ostream& ostream::_M_insert(double);
00346   extern template ostream& ostream::_M_insert(long double);
00347   extern template ostream& ostream::_M_insert(const void*);
00348 
00349 #ifdef _GLIBCXX_USE_WCHAR_T
00350   extern template class basic_ostream<wchar_t>;
00351   extern template wostream& endl(wostream&);
00352   extern template wostream& ends(wostream&);
00353   extern template wostream& flush(wostream&);
00354   extern template wostream& operator<<(wostream&, wchar_t);
00355   extern template wostream& operator<<(wostream&, char);
00356   extern template wostream& operator<<(wostream&, const wchar_t*);
00357   extern template wostream& operator<<(wostream&, const char*);
00358 
00359   extern template wostream& wostream::_M_insert(long);
00360   extern template wostream& wostream::_M_insert(unsigned long);
00361   extern template wostream& wostream::_M_insert(bool);
00362 #ifdef _GLIBCXX_USE_LONG_LONG
00363   extern template wostream& wostream::_M_insert(long long);
00364   extern template wostream& wostream::_M_insert(unsigned long long);
00365 #endif
00366   extern template wostream& wostream::_M_insert(double);
00367   extern template wostream& wostream::_M_insert(long double);
00368   extern template wostream& wostream::_M_insert(const void*);
00369 #endif
00370 #endif
00371 
00372 _GLIBCXX_END_NAMESPACE
00373 
00374 #endif

Generated on Thu Nov 1 13:12:19 2007 for libstdc++ by  doxygen 1.5.1