]>
Commit | Line | Data |
---|---|---|
54c1bf78 | 1 | // Output streams -*- C++ -*- |
de96ac46 | 2 | |
7adcbafe | 3 | // Copyright (C) 1997-2022 Free Software Foundation, Inc. |
de96ac46 BK |
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 | |
748086b7 | 8 | // Free Software Foundation; either version 3, or (at your option) |
de96ac46 BK |
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 | ||
748086b7 JJ |
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. | |
de96ac46 | 19 | |
748086b7 JJ |
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/>. | |
de96ac46 | 24 | |
f910786b | 25 | /** @file include/ostream |
0aa06b18 | 26 | * This is a Standard C++ Library header. |
2f9d51b8 PE |
27 | */ |
28 | ||
143c27b0 BK |
29 | // |
30 | // ISO C++ 14882: 27.6.2 Output streams | |
31 | // | |
32 | ||
1143680e SE |
33 | #ifndef _GLIBCXX_OSTREAM |
34 | #define _GLIBCXX_OSTREAM 1 | |
54c1bf78 BK |
35 | |
36 | #pragma GCC system_header | |
37 | ||
38 | #include <ios> | |
11202768 | 39 | #include <bits/ostream_insert.h> |
54c1bf78 | 40 | |
12ffa228 BK |
41 | namespace std _GLIBCXX_VISIBILITY(default) |
42 | { | |
43 | _GLIBCXX_BEGIN_NAMESPACE_VERSION | |
3cbc7af0 | 44 | |
840ceb34 | 45 | /** |
7897a1c0 | 46 | * @brief Template class basic_ostream. |
5b9daa7e | 47 | * @ingroup io |
840ceb34 | 48 | * |
d632488a BK |
49 | * @tparam _CharT Type of character stream. |
50 | * @tparam _Traits Traits for character type, defaults to | |
51 | * char_traits<_CharT>. | |
52 | * | |
840ceb34 PE |
53 | * This is the base class for all output streams. It provides text |
54 | * formatting of all builtin types, and communicates with any class | |
55 | * derived from basic_streambuf to do the actual output. | |
56 | */ | |
54c1bf78 BK |
57 | template<typename _CharT, typename _Traits> |
58 | class basic_ostream : virtual public basic_ios<_CharT, _Traits> | |
59 | { | |
60 | public: | |
7897a1c0 BK |
61 | // Types (inherited from basic_ios): |
62 | typedef _CharT char_type; | |
54c1bf78 BK |
63 | typedef typename _Traits::int_type int_type; |
64 | typedef typename _Traits::pos_type pos_type; | |
65 | typedef typename _Traits::off_type off_type; | |
7897a1c0 BK |
66 | typedef _Traits traits_type; |
67 | ||
54c1bf78 BK |
68 | // Non-standard Types: |
69 | typedef basic_streambuf<_CharT, _Traits> __streambuf_type; | |
70 | typedef basic_ios<_CharT, _Traits> __ios_type; | |
71 | typedef basic_ostream<_CharT, _Traits> __ostream_type; | |
7897a1c0 | 72 | typedef num_put<_CharT, ostreambuf_iterator<_CharT, _Traits> > |
2803847d | 73 | __num_put_type; |
7897a1c0 | 74 | typedef ctype<_CharT> __ctype_type; |
54c1bf78 | 75 | |
840ceb34 PE |
76 | /** |
77 | * @brief Base constructor. | |
78 | * | |
79 | * This ctor is almost never called by the user directly, rather from | |
80 | * derived classes' initialization lists, which pass a pointer to | |
81 | * their own stream buffer. | |
82 | */ | |
7897a1c0 | 83 | explicit |
54c1bf78 BK |
84 | basic_ostream(__streambuf_type* __sb) |
85 | { this->init(__sb); } | |
86 | ||
840ceb34 PE |
87 | /** |
88 | * @brief Base destructor. | |
89 | * | |
90 | * This does very little apart from providing a virtual base dtor. | |
91 | */ | |
7897a1c0 | 92 | virtual |
54c1bf78 BK |
93 | ~basic_ostream() { } |
94 | ||
7897a1c0 | 95 | /// Safe prefix/suffix operations. |
54c1bf78 BK |
96 | class sentry; |
97 | friend class sentry; | |
7897a1c0 | 98 | |
f0b88346 | 99 | ///@{ |
840ceb34 PE |
100 | /** |
101 | * @brief Interface for manipulators. | |
102 | * | |
28dac70a | 103 | * Manipulators such as @c std::endl and @c std::hex use these |
840ceb34 PE |
104 | * functions in constructs like "std::cout << std::endl". For more |
105 | * information, see the iomanip header. | |
106 | */ | |
f7ab3fd1 PC |
107 | __ostream_type& |
108 | operator<<(__ostream_type& (*__pf)(__ostream_type&)) | |
109 | { | |
110 | // _GLIBCXX_RESOLVE_LIB_DEFECTS | |
111 | // DR 60. What is a formatted input function? | |
112 | // The inserters for manipulators are *not* formatted output functions. | |
113 | return __pf(*this); | |
114 | } | |
115 | ||
116 | __ostream_type& | |
117 | operator<<(__ios_type& (*__pf)(__ios_type&)) | |
118 | { | |
119 | // _GLIBCXX_RESOLVE_LIB_DEFECTS | |
120 | // DR 60. What is a formatted input function? | |
121 | // The inserters for manipulators are *not* formatted output functions. | |
122 | __pf(*this); | |
123 | return *this; | |
124 | } | |
125 | ||
126 | __ostream_type& | |
127 | operator<<(ios_base& (*__pf) (ios_base&)) | |
128 | { | |
129 | // _GLIBCXX_RESOLVE_LIB_DEFECTS | |
130 | // DR 60. What is a formatted input function? | |
131 | // The inserters for manipulators are *not* formatted output functions. | |
132 | __pf(*this); | |
133 | return *this; | |
134 | } | |
f0b88346 | 135 | ///@} |
840ceb34 | 136 | |
f0b88346 | 137 | ///@{ |
840ceb34 | 138 | /** |
7897a1c0 | 139 | * @name Inserters |
840ceb34 PE |
140 | * |
141 | * All the @c operator<< functions (aka <em>formatted output | |
142 | * functions</em>) have some common behavior. Each starts by | |
143 | * constructing a temporary object of type std::basic_ostream::sentry. | |
144 | * This can have several effects, concluding with the setting of a | |
145 | * status flag; see the sentry documentation for more. | |
146 | * | |
147 | * If the sentry status is good, the function tries to generate | |
148 | * whatever data is appropriate for the type of the argument. | |
149 | * | |
150 | * If an exception is thrown during insertion, ios_base::badbit | |
151 | * will be turned on in the stream's error state without causing an | |
152 | * ios_base::failure to be thrown. The original exception will then | |
153 | * be rethrown. | |
154 | */ | |
7897a1c0 | 155 | |
f0b88346 | 156 | ///@{ |
840ceb34 | 157 | /** |
7897a1c0 BK |
158 | * @brief Integer arithmetic inserters |
159 | * @param __n A variable of builtin integral type. | |
840ceb34 PE |
160 | * @return @c *this if successful |
161 | * | |
162 | * These functions use the stream's current locale (specifically, the | |
163 | * @c num_get facet) to perform numeric formatting. | |
164 | */ | |
7897a1c0 | 165 | __ostream_type& |
49d5c016 PC |
166 | operator<<(long __n) |
167 | { return _M_insert(__n); } | |
7897a1c0 BK |
168 | |
169 | __ostream_type& | |
49d5c016 | 170 | operator<<(unsigned long __n) |
7897a1c0 | 171 | { return _M_insert(__n); } |
54c1bf78 | 172 | |
7897a1c0 | 173 | __ostream_type& |
49d5c016 PC |
174 | operator<<(bool __n) |
175 | { return _M_insert(__n); } | |
54c1bf78 | 176 | |
7897a1c0 | 177 | __ostream_type& |
e7968bd8 | 178 | operator<<(short __n); |
54c1bf78 | 179 | |
7897a1c0 | 180 | __ostream_type& |
49d5c016 PC |
181 | operator<<(unsigned short __n) |
182 | { | |
183 | // _GLIBCXX_RESOLVE_LIB_DEFECTS | |
184 | // 117. basic_ostream uses nonexistent num_put member functions. | |
185 | return _M_insert(static_cast<unsigned long>(__n)); | |
186 | } | |
54c1bf78 | 187 | |
7897a1c0 | 188 | __ostream_type& |
e7968bd8 | 189 | operator<<(int __n); |
54c1bf78 | 190 | |
7897a1c0 | 191 | __ostream_type& |
49d5c016 PC |
192 | operator<<(unsigned int __n) |
193 | { | |
194 | // _GLIBCXX_RESOLVE_LIB_DEFECTS | |
195 | // 117. basic_ostream uses nonexistent num_put member functions. | |
196 | return _M_insert(static_cast<unsigned long>(__n)); | |
197 | } | |
54c1bf78 | 198 | |
3d7c150e | 199 | #ifdef _GLIBCXX_USE_LONG_LONG |
7897a1c0 | 200 | __ostream_type& |
49d5c016 PC |
201 | operator<<(long long __n) |
202 | { return _M_insert(__n); } | |
54c1bf78 | 203 | |
7897a1c0 | 204 | __ostream_type& |
49d5c016 | 205 | operator<<(unsigned long long __n) |
7897a1c0 | 206 | { return _M_insert(__n); } |
54c1bf78 | 207 | #endif |
f0b88346 | 208 | ///@} |
54c1bf78 | 209 | |
f0b88346 | 210 | ///@{ |
7897a1c0 BK |
211 | /** |
212 | * @brief Floating point arithmetic inserters | |
213 | * @param __f A variable of builtin floating point type. | |
214 | * @return @c *this if successful | |
215 | * | |
216 | * These functions use the stream's current locale (specifically, the | |
217 | * @c num_get facet) to perform numeric formatting. | |
218 | */ | |
219 | __ostream_type& | |
49d5c016 PC |
220 | operator<<(double __f) |
221 | { return _M_insert(__f); } | |
54c1bf78 | 222 | |
7897a1c0 | 223 | __ostream_type& |
49d5c016 PC |
224 | operator<<(float __f) |
225 | { | |
226 | // _GLIBCXX_RESOLVE_LIB_DEFECTS | |
227 | // 117. basic_ostream uses nonexistent num_put member functions. | |
228 | return _M_insert(static_cast<double>(__f)); | |
229 | } | |
54c1bf78 | 230 | |
7897a1c0 | 231 | __ostream_type& |
49d5c016 PC |
232 | operator<<(long double __f) |
233 | { return _M_insert(__f); } | |
f0b88346 | 234 | ///@} |
54c1bf78 | 235 | |
7897a1c0 BK |
236 | /** |
237 | * @brief Pointer arithmetic inserters | |
238 | * @param __p A variable of pointer type. | |
239 | * @return @c *this if successful | |
240 | * | |
241 | * These functions use the stream's current locale (specifically, the | |
242 | * @c num_get facet) to perform numeric formatting. | |
243 | */ | |
244 | __ostream_type& | |
49d5c016 PC |
245 | operator<<(const void* __p) |
246 | { return _M_insert(__p); } | |
54c1bf78 | 247 | |
c3799b16 VV |
248 | #if __cplusplus >= 201703L |
249 | __ostream_type& | |
250 | operator<<(nullptr_t) | |
251 | { return *this << "nullptr"; } | |
252 | #endif | |
253 | ||
96955a82 JW |
254 | #if __cplusplus > 202002L |
255 | __attribute__((__always_inline__)) | |
256 | __ostream_type& | |
257 | operator<<(const volatile void* __p) | |
258 | { return _M_insert(const_cast<const void*>(__p)); } | |
259 | #endif | |
260 | ||
840ceb34 PE |
261 | /** |
262 | * @brief Extracting from another streambuf. | |
93c66bc6 | 263 | * @param __sb A pointer to a streambuf |
840ceb34 PE |
264 | * |
265 | * This function behaves like one of the basic arithmetic extractors, | |
0f35d192 | 266 | * in that it also constructs a sentry object and has the same error |
840ceb34 PE |
267 | * handling behavior. |
268 | * | |
7897a1c0 | 269 | * If @p __sb is NULL, the stream will set failbit in its error state. |
840ceb34 | 270 | * |
7897a1c0 | 271 | * Characters are extracted from @p __sb and inserted into @c *this |
840ceb34 PE |
272 | * until one of the following occurs: |
273 | * | |
274 | * - the input stream reaches end-of-file, | |
275 | * - insertion into the output sequence fails (in this case, the | |
276 | * character that would have been inserted is not extracted), or | |
7897a1c0 | 277 | * - an exception occurs while getting a character from @p __sb, which |
840ceb34 PE |
278 | * sets failbit in the error state |
279 | * | |
280 | * If the function inserts no characters, failbit is set. | |
281 | */ | |
7897a1c0 | 282 | __ostream_type& |
54c1bf78 | 283 | operator<<(__streambuf_type* __sb); |
f0b88346 | 284 | ///@} |
840ceb34 | 285 | |
f0b88346 | 286 | ///@{ |
840ceb34 PE |
287 | /** |
288 | * @name Unformatted Output Functions | |
289 | * | |
290 | * All the unformatted output functions have some common behavior. | |
291 | * Each starts by constructing a temporary object of type | |
292 | * std::basic_ostream::sentry. This has several effects, concluding | |
293 | * with the setting of a status flag; see the sentry documentation | |
294 | * for more. | |
295 | * | |
296 | * If the sentry status is good, the function tries to generate | |
297 | * whatever data is appropriate for the type of the argument. | |
298 | * | |
299 | * If an exception is thrown during insertion, ios_base::badbit | |
300 | * will be turned on in the stream's error state. If badbit is on in | |
301 | * the stream's exceptions mask, the exception will be rethrown | |
302 | * without completing its actions. | |
303 | */ | |
7897a1c0 | 304 | |
840ceb34 PE |
305 | /** |
306 | * @brief Simple insertion. | |
93c66bc6 | 307 | * @param __c The character to insert. |
840ceb34 PE |
308 | * @return *this |
309 | * | |
7897a1c0 | 310 | * Tries to insert @p __c. |
840ceb34 PE |
311 | * |
312 | * @note This function is not overloaded on signed char and | |
313 | * unsigned char. | |
314 | */ | |
7897a1c0 | 315 | __ostream_type& |
54c1bf78 BK |
316 | put(char_type __c); |
317 | ||
840ceb34 PE |
318 | /** |
319 | * @brief Character string insertion. | |
93c66bc6 BK |
320 | * @param __s The array to insert. |
321 | * @param __n Maximum number of characters to insert. | |
840ceb34 PE |
322 | * @return *this |
323 | * | |
7897a1c0 | 324 | * Characters are copied from @p __s and inserted into the stream until |
840ceb34 PE |
325 | * one of the following happens: |
326 | * | |
7897a1c0 | 327 | * - @p __n characters are inserted |
840ceb34 PE |
328 | * - inserting into the output sequence fails (in this case, badbit |
329 | * will be set in the stream's error state) | |
330 | * | |
331 | * @note This function is not overloaded on signed char and | |
332 | * unsigned char. | |
333 | */ | |
7897a1c0 | 334 | __ostream_type& |
54c1bf78 | 335 | write(const char_type* __s, streamsize __n); |
f0b88346 | 336 | ///@} |
840ceb34 PE |
337 | |
338 | /** | |
339 | * @brief Synchronizing the stream buffer. | |
340 | * @return *this | |
341 | * | |
342 | * If @c rdbuf() is a null pointer, changes nothing. | |
343 | * | |
344 | * Otherwise, calls @c rdbuf()->pubsync(), and if that returns -1, | |
345 | * sets badbit. | |
346 | */ | |
7897a1c0 | 347 | __ostream_type& |
54c1bf78 BK |
348 | flush(); |
349 | ||
840ceb34 PE |
350 | /** |
351 | * @brief Getting the current write position. | |
352 | * @return A file position object. | |
353 | * | |
354 | * If @c fail() is not false, returns @c pos_type(-1) to indicate | |
355 | * failure. Otherwise returns @c rdbuf()->pubseekoff(0,cur,out). | |
356 | */ | |
7897a1c0 | 357 | pos_type |
54c1bf78 BK |
358 | tellp(); |
359 | ||
840ceb34 PE |
360 | /** |
361 | * @brief Changing the current write position. | |
93c66bc6 | 362 | * @param __pos A file position object. |
840ceb34 PE |
363 | * @return *this |
364 | * | |
365 | * If @c fail() is not true, calls @c rdbuf()->pubseekpos(pos). If | |
366 | * that function fails, sets failbit. | |
367 | */ | |
7897a1c0 | 368 | __ostream_type& |
54c1bf78 BK |
369 | seekp(pos_type); |
370 | ||
840ceb34 PE |
371 | /** |
372 | * @brief Changing the current write position. | |
93c66bc6 BK |
373 | * @param __off A file offset object. |
374 | * @param __dir The direction in which to seek. | |
840ceb34 PE |
375 | * @return *this |
376 | * | |
377 | * If @c fail() is not true, calls @c rdbuf()->pubseekoff(off,dir). | |
378 | * If that function fails, sets failbit. | |
379 | */ | |
7897a1c0 | 380 | __ostream_type& |
54c1bf78 | 381 | seekp(off_type, ios_base::seekdir); |
7897a1c0 | 382 | |
d29cc32f | 383 | protected: |
b3aaa617 PC |
384 | basic_ostream() |
385 | { this->init(0); } | |
49d5c016 | 386 | |
9b817548 JW |
387 | #if __cplusplus >= 201103L |
388 | // Non-standard constructor that does not call init() | |
48e968a7 | 389 | basic_ostream(basic_iostream<_CharT, _Traits>&) { } |
9b817548 JW |
390 | |
391 | basic_ostream(const basic_ostream&) = delete; | |
392 | ||
393 | basic_ostream(basic_ostream&& __rhs) | |
394 | : __ios_type() | |
395 | { __ios_type::move(__rhs); } | |
396 | ||
397 | // 27.7.3.3 Assign/swap | |
398 | ||
399 | basic_ostream& operator=(const basic_ostream&) = delete; | |
400 | ||
401 | basic_ostream& | |
402 | operator=(basic_ostream&& __rhs) | |
403 | { | |
404 | swap(__rhs); | |
405 | return *this; | |
406 | } | |
407 | ||
408 | void | |
409 | swap(basic_ostream& __rhs) | |
410 | { __ios_type::swap(__rhs); } | |
411 | #endif | |
412 | ||
49d5c016 | 413 | template<typename _ValueT> |
7897a1c0 BK |
414 | __ostream_type& |
415 | _M_insert(_ValueT __v); | |
4a52cf2e JW |
416 | |
417 | private: | |
418 | #if !_GLIBCXX_INLINE_VERSION | |
419 | void | |
420 | _M_write(const char_type* __s, streamsize __n) | |
421 | { std::__ostream_insert(*this, __s, __n); } | |
422 | #endif | |
54c1bf78 BK |
423 | }; |
424 | ||
840ceb34 PE |
425 | /** |
426 | * @brief Performs setup work for output streams. | |
427 | * | |
428 | * Objects of this class are created before all of the standard | |
2a60a9f6 BK |
429 | * inserters are run. It is responsible for <em>exception-safe prefix and |
430 | * suffix operations</em>. | |
840ceb34 | 431 | */ |
54c1bf78 BK |
432 | template <typename _CharT, typename _Traits> |
433 | class basic_ostream<_CharT, _Traits>::sentry | |
434 | { | |
d29d4507 | 435 | // Data Members. |
54c1bf78 | 436 | bool _M_ok; |
f7ab3fd1 | 437 | basic_ostream<_CharT, _Traits>& _M_os; |
7897a1c0 | 438 | |
54c1bf78 | 439 | public: |
840ceb34 PE |
440 | /** |
441 | * @brief The constructor performs preparatory work. | |
93c66bc6 | 442 | * @param __os The output stream to guard. |
840ceb34 | 443 | * |
93c66bc6 | 444 | * If the stream state is good (@a __os.good() is true), then if the |
840ceb34 PE |
445 | * stream is tied to another output stream, @c is.tie()->flush() |
446 | * is called to synchronize the output sequences. | |
447 | * | |
448 | * If the stream state is still good, then the sentry state becomes | |
2a60a9f6 | 449 | * true (@a okay). |
840ceb34 | 450 | */ |
54c1bf78 | 451 | explicit |
f7ab3fd1 | 452 | sentry(basic_ostream<_CharT, _Traits>& __os); |
54c1bf78 | 453 | |
450f33d6 JW |
454 | #pragma GCC diagnostic push |
455 | #pragma GCC diagnostic ignored "-Wdeprecated-declarations" | |
840ceb34 PE |
456 | /** |
457 | * @brief Possibly flushes the stream. | |
458 | * | |
459 | * If @c ios_base::unitbuf is set in @c os.flags(), and | |
460 | * @c std::uncaught_exception() is true, the sentry destructor calls | |
461 | * @c flush() on the output stream. | |
462 | */ | |
54c1bf78 BK |
463 | ~sentry() |
464 | { | |
465 | // XXX MT | |
7f786096 | 466 | if (bool(_M_os.flags() & ios_base::unitbuf) && !uncaught_exception()) |
54c1bf78 BK |
467 | { |
468 | // Can't call flush directly or else will get into recursive lock. | |
469 | if (_M_os.rdbuf() && _M_os.rdbuf()->pubsync() == -1) | |
470 | _M_os.setstate(ios_base::badbit); | |
471 | } | |
472 | } | |
450f33d6 | 473 | #pragma GCC diagnostic pop |
54c1bf78 | 474 | |
840ceb34 PE |
475 | /** |
476 | * @brief Quick status checking. | |
477 | * @return The sentry state. | |
478 | * | |
479 | * For ease of use, sentries may be converted to booleans. The | |
480 | * return value is that of the sentry state (true == okay). | |
481 | */ | |
734f5023 | 482 | #if __cplusplus >= 201103L |
d29d4507 BK |
483 | explicit |
484 | #endif | |
afb6c265 | 485 | operator bool() const |
54c1bf78 BK |
486 | { return _M_ok; } |
487 | }; | |
488 | ||
f0b88346 | 489 | ///@{ |
840ceb34 PE |
490 | /** |
491 | * @brief Character inserters | |
93c66bc6 BK |
492 | * @param __out An output stream. |
493 | * @param __c A character. | |
840ceb34 PE |
494 | * @return out |
495 | * | |
496 | * Behaves like one of the formatted arithmetic inserters described in | |
497 | * std::basic_ostream. After constructing a sentry object with good | |
498 | * status, this function inserts a single character and any required | |
93c66bc6 | 499 | * padding (as determined by [22.2.2.2.2]). @c __out.width(0) is then |
840ceb34 PE |
500 | * called. |
501 | * | |
7897a1c0 | 502 | * If @p __c is of type @c char and the character type of the stream is not |
840ceb34 PE |
503 | * @c char, the character is widened before insertion. |
504 | */ | |
54c1bf78 | 505 | template<typename _CharT, typename _Traits> |
f7ab3fd1 | 506 | inline basic_ostream<_CharT, _Traits>& |
ec2061a9 | 507 | operator<<(basic_ostream<_CharT, _Traits>& __out, _CharT __c) |
11202768 | 508 | { return __ostream_insert(__out, &__c, 1); } |
54c1bf78 BK |
509 | |
510 | template<typename _CharT, typename _Traits> | |
f7ab3fd1 | 511 | inline basic_ostream<_CharT, _Traits>& |
54c1bf78 BK |
512 | operator<<(basic_ostream<_CharT, _Traits>& __out, char __c) |
513 | { return (__out << __out.widen(__c)); } | |
514 | ||
515 | // Specialization | |
24cc0de9 | 516 | template<typename _Traits> |
f7ab3fd1 | 517 | inline basic_ostream<char, _Traits>& |
ec2061a9 | 518 | operator<<(basic_ostream<char, _Traits>& __out, char __c) |
11202768 | 519 | { return __ostream_insert(__out, &__c, 1); } |
54c1bf78 BK |
520 | |
521 | // Signed and unsigned | |
24cc0de9 | 522 | template<typename _Traits> |
f7ab3fd1 | 523 | inline basic_ostream<char, _Traits>& |
54c1bf78 BK |
524 | operator<<(basic_ostream<char, _Traits>& __out, signed char __c) |
525 | { return (__out << static_cast<char>(__c)); } | |
7897a1c0 | 526 | |
24cc0de9 | 527 | template<typename _Traits> |
f7ab3fd1 | 528 | inline basic_ostream<char, _Traits>& |
54c1bf78 BK |
529 | operator<<(basic_ostream<char, _Traits>& __out, unsigned char __c) |
530 | { return (__out << static_cast<char>(__c)); } | |
2b4e2c93 TH |
531 | |
532 | #if __cplusplus > 201703L | |
533 | // The following deleted overloads prevent formatting character values as | |
534 | // numeric values. | |
535 | ||
24cc0de9 | 536 | template<typename _Traits> |
2b4e2c93 TH |
537 | basic_ostream<char, _Traits>& |
538 | operator<<(basic_ostream<char, _Traits>&, wchar_t) = delete; | |
2b4e2c93 TH |
539 | |
540 | #ifdef _GLIBCXX_USE_CHAR8_T | |
24cc0de9 | 541 | template<typename _Traits> |
2b4e2c93 TH |
542 | basic_ostream<char, _Traits>& |
543 | operator<<(basic_ostream<char, _Traits>&, char8_t) = delete; | |
544 | #endif | |
545 | ||
24cc0de9 | 546 | template<typename _Traits> |
2b4e2c93 TH |
547 | basic_ostream<char, _Traits>& |
548 | operator<<(basic_ostream<char, _Traits>&, char16_t) = delete; | |
549 | ||
24cc0de9 | 550 | template<typename _Traits> |
2b4e2c93 TH |
551 | basic_ostream<char, _Traits>& |
552 | operator<<(basic_ostream<char, _Traits>&, char32_t) = delete; | |
553 | ||
554 | #ifdef _GLIBCXX_USE_WCHAR_T | |
555 | #ifdef _GLIBCXX_USE_CHAR8_T | |
24cc0de9 | 556 | template<typename _Traits> |
2b4e2c93 TH |
557 | basic_ostream<wchar_t, _Traits>& |
558 | operator<<(basic_ostream<wchar_t, _Traits>&, char8_t) = delete; | |
559 | #endif // _GLIBCXX_USE_CHAR8_T | |
560 | ||
24cc0de9 | 561 | template<typename _Traits> |
2b4e2c93 TH |
562 | basic_ostream<wchar_t, _Traits>& |
563 | operator<<(basic_ostream<wchar_t, _Traits>&, char16_t) = delete; | |
564 | ||
24cc0de9 | 565 | template<typename _Traits> |
2b4e2c93 TH |
566 | basic_ostream<wchar_t, _Traits>& |
567 | operator<<(basic_ostream<wchar_t, _Traits>&, char32_t) = delete; | |
568 | #endif // _GLIBCXX_USE_WCHAR_T | |
569 | #endif // C++20 | |
f0b88346 | 570 | ///@} |
7897a1c0 | 571 | |
f0b88346 | 572 | ///@{ |
840ceb34 PE |
573 | /** |
574 | * @brief String inserters | |
93c66bc6 BK |
575 | * @param __out An output stream. |
576 | * @param __s A character string. | |
840ceb34 | 577 | * @return out |
7897a1c0 | 578 | * @pre @p __s must be a non-NULL pointer |
840ceb34 PE |
579 | * |
580 | * Behaves like one of the formatted arithmetic inserters described in | |
581 | * std::basic_ostream. After constructing a sentry object with good | |
93c66bc6 | 582 | * status, this function inserts @c traits::length(__s) characters starting |
7897a1c0 | 583 | * at @p __s, widened if necessary, followed by any required padding (as |
93c66bc6 | 584 | * determined by [22.2.2.2.2]). @c __out.width(0) is then called. |
840ceb34 | 585 | */ |
54c1bf78 | 586 | template<typename _CharT, typename _Traits> |
f7ab3fd1 | 587 | inline basic_ostream<_CharT, _Traits>& |
ec2061a9 PC |
588 | operator<<(basic_ostream<_CharT, _Traits>& __out, const _CharT* __s) |
589 | { | |
590 | if (!__s) | |
591 | __out.setstate(ios_base::badbit); | |
592 | else | |
11202768 PC |
593 | __ostream_insert(__out, __s, |
594 | static_cast<streamsize>(_Traits::length(__s))); | |
ec2061a9 PC |
595 | return __out; |
596 | } | |
54c1bf78 BK |
597 | |
598 | template<typename _CharT, typename _Traits> | |
599 | basic_ostream<_CharT, _Traits> & | |
600 | operator<<(basic_ostream<_CharT, _Traits>& __out, const char* __s); | |
601 | ||
28dac70a | 602 | // Partial specializations |
24cc0de9 | 603 | template<typename _Traits> |
f7ab3fd1 | 604 | inline basic_ostream<char, _Traits>& |
ec2061a9 PC |
605 | operator<<(basic_ostream<char, _Traits>& __out, const char* __s) |
606 | { | |
607 | if (!__s) | |
608 | __out.setstate(ios_base::badbit); | |
609 | else | |
11202768 PC |
610 | __ostream_insert(__out, __s, |
611 | static_cast<streamsize>(_Traits::length(__s))); | |
ec2061a9 PC |
612 | return __out; |
613 | } | |
614 | ||
54c1bf78 | 615 | // Signed and unsigned |
24cc0de9 | 616 | template<typename _Traits> |
f7ab3fd1 | 617 | inline basic_ostream<char, _Traits>& |
54c1bf78 BK |
618 | operator<<(basic_ostream<char, _Traits>& __out, const signed char* __s) |
619 | { return (__out << reinterpret_cast<const char*>(__s)); } | |
620 | ||
24cc0de9 | 621 | template<typename _Traits> |
f7ab3fd1 | 622 | inline basic_ostream<char, _Traits> & |
54c1bf78 BK |
623 | operator<<(basic_ostream<char, _Traits>& __out, const unsigned char* __s) |
624 | { return (__out << reinterpret_cast<const char*>(__s)); } | |
2b4e2c93 TH |
625 | |
626 | #if __cplusplus > 201703L | |
627 | // The following deleted overloads prevent formatting strings as | |
628 | // pointer values. | |
629 | ||
24cc0de9 | 630 | template<typename _Traits> |
2b4e2c93 TH |
631 | basic_ostream<char, _Traits>& |
632 | operator<<(basic_ostream<char, _Traits>&, const wchar_t*) = delete; | |
2b4e2c93 TH |
633 | |
634 | #ifdef _GLIBCXX_USE_CHAR8_T | |
24cc0de9 | 635 | template<typename _Traits> |
2b4e2c93 TH |
636 | basic_ostream<char, _Traits>& |
637 | operator<<(basic_ostream<char, _Traits>&, const char8_t*) = delete; | |
638 | #endif // _GLIBCXX_USE_CHAR8_T | |
639 | ||
24cc0de9 | 640 | template<typename _Traits> |
2b4e2c93 TH |
641 | basic_ostream<char, _Traits>& |
642 | operator<<(basic_ostream<char, _Traits>&, const char16_t*) = delete; | |
643 | ||
24cc0de9 | 644 | template<typename _Traits> |
2b4e2c93 TH |
645 | basic_ostream<char, _Traits>& |
646 | operator<<(basic_ostream<char, _Traits>&, const char32_t*) = delete; | |
647 | ||
648 | #ifdef _GLIBCXX_USE_WCHAR_T | |
649 | #ifdef _GLIBCXX_USE_CHAR8_T | |
24cc0de9 | 650 | template<typename _Traits> |
2b4e2c93 TH |
651 | basic_ostream<wchar_t, _Traits>& |
652 | operator<<(basic_ostream<wchar_t, _Traits>&, const char8_t*) = delete; | |
653 | #endif | |
654 | ||
24cc0de9 | 655 | template<typename _Traits> |
2b4e2c93 TH |
656 | basic_ostream<wchar_t, _Traits>& |
657 | operator<<(basic_ostream<wchar_t, _Traits>&, const char16_t*) = delete; | |
658 | ||
24cc0de9 | 659 | template<typename _Traits> |
2b4e2c93 TH |
660 | basic_ostream<wchar_t, _Traits>& |
661 | operator<<(basic_ostream<wchar_t, _Traits>&, const char32_t*) = delete; | |
662 | #endif // _GLIBCXX_USE_WCHAR_T | |
663 | #endif // C++20 | |
f0b88346 | 664 | ///@} |
840ceb34 | 665 | |
7897a1c0 BK |
666 | // Standard basic_ostream manipulators |
667 | ||
840ceb34 PE |
668 | /** |
669 | * @brief Write a newline and flush the stream. | |
670 | * | |
671 | * This manipulator is often mistakenly used when a simple newline is | |
672 | * desired, leading to poor buffering performance. See | |
10d43d2f | 673 | * https://gcc.gnu.org/onlinedocs/libstdc++/manual/streambufs.html#io.streambuf.buffering |
21a15d9f | 674 | * for more on this subject. |
840ceb34 | 675 | */ |
54c1bf78 | 676 | template<typename _CharT, typename _Traits> |
7897a1c0 | 677 | inline basic_ostream<_CharT, _Traits>& |
54c1bf78 BK |
678 | endl(basic_ostream<_CharT, _Traits>& __os) |
679 | { return flush(__os.put(__os.widen('\n'))); } | |
680 | ||
840ceb34 PE |
681 | /** |
682 | * @brief Write a null character into the output sequence. | |
683 | * | |
7897a1c0 BK |
684 | * <em>Null character</em> is @c CharT() by definition. For CharT |
685 | * of @c char, this correctly writes the ASCII @c NUL character | |
686 | * string terminator. | |
840ceb34 | 687 | */ |
54c1bf78 | 688 | template<typename _CharT, typename _Traits> |
7897a1c0 | 689 | inline basic_ostream<_CharT, _Traits>& |
54c1bf78 BK |
690 | ends(basic_ostream<_CharT, _Traits>& __os) |
691 | { return __os.put(_CharT()); } | |
7897a1c0 | 692 | |
840ceb34 PE |
693 | /** |
694 | * @brief Flushes the output stream. | |
695 | * | |
696 | * This manipulator simply calls the stream's @c flush() member function. | |
697 | */ | |
54c1bf78 | 698 | template<typename _CharT, typename _Traits> |
7897a1c0 | 699 | inline basic_ostream<_CharT, _Traits>& |
54c1bf78 BK |
700 | flush(basic_ostream<_CharT, _Traits>& __os) |
701 | { return __os.flush(); } | |
702 | ||
734f5023 | 703 | #if __cplusplus >= 201103L |
aa475c4a JW |
704 | // C++11 27.7.3.9 Rvalue stream insertion [ostream.rvalue] |
705 | // _GLIBCXX_RESOLVE_LIB_DEFECTS | |
706 | // 1203. More useful rvalue stream insertion | |
707 | ||
aa475c4a | 708 | #if __cpp_lib_concepts |
a87ceadf | 709 | // Use concepts if possible because they're cheaper to evaluate. |
5e88d2d0 | 710 | template<typename _Tp> |
a87ceadf JW |
711 | concept __derived_from_ios_base = is_class_v<_Tp> |
712 | && (!is_same_v<_Tp, ios_base>) | |
713 | && requires (_Tp* __t, ios_base* __b) { __b = __t; }; | |
714 | ||
715 | template<typename _Os, typename _Tp> | |
716 | requires __derived_from_ios_base<_Os> | |
717 | && requires (_Os& __os, const _Tp& __t) { __os << __t; } | |
718 | using __rvalue_stream_insertion_t = _Os&&; | |
aa475c4a | 719 | #else |
a87ceadf JW |
720 | template<typename _Tp> |
721 | using _Require_derived_from_ios_base | |
722 | = _Require<is_class<_Tp>, __not_<is_same<_Tp, ios_base>>, | |
723 | is_convertible<typename add_pointer<_Tp>::type, ios_base*>>; | |
a7da4881 | 724 | |
aa475c4a | 725 | template<typename _Os, typename _Tp, |
a87ceadf JW |
726 | typename = _Require_derived_from_ios_base<_Os>, |
727 | typename | |
728 | = decltype(std::declval<_Os&>() << std::declval<const _Tp&>())> | |
aa475c4a | 729 | using __rvalue_stream_insertion_t = _Os&&; |
a87ceadf | 730 | #endif |
5e88d2d0 | 731 | |
e7f1930f JM |
732 | /** |
733 | * @brief Generic inserter for rvalue stream | |
93c66bc6 BK |
734 | * @param __os An input stream. |
735 | * @param __x A reference to the object being inserted. | |
aa475c4a | 736 | * @return __os |
e7f1930f JM |
737 | * |
738 | * This is just a forwarding function to allow insertion to | |
739 | * rvalue streams since they won't bind to the inserter functions | |
740 | * that take an lvalue reference. | |
741 | */ | |
a7da4881 | 742 | template<typename _Ostream, typename _Tp> |
aa475c4a | 743 | inline __rvalue_stream_insertion_t<_Ostream, _Tp> |
a7da4881 | 744 | operator<<(_Ostream&& __os, const _Tp& __x) |
ea348bbe | 745 | { |
aa475c4a JW |
746 | __os << __x; |
747 | return std::move(__os); | |
ea348bbe | 748 | } |
ecba8547 JW |
749 | |
750 | #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI | |
751 | template<typename _CharT, typename _Traits> | |
752 | class __syncbuf_base : public basic_streambuf<_CharT, _Traits> | |
753 | { | |
754 | public: | |
755 | static bool* | |
14b554c4 | 756 | _S_get(basic_streambuf<_CharT, _Traits>* __buf [[maybe_unused]]) noexcept |
ecba8547 | 757 | { |
14b554c4 | 758 | #if __cpp_rtti |
ecba8547 JW |
759 | if (auto __p = dynamic_cast<__syncbuf_base*>(__buf)) |
760 | return &__p->_M_emit_on_sync; | |
14b554c4 | 761 | #endif |
ecba8547 JW |
762 | return nullptr; |
763 | } | |
764 | ||
765 | protected: | |
766 | __syncbuf_base(basic_streambuf<_CharT, _Traits>* __w = nullptr) | |
767 | : _M_wrapped(__w) | |
768 | { } | |
769 | ||
770 | basic_streambuf<_CharT, _Traits>* _M_wrapped = nullptr; | |
771 | bool _M_emit_on_sync = false; | |
772 | bool _M_needs_sync = false; | |
773 | }; | |
774 | ||
775 | template<typename _CharT, typename _Traits> | |
776 | inline basic_ostream<_CharT, _Traits>& | |
777 | emit_on_flush(basic_ostream<_CharT, _Traits>& __os) | |
778 | { | |
779 | if (bool* __flag = __syncbuf_base<_CharT, _Traits>::_S_get(__os.rdbuf())) | |
780 | *__flag = true; | |
781 | return __os; | |
782 | } | |
783 | ||
784 | template<typename _CharT, typename _Traits> | |
785 | inline basic_ostream<_CharT, _Traits>& | |
786 | noemit_on_flush(basic_ostream<_CharT, _Traits>& __os) | |
787 | { | |
788 | if (bool* __flag = __syncbuf_base<_CharT, _Traits>::_S_get(__os.rdbuf())) | |
789 | *__flag = false; | |
790 | return __os; | |
791 | } | |
792 | ||
793 | template<typename _CharT, typename _Traits> | |
794 | inline basic_ostream<_CharT, _Traits>& | |
795 | flush_emit(basic_ostream<_CharT, _Traits>& __os) | |
796 | { | |
797 | struct _Restore | |
798 | { | |
799 | ~_Restore() { *_M_flag = _M_prev; } | |
800 | ||
801 | bool _M_prev = false; | |
802 | bool* _M_flag = &_M_prev; | |
803 | } __restore; | |
804 | ||
805 | if (bool* __flag = __syncbuf_base<_CharT, _Traits>::_S_get(__os.rdbuf())) | |
806 | { | |
807 | __restore._M_prev = *__flag; | |
808 | __restore._M_flag = __flag; | |
809 | *__flag = true; | |
810 | } | |
811 | ||
812 | __os.flush(); | |
813 | return __os; | |
814 | } | |
815 | ||
816 | #endif // C++20 | |
817 | ||
734f5023 | 818 | #endif // C++11 |
e7f1930f | 819 | |
12ffa228 | 820 | _GLIBCXX_END_NAMESPACE_VERSION |
7897a1c0 | 821 | } // namespace std |
54c1bf78 | 822 | |
ee3ee948 | 823 | #include <bits/ostream.tcc> |
54c1bf78 | 824 | |
1143680e | 825 | #endif /* _GLIBCXX_OSTREAM */ |