1    	// ostream classes -*- C++ -*-
2    	
3    	// Copyright (C) 1997-2013 Free Software Foundation, Inc.
4    	//
5    	// This file is part of the GNU ISO C++ Library.  This library is free
6    	// software; you can redistribute it and/or modify it under the
7    	// terms of the GNU General Public License as published by the
8    	// Free Software Foundation; either version 3, or (at your option)
9    	// any later version.
10   	
11   	// This library is distributed in the hope that it will be useful,
12   	// but WITHOUT ANY WARRANTY; without even the implied warranty of
13   	// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   	// GNU General Public License for more details.
15   	
16   	// Under Section 7 of GPL version 3, you are granted additional
17   	// permissions described in the GCC Runtime Library Exception, version
18   	// 3.1, as published by the Free Software Foundation.
19   	
20   	// You should have received a copy of the GNU General Public License and
21   	// a copy of the GCC Runtime Library Exception along with this program;
22   	// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23   	// <http://www.gnu.org/licenses/>.
24   	
25   	/** @file bits/ostream.tcc
26   	 *  This is an internal header file, included by other library headers.
27   	 *  Do not attempt to use it directly. @headername{ostream}
28   	 */
29   	
30   	//
31   	// ISO C++ 14882: 27.6.2  Output streams
32   	//
33   	
34   	#ifndef _OSTREAM_TCC
35   	#define _OSTREAM_TCC 1
36   	
37   	#pragma GCC system_header
38   	
39   	#include <bits/cxxabi_forced.h>
40   	
41   	namespace std _GLIBCXX_VISIBILITY(default)
42   	{
43   	_GLIBCXX_BEGIN_NAMESPACE_VERSION
44   	
45   	  template<typename _CharT, typename _Traits>
46   	    basic_ostream<_CharT, _Traits>::sentry::
47   	    sentry(basic_ostream<_CharT, _Traits>& __os)
48   	    : _M_ok(false), _M_os(__os)
49   	    {
50   	      // XXX MT
51   	      if (__os.tie() && __os.good())
52   		__os.tie()->flush();
53   	
54   	      if (__os.good())
55   		_M_ok = true;
56   	      else
57   		__os.setstate(ios_base::failbit);
58   	    }
59   	
60   	  template<typename _CharT, typename _Traits>
61   	    template<typename _ValueT>
62   	      basic_ostream<_CharT, _Traits>&
63   	      basic_ostream<_CharT, _Traits>::
64   	      _M_insert(_ValueT __v)
65   	      {
66   		sentry __cerb(*this);
67   		if (__cerb)
68   		  {
69   		    ios_base::iostate __err = ios_base::goodbit;
70   		    __try
71   		      {
72   			const __num_put_type& __np = __check_facet(this->_M_num_put);
73   			if (__np.put(*this, *this, this->fill(), __v).failed())
74   			  __err |= ios_base::badbit;
75   		      }
76   		    __catch(__cxxabiv1::__forced_unwind&)
77   		      {
78   			this->_M_setstate(ios_base::badbit);		
79   			__throw_exception_again;
80   		      }
81   		    __catch(...)
82   		      { this->_M_setstate(ios_base::badbit); }
83   		    if (__err)
84   		      this->setstate(__err);
85   		  }
86   		return *this;
87   	      }
88   	
89   	  template<typename _CharT, typename _Traits>
90   	    basic_ostream<_CharT, _Traits>&
91   	    basic_ostream<_CharT, _Traits>::
92   	    operator<<(short __n)
93   	    {
94   	      // _GLIBCXX_RESOLVE_LIB_DEFECTS
95   	      // 117. basic_ostream uses nonexistent num_put member functions.
96   	      const ios_base::fmtflags __fmt = this->flags() & ios_base::basefield;
97   	      if (__fmt == ios_base::oct || __fmt == ios_base::hex)
98   		return _M_insert(static_cast<long>(static_cast<unsigned short>(__n)));
99   	      else
100  		return _M_insert(static_cast<long>(__n));
101  	    }
102  	
103  	  template<typename _CharT, typename _Traits>
104  	    basic_ostream<_CharT, _Traits>&
105  	    basic_ostream<_CharT, _Traits>::
106  	    operator<<(int __n)
107  	    {
108  	      // _GLIBCXX_RESOLVE_LIB_DEFECTS
109  	      // 117. basic_ostream uses nonexistent num_put member functions.
110  	      const ios_base::fmtflags __fmt = this->flags() & ios_base::basefield;
111  	      if (__fmt == ios_base::oct || __fmt == ios_base::hex)
112  		return _M_insert(static_cast<long>(static_cast<unsigned int>(__n)));
113  	      else
114  		return _M_insert(static_cast<long>(__n));
115  	    }
116  	  
117  	  template<typename _CharT, typename _Traits>
118  	    basic_ostream<_CharT, _Traits>&
119  	    basic_ostream<_CharT, _Traits>::
120  	    operator<<(__streambuf_type* __sbin)
121  	    {
122  	      ios_base::iostate __err = ios_base::goodbit;
123  	      sentry __cerb(*this);
124  	      if (__cerb && __sbin)
125  		{
126  		  __try
127  		    {
128  		      if (!__copy_streambufs(__sbin, this->rdbuf()))
129  			__err |= ios_base::failbit;
130  		    }
131  		  __catch(__cxxabiv1::__forced_unwind&)
132  		    {
133  		      this->_M_setstate(ios_base::badbit);		
134  		      __throw_exception_again;
135  		    }
136  		  __catch(...)
137  		    { this->_M_setstate(ios_base::failbit); }
138  		}
139  	      else if (!__sbin)
140  		__err |= ios_base::badbit;
141  	      if (__err)
142  		this->setstate(__err);
143  	      return *this;
144  	    }
145  	
146  	  template<typename _CharT, typename _Traits>
147  	    basic_ostream<_CharT, _Traits>&
148  	    basic_ostream<_CharT, _Traits>::
149  	    put(char_type __c)
150  	    {
151  	      // _GLIBCXX_RESOLVE_LIB_DEFECTS
152  	      // DR 60. What is a formatted input function?
153  	      // basic_ostream::put(char_type) is an unformatted output function.
154  	      // DR 63. Exception-handling policy for unformatted output.
155  	      // Unformatted output functions should catch exceptions thrown
156  	      // from streambuf members.
157  	      sentry __cerb(*this);
158  	      if (__cerb)
159  		{
160  		  ios_base::iostate __err = ios_base::goodbit;
161  		  __try
162  		    {
163  		      const int_type __put = this->rdbuf()->sputc(__c);
164  		      if (traits_type::eq_int_type(__put, traits_type::eof()))
165  			__err |= ios_base::badbit;
166  		    }
167  		  __catch(__cxxabiv1::__forced_unwind&)
168  		    {
169  		      this->_M_setstate(ios_base::badbit);		
170  		      __throw_exception_again;
171  		    }
172  		  __catch(...)
173  		    { this->_M_setstate(ios_base::badbit); }
174  		  if (__err)
175  		    this->setstate(__err);
176  		}
177  	      return *this;
178  	    }
179  	
180  	  template<typename _CharT, typename _Traits>
181  	    basic_ostream<_CharT, _Traits>&
182  	    basic_ostream<_CharT, _Traits>::
183  	    write(const _CharT* __s, streamsize __n)
184  	    {
185  	      // _GLIBCXX_RESOLVE_LIB_DEFECTS
186  	      // DR 60. What is a formatted input function?
187  	      // basic_ostream::write(const char_type*, streamsize) is an
188  	      // unformatted output function.
189  	      // DR 63. Exception-handling policy for unformatted output.
190  	      // Unformatted output functions should catch exceptions thrown
191  	      // from streambuf members.
192  	      sentry __cerb(*this);
193  	      if (__cerb)
194  		{
195  		  __try
196  		    { _M_write(__s, __n); }
197  		  __catch(__cxxabiv1::__forced_unwind&)
198  		    {
199  		      this->_M_setstate(ios_base::badbit);		
200  		      __throw_exception_again;
201  		    }
202  		  __catch(...)
203  		    { this->_M_setstate(ios_base::badbit); }
204  		}
205  	      return *this;
206  	    }
207  	
208  	  template<typename _CharT, typename _Traits>
209  	    basic_ostream<_CharT, _Traits>&
210  	    basic_ostream<_CharT, _Traits>::
211  	    flush()
212  	    {
213  	      // _GLIBCXX_RESOLVE_LIB_DEFECTS
214  	      // DR 60. What is a formatted input function?
215  	      // basic_ostream::flush() is *not* an unformatted output function.
216  	      ios_base::iostate __err = ios_base::goodbit;
217  	      __try
218  		{
219  		  if (this->rdbuf() && this->rdbuf()->pubsync() == -1)
220  		    __err |= ios_base::badbit;
221  		}
222  	      __catch(__cxxabiv1::__forced_unwind&)
223  		{
224  		  this->_M_setstate(ios_base::badbit);		
225  		  __throw_exception_again;
226  		}
227  	      __catch(...)
228  		{ this->_M_setstate(ios_base::badbit); }
229  	      if (__err)
230  		this->setstate(__err);
231  	      return *this;
232  	    }
233  	
234  	  template<typename _CharT, typename _Traits>
235  	    typename basic_ostream<_CharT, _Traits>::pos_type
236  	    basic_ostream<_CharT, _Traits>::
237  	    tellp()
238  	    {
239  	      pos_type __ret = pos_type(-1);
240  	      __try
241  		{
242  		  if (!this->fail())
243  		    __ret = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::out);
244  		}
245  	      __catch(__cxxabiv1::__forced_unwind&)
246  		{
247  		  this->_M_setstate(ios_base::badbit);		
248  		  __throw_exception_again;
249  		}
250  	      __catch(...)
251  		{ this->_M_setstate(ios_base::badbit); }
252  	      return __ret;
253  	    }
254  	
255  	  template<typename _CharT, typename _Traits>
256  	    basic_ostream<_CharT, _Traits>&
257  	    basic_ostream<_CharT, _Traits>::
258  	    seekp(pos_type __pos)
259  	    {
260  	      ios_base::iostate __err = ios_base::goodbit;
261  	      __try
262  		{
263  		  if (!this->fail())
264  		    {
265  		      // _GLIBCXX_RESOLVE_LIB_DEFECTS
266  		      // 136.  seekp, seekg setting wrong streams?
267  		      const pos_type __p = this->rdbuf()->pubseekpos(__pos,
268  								     ios_base::out);
269  	
270  		      // 129. Need error indication from seekp() and seekg()
271  		      if (__p == pos_type(off_type(-1)))
272  			__err |= ios_base::failbit;
273  		    }
274  		}
275  	      __catch(__cxxabiv1::__forced_unwind&)
276  		{
277  		  this->_M_setstate(ios_base::badbit);		
278  		  __throw_exception_again;
279  		}
280  	      __catch(...)
281  		{ this->_M_setstate(ios_base::badbit); }
282  	      if (__err)
283  		this->setstate(__err);
284  	      return *this;
285  	    }
286  	
287  	  template<typename _CharT, typename _Traits>
288  	    basic_ostream<_CharT, _Traits>&
289  	    basic_ostream<_CharT, _Traits>::
290  	    seekp(off_type __off, ios_base::seekdir __dir)
291  	    {
292  	      ios_base::iostate __err = ios_base::goodbit;
293  	      __try
294  		{
295  		  if (!this->fail())
296  		    {
297  		      // _GLIBCXX_RESOLVE_LIB_DEFECTS
298  		      // 136.  seekp, seekg setting wrong streams?
299  		      const pos_type __p = this->rdbuf()->pubseekoff(__off, __dir,
300  								     ios_base::out);
301  	
302  		      // 129. Need error indication from seekp() and seekg()
303  		      if (__p == pos_type(off_type(-1)))
304  			__err |= ios_base::failbit;
305  		    }
306  		}
307  	      __catch(__cxxabiv1::__forced_unwind&)
308  		{
309  		  this->_M_setstate(ios_base::badbit);		
310  		  __throw_exception_again;
311  		}
312  	      __catch(...)
313  		{ this->_M_setstate(ios_base::badbit); }
314  	      if (__err)
315  		this->setstate(__err);
316  	      return *this;
317  	    }
318  	
319  	  template<typename _CharT, typename _Traits>
320  	    basic_ostream<_CharT, _Traits>&
321  	    operator<<(basic_ostream<_CharT, _Traits>& __out, const char* __s)
322  	    {
323  	      if (!__s)
324  		__out.setstate(ios_base::badbit);
325  	      else
326  		{
327  		  // _GLIBCXX_RESOLVE_LIB_DEFECTS
328  		  // 167.  Improper use of traits_type::length()
329  		  const size_t __clen = char_traits<char>::length(__s);
330  		  __try
331  		    {
332  		      struct __ptr_guard
333  		      {
334  			_CharT *__p;
335  			__ptr_guard (_CharT *__ip): __p(__ip) { }
336  			~__ptr_guard() { delete[] __p; }
337  			_CharT* __get() { return __p; }
338  		      } __pg (new _CharT[__clen]);
339  	
340  		      _CharT *__ws = __pg.__get();
341  		      for (size_t  __i = 0; __i < __clen; ++__i)
342  			__ws[__i] = __out.widen(__s[__i]);
343  		      __ostream_insert(__out, __ws, __clen);
344  		    }
345  		  __catch(__cxxabiv1::__forced_unwind&)
346  		    {
347  		      __out._M_setstate(ios_base::badbit);
348  		      __throw_exception_again;
349  		    }
350  		  __catch(...)
351  		    { __out._M_setstate(ios_base::badbit); }
352  		}
353  	      return __out;
354  	    }
355  	
356  	  // Inhibit implicit instantiations for required instantiations,
357  	  // which are defined via explicit instantiations elsewhere.
358  	#if _GLIBCXX_EXTERN_TEMPLATE
359  	  extern template class basic_ostream<char>;
360  	  extern template ostream& endl(ostream&);
361  	  extern template ostream& ends(ostream&);
362  	  extern template ostream& flush(ostream&);
363  	  extern template ostream& operator<<(ostream&, char);
364  	  extern template ostream& operator<<(ostream&, unsigned char);
365  	  extern template ostream& operator<<(ostream&, signed char);
366  	  extern template ostream& operator<<(ostream&, const char*);
367  	  extern template ostream& operator<<(ostream&, const unsigned char*);
368  	  extern template ostream& operator<<(ostream&, const signed char*);
369  	
370  	  extern template ostream& ostream::_M_insert(long);
371  	  extern template ostream& ostream::_M_insert(unsigned long);
372  	  extern template ostream& ostream::_M_insert(bool);
373  	#ifdef _GLIBCXX_USE_LONG_LONG
374  	  extern template ostream& ostream::_M_insert(long long);
375  	  extern template ostream& ostream::_M_insert(unsigned long long);
376  	#endif
377  	  extern template ostream& ostream::_M_insert(double);
378  	  extern template ostream& ostream::_M_insert(long double);
379  	  extern template ostream& ostream::_M_insert(const void*);
380  	
381  	#ifdef _GLIBCXX_USE_WCHAR_T
382  	  extern template class basic_ostream<wchar_t>;
383  	  extern template wostream& endl(wostream&);
384  	  extern template wostream& ends(wostream&);
385  	  extern template wostream& flush(wostream&);
386  	  extern template wostream& operator<<(wostream&, wchar_t);
387  	  extern template wostream& operator<<(wostream&, char);
388  	  extern template wostream& operator<<(wostream&, const wchar_t*);
389  	  extern template wostream& operator<<(wostream&, const char*);
390  	
391  	  extern template wostream& wostream::_M_insert(long);
392  	  extern template wostream& wostream::_M_insert(unsigned long);
393  	  extern template wostream& wostream::_M_insert(bool);
394  	#ifdef _GLIBCXX_USE_LONG_LONG
395  	  extern template wostream& wostream::_M_insert(long long);
396  	  extern template wostream& wostream::_M_insert(unsigned long long);
397  	#endif
398  	  extern template wostream& wostream::_M_insert(double);
399  	  extern template wostream& wostream::_M_insert(long double);
400  	  extern template wostream& wostream::_M_insert(const void*);
401  	#endif
402  	#endif
403  	
404  	_GLIBCXX_END_NAMESPACE_VERSION
405  	} // namespace std
406  	
407  	#endif
408