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