1// String based streams -*- C++ -*-
3// Copyright (C) 1997-2025 Free Software Foundation, Inc.
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)
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.
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.
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/>.
25/** @file include/sstream
26 * This is a Standard C++ Library header.
30// ISO C++ 14882: 27.7 String-based streams
33#ifndef _GLIBCXX_SSTREAM
34#define _GLIBCXX_SSTREAM 1
37#pragma GCC system_header
40#include <bits/requires_hosted.h> // iostream
45#include <bits/alloc_traits.h> // allocator_traits, __allocator_like
47#define __glibcxx_want_sstream_from_string_view
48#include <bits/version.h>
50#ifdef __cpp_lib_sstream_from_string_view
51# include <string_view>
54#if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
55# define _GLIBCXX_LVAL_REF_QUAL &
56# define _GLIBCXX_SSTREAM_ALWAYS_INLINE
58# define _GLIBCXX_LVAL_REF_QUAL
59// For symbols that are not exported from libstdc++.so for the COW string ABI.
60# define _GLIBCXX_SSTREAM_ALWAYS_INLINE [[__gnu__::__always_inline__]]
63namespace std _GLIBCXX_VISIBILITY(default)
65_GLIBCXX_BEGIN_NAMESPACE_VERSION
66_GLIBCXX_BEGIN_NAMESPACE_CXX11
68 // [27.7.1] template class basic_stringbuf
70 * @brief The actual work of input and output (for std::string).
73 * @tparam _CharT Type of character stream.
74 * @tparam _Traits Traits for character type, defaults to
75 * char_traits<_CharT>.
76 * @tparam _Alloc Allocator type, defaults to allocator<_CharT>.
78 * This class associates either or both of its input and output sequences
79 * with a sequence of characters, which can be initialized from, or made
80 * available as, a @c std::basic_string. (Paraphrased from [27.7.1]/1.)
82 * For this class, open modes (of type @c ios_base::openmode) have
83 * @c in set if the input sequence can be read, and @c out set if the
84 * output sequence can be written.
86 template<typename _CharT, typename _Traits, typename _Alloc>
87 class basic_stringbuf : public basic_streambuf<_CharT, _Traits>
89 struct __xfer_bufptrs;
91#if __cplusplus >= 201103L
92 using allocator_traits = std::allocator_traits<_Alloc>;
94 = __or_<typename allocator_traits::propagate_on_container_swap,
95 typename allocator_traits::is_always_equal>;
100 typedef _CharT char_type;
101 typedef _Traits traits_type;
102 // _GLIBCXX_RESOLVE_LIB_DEFECTS
103 // 251. basic_stringbuf missing allocator_type
104 typedef _Alloc allocator_type;
105 typedef typename traits_type::int_type int_type;
106 typedef typename traits_type::pos_type pos_type;
107 typedef typename traits_type::off_type off_type;
109 typedef basic_streambuf<char_type, traits_type> __streambuf_type;
110 typedef basic_string<char_type, _Traits, _Alloc> __string_type;
111 typedef typename __string_type::size_type __size_type;
114 /// Place to stash in || out || in | out settings for current stringbuf.
115 ios_base::openmode _M_mode;
118 __string_type _M_string;
124 * @brief Starts with an empty string buffer.
126 * The default constructor initializes the parent class using its
130 : __streambuf_type(), _M_mode(ios_base::in | ios_base::out), _M_string()
134 * @brief Starts with an empty string buffer.
135 * @param __mode Whether the buffer can read, or write, or both.
137 * The default constructor initializes the parent class using its
141 basic_stringbuf(ios_base::openmode __mode)
142 : __streambuf_type(), _M_mode(__mode), _M_string()
146 * @brief Starts with an existing string buffer.
147 * @param __str A string to copy as a starting buffer.
148 * @param __mode Whether the buffer can read, or write, or both.
150 * This constructor initializes the parent class using its
154 basic_stringbuf(const __string_type& __str,
155 ios_base::openmode __mode = ios_base::in | ios_base::out)
156 : __streambuf_type(), _M_mode(),
157 _M_string(__str.data(), __str.size(), __str.get_allocator())
158 { _M_stringbuf_init(__mode); }
160#if __cplusplus >= 201103L
161 basic_stringbuf(const basic_stringbuf&) = delete;
163 basic_stringbuf(basic_stringbuf&& __rhs)
164 : basic_stringbuf(std::move(__rhs), __xfer_bufptrs(__rhs, this))
165 { __rhs._M_sync(const_cast<char_type*>(__rhs._M_string.data()), 0, 0); }
167#if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
168 // P0408 Efficient access to basic_stringbuf buffer
170 basic_stringbuf(const allocator_type& __a)
171 : basic_stringbuf(ios_base::in | std::ios_base::out, __a)
174 basic_stringbuf(ios_base::openmode __mode,
175 const allocator_type& __a)
176 : __streambuf_type(), _M_mode(__mode), _M_string(__a)
180 basic_stringbuf(__string_type&& __s,
181 ios_base::openmode __mode = ios_base::in
183 : __streambuf_type(), _M_mode(__mode), _M_string(std::move(__s))
184 { _M_stringbuf_init(__mode); }
186 template<typename _SAlloc>
187 basic_stringbuf(const basic_string<_CharT, _Traits, _SAlloc>& __s,
188 const allocator_type& __a)
189 : basic_stringbuf(__s, ios_base::in | std::ios_base::out, __a)
192 template<typename _SAlloc>
193 basic_stringbuf(const basic_string<_CharT, _Traits, _SAlloc>& __s,
194 ios_base::openmode __mode,
195 const allocator_type& __a)
196 : __streambuf_type(), _M_mode(__mode),
197 _M_string(__s.data(), __s.size(), __a)
198 { _M_stringbuf_init(__mode); }
200 template<typename _SAlloc>
202 basic_stringbuf(const basic_string<_CharT, _Traits, _SAlloc>& __s,
203 ios_base::openmode __mode = ios_base::in
205 : basic_stringbuf(__s, __mode, allocator_type{})
209#ifdef __cpp_lib_sstream_from_string_view
210 template<typename _Tp>
212 basic_stringbuf(const _Tp& __t,
213 ios_base::openmode __mode = ios_base::in | ios_base::out)
214 requires (is_convertible_v<const _Tp&,
215 basic_string_view<_CharT, _Traits>>)
216 : basic_stringbuf(__t, __mode, allocator_type{})
219 template<typename _Tp>
220 basic_stringbuf(const _Tp& __t, const allocator_type& __a)
221 requires (is_convertible_v<const _Tp&,
222 basic_string_view<_CharT, _Traits>>)
223 : basic_stringbuf(__t, ios_base::in | ios_base::out, __a)
226 template<typename _Tp>
227 basic_stringbuf(const _Tp& __t, ios_base::openmode __mode,
228 const allocator_type& __a)
229 requires (is_convertible_v<const _Tp&,
230 basic_string_view<_CharT, _Traits>>)
231 : _M_string(__t, __a)
232 { _M_stringbuf_init(__mode); }
235#if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
236 // P0408 Efficient access to basic_stringbuf buffer
237 basic_stringbuf(basic_stringbuf&& __rhs, const allocator_type& __a)
238 : basic_stringbuf(std::move(__rhs), __a, __xfer_bufptrs(__rhs, this))
239 { __rhs._M_sync(const_cast<char_type*>(__rhs._M_string.data()), 0, 0); }
241 allocator_type get_allocator() const noexcept
242 { return _M_string.get_allocator(); }
245 // 27.8.2.2 Assign and swap:
248 operator=(const basic_stringbuf&) = delete;
251 operator=(basic_stringbuf&& __rhs)
253 __xfer_bufptrs __st{__rhs, this};
254 const __streambuf_type& __base = __rhs;
255 __streambuf_type::operator=(__base);
256 this->pubimbue(__rhs.getloc());
257 _M_mode = __rhs._M_mode;
258 _M_string = std::move(__rhs._M_string);
259 __rhs._M_sync(const_cast<char_type*>(__rhs._M_string.data()), 0, 0);
264 swap(basic_stringbuf& __rhs) noexcept(_Noexcept_swap::value)
266 __xfer_bufptrs __l_st{*this, std::__addressof(__rhs)};
267 __xfer_bufptrs __r_st{__rhs, this};
268 __streambuf_type& __base = __rhs;
269 __streambuf_type::swap(__base);
270 __rhs.pubimbue(this->pubimbue(__rhs.getloc()));
271 std::swap(_M_mode, __rhs._M_mode);
272 std::swap(_M_string, __rhs._M_string); // XXX not exception safe
276 // Getters and setters:
279 * @brief Copying out the string buffer.
280 * @return A copy of one of the underlying sequences.
282 * <em>If the buffer is only created in input mode, the underlying
283 * character sequence is equal to the input sequence; otherwise, it
284 * is equal to the output sequence.</em> [27.7.1.2]/1
288 str() const _GLIBCXX_LVAL_REF_QUAL
290 __string_type __ret(_M_string.get_allocator());
291 if (char_type* __hi = _M_high_mark())
292 __ret.assign(this->pbase(), __hi);
298#if __cplusplus > 201703L
299#if _GLIBCXX_USE_CXX11_ABI
301 // P0407 Allocator-aware basic_streambuf
302 template<__allocator_like _SAlloc>
304 basic_string<_CharT, _Traits, _SAlloc>
305 str(const _SAlloc& __sa) const
308 return { __sv.data(), __sv.size(), __sa };
316 if (char_type* __hi = _M_high_mark())
318 // Set length to end of character sequence and add null terminator.
319 _M_string._M_set_length(_M_high_mark() - this->pbase());
321 auto __str = std::move(_M_string);
323 _M_sync(_M_string.data(), 0, 0);
328 _GLIBCXX_SSTREAM_ALWAYS_INLINE
329 basic_string_view<char_type, traits_type>
330 view() const noexcept
332 if (char_type* __hi = _M_high_mark())
333 return { this->pbase(), __hi };
340 * @brief Setting a new buffer.
341 * @param __s The string to use as a new sequence.
343 * Deallocates any previous stored sequence, then copies @a s to
347 str(const __string_type& __s)
349 // Cannot use _M_string = __s, since v3 strings are COW
350 // (not always true now but assign() always works).
351 _M_string.assign(__s.data(), __s.size());
352 _M_stringbuf_init(_M_mode);
355#if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
357 // P0407 Allocator-aware basic_streambuf
358 template<__allocator_like _SAlloc>
359 requires (!is_same_v<_SAlloc, _Alloc>)
361 str(const basic_string<_CharT, _Traits, _SAlloc>& __s)
363 _M_string.assign(__s.data(), __s.size());
364 _M_stringbuf_init(_M_mode);
369 str(__string_type&& __s)
371 _M_string = std::move(__s);
372 _M_stringbuf_init(_M_mode);
376#ifdef __cpp_lib_sstream_from_string_view
377 template <typename _Tp>
380 requires (is_convertible_v<const _Tp&,
381 basic_string_view<_CharT, _Traits>>)
383 basic_string_view<_CharT, _Traits> __sv{__t};
385 _M_stringbuf_init(_M_mode);
390 // Common initialization code goes here.
392 _M_stringbuf_init(ios_base::openmode __mode)
395 __size_type __len = 0;
396 if (_M_mode & (ios_base::ate | ios_base::app))
397 __len = _M_string.size();
398 _M_sync(const_cast<char_type*>(_M_string.data()), 0, __len);
404 streamsize __ret = -1;
405 if (_M_mode & ios_base::in)
408 __ret = this->egptr() - this->gptr();
417 pbackfail(int_type __c = traits_type::eof());
420 overflow(int_type __c = traits_type::eof());
423 * @brief Manipulates the buffer.
424 * @param __s Pointer to a buffer area.
425 * @param __n Size of @a __s.
428 * If no buffer has already been created, and both @a __s and @a __n are
429 * non-zero, then @c __s is used as a buffer; see
430 * https://gcc.gnu.org/onlinedocs/libstdc++/manual/streambufs.html#io.streambuf.buffering
433 virtual __streambuf_type*
434 setbuf(char_type* __s, streamsize __n)
438 // This is implementation-defined behavior, and assumes
439 // that an external char_type array of length __n exists
440 // and has been pre-allocated. If this is not the case,
441 // things will quickly blow up.
443 // Step 1: Destroy the current internal array.
446 // Step 2: Use the external array.
447 _M_sync(__s, __n, 0);
453 seekoff(off_type __off, ios_base::seekdir __way,
454 ios_base::openmode __mode = ios_base::in | ios_base::out);
457 seekpos(pos_type __sp,
458 ios_base::openmode __mode = ios_base::in | ios_base::out);
460 // Internal function for correctly updating the internal buffer
461 // for a particular _M_string, due to initialization or re-sizing
462 // of an existing _M_string.
464 _M_sync(char_type* __base, __size_type __i, __size_type __o);
466 // Internal function for correctly updating egptr() to the actual
471 if (char_type* __pptr = this->pptr())
473 char_type* __egptr = this->egptr();
474 if (!__egptr || __pptr > __egptr)
476 if (_M_mode & ios_base::in)
477 this->setg(this->eback(), this->gptr(), __pptr);
479 this->setg(__pptr, __pptr, __pptr);
484 // Works around the issue with pbump, part of the protected
485 // interface of basic_streambuf, taking just an int.
487 _M_pbump(char_type* __pbeg, char_type* __pend, off_type __off);
490 // Return a pointer to the end of the underlying character sequence.
491 // This might not be the same character as _M_string.end() because
492 // basic_stringbuf::overflow might have written to unused capacity
493 // in _M_string without updating its length.
494 __attribute__((__always_inline__))
496 _M_high_mark() const _GLIBCXX_NOEXCEPT
498 if (char_type* __pptr = this->pptr())
500 char_type* __egptr = this->egptr();
501 if (!__egptr || __pptr > __egptr)
502 return __pptr; // Underlying sequence is [pbase, pptr).
504 return __egptr; // Underlying sequence is [pbase, egptr).
506 return 0; // Underlying character sequence is just _M_string.
509#if __cplusplus >= 201103L
510#if _GLIBCXX_USE_CXX11_ABI
511 // This type captures the state of the gptr / pptr pointers as offsets
512 // so they can be restored in another object after moving the string.
513 struct __xfer_bufptrs
515 __xfer_bufptrs(const basic_stringbuf& __from, basic_stringbuf* __to)
516 : _M_to{__to}, _M_goff{-1, -1, -1}, _M_poff{-1, -1, -1}
518 const _CharT* const __str = __from._M_string.data();
519 const _CharT* __end = nullptr;
522 _M_goff[0] = __from.eback() - __str;
523 _M_goff[1] = __from.gptr() - __str;
524 _M_goff[2] = __from.egptr() - __str;
525 __end = __from.egptr();
529 _M_poff[0] = __from.pbase() - __str;
530 _M_poff[1] = __from.pptr() - __from.pbase();
531 _M_poff[2] = __from.epptr() - __str;
532 if (!__end || __from.pptr() > __end)
533 __end = __from.pptr();
536 // Set _M_string length to the greater of the get and put areas.
539 // The const_cast avoids changing this constructor's signature,
540 // because it is exported from the dynamic library.
541 auto& __mut_from = const_cast<basic_stringbuf&>(__from);
542 __mut_from._M_string._M_length(__end - __str);
548 char_type* __str = const_cast<char_type*>(_M_to->_M_string.data());
549 if (_M_goff[0] != -1)
550 _M_to->setg(__str+_M_goff[0], __str+_M_goff[1], __str+_M_goff[2]);
551 if (_M_poff[0] != -1)
552 _M_to->_M_pbump(__str+_M_poff[0], __str+_M_poff[2], _M_poff[1]);
555 basic_stringbuf* _M_to;
560 // This type does nothing when using Copy-On-Write strings.
561 struct __xfer_bufptrs
563 __xfer_bufptrs(const basic_stringbuf&, basic_stringbuf*) { }
567 // The move constructor initializes an __xfer_bufptrs temporary then
568 // delegates to this constructor to performs moves during its lifetime.
569 basic_stringbuf(basic_stringbuf&& __rhs, __xfer_bufptrs&&)
570 : __streambuf_type(static_cast<const __streambuf_type&>(__rhs)),
571 _M_mode(__rhs._M_mode), _M_string(std::move(__rhs._M_string))
574#if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
575 // P0408 Efficient access to basic_stringbuf buffer
577 // The move constructor initializes an __xfer_bufptrs temporary then
578 // delegates to this constructor to performs moves during its lifetime.
579 basic_stringbuf(basic_stringbuf&& __rhs, const allocator_type& __a,
581 : __streambuf_type(static_cast<const __streambuf_type&>(__rhs)),
582 _M_mode(__rhs._M_mode), _M_string(std::move(__rhs._M_string), __a)
589 // [27.7.2] Template class basic_istringstream
591 * @brief Controlling input for std::string.
594 * @tparam _CharT Type of character stream.
595 * @tparam _Traits Traits for character type, defaults to
596 * char_traits<_CharT>.
597 * @tparam _Alloc Allocator type, defaults to allocator<_CharT>.
599 * This class supports reading from objects of type std::basic_string,
600 * using the inherited functions from std::basic_istream. To control
601 * the associated sequence, an instance of std::basic_stringbuf is used,
602 * which this page refers to as @c sb.
604 template<typename _CharT, typename _Traits, typename _Alloc>
605 class basic_istringstream : public basic_istream<_CharT, _Traits>
609 typedef _CharT char_type;
610 typedef _Traits traits_type;
611 // _GLIBCXX_RESOLVE_LIB_DEFECTS
612 // 251. basic_stringbuf missing allocator_type
613 typedef _Alloc allocator_type;
614 typedef typename traits_type::int_type int_type;
615 typedef typename traits_type::pos_type pos_type;
616 typedef typename traits_type::off_type off_type;
618 // Non-standard types:
619 typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
620 typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type;
621 typedef basic_istream<char_type, traits_type> __istream_type;
624 __stringbuf_type _M_stringbuf;
630 * @brief Default constructor starts with an empty string buffer.
632 * Initializes @c sb using @c in, and passes @c &sb to the base
633 * class initializer. Does not allocate any buffer.
635 * That's a lie. We initialize the base class with NULL, because the
636 * string class does its own memory management.
638 basic_istringstream()
639 : __istream_type(), _M_stringbuf(ios_base::in)
640 { this->init(std::__addressof(_M_stringbuf)); }
643 * @brief Starts with an empty string buffer.
644 * @param __mode Whether the buffer can read, or write, or both.
646 * @c ios_base::in is automatically included in @a __mode.
648 * Initializes @c sb using @c __mode|in, and passes @c &sb to the base
649 * class initializer. Does not allocate any buffer.
651 * That's a lie. We initialize the base class with NULL, because the
652 * string class does its own memory management.
655 basic_istringstream(ios_base::openmode __mode)
656 : __istream_type(), _M_stringbuf(__mode | ios_base::in)
657 { this->init(std::__addressof(_M_stringbuf)); }
660 * @brief Starts with an existing string buffer.
661 * @param __str A string to copy as a starting buffer.
662 * @param __mode Whether the buffer can read, or write, or both.
664 * @c ios_base::in is automatically included in @a mode.
666 * Initializes @c sb using @a str and @c mode|in, and passes @c &sb
667 * to the base class initializer.
669 * That's a lie. We initialize the base class with NULL, because the
670 * string class does its own memory management.
673 basic_istringstream(const __string_type& __str,
674 ios_base::openmode __mode = ios_base::in)
675 : __istream_type(), _M_stringbuf(__str, __mode | ios_base::in)
676 { this->init(std::__addressof(_M_stringbuf)); }
679 * @brief The destructor does nothing.
681 * The buffer is deallocated by the stringbuf object, not the
684 ~basic_istringstream()
687#if __cplusplus >= 201103L
688 basic_istringstream(const basic_istringstream&) = delete;
690 basic_istringstream(basic_istringstream&& __rhs)
691 : __istream_type(std::move(__rhs)),
692 _M_stringbuf(std::move(__rhs._M_stringbuf))
693 { __istream_type::set_rdbuf(std::__addressof(_M_stringbuf)); }
695#if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
696 // P0408 Efficient access to basic_stringbuf buffer
697 basic_istringstream(ios_base::openmode __mode, const allocator_type& __a)
698 : __istream_type(), _M_stringbuf(__mode | ios_base::in, __a)
699 { this->init(std::__addressof(_M_stringbuf)); }
702 basic_istringstream(__string_type&& __str,
703 ios_base::openmode __mode = ios_base::in)
704 : __istream_type(), _M_stringbuf(std::move(__str), __mode | ios_base::in)
705 { this->init(std::__addressof(_M_stringbuf)); }
707 template<typename _SAlloc>
708 basic_istringstream(const basic_string<_CharT, _Traits, _SAlloc>& __str,
709 const allocator_type& __a)
710 : basic_istringstream(__str, ios_base::in, __a)
713 template<typename _SAlloc>
714 basic_istringstream(const basic_string<_CharT, _Traits, _SAlloc>& __str,
715 ios_base::openmode __mode,
716 const allocator_type& __a)
717 : __istream_type(), _M_stringbuf(__str, __mode | ios_base::in, __a)
718 { this->init(std::__addressof(_M_stringbuf)); }
720 template<typename _SAlloc>
722 basic_istringstream(const basic_string<_CharT, _Traits, _SAlloc>& __str,
723 ios_base::openmode __mode = ios_base::in)
724 : basic_istringstream(__str, __mode, allocator_type())
728#ifdef __cpp_lib_sstream_from_string_view
729 template <typename _Tp>
731 basic_istringstream(const _Tp& __t,
732 ios_base::openmode __mode = ios_base::in)
733 requires (is_convertible_v<const _Tp&,
734 basic_string_view<_CharT, _Traits>>)
735 : basic_istringstream(__t, __mode, allocator_type{})
738 template <typename _Tp>
739 basic_istringstream(const _Tp& __t, const allocator_type& __a)
740 requires (is_convertible_v<const _Tp&,
741 basic_string_view<_CharT, _Traits>>)
742 : basic_istringstream(__t, ios_base::in, __a)
745 template <typename _Tp>
746 basic_istringstream(const _Tp& __t, ios_base::openmode __mode,
747 const allocator_type& __a)
748 requires (is_convertible_v<const _Tp&,
749 basic_string_view<_CharT, _Traits>>)
750 : __istream_type(), _M_stringbuf(__t, __mode | ios_base::in, __a)
751 { this->init(std::__addressof(_M_stringbuf)); }
754 // 27.8.3.2 Assign and swap:
757 operator=(const basic_istringstream&) = delete;
760 operator=(basic_istringstream&& __rhs)
762 __istream_type::operator=(std::move(__rhs));
763 _M_stringbuf = std::move(__rhs._M_stringbuf);
768 swap(basic_istringstream& __rhs)
770 __istream_type::swap(__rhs);
771 _M_stringbuf.swap(__rhs._M_stringbuf);
777 * @brief Accessing the underlying buffer.
778 * @return The current basic_stringbuf buffer.
780 * This hides both signatures of std::basic_ios::rdbuf().
785 { return const_cast<__stringbuf_type*>(std::__addressof(_M_stringbuf)); }
788 * @brief Copying out the string buffer.
789 * @return @c rdbuf()->str()
793 str() const _GLIBCXX_LVAL_REF_QUAL
794 { return _M_stringbuf.str(); }
796#if __cplusplus > 201703L
797#if _GLIBCXX_USE_CXX11_ABI
799 // P0407 Allocator-aware basic_streambuf
800 template<__allocator_like _SAlloc>
802 basic_string<_CharT, _Traits, _SAlloc>
803 str(const _SAlloc& __sa) const
804 { return _M_stringbuf.str(__sa); }
810 { return std::move(_M_stringbuf).str(); }
813 _GLIBCXX_SSTREAM_ALWAYS_INLINE
814 basic_string_view<char_type, traits_type>
815 view() const noexcept
816 { return _M_stringbuf.view(); }
820 * @brief Setting a new buffer.
821 * @param __s The string to use as a new sequence.
823 * Calls @c rdbuf()->str(s).
826 str(const __string_type& __s)
827 { _M_stringbuf.str(__s); }
829#if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
831 // P0407 Allocator-aware basic_streambuf
832 template<__allocator_like _SAlloc>
833 requires (!is_same_v<_SAlloc, _Alloc>)
835 str(const basic_string<_CharT, _Traits, _SAlloc>& __s)
836 { _M_stringbuf.str(__s); }
840 str(__string_type&& __s)
841 { _M_stringbuf.str(std::move(__s)); }
844#ifdef __cpp_lib_sstream_from_string_view
845 template<typename _Tp>
848 requires (is_convertible_v<const _Tp&,
849 basic_string_view<_CharT, _Traits>>)
850 { _M_stringbuf.str(__t); }
855 // [27.7.3] Template class basic_ostringstream
857 * @brief Controlling output for std::string.
860 * @tparam _CharT Type of character stream.
861 * @tparam _Traits Traits for character type, defaults to
862 * char_traits<_CharT>.
863 * @tparam _Alloc Allocator type, defaults to allocator<_CharT>.
865 * This class supports writing to objects of type std::basic_string,
866 * using the inherited functions from std::basic_ostream. To control
867 * the associated sequence, an instance of std::basic_stringbuf is used,
868 * which this page refers to as @c sb.
870 template <typename _CharT, typename _Traits, typename _Alloc>
871 class basic_ostringstream : public basic_ostream<_CharT, _Traits>
875 typedef _CharT char_type;
876 typedef _Traits traits_type;
877 // _GLIBCXX_RESOLVE_LIB_DEFECTS
878 // 251. basic_stringbuf missing allocator_type
879 typedef _Alloc allocator_type;
880 typedef typename traits_type::int_type int_type;
881 typedef typename traits_type::pos_type pos_type;
882 typedef typename traits_type::off_type off_type;
884 // Non-standard types:
885 typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
886 typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type;
887 typedef basic_ostream<char_type, traits_type> __ostream_type;
890 __stringbuf_type _M_stringbuf;
893 // Constructors/destructor:
896 * @brief Default constructor starts with an empty string buffer.
898 * Initializes @c sb using @c mode|out, and passes @c &sb to the base
899 * class initializer. Does not allocate any buffer.
901 * That's a lie. We initialize the base class with NULL, because the
902 * string class does its own memory management.
904 basic_ostringstream()
905 : __ostream_type(), _M_stringbuf(ios_base::out)
906 { this->init(std::__addressof(_M_stringbuf)); }
909 * @brief Starts with an empty string buffer.
910 * @param __mode Whether the buffer can read, or write, or both.
912 * @c ios_base::out is automatically included in @a mode.
914 * Initializes @c sb using @c mode|out, and passes @c &sb to the base
915 * class initializer. Does not allocate any buffer.
917 * That's a lie. We initialize the base class with NULL, because the
918 * string class does its own memory management.
921 basic_ostringstream(ios_base::openmode __mode)
922 : __ostream_type(), _M_stringbuf(__mode | ios_base::out)
923 { this->init(std::__addressof(_M_stringbuf)); }
926 * @brief Starts with an existing string buffer.
927 * @param __str A string to copy as a starting buffer.
928 * @param __mode Whether the buffer can read, or write, or both.
930 * @c ios_base::out is automatically included in @a mode.
932 * Initializes @c sb using @a str and @c mode|out, and passes @c &sb
933 * to the base class initializer.
935 * That's a lie. We initialize the base class with NULL, because the
936 * string class does its own memory management.
939 basic_ostringstream(const __string_type& __str,
940 ios_base::openmode __mode = ios_base::out)
941 : __ostream_type(), _M_stringbuf(__str, __mode | ios_base::out)
942 { this->init(std::__addressof(_M_stringbuf)); }
945 * @brief The destructor does nothing.
947 * The buffer is deallocated by the stringbuf object, not the
950 ~basic_ostringstream()
953#if __cplusplus >= 201103L
954 basic_ostringstream(const basic_ostringstream&) = delete;
956 basic_ostringstream(basic_ostringstream&& __rhs)
957 : __ostream_type(std::move(__rhs)),
958 _M_stringbuf(std::move(__rhs._M_stringbuf))
959 { __ostream_type::set_rdbuf(std::__addressof(_M_stringbuf)); }
961#if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
962 // P0408 Efficient access to basic_stringbuf buffer
963 basic_ostringstream(ios_base::openmode __mode, const allocator_type& __a)
964 : __ostream_type(), _M_stringbuf(__mode | ios_base::out, __a)
965 { this->init(std::__addressof(_M_stringbuf)); }
968 basic_ostringstream(__string_type&& __str,
969 ios_base::openmode __mode = ios_base::out)
970 : __ostream_type(), _M_stringbuf(std::move(__str), __mode | ios_base::out)
971 { this->init(std::__addressof(_M_stringbuf)); }
973 template<typename _SAlloc>
974 basic_ostringstream(const basic_string<_CharT, _Traits, _SAlloc>& __str,
975 const allocator_type& __a)
976 : basic_ostringstream(__str, ios_base::out, __a)
979 template<typename _SAlloc>
980 basic_ostringstream(const basic_string<_CharT, _Traits, _SAlloc>& __str,
981 ios_base::openmode __mode,
982 const allocator_type& __a)
983 : __ostream_type(), _M_stringbuf(__str, __mode | ios_base::out, __a)
984 { this->init(std::__addressof(_M_stringbuf)); }
986 template<typename _SAlloc>
988 basic_ostringstream(const basic_string<_CharT, _Traits, _SAlloc>& __str,
989 ios_base::openmode __mode = ios_base::out)
990 : basic_ostringstream(__str, __mode, allocator_type())
994#ifdef __cpp_lib_sstream_from_string_view
995 template <typename _Tp>
998 const _Tp& __t, ios_base::openmode __mode = ios_base::out)
999 requires (is_convertible_v<const _Tp&,
1000 basic_string_view<_CharT, _Traits>>)
1001 : basic_ostringstream(__t, __mode, allocator_type{})
1004 template <typename _Tp>
1005 basic_ostringstream(const _Tp& __t, const allocator_type& __a)
1006 requires (is_convertible_v<const _Tp&,
1007 basic_string_view<_CharT, _Traits>>)
1008 : basic_ostringstream(__t, ios_base::out, __a)
1011 template <typename _Tp>
1012 basic_ostringstream(const _Tp& __t, ios_base::openmode __mode,
1013 const allocator_type& __a)
1014 requires (is_convertible_v<const _Tp&,
1015 basic_string_view<_CharT, _Traits>>)
1016 : __ostream_type(), _M_stringbuf(__t, __mode | ios_base::out, __a)
1017 { this->init(std::__addressof(_M_stringbuf)); }
1020 // 27.8.3.2 Assign and swap:
1022 basic_ostringstream&
1023 operator=(const basic_ostringstream&) = delete;
1025 basic_ostringstream&
1026 operator=(basic_ostringstream&& __rhs)
1028 __ostream_type::operator=(std::move(__rhs));
1029 _M_stringbuf = std::move(__rhs._M_stringbuf);
1034 swap(basic_ostringstream& __rhs)
1036 __ostream_type::swap(__rhs);
1037 _M_stringbuf.swap(__rhs._M_stringbuf);
1043 * @brief Accessing the underlying buffer.
1044 * @return The current basic_stringbuf buffer.
1046 * This hides both signatures of std::basic_ios::rdbuf().
1051 { return const_cast<__stringbuf_type*>(std::__addressof(_M_stringbuf)); }
1054 * @brief Copying out the string buffer.
1055 * @return @c rdbuf()->str()
1059 str() const _GLIBCXX_LVAL_REF_QUAL
1060 { return _M_stringbuf.str(); }
1062#if __cplusplus > 201703L
1063#if _GLIBCXX_USE_CXX11_ABI
1065 // P0407 Allocator-aware basic_streambuf
1066 template<__allocator_like _SAlloc>
1068 basic_string<_CharT, _Traits, _SAlloc>
1069 str(const _SAlloc& __sa) const
1070 { return _M_stringbuf.str(__sa); }
1076 { return std::move(_M_stringbuf).str(); }
1079 _GLIBCXX_SSTREAM_ALWAYS_INLINE
1080 basic_string_view<char_type, traits_type>
1081 view() const noexcept
1082 { return _M_stringbuf.view(); }
1086 * @brief Setting a new buffer.
1087 * @param __s The string to use as a new sequence.
1089 * Calls @c rdbuf()->str(s).
1092 str(const __string_type& __s)
1093 { _M_stringbuf.str(__s); }
1095#if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
1097 // P0407 Allocator-aware basic_streambuf
1098 template<__allocator_like _SAlloc>
1099 requires (!is_same_v<_SAlloc, _Alloc>)
1101 str(const basic_string<_CharT, _Traits, _SAlloc>& __s)
1102 { _M_stringbuf.str(__s); }
1106 str(__string_type&& __s)
1107 { _M_stringbuf.str(std::move(__s)); }
1110#ifdef __cpp_lib_sstream_from_string_view
1111 template<typename _Tp>
1114 requires (is_convertible_v<const _Tp&,
1115 basic_string_view<_CharT, _Traits>>)
1116 { _M_stringbuf.str(__t); }
1121 // [27.7.4] Template class basic_stringstream
1123 * @brief Controlling input and output for std::string.
1126 * @tparam _CharT Type of character stream.
1127 * @tparam _Traits Traits for character type, defaults to
1128 * char_traits<_CharT>.
1129 * @tparam _Alloc Allocator type, defaults to allocator<_CharT>.
1131 * This class supports reading from and writing to objects of type
1132 * std::basic_string, using the inherited functions from
1133 * std::basic_iostream. To control the associated sequence, an instance
1134 * of std::basic_stringbuf is used, which this page refers to as @c sb.
1136 template <typename _CharT, typename _Traits, typename _Alloc>
1137 class basic_stringstream : public basic_iostream<_CharT, _Traits>
1141 typedef _CharT char_type;
1142 typedef _Traits traits_type;
1143 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1144 // 251. basic_stringbuf missing allocator_type
1145 typedef _Alloc allocator_type;
1146 typedef typename traits_type::int_type int_type;
1147 typedef typename traits_type::pos_type pos_type;
1148 typedef typename traits_type::off_type off_type;
1150 // Non-standard Types:
1151 typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
1152 typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type;
1153 typedef basic_iostream<char_type, traits_type> __iostream_type;
1156 __stringbuf_type _M_stringbuf;
1159 // Constructors/destructors
1162 * @brief Default constructor starts with an empty string buffer.
1164 * Initializes @c sb using the mode @c in|out, and passes @c &sb
1165 * to the base class initializer. Does not allocate any buffer.
1167 * That's a lie. We initialize the base class with NULL, because the
1168 * string class does its own memory management.
1170 basic_stringstream()
1171 : __iostream_type(), _M_stringbuf(ios_base::out | ios_base::in)
1172 { this->init(std::__addressof(_M_stringbuf)); }
1175 * @brief Starts with an empty string buffer.
1176 * @param __m Whether the buffer can read, or write, or both.
1178 * Initializes @c sb using the mode from @c __m, and passes @c &sb
1179 * to the base class initializer. Does not allocate any buffer.
1181 * That's a lie. We initialize the base class with NULL, because the
1182 * string class does its own memory management.
1185 basic_stringstream(ios_base::openmode __m)
1186 : __iostream_type(), _M_stringbuf(__m)
1187 { this->init(std::__addressof(_M_stringbuf)); }
1190 * @brief Starts with an existing string buffer.
1191 * @param __str A string to copy as a starting buffer.
1192 * @param __m Whether the buffer can read, or write, or both.
1194 * Initializes @c sb using @a __str and @c __m, and passes @c &sb
1195 * to the base class initializer.
1197 * That's a lie. We initialize the base class with NULL, because the
1198 * string class does its own memory management.
1201 basic_stringstream(const __string_type& __str,
1202 ios_base::openmode __m = ios_base::out | ios_base::in)
1203 : __iostream_type(), _M_stringbuf(__str, __m)
1204 { this->init(std::__addressof(_M_stringbuf)); }
1207 * @brief The destructor does nothing.
1209 * The buffer is deallocated by the stringbuf object, not the
1210 * formatting stream.
1212 ~basic_stringstream()
1215#if __cplusplus >= 201103L
1216 basic_stringstream(const basic_stringstream&) = delete;
1218 basic_stringstream(basic_stringstream&& __rhs)
1219 : __iostream_type(std::move(__rhs)),
1220 _M_stringbuf(std::move(__rhs._M_stringbuf))
1221 { __iostream_type::set_rdbuf(std::__addressof(_M_stringbuf)); }
1223#if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
1224 // P0408 Efficient access to basic_stringbuf buffer
1225 basic_stringstream(ios_base::openmode __mode, const allocator_type& __a)
1226 : __iostream_type(), _M_stringbuf(__mode, __a)
1227 { this->init(std::__addressof(_M_stringbuf)); }
1230 basic_stringstream(__string_type&& __str,
1231 ios_base::openmode __mode = ios_base::in
1233 : __iostream_type(), _M_stringbuf(std::move(__str), __mode)
1234 { this->init(std::__addressof(_M_stringbuf)); }
1236 template<typename _SAlloc>
1237 basic_stringstream(const basic_string<_CharT, _Traits, _SAlloc>& __str,
1238 const allocator_type& __a)
1239 : basic_stringstream(__str, ios_base::in | ios_base::out, __a)
1242 template<typename _SAlloc>
1243 basic_stringstream(const basic_string<_CharT, _Traits, _SAlloc>& __str,
1244 ios_base::openmode __mode,
1245 const allocator_type& __a)
1246 : __iostream_type(), _M_stringbuf(__str, __mode, __a)
1247 { this->init(std::__addressof(_M_stringbuf)); }
1249 template<typename _SAlloc>
1251 basic_stringstream(const basic_string<_CharT, _Traits, _SAlloc>& __str,
1252 ios_base::openmode __mode = ios_base::in
1254 : basic_stringstream(__str, __mode, allocator_type())
1258#ifdef __cpp_lib_sstream_from_string_view
1259 template <typename _Tp>
1261 basic_stringstream(const _Tp& __t,
1262 ios_base::openmode __mode = ios_base::in | ios_base::out)
1263 requires (is_convertible_v<const _Tp&,
1264 basic_string_view<_CharT, _Traits>>)
1265 : basic_stringstream(__t, __mode, allocator_type{})
1268 template <typename _Tp>
1269 basic_stringstream(const _Tp& __t, const allocator_type& __a)
1270 requires (is_convertible_v<const _Tp&,
1271 basic_string_view<_CharT, _Traits>>)
1272 : basic_stringstream(__t, ios_base::in | ios_base::out, __a)
1275 template <typename _Tp>
1276 basic_stringstream(const _Tp& __t, ios_base::openmode __mode,
1277 const allocator_type& __a)
1278 requires (is_convertible_v<const _Tp&, basic_string_view<_CharT, _Traits>>)
1279 : __iostream_type(), _M_stringbuf(__t, __mode, __a)
1280 { this->init(std::__addressof(_M_stringbuf)); }
1283 // 27.8.3.2 Assign and swap:
1286 operator=(const basic_stringstream&) = delete;
1289 operator=(basic_stringstream&& __rhs)
1291 __iostream_type::operator=(std::move(__rhs));
1292 _M_stringbuf = std::move(__rhs._M_stringbuf);
1297 swap(basic_stringstream& __rhs)
1299 __iostream_type::swap(__rhs);
1300 _M_stringbuf.swap(__rhs._M_stringbuf);
1306 * @brief Accessing the underlying buffer.
1307 * @return The current basic_stringbuf buffer.
1309 * This hides both signatures of std::basic_ios::rdbuf().
1314 { return const_cast<__stringbuf_type*>(std::__addressof(_M_stringbuf)); }
1317 * @brief Copying out the string buffer.
1318 * @return @c rdbuf()->str()
1322 str() const _GLIBCXX_LVAL_REF_QUAL
1323 { return _M_stringbuf.str(); }
1325#if __cplusplus > 201703L
1326#if _GLIBCXX_USE_CXX11_ABI
1328 // P0407 Allocator-aware basic_streambuf
1329 template<__allocator_like _SAlloc>
1331 basic_string<_CharT, _Traits, _SAlloc>
1332 str(const _SAlloc& __sa) const
1333 { return _M_stringbuf.str(__sa); }
1339 { return std::move(_M_stringbuf).str(); }
1342 _GLIBCXX_SSTREAM_ALWAYS_INLINE
1343 basic_string_view<char_type, traits_type>
1344 view() const noexcept
1345 { return _M_stringbuf.view(); }
1349 * @brief Setting a new buffer.
1350 * @param __s The string to use as a new sequence.
1352 * Calls @c rdbuf()->str(s).
1355 str(const __string_type& __s)
1356 { _M_stringbuf.str(__s); }
1358#if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
1360 // P0407 Allocator-aware basic_streambuf
1361 template<__allocator_like _SAlloc>
1362 requires (!is_same_v<_SAlloc, _Alloc>)
1364 str(const basic_string<_CharT, _Traits, _SAlloc>& __s)
1365 { _M_stringbuf.str(__s); }
1369 str(__string_type&& __s)
1370 { _M_stringbuf.str(std::move(__s)); }
1373#ifdef __cpp_lib_sstream_from_string_view
1374 template<typename _Tp>
1377 requires (is_convertible_v<const _Tp&,
1378 basic_string_view<_CharT, _Traits>>)
1379 { _M_stringbuf.str(__t); }
1383#if __cplusplus >= 201103L
1384 /// Swap specialization for stringbufs.
1385 template <class _CharT, class _Traits, class _Allocator>
1387 swap(basic_stringbuf<_CharT, _Traits, _Allocator>& __x,
1388 basic_stringbuf<_CharT, _Traits, _Allocator>& __y)
1389 noexcept(noexcept(__x.swap(__y)))
1392 /// Swap specialization for istringstreams.
1393 template <class _CharT, class _Traits, class _Allocator>
1395 swap(basic_istringstream<_CharT, _Traits, _Allocator>& __x,
1396 basic_istringstream<_CharT, _Traits, _Allocator>& __y)
1399 /// Swap specialization for ostringstreams.
1400 template <class _CharT, class _Traits, class _Allocator>
1402 swap(basic_ostringstream<_CharT, _Traits, _Allocator>& __x,
1403 basic_ostringstream<_CharT, _Traits, _Allocator>& __y)
1406 /// Swap specialization for stringstreams.
1407 template <class _CharT, class _Traits, class _Allocator>
1409 swap(basic_stringstream<_CharT, _Traits, _Allocator>& __x,
1410 basic_stringstream<_CharT, _Traits, _Allocator>& __y)
1414_GLIBCXX_END_NAMESPACE_CXX11
1415_GLIBCXX_END_NAMESPACE_VERSION
1418#undef _GLIBCXX_SSTREAM_ALWAYS_INLINE
1419#undef _GLIBCXX_LVAL_REF_QUAL
1421#include <bits/sstream.tcc>
1423#endif /* _GLIBCXX_SSTREAM */