You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and dots ('.'), can be up to 35 characters long. Letters must be lowercase.
		
		
		
		
		
			
		
			
				
					
					
						
							601 lines
						
					
					
						
							22 KiB
						
					
					
				
			
		
		
	
	
							601 lines
						
					
					
						
							22 KiB
						
					
					
				////////////////////////////////////////////////////////////////////////////// | 
						|
// | 
						|
// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost | 
						|
// Software License, Version 1.0. (See accompanying file | 
						|
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | 
						|
// | 
						|
// See http://www.boost.org/libs/interprocess for documentation. | 
						|
// | 
						|
////////////////////////////////////////////////////////////////////////////// | 
						|
// | 
						|
// This file comes from SGI's sstream file. Modified by Ion Gaztanaga 2005. | 
						|
// Changed internal SGI string to a generic, templatized vector. Added efficient | 
						|
// internal buffer get/set/swap functions, so that we can obtain/establish the | 
						|
// internal buffer without any reallocation or copy. Kill those temporaries! | 
						|
/////////////////////////////////////////////////////////////////////////////// | 
						|
/* | 
						|
 * Copyright (c) 1998 | 
						|
 * Silicon Graphics Computer Systems, Inc. | 
						|
 * | 
						|
 * Permission to use, copy, modify, distribute and sell this software | 
						|
 * and its documentation for any purpose is hereby granted without fee, | 
						|
 * provided that the above copyright notice appear in all copies and | 
						|
 * that both that copyright notice and this permission notice appear | 
						|
 * in supporting documentation.  Silicon Graphics makes no | 
						|
 * representations about the suitability of this software for any | 
						|
 * purpose.  It is provided "as is" without express or implied warranty. | 
						|
 */ | 
						|
 | 
						|
//!\file | 
						|
//!This file defines basic_vectorbuf, basic_ivectorstream, | 
						|
//!basic_ovectorstream, and basic_vectorstreamclasses.  These classes | 
						|
//!represent streamsbufs and streams whose sources or destinations are | 
						|
//!STL-like vectors that can be swapped with external vectors to avoid  | 
						|
//!unnecessary allocations/copies. | 
						|
 | 
						|
#ifndef BOOST_INTERPROCESS_VECTORSTREAM_HPP | 
						|
#define BOOST_INTERPROCESS_VECTORSTREAM_HPP | 
						|
 | 
						|
#include <boost/interprocess/detail/config_begin.hpp> | 
						|
#include <boost/interprocess/detail/workaround.hpp> | 
						|
 | 
						|
#include <iosfwd> | 
						|
#include <ios> | 
						|
#include <istream> | 
						|
#include <ostream> | 
						|
#include <string>    // char traits             | 
						|
#include <cstddef>   // ptrdiff_t | 
						|
#include <boost/interprocess/interprocess_fwd.hpp> | 
						|
#include <boost/assert.hpp> | 
						|
 | 
						|
