sstream 38 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220
  1. // String based streams -*- C++ -*-
  2. // Copyright (C) 1997-2022 Free Software Foundation, Inc.
  3. //
  4. // This file is part of the GNU ISO C++ Library. This library is free
  5. // software; you can redistribute it and/or modify it under the
  6. // terms of the GNU General Public License as published by the
  7. // Free Software Foundation; either version 3, or (at your option)
  8. // any later version.
  9. // This library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. // Under Section 7 of GPL version 3, you are granted additional
  14. // permissions described in the GCC Runtime Library Exception, version
  15. // 3.1, as published by the Free Software Foundation.
  16. // You should have received a copy of the GNU General Public License and
  17. // a copy of the GCC Runtime Library Exception along with this program;
  18. // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
  19. // <http://www.gnu.org/licenses/>.
  20. /** @file include/sstream
  21. * This is a Standard C++ Library header.
  22. */
  23. //
  24. // ISO C++ 14882: 27.7 String-based streams
  25. //
  26. #ifndef _GLIBCXX_SSTREAM
  27. #define _GLIBCXX_SSTREAM 1
  28. #pragma GCC system_header
  29. #include <istream>
  30. #include <ostream>
  31. #include <bits/alloc_traits.h> // allocator_traits, __allocator_like
  32. #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
  33. # define _GLIBCXX_LVAL_REF_QUAL &
  34. #else
  35. # define _GLIBCXX_LVAL_REF_QUAL
  36. #endif
  37. namespace std _GLIBCXX_VISIBILITY(default)
  38. {
  39. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  40. _GLIBCXX_BEGIN_NAMESPACE_CXX11
  41. // [27.7.1] template class basic_stringbuf
  42. /**
  43. * @brief The actual work of input and output (for std::string).
  44. * @ingroup io
  45. *
  46. * @tparam _CharT Type of character stream.
  47. * @tparam _Traits Traits for character type, defaults to
  48. * char_traits<_CharT>.
  49. * @tparam _Alloc Allocator type, defaults to allocator<_CharT>.
  50. *
  51. * This class associates either or both of its input and output sequences
  52. * with a sequence of characters, which can be initialized from, or made
  53. * available as, a @c std::basic_string. (Paraphrased from [27.7.1]/1.)
  54. *
  55. * For this class, open modes (of type @c ios_base::openmode) have
  56. * @c in set if the input sequence can be read, and @c out set if the
  57. * output sequence can be written.
  58. */
  59. template<typename _CharT, typename _Traits, typename _Alloc>
  60. class basic_stringbuf : public basic_streambuf<_CharT, _Traits>
  61. {
  62. struct __xfer_bufptrs;
  63. #if __cplusplus >= 201103L
  64. using allocator_traits = std::allocator_traits<_Alloc>;
  65. using _Noexcept_swap
  66. = __or_<typename allocator_traits::propagate_on_container_swap,
  67. typename allocator_traits::is_always_equal>;
  68. #endif
  69. public:
  70. // Types:
  71. typedef _CharT char_type;
  72. typedef _Traits traits_type;
  73. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  74. // 251. basic_stringbuf missing allocator_type
  75. typedef _Alloc allocator_type;
  76. typedef typename traits_type::int_type int_type;
  77. typedef typename traits_type::pos_type pos_type;
  78. typedef typename traits_type::off_type off_type;
  79. typedef basic_streambuf<char_type, traits_type> __streambuf_type;
  80. typedef basic_string<char_type, _Traits, _Alloc> __string_type;
  81. typedef typename __string_type::size_type __size_type;
  82. protected:
  83. /// Place to stash in || out || in | out settings for current stringbuf.
  84. ios_base::openmode _M_mode;
  85. // Data Members:
  86. __string_type _M_string;
  87. public:
  88. // Constructors:
  89. /**
  90. * @brief Starts with an empty string buffer.
  91. *
  92. * The default constructor initializes the parent class using its
  93. * own default ctor.
  94. */
  95. basic_stringbuf()
  96. : __streambuf_type(), _M_mode(ios_base::in | ios_base::out), _M_string()
  97. { }
  98. /**
  99. * @brief Starts with an empty string buffer.
  100. * @param __mode Whether the buffer can read, or write, or both.
  101. *
  102. * The default constructor initializes the parent class using its
  103. * own default ctor.
  104. */
  105. explicit
  106. basic_stringbuf(ios_base::openmode __mode)
  107. : __streambuf_type(), _M_mode(__mode), _M_string()
  108. { }
  109. /**
  110. * @brief Starts with an existing string buffer.
  111. * @param __str A string to copy as a starting buffer.
  112. * @param __mode Whether the buffer can read, or write, or both.
  113. *
  114. * This constructor initializes the parent class using its
  115. * own default ctor.
  116. */
  117. explicit
  118. basic_stringbuf(const __string_type& __str,
  119. ios_base::openmode __mode = ios_base::in | ios_base::out)
  120. : __streambuf_type(), _M_mode(),
  121. _M_string(__str.data(), __str.size(), __str.get_allocator())
  122. { _M_stringbuf_init(__mode); }
  123. #if __cplusplus >= 201103L
  124. basic_stringbuf(const basic_stringbuf&) = delete;
  125. basic_stringbuf(basic_stringbuf&& __rhs)
  126. : basic_stringbuf(std::move(__rhs), __xfer_bufptrs(__rhs, this))
  127. { __rhs._M_sync(const_cast<char_type*>(__rhs._M_string.data()), 0, 0); }
  128. #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
  129. explicit
  130. basic_stringbuf(const allocator_type& __a)
  131. : basic_stringbuf(ios_base::in | std::ios_base::out, __a)
  132. { }
  133. basic_stringbuf(ios_base::openmode __mode,
  134. const allocator_type& __a)
  135. : __streambuf_type(), _M_mode(__mode), _M_string(__a)
  136. { }
  137. explicit
  138. basic_stringbuf(__string_type&& __s,
  139. ios_base::openmode __mode = ios_base::in
  140. | ios_base::out)
  141. : __streambuf_type(), _M_mode(__mode), _M_string(std::move(__s))
  142. { _M_stringbuf_init(__mode); }
  143. template<typename _SAlloc>
  144. basic_stringbuf(const basic_string<_CharT, _Traits, _SAlloc>& __s,
  145. const allocator_type& __a)
  146. : basic_stringbuf(__s, ios_base::in | std::ios_base::out, __a)
  147. { }
  148. template<typename _SAlloc>
  149. basic_stringbuf(const basic_string<_CharT, _Traits, _SAlloc>& __s,
  150. ios_base::openmode __mode,
  151. const allocator_type& __a)
  152. : __streambuf_type(), _M_mode(__mode),
  153. _M_string(__s.data(), __s.size(), __a)
  154. { _M_stringbuf_init(__mode); }
  155. template<typename _SAlloc>
  156. explicit
  157. basic_stringbuf(const basic_string<_CharT, _Traits, _SAlloc>& __s,
  158. ios_base::openmode __mode = ios_base::in
  159. | ios_base::out)
  160. : basic_stringbuf(__s, __mode, allocator_type{})
  161. { }
  162. basic_stringbuf(basic_stringbuf&& __rhs, const allocator_type& __a)
  163. : basic_stringbuf(std::move(__rhs), __a, __xfer_bufptrs(__rhs, this))
  164. { __rhs._M_sync(const_cast<char_type*>(__rhs._M_string.data()), 0, 0); }
  165. allocator_type get_allocator() const noexcept
  166. { return _M_string.get_allocator(); }
  167. #endif // C++20
  168. // 27.8.2.2 Assign and swap:
  169. basic_stringbuf&
  170. operator=(const basic_stringbuf&) = delete;
  171. basic_stringbuf&
  172. operator=(basic_stringbuf&& __rhs)
  173. {
  174. __xfer_bufptrs __st{__rhs, this};
  175. const __streambuf_type& __base = __rhs;
  176. __streambuf_type::operator=(__base);
  177. this->pubimbue(__rhs.getloc());
  178. _M_mode = __rhs._M_mode;
  179. _M_string = std::move(__rhs._M_string);
  180. __rhs._M_sync(const_cast<char_type*>(__rhs._M_string.data()), 0, 0);
  181. return *this;
  182. }
  183. void
  184. swap(basic_stringbuf& __rhs) noexcept(_Noexcept_swap::value)
  185. {
  186. __xfer_bufptrs __l_st{*this, std::__addressof(__rhs)};
  187. __xfer_bufptrs __r_st{__rhs, this};
  188. __streambuf_type& __base = __rhs;
  189. __streambuf_type::swap(__base);
  190. __rhs.pubimbue(this->pubimbue(__rhs.getloc()));
  191. std::swap(_M_mode, __rhs._M_mode);
  192. std::swap(_M_string, __rhs._M_string); // XXX not exception safe
  193. }
  194. #endif // C++11
  195. // Getters and setters:
  196. /**
  197. * @brief Copying out the string buffer.
  198. * @return A copy of one of the underlying sequences.
  199. *
  200. * <em>If the buffer is only created in input mode, the underlying
  201. * character sequence is equal to the input sequence; otherwise, it
  202. * is equal to the output sequence.</em> [27.7.1.2]/1
  203. */
  204. __string_type
  205. str() const _GLIBCXX_LVAL_REF_QUAL
  206. {
  207. __string_type __ret(_M_string.get_allocator());
  208. if (char_type* __hi = _M_high_mark())
  209. __ret.assign(this->pbase(), __hi);
  210. else
  211. __ret = _M_string;
  212. return __ret;
  213. }
  214. #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
  215. #if __cpp_concepts
  216. template<__allocator_like _SAlloc>
  217. basic_string<_CharT, _Traits, _SAlloc>
  218. str(const _SAlloc& __sa) const
  219. {
  220. auto __sv = view();
  221. return { __sv.data(), __sv.size(), __sa };
  222. }
  223. #endif
  224. __string_type
  225. str() &&
  226. {
  227. if (char_type* __hi = _M_high_mark())
  228. {
  229. // Set length to end of character sequence and add null terminator.
  230. _M_string._M_set_length(_M_high_mark() - this->pbase());
  231. }
  232. auto __str = std::move(_M_string);
  233. _M_string.clear();
  234. _M_sync(_M_string.data(), 0, 0);
  235. return __str;
  236. }
  237. basic_string_view<char_type, traits_type>
  238. view() const noexcept
  239. {
  240. if (char_type* __hi = _M_high_mark())
  241. return { this->pbase(), __hi };
  242. else
  243. return _M_string;
  244. }
  245. #endif // C++20
  246. /**
  247. * @brief Setting a new buffer.
  248. * @param __s The string to use as a new sequence.
  249. *
  250. * Deallocates any previous stored sequence, then copies @a s to
  251. * use as a new one.
  252. */
  253. void
  254. str(const __string_type& __s)
  255. {
  256. // Cannot use _M_string = __s, since v3 strings are COW
  257. // (not always true now but assign() always works).
  258. _M_string.assign(__s.data(), __s.size());
  259. _M_stringbuf_init(_M_mode);
  260. }
  261. #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
  262. #if __cpp_concepts
  263. template<__allocator_like _SAlloc>
  264. requires (!is_same_v<_SAlloc, _Alloc>)
  265. void
  266. str(const basic_string<_CharT, _Traits, _SAlloc>& __s)
  267. {
  268. _M_string.assign(__s.data(), __s.size());
  269. _M_stringbuf_init(_M_mode);
  270. }
  271. #endif
  272. void
  273. str(__string_type&& __s)
  274. {
  275. _M_string = std::move(__s);
  276. _M_stringbuf_init(_M_mode);
  277. }
  278. #endif
  279. protected:
  280. // Common initialization code goes here.
  281. void
  282. _M_stringbuf_init(ios_base::openmode __mode)
  283. {
  284. _M_mode = __mode;
  285. __size_type __len = 0;
  286. if (_M_mode & (ios_base::ate | ios_base::app))
  287. __len = _M_string.size();
  288. _M_sync(const_cast<char_type*>(_M_string.data()), 0, __len);
  289. }
  290. virtual streamsize
  291. showmanyc()
  292. {
  293. streamsize __ret = -1;
  294. if (_M_mode & ios_base::in)
  295. {
  296. _M_update_egptr();
  297. __ret = this->egptr() - this->gptr();
  298. }
  299. return __ret;
  300. }
  301. virtual int_type
  302. underflow();
  303. virtual int_type
  304. pbackfail(int_type __c = traits_type::eof());
  305. virtual int_type
  306. overflow(int_type __c = traits_type::eof());
  307. /**
  308. * @brief Manipulates the buffer.
  309. * @param __s Pointer to a buffer area.
  310. * @param __n Size of @a __s.
  311. * @return @c this
  312. *
  313. * If no buffer has already been created, and both @a __s and @a __n are
  314. * non-zero, then @c __s is used as a buffer; see
  315. * https://gcc.gnu.org/onlinedocs/libstdc++/manual/streambufs.html#io.streambuf.buffering
  316. * for more.
  317. */
  318. virtual __streambuf_type*
  319. setbuf(char_type* __s, streamsize __n)
  320. {
  321. if (__s && __n >= 0)
  322. {
  323. // This is implementation-defined behavior, and assumes
  324. // that an external char_type array of length __n exists
  325. // and has been pre-allocated. If this is not the case,
  326. // things will quickly blow up.
  327. // Step 1: Destroy the current internal array.
  328. _M_string.clear();
  329. // Step 2: Use the external array.
  330. _M_sync(__s, __n, 0);
  331. }
  332. return this;
  333. }
  334. virtual pos_type
  335. seekoff(off_type __off, ios_base::seekdir __way,
  336. ios_base::openmode __mode = ios_base::in | ios_base::out);
  337. virtual pos_type
  338. seekpos(pos_type __sp,
  339. ios_base::openmode __mode = ios_base::in | ios_base::out);
  340. // Internal function for correctly updating the internal buffer
  341. // for a particular _M_string, due to initialization or re-sizing
  342. // of an existing _M_string.
  343. void
  344. _M_sync(char_type* __base, __size_type __i, __size_type __o);
  345. // Internal function for correctly updating egptr() to the actual
  346. // string end.
  347. void
  348. _M_update_egptr()
  349. {
  350. if (char_type* __pptr = this->pptr())
  351. {
  352. char_type* __egptr = this->egptr();
  353. if (!__egptr || __pptr > __egptr)
  354. {
  355. if (_M_mode & ios_base::in)
  356. this->setg(this->eback(), this->gptr(), __pptr);
  357. else
  358. this->setg(__pptr, __pptr, __pptr);
  359. }
  360. }
  361. }
  362. // Works around the issue with pbump, part of the protected
  363. // interface of basic_streambuf, taking just an int.
  364. void
  365. _M_pbump(char_type* __pbeg, char_type* __pend, off_type __off);
  366. private:
  367. // Return a pointer to the end of the underlying character sequence.
  368. // This might not be the same character as _M_string.end() because
  369. // basic_stringbuf::overflow might have written to unused capacity
  370. // in _M_string without updating its length.
  371. __attribute__((__always_inline__))
  372. char_type*
  373. _M_high_mark() const _GLIBCXX_NOEXCEPT
  374. {
  375. if (char_type* __pptr = this->pptr())
  376. {
  377. char_type* __egptr = this->egptr();
  378. if (!__egptr || __pptr > __egptr)
  379. return __pptr; // Underlying sequence is [pbase, pptr).
  380. else
  381. return __egptr; // Underlying sequence is [pbase, egptr).
  382. }
  383. return 0; // Underlying character sequence is just _M_string.
  384. }
  385. #if __cplusplus >= 201103L
  386. #if _GLIBCXX_USE_CXX11_ABI
  387. // This type captures the state of the gptr / pptr pointers as offsets
  388. // so they can be restored in another object after moving the string.
  389. struct __xfer_bufptrs
  390. {
  391. __xfer_bufptrs(const basic_stringbuf& __from, basic_stringbuf* __to)
  392. : _M_to{__to}, _M_goff{-1, -1, -1}, _M_poff{-1, -1, -1}
  393. {
  394. const _CharT* const __str = __from._M_string.data();
  395. const _CharT* __end = nullptr;
  396. if (__from.eback())
  397. {
  398. _M_goff[0] = __from.eback() - __str;
  399. _M_goff[1] = __from.gptr() - __str;
  400. _M_goff[2] = __from.egptr() - __str;
  401. __end = __from.egptr();
  402. }
  403. if (__from.pbase())
  404. {
  405. _M_poff[0] = __from.pbase() - __str;
  406. _M_poff[1] = __from.pptr() - __from.pbase();
  407. _M_poff[2] = __from.epptr() - __str;
  408. if (!__end || __from.pptr() > __end)
  409. __end = __from.pptr();
  410. }
  411. // Set _M_string length to the greater of the get and put areas.
  412. if (__end)
  413. {
  414. // The const_cast avoids changing this constructor's signature,
  415. // because it is exported from the dynamic library.
  416. auto& __mut_from = const_cast<basic_stringbuf&>(__from);
  417. __mut_from._M_string._M_length(__end - __str);
  418. }
  419. }
  420. ~__xfer_bufptrs()
  421. {
  422. char_type* __str = const_cast<char_type*>(_M_to->_M_string.data());
  423. if (_M_goff[0] != -1)
  424. _M_to->setg(__str+_M_goff[0], __str+_M_goff[1], __str+_M_goff[2]);
  425. if (_M_poff[0] != -1)
  426. _M_to->_M_pbump(__str+_M_poff[0], __str+_M_poff[2], _M_poff[1]);
  427. }
  428. basic_stringbuf* _M_to;
  429. off_type _M_goff[3];
  430. off_type _M_poff[3];
  431. };
  432. #else
  433. // This type does nothing when using Copy-On-Write strings.
  434. struct __xfer_bufptrs
  435. {
  436. __xfer_bufptrs(const basic_stringbuf&, basic_stringbuf*) { }
  437. };
  438. #endif
  439. // The move constructor initializes an __xfer_bufptrs temporary then
  440. // delegates to this constructor to performs moves during its lifetime.
  441. basic_stringbuf(basic_stringbuf&& __rhs, __xfer_bufptrs&&)
  442. : __streambuf_type(static_cast<const __streambuf_type&>(__rhs)),
  443. _M_mode(__rhs._M_mode), _M_string(std::move(__rhs._M_string))
  444. { }
  445. #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
  446. // The move constructor initializes an __xfer_bufptrs temporary then
  447. // delegates to this constructor to performs moves during its lifetime.
  448. basic_stringbuf(basic_stringbuf&& __rhs, const allocator_type& __a,
  449. __xfer_bufptrs&&)
  450. : __streambuf_type(static_cast<const __streambuf_type&>(__rhs)),
  451. _M_mode(__rhs._M_mode), _M_string(std::move(__rhs._M_string), __a)
  452. { }
  453. #endif
  454. #endif // C++11
  455. };
  456. // [27.7.2] Template class basic_istringstream
  457. /**
  458. * @brief Controlling input for std::string.
  459. * @ingroup io
  460. *
  461. * @tparam _CharT Type of character stream.
  462. * @tparam _Traits Traits for character type, defaults to
  463. * char_traits<_CharT>.
  464. * @tparam _Alloc Allocator type, defaults to allocator<_CharT>.
  465. *
  466. * This class supports reading from objects of type std::basic_string,
  467. * using the inherited functions from std::basic_istream. To control
  468. * the associated sequence, an instance of std::basic_stringbuf is used,
  469. * which this page refers to as @c sb.
  470. */
  471. template<typename _CharT, typename _Traits, typename _Alloc>
  472. class basic_istringstream : public basic_istream<_CharT, _Traits>
  473. {
  474. public:
  475. // Types:
  476. typedef _CharT char_type;
  477. typedef _Traits traits_type;
  478. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  479. // 251. basic_stringbuf missing allocator_type
  480. typedef _Alloc allocator_type;
  481. typedef typename traits_type::int_type int_type;
  482. typedef typename traits_type::pos_type pos_type;
  483. typedef typename traits_type::off_type off_type;
  484. // Non-standard types:
  485. typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
  486. typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type;
  487. typedef basic_istream<char_type, traits_type> __istream_type;
  488. private:
  489. __stringbuf_type _M_stringbuf;
  490. public:
  491. // Constructors:
  492. /**
  493. * @brief Default constructor starts with an empty string buffer.
  494. *
  495. * Initializes @c sb using @c in, and passes @c &sb to the base
  496. * class initializer. Does not allocate any buffer.
  497. *
  498. * That's a lie. We initialize the base class with NULL, because the
  499. * string class does its own memory management.
  500. */
  501. basic_istringstream()
  502. : __istream_type(), _M_stringbuf(ios_base::in)
  503. { this->init(&_M_stringbuf); }
  504. /**
  505. * @brief Starts with an empty string buffer.
  506. * @param __mode Whether the buffer can read, or write, or both.
  507. *
  508. * @c ios_base::in is automatically included in @a __mode.
  509. *
  510. * Initializes @c sb using @c __mode|in, and passes @c &sb to the base
  511. * class initializer. Does not allocate any buffer.
  512. *
  513. * That's a lie. We initialize the base class with NULL, because the
  514. * string class does its own memory management.
  515. */
  516. explicit
  517. basic_istringstream(ios_base::openmode __mode)
  518. : __istream_type(), _M_stringbuf(__mode | ios_base::in)
  519. { this->init(&_M_stringbuf); }
  520. /**
  521. * @brief Starts with an existing string buffer.
  522. * @param __str A string to copy as a starting buffer.
  523. * @param __mode Whether the buffer can read, or write, or both.
  524. *
  525. * @c ios_base::in is automatically included in @a mode.
  526. *
  527. * Initializes @c sb using @a str and @c mode|in, and passes @c &sb
  528. * to the base class initializer.
  529. *
  530. * That's a lie. We initialize the base class with NULL, because the
  531. * string class does its own memory management.
  532. */
  533. explicit
  534. basic_istringstream(const __string_type& __str,
  535. ios_base::openmode __mode = ios_base::in)
  536. : __istream_type(), _M_stringbuf(__str, __mode | ios_base::in)
  537. { this->init(&_M_stringbuf); }
  538. /**
  539. * @brief The destructor does nothing.
  540. *
  541. * The buffer is deallocated by the stringbuf object, not the
  542. * formatting stream.
  543. */
  544. ~basic_istringstream()
  545. { }
  546. #if __cplusplus >= 201103L
  547. basic_istringstream(const basic_istringstream&) = delete;
  548. basic_istringstream(basic_istringstream&& __rhs)
  549. : __istream_type(std::move(__rhs)),
  550. _M_stringbuf(std::move(__rhs._M_stringbuf))
  551. { __istream_type::set_rdbuf(&_M_stringbuf); }
  552. #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
  553. basic_istringstream(ios_base::openmode __mode, const allocator_type& __a)
  554. : __istream_type(), _M_stringbuf(__mode | ios_base::in, __a)
  555. { this->init(std::__addressof(_M_stringbuf)); }
  556. explicit
  557. basic_istringstream(__string_type&& __str,
  558. ios_base::openmode __mode = ios_base::in)
  559. : __istream_type(), _M_stringbuf(std::move(__str), __mode | ios_base::in)
  560. { this->init(std::__addressof(_M_stringbuf)); }
  561. template<typename _SAlloc>
  562. basic_istringstream(const basic_string<_CharT, _Traits, _SAlloc>& __str,
  563. const allocator_type& __a)
  564. : basic_istringstream(__str, ios_base::in, __a)
  565. { }
  566. template<typename _SAlloc>
  567. basic_istringstream(const basic_string<_CharT, _Traits, _SAlloc>& __str,
  568. ios_base::openmode __mode,
  569. const allocator_type& __a)
  570. : __istream_type(), _M_stringbuf(__str, __mode | ios_base::in, __a)
  571. { this->init(std::__addressof(_M_stringbuf)); }
  572. template<typename _SAlloc>
  573. explicit
  574. basic_istringstream(const basic_string<_CharT, _Traits, _SAlloc>& __str,
  575. ios_base::openmode __mode = ios_base::in)
  576. : basic_istringstream(__str, __mode, allocator_type())
  577. { }
  578. #endif // C++20
  579. // 27.8.3.2 Assign and swap:
  580. basic_istringstream&
  581. operator=(const basic_istringstream&) = delete;
  582. basic_istringstream&
  583. operator=(basic_istringstream&& __rhs)
  584. {
  585. __istream_type::operator=(std::move(__rhs));
  586. _M_stringbuf = std::move(__rhs._M_stringbuf);
  587. return *this;
  588. }
  589. void
  590. swap(basic_istringstream& __rhs)
  591. {
  592. __istream_type::swap(__rhs);
  593. _M_stringbuf.swap(__rhs._M_stringbuf);
  594. }
  595. #endif // C++11
  596. // Members:
  597. /**
  598. * @brief Accessing the underlying buffer.
  599. * @return The current basic_stringbuf buffer.
  600. *
  601. * This hides both signatures of std::basic_ios::rdbuf().
  602. */
  603. __stringbuf_type*
  604. rdbuf() const
  605. { return const_cast<__stringbuf_type*>(&_M_stringbuf); }
  606. /**
  607. * @brief Copying out the string buffer.
  608. * @return @c rdbuf()->str()
  609. */
  610. __string_type
  611. str() const _GLIBCXX_LVAL_REF_QUAL
  612. { return _M_stringbuf.str(); }
  613. #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
  614. #if __cpp_concepts
  615. template<__allocator_like _SAlloc>
  616. basic_string<_CharT, _Traits, _SAlloc>
  617. str(const _SAlloc& __sa) const
  618. { return _M_stringbuf.str(__sa); }
  619. #endif
  620. __string_type
  621. str() &&
  622. { return std::move(_M_stringbuf).str(); }
  623. basic_string_view<char_type, traits_type>
  624. view() const noexcept
  625. { return _M_stringbuf.view(); }
  626. #endif
  627. /**
  628. * @brief Setting a new buffer.
  629. * @param __s The string to use as a new sequence.
  630. *
  631. * Calls @c rdbuf()->str(s).
  632. */
  633. void
  634. str(const __string_type& __s)
  635. { _M_stringbuf.str(__s); }
  636. #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
  637. #if __cpp_concepts
  638. template<__allocator_like _SAlloc>
  639. requires (!is_same_v<_SAlloc, _Alloc>)
  640. void
  641. str(const basic_string<_CharT, _Traits, _SAlloc>& __s)
  642. { _M_stringbuf.str(__s); }
  643. #endif
  644. void
  645. str(__string_type&& __s)
  646. { _M_stringbuf.str(std::move(__s)); }
  647. #endif
  648. };
  649. // [27.7.3] Template class basic_ostringstream
  650. /**
  651. * @brief Controlling output for std::string.
  652. * @ingroup io
  653. *
  654. * @tparam _CharT Type of character stream.
  655. * @tparam _Traits Traits for character type, defaults to
  656. * char_traits<_CharT>.
  657. * @tparam _Alloc Allocator type, defaults to allocator<_CharT>.
  658. *
  659. * This class supports writing to objects of type std::basic_string,
  660. * using the inherited functions from std::basic_ostream. To control
  661. * the associated sequence, an instance of std::basic_stringbuf is used,
  662. * which this page refers to as @c sb.
  663. */
  664. template <typename _CharT, typename _Traits, typename _Alloc>
  665. class basic_ostringstream : public basic_ostream<_CharT, _Traits>
  666. {
  667. public:
  668. // Types:
  669. typedef _CharT char_type;
  670. typedef _Traits traits_type;
  671. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  672. // 251. basic_stringbuf missing allocator_type
  673. typedef _Alloc allocator_type;
  674. typedef typename traits_type::int_type int_type;
  675. typedef typename traits_type::pos_type pos_type;
  676. typedef typename traits_type::off_type off_type;
  677. // Non-standard types:
  678. typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
  679. typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type;
  680. typedef basic_ostream<char_type, traits_type> __ostream_type;
  681. private:
  682. __stringbuf_type _M_stringbuf;
  683. public:
  684. // Constructors/destructor:
  685. /**
  686. * @brief Default constructor starts with an empty string buffer.
  687. *
  688. * Initializes @c sb using @c mode|out, and passes @c &sb to the base
  689. * class initializer. Does not allocate any buffer.
  690. *
  691. * That's a lie. We initialize the base class with NULL, because the
  692. * string class does its own memory management.
  693. */
  694. basic_ostringstream()
  695. : __ostream_type(), _M_stringbuf(ios_base::out)
  696. { this->init(&_M_stringbuf); }
  697. /**
  698. * @brief Starts with an empty string buffer.
  699. * @param __mode Whether the buffer can read, or write, or both.
  700. *
  701. * @c ios_base::out is automatically included in @a mode.
  702. *
  703. * Initializes @c sb using @c mode|out, and passes @c &sb to the base
  704. * class initializer. Does not allocate any buffer.
  705. *
  706. * That's a lie. We initialize the base class with NULL, because the
  707. * string class does its own memory management.
  708. */
  709. explicit
  710. basic_ostringstream(ios_base::openmode __mode)
  711. : __ostream_type(), _M_stringbuf(__mode | ios_base::out)
  712. { this->init(&_M_stringbuf); }
  713. /**
  714. * @brief Starts with an existing string buffer.
  715. * @param __str A string to copy as a starting buffer.
  716. * @param __mode Whether the buffer can read, or write, or both.
  717. *
  718. * @c ios_base::out is automatically included in @a mode.
  719. *
  720. * Initializes @c sb using @a str and @c mode|out, and passes @c &sb
  721. * to the base class initializer.
  722. *
  723. * That's a lie. We initialize the base class with NULL, because the
  724. * string class does its own memory management.
  725. */
  726. explicit
  727. basic_ostringstream(const __string_type& __str,
  728. ios_base::openmode __mode = ios_base::out)
  729. : __ostream_type(), _M_stringbuf(__str, __mode | ios_base::out)
  730. { this->init(&_M_stringbuf); }
  731. /**
  732. * @brief The destructor does nothing.
  733. *
  734. * The buffer is deallocated by the stringbuf object, not the
  735. * formatting stream.
  736. */
  737. ~basic_ostringstream()
  738. { }
  739. #if __cplusplus >= 201103L
  740. basic_ostringstream(const basic_ostringstream&) = delete;
  741. basic_ostringstream(basic_ostringstream&& __rhs)
  742. : __ostream_type(std::move(__rhs)),
  743. _M_stringbuf(std::move(__rhs._M_stringbuf))
  744. { __ostream_type::set_rdbuf(&_M_stringbuf); }
  745. #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
  746. basic_ostringstream(ios_base::openmode __mode, const allocator_type& __a)
  747. : __ostream_type(), _M_stringbuf(__mode | ios_base::out, __a)
  748. { this->init(std::__addressof(_M_stringbuf)); }
  749. explicit
  750. basic_ostringstream(__string_type&& __str,
  751. ios_base::openmode __mode = ios_base::out)
  752. : __ostream_type(), _M_stringbuf(std::move(__str), __mode | ios_base::out)
  753. { this->init(std::__addressof(_M_stringbuf)); }
  754. template<typename _SAlloc>
  755. basic_ostringstream(const basic_string<_CharT, _Traits, _SAlloc>& __str,
  756. const allocator_type& __a)
  757. : basic_ostringstream(__str, ios_base::out, __a)
  758. { }
  759. template<typename _SAlloc>
  760. basic_ostringstream(const basic_string<_CharT, _Traits, _SAlloc>& __str,
  761. ios_base::openmode __mode,
  762. const allocator_type& __a)
  763. : __ostream_type(), _M_stringbuf(__str, __mode | ios_base::out, __a)
  764. { this->init(std::__addressof(_M_stringbuf)); }
  765. template<typename _SAlloc>
  766. explicit
  767. basic_ostringstream(const basic_string<_CharT, _Traits, _SAlloc>& __str,
  768. ios_base::openmode __mode = ios_base::out)
  769. : basic_ostringstream(__str, __mode, allocator_type())
  770. { }
  771. #endif // C++20
  772. // 27.8.3.2 Assign and swap:
  773. basic_ostringstream&
  774. operator=(const basic_ostringstream&) = delete;
  775. basic_ostringstream&
  776. operator=(basic_ostringstream&& __rhs)
  777. {
  778. __ostream_type::operator=(std::move(__rhs));
  779. _M_stringbuf = std::move(__rhs._M_stringbuf);
  780. return *this;
  781. }
  782. void
  783. swap(basic_ostringstream& __rhs)
  784. {
  785. __ostream_type::swap(__rhs);
  786. _M_stringbuf.swap(__rhs._M_stringbuf);
  787. }
  788. #endif // C++11
  789. // Members:
  790. /**
  791. * @brief Accessing the underlying buffer.
  792. * @return The current basic_stringbuf buffer.
  793. *
  794. * This hides both signatures of std::basic_ios::rdbuf().
  795. */
  796. __stringbuf_type*
  797. rdbuf() const
  798. { return const_cast<__stringbuf_type*>(&_M_stringbuf); }
  799. /**
  800. * @brief Copying out the string buffer.
  801. * @return @c rdbuf()->str()
  802. */
  803. __string_type
  804. str() const _GLIBCXX_LVAL_REF_QUAL
  805. { return _M_stringbuf.str(); }
  806. #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
  807. #if __cpp_concepts
  808. template<__allocator_like _SAlloc>
  809. basic_string<_CharT, _Traits, _SAlloc>
  810. str(const _SAlloc& __sa) const
  811. { return _M_stringbuf.str(__sa); }
  812. #endif
  813. __string_type
  814. str() &&
  815. { return std::move(_M_stringbuf).str(); }
  816. basic_string_view<char_type, traits_type>
  817. view() const noexcept
  818. { return _M_stringbuf.view(); }
  819. #endif
  820. /**
  821. * @brief Setting a new buffer.
  822. * @param __s The string to use as a new sequence.
  823. *
  824. * Calls @c rdbuf()->str(s).
  825. */
  826. void
  827. str(const __string_type& __s)
  828. { _M_stringbuf.str(__s); }
  829. #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
  830. #if __cpp_concepts
  831. template<__allocator_like _SAlloc>
  832. requires (!is_same_v<_SAlloc, _Alloc>)
  833. void
  834. str(const basic_string<_CharT, _Traits, _SAlloc>& __s)
  835. { _M_stringbuf.str(__s); }
  836. #endif
  837. void
  838. str(__string_type&& __s)
  839. { _M_stringbuf.str(std::move(__s)); }
  840. #endif
  841. };
  842. // [27.7.4] Template class basic_stringstream
  843. /**
  844. * @brief Controlling input and output for std::string.
  845. * @ingroup io
  846. *
  847. * @tparam _CharT Type of character stream.
  848. * @tparam _Traits Traits for character type, defaults to
  849. * char_traits<_CharT>.
  850. * @tparam _Alloc Allocator type, defaults to allocator<_CharT>.
  851. *
  852. * This class supports reading from and writing to objects of type
  853. * std::basic_string, using the inherited functions from
  854. * std::basic_iostream. To control the associated sequence, an instance
  855. * of std::basic_stringbuf is used, which this page refers to as @c sb.
  856. */
  857. template <typename _CharT, typename _Traits, typename _Alloc>
  858. class basic_stringstream : public basic_iostream<_CharT, _Traits>
  859. {
  860. public:
  861. // Types:
  862. typedef _CharT char_type;
  863. typedef _Traits traits_type;
  864. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  865. // 251. basic_stringbuf missing allocator_type
  866. typedef _Alloc allocator_type;
  867. typedef typename traits_type::int_type int_type;
  868. typedef typename traits_type::pos_type pos_type;
  869. typedef typename traits_type::off_type off_type;
  870. // Non-standard Types:
  871. typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
  872. typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type;
  873. typedef basic_iostream<char_type, traits_type> __iostream_type;
  874. private:
  875. __stringbuf_type _M_stringbuf;
  876. public:
  877. // Constructors/destructors
  878. /**
  879. * @brief Default constructor starts with an empty string buffer.
  880. *
  881. * Initializes @c sb using the mode @c in|out, and passes @c &sb
  882. * to the base class initializer. Does not allocate any buffer.
  883. *
  884. * That's a lie. We initialize the base class with NULL, because the
  885. * string class does its own memory management.
  886. */
  887. basic_stringstream()
  888. : __iostream_type(), _M_stringbuf(ios_base::out | ios_base::in)
  889. { this->init(&_M_stringbuf); }
  890. /**
  891. * @brief Starts with an empty string buffer.
  892. * @param __m Whether the buffer can read, or write, or both.
  893. *
  894. * Initializes @c sb using the mode from @c __m, and passes @c &sb
  895. * to the base class initializer. Does not allocate any buffer.
  896. *
  897. * That's a lie. We initialize the base class with NULL, because the
  898. * string class does its own memory management.
  899. */
  900. explicit
  901. basic_stringstream(ios_base::openmode __m)
  902. : __iostream_type(), _M_stringbuf(__m)
  903. { this->init(&_M_stringbuf); }
  904. /**
  905. * @brief Starts with an existing string buffer.
  906. * @param __str A string to copy as a starting buffer.
  907. * @param __m Whether the buffer can read, or write, or both.
  908. *
  909. * Initializes @c sb using @a __str and @c __m, and passes @c &sb
  910. * to the base class initializer.
  911. *
  912. * That's a lie. We initialize the base class with NULL, because the
  913. * string class does its own memory management.
  914. */
  915. explicit
  916. basic_stringstream(const __string_type& __str,
  917. ios_base::openmode __m = ios_base::out | ios_base::in)
  918. : __iostream_type(), _M_stringbuf(__str, __m)
  919. { this->init(&_M_stringbuf); }
  920. /**
  921. * @brief The destructor does nothing.
  922. *
  923. * The buffer is deallocated by the stringbuf object, not the
  924. * formatting stream.
  925. */
  926. ~basic_stringstream()
  927. { }
  928. #if __cplusplus >= 201103L
  929. basic_stringstream(const basic_stringstream&) = delete;
  930. basic_stringstream(basic_stringstream&& __rhs)
  931. : __iostream_type(std::move(__rhs)),
  932. _M_stringbuf(std::move(__rhs._M_stringbuf))
  933. { __iostream_type::set_rdbuf(&_M_stringbuf); }
  934. #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
  935. basic_stringstream(ios_base::openmode __mode, const allocator_type& __a)
  936. : __iostream_type(), _M_stringbuf(__mode, __a)
  937. { this->init(&_M_stringbuf); }
  938. explicit
  939. basic_stringstream(__string_type&& __str,
  940. ios_base::openmode __mode = ios_base::in
  941. | ios_base::out)
  942. : __iostream_type(), _M_stringbuf(std::move(__str), __mode)
  943. { this->init(std::__addressof(_M_stringbuf)); }
  944. template<typename _SAlloc>
  945. basic_stringstream(const basic_string<_CharT, _Traits, _SAlloc>& __str,
  946. const allocator_type& __a)
  947. : basic_stringstream(__str, ios_base::in | ios_base::out, __a)
  948. { }
  949. template<typename _SAlloc>
  950. basic_stringstream(const basic_string<_CharT, _Traits, _SAlloc>& __str,
  951. ios_base::openmode __mode,
  952. const allocator_type& __a)
  953. : __iostream_type(), _M_stringbuf(__str, __mode, __a)
  954. { this->init(std::__addressof(_M_stringbuf)); }
  955. template<typename _SAlloc>
  956. explicit
  957. basic_stringstream(const basic_string<_CharT, _Traits, _SAlloc>& __str,
  958. ios_base::openmode __mode = ios_base::in
  959. | ios_base::out)
  960. : basic_stringstream(__str, __mode, allocator_type())
  961. { }
  962. #endif // C++20
  963. // 27.8.3.2 Assign and swap:
  964. basic_stringstream&
  965. operator=(const basic_stringstream&) = delete;
  966. basic_stringstream&
  967. operator=(basic_stringstream&& __rhs)
  968. {
  969. __iostream_type::operator=(std::move(__rhs));
  970. _M_stringbuf = std::move(__rhs._M_stringbuf);
  971. return *this;
  972. }
  973. void
  974. swap(basic_stringstream& __rhs)
  975. {
  976. __iostream_type::swap(__rhs);
  977. _M_stringbuf.swap(__rhs._M_stringbuf);
  978. }
  979. #endif // C++11
  980. // Members:
  981. /**
  982. * @brief Accessing the underlying buffer.
  983. * @return The current basic_stringbuf buffer.
  984. *
  985. * This hides both signatures of std::basic_ios::rdbuf().
  986. */
  987. __stringbuf_type*
  988. rdbuf() const
  989. { return const_cast<__stringbuf_type*>(&_M_stringbuf); }
  990. /**
  991. * @brief Copying out the string buffer.
  992. * @return @c rdbuf()->str()
  993. */
  994. __string_type
  995. str() const _GLIBCXX_LVAL_REF_QUAL
  996. { return _M_stringbuf.str(); }
  997. #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
  998. #if __cpp_concepts
  999. template<__allocator_like _SAlloc>
  1000. basic_string<_CharT, _Traits, _SAlloc>
  1001. str(const _SAlloc& __sa) const
  1002. { return _M_stringbuf.str(__sa); }
  1003. #endif
  1004. __string_type
  1005. str() &&
  1006. { return std::move(_M_stringbuf).str(); }
  1007. basic_string_view<char_type, traits_type>
  1008. view() const noexcept
  1009. { return _M_stringbuf.view(); }
  1010. #endif
  1011. /**
  1012. * @brief Setting a new buffer.
  1013. * @param __s The string to use as a new sequence.
  1014. *
  1015. * Calls @c rdbuf()->str(s).
  1016. */
  1017. void
  1018. str(const __string_type& __s)
  1019. { _M_stringbuf.str(__s); }
  1020. #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
  1021. #if __cpp_concepts
  1022. template<__allocator_like _SAlloc>
  1023. requires (!is_same_v<_SAlloc, _Alloc>)
  1024. void
  1025. str(const basic_string<_CharT, _Traits, _SAlloc>& __s)
  1026. { _M_stringbuf.str(__s); }
  1027. #endif
  1028. void
  1029. str(__string_type&& __s)
  1030. { _M_stringbuf.str(std::move(__s)); }
  1031. #endif
  1032. };
  1033. #if __cplusplus >= 201103L
  1034. /// Swap specialization for stringbufs.
  1035. template <class _CharT, class _Traits, class _Allocator>
  1036. inline void
  1037. swap(basic_stringbuf<_CharT, _Traits, _Allocator>& __x,
  1038. basic_stringbuf<_CharT, _Traits, _Allocator>& __y)
  1039. noexcept(noexcept(__x.swap(__y)))
  1040. { __x.swap(__y); }
  1041. /// Swap specialization for istringstreams.
  1042. template <class _CharT, class _Traits, class _Allocator>
  1043. inline void
  1044. swap(basic_istringstream<_CharT, _Traits, _Allocator>& __x,
  1045. basic_istringstream<_CharT, _Traits, _Allocator>& __y)
  1046. { __x.swap(__y); }
  1047. /// Swap specialization for ostringstreams.
  1048. template <class _CharT, class _Traits, class _Allocator>
  1049. inline void
  1050. swap(basic_ostringstream<_CharT, _Traits, _Allocator>& __x,
  1051. basic_ostringstream<_CharT, _Traits, _Allocator>& __y)
  1052. { __x.swap(__y); }
  1053. /// Swap specialization for stringstreams.
  1054. template <class _CharT, class _Traits, class _Allocator>
  1055. inline void
  1056. swap(basic_stringstream<_CharT, _Traits, _Allocator>& __x,
  1057. basic_stringstream<_CharT, _Traits, _Allocator>& __y)
  1058. { __x.swap(__y); }
  1059. #endif // C++11
  1060. _GLIBCXX_END_NAMESPACE_CXX11
  1061. _GLIBCXX_END_NAMESPACE_VERSION
  1062. } // namespace
  1063. #undef _GLIBCXX_LVAL_REF_QUAL
  1064. #include <bits/sstream.tcc>
  1065. #endif /* _GLIBCXX_SSTREAM */