1// String based streams -*- C++ -*- 2 3// Copyright (C) 1997-2016 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#pragma GCC system_header 37 38#include <istream> 39#include <ostream> 40 41namespace std _GLIBCXX_VISIBILITY(default) 42{ 43_GLIBCXX_BEGIN_NAMESPACE_VERSION 44_GLIBCXX_BEGIN_NAMESPACE_CXX11 45 46 // [27.7.1] template class basic_stringbuf 47 /** 48 * @brief The actual work of input and output (for std::string). 49 * @ingroup io 50 * 51 * @tparam _CharT Type of character stream. 52 * @tparam _Traits Traits for character type, defaults to 53 * char_traits<_CharT>. 54 * @tparam _Alloc Allocator type, defaults to allocator<_CharT>. 55 * 56 * This class associates either or both of its input and output sequences 57 * with a sequence of characters, which can be initialized from, or made 58 * available as, a @c std::basic_string. (Paraphrased from [27.7.1]/1.) 59 * 60 * For this class, open modes (of type @c ios_base::openmode) have 61 * @c in set if the input sequence can be read, and @c out set if the 62 * output sequence can be written. 63 */ 64 template<typename _CharT, typename _Traits, typename _Alloc> 65 class basic_stringbuf : public basic_streambuf<_CharT, _Traits> 66 { 67 struct __xfer_bufptrs; 68 public: 69 // Types: 70 typedef _CharT char_type; 71 typedef _Traits traits_type; 72 // _GLIBCXX_RESOLVE_LIB_DEFECTS 73 // 251. basic_stringbuf missing allocator_type 74 typedef _Alloc allocator_type; 75 typedef typename traits_type::int_type int_type; 76 typedef typename traits_type::pos_type pos_type; 77 typedef typename traits_type::off_type off_type; 78 79 typedef basic_streambuf<char_type, traits_type> __streambuf_type; 80 typedef basic_string<char_type, _Traits, _Alloc> __string_type; 81 typedef typename __string_type::size_type __size_type; 82 83 protected: 84 /// Place to stash in || out || in | out settings for current stringbuf. 85 ios_base::openmode _M_mode; 86 87 // Data Members: 88 __string_type _M_string; 89 90 public: 91 // Constructors: 92 /** 93 * @brief Starts with an empty string buffer. 94 * @param __mode Whether the buffer can read, or write, or both. 95 * 96 * The default constructor initializes the parent class using its 97 * own default ctor. 98 */ 99 explicit 100 basic_stringbuf(ios_base::openmode __mode = ios_base::in | ios_base::out) 101 : __streambuf_type(), _M_mode(__mode), _M_string() 102 { } 103 104 /** 105 * @brief Starts with an existing string buffer. 106 * @param __str A string to copy as a starting buffer. 107 * @param __mode Whether the buffer can read, or write, or both. 108 * 109 * This constructor initializes the parent class using its 110 * own default ctor. 111 */ 112 explicit 113 basic_stringbuf(const __string_type& __str, 114 ios_base::openmode __mode = ios_base::in | ios_base::out) 115 : __streambuf_type(), _M_mode(), _M_string(__str.data(), __str.size()) 116 { _M_stringbuf_init(__mode); } 117 118#if __cplusplus >= 201103L 119 basic_stringbuf(const basic_stringbuf&) = delete; 120 121 basic_stringbuf(basic_stringbuf&& __rhs) 122 : basic_stringbuf(std::move(__rhs), __xfer_bufptrs(__rhs, this)) 123 { __rhs._M_sync(const_cast<char_type*>(__rhs._M_string.data()), 0, 0); } 124 125 // 27.8.2.2 Assign and swap: 126 127 basic_stringbuf& 128 operator=(const basic_stringbuf&) = delete; 129 130 basic_stringbuf& 131 operator=(basic_stringbuf&& __rhs) 132 { 133 __xfer_bufptrs __st{__rhs, this}; 134 const __streambuf_type& __base = __rhs; 135 __streambuf_type::operator=(__base); 136 this->pubimbue(__rhs.getloc()); 137 _M_mode = __rhs._M_mode; 138 _M_string = std::move(__rhs._M_string); 139 __rhs._M_sync(const_cast<char_type*>(__rhs._M_string.data()), 0, 0); 140 return *this; 141 } 142 143 void 144 swap(basic_stringbuf& __rhs) 145 { 146 __xfer_bufptrs __l_st{*this, std::__addressof(__rhs)}; 147 __xfer_bufptrs __r_st{__rhs, this}; 148 __streambuf_type& __base = __rhs; 149 __streambuf_type::swap(__base); 150 __rhs.pubimbue(this->pubimbue(__rhs.getloc())); 151 std::swap(_M_mode, __rhs._M_mode); 152 std::swap(_M_string, __rhs._M_string); 153 } 154#endif 155 156 // Get and set: 157 /** 158 * @brief Copying out the string buffer. 159 * @return A copy of one of the underlying sequences. 160 * 161 * <em>If the buffer is only created in input mode, the underlying 162 * character sequence is equal to the input sequence; otherwise, it 163 * is equal to the output sequence.</em> [27.7.1.2]/1 164 */ 165 __string_type 166 str() const 167 { 168 __string_type __ret; 169 if (this->pptr()) 170 { 171 // The current egptr() may not be the actual string end. 172 if (this->pptr() > this->egptr()) 173 __ret = __string_type(this->pbase(), this->pptr()); 174 else 175 __ret = __string_type(this->pbase(), this->egptr()); 176 } 177 else 178 __ret = _M_string; 179 return __ret; 180 } 181 182 /** 183 * @brief Setting a new buffer. 184 * @param __s The string to use as a new sequence. 185 * 186 * Deallocates any previous stored sequence, then copies @a s to 187 * use as a new one. 188 */ 189 void 190 str(const __string_type& __s) 191 { 192 // Cannot use _M_string = __s, since v3 strings are COW 193 // (not always true now but assign() always works). 194 _M_string.assign(__s.data(), __s.size()); 195 _M_stringbuf_init(_M_mode); 196 } 197 198 protected: 199 // Common initialization code goes here. 200 void 201 _M_stringbuf_init(ios_base::openmode __mode) 202 { 203 _M_mode = __mode; 204 __size_type __len = 0; 205 if (_M_mode & (ios_base::ate | ios_base::app)) 206 __len = _M_string.size(); 207 _M_sync(const_cast<char_type*>(_M_string.data()), 0, __len); 208 } 209 210 virtual streamsize 211 showmanyc() 212 { 213 streamsize __ret = -1; 214 if (_M_mode & ios_base::in) 215 { 216 _M_update_egptr(); 217 __ret = this->egptr() - this->gptr(); 218 } 219 return __ret; 220 } 221 222 virtual int_type 223 underflow(); 224 225 virtual int_type 226 pbackfail(int_type __c = traits_type::eof()); 227 228 virtual int_type 229 overflow(int_type __c = traits_type::eof()); 230 231 /** 232 * @brief Manipulates the buffer. 233 * @param __s Pointer to a buffer area. 234 * @param __n Size of @a __s. 235 * @return @c this 236 * 237 * If no buffer has already been created, and both @a __s and @a __n are 238 * non-zero, then @c __s is used as a buffer; see 239 * https://gcc.gnu.org/onlinedocs/libstdc++/manual/streambufs.html#io.streambuf.buffering 240 * for more. 241 */ 242 virtual __streambuf_type* 243 setbuf(char_type* __s, streamsize __n) 244 { 245 if (__s && __n >= 0) 246 { 247 // This is implementation-defined behavior, and assumes 248 // that an external char_type array of length __n exists 249 // and has been pre-allocated. If this is not the case, 250 // things will quickly blow up. 251 252 // Step 1: Destroy the current internal array. 253 _M_string.clear(); 254 255 // Step 2: Use the external array. 256 _M_sync(__s, __n, 0); 257 } 258 return this; 259 } 260 261 virtual pos_type 262 seekoff(off_type __off, ios_base::seekdir __way, 263 ios_base::openmode __mode = ios_base::in | ios_base::out); 264 265 virtual pos_type 266 seekpos(pos_type __sp, 267 ios_base::openmode __mode = ios_base::in | ios_base::out); 268 269 // Internal function for correctly updating the internal buffer 270 // for a particular _M_string, due to initialization or re-sizing 271 // of an existing _M_string. 272 void 273 _M_sync(char_type* __base, __size_type __i, __size_type __o); 274 275 // Internal function for correctly updating egptr() to the actual 276 // string end. 277 void 278 _M_update_egptr() 279 { 280 const bool __testin = _M_mode & ios_base::in; 281 if (this->pptr() && this->pptr() > this->egptr()) 282 { 283 if (__testin) 284 this->setg(this->eback(), this->gptr(), this->pptr()); 285 else 286 this->setg(this->pptr(), this->pptr(), this->pptr()); 287 } 288 } 289 290 // Works around the issue with pbump, part of the protected 291 // interface of basic_streambuf, taking just an int. 292 void 293 _M_pbump(char_type* __pbeg, char_type* __pend, off_type __off); 294 295 private: 296#if __cplusplus >= 201103L 297#if _GLIBCXX_USE_CXX11_ABI 298 // This type captures the state of the gptr / pptr pointers as offsets 299 // so they can be restored in another object after moving the string. 300 struct __xfer_bufptrs 301 { 302 __xfer_bufptrs(const basic_stringbuf& __from, basic_stringbuf* __to) 303 : _M_to{__to}, _M_goff{-1, -1, -1}, _M_poff{-1, -1, -1} 304 { 305 const _CharT* __str = __from._M_string.data(); 306 if (__from.eback()) 307 { 308 _M_goff[0] = __from.eback() - __str; 309 _M_goff[1] = __from.gptr() - __str; 310 _M_goff[2] = __from.egptr() - __str; 311 } 312 if (__from.pbase()) 313 { 314 _M_poff[0] = __from.pbase() - __str; 315 _M_poff[1] = __from.pptr() - __from.pbase(); 316 _M_poff[2] = __from.epptr() - __str; 317 } 318 } 319 320 ~__xfer_bufptrs() 321 { 322 char_type* __str = const_cast<char_type*>(_M_to->_M_string.data()); 323 if (_M_goff[0] != -1) 324 _M_to->setg(__str+_M_goff[0], __str+_M_goff[1], __str+_M_goff[2]); 325 if (_M_poff[0] != -1) 326 _M_to->_M_pbump(__str+_M_poff[0], __str+_M_poff[2], _M_poff[1]); 327 } 328 329 basic_stringbuf* _M_to; 330 off_type _M_goff[3]; 331 off_type _M_poff[3]; 332 }; 333#else 334 // This type does nothing when using Copy-On-Write strings. 335 struct __xfer_bufptrs 336 { 337 __xfer_bufptrs(const basic_stringbuf&, basic_stringbuf*) { } 338 }; 339#endif 340 341 // The move constructor initializes an __xfer_bufptrs temporary then 342 // delegates to this constructor to performs moves during its lifetime. 343 basic_stringbuf(basic_stringbuf&& __rhs, __xfer_bufptrs&&) 344 : __streambuf_type(static_cast<const __streambuf_type&>(__rhs)), 345 _M_mode(__rhs._M_mode), _M_string(std::move(__rhs._M_string)) 346 { } 347#endif 348 }; 349 350 351 // [27.7.2] Template class basic_istringstream 352 /** 353 * @brief Controlling input for std::string. 354 * @ingroup io 355 * 356 * @tparam _CharT Type of character stream. 357 * @tparam _Traits Traits for character type, defaults to 358 * char_traits<_CharT>. 359 * @tparam _Alloc Allocator type, defaults to allocator<_CharT>. 360 * 361 * This class supports reading from objects of type std::basic_string, 362 * using the inherited functions from std::basic_istream. To control 363 * the associated sequence, an instance of std::basic_stringbuf is used, 364 * which this page refers to as @c sb. 365 */ 366 template<typename _CharT, typename _Traits, typename _Alloc> 367 class basic_istringstream : public basic_istream<_CharT, _Traits> 368 { 369 public: 370 // Types: 371 typedef _CharT char_type; 372 typedef _Traits traits_type; 373 // _GLIBCXX_RESOLVE_LIB_DEFECTS 374 // 251. basic_stringbuf missing allocator_type 375 typedef _Alloc allocator_type; 376 typedef typename traits_type::int_type int_type; 377 typedef typename traits_type::pos_type pos_type; 378 typedef typename traits_type::off_type off_type; 379 380 // Non-standard types: 381 typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 382 typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type; 383 typedef basic_istream<char_type, traits_type> __istream_type; 384 385 private: 386 __stringbuf_type _M_stringbuf; 387 388 public: 389 // Constructors: 390 /** 391 * @brief Default constructor starts with an empty string buffer. 392 * @param __mode Whether the buffer can read, or write, or both. 393 * 394 * @c ios_base::in is automatically included in @a __mode. 395 * 396 * Initializes @c sb using @c __mode|in, and passes @c &sb to the base 397 * class initializer. Does not allocate any buffer. 398 * 399 * That's a lie. We initialize the base class with NULL, because the 400 * string class does its own memory management. 401 */ 402 explicit 403 basic_istringstream(ios_base::openmode __mode = ios_base::in) 404 : __istream_type(), _M_stringbuf(__mode | ios_base::in) 405 { this->init(&_M_stringbuf); } 406 407 /** 408 * @brief Starts with an existing string buffer. 409 * @param __str A string to copy as a starting buffer. 410 * @param __mode Whether the buffer can read, or write, or both. 411 * 412 * @c ios_base::in is automatically included in @a mode. 413 * 414 * Initializes @c sb using @a str and @c mode|in, and passes @c &sb 415 * to the base class initializer. 416 * 417 * That's a lie. We initialize the base class with NULL, because the 418 * string class does its own memory management. 419 */ 420 explicit 421 basic_istringstream(const __string_type& __str, 422 ios_base::openmode __mode = ios_base::in) 423 : __istream_type(), _M_stringbuf(__str, __mode | ios_base::in) 424 { this->init(&_M_stringbuf); } 425 426 /** 427 * @brief The destructor does nothing. 428 * 429 * The buffer is deallocated by the stringbuf object, not the 430 * formatting stream. 431 */ 432 ~basic_istringstream() 433 { } 434 435#if __cplusplus >= 201103L 436 basic_istringstream(const basic_istringstream&) = delete; 437 438 basic_istringstream(basic_istringstream&& __rhs) 439 : __istream_type(std::move(__rhs)), 440 _M_stringbuf(std::move(__rhs._M_stringbuf)) 441 { __istream_type::set_rdbuf(&_M_stringbuf); } 442 443 // 27.8.3.2 Assign and swap: 444 445 basic_istringstream& 446 operator=(const basic_istringstream&) = delete; 447 448 basic_istringstream& 449 operator=(basic_istringstream&& __rhs) 450 { 451 __istream_type::operator=(std::move(__rhs)); 452 _M_stringbuf = std::move(__rhs._M_stringbuf); 453 return *this; 454 } 455 456 void 457 swap(basic_istringstream& __rhs) 458 { 459 __istream_type::swap(__rhs); 460 _M_stringbuf.swap(__rhs._M_stringbuf); 461 } 462#endif 463 464 // Members: 465 /** 466 * @brief Accessing the underlying buffer. 467 * @return The current basic_stringbuf buffer. 468 * 469 * This hides both signatures of std::basic_ios::rdbuf(). 470 */ 471 __stringbuf_type* 472 rdbuf() const 473 { return const_cast<__stringbuf_type*>(&_M_stringbuf); } 474 475 /** 476 * @brief Copying out the string buffer. 477 * @return @c rdbuf()->str() 478 */ 479 __string_type 480 str() const 481 { return _M_stringbuf.str(); } 482 483 /** 484 * @brief Setting a new buffer. 485 * @param __s The string to use as a new sequence. 486 * 487 * Calls @c rdbuf()->str(s). 488 */ 489 void 490 str(const __string_type& __s) 491 { _M_stringbuf.str(__s); } 492 }; 493 494 495 // [27.7.3] Template class basic_ostringstream 496 /** 497 * @brief Controlling output for std::string. 498 * @ingroup io 499 * 500 * @tparam _CharT Type of character stream. 501 * @tparam _Traits Traits for character type, defaults to 502 * char_traits<_CharT>. 503 * @tparam _Alloc Allocator type, defaults to allocator<_CharT>. 504 * 505 * This class supports writing to objects of type std::basic_string, 506 * using the inherited functions from std::basic_ostream. To control 507 * the associated sequence, an instance of std::basic_stringbuf is used, 508 * which this page refers to as @c sb. 509 */ 510 template <typename _CharT, typename _Traits, typename _Alloc> 511 class basic_ostringstream : public basic_ostream<_CharT, _Traits> 512 { 513 public: 514 // Types: 515 typedef _CharT char_type; 516 typedef _Traits traits_type; 517 // _GLIBCXX_RESOLVE_LIB_DEFECTS 518 // 251. basic_stringbuf missing allocator_type 519 typedef _Alloc allocator_type; 520 typedef typename traits_type::int_type int_type; 521 typedef typename traits_type::pos_type pos_type; 522 typedef typename traits_type::off_type off_type; 523 524 // Non-standard types: 525 typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 526 typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type; 527 typedef basic_ostream<char_type, traits_type> __ostream_type; 528 529 private: 530 __stringbuf_type _M_stringbuf; 531 532 public: 533 // Constructors/destructor: 534 /** 535 * @brief Default constructor starts with an empty string buffer. 536 * @param __mode Whether the buffer can read, or write, or both. 537 * 538 * @c ios_base::out is automatically included in @a mode. 539 * 540 * Initializes @c sb using @c mode|out, and passes @c &sb to the base 541 * class initializer. Does not allocate any buffer. 542 * 543 * That's a lie. We initialize the base class with NULL, because the 544 * string class does its own memory management. 545 */ 546 explicit 547 basic_ostringstream(ios_base::openmode __mode = ios_base::out) 548 : __ostream_type(), _M_stringbuf(__mode | ios_base::out) 549 { this->init(&_M_stringbuf); } 550 551 /** 552 * @brief Starts with an existing string buffer. 553 * @param __str A string to copy as a starting buffer. 554 * @param __mode Whether the buffer can read, or write, or both. 555 * 556 * @c ios_base::out is automatically included in @a mode. 557 * 558 * Initializes @c sb using @a str and @c mode|out, and passes @c &sb 559 * to the base class initializer. 560 * 561 * That's a lie. We initialize the base class with NULL, because the 562 * string class does its own memory management. 563 */ 564 explicit 565 basic_ostringstream(const __string_type& __str, 566 ios_base::openmode __mode = ios_base::out) 567 : __ostream_type(), _M_stringbuf(__str, __mode | ios_base::out) 568 { this->init(&_M_stringbuf); } 569 570 /** 571 * @brief The destructor does nothing. 572 * 573 * The buffer is deallocated by the stringbuf object, not the 574 * formatting stream. 575 */ 576 ~basic_ostringstream() 577 { } 578 579#if __cplusplus >= 201103L 580 basic_ostringstream(const basic_ostringstream&) = delete; 581 582 basic_ostringstream(basic_ostringstream&& __rhs) 583 : __ostream_type(std::move(__rhs)), 584 _M_stringbuf(std::move(__rhs._M_stringbuf)) 585 { __ostream_type::set_rdbuf(&_M_stringbuf); } 586 587 // 27.8.3.2 Assign and swap: 588 589 basic_ostringstream& 590 operator=(const basic_ostringstream&) = delete; 591 592 basic_ostringstream& 593 operator=(basic_ostringstream&& __rhs) 594 { 595 __ostream_type::operator=(std::move(__rhs)); 596 _M_stringbuf = std::move(__rhs._M_stringbuf); 597 return *this; 598 } 599 600 void 601 swap(basic_ostringstream& __rhs) 602 { 603 __ostream_type::swap(__rhs); 604 _M_stringbuf.swap(__rhs._M_stringbuf); 605 } 606#endif 607 608 // Members: 609 /** 610 * @brief Accessing the underlying buffer. 611 * @return The current basic_stringbuf buffer. 612 * 613 * This hides both signatures of std::basic_ios::rdbuf(). 614 */ 615 __stringbuf_type* 616 rdbuf() const 617 { return const_cast<__stringbuf_type*>(&_M_stringbuf); } 618 619 /** 620 * @brief Copying out the string buffer. 621 * @return @c rdbuf()->str() 622 */ 623 __string_type 624 str() const 625 { return _M_stringbuf.str(); } 626 627 /** 628 * @brief Setting a new buffer. 629 * @param __s The string to use as a new sequence. 630 * 631 * Calls @c rdbuf()->str(s). 632 */ 633 void 634 str(const __string_type& __s) 635 { _M_stringbuf.str(__s); } 636 }; 637 638 639 // [27.7.4] Template class basic_stringstream 640 /** 641 * @brief Controlling input and output for std::string. 642 * @ingroup io 643 * 644 * @tparam _CharT Type of character stream. 645 * @tparam _Traits Traits for character type, defaults to 646 * char_traits<_CharT>. 647 * @tparam _Alloc Allocator type, defaults to allocator<_CharT>. 648 * 649 * This class supports reading from and writing to objects of type 650 * std::basic_string, using the inherited functions from 651 * std::basic_iostream. To control the associated sequence, an instance 652 * of std::basic_stringbuf is used, which this page refers to as @c sb. 653 */ 654 template <typename _CharT, typename _Traits, typename _Alloc> 655 class basic_stringstream : public basic_iostream<_CharT, _Traits> 656 { 657 public: 658 // Types: 659 typedef _CharT char_type; 660 typedef _Traits traits_type; 661 // _GLIBCXX_RESOLVE_LIB_DEFECTS 662 // 251. basic_stringbuf missing allocator_type 663 typedef _Alloc allocator_type; 664 typedef typename traits_type::int_type int_type; 665 typedef typename traits_type::pos_type pos_type; 666 typedef typename traits_type::off_type off_type; 667 668 // Non-standard Types: 669 typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 670 typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type; 671 typedef basic_iostream<char_type, traits_type> __iostream_type; 672 673 private: 674 __stringbuf_type _M_stringbuf; 675 676 public: 677 // Constructors/destructors 678 /** 679 * @brief Default constructor starts with an empty string buffer. 680 * @param __m Whether the buffer can read, or write, or both. 681 * 682 * Initializes @c sb using the mode from @c __m, and passes @c 683 * &sb to the base class initializer. Does not allocate any 684 * buffer. 685 * 686 * That's a lie. We initialize the base class with NULL, because the 687 * string class does its own memory management. 688 */ 689 explicit 690 basic_stringstream(ios_base::openmode __m = ios_base::out | ios_base::in) 691 : __iostream_type(), _M_stringbuf(__m) 692 { this->init(&_M_stringbuf); } 693 694 /** 695 * @brief Starts with an existing string buffer. 696 * @param __str A string to copy as a starting buffer. 697 * @param __m Whether the buffer can read, or write, or both. 698 * 699 * Initializes @c sb using @a __str and @c __m, and passes @c &sb 700 * to the base class initializer. 701 * 702 * That's a lie. We initialize the base class with NULL, because the 703 * string class does its own memory management. 704 */ 705 explicit 706 basic_stringstream(const __string_type& __str, 707 ios_base::openmode __m = ios_base::out | ios_base::in) 708 : __iostream_type(), _M_stringbuf(__str, __m) 709 { this->init(&_M_stringbuf); } 710 711 /** 712 * @brief The destructor does nothing. 713 * 714 * The buffer is deallocated by the stringbuf object, not the 715 * formatting stream. 716 */ 717 ~basic_stringstream() 718 { } 719 720#if __cplusplus >= 201103L 721 basic_stringstream(const basic_stringstream&) = delete; 722 723 basic_stringstream(basic_stringstream&& __rhs) 724 : __iostream_type(std::move(__rhs)), 725 _M_stringbuf(std::move(__rhs._M_stringbuf)) 726 { __iostream_type::set_rdbuf(&_M_stringbuf); } 727 728 // 27.8.3.2 Assign and swap: 729 730 basic_stringstream& 731 operator=(const basic_stringstream&) = delete; 732 733 basic_stringstream& 734 operator=(basic_stringstream&& __rhs) 735 { 736 __iostream_type::operator=(std::move(__rhs)); 737 _M_stringbuf = std::move(__rhs._M_stringbuf); 738 return *this; 739 } 740 741 void 742 swap(basic_stringstream& __rhs) 743 { 744 __iostream_type::swap(__rhs); 745 _M_stringbuf.swap(__rhs._M_stringbuf); 746 } 747#endif 748 749 // Members: 750 /** 751 * @brief Accessing the underlying buffer. 752 * @return The current basic_stringbuf buffer. 753 * 754 * This hides both signatures of std::basic_ios::rdbuf(). 755 */ 756 __stringbuf_type* 757 rdbuf() const 758 { return const_cast<__stringbuf_type*>(&_M_stringbuf); } 759 760 /** 761 * @brief Copying out the string buffer. 762 * @return @c rdbuf()->str() 763 */ 764 __string_type 765 str() const 766 { return _M_stringbuf.str(); } 767 768 /** 769 * @brief Setting a new buffer. 770 * @param __s The string to use as a new sequence. 771 * 772 * Calls @c rdbuf()->str(s). 773 */ 774 void 775 str(const __string_type& __s) 776 { _M_stringbuf.str(__s); } 777 }; 778 779#if __cplusplus >= 201103L 780 /// Swap specialization for stringbufs. 781 template <class _CharT, class _Traits, class _Allocator> 782 inline void 783 swap(basic_stringbuf<_CharT, _Traits, _Allocator>& __x, 784 basic_stringbuf<_CharT, _Traits, _Allocator>& __y) 785 { __x.swap(__y); } 786 787 /// Swap specialization for istringstreams. 788 template <class _CharT, class _Traits, class _Allocator> 789 inline void 790 swap(basic_istringstream<_CharT, _Traits, _Allocator>& __x, 791 basic_istringstream<_CharT, _Traits, _Allocator>& __y) 792 { __x.swap(__y); } 793 794 /// Swap specialization for ostringstreams. 795 template <class _CharT, class _Traits, class _Allocator> 796 inline void 797 swap(basic_ostringstream<_CharT, _Traits, _Allocator>& __x, 798 basic_ostringstream<_CharT, _Traits, _Allocator>& __y) 799 { __x.swap(__y); } 800 801 /// Swap specialization for stringstreams. 802 template <class _CharT, class _Traits, class _Allocator> 803 inline void 804 swap(basic_stringstream<_CharT, _Traits, _Allocator>& __x, 805 basic_stringstream<_CharT, _Traits, _Allocator>& __y) 806 { __x.swap(__y); } 807#endif 808 809_GLIBCXX_END_NAMESPACE_CXX11 810_GLIBCXX_END_NAMESPACE_VERSION 811} // namespace 812 813#include <bits/sstream.tcc> 814 815#endif /* _GLIBCXX_SSTREAM */ 816