Where Online Learning is simpler!
The C and C++ Include Header Files
cat -n /usr/include/c++/15/sstream
1 // String based streams -*- C++ -*- 2 3 // Copyright (C) 1997-2025 Free Software Foundation, Inc. 4 // 5 // This file is part of the GNU ISO C++ Library. This library is free 6 // software; you can redistribute it and/or modify it under the 7 // terms of the GNU General Public License as published by the 8 // Free Software Foundation; either version 3, or (at your option) 9 // any later version. 10 11 // This library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 16 // Under Section 7 of GPL version 3, you are granted additional 17 // permissions described in the GCC Runtime Library Exception, version 18 // 3.1, as published by the Free Software Foundation. 19 20 // You should have received a copy of the GNU General Public License and 21 // a copy of the GCC Runtime Library Exception along with this program; 22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 // <http://www.gnu.org/licenses/>. 24 25 /** @file include/sstream 26 * This is a Standard C++ Library header. 27 */ 28 29 // 30 // ISO C++ 14882: 27.7 String-based streams 31 // 32 33 #ifndef _GLIBCXX_SSTREAM 34 #define _GLIBCXX_SSTREAM 1 35 36 #ifdef _GLIBCXX_SYSHDR 37 #pragma GCC system_header 38 #endif 39 40 #include <bits/requires_hosted.h> // iostream 41 42 #include <istream> 43 #include <ostream> 44 #include <bits/alloc_traits.h> // allocator_traits, __allocator_like 45 46 #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI 47 # define _GLIBCXX_LVAL_REF_QUAL & 48 # define _GLIBCXX_SSTREAM_ALWAYS_INLINE 49 #else 50 # define _GLIBCXX_LVAL_REF_QUAL 51 // For symbols that are not exported from libstdc++.so for the COW string ABI. 52 # define _GLIBCXX_SSTREAM_ALWAYS_INLINE [[__gnu__::__always_inline__]] 53 #endif 54 55 56 57 namespace std _GLIBCXX_VISIBILITY(default) 58 { 59 _GLIBCXX_BEGIN_NAMESPACE_VERSION 60 _GLIBCXX_BEGIN_NAMESPACE_CXX11 61 62 // [27.7.1] template class basic_stringbuf 63 /** 64 * @brief The actual work of input and output (for std::string). 65 * @ingroup io 66 * 67 * @tparam _CharT Type of character stream. 68 * @tparam _Traits Traits for character type, defaults to 69 * char_traits<_CharT>. 70 * @tparam _Alloc Allocator type, defaults to allocator<_CharT>. 71 * 72 * This class associates either or both of its input and output sequences 73 * with a sequence of characters, which can be initialized from, or made 74 * available as, a @c std::basic_string. (Paraphrased from [27.7.1]/1.) 75 * 76 * For this class, open modes (of type @c ios_base::openmode) have 77 * @c in set if the input sequence can be read, and @c out set if the 78 * output sequence can be written. 79 */ 80 template<typename _CharT, typename _Traits, typename _Alloc> 81 class basic_stringbuf : public basic_streambuf<_CharT, _Traits> 82 { 83 struct __xfer_bufptrs; 84 85 #if __cplusplus >= 201103L 86 using allocator_traits = std::allocator_traits<_Alloc>; 87 using _Noexcept_swap 88 = __or_<typename allocator_traits::propagate_on_container_swap, 89 typename allocator_traits::is_always_equal>; 90 #endif 91 92 public: 93 // Types: 94 typedef _CharT char_type; 95 typedef _Traits traits_type; 96 // _GLIBCXX_RESOLVE_LIB_DEFECTS 97 // 251. basic_stringbuf missing allocator_type 98 typedef _Alloc allocator_type; 99 typedef typename traits_type::int_type int_type; 100 typedef typename traits_type::pos_type pos_type; 101 typedef typename traits_type::off_type off_type; 102 103 typedef basic_streambuf<char_type, traits_type> __streambuf_type; 104 typedef basic_string<char_type, _Traits, _Alloc> __string_type; 105 typedef typename __string_type::size_type __size_type; 106 107 protected: 108 /// Place to stash in || out || in | out settings for current stringbuf. 109 ios_base::openmode _M_mode; 110 111 // Data Members: 112 __string_type _M_string; 113 114 public: 115 // Constructors: 116 117 /** 118 * @brief Starts with an empty string buffer. 119 * 120 * The default constructor initializes the parent class using its 121 * own default ctor. 122 */ 123 basic_stringbuf() 124 : __streambuf_type(), _M_mode(ios_base::in | ios_base::out), _M_string() 125 { } 126 127 /** 128 * @brief Starts with an empty string buffer. 129 * @param __mode Whether the buffer can read, or write, or both. 130 * 131 * The default constructor initializes the parent class using its 132 * own default ctor. 133 */ 134 explicit 135 basic_stringbuf(ios_base::openmode __mode) 136 : __streambuf_type(), _M_mode(__mode), _M_string() 137 { } 138 139 /** 140 * @brief Starts with an existing string buffer. 141 * @param __str A string to copy as a starting buffer. 142 * @param __mode Whether the buffer can read, or write, or both. 143 * 144 * This constructor initializes the parent class using its 145 * own default ctor. 146 */ 147 explicit 148 basic_stringbuf(const __string_type& __str, 149 ios_base::openmode __mode = ios_base::in | ios_base::out) 150 : __streambuf_type(), _M_mode(), 151 _M_string(__str.data(), __str.size(), __str.get_allocator()) 152 { _M_stringbuf_init(__mode); } 153 154 #if __cplusplus >= 201103L 155 basic_stringbuf(const basic_stringbuf&) = delete; 156 157 basic_stringbuf(basic_stringbuf&& __rhs) 158 : basic_stringbuf(std::move(__rhs), __xfer_bufptrs(__rhs, this)) 159 { __rhs._M_sync(const_cast<char_type*>(__rhs._M_string.data()), 0, 0); } 160 161 #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI 162 explicit 163 basic_stringbuf(const allocator_type& __a) 164 : basic_stringbuf(ios_base::in | std::ios_base::out, __a) 165 { } 166 167 basic_stringbuf(ios_base::openmode __mode, 168 const allocator_type& __a) 169 : __streambuf_type(), _M_mode(__mode), _M_string(__a) 170 { } 171 172 explicit 173 basic_stringbuf(__string_type&& __s, 174 ios_base::openmode __mode = ios_base::in 175 | ios_base::out) 176 : __streambuf_type(), _M_mode(__mode), _M_string(std::move(__s)) 177 { _M_stringbuf_init(__mode); } 178 179 template<typename _SAlloc> 180 basic_stringbuf(const basic_string<_CharT, _Traits, _SAlloc>& __s, 181 const allocator_type& __a) 182 : basic_stringbuf(__s, ios_base::in | std::ios_base::out, __a) 183 { } 184 185 template<typename _SAlloc> 186 basic_stringbuf(const basic_string<_CharT, _Traits, _SAlloc>& __s, 187 ios_base::openmode __mode, 188 const allocator_type& __a) 189 : __streambuf_type(), _M_mode(__mode), 190 _M_string(__s.data(), __s.size(), __a) 191 { _M_stringbuf_init(__mode); } 192 193 template<typename _SAlloc> 194 explicit 195 basic_stringbuf(const basic_string<_CharT, _Traits, _SAlloc>& __s, 196 ios_base::openmode __mode = ios_base::in 197 | ios_base::out) 198 : basic_stringbuf(__s, __mode, allocator_type{}) 199 { } 200 201 basic_stringbuf(basic_stringbuf&& __rhs, const allocator_type& __a) 202 : basic_stringbuf(std::move(__rhs), __a, __xfer_bufptrs(__rhs, this)) 203 { __rhs._M_sync(const_cast<char_type*>(__rhs._M_string.data()), 0, 0); } 204 205 allocator_type get_allocator() const noexcept 206 { return _M_string.get_allocator(); } 207 #endif // C++20 208 209 // 27.8.2.2 Assign and swap: 210 211 basic_stringbuf& 212 operator=(const basic_stringbuf&) = delete; 213 214 basic_stringbuf& 215 operator=(basic_stringbuf&& __rhs) 216 { 217 __xfer_bufptrs __st{__rhs, this}; 218 const __streambuf_type& __base = __rhs; 219 __streambuf_type::operator=(__base); 220 this->pubimbue(__rhs.getloc()); 221 _M_mode = __rhs._M_mode; 222 _M_string = std::move(__rhs._M_string); 223 __rhs._M_sync(const_cast<char_type*>(__rhs._M_string.data()), 0, 0); 224 return *this; 225 } 226 227 void 228 swap(basic_stringbuf& __rhs) noexcept(_Noexcept_swap::value) 229 { 230 __xfer_bufptrs __l_st{*this, std::__addressof(__rhs)}; 231 __xfer_bufptrs __r_st{__rhs, this}; 232 __streambuf_type& __base = __rhs; 233 __streambuf_type::swap(__base); 234 __rhs.pubimbue(this->pubimbue(__rhs.getloc())); 235 std::swap(_M_mode, __rhs._M_mode); 236 std::swap(_M_string, __rhs._M_string); // XXX not exception safe 237 } 238 #endif // C++11 239 240 // Getters and setters: 241 242 /** 243 * @brief Copying out the string buffer. 244 * @return A copy of one of the underlying sequences. 245 * 246 * <em>If the buffer is only created in input mode, the underlying 247 * character sequence is equal to the input sequence; otherwise, it 248 * is equal to the output sequence.</em> [27.7.1.2]/1 249 */ 250 _GLIBCXX_NODISCARD 251 __string_type 252 str() const _GLIBCXX_LVAL_REF_QUAL 253 { 254 __string_type __ret(_M_string.get_allocator()); 255 if (char_type* __hi = _M_high_mark()) 256 __ret.assign(this->pbase(), __hi); 257 else 258 __ret = _M_string; 259 return __ret; 260 } 261 262 #if __cplusplus > 201703L 263 #if _GLIBCXX_USE_CXX11_ABI 264 #if __cpp_concepts 265 template<__allocator_like _SAlloc> 266 _GLIBCXX_NODISCARD 267 basic_string<_CharT, _Traits, _SAlloc> 268 str(const _SAlloc& __sa) const 269 { 270 auto __sv = view(); 271 return { __sv.data(), __sv.size(), __sa }; 272 } 273 #endif 274 275 _GLIBCXX_NODISCARD 276 __string_type 277 str() && 278 { 279 if (char_type* __hi = _M_high_mark()) 280 { 281 // Set length to end of character sequence and add null terminator. 282 _M_string._M_set_length(_M_high_mark() - this->pbase()); 283 } 284 auto __str = std::move(_M_string); 285 _M_string.clear(); 286 _M_sync(_M_string.data(), 0, 0); 287 return __str; 288 } 289 #endif // cxx11 ABI 290 291 _GLIBCXX_SSTREAM_ALWAYS_INLINE 292 basic_string_view<char_type, traits_type> 293 view() const noexcept 294 { 295 if (char_type* __hi = _M_high_mark()) 296 return { this->pbase(), __hi }; 297 else 298 return _M_string; 299 } 300 #endif // C++20 301 302 /** 303 * @brief Setting a new buffer. 304 * @param __s The string to use as a new sequence. 305 * 306 * Deallocates any previous stored sequence, then copies @a s to 307 * use as a new one. 308 */ 309 void 310 str(const __string_type& __s) 311 { 312 // Cannot use _M_string = __s, since v3 strings are COW 313 // (not always true now but assign() always works). 314 _M_string.assign(__s.data(), __s.size()); 315 _M_stringbuf_init(_M_mode); 316 } 317 318 #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI 319 #if __cpp_concepts 320 template<__allocator_like _SAlloc> 321 requires (!is_same_v<_SAlloc, _Alloc>) 322 void 323 str(const basic_string<_CharT, _Traits, _SAlloc>& __s) 324 { 325 _M_string.assign(__s.data(), __s.size()); 326 _M_stringbuf_init(_M_mode); 327 } 328 #endif 329 330 void 331 str(__string_type&& __s) 332 { 333 _M_string = std::move(__s); 334 _M_stringbuf_init(_M_mode); 335 } 336 #endif 337 338 protected: 339 // Common initialization code goes here. 340 void 341 _M_stringbuf_init(ios_base::openmode __mode) 342 { 343 _M_mode = __mode; 344 __size_type __len = 0; 345 if (_M_mode & (ios_base::ate | ios_base::app)) 346 __len = _M_string.size(); 347 _M_sync(const_cast<char_type*>(_M_string.data()), 0, __len); 348 } 349 350 virtual streamsize 351 showmanyc() 352 { 353 streamsize __ret = -1; 354 if (_M_mode & ios_base::in) 355 { 356 _M_update_egptr(); 357 __ret = this->egptr() - this->gptr(); 358 } 359 return __ret; 360 } 361 362 virtual int_type 363 underflow(); 364 365 virtual int_type 366 pbackfail(int_type __c = traits_type::eof()); 367 368 virtual int_type 369 overflow(int_type __c = traits_type::eof()); 370 371 /** 372 * @brief Manipulates the buffer. 373 * @param __s Pointer to a buffer area. 374 * @param __n Size of @a __s. 375 * @return @c this 376 * 377 * If no buffer has already been created, and both @a __s and @a __n are 378 * non-zero, then @c __s is used as a buffer; see 379 * https://gcc.gnu.org/onlinedocs/libstdc++/manual/streambufs.html#io.streambuf.buffering 380 * for more. 381 */ 382 virtual __streambuf_type* 383 setbuf(char_type* __s, streamsize __n) 384 { 385 if (__s && __n >= 0) 386 { 387 // This is implementation-defined behavior, and assumes 388 // that an external char_type array of length __n exists 389 // and has been pre-allocated. If this is not the case, 390 // things will quickly blow up. 391 392 // Step 1: Destroy the current internal array. 393 _M_string.clear(); 394 395 // Step 2: Use the external array. 396 _M_sync(__s, __n, 0); 397 } 398 return this; 399 } 400 401 virtual pos_type 402 seekoff(off_type __off, ios_base::seekdir __way, 403 ios_base::openmode __mode = ios_base::in | ios_base::out); 404 405 virtual pos_type 406 seekpos(pos_type __sp, 407 ios_base::openmode __mode = ios_base::in | ios_base::out); 408 409 // Internal function for correctly updating the internal buffer 410 // for a particular _M_string, due to initialization or re-sizing 411 // of an existing _M_string. 412 void 413 _M_sync(char_type* __base, __size_type __i, __size_type __o); 414 415 // Internal function for correctly updating egptr() to the actual 416 // string end. 417 void 418 _M_update_egptr() 419 { 420 if (char_type* __pptr = this->pptr()) 421 { 422 char_type* __egptr = this->egptr(); 423 if (!__egptr || __pptr > __egptr) 424 { 425 if (_M_mode & ios_base::in) 426 this->setg(this->eback(), this->gptr(), __pptr); 427 else 428 this->setg(__pptr, __pptr, __pptr); 429 } 430 } 431 } 432 433 // Works around the issue with pbump, part of the protected 434 // interface of basic_streambuf, taking just an int. 435 void 436 _M_pbump(char_type* __pbeg, char_type* __pend, off_type __off); 437 438 private: 439 // Return a pointer to the end of the underlying character sequence. 440 // This might not be the same character as _M_string.end() because 441 // basic_stringbuf::overflow might have written to unused capacity 442 // in _M_string without updating its length. 443 __attribute__((__always_inline__)) 444 char_type* 445 _M_high_mark() const _GLIBCXX_NOEXCEPT 446 { 447 if (char_type* __pptr = this->pptr()) 448 { 449 char_type* __egptr = this->egptr(); 450 if (!__egptr || __pptr > __egptr) 451 return __pptr; // Underlying sequence is [pbase, pptr). 452 else 453 return __egptr; // Underlying sequence is [pbase, egptr). 454 } 455 return 0; // Underlying character sequence is just _M_string. 456 } 457 458 #if __cplusplus >= 201103L 459 #if _GLIBCXX_USE_CXX11_ABI 460 // This type captures the state of the gptr / pptr pointers as offsets 461 // so they can be restored in another object after moving the string. 462 struct __xfer_bufptrs 463 { 464 __xfer_bufptrs(const basic_stringbuf& __from, basic_stringbuf* __to) 465 : _M_to{__to}, _M_goff{-1, -1, -1}, _M_poff{-1, -1, -1} 466 { 467 const _CharT* const __str = __from._M_string.data(); 468 const _CharT* __end = nullptr; 469 if (__from.eback()) 470 { 471 _M_goff[0] = __from.eback() - __str; 472 _M_goff[1] = __from.gptr() - __str; 473 _M_goff[2] = __from.egptr() - __str; 474 __end = __from.egptr(); 475 } 476 if (__from.pbase()) 477 { 478 _M_poff[0] = __from.pbase() - __str; 479 _M_poff[1] = __from.pptr() - __from.pbase(); 480 _M_poff[2] = __from.epptr() - __str; 481 if (!__end || __from.pptr() > __end) 482 __end = __from.pptr(); 483 } 484 485 // Set _M_string length to the greater of the get and put areas. 486 if (__end) 487 { 488 // The const_cast avoids changing this constructor's signature, 489 // because it is exported from the dynamic library. 490 auto& __mut_from = const_cast<basic_stringbuf&>(__from); 491 __mut_from._M_string._M_length(__end - __str); 492 } 493 } 494 495 ~__xfer_bufptrs() 496 { 497 char_type* __str = const_cast<char_type*>(_M_to->_M_string.data()); 498 if (_M_goff[0] != -1) 499 _M_to->setg(__str+_M_goff[0], __str+_M_goff[1], __str+_M_goff[2]); 500 if (_M_poff[0] != -1) 501 _M_to->_M_pbump(__str+_M_poff[0], __str+_M_poff[2], _M_poff[1]); 502 } 503 504 basic_stringbuf* _M_to; 505 off_type _M_goff[3]; 506 off_type _M_poff[3]; 507 }; 508 #else 509 // This type does nothing when using Copy-On-Write strings. 510 struct __xfer_bufptrs 511 { 512 __xfer_bufptrs(const basic_stringbuf&, basic_stringbuf*) { } 513 }; 514 #endif 515 516 // The move constructor initializes an __xfer_bufptrs temporary then 517 // delegates to this constructor to performs moves during its lifetime. 518 basic_stringbuf(basic_stringbuf&& __rhs, __xfer_bufptrs&&) 519 : __streambuf_type(static_cast<const __streambuf_type&>(__rhs)), 520 _M_mode(__rhs._M_mode), _M_string(std::move(__rhs._M_string)) 521 { } 522 523 #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI 524 // The move constructor initializes an __xfer_bufptrs temporary then 525 // delegates to this constructor to performs moves during its lifetime. 526 basic_stringbuf(basic_stringbuf&& __rhs, const allocator_type& __a, 527 __xfer_bufptrs&&) 528 : __streambuf_type(static_cast<const __streambuf_type&>(__rhs)), 529 _M_mode(__rhs._M_mode), _M_string(std::move(__rhs._M_string), __a) 530 { } 531 #endif 532 #endif // C++11 533 }; 534 535 536 // [27.7.2] Template class basic_istringstream 537 /** 538 * @brief Controlling input for std::string. 539 * @ingroup io 540 * 541 * @tparam _CharT Type of character stream. 542 * @tparam _Traits Traits for character type, defaults to 543 * char_traits<_CharT>. 544 * @tparam _Alloc Allocator type, defaults to allocator<_CharT>. 545 * 546 * This class supports reading from objects of type std::basic_string, 547 * using the inherited functions from std::basic_istream. To control 548 * the associated sequence, an instance of std::basic_stringbuf is used, 549 * which this page refers to as @c sb. 550 */ 551 template<typename _CharT, typename _Traits, typename _Alloc> 552 class basic_istringstream : public basic_istream<_CharT, _Traits> 553 { 554 public: 555 // Types: 556 typedef _CharT char_type; 557 typedef _Traits traits_type; 558 // _GLIBCXX_RESOLVE_LIB_DEFECTS 559 // 251. basic_stringbuf missing allocator_type 560 typedef _Alloc allocator_type; 561 typedef typename traits_type::int_type int_type; 562 typedef typename traits_type::pos_type pos_type; 563 typedef typename traits_type::off_type off_type; 564 565 // Non-standard types: 566 typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 567 typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type; 568 typedef basic_istream<char_type, traits_type> __istream_type; 569 570 private: 571 __stringbuf_type _M_stringbuf; 572 573 public: 574 // Constructors: 575 576 /** 577 * @brief Default constructor starts with an empty string buffer. 578 * 579 * Initializes @c sb using @c in, and passes @c &sb to the base 580 * class initializer. Does not allocate any buffer. 581 * 582 * That's a lie. We initialize the base class with NULL, because the 583 * string class does its own memory management. 584 */ 585 basic_istringstream() 586 : __istream_type(), _M_stringbuf(ios_base::in) 587 { this->init(&_M_stringbuf); } 588 589 /** 590 * @brief Starts with an empty string buffer. 591 * @param __mode Whether the buffer can read, or write, or both. 592 * 593 * @c ios_base::in is automatically included in @a __mode. 594 * 595 * Initializes @c sb using @c __mode|in, and passes @c &sb to the base 596 * class initializer. Does not allocate any buffer. 597 * 598 * That's a lie. We initialize the base class with NULL, because the 599 * string class does its own memory management. 600 */ 601 explicit 602 basic_istringstream(ios_base::openmode __mode) 603 : __istream_type(), _M_stringbuf(__mode | ios_base::in) 604 { this->init(&_M_stringbuf); } 605 606 /** 607 * @brief Starts with an existing string buffer. 608 * @param __str A string to copy as a starting buffer. 609 * @param __mode Whether the buffer can read, or write, or both. 610 * 611 * @c ios_base::in is automatically included in @a mode. 612 * 613 * Initializes @c sb using @a str and @c mode|in, and passes @c &sb 614 * to the base class initializer. 615 * 616 * That's a lie. We initialize the base class with NULL, because the 617 * string class does its own memory management. 618 */ 619 explicit 620 basic_istringstream(const __string_type& __str, 621 ios_base::openmode __mode = ios_base::in) 622 : __istream_type(), _M_stringbuf(__str, __mode | ios_base::in) 623 { this->init(&_M_stringbuf); } 624 625 /** 626 * @brief The destructor does nothing. 627 * 628 * The buffer is deallocated by the stringbuf object, not the 629 * formatting stream. 630 */ 631 ~basic_istringstream() 632 { } 633 634 #if __cplusplus >= 201103L 635 basic_istringstream(const basic_istringstream&) = delete; 636 637 basic_istringstream(basic_istringstream&& __rhs) 638 : __istream_type(std::move(__rhs)), 639 _M_stringbuf(std::move(__rhs._M_stringbuf)) 640 { __istream_type::set_rdbuf(&_M_stringbuf); } 641 642 #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI 643 basic_istringstream(ios_base::openmode __mode, const allocator_type& __a) 644 : __istream_type(), _M_stringbuf(__mode | ios_base::in, __a) 645 { this->init(std::__addressof(_M_stringbuf)); } 646 647 explicit 648 basic_istringstream(__string_type&& __str, 649 ios_base::openmode __mode = ios_base::in) 650 : __istream_type(), _M_stringbuf(std::move(__str), __mode | ios_base::in) 651 { this->init(std::__addressof(_M_stringbuf)); } 652 653 template<typename _SAlloc> 654 basic_istringstream(const basic_string<_CharT, _Traits, _SAlloc>& __str, 655 const allocator_type& __a) 656 : basic_istringstream(__str, ios_base::in, __a) 657 { } 658 659 template<typename _SAlloc> 660 basic_istringstream(const basic_string<_CharT, _Traits, _SAlloc>& __str, 661 ios_base::openmode __mode, 662 const allocator_type& __a) 663 : __istream_type(), _M_stringbuf(__str, __mode | ios_base::in, __a) 664 { this->init(std::__addressof(_M_stringbuf)); } 665 666 template<typename _SAlloc> 667 explicit 668 basic_istringstream(const basic_string<_CharT, _Traits, _SAlloc>& __str, 669 ios_base::openmode __mode = ios_base::in) 670 : basic_istringstream(__str, __mode, allocator_type()) 671 { } 672 #endif // C++20 673 674 // 27.8.3.2 Assign and swap: 675 676 basic_istringstream& 677 operator=(const basic_istringstream&) = delete; 678 679 basic_istringstream& 680 operator=(basic_istringstream&& __rhs) 681 { 682 __istream_type::operator=(std::move(__rhs)); 683 _M_stringbuf = std::move(__rhs._M_stringbuf); 684 return *this; 685 } 686 687 void 688 swap(basic_istringstream& __rhs) 689 { 690 __istream_type::swap(__rhs); 691 _M_stringbuf.swap(__rhs._M_stringbuf); 692 } 693 #endif // C++11 694 695 // Members: 696 /** 697 * @brief Accessing the underlying buffer. 698 * @return The current basic_stringbuf buffer. 699 * 700 * This hides both signatures of std::basic_ios::rdbuf(). 701 */ 702 _GLIBCXX_NODISCARD 703 __stringbuf_type* 704 rdbuf() const 705 { return const_cast<__stringbuf_type*>(&_M_stringbuf); } 706 707 /** 708 * @brief Copying out the string buffer. 709 * @return @c rdbuf()->str() 710 */ 711 _GLIBCXX_NODISCARD 712 __string_type 713 str() const _GLIBCXX_LVAL_REF_QUAL 714 { return _M_stringbuf.str(); } 715 716 #if __cplusplus > 201703L 717 #if _GLIBCXX_USE_CXX11_ABI 718 #if __cpp_concepts 719 template<__allocator_like _SAlloc> 720 _GLIBCXX_NODISCARD 721 basic_string<_CharT, _Traits, _SAlloc> 722 str(const _SAlloc& __sa) const 723 { return _M_stringbuf.str(__sa); } 724 #endif 725 726 _GLIBCXX_NODISCARD 727 __string_type 728 str() && 729 { return std::move(_M_stringbuf).str(); } 730 #endif // cxx11 ABI 731 732 _GLIBCXX_SSTREAM_ALWAYS_INLINE 733 basic_string_view<char_type, traits_type> 734 view() const noexcept 735 { return _M_stringbuf.view(); } 736 #endif // C++20 737 738 /** 739 * @brief Setting a new buffer. 740 * @param __s The string to use as a new sequence. 741 * 742 * Calls @c rdbuf()->str(s). 743 */ 744 void 745 str(const __string_type& __s) 746 { _M_stringbuf.str(__s); } 747 748 #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI 749 #if __cpp_concepts 750 template<__allocator_like _SAlloc> 751 requires (!is_same_v<_SAlloc, _Alloc>) 752 void 753 str(const basic_string<_CharT, _Traits, _SAlloc>& __s) 754 { _M_stringbuf.str(__s); } 755 #endif 756 757 void 758 str(__string_type&& __s) 759 { _M_stringbuf.str(std::move(__s)); } 760 #endif 761 }; 762 763 764 // [27.7.3] Template class basic_ostringstream 765 /** 766 * @brief Controlling output for std::string. 767 * @ingroup io 768 * 769 * @tparam _CharT Type of character stream. 770 * @tparam _Traits Traits for character type, defaults to 771 * char_traits<_CharT>. 772 * @tparam _Alloc Allocator type, defaults to allocator<_CharT>. 773 * 774 * This class supports writing to objects of type std::basic_string, 775 * using the inherited functions from std::basic_ostream. To control 776 * the associated sequence, an instance of std::basic_stringbuf is used, 777 * which this page refers to as @c sb. 778 */ 779 template <typename _CharT, typename _Traits, typename _Alloc> 780 class basic_ostringstream : public basic_ostream<_CharT, _Traits> 781 { 782 public: 783 // Types: 784 typedef _CharT char_type; 785 typedef _Traits traits_type; 786 // _GLIBCXX_RESOLVE_LIB_DEFECTS 787 // 251. basic_stringbuf missing allocator_type 788 typedef _Alloc allocator_type; 789 typedef typename traits_type::int_type int_type; 790 typedef typename traits_type::pos_type pos_type; 791 typedef typename traits_type::off_type off_type; 792 793 // Non-standard types: 794 typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 795 typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type; 796 typedef basic_ostream<char_type, traits_type> __ostream_type; 797 798 private: 799 __stringbuf_type _M_stringbuf; 800 801 public: 802 // Constructors/destructor: 803 804 /** 805 * @brief Default constructor starts with an empty string buffer. 806 * 807 * Initializes @c sb using @c mode|out, and passes @c &sb to the base 808 * class initializer. Does not allocate any buffer. 809 * 810 * That's a lie. We initialize the base class with NULL, because the 811 * string class does its own memory management. 812 */ 813 basic_ostringstream() 814 : __ostream_type(), _M_stringbuf(ios_base::out) 815 { this->init(&_M_stringbuf); } 816 817 /** 818 * @brief Starts with an empty string buffer. 819 * @param __mode Whether the buffer can read, or write, or both. 820 * 821 * @c ios_base::out is automatically included in @a mode. 822 * 823 * Initializes @c sb using @c mode|out, and passes @c &sb to the base 824 * class initializer. Does not allocate any buffer. 825 * 826 * That's a lie. We initialize the base class with NULL, because the 827 * string class does its own memory management. 828 */ 829 explicit 830 basic_ostringstream(ios_base::openmode __mode) 831 : __ostream_type(), _M_stringbuf(__mode | ios_base::out) 832 { this->init(&_M_stringbuf); } 833 834 /** 835 * @brief Starts with an existing string buffer. 836 * @param __str A string to copy as a starting buffer. 837 * @param __mode Whether the buffer can read, or write, or both. 838 * 839 * @c ios_base::out is automatically included in @a mode. 840 * 841 * Initializes @c sb using @a str and @c mode|out, and passes @c &sb 842 * to the base class initializer. 843 * 844 * That's a lie. We initialize the base class with NULL, because the 845 * string class does its own memory management. 846 */ 847 explicit 848 basic_ostringstream(const __string_type& __str, 849 ios_base::openmode __mode = ios_base::out) 850 : __ostream_type(), _M_stringbuf(__str, __mode | ios_base::out) 851 { this->init(&_M_stringbuf); } 852 853 /** 854 * @brief The destructor does nothing. 855 * 856 * The buffer is deallocated by the stringbuf object, not the 857 * formatting stream. 858 */ 859 ~basic_ostringstream() 860 { } 861 862 #if __cplusplus >= 201103L 863 basic_ostringstream(const basic_ostringstream&) = delete; 864 865 basic_ostringstream(basic_ostringstream&& __rhs) 866 : __ostream_type(std::move(__rhs)), 867 _M_stringbuf(std::move(__rhs._M_stringbuf)) 868 { __ostream_type::set_rdbuf(&_M_stringbuf); } 869 870 #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI 871 basic_ostringstream(ios_base::openmode __mode, const allocator_type& __a) 872 : __ostream_type(), _M_stringbuf(__mode | ios_base::out, __a) 873 { this->init(std::__addressof(_M_stringbuf)); } 874 875 explicit 876 basic_ostringstream(__string_type&& __str, 877 ios_base::openmode __mode = ios_base::out) 878 : __ostream_type(), _M_stringbuf(std::move(__str), __mode | ios_base::out) 879 { this->init(std::__addressof(_M_stringbuf)); } 880 881 template<typename _SAlloc> 882 basic_ostringstream(const basic_string<_CharT, _Traits, _SAlloc>& __str, 883 const allocator_type& __a) 884 : basic_ostringstream(__str, ios_base::out, __a) 885 { } 886 887 template<typename _SAlloc> 888 basic_ostringstream(const basic_string<_CharT, _Traits, _SAlloc>& __str, 889 ios_base::openmode __mode, 890 const allocator_type& __a) 891 : __ostream_type(), _M_stringbuf(__str, __mode | ios_base::out, __a) 892 { this->init(std::__addressof(_M_stringbuf)); } 893 894 template<typename _SAlloc> 895 explicit 896 basic_ostringstream(const basic_string<_CharT, _Traits, _SAlloc>& __str, 897 ios_base::openmode __mode = ios_base::out) 898 : basic_ostringstream(__str, __mode, allocator_type()) 899 { } 900 #endif // C++20 901 902 // 27.8.3.2 Assign and swap: 903 904 basic_ostringstream& 905 operator=(const basic_ostringstream&) = delete; 906 907 basic_ostringstream& 908 operator=(basic_ostringstream&& __rhs) 909 { 910 __ostream_type::operator=(std::move(__rhs)); 911 _M_stringbuf = std::move(__rhs._M_stringbuf); 912 return *this; 913 } 914 915 void 916 swap(basic_ostringstream& __rhs) 917 { 918 __ostream_type::swap(__rhs); 919 _M_stringbuf.swap(__rhs._M_stringbuf); 920 } 921 #endif // C++11 922 923 // Members: 924 /** 925 * @brief Accessing the underlying buffer. 926 * @return The current basic_stringbuf buffer. 927 * 928 * This hides both signatures of std::basic_ios::rdbuf(). 929 */ 930 _GLIBCXX_NODISCARD 931 __stringbuf_type* 932 rdbuf() const 933 { return const_cast<__stringbuf_type*>(&_M_stringbuf); } 934 935 /** 936 * @brief Copying out the string buffer. 937 * @return @c rdbuf()->str() 938 */ 939 _GLIBCXX_NODISCARD 940 __string_type 941 str() const _GLIBCXX_LVAL_REF_QUAL 942 { return _M_stringbuf.str(); } 943 944 #if __cplusplus > 201703L 945 #if _GLIBCXX_USE_CXX11_ABI 946 #if __cpp_concepts 947 template<__allocator_like _SAlloc> 948 _GLIBCXX_NODISCARD 949 basic_string<_CharT, _Traits, _SAlloc> 950 str(const _SAlloc& __sa) const 951 { return _M_stringbuf.str(__sa); } 952 #endif 953 954 _GLIBCXX_NODISCARD 955 __string_type 956 str() && 957 { return std::move(_M_stringbuf).str(); } 958 #endif // cxx11 ABI 959 960 _GLIBCXX_SSTREAM_ALWAYS_INLINE 961 basic_string_view<char_type, traits_type> 962 view() const noexcept 963 { return _M_stringbuf.view(); } 964 #endif // C++20 965 966 /** 967 * @brief Setting a new buffer. 968 * @param __s The string to use as a new sequence. 969 * 970 * Calls @c rdbuf()->str(s). 971 */ 972 void 973 str(const __string_type& __s) 974 { _M_stringbuf.str(__s); } 975 976 #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI 977 #if __cpp_concepts 978 template<__allocator_like _SAlloc> 979 requires (!is_same_v<_SAlloc, _Alloc>) 980 void 981 str(const basic_string<_CharT, _Traits, _SAlloc>& __s) 982 { _M_stringbuf.str(__s); } 983 #endif 984 985 void 986 str(__string_type&& __s) 987 { _M_stringbuf.str(std::move(__s)); } 988 #endif 989 }; 990 991 992 // [27.7.4] Template class basic_stringstream 993 /** 994 * @brief Controlling input and output for std::string. 995 * @ingroup io 996 * 997 * @tparam _CharT Type of character stream. 998 * @tparam _Traits Traits for character type, defaults to 999 * char_traits<_CharT>. 1000 * @tparam _Alloc Allocator type, defaults to allocator<_CharT>. 1001 * 1002 * This class supports reading from and writing to objects of type 1003 * std::basic_string, using the inherited functions from 1004 * std::basic_iostream. To control the associated sequence, an instance 1005 * of std::basic_stringbuf is used, which this page refers to as @c sb. 1006 */ 1007 template <typename _CharT, typename _Traits, typename _Alloc> 1008 class basic_stringstream : public basic_iostream<_CharT, _Traits> 1009 { 1010 public: 1011 // Types: 1012 typedef _CharT char_type; 1013 typedef _Traits traits_type; 1014 // _GLIBCXX_RESOLVE_LIB_DEFECTS 1015 // 251. basic_stringbuf missing allocator_type 1016 typedef _Alloc allocator_type; 1017 typedef typename traits_type::int_type int_type; 1018 typedef typename traits_type::pos_type pos_type; 1019 typedef typename traits_type::off_type off_type; 1020 1021 // Non-standard Types: 1022 typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 1023 typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type; 1024 typedef basic_iostream<char_type, traits_type> __iostream_type; 1025 1026 private: 1027 __stringbuf_type _M_stringbuf; 1028 1029 public: 1030 // Constructors/destructors 1031 1032 /** 1033 * @brief Default constructor starts with an empty string buffer. 1034 * 1035 * Initializes @c sb using the mode @c in|out, and passes @c &sb 1036 * to the base class initializer. Does not allocate any buffer. 1037 * 1038 * That's a lie. We initialize the base class with NULL, because the 1039 * string class does its own memory management. 1040 */ 1041 basic_stringstream() 1042 : __iostream_type(), _M_stringbuf(ios_base::out | ios_base::in) 1043 { this->init(&_M_stringbuf); } 1044 1045 /** 1046 * @brief Starts with an empty string buffer. 1047 * @param __m Whether the buffer can read, or write, or both. 1048 * 1049 * Initializes @c sb using the mode from @c __m, and passes @c &sb 1050 * to the base class initializer. Does not allocate any buffer. 1051 * 1052 * That's a lie. We initialize the base class with NULL, because the 1053 * string class does its own memory management. 1054 */ 1055 explicit 1056 basic_stringstream(ios_base::openmode __m) 1057 : __iostream_type(), _M_stringbuf(__m) 1058 { this->init(&_M_stringbuf); } 1059 1060 /** 1061 * @brief Starts with an existing string buffer. 1062 * @param __str A string to copy as a starting buffer. 1063 * @param __m Whether the buffer can read, or write, or both. 1064 * 1065 * Initializes @c sb using @a __str and @c __m, and passes @c &sb 1066 * to the base class initializer. 1067 * 1068 * That's a lie. We initialize the base class with NULL, because the 1069 * string class does its own memory management. 1070 */ 1071 explicit 1072 basic_stringstream(const __string_type& __str, 1073 ios_base::openmode __m = ios_base::out | ios_base::in) 1074 : __iostream_type(), _M_stringbuf(__str, __m) 1075 { this->init(&_M_stringbuf); } 1076 1077 /** 1078 * @brief The destructor does nothing. 1079 * 1080 * The buffer is deallocated by the stringbuf object, not the 1081 * formatting stream. 1082 */ 1083 ~basic_stringstream() 1084 { } 1085 1086 #if __cplusplus >= 201103L 1087 basic_stringstream(const basic_stringstream&) = delete; 1088 1089 basic_stringstream(basic_stringstream&& __rhs) 1090 : __iostream_type(std::move(__rhs)), 1091 _M_stringbuf(std::move(__rhs._M_stringbuf)) 1092 { __iostream_type::set_rdbuf(&_M_stringbuf); } 1093 1094 #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI 1095 basic_stringstream(ios_base::openmode __mode, const allocator_type& __a) 1096 : __iostream_type(), _M_stringbuf(__mode, __a) 1097 { this->init(&_M_stringbuf); } 1098 1099 explicit 1100 basic_stringstream(__string_type&& __str, 1101 ios_base::openmode __mode = ios_base::in 1102 | ios_base::out) 1103 : __iostream_type(), _M_stringbuf(std::move(__str), __mode) 1104 { this->init(std::__addressof(_M_stringbuf)); } 1105 1106 template<typename _SAlloc> 1107 basic_stringstream(const basic_string<_CharT, _Traits, _SAlloc>& __str, 1108 const allocator_type& __a) 1109 : basic_stringstream(__str, ios_base::in | ios_base::out, __a) 1110 { } 1111 1112 template<typename _SAlloc> 1113 basic_stringstream(const basic_string<_CharT, _Traits, _SAlloc>& __str, 1114 ios_base::openmode __mode, 1115 const allocator_type& __a) 1116 : __iostream_type(), _M_stringbuf(__str, __mode, __a) 1117 { this->init(std::__addressof(_M_stringbuf)); } 1118 1119 template<typename _SAlloc> 1120 explicit 1121 basic_stringstream(const basic_string<_CharT, _Traits, _SAlloc>& __str, 1122 ios_base::openmode __mode = ios_base::in 1123 | ios_base::out) 1124 : basic_stringstream(__str, __mode, allocator_type()) 1125 { } 1126 #endif // C++20 1127 1128 // 27.8.3.2 Assign and swap: 1129 1130 basic_stringstream& 1131 operator=(const basic_stringstream&) = delete; 1132 1133 basic_stringstream& 1134 operator=(basic_stringstream&& __rhs) 1135 { 1136 __iostream_type::operator=(std::move(__rhs)); 1137 _M_stringbuf = std::move(__rhs._M_stringbuf); 1138 return *this; 1139 } 1140 1141 void 1142 swap(basic_stringstream& __rhs) 1143 { 1144 __iostream_type::swap(__rhs); 1145 _M_stringbuf.swap(__rhs._M_stringbuf); 1146 } 1147 #endif // C++11 1148 1149 // Members: 1150 /** 1151 * @brief Accessing the underlying buffer. 1152 * @return The current basic_stringbuf buffer. 1153 * 1154 * This hides both signatures of std::basic_ios::rdbuf(). 1155 */ 1156 _GLIBCXX_NODISCARD 1157 __stringbuf_type* 1158 rdbuf() const 1159 { return const_cast<__stringbuf_type*>(&_M_stringbuf); } 1160 1161 /** 1162 * @brief Copying out the string buffer. 1163 * @return @c rdbuf()->str() 1164 */ 1165 _GLIBCXX_NODISCARD 1166 __string_type 1167 str() const _GLIBCXX_LVAL_REF_QUAL 1168 { return _M_stringbuf.str(); } 1169 1170 #if __cplusplus > 201703L 1171 #if _GLIBCXX_USE_CXX11_ABI 1172 #if __cpp_concepts 1173 template<__allocator_like _SAlloc> 1174 _GLIBCXX_NODISCARD 1175 basic_string<_CharT, _Traits, _SAlloc> 1176 str(const _SAlloc& __sa) const 1177 { return _M_stringbuf.str(__sa); } 1178 #endif 1179 1180 _GLIBCXX_NODISCARD 1181 __string_type 1182 str() && 1183 { return std::move(_M_stringbuf).str(); } 1184 #endif // cxx11 ABI 1185 1186 _GLIBCXX_SSTREAM_ALWAYS_INLINE 1187 basic_string_view<char_type, traits_type> 1188 view() const noexcept 1189 { return _M_stringbuf.view(); } 1190 #endif // C++20 1191 1192 /** 1193 * @brief Setting a new buffer. 1194 * @param __s The string to use as a new sequence. 1195 * 1196 * Calls @c rdbuf()->str(s). 1197 */ 1198 void 1199 str(const __string_type& __s) 1200 { _M_stringbuf.str(__s); } 1201 1202 #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI 1203 #if __cpp_concepts 1204 template<__allocator_like _SAlloc> 1205 requires (!is_same_v<_SAlloc, _Alloc>) 1206 void 1207 str(const basic_string<_CharT, _Traits, _SAlloc>& __s) 1208 { _M_stringbuf.str(__s); } 1209 #endif 1210 1211 void 1212 str(__string_type&& __s) 1213 { _M_stringbuf.str(std::move(__s)); } 1214 #endif 1215 }; 1216 1217 #if __cplusplus >= 201103L 1218 /// Swap specialization for stringbufs. 1219 template <class _CharT, class _Traits, class _Allocator> 1220 inline void 1221 swap(basic_stringbuf<_CharT, _Traits, _Allocator>& __x, 1222 basic_stringbuf<_CharT, _Traits, _Allocator>& __y) 1223 noexcept(noexcept(__x.swap(__y))) 1224 { __x.swap(__y); } 1225 1226 /// Swap specialization for istringstreams. 1227 template <class _CharT, class _Traits, class _Allocator> 1228 inline void 1229 swap(basic_istringstream<_CharT, _Traits, _Allocator>& __x, 1230 basic_istringstream<_CharT, _Traits, _Allocator>& __y) 1231 { __x.swap(__y); } 1232 1233 /// Swap specialization for ostringstreams. 1234 template <class _CharT, class _Traits, class _Allocator> 1235 inline void 1236 swap(basic_ostringstream<_CharT, _Traits, _Allocator>& __x, 1237 basic_ostringstream<_CharT, _Traits, _Allocator>& __y) 1238 { __x.swap(__y); } 1239 1240 /// Swap specialization for stringstreams. 1241 template <class _CharT, class _Traits, class _Allocator> 1242 inline void 1243 swap(basic_stringstream<_CharT, _Traits, _Allocator>& __x, 1244 basic_stringstream<_CharT, _Traits, _Allocator>& __y) 1245 { __x.swap(__y); } 1246 #endif // C++11 1247 1248 _GLIBCXX_END_NAMESPACE_CXX11 1249 _GLIBCXX_END_NAMESPACE_VERSION 1250 } // namespace 1251 1252 #undef _GLIBCXX_SSTREAM_ALWAYS_INLINE 1253 #undef _GLIBCXX_LVAL_REF_QUAL 1254 1255 #include <bits/sstream.tcc> 1256 1257 #endif /* _GLIBCXX_SSTREAM */