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