| // ---------------------------------------------------------------------------- |
| // alt_sstream.hpp : alternative stringstream |
| // ---------------------------------------------------------------------------- |
| |
| // Copyright Samuel Krempp 2003. Use, modification, and distribution are |
| // subject to 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/format for library home page |
| |
| // ---------------------------------------------------------------------------- |
| |
| |
| |
| #ifndef BOOST_SK_ALT_SSTREAM_HPP |
| #define BOOST_SK_ALT_SSTREAM_HPP |
| |
| #include <string> |
| #include <boost/format/detail/compat_workarounds.hpp> |
| #include <boost/utility/base_from_member.hpp> |
| #include <boost/shared_ptr.hpp> |
| #include <boost/assert.hpp> |
| |
| namespace boost { |
| namespace io { |
| |
| template<class Ch, class Tr=::std::char_traits<Ch>, |
| class Alloc=::std::allocator<Ch> > |
| class basic_altstringbuf; |
| |
| template<class Ch, class Tr =::std::char_traits<Ch>, |
| class Alloc=::std::allocator<Ch> > |
| class basic_oaltstringstream; |
| |
| |
| template<class Ch, class Tr, class Alloc> |
| class basic_altstringbuf |
| : public ::std::basic_streambuf<Ch, Tr> |
| { |
| typedef ::std::basic_streambuf<Ch, Tr> streambuf_t; |
| typedef typename CompatAlloc<Alloc>::compatible_type compat_allocator_type; |
| typedef typename CompatTraits<Tr>::compatible_type compat_traits_type; |
| public: |
| typedef Ch char_type; |
| typedef Tr traits_type; |
| typedef typename compat_traits_type::int_type int_type; |
| typedef typename compat_traits_type::pos_type pos_type; |
| typedef typename compat_traits_type::off_type off_type; |
| typedef Alloc allocator_type; |
| typedef ::std::basic_string<Ch, Tr, Alloc> string_type; |
| typedef typename string_type::size_type size_type; |
| |
| typedef ::std::streamsize streamsize; |
| |
| |
| explicit basic_altstringbuf(std::ios_base::openmode mode |
| = std::ios_base::in | std::ios_base::out) |
| : putend_(NULL), is_allocated_(false), mode_(mode) |
| {} |
| explicit basic_altstringbuf(const string_type& s, |
| ::std::ios_base::openmode mode |
| = ::std::ios_base::in | ::std::ios_base::out) |
| : putend_(NULL), is_allocated_(false), mode_(mode) |
| { dealloc(); str(s); } |
| virtual ~basic_altstringbuf() |
| { dealloc(); } |
| using streambuf_t::pbase; |
| using streambuf_t::pptr; |
| using streambuf_t::epptr; |
| using streambuf_t::eback; |
| using streambuf_t::gptr; |
| using streambuf_t::egptr; |
| |
| void clear_buffer(); |
| void str(const string_type& s); |
| |
| // 0-copy access : |
| Ch * begin() const; |
| size_type size() const; |
| size_type cur_size() const; // stop at current pointer |
| Ch * pend() const // the highest position reached by pptr() since creation |
| { return ((putend_ < pptr()) ? pptr() : putend_); } |
| size_type pcount() const |
| { return static_cast<size_type>( pptr() - pbase()) ;} |
| |
| // copy buffer to string : |
| string_type str() const |
| { return string_type(begin(), size()); } |
| string_type cur_str() const |
| { return string_type(begin(), cur_size()); } |
| protected: |
| explicit basic_altstringbuf (basic_altstringbuf * s, |
| ::std::ios_base::openmode mode |
| = ::std::ios_base::in | ::std::ios_base::out) |
| : putend_(NULL), is_allocated_(false), mode_(mode) |
| { dealloc(); str(s); } |
| |
| virtual pos_type seekoff(off_type off, ::std::ios_base::seekdir way, |
| ::std::ios_base::openmode which |
| = ::std::ios_base::in | ::std::ios_base::out); |
| virtual pos_type seekpos (pos_type pos, |
| ::std::ios_base::openmode which |
| = ::std::ios_base::in | ::std::ios_base::out); |
| virtual int_type underflow(); |
| virtual int_type pbackfail(int_type meta = compat_traits_type::eof()); |
| virtual int_type overflow(int_type meta = compat_traits_type::eof()); |
| void dealloc(); |
| private: |
| enum { alloc_min = 256}; // minimum size of allocations |
| |
| Ch *putend_; // remembers (over seeks) the highest value of pptr() |
| bool is_allocated_; |
| ::std::ios_base::openmode mode_; |
| compat_allocator_type alloc_; // the allocator object |
| }; |
| |
| |
| // --- class basic_oaltstringstream ---------------------------------------- |
| template <class Ch, class Tr, class Alloc> |
| class basic_oaltstringstream |
| : private base_from_member< shared_ptr< basic_altstringbuf< Ch, Tr, Alloc> > >, |
| public ::std::basic_ostream<Ch, Tr> |
| { |
| class No_Op { |
| // used as no-op deleter for (not-owner) shared_pointers |
| public: |
| template<class T> |
| const T & operator()(const T & arg) { return arg; } |
| }; |
| typedef ::std::basic_ostream<Ch, Tr> stream_t; |
| typedef boost::base_from_member<boost::shared_ptr< |
| basic_altstringbuf<Ch,Tr, Alloc> > > |
| pbase_type; |
| typedef ::std::basic_string<Ch, Tr, Alloc> string_type; |
| typedef typename string_type::size_type size_type; |
| typedef basic_altstringbuf<Ch, Tr, Alloc> stringbuf_t; |
| public: |
| typedef Alloc allocator_type; |
| basic_oaltstringstream() |
| : pbase_type(new stringbuf_t), stream_t(rdbuf()) |
| { } |
| basic_oaltstringstream(::boost::shared_ptr<stringbuf_t> buf) |
| : pbase_type(buf), stream_t(rdbuf()) |
| { } |
| basic_oaltstringstream(stringbuf_t * buf) |
| : pbase_type(buf, No_Op() ), stream_t(rdbuf()) |
| { } |
| stringbuf_t * rdbuf() const |
| { return pbase_type::member.get(); } |
| void clear_buffer() |
| { rdbuf()->clear_buffer(); } |
| |
| // 0-copy access : |
| Ch * begin() const |
| { return rdbuf()->begin(); } |
| size_type size() const |
| { return rdbuf()->size(); } |
| size_type cur_size() const // stops at current position |
| { return rdbuf()->cur_size(); } |
| |
| // copy buffer to string : |
| string_type str() const // [pbase, epptr[ |
| { return rdbuf()->str(); } |
| string_type cur_str() const // [pbase, pptr[ |
| { return rdbuf()->cur_str(); } |
| void str(const string_type& s) |
| { rdbuf()->str(s); } |
| }; |
| |
| } // N.S. io |
| } // N.S. boost |
| |
| #include <boost/format/alt_sstream_impl.hpp> |
| |
| #endif // include guard |
| |