vectorstream.hpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614
  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
  4. // Software License, Version 1.0. (See accompanying file
  5. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. // See http://www.boost.org/libs/interprocess for documentation.
  8. //
  9. //////////////////////////////////////////////////////////////////////////////
  10. //
  11. // This file comes from SGI's sstream file. Modified by Ion Gaztanaga 2005-2012.
  12. // Changed internal SGI string to a generic, templatized vector. Added efficient
  13. // internal buffer get/set/swap functions, so that we can obtain/establish the
  14. // internal buffer without any reallocation or copy. Kill those temporaries!
  15. ///////////////////////////////////////////////////////////////////////////////
  16. /*
  17. * Copyright (c) 1998
  18. * Silicon Graphics Computer Systems, Inc.
  19. *
  20. * Permission to use, copy, modify, distribute and sell this software
  21. * and its documentation for any purpose is hereby granted without fee,
  22. * provided that the above copyright notice appear in all copies and
  23. * that both that copyright notice and this permission notice appear
  24. * in supporting documentation. Silicon Graphics makes no
  25. * representations about the suitability of this software for any
  26. * purpose. It is provided "as is" without express or implied warranty.
  27. */
  28. //!\file
  29. //!This file defines basic_vectorbuf, basic_ivectorstream,
  30. //!basic_ovectorstream, and basic_vectorstreamclasses. These classes
  31. //!represent streamsbufs and streams whose sources or destinations are
  32. //!STL-like vectors that can be swapped with external vectors to avoid
  33. //!unnecessary allocations/copies.
  34. #ifndef BOOST_INTERPROCESS_VECTORSTREAM_HPP
  35. #define BOOST_INTERPROCESS_VECTORSTREAM_HPP
  36. #include <boost/interprocess/detail/config_begin.hpp>
  37. #include <boost/interprocess/detail/workaround.hpp>
  38. #include <iosfwd>
  39. #include <ios>
  40. #include <istream>
  41. #include <ostream>
  42. #include <string> // char traits
  43. #include <cstddef> // ptrdiff_t
  44. #include <boost/interprocess/interprocess_fwd.hpp>
  45. #include <boost/assert.hpp>
  46. namespace boost { namespace interprocess {
  47. //!A streambuf class that controls the transmission of elements to and from
  48. //!a basic_ivectorstream, basic_ovectorstream or basic_vectorstream.
  49. //!It holds a character vector specified by CharVector template parameter
  50. //!as its formatting buffer. The vector must have contiguous storage, like
  51. //!std::vector, boost::interprocess::vector or boost::interprocess::basic_string
  52. template <class CharVector, class CharTraits>
  53. class basic_vectorbuf
  54. : public std::basic_streambuf<typename CharVector::value_type, CharTraits>
  55. {
  56. public:
  57. typedef CharVector vector_type;
  58. typedef typename CharVector::value_type char_type;
  59. typedef typename CharTraits::int_type int_type;
  60. typedef typename CharTraits::pos_type pos_type;
  61. typedef typename CharTraits::off_type off_type;
  62. typedef CharTraits traits_type;
  63. /// @cond
  64. private:
  65. typedef std::basic_streambuf<char_type, traits_type> base_t;
  66. basic_vectorbuf(const basic_vectorbuf&);
  67. basic_vectorbuf & operator =(const basic_vectorbuf&);
  68. /// @endcond
  69. public:
  70. //!Constructor. Throws if vector_type default
  71. //!constructor throws.
  72. explicit basic_vectorbuf(std::ios_base::openmode mode
  73. = std::ios_base::in | std::ios_base::out)
  74. : base_t(), m_mode(mode)
  75. { this->initialize_pointers(); }
  76. //!Constructor. Throws if
  77. //!vector_type(const VectorParameter &param) throws.
  78. template<class VectorParameter>
  79. explicit basic_vectorbuf(const VectorParameter &param,
  80. std::ios_base::openmode mode
  81. = std::ios_base::in | std::ios_base::out)
  82. : base_t(), m_mode(mode), m_vect(param)
  83. { this->initialize_pointers(); }
  84. public:
  85. //!Swaps the underlying vector with the passed vector.
  86. //!This function resets the read/write position in the stream.
  87. //!Does not throw.
  88. void swap_vector(vector_type &vect)
  89. {
  90. if (this->m_mode & std::ios_base::out){
  91. //Update high water if necessary
  92. //And resize vector to remove extra size
  93. if (mp_high_water < base_t::pptr()){
  94. //Restore the vector's size if necessary
  95. mp_high_water = base_t::pptr();
  96. }
  97. //This does not reallocate
  98. m_vect.resize(mp_high_water - (m_vect.size() ? &m_vect[0] : 0));
  99. }
  100. //Now swap vector
  101. m_vect.swap(vect);
  102. this->initialize_pointers();
  103. }
  104. //!Returns a const reference to the internal vector.
  105. //!Does not throw.
  106. const vector_type &vector() const
  107. {
  108. if (this->m_mode & std::ios_base::out){
  109. if (mp_high_water < base_t::pptr()){
  110. //Restore the vector's size if necessary
  111. mp_high_water = base_t::pptr();
  112. }
  113. //This shouldn't reallocate
  114. typedef typename vector_type::size_type size_type;
  115. char_type *old_ptr = base_t::pbase();
  116. size_type high_pos = size_type(mp_high_water-old_ptr);
  117. if(m_vect.size() > high_pos){
  118. m_vect.resize(high_pos);
  119. //But we must update end write pointer because vector size is now shorter
  120. int old_pos = base_t::pptr() - base_t::pbase();
  121. const_cast<basic_vectorbuf*>(this)->base_t::setp(old_ptr, old_ptr + high_pos);
  122. const_cast<basic_vectorbuf*>(this)->base_t::pbump(old_pos);
  123. }
  124. }
  125. return m_vect;
  126. }
  127. //!Preallocates memory from the internal vector.
  128. //!Resets the stream to the first position.
  129. //!Throws if the internals vector's memory allocation throws.
  130. void reserve(typename vector_type::size_type size)
  131. {
  132. if (this->m_mode & std::ios_base::out && size > m_vect.size()){
  133. typename vector_type::difference_type write_pos = base_t::pptr() - base_t::pbase();
  134. typename vector_type::difference_type read_pos = base_t::gptr() - base_t::eback();
  135. //Now update pointer data
  136. m_vect.reserve(size);
  137. this->initialize_pointers();
  138. base_t::pbump((int)write_pos);
  139. if(this->m_mode & std::ios_base::in){
  140. base_t::gbump((int)read_pos);
  141. }
  142. }
  143. }
  144. //!Calls clear() method of the internal vector.
  145. //!Resets the stream to the first position.
  146. void clear()
  147. { m_vect.clear(); this->initialize_pointers(); }
  148. /// @cond
  149. private:
  150. //Maximizes high watermark to the initial vector size,
  151. //initializes read and write iostream buffers to the capacity
  152. //and resets stream positions
  153. void initialize_pointers()
  154. {
  155. // The initial read position is the beginning of the vector.
  156. if(!(m_mode & std::ios_base::out)){
  157. if(m_vect.empty()){
  158. this->setg(0, 0, 0);
  159. }
  160. else{
  161. this->setg(&m_vect[0], &m_vect[0], &m_vect[0] + m_vect.size());
  162. }
  163. }
  164. // The initial write position is the beginning of the vector.
  165. if(m_mode & std::ios_base::out){
  166. //First get real size
  167. int real_size = (int)m_vect.size();
  168. //Then maximize size for high watermarking
  169. m_vect.resize(m_vect.capacity());
  170. BOOST_ASSERT(m_vect.size() == m_vect.capacity());
  171. //Set high watermarking with the expanded size
  172. mp_high_water = m_vect.size() ? (&m_vect[0] + real_size) : 0;
  173. //Now set formatting pointers
  174. if(m_vect.empty()){
  175. this->setp(0, 0);
  176. if(m_mode & std::ios_base::in)
  177. this->setg(0, 0, 0);
  178. }
  179. else{
  180. char_type *p = &m_vect[0];
  181. this->setp(p, p + m_vect.size());
  182. if(m_mode & std::ios_base::in)
  183. this->setg(p, p, p + real_size);
  184. }
  185. if (m_mode & (std::ios_base::app | std::ios_base::ate)){
  186. base_t::pbump((int)real_size);
  187. }
  188. }
  189. }
  190. protected:
  191. virtual int_type underflow()
  192. {
  193. if (base_t::gptr() == 0)
  194. return CharTraits::eof();
  195. if(m_mode & std::ios_base::out){
  196. if (mp_high_water < base_t::pptr())
  197. mp_high_water = base_t::pptr();
  198. if (base_t::egptr() < mp_high_water)
  199. base_t::setg(base_t::eback(), base_t::gptr(), mp_high_water);
  200. }
  201. if (base_t::gptr() < base_t::egptr())
  202. return CharTraits::to_int_type(*base_t::gptr());
  203. return CharTraits::eof();
  204. }
  205. virtual int_type pbackfail(int_type c = CharTraits::eof())
  206. {
  207. if(this->gptr() != this->eback()) {
  208. if(!CharTraits::eq_int_type(c, CharTraits::eof())) {
  209. if(CharTraits::eq(CharTraits::to_char_type(c), this->gptr()[-1])) {
  210. this->gbump(-1);
  211. return c;
  212. }
  213. else if(m_mode & std::ios_base::out) {
  214. this->gbump(-1);
  215. *this->gptr() = c;
  216. return c;
  217. }
  218. else
  219. return CharTraits::eof();
  220. }
  221. else {
  222. this->gbump(-1);
  223. return CharTraits::not_eof(c);
  224. }
  225. }
  226. else
  227. return CharTraits::eof();
  228. }
  229. virtual int_type overflow(int_type c = CharTraits::eof())
  230. {
  231. if(m_mode & std::ios_base::out) {
  232. if(!CharTraits::eq_int_type(c, CharTraits::eof())) {
  233. typedef typename vector_type::difference_type dif_t;
  234. //The new output position is the previous one plus one
  235. //because 'overflow' requires putting 'c' on the buffer
  236. dif_t new_outpos = base_t::pptr() - base_t::pbase() + 1;
  237. //Adjust high water if necessary
  238. dif_t hipos = mp_high_water - base_t::pbase();
  239. if (hipos < new_outpos)
  240. hipos = new_outpos;
  241. //Insert the new data
  242. m_vect.push_back(CharTraits::to_char_type(c));
  243. m_vect.resize(m_vect.capacity());
  244. BOOST_ASSERT(m_vect.size() == m_vect.capacity());
  245. char_type* p = const_cast<char_type*>(&m_vect[0]);
  246. //A reallocation might have happened, update pointers
  247. base_t::setp(p, p + (dif_t)m_vect.size());
  248. mp_high_water = p + hipos;
  249. if (m_mode & std::ios_base::in)
  250. base_t::setg(p, p + (base_t::gptr() - base_t::eback()), mp_high_water);
  251. //Update write position to the old position + 1
  252. base_t::pbump((int)new_outpos);
  253. return c;
  254. }
  255. else // c is EOF, so we don't have to do anything
  256. return CharTraits::not_eof(c);
  257. }
  258. else // Overflow always fails if it's read-only.
  259. return CharTraits::eof();
  260. }
  261. virtual pos_type seekoff(off_type off, std::ios_base::seekdir dir,
  262. std::ios_base::openmode mode
  263. = std::ios_base::in | std::ios_base::out)
  264. {
  265. //Get seek mode
  266. bool in(0 != (mode & std::ios_base::in)), out(0 != (mode & std::ios_base::out));
  267. //Test for logic errors
  268. if(!in & !out)
  269. return pos_type(off_type(-1));
  270. else if((in && out) && (dir == std::ios_base::cur))
  271. return pos_type(off_type(-1));
  272. else if((in && (!(m_mode & std::ios_base::in) || this->gptr() == 0)) ||
  273. (out && (!(m_mode & std::ios_base::out) || this->pptr() == 0)))
  274. return pos_type(off_type(-1));
  275. off_type newoff;
  276. //Just calculate the end of the stream. If the stream is read-only
  277. //the limit is the size of the vector. Otherwise, the high water mark
  278. //will mark the real size.
  279. off_type limit;
  280. if(m_mode & std::ios_base::out){
  281. //Update high water marking because pptr() is going to change and it might
  282. //have been updated since last overflow()
  283. if(mp_high_water < base_t::pptr())
  284. mp_high_water = base_t::pptr();
  285. //Update read limits in case high water mark was changed
  286. if(m_mode & std::ios_base::in){
  287. if (base_t::egptr() < mp_high_water)
  288. base_t::setg(base_t::eback(), base_t::gptr(), mp_high_water);
  289. }
  290. limit = static_cast<off_type>(mp_high_water - base_t::pbase());
  291. }
  292. else{
  293. limit = static_cast<off_type>(m_vect.size());
  294. }
  295. switch(dir) {
  296. case std::ios_base::beg:
  297. newoff = 0;
  298. break;
  299. case std::ios_base::end:
  300. newoff = limit;
  301. break;
  302. case std::ios_base::cur:
  303. newoff = in ? static_cast<std::streamoff>(this->gptr() - this->eback())
  304. : static_cast<std::streamoff>(this->pptr() - this->pbase());
  305. break;
  306. default:
  307. return pos_type(off_type(-1));
  308. }
  309. newoff += off;
  310. if (newoff < 0 || newoff > limit)
  311. return pos_type(-1);
  312. if (m_mode & std::ios_base::app && mode & std::ios_base::out && newoff != limit)
  313. return pos_type(-1);
  314. //This can reassign pointers
  315. //if(m_vect.size() != m_vect.capacity())
  316. //this->initialize_pointers();
  317. if (in)
  318. base_t::setg(base_t::eback(), base_t::eback() + newoff, base_t::egptr());
  319. if (out){
  320. base_t::setp(base_t::pbase(), base_t::epptr());
  321. base_t::pbump(newoff);
  322. }
  323. return pos_type(newoff);
  324. }
  325. virtual pos_type seekpos(pos_type pos, std::ios_base::openmode mode
  326. = std::ios_base::in | std::ios_base::out)
  327. { return seekoff(pos - pos_type(off_type(0)), std::ios_base::beg, mode); }
  328. private:
  329. std::ios_base::openmode m_mode;
  330. mutable vector_type m_vect;
  331. mutable char_type* mp_high_water;
  332. /// @endcond
  333. };
  334. //!A basic_istream class that holds a character vector specified by CharVector
  335. //!template parameter as its formatting buffer. The vector must have
  336. //!contiguous storage, like std::vector, boost::interprocess::vector or
  337. //!boost::interprocess::basic_string
  338. template <class CharVector, class CharTraits>
  339. class basic_ivectorstream
  340. : public std::basic_istream<typename CharVector::value_type, CharTraits>
  341. /// @cond
  342. , private basic_vectorbuf<CharVector, CharTraits>
  343. /// @endcond
  344. {
  345. public:
  346. typedef CharVector vector_type;
  347. typedef typename std::basic_ios
  348. <typename CharVector::value_type, CharTraits>::char_type char_type;
  349. typedef typename std::basic_ios<char_type, CharTraits>::int_type int_type;
  350. typedef typename std::basic_ios<char_type, CharTraits>::pos_type pos_type;
  351. typedef typename std::basic_ios<char_type, CharTraits>::off_type off_type;
  352. typedef typename std::basic_ios<char_type, CharTraits>::traits_type traits_type;
  353. /// @cond
  354. private:
  355. typedef basic_vectorbuf<CharVector, CharTraits> vectorbuf_t;
  356. typedef std::basic_ios<char_type, CharTraits> basic_ios_t;
  357. typedef std::basic_istream<char_type, CharTraits> base_t;
  358. vectorbuf_t & get_buf() { return *this; }
  359. const vectorbuf_t & get_buf() const{ return *this; }
  360. /// @endcond
  361. public:
  362. //!Constructor. Throws if vector_type default
  363. //!constructor throws.
  364. basic_ivectorstream(std::ios_base::openmode mode = std::ios_base::in)
  365. : base_t(0) //Initializes first the base class to safely init the virtual basic_ios base
  366. //(via basic_ios::init() call in base_t's constructor) without the risk of a
  367. //previous throwing vectorbuf constructor. Set the streambuf after risk has gone.
  368. , vectorbuf_t(mode | std::ios_base::in)
  369. { this->base_t::rdbuf(&get_buf()); }
  370. //!Constructor. Throws if vector_type(const VectorParameter &param)
  371. //!throws.
  372. template<class VectorParameter>
  373. basic_ivectorstream(const VectorParameter &param,
  374. std::ios_base::openmode mode = std::ios_base::in)
  375. : vectorbuf_t(param, mode | std::ios_base::in)
  376. //basic_ios_t() is constructed uninitialized as virtual base
  377. //and initialized inside base_t calling basic_ios::init()
  378. , base_t(&get_buf())
  379. {}
  380. public:
  381. //!Returns the address of the stored
  382. //!stream buffer.
  383. basic_vectorbuf<CharVector, CharTraits>* rdbuf() const
  384. { return const_cast<basic_vectorbuf<CharVector, CharTraits>*>(&get_buf()); }
  385. //!Swaps the underlying vector with the passed vector.
  386. //!This function resets the read position in the stream.
  387. //!Does not throw.
  388. void swap_vector(vector_type &vect)
  389. { get_buf().swap_vector(vect); }
  390. //!Returns a const reference to the internal vector.
  391. //!Does not throw.
  392. const vector_type &vector() const
  393. { return get_buf().vector(); }
  394. //!Calls reserve() method of the internal vector.
  395. //!Resets the stream to the first position.
  396. //!Throws if the internals vector's reserve throws.
  397. void reserve(typename vector_type::size_type size)
  398. { get_buf().reserve(size); }
  399. //!Calls clear() method of the internal vector.
  400. //!Resets the stream to the first position.
  401. void clear()
  402. { get_buf().clear(); }
  403. };
  404. //!A basic_ostream class that holds a character vector specified by CharVector
  405. //!template parameter as its formatting buffer. The vector must have
  406. //!contiguous storage, like std::vector, boost::interprocess::vector or
  407. //!boost::interprocess::basic_string
  408. template <class CharVector, class CharTraits>
  409. class basic_ovectorstream
  410. : public std::basic_ostream<typename CharVector::value_type, CharTraits>
  411. /// @cond
  412. , private basic_vectorbuf<CharVector, CharTraits>
  413. /// @endcond
  414. {
  415. public:
  416. typedef CharVector vector_type;
  417. typedef typename std::basic_ios
  418. <typename CharVector::value_type, CharTraits>::char_type char_type;
  419. typedef typename std::basic_ios<char_type, CharTraits>::int_type int_type;
  420. typedef typename std::basic_ios<char_type, CharTraits>::pos_type pos_type;
  421. typedef typename std::basic_ios<char_type, CharTraits>::off_type off_type;
  422. typedef typename std::basic_ios<char_type, CharTraits>::traits_type traits_type;
  423. /// @cond
  424. private:
  425. typedef basic_vectorbuf<CharVector, CharTraits> vectorbuf_t;
  426. typedef std::basic_ios<char_type, CharTraits> basic_ios_t;
  427. typedef std::basic_ostream<char_type, CharTraits> base_t;
  428. vectorbuf_t & get_buf() { return *this; }
  429. const vectorbuf_t & get_buf()const { return *this; }
  430. /// @endcond
  431. public:
  432. //!Constructor. Throws if vector_type default
  433. //!constructor throws.
  434. basic_ovectorstream(std::ios_base::openmode mode = std::ios_base::out)
  435. : base_t(0) //Initializes first the base class to safely init the virtual basic_ios base
  436. //(via basic_ios::init() call in base_t's constructor) without the risk of a
  437. //previous throwing vectorbuf constructor. Set the streambuf after risk has gone.
  438. , vectorbuf_t(mode | std::ios_base::out)
  439. { this->base_t::rdbuf(&get_buf()); }
  440. //!Constructor. Throws if vector_type(const VectorParameter &param)
  441. //!throws.
  442. template<class VectorParameter>
  443. basic_ovectorstream(const VectorParameter &param,
  444. std::ios_base::openmode mode = std::ios_base::out)
  445. : base_t(0) //Initializes first the base class to safely init the virtual basic_ios base
  446. //(via basic_ios::init() call in base_t's constructor) without the risk of a
  447. //previous throwing vectorbuf constructor. Set the streambuf after risk has gone.
  448. , vectorbuf_t(param, mode | std::ios_base::out)
  449. { this->base_t::rdbuf(&get_buf()); }
  450. public:
  451. //!Returns the address of the stored
  452. //!stream buffer.
  453. basic_vectorbuf<CharVector, CharTraits>* rdbuf() const
  454. { return const_cast<basic_vectorbuf<CharVector, CharTraits>*>(&get_buf()); }
  455. //!Swaps the underlying vector with the passed vector.
  456. //!This function resets the write position in the stream.
  457. //!Does not throw.
  458. void swap_vector(vector_type &vect)
  459. { get_buf().swap_vector(vect); }
  460. //!Returns a const reference to the internal vector.
  461. //!Does not throw.
  462. const vector_type &vector() const
  463. { return get_buf().vector(); }
  464. //!Calls reserve() method of the internal vector.
  465. //!Resets the stream to the first position.
  466. //!Throws if the internals vector's reserve throws.
  467. void reserve(typename vector_type::size_type size)
  468. { get_buf().reserve(size); }
  469. };
  470. //!A basic_iostream class that holds a character vector specified by CharVector
  471. //!template parameter as its formatting buffer. The vector must have
  472. //!contiguous storage, like std::vector, boost::interprocess::vector or
  473. //!boost::interprocess::basic_string
  474. template <class CharVector, class CharTraits>
  475. class basic_vectorstream
  476. : public std::basic_iostream<typename CharVector::value_type, CharTraits>
  477. /// @cond
  478. , private basic_vectorbuf<CharVector, CharTraits>
  479. /// @endcond
  480. {
  481. public:
  482. typedef CharVector vector_type;
  483. typedef typename std::basic_ios
  484. <typename CharVector::value_type, CharTraits>::char_type char_type;
  485. typedef typename std::basic_ios<char_type, CharTraits>::int_type int_type;
  486. typedef typename std::basic_ios<char_type, CharTraits>::pos_type pos_type;
  487. typedef typename std::basic_ios<char_type, CharTraits>::off_type off_type;
  488. typedef typename std::basic_ios<char_type, CharTraits>::traits_type traits_type;
  489. /// @cond
  490. private:
  491. typedef basic_vectorbuf<CharVector, CharTraits> vectorbuf_t;
  492. typedef std::basic_ios<char_type, CharTraits> basic_ios_t;
  493. typedef std::basic_iostream<char_type, CharTraits> base_t;
  494. vectorbuf_t & get_buf() { return *this; }
  495. const vectorbuf_t & get_buf() const{ return *this; }
  496. /// @endcond
  497. public:
  498. //!Constructor. Throws if vector_type default
  499. //!constructor throws.
  500. basic_vectorstream(std::ios_base::openmode mode
  501. = std::ios_base::in | std::ios_base::out)
  502. : base_t(0) //Initializes first the base class to safely init the virtual basic_ios base
  503. //(via basic_ios::init() call in base_t's constructor) without the risk of a
  504. //previous throwing vectorbuf constructor. Set the streambuf after risk has gone.
  505. , vectorbuf_t(mode)
  506. { this->base_t::rdbuf(&get_buf()); }
  507. //!Constructor. Throws if vector_type(const VectorParameter &param)
  508. //!throws.
  509. template<class VectorParameter>
  510. basic_vectorstream(const VectorParameter &param, std::ios_base::openmode mode
  511. = std::ios_base::in | std::ios_base::out)
  512. : base_t(0) //Initializes first the base class to safely init the virtual basic_ios base
  513. //(via basic_ios::init() call in base_t's constructor) without the risk of a
  514. //previous throwing vectorbuf constructor. Set the streambuf after risk has gone.
  515. , vectorbuf_t(param, mode)
  516. { this->base_t::rdbuf(&get_buf()); }
  517. public:
  518. //Returns the address of the stored stream buffer.
  519. basic_vectorbuf<CharVector, CharTraits>* rdbuf() const
  520. { return const_cast<basic_vectorbuf<CharVector, CharTraits>*>(&get_buf()); }
  521. //!Swaps the underlying vector with the passed vector.
  522. //!This function resets the read/write position in the stream.
  523. //!Does not throw.
  524. void swap_vector(vector_type &vect)
  525. { get_buf().swap_vector(vect); }
  526. //!Returns a const reference to the internal vector.
  527. //!Does not throw.
  528. const vector_type &vector() const
  529. { return get_buf().vector(); }
  530. //!Calls reserve() method of the internal vector.
  531. //!Resets the stream to the first position.
  532. //!Throws if the internals vector's reserve throws.
  533. void reserve(typename vector_type::size_type size)
  534. { get_buf().reserve(size); }
  535. //!Calls clear() method of the internal vector.
  536. //!Resets the stream to the first position.
  537. void clear()
  538. { get_buf().clear(); }
  539. };
  540. //Some typedefs to simplify usage
  541. //!
  542. //!typedef basic_vectorbuf<std::vector<char> > vectorbuf;
  543. //!typedef basic_vectorstream<std::vector<char> > vectorstream;
  544. //!typedef basic_ivectorstream<std::vector<char> > ivectorstream;
  545. //!typedef basic_ovectorstream<std::vector<char> > ovectorstream;
  546. //!
  547. //!typedef basic_vectorbuf<std::vector<wchar_t> > wvectorbuf;
  548. //!typedef basic_vectorstream<std::vector<wchar_t> > wvectorstream;
  549. //!typedef basic_ivectorstream<std::vector<wchar_t> > wivectorstream;
  550. //!typedef basic_ovectorstream<std::vector<wchar_t> > wovectorstream;
  551. }} //namespace boost { namespace interprocess {
  552. #include <boost/interprocess/detail/config_end.hpp>
  553. #endif /* BOOST_INTERPROCESS_VECTORSTREAM_HPP */