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