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

Generated on Sat Oct 25 05:09:06 2008 for libstdc++ by  doxygen 1.5.6