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