sstream 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219
  1. // String based streams -*- C++ -*-
  2. // Copyright (C) 1997-2021 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. char_type*
  372. _M_high_mark() const _GLIBCXX_NOEXCEPT
  373. {
  374. if (char_type* __pptr = this->pptr())
  375. {
  376. char_type* __egptr = this->egptr();
  377. if (!__egptr || __pptr > __egptr)
  378. return __pptr; // Underlying sequence is [pbase, pptr).
  379. else
  380. return __egptr; // Underlying sequence is [pbase, egptr).
  381. }
  382. return 0; // Underlying character sequence is just _M_string.
  383. }
  384. #if __cplusplus >= 201103L
  385. #if _GLIBCXX_USE_CXX11_ABI
  386. // This type captures the state of the gptr / pptr pointers as offsets
  387. // so they can be restored in another object after moving the string.
  388. struct __xfer_bufptrs
  389. {
  390. __xfer_bufptrs(const basic_stringbuf& __from, basic_stringbuf* __to)
  391. : _M_to{__to}, _M_goff{-1, -1, -1}, _M_poff{-1, -1, -1}
  392. {
  393. const _CharT* const __str = __from._M_string.data();
  394. const _CharT* __end = nullptr;
  395. if (__from.eback())
  396. {
  397. _M_goff[0] = __from.eback() - __str;
  398. _M_goff[1] = __from.gptr() - __str;
  399. _M_goff[2] = __from.egptr() - __str;
  400. __end = __from.egptr();
  401. }
  402. if (__from.pbase())
  403. {
  404. _M_poff[0] = __from.pbase() - __str;
  405. _M_poff[1] = __from.pptr() - __from.pbase();
  406. _M_poff[2] = __from.epptr() - __str;
  407. if (!__end || __from.pptr() > __end)
  408. __end = __from.pptr();
  409. }
  410. // Set _M_string length to the greater of the get and put areas.
  411. if (__end)
  412. {
  413. // The const_cast avoids changing this constructor's signature,
  414. // because it is exported from the dynamic library.
  415. auto& __mut_from = const_cast<basic_stringbuf&>(__from);
  416. __mut_from._M_string._M_length(__end - __str);
  417. }
  418. }
  419. ~__xfer_bufptrs()
  420. {
  421. char_type* __str = const_cast<char_type*>(_M_to->_M_string.data());
  422. if (_M_goff[0] != -1)
  423. _M_to->setg(__str+_M_goff[0], __str+_M_goff[1], __str+_M_goff[2]);
  424. if (_M_poff[0] != -1)
  425. _M_to->_M_pbump(__str+_M_poff[0], __str+_M_poff[2], _M_poff[1]);
  426. }
  427. basic_stringbuf* _M_to;
  428. off_type _M_goff[3];
  429. off_type _M_poff[3];
  430. };
  431. #else
  432. // This type does nothing when using Copy-On-Write strings.
  433. struct __xfer_bufptrs
  434. {
  435. __xfer_bufptrs(const basic_stringbuf&, basic_stringbuf*) { }
  436. };
  437. #endif
  438. // The move constructor initializes an __xfer_bufptrs temporary then
  439. // delegates to this constructor to performs moves during its lifetime.
  440. basic_stringbuf(basic_stringbuf&& __rhs, __xfer_bufptrs&&)
  441. : __streambuf_type(static_cast<const __streambuf_type&>(__rhs)),
  442. _M_mode(__rhs._M_mode), _M_string(std::move(__rhs._M_string))
  443. { }
  444. #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
  445. // The move constructor initializes an __xfer_bufptrs temporary then
  446. // delegates to this constructor to performs moves during its lifetime.
  447. basic_stringbuf(basic_stringbuf&& __rhs, const allocator_type& __a,
  448. __xfer_bufptrs&&)
  449. : __streambuf_type(static_cast<const __streambuf_type&>(__rhs)),
  450. _M_mode(__rhs._M_mode), _M_string(std::move(__rhs._M_string), __a)
  451. { }
  452. #endif
  453. #endif // C++11
  454. };
  455. // [27.7.2] Template class basic_istringstream
  456. /**
  457. * @brief Controlling input for std::string.
  458. * @ingroup io
  459. *
  460. * @tparam _CharT Type of character stream.
  461. * @tparam _Traits Traits for character type, defaults to
  462. * char_traits<_CharT>.
  463. * @tparam _Alloc Allocator type, defaults to allocator<_CharT>.
  464. *
  465. * This class supports reading from objects of type std::basic_string,
  466. * using the inherited functions from std::basic_istream. To control
  467. * the associated sequence, an instance of std::basic_stringbuf is used,
  468. * which this page refers to as @c sb.
  469. */
  470. template<typename _CharT, typename _Traits, typename _Alloc>
  471. class basic_istringstream : public basic_istream<_CharT, _Traits>
  472. {
  473. public:
  474. // Types:
  475. typedef _CharT char_type;
  476. typedef _Traits traits_type;
  477. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  478. // 251. basic_stringbuf missing allocator_type
  479. typedef _Alloc allocator_type;
  480. typedef typename traits_type::int_type int_type;
  481. typedef typename traits_type::pos_type pos_type;
  482. typedef typename traits_type::off_type off_type;
  483. // Non-standard types:
  484. typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
  485. typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type;
  486. typedef basic_istream<char_type, traits_type> __istream_type;
  487. private:
  488. __stringbuf_type _M_stringbuf;
  489. public:
  490. // Constructors:
  491. /**
  492. * @brief Default constructor starts with an empty string buffer.
  493. *
  494. * Initializes @c sb using @c in, and passes @c &sb to the base
  495. * class initializer. Does not allocate any buffer.
  496. *
  497. * That's a lie. We initialize the base class with NULL, because the
  498. * string class does its own memory management.
  499. */
  500. basic_istringstream()
  501. : __istream_type(), _M_stringbuf(ios_base::in)
  502. { this->init(&_M_stringbuf); }
  503. /**
  504. * @brief Starts with an empty string buffer.
  505. * @param __mode Whether the buffer can read, or write, or both.
  506. *
  507. * @c ios_base::in is automatically included in @a __mode.
  508. *
  509. * Initializes @c sb using @c __mode|in, and passes @c &sb to the base
  510. * class initializer. Does not allocate any buffer.
  511. *
  512. * That's a lie. We initialize the base class with NULL, because the
  513. * string class does its own memory management.
  514. */
  515. explicit
  516. basic_istringstream(ios_base::openmode __mode)
  517. : __istream_type(), _M_stringbuf(__mode | ios_base::in)
  518. { this->init(&_M_stringbuf); }
  519. /**
  520. * @brief Starts with an existing string buffer.
  521. * @param __str A string to copy as a starting buffer.
  522. * @param __mode Whether the buffer can read, or write, or both.
  523. *
  524. * @c ios_base::in is automatically included in @a mode.
  525. *
  526. * Initializes @c sb using @a str and @c mode|in, and passes @c &sb
  527. * to the base class initializer.
  528. *
  529. * That's a lie. We initialize the base class with NULL, because the
  530. * string class does its own memory management.
  531. */
  532. explicit
  533. basic_istringstream(const __string_type& __str,
  534. ios_base::openmode __mode = ios_base::in)
  535. : __istream_type(), _M_stringbuf(__str, __mode | ios_base::in)
  536. { this->init(&_M_stringbuf); }
  537. /**
  538. * @brief The destructor does nothing.
  539. *
  540. * The buffer is deallocated by the stringbuf object, not the
  541. * formatting stream.
  542. */
  543. ~basic_istringstream()
  544. { }
  545. #if __cplusplus >= 201103L
  546. basic_istringstream(const basic_istringstream&) = delete;
  547. basic_istringstream(basic_istringstream&& __rhs)
  548. : __istream_type(std::move(__rhs)),
  549. _M_stringbuf(std::move(__rhs._M_stringbuf))
  550. { __istream_type::set_rdbuf(&_M_stringbuf); }
  551. #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
  552. basic_istringstream(ios_base::openmode __mode, const allocator_type& __a)
  553. : __istream_type(), _M_stringbuf(__mode | ios_base::in, __a)
  554. { this->init(std::__addressof(_M_stringbuf)); }
  555. explicit
  556. basic_istringstream(__string_type&& __str,
  557. ios_base::openmode __mode = ios_base::in)
  558. : __istream_type(), _M_stringbuf(std::move(__str), __mode | ios_base::in)
  559. { this->init(std::__addressof(_M_stringbuf)); }
  560. template<typename _SAlloc>
  561. basic_istringstream(const basic_string<_CharT, _Traits, _SAlloc>& __str,
  562. const allocator_type& __a)
  563. : basic_istringstream(__str, ios_base::in, __a)
  564. { }
  565. template<typename _SAlloc>
  566. basic_istringstream(const basic_string<_CharT, _Traits, _SAlloc>& __str,
  567. ios_base::openmode __mode,
  568. const allocator_type& __a)
  569. : __istream_type(), _M_stringbuf(__str, __mode | ios_base::in, __a)
  570. { this->init(std::__addressof(_M_stringbuf)); }
  571. template<typename _SAlloc>
  572. explicit
  573. basic_istringstream(const basic_string<_CharT, _Traits, _SAlloc>& __str,
  574. ios_base::openmode __mode = ios_base::in)
  575. : basic_istringstream(__str, __mode, allocator_type())
  576. { }
  577. #endif // C++20
  578. // 27.8.3.2 Assign and swap:
  579. basic_istringstream&
  580. operator=(const basic_istringstream&) = delete;
  581. basic_istringstream&
  582. operator=(basic_istringstream&& __rhs)
  583. {
  584. __istream_type::operator=(std::move(__rhs));
  585. _M_stringbuf = std::move(__rhs._M_stringbuf);
  586. return *this;
  587. }
  588. void
  589. swap(basic_istringstream& __rhs)
  590. {
  591. __istream_type::swap(__rhs);
  592. _M_stringbuf.swap(__rhs._M_stringbuf);
  593. }
  594. #endif // C++11
  595. // Members:
  596. /**
  597. * @brief Accessing the underlying buffer.
  598. * @return The current basic_stringbuf buffer.
  599. *
  600. * This hides both signatures of std::basic_ios::rdbuf().
  601. */
  602. __stringbuf_type*
  603. rdbuf() const
  604. { return const_cast<__stringbuf_type*>(&_M_stringbuf); }
  605. /**
  606. * @brief Copying out the string buffer.
  607. * @return @c rdbuf()->str()
  608. */
  609. __string_type
  610. str() const _GLIBCXX_LVAL_REF_QUAL
  611. { return _M_stringbuf.str(); }
  612. #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
  613. #if __cpp_concepts
  614. template<__allocator_like _SAlloc>
  615. basic_string<_CharT, _Traits, _SAlloc>
  616. str(const _SAlloc& __sa) const
  617. { return _M_stringbuf.str(__sa); }
  618. #endif
  619. __string_type
  620. str() &&
  621. { return std::move(_M_stringbuf).str(); }
  622. basic_string_view<char_type, traits_type>
  623. view() const noexcept
  624. { return _M_stringbuf.view(); }
  625. #endif
  626. /**
  627. * @brief Setting a new buffer.
  628. * @param __s The string to use as a new sequence.
  629. *
  630. * Calls @c rdbuf()->str(s).
  631. */
  632. void
  633. str(const __string_type& __s)
  634. { _M_stringbuf.str(__s); }
  635. #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
  636. #if __cpp_concepts
  637. template<__allocator_like _SAlloc>
  638. requires (!is_same_v<_SAlloc, _Alloc>)
  639. void
  640. str(const basic_string<_CharT, _Traits, _SAlloc>& __s)
  641. { _M_stringbuf.str(__s); }
  642. #endif
  643. void
  644. str(__string_type&& __s)
  645. { _M_stringbuf.str(std::move(__s)); }
  646. #endif
  647. };
  648. // [27.7.3] Template class basic_ostringstream
  649. /**
  650. * @brief Controlling output for std::string.
  651. * @ingroup io
  652. *
  653. * @tparam _CharT Type of character stream.
  654. * @tparam _Traits Traits for character type, defaults to
  655. * char_traits<_CharT>.
  656. * @tparam _Alloc Allocator type, defaults to allocator<_CharT>.
  657. *
  658. * This class supports writing to objects of type std::basic_string,
  659. * using the inherited functions from std::basic_ostream. To control
  660. * the associated sequence, an instance of std::basic_stringbuf is used,
  661. * which this page refers to as @c sb.
  662. */
  663. template <typename _CharT, typename _Traits, typename _Alloc>
  664. class basic_ostringstream : public basic_ostream<_CharT, _Traits>
  665. {
  666. public:
  667. // Types:
  668. typedef _CharT char_type;
  669. typedef _Traits traits_type;
  670. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  671. // 251. basic_stringbuf missing allocator_type
  672. typedef _Alloc allocator_type;
  673. typedef typename traits_type::int_type int_type;
  674. typedef typename traits_type::pos_type pos_type;
  675. typedef typename traits_type::off_type off_type;
  676. // Non-standard types:
  677. typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
  678. typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type;
  679. typedef basic_ostream<char_type, traits_type> __ostream_type;
  680. private:
  681. __stringbuf_type _M_stringbuf;
  682. public:
  683. // Constructors/destructor:
  684. /**
  685. * @brief Default constructor starts with an empty string buffer.
  686. *
  687. * Initializes @c sb using @c mode|out, and passes @c &sb to the base
  688. * class initializer. Does not allocate any buffer.
  689. *
  690. * That's a lie. We initialize the base class with NULL, because the
  691. * string class does its own memory management.
  692. */
  693. basic_ostringstream()
  694. : __ostream_type(), _M_stringbuf(ios_base::out)
  695. { this->init(&_M_stringbuf); }
  696. /**
  697. * @brief Starts with an empty string buffer.
  698. * @param __mode Whether the buffer can read, or write, or both.
  699. *
  700. * @c ios_base::out is automatically included in @a mode.
  701. *
  702. * Initializes @c sb using @c mode|out, and passes @c &sb to the base
  703. * class initializer. Does not allocate any buffer.
  704. *
  705. * That's a lie. We initialize the base class with NULL, because the
  706. * string class does its own memory management.
  707. */
  708. explicit
  709. basic_ostringstream(ios_base::openmode __mode)
  710. : __ostream_type(), _M_stringbuf(__mode | ios_base::out)
  711. { this->init(&_M_stringbuf); }
  712. /**
  713. * @brief Starts with an existing string buffer.
  714. * @param __str A string to copy as a starting buffer.
  715. * @param __mode Whether the buffer can read, or write, or both.
  716. *
  717. * @c ios_base::out is automatically included in @a mode.
  718. *
  719. * Initializes @c sb using @a str and @c mode|out, and passes @c &sb
  720. * to the base class initializer.
  721. *
  722. * That's a lie. We initialize the base class with NULL, because the
  723. * string class does its own memory management.
  724. */
  725. explicit
  726. basic_ostringstream(const __string_type& __str,
  727. ios_base::openmode __mode = ios_base::out)
  728. : __ostream_type(), _M_stringbuf(__str, __mode | ios_base::out)
  729. { this->init(&_M_stringbuf); }
  730. /**
  731. * @brief The destructor does nothing.
  732. *
  733. * The buffer is deallocated by the stringbuf object, not the
  734. * formatting stream.
  735. */
  736. ~basic_ostringstream()
  737. { }
  738. #if __cplusplus >= 201103L
  739. basic_ostringstream(const basic_ostringstream&) = delete;
  740. basic_ostringstream(basic_ostringstream&& __rhs)
  741. : __ostream_type(std::move(__rhs)),
  742. _M_stringbuf(std::move(__rhs._M_stringbuf))
  743. { __ostream_type::set_rdbuf(&_M_stringbuf); }
  744. #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
  745. basic_ostringstream(ios_base::openmode __mode, const allocator_type& __a)
  746. : __ostream_type(), _M_stringbuf(__mode | ios_base::out, __a)
  747. { this->init(std::__addressof(_M_stringbuf)); }
  748. explicit
  749. basic_ostringstream(__string_type&& __str,
  750. ios_base::openmode __mode = ios_base::out)
  751. : __ostream_type(), _M_stringbuf(std::move(__str), __mode | ios_base::out)
  752. { this->init(std::__addressof(_M_stringbuf)); }
  753. template<typename _SAlloc>
  754. basic_ostringstream(const basic_string<_CharT, _Traits, _SAlloc>& __str,
  755. const allocator_type& __a)
  756. : basic_ostringstream(__str, ios_base::out, __a)
  757. { }
  758. template<typename _SAlloc>
  759. basic_ostringstream(const basic_string<_CharT, _Traits, _SAlloc>& __str,
  760. ios_base::openmode __mode,
  761. const allocator_type& __a)
  762. : __ostream_type(), _M_stringbuf(__str, __mode | ios_base::out, __a)
  763. { this->init(std::__addressof(_M_stringbuf)); }
  764. template<typename _SAlloc>
  765. explicit
  766. basic_ostringstream(const basic_string<_CharT, _Traits, _SAlloc>& __str,
  767. ios_base::openmode __mode = ios_base::out)
  768. : basic_ostringstream(__str, __mode, allocator_type())
  769. { }
  770. #endif // C++20
  771. // 27.8.3.2 Assign and swap:
  772. basic_ostringstream&
  773. operator=(const basic_ostringstream&) = delete;
  774. basic_ostringstream&
  775. operator=(basic_ostringstream&& __rhs)
  776. {
  777. __ostream_type::operator=(std::move(__rhs));
  778. _M_stringbuf = std::move(__rhs._M_stringbuf);
  779. return *this;
  780. }
  781. void
  782. swap(basic_ostringstream& __rhs)
  783. {
  784. __ostream_type::swap(__rhs);
  785. _M_stringbuf.swap(__rhs._M_stringbuf);
  786. }
  787. #endif // C++11
  788. // Members:
  789. /**
  790. * @brief Accessing the underlying buffer.
  791. * @return The current basic_stringbuf buffer.
  792. *
  793. * This hides both signatures of std::basic_ios::rdbuf().
  794. */
  795. __stringbuf_type*
  796. rdbuf() const
  797. { return const_cast<__stringbuf_type*>(&_M_stringbuf); }
  798. /**
  799. * @brief Copying out the string buffer.
  800. * @return @c rdbuf()->str()
  801. */
  802. __string_type
  803. str() const _GLIBCXX_LVAL_REF_QUAL
  804. { return _M_stringbuf.str(); }
  805. #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
  806. #if __cpp_concepts
  807. template<__allocator_like _SAlloc>
  808. basic_string<_CharT, _Traits, _SAlloc>
  809. str(const _SAlloc& __sa) const
  810. { return _M_stringbuf.str(__sa); }
  811. #endif
  812. __string_type
  813. str() &&
  814. { return std::move(_M_stringbuf).str(); }
  815. basic_string_view<char_type, traits_type>
  816. view() const noexcept
  817. { return _M_stringbuf.view(); }
  818. #endif
  819. /**
  820. * @brief Setting a new buffer.
  821. * @param __s The string to use as a new sequence.
  822. *
  823. * Calls @c rdbuf()->str(s).
  824. */
  825. void
  826. str(const __string_type& __s)
  827. { _M_stringbuf.str(__s); }
  828. #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
  829. #if __cpp_concepts
  830. template<__allocator_like _SAlloc>
  831. requires (!is_same_v<_SAlloc, _Alloc>)
  832. void
  833. str(const basic_string<_CharT, _Traits, _SAlloc>& __s)
  834. { _M_stringbuf.str(__s); }
  835. #endif
  836. void
  837. str(__string_type&& __s)
  838. { _M_stringbuf.str(std::move(__s)); }
  839. #endif
  840. };
  841. // [27.7.4] Template class basic_stringstream
  842. /**
  843. * @brief Controlling input and output for std::string.
  844. * @ingroup io
  845. *
  846. * @tparam _CharT Type of character stream.
  847. * @tparam _Traits Traits for character type, defaults to
  848. * char_traits<_CharT>.
  849. * @tparam _Alloc Allocator type, defaults to allocator<_CharT>.
  850. *
  851. * This class supports reading from and writing to objects of type
  852. * std::basic_string, using the inherited functions from
  853. * std::basic_iostream. To control the associated sequence, an instance
  854. * of std::basic_stringbuf is used, which this page refers to as @c sb.
  855. */
  856. template <typename _CharT, typename _Traits, typename _Alloc>
  857. class basic_stringstream : public basic_iostream<_CharT, _Traits>
  858. {
  859. public:
  860. // Types:
  861. typedef _CharT char_type;
  862. typedef _Traits traits_type;
  863. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  864. // 251. basic_stringbuf missing allocator_type
  865. typedef _Alloc allocator_type;
  866. typedef typename traits_type::int_type int_type;
  867. typedef typename traits_type::pos_type pos_type;
  868. typedef typename traits_type::off_type off_type;
  869. // Non-standard Types:
  870. typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
  871. typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type;
  872. typedef basic_iostream<char_type, traits_type> __iostream_type;
  873. private:
  874. __stringbuf_type _M_stringbuf;
  875. public:
  876. // Constructors/destructors
  877. /**
  878. * @brief Default constructor starts with an empty string buffer.
  879. *
  880. * Initializes @c sb using the mode @c in|out, and passes @c &sb
  881. * to the base class initializer. Does not allocate any buffer.
  882. *
  883. * That's a lie. We initialize the base class with NULL, because the
  884. * string class does its own memory management.
  885. */
  886. basic_stringstream()
  887. : __iostream_type(), _M_stringbuf(ios_base::out | ios_base::in)
  888. { this->init(&_M_stringbuf); }
  889. /**
  890. * @brief Starts with an empty string buffer.
  891. * @param __m Whether the buffer can read, or write, or both.
  892. *
  893. * Initializes @c sb using the mode from @c __m, and passes @c &sb
  894. * to the base class initializer. Does not allocate any buffer.
  895. *
  896. * That's a lie. We initialize the base class with NULL, because the
  897. * string class does its own memory management.
  898. */
  899. explicit
  900. basic_stringstream(ios_base::openmode __m)
  901. : __iostream_type(), _M_stringbuf(__m)
  902. { this->init(&_M_stringbuf); }
  903. /**
  904. * @brief Starts with an existing string buffer.
  905. * @param __str A string to copy as a starting buffer.
  906. * @param __m Whether the buffer can read, or write, or both.
  907. *
  908. * Initializes @c sb using @a __str and @c __m, and passes @c &sb
  909. * to the base class initializer.
  910. *
  911. * That's a lie. We initialize the base class with NULL, because the
  912. * string class does its own memory management.
  913. */
  914. explicit
  915. basic_stringstream(const __string_type& __str,
  916. ios_base::openmode __m = ios_base::out | ios_base::in)
  917. : __iostream_type(), _M_stringbuf(__str, __m)
  918. { this->init(&_M_stringbuf); }
  919. /**
  920. * @brief The destructor does nothing.
  921. *
  922. * The buffer is deallocated by the stringbuf object, not the
  923. * formatting stream.
  924. */
  925. ~basic_stringstream()
  926. { }
  927. #if __cplusplus >= 201103L
  928. basic_stringstream(const basic_stringstream&) = delete;
  929. basic_stringstream(basic_stringstream&& __rhs)
  930. : __iostream_type(std::move(__rhs)),
  931. _M_stringbuf(std::move(__rhs._M_stringbuf))
  932. { __iostream_type::set_rdbuf(&_M_stringbuf); }
  933. #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
  934. basic_stringstream(ios_base::openmode __mode, const allocator_type& __a)
  935. : __iostream_type(), _M_stringbuf(__mode, __a)
  936. { this->init(&_M_stringbuf); }
  937. explicit
  938. basic_stringstream(__string_type&& __str,
  939. ios_base::openmode __mode = ios_base::in
  940. | ios_base::out)
  941. : __iostream_type(), _M_stringbuf(std::move(__str), __mode)
  942. { this->init(std::__addressof(_M_stringbuf)); }
  943. template<typename _SAlloc>
  944. basic_stringstream(const basic_string<_CharT, _Traits, _SAlloc>& __str,
  945. const allocator_type& __a)
  946. : basic_stringstream(__str, ios_base::in | ios_base::out, __a)
  947. { }
  948. template<typename _SAlloc>
  949. basic_stringstream(const basic_string<_CharT, _Traits, _SAlloc>& __str,
  950. ios_base::openmode __mode,
  951. const allocator_type& __a)
  952. : __iostream_type(), _M_stringbuf(__str, __mode, __a)
  953. { this->init(std::__addressof(_M_stringbuf)); }
  954. template<typename _SAlloc>
  955. explicit
  956. basic_stringstream(const basic_string<_CharT, _Traits, _SAlloc>& __str,
  957. ios_base::openmode __mode = ios_base::in
  958. | ios_base::out)
  959. : basic_stringstream(__str, __mode, allocator_type())
  960. { }
  961. #endif // C++20
  962. // 27.8.3.2 Assign and swap:
  963. basic_stringstream&
  964. operator=(const basic_stringstream&) = delete;
  965. basic_stringstream&
  966. operator=(basic_stringstream&& __rhs)
  967. {
  968. __iostream_type::operator=(std::move(__rhs));
  969. _M_stringbuf = std::move(__rhs._M_stringbuf);
  970. return *this;
  971. }
  972. void
  973. swap(basic_stringstream& __rhs)
  974. {
  975. __iostream_type::swap(__rhs);
  976. _M_stringbuf.swap(__rhs._M_stringbuf);
  977. }
  978. #endif // C++11
  979. // Members:
  980. /**
  981. * @brief Accessing the underlying buffer.
  982. * @return The current basic_stringbuf buffer.
  983. *
  984. * This hides both signatures of std::basic_ios::rdbuf().
  985. */
  986. __stringbuf_type*
  987. rdbuf() const
  988. { return const_cast<__stringbuf_type*>(&_M_stringbuf); }
  989. /**
  990. * @brief Copying out the string buffer.
  991. * @return @c rdbuf()->str()
  992. */
  993. __string_type
  994. str() const _GLIBCXX_LVAL_REF_QUAL
  995. { return _M_stringbuf.str(); }
  996. #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
  997. #if __cpp_concepts
  998. template<__allocator_like _SAlloc>
  999. basic_string<_CharT, _Traits, _SAlloc>
  1000. str(const _SAlloc& __sa) const
  1001. { return _M_stringbuf.str(__sa); }
  1002. #endif
  1003. __string_type
  1004. str() &&
  1005. { return std::move(_M_stringbuf).str(); }
  1006. basic_string_view<char_type, traits_type>
  1007. view() const noexcept
  1008. { return _M_stringbuf.view(); }
  1009. #endif
  1010. /**
  1011. * @brief Setting a new buffer.
  1012. * @param __s The string to use as a new sequence.
  1013. *
  1014. * Calls @c rdbuf()->str(s).
  1015. */
  1016. void
  1017. str(const __string_type& __s)
  1018. { _M_stringbuf.str(__s); }
  1019. #if __cplusplus > 201703L && _GLIBCXX_USE_CXX11_ABI
  1020. #if __cpp_concepts
  1021. template<__allocator_like _SAlloc>
  1022. requires (!is_same_v<_SAlloc, _Alloc>)
  1023. void
  1024. str(const basic_string<_CharT, _Traits, _SAlloc>& __s)
  1025. { _M_stringbuf.str(__s); }
  1026. #endif
  1027. void
  1028. str(__string_type&& __s)
  1029. { _M_stringbuf.str(std::move(__s)); }
  1030. #endif
  1031. };
  1032. #if __cplusplus >= 201103L
  1033. /// Swap specialization for stringbufs.
  1034. template <class _CharT, class _Traits, class _Allocator>
  1035. inline void
  1036. swap(basic_stringbuf<_CharT, _Traits, _Allocator>& __x,
  1037. basic_stringbuf<_CharT, _Traits, _Allocator>& __y)
  1038. noexcept(noexcept(__x.swap(__y)))
  1039. { __x.swap(__y); }
  1040. /// Swap specialization for istringstreams.
  1041. template <class _CharT, class _Traits, class _Allocator>
  1042. inline void
  1043. swap(basic_istringstream<_CharT, _Traits, _Allocator>& __x,
  1044. basic_istringstream<_CharT, _Traits, _Allocator>& __y)
  1045. { __x.swap(__y); }
  1046. /// Swap specialization for ostringstreams.
  1047. template <class _CharT, class _Traits, class _Allocator>
  1048. inline void
  1049. swap(basic_ostringstream<_CharT, _Traits, _Allocator>& __x,
  1050. basic_ostringstream<_CharT, _Traits, _Allocator>& __y)
  1051. { __x.swap(__y); }
  1052. /// Swap specialization for stringstreams.
  1053. template <class _CharT, class _Traits, class _Allocator>
  1054. inline void
  1055. swap(basic_stringstream<_CharT, _Traits, _Allocator>& __x,
  1056. basic_stringstream<_CharT, _Traits, _Allocator>& __y)
  1057. { __x.swap(__y); }
  1058. #endif // C++11
  1059. _GLIBCXX_END_NAMESPACE_CXX11
  1060. _GLIBCXX_END_NAMESPACE_VERSION
  1061. } // namespace
  1062. #undef _GLIBCXX_LVAL_REF_QUAL
  1063. #include <bits/sstream.tcc>
  1064. #endif /* _GLIBCXX_SSTREAM */