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