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