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