Home | History | Annotate | Line # | Download | only in std
      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