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