1// Output streams -*- C++ -*- 2 3// Copyright (C) 1997-2022 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 41namespace 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#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 261 /** 262 * @brief Extracting from another streambuf. 263 * @param __sb A pointer to a streambuf 264 * 265 * This function behaves like one of the basic arithmetic extractors, 266 * in that it also constructs a sentry object and has the same error 267 * handling behavior. 268 * 269 * If @p __sb is NULL, the stream will set failbit in its error state. 270 * 271 * Characters are extracted from @p __sb and inserted into @c *this 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 277 * - an exception occurs while getting a character from @p __sb, which 278 * sets failbit in the error state 279 * 280 * If the function inserts no characters, failbit is set. 281 */ 282 __ostream_type& 283 operator<<(__streambuf_type* __sb); 284 ///@} 285 286 ///@{ 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 */ 304 305 /** 306 * @brief Simple insertion. 307 * @param __c The character to insert. 308 * @return *this 309 * 310 * Tries to insert @p __c. 311 * 312 * @note This function is not overloaded on signed char and 313 * unsigned char. 314 */ 315 __ostream_type& 316 put(char_type __c); 317 318 /** 319 * @brief Character string insertion. 320 * @param __s The array to insert. 321 * @param __n Maximum number of characters to insert. 322 * @return *this 323 * 324 * Characters are copied from @p __s and inserted into the stream until 325 * one of the following happens: 326 * 327 * - @p __n characters are inserted 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 */ 334 __ostream_type& 335 write(const char_type* __s, streamsize __n); 336 ///@} 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 */ 347 __ostream_type& 348 flush(); 349 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 */ 357 pos_type 358 tellp(); 359 360 /** 361 * @brief Changing the current write position. 362 * @param __pos A file position object. 363 * @return *this 364 * 365 * If @c fail() is not true, calls @c rdbuf()->pubseekpos(pos). If 366 * that function fails, sets failbit. 367 */ 368 __ostream_type& 369 seekp(pos_type); 370 371 /** 372 * @brief Changing the current write position. 373 * @param __off A file offset object. 374 * @param __dir The direction in which to seek. 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 */ 380 __ostream_type& 381 seekp(off_type, ios_base::seekdir); 382 383 protected: 384 basic_ostream() 385 { this->init(0); } 386 387#if __cplusplus >= 201103L 388 // Non-standard constructor that does not call init() 389 basic_ostream(basic_iostream<_CharT, _Traits>&) { } 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 413 template<typename _ValueT> 414 __ostream_type& 415 _M_insert(_ValueT __v); 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 423 }; 424 425 /** 426 * @brief Performs setup work for output streams. 427 * 428 * Objects of this class are created before all of the standard 429 * inserters are run. It is responsible for <em>exception-safe prefix and 430 * suffix operations</em>. 431 */ 432 template <typename _CharT, typename _Traits> 433 class basic_ostream<_CharT, _Traits>::sentry 434 { 435 // Data Members. 436 bool _M_ok; 437 basic_ostream<_CharT, _Traits>& _M_os; 438 439 public: 440 /** 441 * @brief The constructor performs preparatory work. 442 * @param __os The output stream to guard. 443 * 444 * If the stream state is good (@a __os.good() is true), then if the 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 449 * true (@a okay). 450 */ 451 explicit 452 sentry(basic_ostream<_CharT, _Traits>& __os); 453 454#pragma GCC diagnostic push 455#pragma GCC diagnostic ignored "-Wdeprecated-declarations" 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 */ 463 ~sentry() 464 { 465 // XXX MT 466 if (bool(_M_os.flags() & ios_base::unitbuf) && !uncaught_exception()) 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 } 473#pragma GCC diagnostic pop 474 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 */ 482#if __cplusplus >= 201103L 483 explicit 484#endif 485 operator bool() const 486 { return _M_ok; } 487 }; 488 489 ///@{ 490 /** 491 * @brief Character inserters 492 * @param __out An output stream. 493 * @param __c A character. 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 499 * padding (as determined by [22.2.2.2.2]). @c __out.width(0) is then 500 * called. 501 * 502 * If @p __c is of type @c char and the character type of the stream is not 503 * @c char, the character is widened before insertion. 504 */ 505 template<typename _CharT, typename _Traits> 506 inline basic_ostream<_CharT, _Traits>& 507 operator<<(basic_ostream<_CharT, _Traits>& __out, _CharT __c) 508 { 509 if (__out.width() != 0) 510 return __ostream_insert(__out, &__c, 1); 511 __out.put(__c); 512 return __out; 513 } 514 515 template<typename _CharT, typename _Traits> 516 inline basic_ostream<_CharT, _Traits>& 517 operator<<(basic_ostream<_CharT, _Traits>& __out, char __c) 518 { return (__out << __out.widen(__c)); } 519 520 // Specialization 521 template<typename _Traits> 522 inline basic_ostream<char, _Traits>& 523 operator<<(basic_ostream<char, _Traits>& __out, char __c) 524 { 525 if (__out.width() != 0) 526 return __ostream_insert(__out, &__c, 1); 527 __out.put(__c); 528 return __out; 529 } 530 531 // Signed and unsigned 532 template<typename _Traits> 533 inline basic_ostream<char, _Traits>& 534 operator<<(basic_ostream<char, _Traits>& __out, signed char __c) 535 { return (__out << static_cast<char>(__c)); } 536 537 template<typename _Traits> 538 inline basic_ostream<char, _Traits>& 539 operator<<(basic_ostream<char, _Traits>& __out, unsigned char __c) 540 { return (__out << static_cast<char>(__c)); } 541 542#if __cplusplus > 201703L 543 // The following deleted overloads prevent formatting character values as 544 // numeric values. 545 546 template<typename _Traits> 547 basic_ostream<char, _Traits>& 548 operator<<(basic_ostream<char, _Traits>&, wchar_t) = delete; 549 550#ifdef _GLIBCXX_USE_CHAR8_T 551 template<typename _Traits> 552 basic_ostream<char, _Traits>& 553 operator<<(basic_ostream<char, _Traits>&, char8_t) = delete; 554#endif 555 556 template<typename _Traits> 557 basic_ostream<char, _Traits>& 558 operator<<(basic_ostream<char, _Traits>&, char16_t) = delete; 559 560 template<typename _Traits> 561 basic_ostream<char, _Traits>& 562 operator<<(basic_ostream<char, _Traits>&, char32_t) = delete; 563 564#ifdef _GLIBCXX_USE_WCHAR_T 565#ifdef _GLIBCXX_USE_CHAR8_T 566 template<typename _Traits> 567 basic_ostream<wchar_t, _Traits>& 568 operator<<(basic_ostream<wchar_t, _Traits>&, char8_t) = delete; 569#endif // _GLIBCXX_USE_CHAR8_T 570 571 template<typename _Traits> 572 basic_ostream<wchar_t, _Traits>& 573 operator<<(basic_ostream<wchar_t, _Traits>&, char16_t) = delete; 574 575 template<typename _Traits> 576 basic_ostream<wchar_t, _Traits>& 577 operator<<(basic_ostream<wchar_t, _Traits>&, char32_t) = delete; 578#endif // _GLIBCXX_USE_WCHAR_T 579#endif // C++20 580 ///@} 581 582 ///@{ 583 /** 584 * @brief String inserters 585 * @param __out An output stream. 586 * @param __s A character string. 587 * @return out 588 * @pre @p __s must be a non-NULL pointer 589 * 590 * Behaves like one of the formatted arithmetic inserters described in 591 * std::basic_ostream. After constructing a sentry object with good 592 * status, this function inserts @c traits::length(__s) characters starting 593 * at @p __s, widened if necessary, followed by any required padding (as 594 * determined by [22.2.2.2.2]). @c __out.width(0) is then called. 595 */ 596 template<typename _CharT, typename _Traits> 597 inline basic_ostream<_CharT, _Traits>& 598 operator<<(basic_ostream<_CharT, _Traits>& __out, const _CharT* __s) 599 { 600 if (!__s) 601 __out.setstate(ios_base::badbit); 602 else 603 __ostream_insert(__out, __s, 604 static_cast<streamsize>(_Traits::length(__s))); 605 return __out; 606 } 607 608 template<typename _CharT, typename _Traits> 609 basic_ostream<_CharT, _Traits> & 610 operator<<(basic_ostream<_CharT, _Traits>& __out, const char* __s); 611 612 // Partial specializations 613 template<typename _Traits> 614 inline basic_ostream<char, _Traits>& 615 operator<<(basic_ostream<char, _Traits>& __out, const char* __s) 616 { 617 if (!__s) 618 __out.setstate(ios_base::badbit); 619 else 620 __ostream_insert(__out, __s, 621 static_cast<streamsize>(_Traits::length(__s))); 622 return __out; 623 } 624 625 // Signed and unsigned 626 template<typename _Traits> 627 inline basic_ostream<char, _Traits>& 628 operator<<(basic_ostream<char, _Traits>& __out, const signed char* __s) 629 { return (__out << reinterpret_cast<const char*>(__s)); } 630 631 template<typename _Traits> 632 inline basic_ostream<char, _Traits> & 633 operator<<(basic_ostream<char, _Traits>& __out, const unsigned char* __s) 634 { return (__out << reinterpret_cast<const char*>(__s)); } 635 636#if __cplusplus > 201703L 637 // The following deleted overloads prevent formatting strings as 638 // pointer values. 639 640 template<typename _Traits> 641 basic_ostream<char, _Traits>& 642 operator<<(basic_ostream<char, _Traits>&, const wchar_t*) = delete; 643 644#ifdef _GLIBCXX_USE_CHAR8_T 645 template<typename _Traits> 646 basic_ostream<char, _Traits>& 647 operator<<(basic_ostream<char, _Traits>&, const char8_t*) = delete; 648#endif // _GLIBCXX_USE_CHAR8_T 649 650 template<typename _Traits> 651 basic_ostream<char, _Traits>& 652 operator<<(basic_ostream<char, _Traits>&, const char16_t*) = delete; 653 654 template<typename _Traits> 655 basic_ostream<char, _Traits>& 656 operator<<(basic_ostream<char, _Traits>&, const char32_t*) = delete; 657 658#ifdef _GLIBCXX_USE_WCHAR_T 659#ifdef _GLIBCXX_USE_CHAR8_T 660 template<typename _Traits> 661 basic_ostream<wchar_t, _Traits>& 662 operator<<(basic_ostream<wchar_t, _Traits>&, const char8_t*) = delete; 663#endif 664 665 template<typename _Traits> 666 basic_ostream<wchar_t, _Traits>& 667 operator<<(basic_ostream<wchar_t, _Traits>&, const char16_t*) = delete; 668 669 template<typename _Traits> 670 basic_ostream<wchar_t, _Traits>& 671 operator<<(basic_ostream<wchar_t, _Traits>&, const char32_t*) = delete; 672#endif // _GLIBCXX_USE_WCHAR_T 673#endif // C++20 674 ///@} 675 676 // Standard basic_ostream manipulators 677 678 /** 679 * @brief Write a newline and flush the stream. 680 * 681 * This manipulator is often mistakenly used when a simple newline is 682 * desired, leading to poor buffering performance. See 683 * https://gcc.gnu.org/onlinedocs/libstdc++/manual/streambufs.html#io.streambuf.buffering 684 * for more on this subject. 685 */ 686 template<typename _CharT, typename _Traits> 687 inline basic_ostream<_CharT, _Traits>& 688 endl(basic_ostream<_CharT, _Traits>& __os) 689 { return flush(__os.put(__os.widen('\n'))); } 690 691 /** 692 * @brief Write a null character into the output sequence. 693 * 694 * <em>Null character</em> is @c CharT() by definition. For CharT 695 * of @c char, this correctly writes the ASCII @c NUL character 696 * string terminator. 697 */ 698 template<typename _CharT, typename _Traits> 699 inline basic_ostream<_CharT, _Traits>& 700 ends(basic_ostream<_CharT, _Traits>& __os) 701 { return __os.put(_CharT()); } 702 703 /** 704 * @brief Flushes the output stream. 705 * 706 * This manipulator simply calls the stream's @c flush() member function. 707 */ 708 template<typename _CharT, typename _Traits> 709 inline basic_ostream<_CharT, _Traits>& 710 flush(basic_ostream<_CharT, _Traits>& __os) 711 { return __os.flush(); } 712 713#if __cplusplus >= 201103L 714 // C++11 27.7.3.9 Rvalue stream insertion [ostream.rvalue] 715 // _GLIBCXX_RESOLVE_LIB_DEFECTS 716 // 1203. More useful rvalue stream insertion 717 718#if __cpp_lib_concepts 719 // Use concepts if possible because they're cheaper to evaluate. 720 template<typename _Tp> 721 concept __derived_from_ios_base = is_class_v<_Tp> 722 && (!is_same_v<_Tp, ios_base>) 723 && requires (_Tp* __t, ios_base* __b) { __b = __t; }; 724 725 template<typename _Os, typename _Tp> 726 requires __derived_from_ios_base<_Os> 727 && requires (_Os& __os, const _Tp& __t) { __os << __t; } 728 using __rvalue_stream_insertion_t = _Os&&; 729#else 730 template<typename _Tp> 731 using _Require_derived_from_ios_base 732 = _Require<is_class<_Tp>, __not_<is_same<_Tp, ios_base>>, 733 is_convertible<typename add_pointer<_Tp>::type, ios_base*>>; 734 735 template<typename _Os, typename _Tp, 736 typename = _Require_derived_from_ios_base<_Os>, 737 typename 738 = decltype(std::declval<_Os&>() << std::declval<const _Tp&>())> 739 using __rvalue_stream_insertion_t = _Os&&; 740#endif 741 742 /** 743 * @brief Generic inserter for rvalue stream 744 * @param __os An input stream. 745 * @param __x A reference to the object being inserted. 746 * @return __os 747 * 748 * This is just a forwarding function to allow insertion to 749 * rvalue streams since they won't bind to the inserter functions 750 * that take an lvalue reference. 751 */ 752 template<typename _Ostream, typename _Tp> 753 inline __rvalue_stream_insertion_t<_Ostream, _Tp> 754 operator<<(_Ostream&& __os, const _Tp& __x) 755 { 756 __os << __x; 757 return std::move(__os); 758 } 759 760#if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI 761 template<typename _CharT, typename _Traits> 762 class __syncbuf_base : public basic_streambuf<_CharT, _Traits> 763 { 764 public: 765 static bool* 766 _S_get(basic_streambuf<_CharT, _Traits>* __buf [[maybe_unused]]) noexcept 767 { 768#if __cpp_rtti 769 if (auto __p = dynamic_cast<__syncbuf_base*>(__buf)) 770 return &__p->_M_emit_on_sync; 771#endif 772 return nullptr; 773 } 774 775 protected: 776 __syncbuf_base(basic_streambuf<_CharT, _Traits>* __w = nullptr) 777 : _M_wrapped(__w) 778 { } 779 780 basic_streambuf<_CharT, _Traits>* _M_wrapped = nullptr; 781 bool _M_emit_on_sync = false; 782 bool _M_needs_sync = false; 783 }; 784 785 template<typename _CharT, typename _Traits> 786 inline basic_ostream<_CharT, _Traits>& 787 emit_on_flush(basic_ostream<_CharT, _Traits>& __os) 788 { 789 if (bool* __flag = __syncbuf_base<_CharT, _Traits>::_S_get(__os.rdbuf())) 790 *__flag = true; 791 return __os; 792 } 793 794 template<typename _CharT, typename _Traits> 795 inline basic_ostream<_CharT, _Traits>& 796 noemit_on_flush(basic_ostream<_CharT, _Traits>& __os) 797 { 798 if (bool* __flag = __syncbuf_base<_CharT, _Traits>::_S_get(__os.rdbuf())) 799 *__flag = false; 800 return __os; 801 } 802 803 template<typename _CharT, typename _Traits> 804 inline basic_ostream<_CharT, _Traits>& 805 flush_emit(basic_ostream<_CharT, _Traits>& __os) 806 { 807 struct _Restore 808 { 809 ~_Restore() { *_M_flag = _M_prev; } 810 811 bool _M_prev = false; 812 bool* _M_flag = &_M_prev; 813 } __restore; 814 815 if (bool* __flag = __syncbuf_base<_CharT, _Traits>::_S_get(__os.rdbuf())) 816 { 817 __restore._M_prev = *__flag; 818 __restore._M_flag = __flag; 819 *__flag = true; 820 } 821 822 __os.flush(); 823 return __os; 824 } 825 826#endif // C++20 827 828#endif // C++11 829 830_GLIBCXX_END_NAMESPACE_VERSION 831} // namespace std 832 833#include <bits/ostream.tcc> 834 835#endif /* _GLIBCXX_OSTREAM */ 836