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