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