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