libstdc++
ostream.tcc
Go to the documentation of this file.
1 // ostream classes -*- C++ -*-
2 
3 // Copyright (C) 1997-2025 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 #ifdef _GLIBCXX_SYSHDR
38 #pragma GCC system_header
39 #endif
40 #pragma GCC diagnostic push
41 #pragma GCC diagnostic ignored "-Wc++11-extensions" // extern template
42 
43 #include <bits/cxxabi_forced.h>
44 
45 namespace std _GLIBCXX_VISIBILITY(default)
46 {
47 _GLIBCXX_BEGIN_NAMESPACE_VERSION
48 
49  template<typename _CharT, typename _Traits>
52  : _M_ok(false), _M_os(__os)
53  {
54  // XXX MT
55  if (__os.tie() && __os.good())
56  __os.tie()->flush();
57 
58  if (__os.good())
59  _M_ok = true;
60  else if (__os.bad())
61  __os.setstate(ios_base::failbit);
62  }
63 
64  template<typename _CharT, typename _Traits>
65  template<typename _ValueT>
68  _M_insert(_ValueT __v)
69  {
70  sentry __cerb(*this);
71  if (__cerb)
72  {
73  ios_base::iostate __err = ios_base::goodbit;
74  __try
75  {
76 #ifndef _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT
77  const __num_put_type& __np = __check_facet(this->_M_num_put);
78 #else
79  const __num_put_type& __np
80  = use_facet<__num_put_type>(this->_M_ios_locale);
81 #endif
82  if (__np.put(*this, *this, this->fill(), __v).failed())
83  __err |= ios_base::badbit;
84  }
86  {
87  this->_M_setstate(ios_base::badbit);
88  __throw_exception_again;
89  }
90  __catch(...)
91  { this->_M_setstate(ios_base::badbit); }
92  if (__err)
93  this->setstate(__err);
94  }
95  return *this;
96  }
97 
98  template<typename _CharT, typename _Traits>
101  operator<<(short __n)
102  {
103  // _GLIBCXX_RESOLVE_LIB_DEFECTS
104  // 117. basic_ostream uses nonexistent num_put member functions.
105  const ios_base::fmtflags __fmt = this->flags() & ios_base::basefield;
106  if (__fmt == ios_base::oct || __fmt == ios_base::hex)
107  return _M_insert(static_cast<long>(static_cast<unsigned short>(__n)));
108  else
109  return _M_insert(static_cast<long>(__n));
110  }
111 
112  template<typename _CharT, typename _Traits>
113  basic_ostream<_CharT, _Traits>&
115  operator<<(int __n)
116  {
117  // _GLIBCXX_RESOLVE_LIB_DEFECTS
118  // 117. basic_ostream uses nonexistent num_put member functions.
119  const ios_base::fmtflags __fmt = this->flags() & ios_base::basefield;
120  if (__fmt == ios_base::oct || __fmt == ios_base::hex)
121  return _M_insert(static_cast<long>(static_cast<unsigned int>(__n)));
122  else
123  return _M_insert(static_cast<long>(__n));
124  }
125 
126  template<typename _CharT, typename _Traits>
127  basic_ostream<_CharT, _Traits>&
129  operator<<(__streambuf_type* __sbin)
130  {
132  sentry __cerb(*this);
133  if (__cerb && __sbin)
134  {
135  __try
136  {
137  if (!__copy_streambufs(__sbin, this->rdbuf()))
138  __err |= ios_base::failbit;
139  }
141  {
142  this->_M_setstate(ios_base::badbit);
143  __throw_exception_again;
144  }
145  __catch(...)
146  { this->_M_setstate(ios_base::failbit); }
147  }
148  else if (!__sbin)
149  __err |= ios_base::badbit;
150  if (__err)
151  this->setstate(__err);
152  return *this;
153  }
154 
155  template<typename _CharT, typename _Traits>
156  basic_ostream<_CharT, _Traits>&
158  put(char_type __c)
159  {
160  // _GLIBCXX_RESOLVE_LIB_DEFECTS
161  // DR 60. What is a formatted input function?
162  // basic_ostream::put(char_type) is an unformatted output function.
163  // DR 63. Exception-handling policy for unformatted output.
164  // Unformatted output functions should catch exceptions thrown
165  // from streambuf members.
166  sentry __cerb(*this);
167  if (__cerb)
168  {
169  ios_base::iostate __err = ios_base::goodbit;
170  __try
171  {
172  const int_type __put = this->rdbuf()->sputc(__c);
173  if (traits_type::eq_int_type(__put, traits_type::eof()))
174  __err |= ios_base::badbit;
175  }
177  {
178  this->_M_setstate(ios_base::badbit);
179  __throw_exception_again;
180  }
181  __catch(...)
182  { this->_M_setstate(ios_base::badbit); }
183  if (__err)
184  this->setstate(__err);
185  }
186  return *this;
187  }
188 
189  template<typename _CharT, typename _Traits>
190  basic_ostream<_CharT, _Traits>&
192  write(const _CharT* __s, streamsize __n)
193  {
194  // _GLIBCXX_RESOLVE_LIB_DEFECTS
195  // DR 60. What is a formatted input function?
196  // basic_ostream::write(const char_type*, streamsize) is an
197  // unformatted output function.
198  // DR 63. Exception-handling policy for unformatted output.
199  // Unformatted output functions should catch exceptions thrown
200  // from streambuf members.
201  sentry __cerb(*this);
202  if (__cerb)
203  {
204  ios_base::iostate __err = ios_base::goodbit;
205  __try
206  {
207  if (this->rdbuf()->sputn(__s, __n) != __n)
208  __err = ios_base::badbit;
209  }
211  {
212  this->_M_setstate(ios_base::badbit);
213  __throw_exception_again;
214  }
215  __catch(...)
216  { this->_M_setstate(ios_base::badbit); }
217  if (__err)
218  this->setstate(ios_base::badbit);
219  }
220  return *this;
221  }
222 
223  template<typename _CharT, typename _Traits>
224  basic_ostream<_CharT, _Traits>&
226  flush()
227  {
228  // _GLIBCXX_RESOLVE_LIB_DEFECTS
229  // DR 60. What is a formatted input function?
230  // basic_ostream::flush() is *not* an unformatted output function.
231  // 581. flush() not unformatted function
232  // basic_ostream::flush() *is* an unformatted output function.
233  if (__streambuf_type* __buf = this->rdbuf())
234  {
235  sentry __cerb(*this);
236  if (__cerb)
237  {
238  ios_base::iostate __err = ios_base::goodbit;
239  __try
240  {
241  if (this->rdbuf()->pubsync() == -1)
242  __err |= ios_base::badbit;
243  }
245  {
246  this->_M_setstate(ios_base::badbit);
247  __throw_exception_again;
248  }
249  __catch(...)
250  { this->_M_setstate(ios_base::badbit); }
251  if (__err)
252  this->setstate(__err);
253  }
254  }
255  return *this;
256  }
257 
258  template<typename _CharT, typename _Traits>
259  typename basic_ostream<_CharT, _Traits>::pos_type
261  tellp()
262  {
263  sentry __cerb(*this);
264  pos_type __ret = pos_type(-1);
265  if (!this->fail())
266  __ret = this->rdbuf()->pubseekoff(0, ios_base::cur, ios_base::out);
267  return __ret;
268  }
269 
270  template<typename _CharT, typename _Traits>
273  seekp(pos_type __pos)
274  {
275  sentry __cerb(*this);
276  if (!this->fail())
277  {
278  // _GLIBCXX_RESOLVE_LIB_DEFECTS
279  // 136. seekp, seekg setting wrong streams?
280  const pos_type __p = this->rdbuf()->pubseekpos(__pos, ios_base::out);
281 
282  // 129. Need error indication from seekp() and seekg()
283  if (__p == pos_type(off_type(-1)))
285  }
286  return *this;
287  }
288 
289  template<typename _CharT, typename _Traits>
292  seekp(off_type __off, ios_base::seekdir __dir)
293  {
294  sentry __cerb(*this);
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)))
305  }
306  return *this;
307  }
308 
309  template<typename _CharT, typename _Traits>
311  operator<<(basic_ostream<_CharT, _Traits>& __out, const char* __s)
312  {
313  if (!__s)
314  __out.setstate(ios_base::badbit);
315  else
316  {
317  // _GLIBCXX_RESOLVE_LIB_DEFECTS
318  // 167. Improper use of traits_type::length()
319  const size_t __clen = char_traits<char>::length(__s);
320  __try
321  {
322  struct __ptr_guard
323  {
324  _CharT *__p;
325  __ptr_guard (_CharT *__ip): __p(__ip) { }
326  ~__ptr_guard() { delete[] __p; }
327  _CharT* __get() { return __p; }
328  } __pg (new _CharT[__clen]);
329 
330  _CharT *__ws = __pg.__get();
331  for (size_t __i = 0; __i < __clen; ++__i)
332  __ws[__i] = __out.widen(__s[__i]);
333  __ostream_insert(__out, __ws, __clen);
334  }
336  {
337  __out._M_setstate(ios_base::badbit);
338  __throw_exception_again;
339  }
340  __catch(...)
341  { __out._M_setstate(ios_base::badbit); }
342  }
343  return __out;
344  }
345 
346  // Inhibit implicit instantiations for required instantiations,
347  // which are defined via explicit instantiations elsewhere.
348 #if _GLIBCXX_EXTERN_TEMPLATE
349  extern template class basic_ostream<char>;
350  extern template ostream& endl(ostream&);
351  extern template ostream& ends(ostream&);
352  extern template ostream& flush(ostream&);
353  extern template ostream& operator<<(ostream&, char);
354  extern template ostream& operator<<(ostream&, unsigned char);
355  extern template ostream& operator<<(ostream&, signed char);
356  extern template ostream& operator<<(ostream&, const char*);
357  extern template ostream& operator<<(ostream&, const unsigned char*);
358  extern template ostream& operator<<(ostream&, const signed char*);
359 
360  extern template ostream& ostream::_M_insert(long);
361  extern template ostream& ostream::_M_insert(unsigned long);
362  extern template ostream& ostream::_M_insert(bool);
363 #ifdef _GLIBCXX_USE_LONG_LONG
364 #pragma GCC diagnostic push
365 #pragma GCC diagnostic ignored "-Wlong-long"
366  extern template ostream& ostream::_M_insert(long long);
367  extern template ostream& ostream::_M_insert(unsigned long long);
368 #pragma GCC diagnostic pop
369 #endif
370  extern template ostream& ostream::_M_insert(double);
371  extern template ostream& ostream::_M_insert(long double);
372  extern template ostream& ostream::_M_insert(const void*);
373 
374 #ifdef _GLIBCXX_USE_WCHAR_T
375  extern template class basic_ostream<wchar_t>;
376  extern template wostream& endl(wostream&);
377  extern template wostream& ends(wostream&);
378  extern template wostream& flush(wostream&);
379  extern template wostream& operator<<(wostream&, wchar_t);
380  extern template wostream& operator<<(wostream&, char);
381  extern template wostream& operator<<(wostream&, const wchar_t*);
382  extern template wostream& operator<<(wostream&, const char*);
383 
384  extern template wostream& wostream::_M_insert(long);
385  extern template wostream& wostream::_M_insert(unsigned long);
386  extern template wostream& wostream::_M_insert(bool);
387 #ifdef _GLIBCXX_USE_LONG_LONG
388 #pragma GCC diagnostic push
389 #pragma GCC diagnostic ignored "-Wlong-long"
390  extern template wostream& wostream::_M_insert(long long);
391  extern template wostream& wostream::_M_insert(unsigned long long);
392 #pragma GCC diagnostic pop
393 #endif
394  extern template wostream& wostream::_M_insert(double);
395  extern template wostream& wostream::_M_insert(long double);
396  extern template wostream& wostream::_M_insert(const void*);
397 #endif
398 #endif
399 
400 _GLIBCXX_END_NAMESPACE_VERSION
401 } // namespace std
402 
403 #pragma GCC diagnostic pop
404 #endif
basic_ostream< char > ostream
Base class for char output streams.
Definition: iosfwd:145
ISO C++ entities toplevel namespace is std.
ptrdiff_t streamsize
Integral type for I/O operation counts and buffer sizes.
Definition: postypes.h:73
basic_ostream< _CharT, _Traits > & endl(basic_ostream< _CharT, _Traits > &__os)
Write a newline and flush the stream.
Definition: ostream:66
basic_ostream< _CharT, _Traits > & ends(basic_ostream< _CharT, _Traits > &__os)
Write a null character into the output sequence.
Definition: ostream:78
_Traits::pos_type pos_type
Definition: basic_ios.h:84
basic_streambuf< _CharT, _Traits > * rdbuf() const
Accessing the underlying buffer.
Definition: basic_ios.h:337
void setstate(iostate __state)
Sets additional flags in the error state.
Definition: basic_ios.h:166
char_type widen(char __c) const
Widens characters.
Definition: basic_ios.h:464
_Traits::off_type off_type
Definition: basic_ios.h:85
bool fail() const
Fast error checking.
Definition: basic_ios.h:213
_CharT char_type
Definition: basic_ios.h:72
_Traits::int_type int_type
Definition: basic_ios.h:83
The actual work of input and output (interface).
Definition: streambuf:127
Template class basic_ostream.
Definition: ostream.h:67
__ostream_type & write(const char_type *__s, streamsize __n)
Character string insertion.
Definition: ostream.tcc:192
__ostream_type & operator<<(__ostream_type &(*__pf)(__ostream_type &))
Interface for manipulators.
Definition: ostream.h:116
pos_type tellp()
Getting the current write position.
Definition: ostream.tcc:261
__ostream_type & put(char_type __c)
Simple insertion.
Definition: ostream.tcc:158
__ostream_type & flush()
Synchronizing the stream buffer.
Definition: ostream.tcc:226
__ostream_type & seekp(pos_type)
Changing the current write position.
Definition: ostream.tcc:273
Basis for explicit traits specializations.
Definition: char_traits.h:326
Thrown as part of forced unwinding.
Definition: cxxabi_forced.h:51
_Ios_Fmtflags fmtflags
This is a bitmask type.
Definition: ios_base.h:378
_Ios_Iostate iostate
This is a bitmask type.
Definition: ios_base.h:453
static const fmtflags hex
Converts integer input or generates integer output in hexadecimal base.
Definition: ios_base.h:390
static const seekdir cur
Request a seek relative to the current position within the sequence.
Definition: ios_base.h:529
static const fmtflags basefield
A mask of dec|oct|hex. Useful for the 2-arg form of setf.
Definition: ios_base.h:436
static const openmode out
Open for output. Default for ofstream and fstream.
Definition: ios_base.h:501
fmtflags flags() const
Access to format flags.
Definition: ios_base.h:694
static const iostate goodbit
Indicates all is well.
Definition: ios_base.h:468
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:457
static const fmtflags oct
Converts integer input or generates integer output in octal base.
Definition: ios_base.h:402
static const iostate failbit
Indicates that an input operation failed to read the expected characters, or that an output operation...
Definition: ios_base.h:465
Primary class template num_put.
iter_type put(iter_type __s, ios_base &__io, char_type __fill, bool __v) const
Numeric formatting.
Performs setup work for output streams.
Definition: ostream.h:542
sentry(basic_ostream< _CharT, _Traits > &__os)
The constructor performs preparatory work.
Definition: ostream.tcc:51