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