// ---------------------------------------------------------------------------- // 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