namespace boost {  namespace interprocess { | 
						|
 | 
						|
//!A streambuf class that controls the transmission of elements to and from | 
						|
//!a basic_ivectorstream, basic_ovectorstream or basic_vectorstream.  | 
						|
//!It holds a character vector specified by CharVector template parameter | 
						|
//!as its formatting buffer. The vector must have contiguous storage, like  | 
						|
//!std::vector, boost::interprocess::vector or boost::interprocess::basic_string | 
						|
template <class CharVector, class CharTraits> | 
						|
class basic_vectorbuf | 
						|
   : public std::basic_streambuf<typename CharVector::value_type, CharTraits> | 
						|
{ | 
						|
   public: | 
						|
   typedef CharVector                        vector_type; | 
						|
   typedef typename CharVector::value_type   char_type; | 
						|
   typedef typename CharTraits::int_type     int_type; | 
						|
   typedef typename CharTraits::pos_type     pos_type; | 
						|
   typedef typename CharTraits::off_type     off_type; | 
						|
   typedef CharTraits                        traits_type; | 
						|
 | 
						|
   /// @cond | 
						|
   private: | 
						|
   typedef std::basic_streambuf<char_type, traits_type> base_t; | 
						|
 | 
						|
   basic_vectorbuf(const basic_vectorbuf&); | 
						|
   basic_vectorbuf & operator =(const basic_vectorbuf&); | 
						|
   /// @endcond | 
						|
 | 
						|
   public: | 
						|
   //!Constructor. Throws if vector_type default | 
						|
   //!constructor throws. | 
						|
   explicit basic_vectorbuf(std::ios_base::openmode mode | 
						|
                              = std::ios_base::in | std::ios_base::out) | 
						|
      :  base_t(), m_mode(mode) | 
						|
   {  this->initialize_pointers();   } | 
						|
 | 
						|
   //!Constructor. Throws if | 
						|
   //!vector_type(const VectorParameter ¶m) throws. | 
						|
   template<class VectorParameter> | 
						|
   explicit basic_vectorbuf(const VectorParameter ¶m, | 
						|
                            std::ios_base::openmode mode | 
						|
                                 = std::ios_base::in | std::ios_base::out) | 
						|
      :  base_t(), m_mode(mode), m_vect(param) | 
						|
   {  this->initialize_pointers();   } | 
						|
 | 
						|
   virtual ~basic_vectorbuf(){} | 
						|
 | 
						|
   public: | 
						|
 | 
						|
   //!Swaps the underlying vector with the passed vector.  | 
						|
   //!This function resets the read/write position in the stream. | 
						|
   //!Does not throw. | 
						|
   void swap_vector(vector_type &vect) | 
						|
   {   | 
						|
      if (this->m_mode & std::ios_base::out){ | 
						|
         //Update high water if necessary | 
						|
         //And resize vector to remove extra size | 
						|
         if (mp_high_water < base_t::pptr()){ | 
						|
            //Restore the vector's size if necessary | 
						|
            mp_high_water = base_t::pptr(); | 
						|
         } | 
						|
         //This does not reallocate | 
						|
         m_vect.resize(mp_high_water - (m_vect.size() ? &m_vect[0] : 0)); | 
						|
      } | 
						|
      //Now swap vector | 
						|
      m_vect.swap(vect); | 
						|
      this->initialize_pointers(); | 
						|
   } | 
						|
 | 
						|
   //!Returns a const reference to the internal vector. | 
						|
   //!Does not throw. | 
						|
   const vector_type &vector() const  | 
						|
   {   | 
						|
      if (this->m_mode & std::ios_base::out){ | 
						|
         if (mp_high_water < base_t::pptr()){ | 
						|
            //Restore the vector's size if necessary | 
						|
            mp_high_water = base_t::pptr(); | 
						|
         } | 
						|
         //This shouldn't reallocate | 
						|
         typedef typename vector_type::size_type size_type; | 
						|
         char_type *old_ptr = base_t::pbase(); | 
						|
         size_type high_pos = size_type(mp_high_water-old_ptr); | 
						|
         if(m_vect.size() > high_pos){ | 
						|
            m_vect.resize(high_pos); | 
						|
            //But we must update end write pointer because vector size is now shorter | 
						|
            int old_pos = base_t::pptr() - base_t::pbase(); | 
						|
            const_cast<basic_vectorbuf*>(this)->base_t::setp(old_ptr, old_ptr + high_pos); | 
						|
            const_cast<basic_vectorbuf*>(this)->base_t::pbump(old_pos); | 
						|
         } | 
						|
      } | 
						|
      return m_vect;  | 
						|
   } | 
						|
 | 
						|
   //!Preallocates memory from the internal vector. | 
						|
   //!Resets the stream to the first position. | 
						|
   //!Throws if the internals vector's memory allocation throws. | 
						|
   void reserve(typename vector_type::size_type size)  | 
						|
   { | 
						|
      if (this->m_mode & std::ios_base::out && size > m_vect.size()){ | 
						|
         typename vector_type::difference_type write_pos = base_t::pptr() - base_t::pbase(); | 
						|
         typename vector_type::difference_type read_pos  = base_t::gptr() - base_t::eback(); | 
						|
         //Now update pointer data | 
						|
         m_vect.reserve(size); | 
						|
         this->initialize_pointers(); | 
						|
         base_t::pbump((int)write_pos); | 
						|
         if(this->m_mode & std::ios_base::in){ | 
						|
            base_t::gbump((int)read_pos); | 
						|
         } | 
						|
      } | 
						|
   } | 
						|
 | 
						|
   //!Calls clear() method of the internal vector. | 
						|
   //!Resets the stream to the first position. | 
						|
   void clear() | 
						|
   {  m_vect.clear();   this->initialize_pointers();   } | 
						|
 | 
						|
   /// @cond | 
						|
   private: | 
						|
   //Maximizes high watermark to the initial vector size, | 
						|
   //initializes read and write iostream buffers to the capacity | 
						|
   //and resets stream positions | 
						|
   void initialize_pointers() | 
						|
   { | 
						|
      // The initial read position is the beginning of the vector. | 
						|
      if(!(m_mode & std::ios_base::out)){ | 
						|
         if(m_vect.empty()){ | 
						|
            this->setg(0, 0, 0); | 
						|
         } | 
						|
         else{ | 
						|
            this->setg(&m_vect[0], &m_vect[0], &m_vect[0] + m_vect.size()); | 
						|
         } | 
						|
      } | 
						|
 | 
						|
      // The initial write position is the beginning of the vector. | 
						|
      if(m_mode & std::ios_base::out){ | 
						|
         //First get real size | 
						|
         int real_size = (int)m_vect.size(); | 
						|
         //Then maximize size for high watermarking | 
						|
         m_vect.resize(m_vect.capacity()); | 
						|
         BOOST_ASSERT(m_vect.size() == m_vect.capacity()); | 
						|
         //Set high watermarking with the expanded size | 
						|
         mp_high_water = m_vect.size() ? (&m_vect[0] + real_size) : 0; | 
						|
         //Now set formatting pointers | 
						|
         if(m_vect.empty()){ | 
						|
            this->setp(0, 0); | 
						|
            if(m_mode & std::ios_base::in) | 
						|
               this->setg(0, 0, 0); | 
						|
         } | 
						|
         else{ | 
						|
            char_type *p = &m_vect[0]; | 
						|
            this->setp(p, p + m_vect.size()); | 
						|
            if(m_mode & std::ios_base::in) | 
						|
               this->setg(p, p, p + real_size); | 
						|
         } | 
						|
         if (m_mode & (std::ios_base::app | std::ios_base::ate)){ | 
						|
            base_t::pbump((int)real_size); | 
						|
         } | 
						|
      } | 
						|
   } | 
						|
 | 
						|
   protected: | 
						|
   virtual int_type underflow() | 
						|
   { | 
						|
      if (base_t::gptr() == 0) | 
						|
         return CharTraits::eof(); | 
						|
      if(m_mode & std::ios_base::out){ | 
						|
         if (mp_high_water < base_t::pptr()) | 
						|
            mp_high_water = base_t::pptr(); | 
						|
         if (base_t::egptr() < mp_high_water) | 
						|
            base_t::setg(base_t::eback(), base_t::gptr(), mp_high_water); | 
						|
      } | 
						|
      if (base_t::gptr() < base_t::egptr()) | 
						|
         return CharTraits::to_int_type(*base_t::gptr()); | 
						|
      return CharTraits::eof(); | 
						|
   } | 
						|
 | 
						|
   virtual int_type pbackfail(int_type c = CharTraits::eof()) | 
						|
   { | 
						|
      if(this->gptr() != this->eback()) { | 
						|
         if(!CharTraits::eq_int_type(c, CharTraits::eof())) { | 
						|
            if(CharTraits::eq(CharTraits::to_char_type(c), this->gptr()[-1])) { | 
						|
               this->gbump(-1); | 
						|
               return c; | 
						|
            } | 
						|
            else if(m_mode & std::ios_base::out) { | 
						|
               this->gbump(-1); | 
						|
               *this->gptr() = c; | 
						|
               return c; | 
						|
            } | 
						|
            else | 
						|
               return CharTraits::eof(); | 
						|
         } | 
						|
         else { | 
						|
            this->gbump(-1); | 
						|
            return CharTraits::not_eof(c); | 
						|
         } | 
						|
      } | 
						|
      else | 
						|
         return CharTraits::eof(); | 
						|
   } | 
						|
 | 
						|
   virtual int_type overflow(int_type c = CharTraits::eof()) | 
						|
   { | 
						|
      if(m_mode & std::ios_base::out) { | 
						|
         if(!CharTraits::eq_int_type(c, CharTraits::eof())) { | 
						|
               typedef typename vector_type::difference_type dif_t; | 
						|
               //The new output position is the previous one plus one | 
						|
               //because 'overflow' requires putting 'c' on the buffer | 
						|
               dif_t new_outpos = base_t::pptr() - base_t::pbase() + 1; | 
						|
               //Adjust high water if necessary | 
						|
               dif_t hipos = mp_high_water - base_t::pbase(); | 
						|
               if (hipos < new_outpos) | 
						|
                  hipos = new_outpos; | 
						|
               //Insert the new data | 
						|
               m_vect.push_back(CharTraits::to_char_type(c)); | 
						|
               m_vect.resize(m_vect.capacity()); | 
						|
               BOOST_ASSERT(m_vect.size() == m_vect.capacity()); | 
						|
               char_type* p = const_cast<char_type*>(&m_vect[0]); | 
						|
               //A reallocation might have happened, update pointers | 
						|
               base_t::setp(p, p + (dif_t)m_vect.size()); | 
						|
               mp_high_water = p + hipos; | 
						|
               if (m_mode & std::ios_base::in) | 
						|
                  base_t::setg(p, p + (base_t::gptr() - base_t::eback()), mp_high_water); | 
						|
               //Update write position to the old position + 1 | 
						|
               base_t::pbump((int)new_outpos); | 
						|
               return c; | 
						|
         } | 
						|
         else  // c is EOF, so we don't have to do anything | 
						|
            return CharTraits::not_eof(c); | 
						|
      } | 
						|
      else     // Overflow always fails if it's read-only. | 
						|
         return CharTraits::eof(); | 
						|
   } | 
						|
 | 
						|
   virtual pos_type seekoff(off_type off, std::ios_base::seekdir dir, | 
						|
                              std::ios_base::openmode mode  | 
						|
                                 = std::ios_base::in | std::ios_base::out) | 
						|
   { | 
						|
      //Get seek mode | 
						|
      bool in(0 != (mode & std::ios_base::in)), out(0 != (mode & std::ios_base::out)); | 
						|
      //Test for logic errors | 
						|
      if(!in & !out) | 
						|
         return pos_type(off_type(-1)); | 
						|
      else if((in && out) && (dir == std::ios_base::cur)) | 
						|
         return pos_type(off_type(-1)); | 
						|
      else if((in  && (!(m_mode & std::ios_base::in) || this->gptr() == 0)) || | 
						|
               (out && (!(m_mode & std::ios_base::out) || this->pptr() == 0))) | 
						|
         return pos_type(off_type(-1)); | 
						|
 | 
						|
      off_type newoff; | 
						|
      //Just calculate the end of the stream. If the stream is read-only | 
						|
      //the limit is the size of the vector. Otherwise, the high water mark | 
						|
      //will mark the real size. | 
						|
      off_type limit; | 
						|
      if(m_mode & std::ios_base::out){ | 
						|
         //Update high water marking because pptr() is going to change and it might | 
						|
         //have been updated since last overflow() | 
						|
         if(mp_high_water < base_t::pptr()) | 
						|
            mp_high_water = base_t::pptr(); | 
						|
         //Update read limits in case high water mark was changed | 
						|
         if(m_mode & std::ios_base::in){ | 
						|
            if (base_t::egptr() < mp_high_water) | 
						|
               base_t::setg(base_t::eback(), base_t::gptr(), mp_high_water); | 
						|
         } | 
						|
         limit = static_cast<off_type>(mp_high_water - base_t::pbase()); | 
						|
      } | 
						|
      else{ | 
						|
         limit = static_cast<off_type>(m_vect.size()); | 
						|
      } | 
						|
 | 
						|
      switch(dir) { | 
						|
         case std::ios_base::beg: | 
						|
            newoff = 0; | 
						|
         break; | 
						|
         case std::ios_base::end: | 
						|
            newoff = limit; | 
						|
         break; | 
						|
         case std::ios_base::cur: | 
						|
            newoff = in ? static_cast<std::streamoff>(this->gptr() - this->eback())  | 
						|
                        : static_cast<std::streamoff>(this->pptr() - this->pbase()); | 
						|
         break; | 
						|
         default: | 
						|
            return pos_type(off_type(-1)); | 
						|
      } | 
						|
 | 
						|
      newoff += off; | 
						|
 | 
						|
      if (newoff < 0 || newoff > limit) | 
						|
         return pos_type(-1); | 
						|
      if (m_mode & std::ios_base::app && mode & std::ios_base::out && newoff != limit) | 
						|
         return pos_type(-1); | 
						|
      //This can reassign pointers | 
						|
      //if(m_vect.size() != m_vect.capacity()) | 
						|
         //this->initialize_pointers(); | 
						|
      if (in) | 
						|
         base_t::setg(base_t::eback(), base_t::eback() + newoff, base_t::egptr()); | 
						|
      if (out){ | 
						|
         base_t::setp(base_t::pbase(), base_t::epptr()); | 
						|
         base_t::pbump(newoff); | 
						|
      } | 
						|
      return pos_type(newoff); | 
						|
   } | 
						|
 | 
						|
   virtual pos_type seekpos(pos_type pos, std::ios_base::openmode mode  | 
						|
                                 = std::ios_base::in | std::ios_base::out) | 
						|
   {  return seekoff(pos - pos_type(off_type(0)), std::ios_base::beg, mode);  } | 
						|
 | 
						|
   private: | 
						|
   std::ios_base::openmode m_mode; | 
						|
   mutable vector_type     m_vect; | 
						|
   mutable char_type*      mp_high_water; | 
						|
   /// @endcond | 
						|
}; | 
						|
 | 
						|
//!A basic_istream class that holds a character vector specified by CharVector | 
						|
//!template parameter as its formatting buffer. The vector must have | 
						|
//!contiguous storage, like std::vector, boost::interprocess::vector or | 
						|
//!boost::interprocess::basic_string | 
						|
template <class CharVector, class CharTraits> | 
						|
class basic_ivectorstream | 
						|
   /// @cond | 
						|
   : private basic_vectorbuf<CharVector, CharTraits> | 
						|
   /// @endcond | 
						|
   , public std::basic_istream<typename CharVector::value_type, CharTraits> | 
						|
{ | 
						|
   public: | 
						|
   typedef CharVector                                                   vector_type; | 
						|
   typedef typename std::basic_ios | 
						|
      <typename CharVector::value_type, CharTraits>::char_type          char_type; | 
						|
   typedef typename std::basic_ios<char_type, CharTraits>::int_type     int_type; | 
						|
   typedef typename std::basic_ios<char_type, CharTraits>::pos_type     pos_type; | 
						|
   typedef typename std::basic_ios<char_type, CharTraits>::off_type     off_type; | 
						|
   typedef typename std::basic_ios<char_type, CharTraits>::traits_type  traits_type; | 
						|
 | 
						|
   /// @cond | 
						|
   private: | 
						|
   typedef basic_vectorbuf<CharVector, CharTraits>    vectorbuf_t; | 
						|
   typedef std::basic_istream<char_type, CharTraits>  base_t; | 
						|
 | 
						|
   vectorbuf_t &       m_buf()      {  return *this;  } | 
						|
   const vectorbuf_t & m_buf() const{  return *this;  } | 
						|
   /// @endcond | 
						|
 | 
						|
   public: | 
						|
   //!Constructor. Throws if vector_type default | 
						|
   //!constructor throws. | 
						|
   basic_ivectorstream(std::ios_base::openmode mode = std::ios_base::in) | 
						|
      :  vectorbuf_t(mode | std::ios_base::in), base_t(&m_buf()) | 
						|
   {} | 
						|
 | 
						|
   //!Constructor. Throws if vector_type(const VectorParameter ¶m) | 
						|
   //!throws. | 
						|
   template<class VectorParameter> | 
						|
   basic_ivectorstream(const VectorParameter ¶m, | 
						|
                       std::ios_base::openmode mode = std::ios_base::in) | 
						|
      :  vectorbuf_t(param, mode | std::ios_base::in), base_t(&m_buf()) | 
						|
   {} | 
						|
 | 
						|
   ~basic_ivectorstream(){}; | 
						|
 | 
						|
   public: | 
						|
   //!Returns the address of the stored | 
						|
   //!stream buffer. | 
						|
   basic_vectorbuf<CharVector, CharTraits>* rdbuf() const | 
						|
   { return const_cast<basic_vectorbuf<CharVector, CharTraits>*>(&m_buf()); } | 
						|
 | 
						|
   //!Swaps the underlying vector with the passed vector.  | 
						|
   //!This function resets the read position in the stream. | 
						|
   //!Does not throw. | 
						|
   void swap_vector(vector_type &vect) | 
						|
   {  m_buf().swap_vector(vect);   } | 
						|
 | 
						|
   //!Returns a const reference to the internal vector. | 
						|
   //!Does not throw. | 
						|
   const vector_type &vector() const  | 
						|
   {  return m_buf().vector();   } | 
						|
 | 
						|
   //!Calls reserve() method of the internal vector. | 
						|
   //!Resets the stream to the first position. | 
						|
   //!Throws if the internals vector's reserve throws. | 
						|
   void reserve(typename vector_type::size_type size)  | 
						|
   {  m_buf().reserve(size);   } | 
						|
 | 
						|
   //!Calls clear() method of the internal vector. | 
						|
   //!Resets the stream to the first position. | 
						|
   void clear()  | 
						|
   {  m_buf().clear();   } | 
						|
}; | 
						|
 | 
						|
//!A basic_ostream class that holds a character vector specified by CharVector | 
						|
//!template parameter as its formatting buffer. The vector must have | 
						|
//!contiguous storage, like std::vector, boost::interprocess::vector or | 
						|
//!boost::interprocess::basic_string | 
						|
template <class CharVector, class CharTraits> | 
						|
class basic_ovectorstream | 
						|
   /// @cond | 
						|
   : private basic_vectorbuf<CharVector, CharTraits> | 
						|
   /// @endcond | 
						|
   , public std::basic_ostream<typename CharVector::value_type, CharTraits> | 
						|
{ | 
						|
   public: | 
						|
   typedef CharVector                                                   vector_type; | 
						|
   typedef typename std::basic_ios | 
						|
      <typename CharVector::value_type, CharTraits>::char_type          char_type; | 
						|
   typedef typename std::basic_ios<char_type, CharTraits>::int_type     int_type; | 
						|
   typedef typename std::basic_ios<char_type, CharTraits>::pos_type     pos_type; | 
						|
   typedef typename std::basic_ios<char_type, CharTraits>::off_type     off_type; | 
						|
   typedef typename std::basic_ios<char_type, CharTraits>::traits_type  traits_type; | 
						|
 | 
						|
   /// @cond | 
						|
   private: | 
						|
   typedef basic_vectorbuf<CharVector, CharTraits>    vectorbuf_t; | 
						|
   typedef std::basic_ostream<char_type, CharTraits>  base_t; | 
						|
 | 
						|
   vectorbuf_t &       m_buf()      {  return *this;  } | 
						|
   const vectorbuf_t & m_buf()const {  return *this;  } | 
						|
   /// @endcond | 
						|
 | 
						|
   public: | 
						|
   //!Constructor. Throws if vector_type default | 
						|
   //!constructor throws. | 
						|
   basic_ovectorstream(std::ios_base::openmode mode = std::ios_base::out) | 
						|
      :  vectorbuf_t(mode | std::ios_base::out), base_t(&m_buf()) | 
						|
   {} | 
						|
 | 
						|
   //!Constructor. Throws if vector_type(const VectorParameter ¶m) | 
						|
   //!throws. | 
						|
   template<class VectorParameter> | 
						|
   basic_ovectorstream(const VectorParameter ¶m, | 
						|
                        std::ios_base::openmode mode = std::ios_base::out) | 
						|
      :  vectorbuf_t(param, mode | std::ios_base::out), base_t(&m_buf()) | 
						|
   {} | 
						|
 | 
						|
   ~basic_ovectorstream(){} | 
						|
 | 
						|
   public: | 
						|
   //!Returns the address of the stored | 
						|
   //!stream buffer. | 
						|
   basic_vectorbuf<CharVector, CharTraits>* rdbuf() const | 
						|
   { return const_cast<basic_vectorbuf<CharVector, CharTraits>*>(&m_buf()); } | 
						|
 | 
						|
   //!Swaps the underlying vector with the passed vector.  | 
						|
   //!This function resets the write position in the stream. | 
						|
   //!Does not throw. | 
						|
   void swap_vector(vector_type &vect) | 
						|
   {  m_buf().swap_vector(vect);   } | 
						|
 | 
						|
   //!Returns a const reference to the internal vector. | 
						|
   //!Does not throw. | 
						|
   const vector_type &vector() const  | 
						|
   {  return m_buf().vector();   } | 
						|
 | 
						|
   //!Calls reserve() method of the internal vector. | 
						|
   //!Resets the stream to the first position. | 
						|
   //!Throws if the internals vector's reserve throws. | 
						|
   void reserve(typename vector_type::size_type size)  | 
						|
   {  m_buf().reserve(size);   } | 
						|
}; | 
						|
 | 
						|
 | 
						|
//!A basic_iostream class that holds a character vector specified by CharVector | 
						|
//!template parameter as its formatting buffer. The vector must have | 
						|
//!contiguous storage, like std::vector, boost::interprocess::vector or | 
						|
//!boost::interprocess::basic_string | 
						|
template <class CharVector, class CharTraits> | 
						|
class basic_vectorstream | 
						|
   : public std::basic_iostream<typename CharVector::value_type, CharTraits> | 
						|
 | 
						|
{ | 
						|
   public: | 
						|
   typedef CharVector                                                   vector_type; | 
						|
   typedef typename std::basic_ios | 
						|
      <typename CharVector::value_type, CharTraits>::char_type          char_type; | 
						|
   typedef typename std::basic_ios<char_type, CharTraits>::int_type     int_type; | 
						|
   typedef typename std::basic_ios<char_type, CharTraits>::pos_type     pos_type; | 
						|
   typedef typename std::basic_ios<char_type, CharTraits>::off_type     off_type; | 
						|
   typedef typename std::basic_ios<char_type, CharTraits>::traits_type  traits_type; | 
						|
 | 
						|
   /// @cond | 
						|
   private: | 
						|
   typedef std::basic_ios<char_type, CharTraits>                 basic_ios_t; | 
						|
   typedef std::basic_iostream<char_type, CharTraits>            base_t; | 
						|
   /// @endcond | 
						|
 | 
						|
   public: | 
						|
   //!Constructor. Throws if vector_type default | 
						|
   //!constructor throws. | 
						|
   basic_vectorstream(std::ios_base::openmode mode  | 
						|
                      = std::ios_base::in | std::ios_base::out) | 
						|
      :  basic_ios_t(), base_t(0), m_buf(mode) | 
						|
   {  basic_ios_t::init(&m_buf); } | 
						|
 | 
						|
   //!Constructor. Throws if vector_type(const VectorParameter ¶m) | 
						|
   //!throws. | 
						|
   template<class VectorParameter> | 
						|
   basic_vectorstream(const VectorParameter ¶m, std::ios_base::openmode mode | 
						|
                      = std::ios_base::in | std::ios_base::out) | 
						|
      :  basic_ios_t(), base_t(0), m_buf(param, mode) | 
						|
   {  basic_ios_t::init(&m_buf); } | 
						|
 | 
						|
   ~basic_vectorstream(){} | 
						|
 | 
						|
   public: | 
						|
   //Returns the address of the stored stream buffer. | 
						|
   basic_vectorbuf<CharVector, CharTraits>* rdbuf() const | 
						|
   { return const_cast<basic_vectorbuf<CharVector, CharTraits>*>(&m_buf); } | 
						|
 | 
						|
   //!Swaps the underlying vector with the passed vector.  | 
						|
   //!This function resets the read/write position in the stream. | 
						|
   //!Does not throw. | 
						|
   void swap_vector(vector_type &vect) | 
						|
   {  m_buf.swap_vector(vect);   } | 
						|
 | 
						|
   //!Returns a const reference to the internal vector. | 
						|
   //!Does not throw. | 
						|
   const vector_type &vector() const  | 
						|
   {  return m_buf.vector();   } | 
						|
 | 
						|
   //!Calls reserve() method of the internal vector. | 
						|
   //!Resets the stream to the first position. | 
						|
   //!Throws if the internals vector's reserve throws. | 
						|
   void reserve(typename vector_type::size_type size)  | 
						|
   {  m_buf.reserve(size);   } | 
						|
 | 
						|
   //!Calls clear() method of the internal vector. | 
						|
   //!Resets the stream to the first position. | 
						|
   void clear()  | 
						|
   {  m_buf.clear();   } | 
						|
 | 
						|
   /// @cond | 
						|
   private: | 
						|
   basic_vectorbuf<CharVector, CharTraits> m_buf; | 
						|
   /// @endcond | 
						|
}; | 
						|
 | 
						|
//Some typedefs to simplify usage | 
						|
//! | 
						|
//!typedef basic_vectorbuf<std::vector<char> >        vectorbuf; | 
						|
//!typedef basic_vectorstream<std::vector<char> >     vectorstream; | 
						|
//!typedef basic_ivectorstream<std::vector<char> >    ivectorstream; | 
						|
//!typedef basic_ovectorstream<std::vector<char> >    ovectorstream; | 
						|
//! | 
						|
//!typedef basic_vectorbuf<std::vector<wchar_t> >     wvectorbuf; | 
						|
//!typedef basic_vectorstream<std::vector<wchar_t> >  wvectorstream; | 
						|
//!typedef basic_ivectorstream<std::vector<wchar_t> > wivectorstream; | 
						|
//!typedef basic_ovectorstream<std::vector<wchar_t> > wovectorstream; | 
						|
 | 
						|
}} //namespace boost {  namespace interprocess { | 
						|
 | 
						|
#include <boost/interprocess/detail/config_end.hpp> | 
						|
 | 
						|
#endif /* BOOST_INTERPROCESS_VECTORSTREAM_HPP */
 | 
						|
 |