Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

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