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