diff options
Diffstat (limited to 'Build/source/texk/dvisvgm/dvisvgm-src/libs/boost/boost-vectorstream.hpp')
-rw-r--r-- | Build/source/texk/dvisvgm/dvisvgm-src/libs/boost/boost-vectorstream.hpp | 607 |
1 files changed, 607 insertions, 0 deletions
diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/libs/boost/boost-vectorstream.hpp b/Build/source/texk/dvisvgm/dvisvgm-src/libs/boost/boost-vectorstream.hpp new file mode 100644 index 00000000000..91aa2f864d1 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-src/libs/boost/boost-vectorstream.hpp @@ -0,0 +1,607 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2012. 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-2012. +// 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 <iosfwd> +#include <ios> +#include <istream> +#include <ostream> +#include <string> // char traits +#include <cstddef> // ptrdiff_t + +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; + + #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) + private: + typedef std::basic_streambuf<char_type, traits_type> base_t; + + basic_vectorbuf(const basic_vectorbuf&); + basic_vectorbuf & operator =(const basic_vectorbuf&); + #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED + + 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(); } + + 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(std::size_t(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 = (int)(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(); } + + #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) + 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() BOOST_OVERRIDE + { + 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()) BOOST_OVERRIDE + { + 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() = CharTraits::to_char_type(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()) BOOST_OVERRIDE + { + 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) BOOST_OVERRIDE + { + //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) || (off != 0 && this->gptr() == 0) )) || + (out && (!(m_mode & std::ios_base::out) || (off != 0 && 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(static_cast<int>(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) BOOST_OVERRIDE + { 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; + #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED +}; + +//!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 + : public std::basic_istream<typename CharVector::value_type, CharTraits> + #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) + , private basic_vectorbuf<CharVector, CharTraits> + #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED +{ + 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; + + #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) + private: + typedef basic_vectorbuf<CharVector, CharTraits> vectorbuf_t; + typedef std::basic_ios<char_type, CharTraits> basic_ios_t; + typedef std::basic_istream<char_type, CharTraits> base_t; + + vectorbuf_t & get_buf() { return *this; } + const vectorbuf_t & get_buf() const{ return *this; } + #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED + + public: + + //!Constructor. Throws if vector_type default + //!constructor throws. + basic_ivectorstream(std::ios_base::openmode mode = std::ios_base::in) + : base_t(0) //Initializes first the base class to safely init the virtual basic_ios base + //(via basic_ios::init() call in base_t's constructor) without the risk of a + //previous throwing vectorbuf constructor. Set the streambuf after risk has gone. + , vectorbuf_t(mode | std::ios_base::in) + { this->base_t::rdbuf(&get_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) + //basic_ios_t() is constructed uninitialized as virtual base + //and initialized inside base_t calling basic_ios::init() + , base_t(&get_buf()) + {} + + public: + //!Returns the address of the stored + //!stream buffer. + basic_vectorbuf<CharVector, CharTraits>* rdbuf() const + { return const_cast<basic_vectorbuf<CharVector, CharTraits>*>(&get_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) + { get_buf().swap_vector(vect); } + + //!Returns a const reference to the internal vector. + //!Does not throw. + const vector_type &vector() const + { return get_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) + { get_buf().reserve(size); } + + //!Calls clear() method of the internal vector. + //!Resets the stream to the first position. + void clear() + { get_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 + : public std::basic_ostream<typename CharVector::value_type, CharTraits> + #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) + , private basic_vectorbuf<CharVector, CharTraits> + #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED +{ + 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; + + #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) + private: + typedef basic_vectorbuf<CharVector, CharTraits> vectorbuf_t; + typedef std::basic_ios<char_type, CharTraits> basic_ios_t; + typedef std::basic_ostream<char_type, CharTraits> base_t; + + vectorbuf_t & get_buf() { return *this; } + const vectorbuf_t & get_buf()const { return *this; } + #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED + + public: + //!Constructor. Throws if vector_type default + //!constructor throws. + basic_ovectorstream(std::ios_base::openmode mode = std::ios_base::out) + : base_t(0) //Initializes first the base class to safely init the virtual basic_ios base + //(via basic_ios::init() call in base_t's constructor) without the risk of a + //previous throwing vectorbuf constructor. Set the streambuf after risk has gone. + , vectorbuf_t(mode | std::ios_base::out) + { this->base_t::rdbuf(&get_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) + : base_t(0) //Initializes first the base class to safely init the virtual basic_ios base + //(via basic_ios::init() call in base_t's constructor) without the risk of a + //previous throwing vectorbuf constructor. Set the streambuf after risk has gone. + , vectorbuf_t(param, mode | std::ios_base::out) + { this->base_t::rdbuf(&get_buf()); } + + public: + //!Returns the address of the stored + //!stream buffer. + basic_vectorbuf<CharVector, CharTraits>* rdbuf() const + { return const_cast<basic_vectorbuf<CharVector, CharTraits>*>(&get_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) + { get_buf().swap_vector(vect); } + + //!Returns a const reference to the internal vector. + //!Does not throw. + const vector_type &vector() const + { return get_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) + { get_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> + #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) + , private basic_vectorbuf<CharVector, CharTraits> + #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED +{ + 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; + + #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) + private: + typedef basic_vectorbuf<CharVector, CharTraits> vectorbuf_t; + typedef std::basic_ios<char_type, CharTraits> basic_ios_t; + typedef std::basic_iostream<char_type, CharTraits> base_t; + + vectorbuf_t & get_buf() { return *this; } + const vectorbuf_t & get_buf() const{ return *this; } + #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED + + public: + //!Constructor. Throws if vector_type default + //!constructor throws. + basic_vectorstream(std::ios_base::openmode mode + = std::ios_base::in | std::ios_base::out) + : base_t(0) //Initializes first the base class to safely init the virtual basic_ios base + //(via basic_ios::init() call in base_t's constructor) without the risk of a + //previous throwing vectorbuf constructor. Set the streambuf after risk has gone. + , vectorbuf_t(mode) + { this->base_t::rdbuf(&get_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) + : base_t(0) //Initializes first the base class to safely init the virtual basic_ios base + //(via basic_ios::init() call in base_t's constructor) without the risk of a + //previous throwing vectorbuf constructor. Set the streambuf after risk has gone. + , vectorbuf_t(param, mode) + { this->base_t::rdbuf(&get_buf()); } + + public: + //Returns the address of the stored stream buffer. + basic_vectorbuf<CharVector, CharTraits>* rdbuf() const + { return const_cast<basic_vectorbuf<CharVector, CharTraits>*>(&get_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) + { get_buf().swap_vector(vect); } + + //!Returns a const reference to the internal vector. + //!Does not throw. + const vector_type &vector() const + { return get_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) + { get_buf().reserve(size); } + + //!Calls clear() method of the internal vector. + //!Resets the stream to the first position. + void clear() + { get_buf().clear(); } +}; + +//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 { + +#endif /* BOOST_INTERPROCESS_VECTORSTREAM_HPP */ |