libstdc++
ostream.tcc
Go to the documentation of this file.
1 // ostream classes -*- C++ -*-
2 
3 // Copyright (C) 1997-2023 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>
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 if (__os.bad())
57  __os.setstate(ios_base::failbit);
58  }
59 
60  template<typename _CharT, typename _Traits>
61  template<typename _ValueT>
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 #ifndef _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT
73  const __num_put_type& __np = __check_facet(this->_M_num_put);
74 #else
75  const __num_put_type& __np
76  = use_facet<__num_put_type>(this->_M_ios_locale);
77 #endif
78  if (__np.put(*this, *this, this->fill(), __v).failed())
79  __err |= ios_base::badbit;
80  }
82  {
83  this->_M_setstate(ios_base::badbit);
84  __throw_exception_again;
85  }
86  __catch(...)
87  { this->_M_setstate(ios_base::badbit); }
88  if (__err)
89  this->setstate(__err);
90  }
91  return *this;
92  }
93 
94  template<typename _CharT, typename _Traits>
95  basic_ostream<_CharT, _Traits>&
97  operator<<(short __n)
98  {
99  // _GLIBCXX_RESOLVE_LIB_DEFECTS
100  // 117. basic_ostream uses nonexistent num_put member functions.
101  const ios_base::fmtflags __fmt = this->flags() & ios_base::basefield;
102  if (__fmt == ios_base::oct || __fmt == ios_base::hex)
103  return _M_insert(static_cast<long>(static_cast<unsigned short>(__n)));
104  else
105  return _M_insert(static_cast<long>(__n));
106  }
107 
108  template<typename _CharT, typename _Traits>
111  operator<<(int __n)
112  {
113  // _GLIBCXX_RESOLVE_LIB_DEFECTS
114  // 117. basic_ostream uses nonexistent num_put member functions.
115  const ios_base::fmtflags __fmt = this->flags() & ios_base::basefield;
116  if (__fmt == ios_base::oct || __fmt == ios_base::hex)
117  return _M_insert(static_cast<long>(static_cast<unsigned int>(__n)));
118  else
119  return _M_insert(static_cast<long>(__n));
120  }
121 
122  template<typename _CharT, typename _Traits>
126  {
127  ios_base::iostate __err = ios_base::goodbit;
128  sentry __cerb(*this);
129  if (__cerb && __sbin)
130  {
131  __try
132  {
133  if (!__copy_streambufs(__sbin, this->rdbuf()))
134  __err |= ios_base::failbit;
135  }
137  {
138  this->_M_setstate(ios_base::badbit);
139  __throw_exception_again;
140  }
141  __catch(...)
142  { this->_M_setstate(ios_base::failbit); }
143  }
144  else if (!__sbin)
145  __err |= ios_base::badbit;
146  if (__err)
147  this->setstate(__err);
148  return *this;
149  }
150 
151  template<typename _CharT, typename _Traits>
154  put(char_type __c)
155  {
156  // _GLIBCXX_RESOLVE_LIB_DEFECTS
157  // DR 60. What is a formatted input function?
158  // basic_ostream::put(char_type) is an unformatted output function.
159  // DR 63. Exception-handling policy for unformatted output.
160  // Unformatted output functions should catch exceptions thrown
161  // from streambuf members.
162  sentry __cerb(*this);
163  if (__cerb)
164  {
165  ios_base::iostate __err = ios_base::goodbit;
166  __try
167  {
168  const int_type __put = this->rdbuf()->sputc(__c);
169  if (traits_type::eq_int_type(__put, traits_type::eof()))
170  __err |= ios_base::badbit;
171  }
173  {
174  this->_M_setstate(ios_base::badbit);
175  __throw_exception_again;
176  }
177  __catch(...)
178  { this->_M_setstate(ios_base::badbit); }
179  if (__err)
180  this->setstate(__err);
181  }
182  return *this;
183  }
184 
185  template<typename _CharT, typename _Traits>
188  write(const _CharT* __s, streamsize __n)
189  {
190  // _GLIBCXX_RESOLVE_LIB_DEFECTS
191  // DR 60. What is a formatted input function?
192  // basic_ostream::write(const char_type*, streamsize) is an
193  // unformatted output function.
194  // DR 63. Exception-handling policy for unformatted output.
195  // Unformatted output functions should catch exceptions thrown
196  // from streambuf members.
197  sentry __cerb(*this);
198  if (__cerb)
199  {
200  ios_base::iostate __err = ios_base::goodbit;
201  __try
202  {
203  if (this->rdbuf()->sputn(__s, __n) != __n)
204  __err = ios_base::badbit;
205  }
207  {
208  this->_M_setstate(ios_base::badbit);
209  __throw_exception_again;
210  }
211  __catch(...)
212  { this->_M_setstate(ios_base::badbit); }
213  if (__err)
214  this->setstate(ios_base::badbit);
215  }
216  return *this;
217  }
218 
219  template<typename _CharT, typename _Traits>
223  {
224  // _GLIBCXX_RESOLVE_LIB_DEFECTS
225  // DR 60. What is a formatted input function?
226  // basic_ostream::flush() is *not* an unformatted output function.
227  // 581. flush() not unformatted function
228  // basic_ostream::flush() *is* an unformatted output function.
229  if (__streambuf_type* __buf = this->rdbuf())
230  {
231  sentry __cerb(*this);
232  if (__cerb)
233  {
234  ios_base::iostate __err = ios_base::goodbit;
235  __try
236  {
237  if (this->rdbuf()->pubsync() == -1)
238  __err |= ios_base::badbit;
239  }
241  {
242  this->_M_setstate(ios_base::badbit);
243  __throw_exception_again;
244  }
245  __catch(...)
246  { this->_M_setstate(ios_base::badbit); }
247  if (__err)
248  this->setstate(__err);
249  }
250  }
251  return *this;
252  }
253 
254  template<typename _CharT, typename _Traits>
255  typename basic_ostream<_CharT, _Traits>::pos_type
258  {
259  sentry __cerb(*this);
260  pos_type __ret = pos_type(-1);
261  if (!this->fail())
262  __ret = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::out);
263  return __ret;
264  }
265 
266  template<typename _CharT, typename _Traits>
269  seekp(pos_type __pos)
270  {
271  sentry __cerb(*this);
272  if (!this->fail())
273  {
274  // _GLIBCXX_RESOLVE_LIB_DEFECTS
275  // 136. seekp, seekg setting wrong streams?
276  const pos_type __p = this->rdbuf()->pubseekpos(__pos, ios_base::out);
277 
278  // 129. Need error indication from seekp() and seekg()
279  if (__p == pos_type(off_type(-1)))
280  this->setstate(ios_base::failbit);
281  }
282  return *this;
283  }
284 
285  template<typename _CharT, typename _Traits>
288  seekp(off_type __off, ios_base::seekdir __dir)
289  {
290  sentry __cerb(*this);
291  if (!this->fail())
292  {
293  // _GLIBCXX_RESOLVE_LIB_DEFECTS
294  // 136. seekp, seekg setting wrong streams?
295  const pos_type __p = this->rdbuf()->pubseekoff(__off, __dir,
296  ios_base::out);
297 
298  // 129. Need error indication from seekp() and seekg()
299  if (__p == pos_type(off_type(-1)))
300  this->setstate(ios_base::failbit);
301  }
302  return *this;
303  }
304 
305  template<typename _CharT, typename _Traits>
308  {
309  if (!__s)
310  __out.setstate(ios_base::badbit);
311  else
312  {
313  // _GLIBCXX_RESOLVE_LIB_DEFECTS
314  // 167. Improper use of traits_type::length()
315  const size_t __clen = char_traits<char>::length(__s);
316  __try
317  {
318  struct __ptr_guard
319  {
320  _CharT *__p;
321  __ptr_guard (_CharT *__ip): __p(__ip) { }
322  ~__ptr_guard() { delete[] __p; }
323  _CharT* __get() { return __p; }
324  } __pg (new _CharT[__clen]);
325 
326  _CharT *__ws = __pg.__get();
327  for (size_t __i = 0; __i < __clen; ++__i)
328  __ws[__i] = __out.widen(__s[__i]);
329  __ostream_insert(__out, __ws, __clen);
330  }
332  {
333  __out._M_setstate(ios_base::badbit);
334  __throw_exception_again;
335  }
336  __catch(...)
337  { __out._M_setstate(ios_base::badbit); }
338  }
339  return __out;
340  }
341 
342  // Inhibit implicit instantiations for required instantiations,
343  // which are defined via explicit instantiations elsewhere.
344 #if _GLIBCXX_EXTERN_TEMPLATE
345  extern template class basic_ostream<char>;
346  extern template ostream& endl(ostream&);
347  extern template ostream& ends(ostream&);
348  extern template ostream& flush(ostream&);
349  extern template ostream& operator<<(ostream&, char);
350  extern template ostream& operator<<(ostream&, unsigned char);
351  extern template ostream& operator<<(ostream&, signed char);
352  extern template ostream& operator<<(ostream&, const char*);
353  extern template ostream& operator<<(ostream&, const unsigned char*);
354  extern template ostream& operator<<(ostream&, const signed char*);
355 
356  extern template ostream& ostream::_M_insert(long);
357  extern template ostream& ostream::_M_insert(unsigned long);
358  extern template ostream& ostream::_M_insert(bool);
359 #ifdef _GLIBCXX_USE_LONG_LONG
360  extern template ostream& ostream::_M_insert(long long);
361  extern template ostream& ostream::_M_insert(unsigned long long);
362 #endif
363  extern template ostream& ostream::_M_insert(double);
364  extern template ostream& ostream::_M_insert(long double);
365  extern template ostream& ostream::_M_insert(const void*);
366 
367 #ifdef _GLIBCXX_USE_WCHAR_T
368  extern template class basic_ostream<wchar_t>;
369  extern template wostream& endl(wostream&);
370  extern template wostream& ends(wostream&);
371  extern template wostream& flush(wostream&);
372  extern template wostream& operator<<(wostream&, wchar_t);
373  extern template wostream& operator<<(wostream&, char);
374  extern template wostream& operator<<(wostream&, const wchar_t*);
375  extern template wostream& operator<<(wostream&, const char*);
376 
377  extern template wostream& wostream::_M_insert(long);
378  extern template wostream& wostream::_M_insert(unsigned long);
379  extern template wostream& wostream::_M_insert(bool);
380 #ifdef _GLIBCXX_USE_LONG_LONG
381  extern template wostream& wostream::_M_insert(long long);
382  extern template wostream& wostream::_M_insert(unsigned long long);
383 #endif
384  extern template wostream& wostream::_M_insert(double);
385  extern template wostream& wostream::_M_insert(long double);
386  extern template wostream& wostream::_M_insert(const void*);
387 #endif
388 #endif
389 
390 _GLIBCXX_END_NAMESPACE_VERSION
391 } // namespace std
392 
393 #endif
std::basic_ostream::seekp
__ostream_type & seekp(pos_type)
Changing the current write position.
Definition: ostream.tcc:269
std::ends
basic_ostream< _CharT, _Traits > & ends(basic_ostream< _CharT, _Traits > &__os)
Write a null character into the output sequence.
Definition: ostream:747
std::ios_base::out
static const openmode out
Open for output. Default for ofstream and fstream.
Definition: ios_base.h:469
__cxxabiv1::__forced_unwind
Thrown as part of forced unwinding.
Definition: cxxabi_forced.h:48
std::basic_ostream
Template class basic_ostream.
Definition: iosfwd:88
cxxabi_forced.h
std::ostream
basic_ostream< char > ostream
Base class for char output streams.
Definition: iosfwd:143
std::basic_ostream::sentry::sentry
sentry(basic_ostream< _CharT, _Traits > &__os)
The constructor performs preparatory work.
Definition: ostream.tcc:47
std::num_put
Primary class template num_put.
Definition: locale_facets.h:2318
std::ios_base::hex
static const fmtflags hex
Converts integer input or generates integer output in hexadecimal base.
Definition: ios_base.h:358
std::wostream
basic_ostream< wchar_t > wostream
Base class for wchar_t output streams.
Definition: iosfwd:183
std::streamsize
ptrdiff_t streamsize
Integral type for I/O operation counts and buffer sizes.
Definition: postypes.h:68
std::basic_ostream::tellp
pos_type tellp()
Getting the current write position.
Definition: ostream.tcc:257
std::ios_base::oct
static const fmtflags oct
Converts integer input or generates integer output in octal base.
Definition: ios_base.h:370
std::ios_base::cur
static const seekdir cur
Request a seek relative to the current position within the sequence.
Definition: ios_base.h:498
std::basic_ostream::operator<<
__ostream_type & operator<<(__ostream_type &(*__pf)(__ostream_type &))
Interface for manipulators.
Definition: ostream:110
std::ios_base::goodbit
static const iostate goodbit
Indicates all is well.
Definition: ios_base.h:436
std::ios_base::basefield
static const fmtflags basefield
A mask of dec|oct|hex. Useful for the 2-arg form of setf.
Definition: ios_base.h:404
std::endl
basic_ostream< _CharT, _Traits > & endl(basic_ostream< _CharT, _Traits > &__os)
Write a newline and flush the stream.
Definition: ostream:735
std::num_put::put
iter_type put(iter_type __s, ios_base &__io, char_type __fill, bool __v) const
Numeric formatting.
Definition: locale_facets.h:2357
std::char_traits
Basis for explicit traits specializations.
Definition: char_traits.h:341
std::basic_ostream::write
__ostream_type & write(const char_type *__s, streamsize __n)
Character string insertion.
Definition: ostream.tcc:188
std::ios_base::badbit
static const iostate badbit
Indicates a loss of integrity in an input or output sequence (such as an irrecoverable read error fro...
Definition: ios_base.h:425
std
ISO C++ entities toplevel namespace is std.
std::ios_base::failbit
static const iostate failbit
Indicates that an input operation failed to read the expected characters, or that an output operation...
Definition: ios_base.h:433
std::basic_ostream::sentry
Performs setup work for output streams.
Definition: ostream:480
std::basic_ostream::put
__ostream_type & put(char_type __c)
Simple insertion.
Definition: ostream.tcc:154
std::basic_streambuf
The actual work of input and output (interface).
Definition: iosfwd:82
std::basic_ostream::flush
__ostream_type & flush()
Synchronizing the stream buffer.
Definition: ostream.tcc:222