1// String based streams -*- C++ -*-
3// Copyright (C) 1997-2022 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
36#pragma GCC system_header
40#include <bits/alloc_traits.h> // allocator_traits, __allocator_like
42#if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
43# define _GLIBCXX_LVAL_REF_QUAL &
44# define _GLIBCXX_SSTREAM_ALWAYS_INLINE
46# define _GLIBCXX_LVAL_REF_QUAL
47// For symbols that are not exported from libstdc++.so for the COW string ABI.
48# define _GLIBCXX_SSTREAM_ALWAYS_INLINE [[__gnu__::__always_inline__]]
53namespace std _GLIBCXX_VISIBILITY(default)
55_GLIBCXX_BEGIN_NAMESPACE_VERSION
56_GLIBCXX_BEGIN_NAMESPACE_CXX11
58 // [27.7.1] template class basic_stringbuf
60 * @brief The actual work of input and output (for std::string).
63 * @tparam _CharT Type of character stream.
64 * @tparam _Traits Traits for character type, defaults to
65 * char_traits<_CharT>.
66 * @tparam _Alloc Allocator type, defaults to allocator<_CharT>.
68 * This class associates either or both of its input and output sequences
69 * with a sequence of characters, which can be initialized from, or made
70 * available as, a @c std::basic_string. (Paraphrased from [27.7.1]/1.)
72 * For this class, open modes (of type @c ios_base::openmode) have
73 * @c in set if the input sequence can be read, and @c out set if the
74 * output sequence can be written.
76 template<typename _CharT, typename _Traits, typename _Alloc>
77 class basic_stringbuf : public basic_streambuf<_CharT, _Traits>
79 struct __xfer_bufptrs;
81#if __cplusplus >= 201103L
82 using allocator_traits = std::allocator_traits<_Alloc>;
84 = __or_<typename allocator_traits::propagate_on_container_swap,
85 typename allocator_traits::is_always_equal>;
90 typedef _CharT char_type;
91 typedef _Traits traits_type;
92 // _GLIBCXX_RESOLVE_LIB_DEFECTS
93 // 251. basic_stringbuf missing allocator_type
94 typedef _Alloc allocator_type;
95 typedef typename traits_type::int_type int_type;
96 typedef typename traits_type::pos_type pos_type;
97 typedef typename traits_type::off_type off_type;
99 typedef basic_streambuf<char_type, traits_type> __streambuf_type;
100 typedef basic_string<char_type, _Traits, _Alloc> __string_type;
101 typedef typename __string_type::size_type __size_type;
104 /// Place to stash in || out || in | out settings for current stringbuf.
105 ios_base::openmode _M_mode;
108 __string_type _M_string;
114 * @brief Starts with an empty string buffer.
116 * The default constructor initializes the parent class using its
120 : __streambuf_type(), _M_mode(ios_base::in | ios_base::out), _M_string()
124 * @brief Starts with an empty string buffer.
125 * @param __mode Whether the buffer can read, or write, or both.
127 * The default constructor initializes the parent class using its
131 basic_stringbuf(ios_base::openmode __mode)
132 : __streambuf_type(), _M_mode(__mode), _M_string()
136 * @brief Starts with an existing string buffer.
137 * @param __str A string to copy as a starting buffer.
138 * @param __mode Whether the buffer can read, or write, or both.
140 * This constructor initializes the parent class using its
144 basic_stringbuf(const __string_type& __str,
145 ios_base::openmode __mode = ios_base::in | ios_base::out)
146 : __streambuf_type(), _M_mode(),
147 _M_string(__str.data(), __str.size(), __str.get_allocator())
148 { _M_stringbuf_init(__mode); }
150#if __cplusplus >= 201103L
151 basic_stringbuf(const basic_stringbuf&) = delete;
153 basic_stringbuf(basic_stringbuf&& __rhs)
154 : basic_stringbuf(std::move(__rhs), __xfer_bufptrs(__rhs, this))
155 { __rhs._M_sync(const_cast<char_type*>(__rhs._M_string.data()), 0, 0); }
157#if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
159 basic_stringbuf(const allocator_type& __a)
160 : basic_stringbuf(ios_base::in | std::ios_base::out, __a)
163 basic_stringbuf(ios_base::openmode __mode,
164 const allocator_type& __a)
165 : __streambuf_type(), _M_mode(__mode), _M_string(__a)
169 basic_stringbuf(__string_type&& __s,
170 ios_base::openmode __mode = ios_base::in
172 : __streambuf_type(), _M_mode(__mode), _M_string(std::move(__s))
173 { _M_stringbuf_init(__mode); }
175 template<typename _SAlloc>
176 basic_stringbuf(const basic_string<_CharT, _Traits, _SAlloc>& __s,
177 const allocator_type& __a)
178 : basic_stringbuf(__s, ios_base::in | std::ios_base::out, __a)
181 template<typename _SAlloc>
182 basic_stringbuf(const basic_string<_CharT, _Traits, _SAlloc>& __s,
183 ios_base::openmode __mode,
184 const allocator_type& __a)
185 : __streambuf_type(), _M_mode(__mode),
186 _M_string(__s.data(), __s.size(), __a)
187 { _M_stringbuf_init(__mode); }
189 template<typename _SAlloc>
191 basic_stringbuf(const basic_string<_CharT, _Traits, _SAlloc>& __s,
192 ios_base::openmode __mode = ios_base::in
194 : basic_stringbuf(__s, __mode, allocator_type{})
197 basic_stringbuf(basic_stringbuf&& __rhs, const allocator_type& __a)
198 : basic_stringbuf(std::move(__rhs), __a, __xfer_bufptrs(__rhs, this))
199 { __rhs._M_sync(const_cast<char_type*>(__rhs._M_string.data()), 0, 0); }
201 allocator_type get_allocator() const noexcept
202 { return _M_string.get_allocator(); }
205 // 27.8.2.2 Assign and swap:
208 operator=(const basic_stringbuf&) = delete;
211 operator=(basic_stringbuf&& __rhs)
213 __xfer_bufptrs __st{__rhs, this};
214 const __streambuf_type& __base = __rhs;
215 __streambuf_type::operator=(__base);
216 this->pubimbue(__rhs.getloc());
217 _M_mode = __rhs._M_mode;
218 _M_string = std::move(__rhs._M_string);
219 __rhs._M_sync(const_cast<char_type*>(__rhs._M_string.data()), 0, 0);
224 swap(basic_stringbuf& __rhs) noexcept(_Noexcept_swap::value)
226 __xfer_bufptrs __l_st{*this, std::__addressof(__rhs)};
227 __xfer_bufptrs __r_st{__rhs, this};
228 __streambuf_type& __base = __rhs;
229 __streambuf_type::swap(__base);
230 __rhs.pubimbue(this->pubimbue(__rhs.getloc()));
231 std::swap(_M_mode, __rhs._M_mode);
232 std::swap(_M_string, __rhs._M_string); // XXX not exception safe
236 // Getters and setters:
239 * @brief Copying out the string buffer.
240 * @return A copy of one of the underlying sequences.
242 * <em>If the buffer is only created in input mode, the underlying
243 * character sequence is equal to the input sequence; otherwise, it
244 * is equal to the output sequence.</em> [27.7.1.2]/1
247 str() const _GLIBCXX_LVAL_REF_QUAL
249 __string_type __ret(_M_string.get_allocator());
250 if (char_type* __hi = _M_high_mark())
251 __ret.assign(this->pbase(), __hi);
257#if __cplusplus > 201703L
258#if _GLIBCXX_USE_CXX11_ABI
260 template<__allocator_like _SAlloc>
261 basic_string<_CharT, _Traits, _SAlloc>
262 str(const _SAlloc& __sa) const
265 return { __sv.data(), __sv.size(), __sa };
272 if (char_type* __hi = _M_high_mark())
274 // Set length to end of character sequence and add null terminator.
275 _M_string._M_set_length(_M_high_mark() - this->pbase());
277 auto __str = std::move(_M_string);
279 _M_sync(_M_string.data(), 0, 0);
284 _GLIBCXX_SSTREAM_ALWAYS_INLINE
285 basic_string_view<char_type, traits_type>
286 view() const noexcept
288 if (char_type* __hi = _M_high_mark())
289 return { this->pbase(), __hi };
296 * @brief Setting a new buffer.
297 * @param __s The string to use as a new sequence.
299 * Deallocates any previous stored sequence, then copies @a s to
303 str(const __string_type& __s)
305 // Cannot use _M_string = __s, since v3 strings are COW
306 // (not always true now but assign() always works).
307 _M_string.assign(__s.data(), __s.size());
308 _M_stringbuf_init(_M_mode);
311#if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
313 template<__allocator_like _SAlloc>
314 requires (!is_same_v<_SAlloc, _Alloc>)
316 str(const basic_string<_CharT, _Traits, _SAlloc>& __s)
318 _M_string.assign(__s.data(), __s.size());
319 _M_stringbuf_init(_M_mode);
324 str(__string_type&& __s)
326 _M_string = std::move(__s);
327 _M_stringbuf_init(_M_mode);
332 // Common initialization code goes here.
334 _M_stringbuf_init(ios_base::openmode __mode)
337 __size_type __len = 0;
338 if (_M_mode & (ios_base::ate | ios_base::app))
339 __len = _M_string.size();
340 _M_sync(const_cast<char_type*>(_M_string.data()), 0, __len);
346 streamsize __ret = -1;
347 if (_M_mode & ios_base::in)
350 __ret = this->egptr() - this->gptr();
359 pbackfail(int_type __c = traits_type::eof());
362 overflow(int_type __c = traits_type::eof());
365 * @brief Manipulates the buffer.
366 * @param __s Pointer to a buffer area.
367 * @param __n Size of @a __s.
370 * If no buffer has already been created, and both @a __s and @a __n are
371 * non-zero, then @c __s is used as a buffer; see
372 * https://gcc.gnu.org/onlinedocs/libstdc++/manual/streambufs.html#io.streambuf.buffering
375 virtual __streambuf_type*
376 setbuf(char_type* __s, streamsize __n)
380 // This is implementation-defined behavior, and assumes
381 // that an external char_type array of length __n exists
382 // and has been pre-allocated. If this is not the case,
383 // things will quickly blow up.
385 // Step 1: Destroy the current internal array.
388 // Step 2: Use the external array.
389 _M_sync(__s, __n, 0);
395 seekoff(off_type __off, ios_base::seekdir __way,
396 ios_base::openmode __mode = ios_base::in | ios_base::out);
399 seekpos(pos_type __sp,
400 ios_base::openmode __mode = ios_base::in | ios_base::out);
402 // Internal function for correctly updating the internal buffer
403 // for a particular _M_string, due to initialization or re-sizing
404 // of an existing _M_string.
406 _M_sync(char_type* __base, __size_type __i, __size_type __o);
408 // Internal function for correctly updating egptr() to the actual
413 if (char_type* __pptr = this->pptr())
415 char_type* __egptr = this->egptr();
416 if (!__egptr || __pptr > __egptr)
418 if (_M_mode & ios_base::in)
419 this->setg(this->eback(), this->gptr(), __pptr);
421 this->setg(__pptr, __pptr, __pptr);
426 // Works around the issue with pbump, part of the protected
427 // interface of basic_streambuf, taking just an int.
429 _M_pbump(char_type* __pbeg, char_type* __pend, off_type __off);
432 // Return a pointer to the end of the underlying character sequence.
433 // This might not be the same character as _M_string.end() because
434 // basic_stringbuf::overflow might have written to unused capacity
435 // in _M_string without updating its length.
436 __attribute__((__always_inline__))
438 _M_high_mark() const _GLIBCXX_NOEXCEPT
440 if (char_type* __pptr = this->pptr())
442 char_type* __egptr = this->egptr();
443 if (!__egptr || __pptr > __egptr)
444 return __pptr; // Underlying sequence is [pbase, pptr).
446 return __egptr; // Underlying sequence is [pbase, egptr).
448 return 0; // Underlying character sequence is just _M_string.
451#if __cplusplus >= 201103L
452#if _GLIBCXX_USE_CXX11_ABI
453 // This type captures the state of the gptr / pptr pointers as offsets
454 // so they can be restored in another object after moving the string.
455 struct __xfer_bufptrs
457 __xfer_bufptrs(const basic_stringbuf& __from, basic_stringbuf* __to)
458 : _M_to{__to}, _M_goff{-1, -1, -1}, _M_poff{-1, -1, -1}
460 const _CharT* const __str = __from._M_string.data();
461 const _CharT* __end = nullptr;
464 _M_goff[0] = __from.eback() - __str;
465 _M_goff[1] = __from.gptr() - __str;
466 _M_goff[2] = __from.egptr() - __str;
467 __end = __from.egptr();
471 _M_poff[0] = __from.pbase() - __str;
472 _M_poff[1] = __from.pptr() - __from.pbase();
473 _M_poff[2] = __from.epptr() - __str;
474 if (!__end || __from.pptr() > __end)
475 __end = __from.pptr();
478 // Set _M_string length to the greater of the get and put areas.
481 // The const_cast avoids changing this constructor's signature,
482 // because it is exported from the dynamic library.
483 auto& __mut_from = const_cast<basic_stringbuf&>(__from);
484 __mut_from._M_string._M_length(__end - __str);
490 char_type* __str = const_cast<char_type*>(_M_to->_M_string.data());
491 if (_M_goff[0] != -1)
492 _M_to->setg(__str+_M_goff[0], __str+_M_goff[1], __str+_M_goff[2]);
493 if (_M_poff[0] != -1)
494 _M_to->_M_pbump(__str+_M_poff[0], __str+_M_poff[2], _M_poff[1]);
497 basic_stringbuf* _M_to;
502 // This type does nothing when using Copy-On-Write strings.
503 struct __xfer_bufptrs
505 __xfer_bufptrs(const basic_stringbuf&, basic_stringbuf*) { }
509 // The move constructor initializes an __xfer_bufptrs temporary then
510 // delegates to this constructor to performs moves during its lifetime.
511 basic_stringbuf(basic_stringbuf&& __rhs, __xfer_bufptrs&&)
512 : __streambuf_type(static_cast<const __streambuf_type&>(__rhs)),
513 _M_mode(__rhs._M_mode), _M_string(std::move(__rhs._M_string))
516#if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
517 // The move constructor initializes an __xfer_bufptrs temporary then
518 // delegates to this constructor to performs moves during its lifetime.
519 basic_stringbuf(basic_stringbuf&& __rhs, const allocator_type& __a,
521 : __streambuf_type(static_cast<const __streambuf_type&>(__rhs)),
522 _M_mode(__rhs._M_mode), _M_string(std::move(__rhs._M_string), __a)
529 // [27.7.2] Template class basic_istringstream
531 * @brief Controlling input for std::string.
534 * @tparam _CharT Type of character stream.
535 * @tparam _Traits Traits for character type, defaults to
536 * char_traits<_CharT>.
537 * @tparam _Alloc Allocator type, defaults to allocator<_CharT>.
539 * This class supports reading from objects of type std::basic_string,
540 * using the inherited functions from std::basic_istream. To control
541 * the associated sequence, an instance of std::basic_stringbuf is used,
542 * which this page refers to as @c sb.
544 template<typename _CharT, typename _Traits, typename _Alloc>
545 class basic_istringstream : public basic_istream<_CharT, _Traits>
549 typedef _CharT char_type;
550 typedef _Traits traits_type;
551 // _GLIBCXX_RESOLVE_LIB_DEFECTS
552 // 251. basic_stringbuf missing allocator_type
553 typedef _Alloc allocator_type;
554 typedef typename traits_type::int_type int_type;
555 typedef typename traits_type::pos_type pos_type;
556 typedef typename traits_type::off_type off_type;
558 // Non-standard types:
559 typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
560 typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type;
561 typedef basic_istream<char_type, traits_type> __istream_type;
564 __stringbuf_type _M_stringbuf;
570 * @brief Default constructor starts with an empty string buffer.
572 * Initializes @c sb using @c in, and passes @c &sb to the base
573 * class initializer. Does not allocate any buffer.
575 * That's a lie. We initialize the base class with NULL, because the
576 * string class does its own memory management.
578 basic_istringstream()
579 : __istream_type(), _M_stringbuf(ios_base::in)
580 { this->init(&_M_stringbuf); }
583 * @brief Starts with an empty string buffer.
584 * @param __mode Whether the buffer can read, or write, or both.
586 * @c ios_base::in is automatically included in @a __mode.
588 * Initializes @c sb using @c __mode|in, and passes @c &sb to the base
589 * class initializer. Does not allocate any buffer.
591 * That's a lie. We initialize the base class with NULL, because the
592 * string class does its own memory management.
595 basic_istringstream(ios_base::openmode __mode)
596 : __istream_type(), _M_stringbuf(__mode | ios_base::in)
597 { this->init(&_M_stringbuf); }
600 * @brief Starts with an existing string buffer.
601 * @param __str A string to copy as a starting buffer.
602 * @param __mode Whether the buffer can read, or write, or both.
604 * @c ios_base::in is automatically included in @a mode.
606 * Initializes @c sb using @a str and @c mode|in, and passes @c &sb
607 * to the base class initializer.
609 * That's a lie. We initialize the base class with NULL, because the
610 * string class does its own memory management.
613 basic_istringstream(const __string_type& __str,
614 ios_base::openmode __mode = ios_base::in)
615 : __istream_type(), _M_stringbuf(__str, __mode | ios_base::in)
616 { this->init(&_M_stringbuf); }
619 * @brief The destructor does nothing.
621 * The buffer is deallocated by the stringbuf object, not the
624 ~basic_istringstream()
627#if __cplusplus >= 201103L
628 basic_istringstream(const basic_istringstream&) = delete;
630 basic_istringstream(basic_istringstream&& __rhs)
631 : __istream_type(std::move(__rhs)),
632 _M_stringbuf(std::move(__rhs._M_stringbuf))
633 { __istream_type::set_rdbuf(&_M_stringbuf); }
635#if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
636 basic_istringstream(ios_base::openmode __mode, const allocator_type& __a)
637 : __istream_type(), _M_stringbuf(__mode | ios_base::in, __a)
638 { this->init(std::__addressof(_M_stringbuf)); }
641 basic_istringstream(__string_type&& __str,
642 ios_base::openmode __mode = ios_base::in)
643 : __istream_type(), _M_stringbuf(std::move(__str), __mode | ios_base::in)
644 { this->init(std::__addressof(_M_stringbuf)); }
646 template<typename _SAlloc>
647 basic_istringstream(const basic_string<_CharT, _Traits, _SAlloc>& __str,
648 const allocator_type& __a)
649 : basic_istringstream(__str, ios_base::in, __a)
652 template<typename _SAlloc>
653 basic_istringstream(const basic_string<_CharT, _Traits, _SAlloc>& __str,
654 ios_base::openmode __mode,
655 const allocator_type& __a)
656 : __istream_type(), _M_stringbuf(__str, __mode | ios_base::in, __a)
657 { this->init(std::__addressof(_M_stringbuf)); }
659 template<typename _SAlloc>
661 basic_istringstream(const basic_string<_CharT, _Traits, _SAlloc>& __str,
662 ios_base::openmode __mode = ios_base::in)
663 : basic_istringstream(__str, __mode, allocator_type())
667 // 27.8.3.2 Assign and swap:
670 operator=(const basic_istringstream&) = delete;
673 operator=(basic_istringstream&& __rhs)
675 __istream_type::operator=(std::move(__rhs));
676 _M_stringbuf = std::move(__rhs._M_stringbuf);
681 swap(basic_istringstream& __rhs)
683 __istream_type::swap(__rhs);
684 _M_stringbuf.swap(__rhs._M_stringbuf);
690 * @brief Accessing the underlying buffer.
691 * @return The current basic_stringbuf buffer.
693 * This hides both signatures of std::basic_ios::rdbuf().
697 { return const_cast<__stringbuf_type*>(&_M_stringbuf); }
700 * @brief Copying out the string buffer.
701 * @return @c rdbuf()->str()
704 str() const _GLIBCXX_LVAL_REF_QUAL
705 { return _M_stringbuf.str(); }
707#if __cplusplus > 201703L
708#if _GLIBCXX_USE_CXX11_ABI
710 template<__allocator_like _SAlloc>
711 basic_string<_CharT, _Traits, _SAlloc>
712 str(const _SAlloc& __sa) const
713 { return _M_stringbuf.str(__sa); }
718 { return std::move(_M_stringbuf).str(); }
721 _GLIBCXX_SSTREAM_ALWAYS_INLINE
722 basic_string_view<char_type, traits_type>
723 view() const noexcept
724 { return _M_stringbuf.view(); }
728 * @brief Setting a new buffer.
729 * @param __s The string to use as a new sequence.
731 * Calls @c rdbuf()->str(s).
734 str(const __string_type& __s)
735 { _M_stringbuf.str(__s); }
737#if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
739 template<__allocator_like _SAlloc>
740 requires (!is_same_v<_SAlloc, _Alloc>)
742 str(const basic_string<_CharT, _Traits, _SAlloc>& __s)
743 { _M_stringbuf.str(__s); }
747 str(__string_type&& __s)
748 { _M_stringbuf.str(std::move(__s)); }
753 // [27.7.3] Template class basic_ostringstream
755 * @brief Controlling output for std::string.
758 * @tparam _CharT Type of character stream.
759 * @tparam _Traits Traits for character type, defaults to
760 * char_traits<_CharT>.
761 * @tparam _Alloc Allocator type, defaults to allocator<_CharT>.
763 * This class supports writing to objects of type std::basic_string,
764 * using the inherited functions from std::basic_ostream. To control
765 * the associated sequence, an instance of std::basic_stringbuf is used,
766 * which this page refers to as @c sb.
768 template <typename _CharT, typename _Traits, typename _Alloc>
769 class basic_ostringstream : public basic_ostream<_CharT, _Traits>
773 typedef _CharT char_type;
774 typedef _Traits traits_type;
775 // _GLIBCXX_RESOLVE_LIB_DEFECTS
776 // 251. basic_stringbuf missing allocator_type
777 typedef _Alloc allocator_type;
778 typedef typename traits_type::int_type int_type;
779 typedef typename traits_type::pos_type pos_type;
780 typedef typename traits_type::off_type off_type;
782 // Non-standard types:
783 typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
784 typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type;
785 typedef basic_ostream<char_type, traits_type> __ostream_type;
788 __stringbuf_type _M_stringbuf;
791 // Constructors/destructor:
794 * @brief Default constructor starts with an empty string buffer.
796 * Initializes @c sb using @c mode|out, and passes @c &sb to the base
797 * class initializer. Does not allocate any buffer.
799 * That's a lie. We initialize the base class with NULL, because the
800 * string class does its own memory management.
802 basic_ostringstream()
803 : __ostream_type(), _M_stringbuf(ios_base::out)
804 { this->init(&_M_stringbuf); }
807 * @brief Starts with an empty string buffer.
808 * @param __mode Whether the buffer can read, or write, or both.
810 * @c ios_base::out is automatically included in @a mode.
812 * Initializes @c sb using @c mode|out, and passes @c &sb to the base
813 * class initializer. Does not allocate any buffer.
815 * That's a lie. We initialize the base class with NULL, because the
816 * string class does its own memory management.
819 basic_ostringstream(ios_base::openmode __mode)
820 : __ostream_type(), _M_stringbuf(__mode | ios_base::out)
821 { this->init(&_M_stringbuf); }
824 * @brief Starts with an existing string buffer.
825 * @param __str A string to copy as a starting buffer.
826 * @param __mode Whether the buffer can read, or write, or both.
828 * @c ios_base::out is automatically included in @a mode.
830 * Initializes @c sb using @a str and @c mode|out, and passes @c &sb
831 * to the base class initializer.
833 * That's a lie. We initialize the base class with NULL, because the
834 * string class does its own memory management.
837 basic_ostringstream(const __string_type& __str,
838 ios_base::openmode __mode = ios_base::out)
839 : __ostream_type(), _M_stringbuf(__str, __mode | ios_base::out)
840 { this->init(&_M_stringbuf); }
843 * @brief The destructor does nothing.
845 * The buffer is deallocated by the stringbuf object, not the
848 ~basic_ostringstream()
851#if __cplusplus >= 201103L
852 basic_ostringstream(const basic_ostringstream&) = delete;
854 basic_ostringstream(basic_ostringstream&& __rhs)
855 : __ostream_type(std::move(__rhs)),
856 _M_stringbuf(std::move(__rhs._M_stringbuf))
857 { __ostream_type::set_rdbuf(&_M_stringbuf); }
859#if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
860 basic_ostringstream(ios_base::openmode __mode, const allocator_type& __a)
861 : __ostream_type(), _M_stringbuf(__mode | ios_base::out, __a)
862 { this->init(std::__addressof(_M_stringbuf)); }
865 basic_ostringstream(__string_type&& __str,
866 ios_base::openmode __mode = ios_base::out)
867 : __ostream_type(), _M_stringbuf(std::move(__str), __mode | ios_base::out)
868 { this->init(std::__addressof(_M_stringbuf)); }
870 template<typename _SAlloc>
871 basic_ostringstream(const basic_string<_CharT, _Traits, _SAlloc>& __str,
872 const allocator_type& __a)
873 : basic_ostringstream(__str, ios_base::out, __a)
876 template<typename _SAlloc>
877 basic_ostringstream(const basic_string<_CharT, _Traits, _SAlloc>& __str,
878 ios_base::openmode __mode,
879 const allocator_type& __a)
880 : __ostream_type(), _M_stringbuf(__str, __mode | ios_base::out, __a)
881 { this->init(std::__addressof(_M_stringbuf)); }
883 template<typename _SAlloc>
885 basic_ostringstream(const basic_string<_CharT, _Traits, _SAlloc>& __str,
886 ios_base::openmode __mode = ios_base::out)
887 : basic_ostringstream(__str, __mode, allocator_type())
891 // 27.8.3.2 Assign and swap:
894 operator=(const basic_ostringstream&) = delete;
897 operator=(basic_ostringstream&& __rhs)
899 __ostream_type::operator=(std::move(__rhs));
900 _M_stringbuf = std::move(__rhs._M_stringbuf);
905 swap(basic_ostringstream& __rhs)
907 __ostream_type::swap(__rhs);
908 _M_stringbuf.swap(__rhs._M_stringbuf);
914 * @brief Accessing the underlying buffer.
915 * @return The current basic_stringbuf buffer.
917 * This hides both signatures of std::basic_ios::rdbuf().
921 { return const_cast<__stringbuf_type*>(&_M_stringbuf); }
924 * @brief Copying out the string buffer.
925 * @return @c rdbuf()->str()
928 str() const _GLIBCXX_LVAL_REF_QUAL
929 { return _M_stringbuf.str(); }
931#if __cplusplus > 201703L
932#if _GLIBCXX_USE_CXX11_ABI
934 template<__allocator_like _SAlloc>
935 basic_string<_CharT, _Traits, _SAlloc>
936 str(const _SAlloc& __sa) const
937 { return _M_stringbuf.str(__sa); }
942 { return std::move(_M_stringbuf).str(); }
945 _GLIBCXX_SSTREAM_ALWAYS_INLINE
946 basic_string_view<char_type, traits_type>
947 view() const noexcept
948 { return _M_stringbuf.view(); }
952 * @brief Setting a new buffer.
953 * @param __s The string to use as a new sequence.
955 * Calls @c rdbuf()->str(s).
958 str(const __string_type& __s)
959 { _M_stringbuf.str(__s); }
961#if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
963 template<__allocator_like _SAlloc>
964 requires (!is_same_v<_SAlloc, _Alloc>)
966 str(const basic_string<_CharT, _Traits, _SAlloc>& __s)
967 { _M_stringbuf.str(__s); }
971 str(__string_type&& __s)
972 { _M_stringbuf.str(std::move(__s)); }
977 // [27.7.4] Template class basic_stringstream
979 * @brief Controlling input and output for std::string.
982 * @tparam _CharT Type of character stream.
983 * @tparam _Traits Traits for character type, defaults to
984 * char_traits<_CharT>.
985 * @tparam _Alloc Allocator type, defaults to allocator<_CharT>.
987 * This class supports reading from and writing to objects of type
988 * std::basic_string, using the inherited functions from
989 * std::basic_iostream. To control the associated sequence, an instance
990 * of std::basic_stringbuf is used, which this page refers to as @c sb.
992 template <typename _CharT, typename _Traits, typename _Alloc>
993 class basic_stringstream : public basic_iostream<_CharT, _Traits>
997 typedef _CharT char_type;
998 typedef _Traits traits_type;
999 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1000 // 251. basic_stringbuf missing allocator_type
1001 typedef _Alloc allocator_type;
1002 typedef typename traits_type::int_type int_type;
1003 typedef typename traits_type::pos_type pos_type;
1004 typedef typename traits_type::off_type off_type;
1006 // Non-standard Types:
1007 typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
1008 typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type;
1009 typedef basic_iostream<char_type, traits_type> __iostream_type;
1012 __stringbuf_type _M_stringbuf;
1015 // Constructors/destructors
1018 * @brief Default constructor starts with an empty string buffer.
1020 * Initializes @c sb using the mode @c in|out, and passes @c &sb
1021 * to the base class initializer. Does not allocate any buffer.
1023 * That's a lie. We initialize the base class with NULL, because the
1024 * string class does its own memory management.
1026 basic_stringstream()
1027 : __iostream_type(), _M_stringbuf(ios_base::out | ios_base::in)
1028 { this->init(&_M_stringbuf); }
1031 * @brief Starts with an empty string buffer.
1032 * @param __m Whether the buffer can read, or write, or both.
1034 * Initializes @c sb using the mode from @c __m, and passes @c &sb
1035 * to the base class initializer. Does not allocate any buffer.
1037 * That's a lie. We initialize the base class with NULL, because the
1038 * string class does its own memory management.
1041 basic_stringstream(ios_base::openmode __m)
1042 : __iostream_type(), _M_stringbuf(__m)
1043 { this->init(&_M_stringbuf); }
1046 * @brief Starts with an existing string buffer.
1047 * @param __str A string to copy as a starting buffer.
1048 * @param __m Whether the buffer can read, or write, or both.
1050 * Initializes @c sb using @a __str and @c __m, and passes @c &sb
1051 * to the base class initializer.
1053 * That's a lie. We initialize the base class with NULL, because the
1054 * string class does its own memory management.
1057 basic_stringstream(const __string_type& __str,
1058 ios_base::openmode __m = ios_base::out | ios_base::in)
1059 : __iostream_type(), _M_stringbuf(__str, __m)
1060 { this->init(&_M_stringbuf); }
1063 * @brief The destructor does nothing.
1065 * The buffer is deallocated by the stringbuf object, not the
1066 * formatting stream.
1068 ~basic_stringstream()
1071#if __cplusplus >= 201103L
1072 basic_stringstream(const basic_stringstream&) = delete;
1074 basic_stringstream(basic_stringstream&& __rhs)
1075 : __iostream_type(std::move(__rhs)),
1076 _M_stringbuf(std::move(__rhs._M_stringbuf))
1077 { __iostream_type::set_rdbuf(&_M_stringbuf); }
1079#if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
1080 basic_stringstream(ios_base::openmode __mode, const allocator_type& __a)
1081 : __iostream_type(), _M_stringbuf(__mode, __a)
1082 { this->init(&_M_stringbuf); }
1085 basic_stringstream(__string_type&& __str,
1086 ios_base::openmode __mode = ios_base::in
1088 : __iostream_type(), _M_stringbuf(std::move(__str), __mode)
1089 { this->init(std::__addressof(_M_stringbuf)); }
1091 template<typename _SAlloc>
1092 basic_stringstream(const basic_string<_CharT, _Traits, _SAlloc>& __str,
1093 const allocator_type& __a)
1094 : basic_stringstream(__str, ios_base::in | ios_base::out, __a)
1097 template<typename _SAlloc>
1098 basic_stringstream(const basic_string<_CharT, _Traits, _SAlloc>& __str,
1099 ios_base::openmode __mode,
1100 const allocator_type& __a)
1101 : __iostream_type(), _M_stringbuf(__str, __mode, __a)
1102 { this->init(std::__addressof(_M_stringbuf)); }
1104 template<typename _SAlloc>
1106 basic_stringstream(const basic_string<_CharT, _Traits, _SAlloc>& __str,
1107 ios_base::openmode __mode = ios_base::in
1109 : basic_stringstream(__str, __mode, allocator_type())
1113 // 27.8.3.2 Assign and swap:
1116 operator=(const basic_stringstream&) = delete;
1119 operator=(basic_stringstream&& __rhs)
1121 __iostream_type::operator=(std::move(__rhs));
1122 _M_stringbuf = std::move(__rhs._M_stringbuf);
1127 swap(basic_stringstream& __rhs)
1129 __iostream_type::swap(__rhs);
1130 _M_stringbuf.swap(__rhs._M_stringbuf);
1136 * @brief Accessing the underlying buffer.
1137 * @return The current basic_stringbuf buffer.
1139 * This hides both signatures of std::basic_ios::rdbuf().
1143 { return const_cast<__stringbuf_type*>(&_M_stringbuf); }
1146 * @brief Copying out the string buffer.
1147 * @return @c rdbuf()->str()
1150 str() const _GLIBCXX_LVAL_REF_QUAL
1151 { return _M_stringbuf.str(); }
1153#if __cplusplus > 201703L
1154#if _GLIBCXX_USE_CXX11_ABI
1156 template<__allocator_like _SAlloc>
1157 basic_string<_CharT, _Traits, _SAlloc>
1158 str(const _SAlloc& __sa) const
1159 { return _M_stringbuf.str(__sa); }
1164 { return std::move(_M_stringbuf).str(); }
1167 _GLIBCXX_SSTREAM_ALWAYS_INLINE
1168 basic_string_view<char_type, traits_type>
1169 view() const noexcept
1170 { return _M_stringbuf.view(); }
1174 * @brief Setting a new buffer.
1175 * @param __s The string to use as a new sequence.
1177 * Calls @c rdbuf()->str(s).
1180 str(const __string_type& __s)
1181 { _M_stringbuf.str(__s); }
1183#if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
1185 template<__allocator_like _SAlloc>
1186 requires (!is_same_v<_SAlloc, _Alloc>)
1188 str(const basic_string<_CharT, _Traits, _SAlloc>& __s)
1189 { _M_stringbuf.str(__s); }
1193 str(__string_type&& __s)
1194 { _M_stringbuf.str(std::move(__s)); }
1198#if __cplusplus >= 201103L
1199 /// Swap specialization for stringbufs.
1200 template <class _CharT, class _Traits, class _Allocator>
1202 swap(basic_stringbuf<_CharT, _Traits, _Allocator>& __x,
1203 basic_stringbuf<_CharT, _Traits, _Allocator>& __y)
1204 noexcept(noexcept(__x.swap(__y)))
1207 /// Swap specialization for istringstreams.
1208 template <class _CharT, class _Traits, class _Allocator>
1210 swap(basic_istringstream<_CharT, _Traits, _Allocator>& __x,
1211 basic_istringstream<_CharT, _Traits, _Allocator>& __y)
1214 /// Swap specialization for ostringstreams.
1215 template <class _CharT, class _Traits, class _Allocator>
1217 swap(basic_ostringstream<_CharT, _Traits, _Allocator>& __x,
1218 basic_ostringstream<_CharT, _Traits, _Allocator>& __y)
1221 /// Swap specialization for stringstreams.
1222 template <class _CharT, class _Traits, class _Allocator>
1224 swap(basic_stringstream<_CharT, _Traits, _Allocator>& __x,
1225 basic_stringstream<_CharT, _Traits, _Allocator>& __y)
1229_GLIBCXX_END_NAMESPACE_CXX11
1230_GLIBCXX_END_NAMESPACE_VERSION
1233#undef _GLIBCXX_SSTREAM_ALWAYS_INLINE
1234#undef _GLIBCXX_LVAL_REF_QUAL
1236#include <bits/sstream.tcc>
1238#endif /* _GLIBCXX_SSTREAM */