sstream 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815
  1. // String based streams -*- C++ -*-
  2. // Copyright (C) 1997-2015 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. namespace std _GLIBCXX_VISIBILITY(default)
  32. {
  33. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  34. _GLIBCXX_BEGIN_NAMESPACE_CXX11
  35. // [27.7.1] template class basic_stringbuf
  36. /**
  37. * @brief The actual work of input and output (for std::string).
  38. * @ingroup io
  39. *
  40. * @tparam _CharT Type of character stream.
  41. * @tparam _Traits Traits for character type, defaults to
  42. * char_traits<_CharT>.
  43. * @tparam _Alloc Allocator type, defaults to allocator<_CharT>.
  44. *
  45. * This class associates either or both of its input and output sequences
  46. * with a sequence of characters, which can be initialized from, or made
  47. * available as, a @c std::basic_string. (Paraphrased from [27.7.1]/1.)
  48. *
  49. * For this class, open modes (of type @c ios_base::openmode) have
  50. * @c in set if the input sequence can be read, and @c out set if the
  51. * output sequence can be written.
  52. */
  53. template<typename _CharT, typename _Traits, typename _Alloc>
  54. class basic_stringbuf : public basic_streambuf<_CharT, _Traits>
  55. {
  56. struct __xfer_bufptrs;
  57. public:
  58. // Types:
  59. typedef _CharT char_type;
  60. typedef _Traits traits_type;
  61. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  62. // 251. basic_stringbuf missing allocator_type
  63. typedef _Alloc allocator_type;
  64. typedef typename traits_type::int_type int_type;
  65. typedef typename traits_type::pos_type pos_type;
  66. typedef typename traits_type::off_type off_type;
  67. typedef basic_streambuf<char_type, traits_type> __streambuf_type;
  68. typedef basic_string<char_type, _Traits, _Alloc> __string_type;
  69. typedef typename __string_type::size_type __size_type;
  70. protected:
  71. /// Place to stash in || out || in | out settings for current stringbuf.
  72. ios_base::openmode _M_mode;
  73. // Data Members:
  74. __string_type _M_string;
  75. public:
  76. // Constructors:
  77. /**
  78. * @brief Starts with an empty string buffer.
  79. * @param __mode Whether the buffer can read, or write, or both.
  80. *
  81. * The default constructor initializes the parent class using its
  82. * own default ctor.
  83. */
  84. explicit
  85. basic_stringbuf(ios_base::openmode __mode = ios_base::in | ios_base::out)
  86. : __streambuf_type(), _M_mode(__mode), _M_string()
  87. { }
  88. /**
  89. * @brief Starts with an existing string buffer.
  90. * @param __str A string to copy as a starting buffer.
  91. * @param __mode Whether the buffer can read, or write, or both.
  92. *
  93. * This constructor initializes the parent class using its
  94. * own default ctor.
  95. */
  96. explicit
  97. basic_stringbuf(const __string_type& __str,
  98. ios_base::openmode __mode = ios_base::in | ios_base::out)
  99. : __streambuf_type(), _M_mode(), _M_string(__str.data(), __str.size())
  100. { _M_stringbuf_init(__mode); }
  101. #if __cplusplus >= 201103L
  102. basic_stringbuf(const basic_stringbuf&) = delete;
  103. basic_stringbuf(basic_stringbuf&& __rhs)
  104. : basic_stringbuf(std::move(__rhs), __xfer_bufptrs(__rhs, this))
  105. { __rhs._M_sync(const_cast<char_type*>(__rhs._M_string.data()), 0, 0); }
  106. // 27.8.2.2 Assign and swap:
  107. basic_stringbuf&
  108. operator=(const basic_stringbuf&) = delete;
  109. basic_stringbuf&
  110. operator=(basic_stringbuf&& __rhs)
  111. {
  112. __xfer_bufptrs __st{__rhs, this};
  113. const __streambuf_type& __base = __rhs;
  114. __streambuf_type::operator=(__base);
  115. this->pubimbue(__rhs.getloc());
  116. _M_mode = __rhs._M_mode;
  117. _M_string = std::move(__rhs._M_string);
  118. __rhs._M_sync(const_cast<char_type*>(__rhs._M_string.data()), 0, 0);
  119. return *this;
  120. }
  121. void
  122. swap(basic_stringbuf& __rhs)
  123. {
  124. __xfer_bufptrs __l_st{*this, std::__addressof(__rhs)};
  125. __xfer_bufptrs __r_st{__rhs, this};
  126. __streambuf_type& __base = __rhs;
  127. __streambuf_type::swap(__base);
  128. __rhs.pubimbue(this->pubimbue(__rhs.getloc()));
  129. std::swap(_M_mode, __rhs._M_mode);
  130. std::swap(_M_string, __rhs._M_string);
  131. }
  132. #endif
  133. // Get and set:
  134. /**
  135. * @brief Copying out the string buffer.
  136. * @return A copy of one of the underlying sequences.
  137. *
  138. * <em>If the buffer is only created in input mode, the underlying
  139. * character sequence is equal to the input sequence; otherwise, it
  140. * is equal to the output sequence.</em> [27.7.1.2]/1
  141. */
  142. __string_type
  143. str() const
  144. {
  145. __string_type __ret;
  146. if (this->pptr())
  147. {
  148. // The current egptr() may not be the actual string end.
  149. if (this->pptr() > this->egptr())
  150. __ret = __string_type(this->pbase(), this->pptr());
  151. else
  152. __ret = __string_type(this->pbase(), this->egptr());
  153. }
  154. else
  155. __ret = _M_string;
  156. return __ret;
  157. }
  158. /**
  159. * @brief Setting a new buffer.
  160. * @param __s The string to use as a new sequence.
  161. *
  162. * Deallocates any previous stored sequence, then copies @a s to
  163. * use as a new one.
  164. */
  165. void
  166. str(const __string_type& __s)
  167. {
  168. // Cannot use _M_string = __s, since v3 strings are COW
  169. // (not always true now but assign() always works).
  170. _M_string.assign(__s.data(), __s.size());
  171. _M_stringbuf_init(_M_mode);
  172. }
  173. protected:
  174. // Common initialization code goes here.
  175. void
  176. _M_stringbuf_init(ios_base::openmode __mode)
  177. {
  178. _M_mode = __mode;
  179. __size_type __len = 0;
  180. if (_M_mode & (ios_base::ate | ios_base::app))
  181. __len = _M_string.size();
  182. _M_sync(const_cast<char_type*>(_M_string.data()), 0, __len);
  183. }
  184. virtual streamsize
  185. showmanyc()
  186. {
  187. streamsize __ret = -1;
  188. if (_M_mode & ios_base::in)
  189. {
  190. _M_update_egptr();
  191. __ret = this->egptr() - this->gptr();
  192. }
  193. return __ret;
  194. }
  195. virtual int_type
  196. underflow();
  197. virtual int_type
  198. pbackfail(int_type __c = traits_type::eof());
  199. virtual int_type
  200. overflow(int_type __c = traits_type::eof());
  201. /**
  202. * @brief Manipulates the buffer.
  203. * @param __s Pointer to a buffer area.
  204. * @param __n Size of @a __s.
  205. * @return @c this
  206. *
  207. * If no buffer has already been created, and both @a __s and @a __n are
  208. * non-zero, then @c __s is used as a buffer; see
  209. * https://gcc.gnu.org/onlinedocs/libstdc++/manual/streambufs.html#io.streambuf.buffering
  210. * for more.
  211. */
  212. virtual __streambuf_type*
  213. setbuf(char_type* __s, streamsize __n)
  214. {
  215. if (__s && __n >= 0)
  216. {
  217. // This is implementation-defined behavior, and assumes
  218. // that an external char_type array of length __n exists
  219. // and has been pre-allocated. If this is not the case,
  220. // things will quickly blow up.
  221. // Step 1: Destroy the current internal array.
  222. _M_string.clear();
  223. // Step 2: Use the external array.
  224. _M_sync(__s, __n, 0);
  225. }
  226. return this;
  227. }
  228. virtual pos_type
  229. seekoff(off_type __off, ios_base::seekdir __way,
  230. ios_base::openmode __mode = ios_base::in | ios_base::out);
  231. virtual pos_type
  232. seekpos(pos_type __sp,
  233. ios_base::openmode __mode = ios_base::in | ios_base::out);
  234. // Internal function for correctly updating the internal buffer
  235. // for a particular _M_string, due to initialization or re-sizing
  236. // of an existing _M_string.
  237. void
  238. _M_sync(char_type* __base, __size_type __i, __size_type __o);
  239. // Internal function for correctly updating egptr() to the actual
  240. // string end.
  241. void
  242. _M_update_egptr()
  243. {
  244. const bool __testin = _M_mode & ios_base::in;
  245. if (this->pptr() && this->pptr() > this->egptr())
  246. {
  247. if (__testin)
  248. this->setg(this->eback(), this->gptr(), this->pptr());
  249. else
  250. this->setg(this->pptr(), this->pptr(), this->pptr());
  251. }
  252. }
  253. // Works around the issue with pbump, part of the protected
  254. // interface of basic_streambuf, taking just an int.
  255. void
  256. _M_pbump(char_type* __pbeg, char_type* __pend, off_type __off);
  257. private:
  258. #if __cplusplus >= 201103L
  259. #if _GLIBCXX_USE_CXX11_ABI
  260. // This type captures the state of the gptr / pptr pointers as offsets
  261. // so they can be restored in another object after moving the string.
  262. struct __xfer_bufptrs
  263. {
  264. __xfer_bufptrs(const basic_stringbuf& __from, basic_stringbuf* __to)
  265. : _M_to{__to}, _M_goff{-1, -1, -1}, _M_poff{-1, -1, -1}
  266. {
  267. const _CharT* __str = __from._M_string.data();
  268. if (__from.eback())
  269. {
  270. _M_goff[0] = __from.eback() - __str;
  271. _M_goff[1] = __from.gptr() - __str;
  272. _M_goff[2] = __from.egptr() - __str;
  273. }
  274. if (__from.pbase())
  275. {
  276. _M_poff[0] = __from.pbase() - __str;
  277. _M_poff[1] = __from.pptr() - __from.pbase();
  278. _M_poff[2] = __from.epptr() - __str;
  279. }
  280. }
  281. ~__xfer_bufptrs()
  282. {
  283. char_type* __str = const_cast<char_type*>(_M_to->_M_string.data());
  284. if (_M_goff[0] != -1)
  285. _M_to->setg(__str+_M_goff[0], __str+_M_goff[1], __str+_M_goff[2]);
  286. if (_M_poff[0] != -1)
  287. _M_to->_M_pbump(__str+_M_poff[0], __str+_M_poff[2], _M_poff[1]);
  288. }
  289. basic_stringbuf* _M_to;
  290. off_type _M_goff[3];
  291. off_type _M_poff[3];
  292. };
  293. #else
  294. // This type does nothing when using Copy-On-Write strings.
  295. struct __xfer_bufptrs
  296. {
  297. __xfer_bufptrs(const basic_stringbuf&, basic_stringbuf*) { }
  298. };
  299. #endif
  300. // The move constructor initializes an __xfer_bufptrs temporary then
  301. // delegates to this constructor to performs moves during its lifetime.
  302. basic_stringbuf(basic_stringbuf&& __rhs, __xfer_bufptrs&&)
  303. : __streambuf_type(static_cast<const __streambuf_type&>(__rhs)),
  304. _M_mode(__rhs._M_mode), _M_string(std::move(__rhs._M_string))
  305. { }
  306. #endif
  307. };
  308. // [27.7.2] Template class basic_istringstream
  309. /**
  310. * @brief Controlling input for std::string.
  311. * @ingroup io
  312. *
  313. * @tparam _CharT Type of character stream.
  314. * @tparam _Traits Traits for character type, defaults to
  315. * char_traits<_CharT>.
  316. * @tparam _Alloc Allocator type, defaults to allocator<_CharT>.
  317. *
  318. * This class supports reading from objects of type std::basic_string,
  319. * using the inherited functions from std::basic_istream. To control
  320. * the associated sequence, an instance of std::basic_stringbuf is used,
  321. * which this page refers to as @c sb.
  322. */
  323. template<typename _CharT, typename _Traits, typename _Alloc>
  324. class basic_istringstream : public basic_istream<_CharT, _Traits>
  325. {
  326. public:
  327. // Types:
  328. typedef _CharT char_type;
  329. typedef _Traits traits_type;
  330. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  331. // 251. basic_stringbuf missing allocator_type
  332. typedef _Alloc allocator_type;
  333. typedef typename traits_type::int_type int_type;
  334. typedef typename traits_type::pos_type pos_type;
  335. typedef typename traits_type::off_type off_type;
  336. // Non-standard types:
  337. typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
  338. typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type;
  339. typedef basic_istream<char_type, traits_type> __istream_type;
  340. private:
  341. __stringbuf_type _M_stringbuf;
  342. public:
  343. // Constructors:
  344. /**
  345. * @brief Default constructor starts with an empty string buffer.
  346. * @param __mode Whether the buffer can read, or write, or both.
  347. *
  348. * @c ios_base::in is automatically included in @a __mode.
  349. *
  350. * Initializes @c sb using @c __mode|in, and passes @c &sb to the base
  351. * class initializer. Does not allocate any buffer.
  352. *
  353. * That's a lie. We initialize the base class with NULL, because the
  354. * string class does its own memory management.
  355. */
  356. explicit
  357. basic_istringstream(ios_base::openmode __mode = ios_base::in)
  358. : __istream_type(), _M_stringbuf(__mode | ios_base::in)
  359. { this->init(&_M_stringbuf); }
  360. /**
  361. * @brief Starts with an existing string buffer.
  362. * @param __str A string to copy as a starting buffer.
  363. * @param __mode Whether the buffer can read, or write, or both.
  364. *
  365. * @c ios_base::in is automatically included in @a mode.
  366. *
  367. * Initializes @c sb using @a str and @c mode|in, and passes @c &sb
  368. * to the base class initializer.
  369. *
  370. * That's a lie. We initialize the base class with NULL, because the
  371. * string class does its own memory management.
  372. */
  373. explicit
  374. basic_istringstream(const __string_type& __str,
  375. ios_base::openmode __mode = ios_base::in)
  376. : __istream_type(), _M_stringbuf(__str, __mode | ios_base::in)
  377. { this->init(&_M_stringbuf); }
  378. /**
  379. * @brief The destructor does nothing.
  380. *
  381. * The buffer is deallocated by the stringbuf object, not the
  382. * formatting stream.
  383. */
  384. ~basic_istringstream()
  385. { }
  386. #if __cplusplus >= 201103L
  387. basic_istringstream(const basic_istringstream&) = delete;
  388. basic_istringstream(basic_istringstream&& __rhs)
  389. : __istream_type(std::move(__rhs)),
  390. _M_stringbuf(std::move(__rhs._M_stringbuf))
  391. { __istream_type::set_rdbuf(&_M_stringbuf); }
  392. // 27.8.3.2 Assign and swap:
  393. basic_istringstream&
  394. operator=(const basic_istringstream&) = delete;
  395. basic_istringstream&
  396. operator=(basic_istringstream&& __rhs)
  397. {
  398. __istream_type::operator=(std::move(__rhs));
  399. _M_stringbuf = std::move(__rhs._M_stringbuf);
  400. return *this;
  401. }
  402. void
  403. swap(basic_istringstream& __rhs)
  404. {
  405. __istream_type::swap(__rhs);
  406. _M_stringbuf.swap(__rhs._M_stringbuf);
  407. }
  408. #endif
  409. // Members:
  410. /**
  411. * @brief Accessing the underlying buffer.
  412. * @return The current basic_stringbuf buffer.
  413. *
  414. * This hides both signatures of std::basic_ios::rdbuf().
  415. */
  416. __stringbuf_type*
  417. rdbuf() const
  418. { return const_cast<__stringbuf_type*>(&_M_stringbuf); }
  419. /**
  420. * @brief Copying out the string buffer.
  421. * @return @c rdbuf()->str()
  422. */
  423. __string_type
  424. str() const
  425. { return _M_stringbuf.str(); }
  426. /**
  427. * @brief Setting a new buffer.
  428. * @param __s The string to use as a new sequence.
  429. *
  430. * Calls @c rdbuf()->str(s).
  431. */
  432. void
  433. str(const __string_type& __s)
  434. { _M_stringbuf.str(__s); }
  435. };
  436. // [27.7.3] Template class basic_ostringstream
  437. /**
  438. * @brief Controlling output for std::string.
  439. * @ingroup io
  440. *
  441. * @tparam _CharT Type of character stream.
  442. * @tparam _Traits Traits for character type, defaults to
  443. * char_traits<_CharT>.
  444. * @tparam _Alloc Allocator type, defaults to allocator<_CharT>.
  445. *
  446. * This class supports writing to objects of type std::basic_string,
  447. * using the inherited functions from std::basic_ostream. To control
  448. * the associated sequence, an instance of std::basic_stringbuf is used,
  449. * which this page refers to as @c sb.
  450. */
  451. template <typename _CharT, typename _Traits, typename _Alloc>
  452. class basic_ostringstream : public basic_ostream<_CharT, _Traits>
  453. {
  454. public:
  455. // Types:
  456. typedef _CharT char_type;
  457. typedef _Traits traits_type;
  458. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  459. // 251. basic_stringbuf missing allocator_type
  460. typedef _Alloc allocator_type;
  461. typedef typename traits_type::int_type int_type;
  462. typedef typename traits_type::pos_type pos_type;
  463. typedef typename traits_type::off_type off_type;
  464. // Non-standard types:
  465. typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
  466. typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type;
  467. typedef basic_ostream<char_type, traits_type> __ostream_type;
  468. private:
  469. __stringbuf_type _M_stringbuf;
  470. public:
  471. // Constructors/destructor:
  472. /**
  473. * @brief Default constructor starts with an empty string buffer.
  474. * @param __mode Whether the buffer can read, or write, or both.
  475. *
  476. * @c ios_base::out is automatically included in @a mode.
  477. *
  478. * Initializes @c sb using @c mode|out, and passes @c &sb to the base
  479. * class initializer. Does not allocate any buffer.
  480. *
  481. * That's a lie. We initialize the base class with NULL, because the
  482. * string class does its own memory management.
  483. */
  484. explicit
  485. basic_ostringstream(ios_base::openmode __mode = ios_base::out)
  486. : __ostream_type(), _M_stringbuf(__mode | ios_base::out)
  487. { this->init(&_M_stringbuf); }
  488. /**
  489. * @brief Starts with an existing string buffer.
  490. * @param __str A string to copy as a starting buffer.
  491. * @param __mode Whether the buffer can read, or write, or both.
  492. *
  493. * @c ios_base::out is automatically included in @a mode.
  494. *
  495. * Initializes @c sb using @a str and @c mode|out, and passes @c &sb
  496. * to the base class initializer.
  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. explicit
  502. basic_ostringstream(const __string_type& __str,
  503. ios_base::openmode __mode = ios_base::out)
  504. : __ostream_type(), _M_stringbuf(__str, __mode | ios_base::out)
  505. { this->init(&_M_stringbuf); }
  506. /**
  507. * @brief The destructor does nothing.
  508. *
  509. * The buffer is deallocated by the stringbuf object, not the
  510. * formatting stream.
  511. */
  512. ~basic_ostringstream()
  513. { }
  514. #if __cplusplus >= 201103L
  515. basic_ostringstream(const basic_ostringstream&) = delete;
  516. basic_ostringstream(basic_ostringstream&& __rhs)
  517. : __ostream_type(std::move(__rhs)),
  518. _M_stringbuf(std::move(__rhs._M_stringbuf))
  519. { __ostream_type::set_rdbuf(&_M_stringbuf); }
  520. // 27.8.3.2 Assign and swap:
  521. basic_ostringstream&
  522. operator=(const basic_ostringstream&) = delete;
  523. basic_ostringstream&
  524. operator=(basic_ostringstream&& __rhs)
  525. {
  526. __ostream_type::operator=(std::move(__rhs));
  527. _M_stringbuf = std::move(__rhs._M_stringbuf);
  528. return *this;
  529. }
  530. void
  531. swap(basic_ostringstream& __rhs)
  532. {
  533. __ostream_type::swap(__rhs);
  534. _M_stringbuf.swap(__rhs._M_stringbuf);
  535. }
  536. #endif
  537. // Members:
  538. /**
  539. * @brief Accessing the underlying buffer.
  540. * @return The current basic_stringbuf buffer.
  541. *
  542. * This hides both signatures of std::basic_ios::rdbuf().
  543. */
  544. __stringbuf_type*
  545. rdbuf() const
  546. { return const_cast<__stringbuf_type*>(&_M_stringbuf); }
  547. /**
  548. * @brief Copying out the string buffer.
  549. * @return @c rdbuf()->str()
  550. */
  551. __string_type
  552. str() const
  553. { return _M_stringbuf.str(); }
  554. /**
  555. * @brief Setting a new buffer.
  556. * @param __s The string to use as a new sequence.
  557. *
  558. * Calls @c rdbuf()->str(s).
  559. */
  560. void
  561. str(const __string_type& __s)
  562. { _M_stringbuf.str(__s); }
  563. };
  564. // [27.7.4] Template class basic_stringstream
  565. /**
  566. * @brief Controlling input and output for std::string.
  567. * @ingroup io
  568. *
  569. * @tparam _CharT Type of character stream.
  570. * @tparam _Traits Traits for character type, defaults to
  571. * char_traits<_CharT>.
  572. * @tparam _Alloc Allocator type, defaults to allocator<_CharT>.
  573. *
  574. * This class supports reading from and writing to objects of type
  575. * std::basic_string, using the inherited functions from
  576. * std::basic_iostream. To control the associated sequence, an instance
  577. * of std::basic_stringbuf is used, which this page refers to as @c sb.
  578. */
  579. template <typename _CharT, typename _Traits, typename _Alloc>
  580. class basic_stringstream : public basic_iostream<_CharT, _Traits>
  581. {
  582. public:
  583. // Types:
  584. typedef _CharT char_type;
  585. typedef _Traits traits_type;
  586. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  587. // 251. basic_stringbuf missing allocator_type
  588. typedef _Alloc allocator_type;
  589. typedef typename traits_type::int_type int_type;
  590. typedef typename traits_type::pos_type pos_type;
  591. typedef typename traits_type::off_type off_type;
  592. // Non-standard Types:
  593. typedef basic_string<_CharT, _Traits, _Alloc> __string_type;
  594. typedef basic_stringbuf<_CharT, _Traits, _Alloc> __stringbuf_type;
  595. typedef basic_iostream<char_type, traits_type> __iostream_type;
  596. private:
  597. __stringbuf_type _M_stringbuf;
  598. public:
  599. // Constructors/destructors
  600. /**
  601. * @brief Default constructor starts with an empty string buffer.
  602. * @param __m Whether the buffer can read, or write, or both.
  603. *
  604. * Initializes @c sb using the mode from @c __m, and passes @c
  605. * &sb to the base class initializer. Does not allocate any
  606. * buffer.
  607. *
  608. * That's a lie. We initialize the base class with NULL, because the
  609. * string class does its own memory management.
  610. */
  611. explicit
  612. basic_stringstream(ios_base::openmode __m = ios_base::out | ios_base::in)
  613. : __iostream_type(), _M_stringbuf(__m)
  614. { this->init(&_M_stringbuf); }
  615. /**
  616. * @brief Starts with an existing string buffer.
  617. * @param __str A string to copy as a starting buffer.
  618. * @param __m Whether the buffer can read, or write, or both.
  619. *
  620. * Initializes @c sb using @a __str and @c __m, and passes @c &sb
  621. * to the base class initializer.
  622. *
  623. * That's a lie. We initialize the base class with NULL, because the
  624. * string class does its own memory management.
  625. */
  626. explicit
  627. basic_stringstream(const __string_type& __str,
  628. ios_base::openmode __m = ios_base::out | ios_base::in)
  629. : __iostream_type(), _M_stringbuf(__str, __m)
  630. { this->init(&_M_stringbuf); }
  631. /**
  632. * @brief The destructor does nothing.
  633. *
  634. * The buffer is deallocated by the stringbuf object, not the
  635. * formatting stream.
  636. */
  637. ~basic_stringstream()
  638. { }
  639. #if __cplusplus >= 201103L
  640. basic_stringstream(const basic_stringstream&) = delete;
  641. basic_stringstream(basic_stringstream&& __rhs)
  642. : __iostream_type(std::move(__rhs)),
  643. _M_stringbuf(std::move(__rhs._M_stringbuf))
  644. { __iostream_type::set_rdbuf(&_M_stringbuf); }
  645. // 27.8.3.2 Assign and swap:
  646. basic_stringstream&
  647. operator=(const basic_stringstream&) = delete;
  648. basic_stringstream&
  649. operator=(basic_stringstream&& __rhs)
  650. {
  651. __iostream_type::operator=(std::move(__rhs));
  652. _M_stringbuf = std::move(__rhs._M_stringbuf);
  653. return *this;
  654. }
  655. void
  656. swap(basic_stringstream& __rhs)
  657. {
  658. __iostream_type::swap(__rhs);
  659. _M_stringbuf.swap(__rhs._M_stringbuf);
  660. }
  661. #endif
  662. // Members:
  663. /**
  664. * @brief Accessing the underlying buffer.
  665. * @return The current basic_stringbuf buffer.
  666. *
  667. * This hides both signatures of std::basic_ios::rdbuf().
  668. */
  669. __stringbuf_type*
  670. rdbuf() const
  671. { return const_cast<__stringbuf_type*>(&_M_stringbuf); }
  672. /**
  673. * @brief Copying out the string buffer.
  674. * @return @c rdbuf()->str()
  675. */
  676. __string_type
  677. str() const
  678. { return _M_stringbuf.str(); }
  679. /**
  680. * @brief Setting a new buffer.
  681. * @param __s The string to use as a new sequence.
  682. *
  683. * Calls @c rdbuf()->str(s).
  684. */
  685. void
  686. str(const __string_type& __s)
  687. { _M_stringbuf.str(__s); }
  688. };
  689. #if __cplusplus >= 201103L
  690. /// Swap specialization for stringbufs.
  691. template <class _CharT, class _Traits, class _Allocator>
  692. inline void
  693. swap(basic_stringbuf<_CharT, _Traits, _Allocator>& __x,
  694. basic_stringbuf<_CharT, _Traits, _Allocator>& __y)
  695. { __x.swap(__y); }
  696. /// Swap specialization for istringstreams.
  697. template <class _CharT, class _Traits, class _Allocator>
  698. inline void
  699. swap(basic_istringstream<_CharT, _Traits, _Allocator>& __x,
  700. basic_istringstream<_CharT, _Traits, _Allocator>& __y)
  701. { __x.swap(__y); }
  702. /// Swap specialization for ostringstreams.
  703. template <class _CharT, class _Traits, class _Allocator>
  704. inline void
  705. swap(basic_ostringstream<_CharT, _Traits, _Allocator>& __x,
  706. basic_ostringstream<_CharT, _Traits, _Allocator>& __y)
  707. { __x.swap(__y); }
  708. /// Swap specialization for stringstreams.
  709. template <class _CharT, class _Traits, class _Allocator>
  710. inline void
  711. swap(basic_stringstream<_CharT, _Traits, _Allocator>& __x,
  712. basic_stringstream<_CharT, _Traits, _Allocator>& __y)
  713. { __x.swap(__y); }
  714. #endif
  715. _GLIBCXX_END_NAMESPACE_CXX11
  716. _GLIBCXX_END_NAMESPACE_VERSION
  717. } // namespace
  718. #include <bits/sstream.tcc>
  719. #endif /* _GLIBCXX_SSTREAM */