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 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 /** 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 */ 829