197403Sobrien// ostream classes -*- C++ -*- 297403Sobrien 3169691Skan// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 4169691Skan// 2006, 2007 597403Sobrien// Free Software Foundation, Inc. 697403Sobrien// 797403Sobrien// This file is part of the GNU ISO C++ Library. This library is free 897403Sobrien// software; you can redistribute it and/or modify it under the 997403Sobrien// terms of the GNU General Public License as published by the 1097403Sobrien// Free Software Foundation; either version 2, or (at your option) 1197403Sobrien// any later version. 1297403Sobrien 1397403Sobrien// This library is distributed in the hope that it will be useful, 1497403Sobrien// but WITHOUT ANY WARRANTY; without even the implied warranty of 1597403Sobrien// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1697403Sobrien// GNU General Public License for more details. 1797403Sobrien 1897403Sobrien// You should have received a copy of the GNU General Public License along 1997403Sobrien// with this library; see the file COPYING. If not, write to the Free 20169691Skan// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 2197403Sobrien// USA. 2297403Sobrien 2397403Sobrien// As a special exception, you may use this file as part of a free software 2497403Sobrien// library without restriction. Specifically, if other files instantiate 2597403Sobrien// templates or use macros or inline functions from this file, or you compile 2697403Sobrien// this file and link it with other files to produce an executable, this 2797403Sobrien// file does not by itself cause the resulting executable to be covered by 2897403Sobrien// the GNU General Public License. This exception does not however 2997403Sobrien// invalidate any other reasons why the executable file might be covered by 3097403Sobrien// the GNU General Public License. 3197403Sobrien 32169691Skan/** @file ostream.tcc 33169691Skan * This is an internal header file, included by other library headers. 34169691Skan * You should not attempt to use it directly. 35169691Skan */ 36169691Skan 3797403Sobrien// 3897403Sobrien// ISO C++ 14882: 27.6.2 Output streams 3997403Sobrien// 4097403Sobrien 41132720Skan#ifndef _OSTREAM_TCC 42132720Skan#define _OSTREAM_TCC 1 43132720Skan 4497403Sobrien#pragma GCC system_header 4597403Sobrien 4697403Sobrien#include <locale> 4797403Sobrien 48169691Skan_GLIBCXX_BEGIN_NAMESPACE(std) 49169691Skan 5097403Sobrien template<typename _CharT, typename _Traits> 5197403Sobrien basic_ostream<_CharT, _Traits>::sentry:: 52132720Skan sentry(basic_ostream<_CharT, _Traits>& __os) 53132720Skan : _M_ok(false), _M_os(__os) 5497403Sobrien { 55117397Skan // XXX MT 56117397Skan if (__os.tie() && __os.good()) 57117397Skan __os.tie()->flush(); 58117397Skan 59117397Skan if (__os.good()) 60117397Skan _M_ok = true; 61117397Skan else 62132720Skan __os.setstate(ios_base::failbit); 6397403Sobrien } 64132720Skan 6597403Sobrien template<typename _CharT, typename _Traits> 66169691Skan template<typename _ValueT> 67169691Skan basic_ostream<_CharT, _Traits>& 68169691Skan basic_ostream<_CharT, _Traits>:: 69169691Skan _M_insert(_ValueT __v) 70169691Skan { 71169691Skan sentry __cerb(*this); 72169691Skan if (__cerb) 73169691Skan { 74169691Skan ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); 75169691Skan try 76169691Skan { 77169691Skan const __num_put_type& __np = __check_facet(this->_M_num_put); 78169691Skan if (__np.put(*this, *this, this->fill(), __v).failed()) 79169691Skan __err |= ios_base::badbit; 80169691Skan } 81169691Skan catch(...) 82169691Skan { this->_M_setstate(ios_base::badbit); } 83169691Skan if (__err) 84169691Skan this->setstate(__err); 85169691Skan } 86169691Skan return *this; 87169691Skan } 88132720Skan 8997403Sobrien template<typename _CharT, typename _Traits> 90132720Skan basic_ostream<_CharT, _Traits>& 9197403Sobrien basic_ostream<_CharT, _Traits>:: 92169691Skan operator<<(short __n) 9397403Sobrien { 94132720Skan // _GLIBCXX_RESOLVE_LIB_DEFECTS 95169691Skan // 117. basic_ostream uses nonexistent num_put member functions. 96169691Skan const ios_base::fmtflags __fmt = this->flags() & ios_base::basefield; 97169691Skan if (__fmt == ios_base::oct || __fmt == ios_base::hex) 98169691Skan return _M_insert(static_cast<long>(static_cast<unsigned short>(__n))); 99169691Skan else 100169691Skan return _M_insert(static_cast<long>(__n)); 10197403Sobrien } 10297403Sobrien 10397403Sobrien template<typename _CharT, typename _Traits> 104132720Skan basic_ostream<_CharT, _Traits>& 10597403Sobrien basic_ostream<_CharT, _Traits>:: 106169691Skan operator<<(int __n) 10797403Sobrien { 108132720Skan // _GLIBCXX_RESOLVE_LIB_DEFECTS 109169691Skan // 117. basic_ostream uses nonexistent num_put member functions. 110169691Skan const ios_base::fmtflags __fmt = this->flags() & ios_base::basefield; 111169691Skan if (__fmt == ios_base::oct || __fmt == ios_base::hex) 112169691Skan return _M_insert(static_cast<long>(static_cast<unsigned int>(__n))); 113169691Skan else 114169691Skan return _M_insert(static_cast<long>(__n)); 11597403Sobrien } 116169691Skan 11797403Sobrien template<typename _CharT, typename _Traits> 118132720Skan basic_ostream<_CharT, _Traits>& 119132720Skan basic_ostream<_CharT, _Traits>:: 120132720Skan operator<<(__streambuf_type* __sbin) 12197403Sobrien { 122132720Skan ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); 12397403Sobrien sentry __cerb(*this); 124132720Skan if (__cerb && __sbin) 12597403Sobrien { 126132720Skan try 12797403Sobrien { 128132720Skan if (!__copy_streambufs(__sbin, this->rdbuf())) 129132720Skan __err |= ios_base::failbit; 13097403Sobrien } 131117397Skan catch(...) 132132720Skan { this->_M_setstate(ios_base::failbit); } 13397403Sobrien } 134132720Skan else if (!__sbin) 135132720Skan __err |= ios_base::badbit; 136132720Skan if (__err) 137132720Skan this->setstate(__err); 13897403Sobrien return *this; 13997403Sobrien } 14097403Sobrien 14197403Sobrien template<typename _CharT, typename _Traits> 14297403Sobrien basic_ostream<_CharT, _Traits>& 143132720Skan basic_ostream<_CharT, _Traits>:: 144132720Skan put(char_type __c) 145132720Skan { 146132720Skan // _GLIBCXX_RESOLVE_LIB_DEFECTS 147132720Skan // DR 60. What is a formatted input function? 148132720Skan // basic_ostream::put(char_type) is an unformatted output function. 149132720Skan // DR 63. Exception-handling policy for unformatted output. 150132720Skan // Unformatted output functions should catch exceptions thrown 151132720Skan // from streambuf members. 15297403Sobrien sentry __cerb(*this); 153132720Skan if (__cerb) 15497403Sobrien { 155132720Skan ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); 156132720Skan try 157132720Skan { 158132720Skan const int_type __put = this->rdbuf()->sputc(__c); 159132720Skan if (traits_type::eq_int_type(__put, traits_type::eof())) 160132720Skan __err |= ios_base::badbit; 161132720Skan } 162132720Skan catch (...) 163132720Skan { this->_M_setstate(ios_base::badbit); } 164132720Skan if (__err) 165132720Skan this->setstate(__err); 16697403Sobrien } 16797403Sobrien return *this; 16897403Sobrien } 16997403Sobrien 17097403Sobrien template<typename _CharT, typename _Traits> 17197403Sobrien basic_ostream<_CharT, _Traits>& 172132720Skan basic_ostream<_CharT, _Traits>:: 173132720Skan write(const _CharT* __s, streamsize __n) 17497403Sobrien { 175132720Skan // _GLIBCXX_RESOLVE_LIB_DEFECTS 176132720Skan // DR 60. What is a formatted input function? 177132720Skan // basic_ostream::write(const char_type*, streamsize) is an 178132720Skan // unformatted output function. 179132720Skan // DR 63. Exception-handling policy for unformatted output. 180132720Skan // Unformatted output functions should catch exceptions thrown 181132720Skan // from streambuf members. 18297403Sobrien sentry __cerb(*this); 18397403Sobrien if (__cerb) 18497403Sobrien { 185132720Skan try 186132720Skan { _M_write(__s, __n); } 187132720Skan catch (...) 188132720Skan { this->_M_setstate(ios_base::badbit); } 18997403Sobrien } 19097403Sobrien return *this; 19197403Sobrien } 19297403Sobrien 19397403Sobrien template<typename _CharT, typename _Traits> 19497403Sobrien basic_ostream<_CharT, _Traits>& 195132720Skan basic_ostream<_CharT, _Traits>:: 196132720Skan flush() 19797403Sobrien { 198132720Skan // _GLIBCXX_RESOLVE_LIB_DEFECTS 199132720Skan // DR 60. What is a formatted input function? 200132720Skan // basic_ostream::flush() is *not* an unformatted output function. 201132720Skan ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); 202132720Skan try 20397403Sobrien { 20497403Sobrien if (this->rdbuf() && this->rdbuf()->pubsync() == -1) 205132720Skan __err |= ios_base::badbit; 20697403Sobrien } 207132720Skan catch(...) 208132720Skan { this->_M_setstate(ios_base::badbit); } 209132720Skan if (__err) 210132720Skan this->setstate(__err); 21197403Sobrien return *this; 21297403Sobrien } 213132720Skan 21497403Sobrien template<typename _CharT, typename _Traits> 21597403Sobrien typename basic_ostream<_CharT, _Traits>::pos_type 216132720Skan basic_ostream<_CharT, _Traits>:: 217132720Skan tellp() 21897403Sobrien { 21997403Sobrien pos_type __ret = pos_type(-1); 220132720Skan try 221132720Skan { 222132720Skan if (!this->fail()) 223132720Skan __ret = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::out); 224132720Skan } 225132720Skan catch(...) 226132720Skan { this->_M_setstate(ios_base::badbit); } 22797403Sobrien return __ret; 22897403Sobrien } 22997403Sobrien 23097403Sobrien template<typename _CharT, typename _Traits> 23197403Sobrien basic_ostream<_CharT, _Traits>& 232132720Skan basic_ostream<_CharT, _Traits>:: 233132720Skan seekp(pos_type __pos) 23497403Sobrien { 235132720Skan ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); 236132720Skan try 23797403Sobrien { 238132720Skan if (!this->fail()) 239132720Skan { 240132720Skan // _GLIBCXX_RESOLVE_LIB_DEFECTS 241132720Skan // 136. seekp, seekg setting wrong streams? 242132720Skan const pos_type __p = this->rdbuf()->pubseekpos(__pos, 243132720Skan ios_base::out); 24497403Sobrien 245132720Skan // 129. Need error indication from seekp() and seekg() 246132720Skan if (__p == pos_type(off_type(-1))) 247132720Skan __err |= ios_base::failbit; 248132720Skan } 24997403Sobrien } 250132720Skan catch(...) 251132720Skan { this->_M_setstate(ios_base::badbit); } 252132720Skan if (__err) 253132720Skan this->setstate(__err); 25497403Sobrien return *this; 25597403Sobrien } 25697403Sobrien 25797403Sobrien template<typename _CharT, typename _Traits> 25897403Sobrien basic_ostream<_CharT, _Traits>& 25997403Sobrien basic_ostream<_CharT, _Traits>:: 260132720Skan seekp(off_type __off, ios_base::seekdir __dir) 26197403Sobrien { 262132720Skan ios_base::iostate __err = ios_base::iostate(ios_base::goodbit); 263132720Skan try 26497403Sobrien { 265132720Skan if (!this->fail()) 266132720Skan { 267132720Skan // _GLIBCXX_RESOLVE_LIB_DEFECTS 268132720Skan // 136. seekp, seekg setting wrong streams? 269132720Skan const pos_type __p = this->rdbuf()->pubseekoff(__off, __dir, 270132720Skan ios_base::out); 27197403Sobrien 272132720Skan // 129. Need error indication from seekp() and seekg() 273132720Skan if (__p == pos_type(off_type(-1))) 274132720Skan __err |= ios_base::failbit; 275132720Skan } 27697403Sobrien } 277132720Skan catch(...) 278132720Skan { this->_M_setstate(ios_base::badbit); } 279132720Skan if (__err) 280132720Skan this->setstate(__err); 28197403Sobrien return *this; 28297403Sobrien } 28397403Sobrien 28497403Sobrien template<typename _CharT, typename _Traits> 28597403Sobrien basic_ostream<_CharT, _Traits>& 286169691Skan operator<<(basic_ostream<_CharT, _Traits>& __out, const char* __s) 28797403Sobrien { 288169691Skan if (!__s) 289169691Skan __out.setstate(ios_base::badbit); 290169691Skan else 29197403Sobrien { 292169691Skan // _GLIBCXX_RESOLVE_LIB_DEFECTS 293169691Skan // 167. Improper use of traits_type::length() 294169691Skan const size_t __clen = char_traits<char>::length(__s); 295169691Skan _CharT* __ws = 0; 296132720Skan try 297169691Skan { 298169691Skan __ws = new _CharT[__clen]; 299169691Skan for (size_t __i = 0; __i < __clen; ++__i) 300169691Skan __ws[__i] = __out.widen(__s[__i]); 30197403Sobrien } 302117397Skan catch(...) 30397403Sobrien { 304169691Skan delete [] __ws; 305169691Skan __out._M_setstate(ios_base::badbit); 306169691Skan return __out; 30797403Sobrien } 30897403Sobrien 309132720Skan try 31097403Sobrien { 311169691Skan __ostream_insert(__out, __ws, __clen); 312169691Skan delete [] __ws; 31397403Sobrien } 314117397Skan catch(...) 31597403Sobrien { 316169691Skan delete [] __ws; 317169691Skan __throw_exception_again; 31897403Sobrien } 31997403Sobrien } 32097403Sobrien return __out; 32197403Sobrien } 32297403Sobrien 32397403Sobrien // Inhibit implicit instantiations for required instantiations, 324132720Skan // which are defined via explicit instantiations elsewhere. 32597403Sobrien // NB: This syntax is a GNU extension. 326132720Skan#if _GLIBCXX_EXTERN_TEMPLATE 32797403Sobrien extern template class basic_ostream<char>; 32897403Sobrien extern template ostream& endl(ostream&); 32997403Sobrien extern template ostream& ends(ostream&); 33097403Sobrien extern template ostream& flush(ostream&); 33197403Sobrien extern template ostream& operator<<(ostream&, char); 33297403Sobrien extern template ostream& operator<<(ostream&, unsigned char); 33397403Sobrien extern template ostream& operator<<(ostream&, signed char); 33497403Sobrien extern template ostream& operator<<(ostream&, const char*); 33597403Sobrien extern template ostream& operator<<(ostream&, const unsigned char*); 33697403Sobrien extern template ostream& operator<<(ostream&, const signed char*); 33797403Sobrien 338169691Skan extern template ostream& ostream::_M_insert(long); 339169691Skan extern template ostream& ostream::_M_insert(unsigned long); 340169691Skan extern template ostream& ostream::_M_insert(bool); 341169691Skan#ifdef _GLIBCXX_USE_LONG_LONG 342169691Skan extern template ostream& ostream::_M_insert(long long); 343169691Skan extern template ostream& ostream::_M_insert(unsigned long long); 344169691Skan#endif 345169691Skan extern template ostream& ostream::_M_insert(double); 346169691Skan extern template ostream& ostream::_M_insert(long double); 347169691Skan extern template ostream& ostream::_M_insert(const void*); 348169691Skan 349132720Skan#ifdef _GLIBCXX_USE_WCHAR_T 35097403Sobrien extern template class basic_ostream<wchar_t>; 35197403Sobrien extern template wostream& endl(wostream&); 35297403Sobrien extern template wostream& ends(wostream&); 35397403Sobrien extern template wostream& flush(wostream&); 35497403Sobrien extern template wostream& operator<<(wostream&, wchar_t); 35597403Sobrien extern template wostream& operator<<(wostream&, char); 35697403Sobrien extern template wostream& operator<<(wostream&, const wchar_t*); 35797403Sobrien extern template wostream& operator<<(wostream&, const char*); 358169691Skan 359169691Skan extern template wostream& wostream::_M_insert(long); 360169691Skan extern template wostream& wostream::_M_insert(unsigned long); 361169691Skan extern template wostream& wostream::_M_insert(bool); 362169691Skan#ifdef _GLIBCXX_USE_LONG_LONG 363169691Skan extern template wostream& wostream::_M_insert(long long); 364169691Skan extern template wostream& wostream::_M_insert(unsigned long long); 365102782Skan#endif 366169691Skan extern template wostream& wostream::_M_insert(double); 367169691Skan extern template wostream& wostream::_M_insert(long double); 368169691Skan extern template wostream& wostream::_M_insert(const void*); 369117397Skan#endif 370169691Skan#endif 371132720Skan 372169691Skan_GLIBCXX_END_NAMESPACE 373169691Skan 374132720Skan#endif 375