libstdc++
ostream.tcc
Go to the documentation of this file.
00001 // ostream classes -*- C++ -*-
00002 
00003 // Copyright (C) 1997-2015 Free Software Foundation, Inc.
00004 //
00005 // This file is part of the GNU ISO C++ Library.  This library is free
00006 // software; you can redistribute it and/or modify it under the
00007 // terms of the GNU General Public License as published by the
00008 // Free Software Foundation; either version 3, or (at your option)
00009 // any later version.
00010 
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 
00016 // Under Section 7 of GPL version 3, you are granted additional
00017 // permissions described in the GCC Runtime Library Exception, version
00018 // 3.1, as published by the Free Software Foundation.
00019 
00020 // You should have received a copy of the GNU General Public License and
00021 // a copy of the GCC Runtime Library Exception along with this program;
00022 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00023 // <http://www.gnu.org/licenses/>.
00024 
00025 /** @file bits/ostream.tcc
00026  *  This is an internal header file, included by other library headers.
00027  *  Do not attempt to use it directly. @headername{ostream}
00028  */
00029 
00030 //
00031 // ISO C++ 14882: 27.6.2  Output streams
00032 //
00033 
00034 #ifndef _OSTREAM_TCC
00035 #define _OSTREAM_TCC 1
00036 
00037 #pragma GCC system_header
00038 
00039 #include <bits/cxxabi_forced.h>
00040 
00041 namespace std _GLIBCXX_VISIBILITY(default)
00042 {
00043 _GLIBCXX_BEGIN_NAMESPACE_VERSION
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 #if _GLIBCXX_EXTERN_TEMPLATE
00359   extern template class basic_ostream<char>;
00360   extern template ostream& endl(ostream&);
00361   extern template ostream& ends(ostream&);
00362   extern template ostream& flush(ostream&);
00363   extern template ostream& operator<<(ostream&, char);
00364   extern template ostream& operator<<(ostream&, unsigned char);
00365   extern template ostream& operator<<(ostream&, signed char);
00366   extern template ostream& operator<<(ostream&, const char*);
00367   extern template ostream& operator<<(ostream&, const unsigned char*);
00368   extern template ostream& operator<<(ostream&, const signed char*);
00369 
00370   extern template ostream& ostream::_M_insert(long);
00371   extern template ostream& ostream::_M_insert(unsigned long);
00372   extern template ostream& ostream::_M_insert(bool);
00373 #ifdef _GLIBCXX_USE_LONG_LONG
00374   extern template ostream& ostream::_M_insert(long long);
00375   extern template ostream& ostream::_M_insert(unsigned long long);
00376 #endif
00377   extern template ostream& ostream::_M_insert(double);
00378   extern template ostream& ostream::_M_insert(long double);
00379   extern template ostream& ostream::_M_insert(const void*);
00380 
00381 #ifdef _GLIBCXX_USE_WCHAR_T
00382   extern template class basic_ostream<wchar_t>;
00383   extern template wostream& endl(wostream&);
00384   extern template wostream& ends(wostream&);
00385   extern template wostream& flush(wostream&);
00386   extern template wostream& operator<<(wostream&, wchar_t);
00387   extern template wostream& operator<<(wostream&, char);
00388   extern template wostream& operator<<(wostream&, const wchar_t*);
00389   extern template wostream& operator<<(wostream&, const char*);
00390 
00391   extern template wostream& wostream::_M_insert(long);
00392   extern template wostream& wostream::_M_insert(unsigned long);
00393   extern template wostream& wostream::_M_insert(bool);
00394 #ifdef _GLIBCXX_USE_LONG_LONG
00395   extern template wostream& wostream::_M_insert(long long);
00396   extern template wostream& wostream::_M_insert(unsigned long long);
00397 #endif
00398   extern template wostream& wostream::_M_insert(double);
00399   extern template wostream& wostream::_M_insert(long double);
00400   extern template wostream& wostream::_M_insert(const void*);
00401 #endif
00402 #endif
00403 
00404 _GLIBCXX_END_NAMESPACE_VERSION
00405 } // namespace std
00406 
00407 #endif