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