libstdc++
|
00001 // String based streams -*- C++ -*- 00002 00003 // Copyright (C) 1997-2019 Free Software Foundation, Inc. 00004 // 00005 // This file is part of the GNU ISO C++ Library. This library is free 00006 // software; you can redistribute it and/or modify it under the 00007 // terms of the GNU General Public License as published by the 00008 // Free Software Foundation; either version 3, or (at your option) 00009 // any later version. 00010 00011 // This library is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 // GNU General Public License for more details. 00015 00016 // Under Section 7 of GPL version 3, you are granted additional 00017 // permissions described in the GCC Runtime Library Exception, version 00018 // 3.1, as published by the Free Software Foundation. 00019 00020 // You should have received a copy of the GNU General Public License and 00021 // a copy of the GCC Runtime Library Exception along with this program; 00022 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 00023 // <http://www.gnu.org/licenses/>. 00024 00025 /** @file include/sstream 00026 * This is a Standard C++ Library header. 00027 */ 00028 00029 // 00030 // ISO C++ 14882: 27.7 String-based streams 00031 // 00032 00033 #ifndef _GLIBCXX_SSTREAM 00034 #define _GLIBCXX_SSTREAM 1 00035 00036 #pragma GCC system_header 00037 00038 #include <istream> 00039 #include <ostream> 00040 00041 namespace std _GLIBCXX_VISIBILITY(default) 00042 { 00043 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00044 _GLIBCXX_BEGIN_NAMESPACE_CXX11 00045 00046 // [27.7.1] template class basic_stringbuf 00047 /** 00048 * @brief The actual work of input and output (for std::string). 00049 * @ingroup io 00050 * 00051 * @tparam _CharT Type of character stream. 00052 * @tparam _Traits Traits for character type, defaults to 00053 * char_traits<_CharT>. 00054 * @tparam _Alloc Allocator type, defaults to allocator<_CharT>. 00055 * 00056 * This class associates either or both of its input and output sequences 00057 * with a sequence of characters, which can be initialized from, or made 00058 * available as, a @c std::basic_string. (Paraphrased from [27.7.1]/1.) 00059 * 00060 * For this class, open modes (of type @c ios_base::openmode) have 00061 * @c in set if the input sequence can be read, and @c out set if the 00062 * output sequence can be written. 00063 */ 00064 template<typename _CharT, typename _Traits, typename _Alloc> 00065 class basic_stringbuf : public basic_streambuf<_CharT, _Traits> 00066 { 00067 struct __xfer_bufptrs; 00068 public: 00069 // Types: 00070 typedef _CharT char_type; 00071 typedef _Traits traits_type; 00072 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00073 // 251. basic_stringbuf missing allocator_type 00074 typedef _Alloc allocator_type; 00075 typedef typename traits_type::int_type int_type; 00076 typedef typename traits_type::pos_type pos_type; 00077 typedef typename traits_type::off_type off_type; 00078 00079 typedef basic_streambuf<char_type, traits_type> __streambuf_type; 00080 typedef basic_string<char_type, _Traits, _Alloc> __string_type; 00081 typedef typename __string_type::size_type __size_type; 00082 00083 protected: 00084 /// Place to stash in || out || in | out settings for current stringbuf. 00085 ios_base::openmode _M_mode; 00086 00087 // Data Members: 00088 __string_type _M_string; 00089 00090 public: 00091 // Constructors: 00092 00093 /** 00094 * @brief Starts with an empty string buffer. 00095 * 00096 * The default constructor initializes the parent class using its 00097 * own default ctor. 00098 */ 00099 basic_stringbuf() 00100 : __streambuf_type(), _M_mode(ios_base::in | ios_base::out), _M_string() 00101 { } 00102 00103 /** 00104 * @brief Starts with an empty string buffer. 00105 * @param __mode Whether the buffer can read, or write, or both. 00106 * 00107 * The default constructor initializes the parent class using its 00108 * own default ctor. 00109 */ 00110 explicit 00111 basic_stringbuf(ios_base::openmode __mode) 00112 : __streambuf_type(), _M_mode(__mode), _M_string() 00113 { } 00114 00115 /** 00116 * @brief Starts with an existing string buffer. 00117 * @param __str A string to copy as a starting buffer. 00118 * @param __mode Whether the buffer can read, or write, or both. 00119 * 00120 * This constructor initializes the parent class using its 00121 * own default ctor. 00122 */ 00123 explicit 00124 basic_stringbuf(const __string_type& __str, 00125 ios_base::openmode __mode = ios_base::in | ios_base::out) 00126 : __streambuf_type(), _M_mode(), 00127 _M_string(__str.data(), __str.size(), __str.get_allocator()) 00128 { _M_stringbuf_init(__mode); } 00129 00130 #if __cplusplus >= 201103L 00131 basic_stringbuf(const basic_stringbuf&) = delete; 00132 00133 basic_stringbuf(basic_stringbuf&& __rhs) 00134 : basic_stringbuf(std::move(__rhs), __xfer_bufptrs(__rhs, this)) 00135 { __rhs._M_sync(const_cast<char_type*>(__rhs._M_string.data()), 0, 0); } 00136 00137 // 27.8.2.2 Assign and swap: 00138 00139 basic_stringbuf& 00140 operator=(const basic_stringbuf&) = delete; 00141 00142 basic_stringbuf& 00143 operator=(basic_stringbuf&& __rhs) 00144 { 00145 __xfer_bufptrs __st{__rhs, this}; 00146 const __streambuf_type& __base = __rhs; 00147 __streambuf_type::operator=(__base); 00148 this->pubimbue(__rhs.getloc()); 00149 _M_mode = __rhs._M_mode; 00150 _M_string = std::move(__rhs._M_string); 00151 __rhs._M_sync(const_cast<char_type*>(__rhs._M_string.data()), 0, 0); 00152 return *this; 00153 } 00154 00155 void 00156 swap(basic_stringbuf& __rhs) 00157 { 00158 __xfer_bufptrs __l_st{*this, std::__addressof(__rhs)}; 00159 __xfer_bufptrs __r_st{__rhs, this}; 00160 __streambuf_type& __base = __rhs; 00161 __streambuf_type::swap(__base); 00162 __rhs.pubimbue(this->pubimbue(__rhs.getloc())); 00163 std::swap(_M_mode, __rhs._M_mode); 00164 std::swap(_M_string, __rhs._M_string); 00165 } 00166 #endif 00167 00168 // Get and set: 00169 /** 00170 * @brief Copying out the string buffer. 00171 * @return A copy of one of the underlying sequences. 00172 * 00173 * <em>If the buffer is only created in input mode, the underlying 00174 * character sequence is equal to the input sequence; otherwise, it 00175 * is equal to the output sequence.</em> [27.7.1.2]/1 00176 */ 00177 __string_type 00178 str() const 00179 { 00180 __string_type __ret(_M_string.get_allocator()); 00181 if (this->pptr()) 00182 { 00183 // The current egptr() may not be the actual string end. 00184 if (this->pptr() > this->egptr()) 00185 __ret.assign(this->pbase(), this->pptr()); 00186 else 00187 __ret.assign(this->pbase(), this->egptr()); 00188 } 00189 else 00190 __ret = _M_string; 00191 return __ret; 00192 } 00193 00194 /** 00195 * @brief Setting a new buffer. 00196 * @param __s The string to use as a new sequence. 00197 * 00198 * Deallocates any previous stored sequence, then copies @a s to 00199 * use as a new one. 00200 */ 00201 void 00202 str(const __string_type& __s) 00203 { 00204 // Cannot use _M_string = __s, since v3 strings are COW 00205 // (not always true now but assign() always works). 00206 _M_string.assign(__s.data(), __s.size()); 00207 _M_stringbuf_init(_M_mode); 00208 } 00209 00210 protected: 00211 // Common initialization code goes here. 00212 void 00213 _M_stringbuf_init(ios_base::openmode __mode) 00214 { 00215 _M_mode = __mode; 00216 __size_type __len = 0; 00217 if (_M_mode & (ios_base::ate | ios_base::app)) 00218 __len = _M_string.size(); 00219 _M_sync(const_cast<char_type*>(_M_string.data()), 0, __len); 00220 } 00221 00222 virtual streamsize 00223 showmanyc() 00224 { 00225 streamsize __ret = -1; 00226 if (_M_mode & ios_base::in) 00227 { 00228 _M_update_egptr(); 00229 __ret = this->egptr() - this->gptr(); 00230 } 00231 return __ret; 00232 } 00233 00234 virtual int_type 00235 underflow(); 00236 00237 virtual int_type 00238 pbackfail(int_type __c = traits_type::eof()); 00239 00240 virtual int_type 00241 overflow(int_type __c = traits_type::eof()); 00242 00243 /** 00244 * @brief Manipulates the buffer. 00245 * @param __s Pointer to a buffer area. 00246 * @param __n Size of @a __s. 00247 * @return @c this 00248 * 00249 * If no buffer has already been created, and both @a __s and @a __n are 00250 * non-zero, then @c __s is used as a buffer; see 00251 * https://gcc.gnu.org/onlinedocs/libstdc++/manual/streambufs.html#io.streambuf.buffering 00252 * for more. 00253 */ 00254 virtual __streambuf_type* 00255 setbuf(char_type* __s, streamsize __n) 00256 { 00257 if (__s && __n >= 0) 00258 { 00259 // This is implementation-defined behavior, and assumes 00260 // that an external char_type array of length __n exists 00261 // and has been pre-allocated. If this is not the case, 00262 // things will quickly blow up. 00263 00264 // Step 1: Destroy the current internal array. 00265 _M_string.clear(); 00266 00267 // Step 2: Use the external array. 00268 _M_sync(__s, __n, 0); 00269 } 00270 return this; 00271 } 00272 00273 virtual pos_type 00274 seekoff(off_type __off, ios_base::seekdir __way, 00275 ios_base::openmode __mode = ios_base::in | ios_base::out); 00276 00277 virtual pos_type 00278 seekpos(pos_type __sp, 00279 ios_base::openmode __mode = ios_base::in | ios_base::out); 00280 00281 // Internal function for correctly updating the internal buffer 00282 // for a particular _M_string, due to initialization or re-sizing 00283 // of an existing _M_string. 00284 void 00285 _M_sync(char_type* __base, __size_type __i, __size_type __o); 00286 00287 // Internal function for correctly updating egptr() to the actual 00288 // string end. 00289 void 00290 _M_update_egptr() 00291 { 00292 const bool __testin = _M_mode & ios_base::in; 00293 if (this->pptr() && this->pptr() > this->egptr()) 00294 { 00295 if (__testin) 00296 this->setg(this->eback(), this->gptr(), this->pptr()); 00297 else 00298 this->setg(this->pptr(), this->pptr(), this->pptr()); 00299 } 00300 } 00301 00302 // Works around the issue with pbump, part of the protected 00303 // interface of basic_streambuf, taking just an int. 00304 void 00305 _M_pbump(char_type* __pbeg, char_type* __pend, off_type __off); 00306 00307 private: 00308 #if __cplusplus >= 201103L 00309 #if _GLIBCXX_USE_CXX11_ABI 00310 // This type captures the state of the gptr / pptr pointers as offsets 00311 // so they can be restored in another object after moving the string. 00312 struct __xfer_bufptrs 00313 { 00314 __xfer_bufptrs(const basic_stringbuf& __from, basic_stringbuf* __to) 00315 : _M_to{__to}, _M_goff{-1, -1, -1}, _M_poff{-1, -1, -1} 00316 { 00317 const _CharT* const __str = __from._M_string.data(); 00318 const _CharT* __end = nullptr; 00319 if (__from.eback()) 00320 { 00321 _M_goff[0] = __from.eback() - __str; 00322 _M_goff[1] = __from.gptr() - __str; 00323 _M_goff[2] = __from.egptr() - __str; 00324 __end = __from.egptr(); 00325 } 00326 if (__from.pbase()) 00327 { 00328 _M_poff[0] = __from.pbase() - __str; 00329 _M_poff[1] = __from.pptr() - __from.pbase(); 00330 _M_poff[2] = __from.epptr() - __str; 00331 if (__from.pptr() > __end) 00332 __end = __from.pptr(); 00333 } 00334 00335 // Set _M_string length to the greater of the get and put areas. 00336 if (__end) 00337 { 00338 // The const_cast avoids changing this constructor's signature, 00339 // because it is exported from the dynamic library. 00340 auto& __mut_from = const_cast<basic_stringbuf&>(__from); 00341 __mut_from._M_string._M_length(__end - __str); 00342 } 00343 } 00344 00345 ~__xfer_bufptrs() 00346 { 00347 char_type* __str = const_cast<char_type*>(_M_to->_M_string.data()); 00348 if (_M_goff[0] != -1) 00349 _M_to->setg(__str+_M_goff[0], __str+_M_goff[1], __str+_M_goff[2]); 00350 if (_M_poff[0] != -1) 00351 _M_to->_M_pbump(__str+_M_poff[0], __str+_M_poff[2], _M_poff[1]); 00352 } 00353 00354 basic_stringbuf* _M_to; 00355 off_type _M_goff[3]; 00356 off_type _M_poff[3]; 00357 }; 00358 #else 00359 // This type does nothing when using Copy-On-Write strings. 00360 struct __xfer_bufptrs 00361 { 00362 __xfer_bufptrs(const basic_stringbuf&, basic_stringbuf*) { } 00363 }; 00364 #endif 00365 00366 // The move constructor initializes an __xfer_bufptrs temporary then 00367 // delegates to this constructor to performs moves during its lifetime. 00368 basic_stringbuf(basic_stringbuf&& __rhs, __xfer_bufptrs&&) 00369 : __streambuf_type(static_cast<const __streambuf_type&>(__rhs)), 00370 _M_mode(__rhs._M_mode), _M_string(std::move(__rhs._M_string)) 00371 { } 00372 #endif 00373 }; 00374 00375 00376 // [27.7.2] Template class basic_istringstream 00377 /** 00378 * @brief Controlling input for std::string. 00379 * @ingroup io 00380 * 00381 * @tparam _CharT Type of character stream. 00382 * @tparam _Traits Traits for character type, defaults to 00383 * char_traits<_CharT>. 00384 * @tparam _Alloc Allocator type, defaults to allocator<_CharT>. 00385 * 00386 * This class supports reading from objects of type std::basic_string, 00387 * using the inherited functions from std::basic_istream. To control 00388 * the associated sequence, an instance of std::basic_stringbuf is used, 00389 * which this page refers to as @c sb. 00390 */ 00391 template<typename _CharT, typename _Traits, typename _Alloc> 00392 class basic_istringstream : public basic_istream<_CharT, _Traits> 00393 { 00394 public: 00395 // Types: 00396 typedef _CharT char_type; 00397 typedef _Traits traits_type; 00398 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00399 // 251. basic_stringbuf missing allocator_type 00400 typedef _Alloc allocator_type; 00401 typedef typename traits_type::int_type int_type; 00402 typedef typename traits_type::pos_type pos_type; 00403 typedef typename traits_type::off_type off_type; 00404 00405 // Non-standard types: 00406 typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 00407 typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type; 00408 typedef basic_istream<char_type, traits_type> __istream_type; 00409 00410 private: 00411 __stringbuf_type _M_stringbuf; 00412 00413 public: 00414 // Constructors: 00415 00416 /** 00417 * @brief Default constructor starts with an empty string buffer. 00418 * 00419 * Initializes @c sb using @c in, and passes @c &sb to the base 00420 * class initializer. Does not allocate any buffer. 00421 * 00422 * That's a lie. We initialize the base class with NULL, because the 00423 * string class does its own memory management. 00424 */ 00425 basic_istringstream() 00426 : __istream_type(), _M_stringbuf(ios_base::in) 00427 { this->init(&_M_stringbuf); } 00428 00429 /** 00430 * @brief Starts with an empty string buffer. 00431 * @param __mode Whether the buffer can read, or write, or both. 00432 * 00433 * @c ios_base::in is automatically included in @a __mode. 00434 * 00435 * Initializes @c sb using @c __mode|in, and passes @c &sb to the base 00436 * class initializer. Does not allocate any buffer. 00437 * 00438 * That's a lie. We initialize the base class with NULL, because the 00439 * string class does its own memory management. 00440 */ 00441 explicit 00442 basic_istringstream(ios_base::openmode __mode) 00443 : __istream_type(), _M_stringbuf(__mode | ios_base::in) 00444 { this->init(&_M_stringbuf); } 00445 00446 /** 00447 * @brief Starts with an existing string buffer. 00448 * @param __str A string to copy as a starting buffer. 00449 * @param __mode Whether the buffer can read, or write, or both. 00450 * 00451 * @c ios_base::in is automatically included in @a mode. 00452 * 00453 * Initializes @c sb using @a str and @c mode|in, and passes @c &sb 00454 * to the base class initializer. 00455 * 00456 * That's a lie. We initialize the base class with NULL, because the 00457 * string class does its own memory management. 00458 */ 00459 explicit 00460 basic_istringstream(const __string_type& __str, 00461 ios_base::openmode __mode = ios_base::in) 00462 : __istream_type(), _M_stringbuf(__str, __mode | ios_base::in) 00463 { this->init(&_M_stringbuf); } 00464 00465 /** 00466 * @brief The destructor does nothing. 00467 * 00468 * The buffer is deallocated by the stringbuf object, not the 00469 * formatting stream. 00470 */ 00471 ~basic_istringstream() 00472 { } 00473 00474 #if __cplusplus >= 201103L 00475 basic_istringstream(const basic_istringstream&) = delete; 00476 00477 basic_istringstream(basic_istringstream&& __rhs) 00478 : __istream_type(std::move(__rhs)), 00479 _M_stringbuf(std::move(__rhs._M_stringbuf)) 00480 { __istream_type::set_rdbuf(&_M_stringbuf); } 00481 00482 // 27.8.3.2 Assign and swap: 00483 00484 basic_istringstream& 00485 operator=(const basic_istringstream&) = delete; 00486 00487 basic_istringstream& 00488 operator=(basic_istringstream&& __rhs) 00489 { 00490 __istream_type::operator=(std::move(__rhs)); 00491 _M_stringbuf = std::move(__rhs._M_stringbuf); 00492 return *this; 00493 } 00494 00495 void 00496 swap(basic_istringstream& __rhs) 00497 { 00498 __istream_type::swap(__rhs); 00499 _M_stringbuf.swap(__rhs._M_stringbuf); 00500 } 00501 #endif 00502 00503 // Members: 00504 /** 00505 * @brief Accessing the underlying buffer. 00506 * @return The current basic_stringbuf buffer. 00507 * 00508 * This hides both signatures of std::basic_ios::rdbuf(). 00509 */ 00510 __stringbuf_type* 00511 rdbuf() const 00512 { return const_cast<__stringbuf_type*>(&_M_stringbuf); } 00513 00514 /** 00515 * @brief Copying out the string buffer. 00516 * @return @c rdbuf()->str() 00517 */ 00518 __string_type 00519 str() const 00520 { return _M_stringbuf.str(); } 00521 00522 /** 00523 * @brief Setting a new buffer. 00524 * @param __s The string to use as a new sequence. 00525 * 00526 * Calls @c rdbuf()->str(s). 00527 */ 00528 void 00529 str(const __string_type& __s) 00530 { _M_stringbuf.str(__s); } 00531 }; 00532 00533 00534 // [27.7.3] Template class basic_ostringstream 00535 /** 00536 * @brief Controlling output for std::string. 00537 * @ingroup io 00538 * 00539 * @tparam _CharT Type of character stream. 00540 * @tparam _Traits Traits for character type, defaults to 00541 * char_traits<_CharT>. 00542 * @tparam _Alloc Allocator type, defaults to allocator<_CharT>. 00543 * 00544 * This class supports writing to objects of type std::basic_string, 00545 * using the inherited functions from std::basic_ostream. To control 00546 * the associated sequence, an instance of std::basic_stringbuf is used, 00547 * which this page refers to as @c sb. 00548 */ 00549 template <typename _CharT, typename _Traits, typename _Alloc> 00550 class basic_ostringstream : public basic_ostream<_CharT, _Traits> 00551 { 00552 public: 00553 // Types: 00554 typedef _CharT char_type; 00555 typedef _Traits traits_type; 00556 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00557 // 251. basic_stringbuf missing allocator_type 00558 typedef _Alloc allocator_type; 00559 typedef typename traits_type::int_type int_type; 00560 typedef typename traits_type::pos_type pos_type; 00561 typedef typename traits_type::off_type off_type; 00562 00563 // Non-standard types: 00564 typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 00565 typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type; 00566 typedef basic_ostream<char_type, traits_type> __ostream_type; 00567 00568 private: 00569 __stringbuf_type _M_stringbuf; 00570 00571 public: 00572 // Constructors/destructor: 00573 00574 /** 00575 * @brief Default constructor starts with an empty string buffer. 00576 * 00577 * Initializes @c sb using @c mode|out, and passes @c &sb to the base 00578 * class initializer. Does not allocate any buffer. 00579 * 00580 * That's a lie. We initialize the base class with NULL, because the 00581 * string class does its own memory management. 00582 */ 00583 basic_ostringstream() 00584 : __ostream_type(), _M_stringbuf(ios_base::out) 00585 { this->init(&_M_stringbuf); } 00586 00587 /** 00588 * @brief Starts with an empty string buffer. 00589 * @param __mode Whether the buffer can read, or write, or both. 00590 * 00591 * @c ios_base::out is automatically included in @a mode. 00592 * 00593 * Initializes @c sb using @c mode|out, and passes @c &sb to the base 00594 * class initializer. Does not allocate any buffer. 00595 * 00596 * That's a lie. We initialize the base class with NULL, because the 00597 * string class does its own memory management. 00598 */ 00599 explicit 00600 basic_ostringstream(ios_base::openmode __mode) 00601 : __ostream_type(), _M_stringbuf(__mode | ios_base::out) 00602 { this->init(&_M_stringbuf); } 00603 00604 /** 00605 * @brief Starts with an existing string buffer. 00606 * @param __str A string to copy as a starting buffer. 00607 * @param __mode Whether the buffer can read, or write, or both. 00608 * 00609 * @c ios_base::out is automatically included in @a mode. 00610 * 00611 * Initializes @c sb using @a str and @c mode|out, and passes @c &sb 00612 * to the base class initializer. 00613 * 00614 * That's a lie. We initialize the base class with NULL, because the 00615 * string class does its own memory management. 00616 */ 00617 explicit 00618 basic_ostringstream(const __string_type& __str, 00619 ios_base::openmode __mode = ios_base::out) 00620 : __ostream_type(), _M_stringbuf(__str, __mode | ios_base::out) 00621 { this->init(&_M_stringbuf); } 00622 00623 /** 00624 * @brief The destructor does nothing. 00625 * 00626 * The buffer is deallocated by the stringbuf object, not the 00627 * formatting stream. 00628 */ 00629 ~basic_ostringstream() 00630 { } 00631 00632 #if __cplusplus >= 201103L 00633 basic_ostringstream(const basic_ostringstream&) = delete; 00634 00635 basic_ostringstream(basic_ostringstream&& __rhs) 00636 : __ostream_type(std::move(__rhs)), 00637 _M_stringbuf(std::move(__rhs._M_stringbuf)) 00638 { __ostream_type::set_rdbuf(&_M_stringbuf); } 00639 00640 // 27.8.3.2 Assign and swap: 00641 00642 basic_ostringstream& 00643 operator=(const basic_ostringstream&) = delete; 00644 00645 basic_ostringstream& 00646 operator=(basic_ostringstream&& __rhs) 00647 { 00648 __ostream_type::operator=(std::move(__rhs)); 00649 _M_stringbuf = std::move(__rhs._M_stringbuf); 00650 return *this; 00651 } 00652 00653 void 00654 swap(basic_ostringstream& __rhs) 00655 { 00656 __ostream_type::swap(__rhs); 00657 _M_stringbuf.swap(__rhs._M_stringbuf); 00658 } 00659 #endif 00660 00661 // Members: 00662 /** 00663 * @brief Accessing the underlying buffer. 00664 * @return The current basic_stringbuf buffer. 00665 * 00666 * This hides both signatures of std::basic_ios::rdbuf(). 00667 */ 00668 __stringbuf_type* 00669 rdbuf() const 00670 { return const_cast<__stringbuf_type*>(&_M_stringbuf); } 00671 00672 /** 00673 * @brief Copying out the string buffer. 00674 * @return @c rdbuf()->str() 00675 */ 00676 __string_type 00677 str() const 00678 { return _M_stringbuf.str(); } 00679 00680 /** 00681 * @brief Setting a new buffer. 00682 * @param __s The string to use as a new sequence. 00683 * 00684 * Calls @c rdbuf()->str(s). 00685 */ 00686 void 00687 str(const __string_type& __s) 00688 { _M_stringbuf.str(__s); } 00689 }; 00690 00691 00692 // [27.7.4] Template class basic_stringstream 00693 /** 00694 * @brief Controlling input and output for std::string. 00695 * @ingroup io 00696 * 00697 * @tparam _CharT Type of character stream. 00698 * @tparam _Traits Traits for character type, defaults to 00699 * char_traits<_CharT>. 00700 * @tparam _Alloc Allocator type, defaults to allocator<_CharT>. 00701 * 00702 * This class supports reading from and writing to objects of type 00703 * std::basic_string, using the inherited functions from 00704 * std::basic_iostream. To control the associated sequence, an instance 00705 * of std::basic_stringbuf is used, which this page refers to as @c sb. 00706 */ 00707 template <typename _CharT, typename _Traits, typename _Alloc> 00708 class basic_stringstream : public basic_iostream<_CharT, _Traits> 00709 { 00710 public: 00711 // Types: 00712 typedef _CharT char_type; 00713 typedef _Traits traits_type; 00714 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00715 // 251. basic_stringbuf missing allocator_type 00716 typedef _Alloc allocator_type; 00717 typedef typename traits_type::int_type int_type; 00718 typedef typename traits_type::pos_type pos_type; 00719 typedef typename traits_type::off_type off_type; 00720 00721 // Non-standard Types: 00722 typedef basic_string<_CharT, _Traits, _Alloc> __string_type; 00723 typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type; 00724 typedef basic_iostream<char_type, traits_type> __iostream_type; 00725 00726 private: 00727 __stringbuf_type _M_stringbuf; 00728 00729 public: 00730 // Constructors/destructors 00731 00732 /** 00733 * @brief Default constructor starts with an empty string buffer. 00734 * 00735 * Initializes @c sb using the mode @c in|out, and passes @c &sb 00736 * to the base class initializer. Does not allocate any buffer. 00737 * 00738 * That's a lie. We initialize the base class with NULL, because the 00739 * string class does its own memory management. 00740 */ 00741 basic_stringstream() 00742 : __iostream_type(), _M_stringbuf(ios_base::out | ios_base::in) 00743 { this->init(&_M_stringbuf); } 00744 00745 /** 00746 * @brief Starts with an empty string buffer. 00747 * @param __m Whether the buffer can read, or write, or both. 00748 * 00749 * Initializes @c sb using the mode from @c __m, and passes @c &sb 00750 * to the base class initializer. Does not allocate any buffer. 00751 * 00752 * That's a lie. We initialize the base class with NULL, because the 00753 * string class does its own memory management. 00754 */ 00755 explicit 00756 basic_stringstream(ios_base::openmode __m) 00757 : __iostream_type(), _M_stringbuf(__m) 00758 { this->init(&_M_stringbuf); } 00759 00760 /** 00761 * @brief Starts with an existing string buffer. 00762 * @param __str A string to copy as a starting buffer. 00763 * @param __m Whether the buffer can read, or write, or both. 00764 * 00765 * Initializes @c sb using @a __str and @c __m, and passes @c &sb 00766 * to the base class initializer. 00767 * 00768 * That's a lie. We initialize the base class with NULL, because the 00769 * string class does its own memory management. 00770 */ 00771 explicit 00772 basic_stringstream(const __string_type& __str, 00773 ios_base::openmode __m = ios_base::out | ios_base::in) 00774 : __iostream_type(), _M_stringbuf(__str, __m) 00775 { this->init(&_M_stringbuf); } 00776 00777 /** 00778 * @brief The destructor does nothing. 00779 * 00780 * The buffer is deallocated by the stringbuf object, not the 00781 * formatting stream. 00782 */ 00783 ~basic_stringstream() 00784 { } 00785 00786 #if __cplusplus >= 201103L 00787 basic_stringstream(const basic_stringstream&) = delete; 00788 00789 basic_stringstream(basic_stringstream&& __rhs) 00790 : __iostream_type(std::move(__rhs)), 00791 _M_stringbuf(std::move(__rhs._M_stringbuf)) 00792 { __iostream_type::set_rdbuf(&_M_stringbuf); } 00793 00794 // 27.8.3.2 Assign and swap: 00795 00796 basic_stringstream& 00797 operator=(const basic_stringstream&) = delete; 00798 00799 basic_stringstream& 00800 operator=(basic_stringstream&& __rhs) 00801 { 00802 __iostream_type::operator=(std::move(__rhs)); 00803 _M_stringbuf = std::move(__rhs._M_stringbuf); 00804 return *this; 00805 } 00806 00807 void 00808 swap(basic_stringstream& __rhs) 00809 { 00810 __iostream_type::swap(__rhs); 00811 _M_stringbuf.swap(__rhs._M_stringbuf); 00812 } 00813 #endif 00814 00815 // Members: 00816 /** 00817 * @brief Accessing the underlying buffer. 00818 * @return The current basic_stringbuf buffer. 00819 * 00820 * This hides both signatures of std::basic_ios::rdbuf(). 00821 */ 00822 __stringbuf_type* 00823 rdbuf() const 00824 { return const_cast<__stringbuf_type*>(&_M_stringbuf); } 00825 00826 /** 00827 * @brief Copying out the string buffer. 00828 * @return @c rdbuf()->str() 00829 */ 00830 __string_type 00831 str() const 00832 { return _M_stringbuf.str(); } 00833 00834 /** 00835 * @brief Setting a new buffer. 00836 * @param __s The string to use as a new sequence. 00837 * 00838 * Calls @c rdbuf()->str(s). 00839 */ 00840 void 00841 str(const __string_type& __s) 00842 { _M_stringbuf.str(__s); } 00843 }; 00844 00845 #if __cplusplus >= 201103L 00846 /// Swap specialization for stringbufs. 00847 template <class _CharT, class _Traits, class _Allocator> 00848 inline void 00849 swap(basic_stringbuf<_CharT, _Traits, _Allocator>& __x, 00850 basic_stringbuf<_CharT, _Traits, _Allocator>& __y) 00851 { __x.swap(__y); } 00852 00853 /// Swap specialization for istringstreams. 00854 template <class _CharT, class _Traits, class _Allocator> 00855 inline void 00856 swap(basic_istringstream<_CharT, _Traits, _Allocator>& __x, 00857 basic_istringstream<_CharT, _Traits, _Allocator>& __y) 00858 { __x.swap(__y); } 00859 00860 /// Swap specialization for ostringstreams. 00861 template <class _CharT, class _Traits, class _Allocator> 00862 inline void 00863 swap(basic_ostringstream<_CharT, _Traits, _Allocator>& __x, 00864 basic_ostringstream<_CharT, _Traits, _Allocator>& __y) 00865 { __x.swap(__y); } 00866 00867 /// Swap specialization for stringstreams. 00868 template <class _CharT, class _Traits, class _Allocator> 00869 inline void 00870 swap(basic_stringstream<_CharT, _Traits, _Allocator>& __x, 00871 basic_stringstream<_CharT, _Traits, _Allocator>& __y) 00872 { __x.swap(__y); } 00873 #endif 00874 00875 _GLIBCXX_END_NAMESPACE_CXX11 00876 _GLIBCXX_END_NAMESPACE_VERSION 00877 } // namespace 00878 00879 #include <bits/sstream.tcc> 00880 00881 #endif /* _GLIBCXX_SSTREAM */