1 // ---------------------------------------------------------------------------- 2 // alt_sstream.hpp : alternative stringstream 3 // ---------------------------------------------------------------------------- 4 5 // Copyright Samuel Krempp 2003. Use, modification, and distribution are 6 // subject to the Boost Software License, Version 1.0. (See accompanying 7 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 8 9 // See http://www.boost.org/libs/format for library home page 10 11 // ---------------------------------------------------------------------------- 12 13 14 15 #ifndef BOOST_SK_ALT_SSTREAM_HPP 16 #define BOOST_SK_ALT_SSTREAM_HPP 17 18 #include <string> 19 #include <boost/format/detail/compat_workarounds.hpp> 20 #include <boost/utility/base_from_member.hpp> 21 #include <boost/shared_ptr.hpp> 22 #include <boost/assert.hpp> 23 24 namespace boost { 25 namespace io { 26 27 template<class Ch, class Tr=::std::char_traits<Ch>, 28 class Alloc=::std::allocator<Ch> > 29 class basic_altstringbuf; 30 31 template<class Ch, class Tr =::std::char_traits<Ch>, 32 class Alloc=::std::allocator<Ch> > 33 class basic_oaltstringstream; 34 35 36 template<class Ch, class Tr, class Alloc> 37 class basic_altstringbuf 38 : public ::std::basic_streambuf<Ch, Tr> 39 { 40 typedef ::std::basic_streambuf<Ch, Tr> streambuf_t; 41 typedef typename CompatAlloc<Alloc>::compatible_type compat_allocator_type; 42 typedef typename CompatTraits<Tr>::compatible_type compat_traits_type; 43 public: 44 typedef Ch char_type; 45 typedef Tr traits_type; 46 typedef typename compat_traits_type::int_type int_type; 47 typedef typename compat_traits_type::pos_type pos_type; 48 typedef typename compat_traits_type::off_type off_type; 49 typedef Alloc allocator_type; 50 typedef ::std::basic_string<Ch, Tr, Alloc> string_type; 51 typedef typename string_type::size_type size_type; 52 53 typedef ::std::streamsize streamsize; 54 55 basic_altstringbuf(std::ios_base::openmode mode=std::ios_base::in|std::ios_base::out)56 explicit basic_altstringbuf(std::ios_base::openmode mode 57 = std::ios_base::in | std::ios_base::out) 58 : putend_(NULL), is_allocated_(false), mode_(mode) 59 {} basic_altstringbuf(const string_type & s,::std::ios_base::openmode mode=::std::ios_base::in|::std::ios_base::out)60 explicit basic_altstringbuf(const string_type& s, 61 ::std::ios_base::openmode mode 62 = ::std::ios_base::in | ::std::ios_base::out) 63 : putend_(NULL), is_allocated_(false), mode_(mode) 64 { dealloc(); str(s); } ~basic_altstringbuf()65 virtual ~basic_altstringbuf() 66 { dealloc(); } 67 using streambuf_t::pbase; 68 using streambuf_t::pptr; 69 using streambuf_t::epptr; 70 using streambuf_t::eback; 71 using streambuf_t::gptr; 72 using streambuf_t::egptr; 73 74 void clear_buffer(); 75 void str(const string_type& s); 76 77 // 0-copy access : 78 Ch * begin() const; 79 size_type size() const; 80 size_type cur_size() const; // stop at current pointer pend() const81 Ch * pend() const // the highest position reached by pptr() since creation 82 { return ((putend_ < pptr()) ? pptr() : putend_); } pcount() const83 size_type pcount() const 84 { return static_cast<size_type>( pptr() - pbase()) ;} 85 86 // copy buffer to string : str() const87 string_type str() const 88 { return string_type(begin(), size()); } cur_str() const89 string_type cur_str() const 90 { return string_type(begin(), cur_size()); } 91 protected: basic_altstringbuf(basic_altstringbuf * s,::std::ios_base::openmode mode=::std::ios_base::in|::std::ios_base::out)92 explicit basic_altstringbuf (basic_altstringbuf * s, 93 ::std::ios_base::openmode mode 94 = ::std::ios_base::in | ::std::ios_base::out) 95 : putend_(NULL), is_allocated_(false), mode_(mode) 96 { dealloc(); str(s); } 97 98 virtual pos_type seekoff(off_type off, ::std::ios_base::seekdir way, 99 ::std::ios_base::openmode which 100 = ::std::ios_base::in | ::std::ios_base::out); 101 virtual pos_type seekpos (pos_type pos, 102 ::std::ios_base::openmode which 103 = ::std::ios_base::in | ::std::ios_base::out); 104 virtual int_type underflow(); 105 virtual int_type pbackfail(int_type meta = compat_traits_type::eof()); 106 virtual int_type overflow(int_type meta = compat_traits_type::eof()); 107 void dealloc(); 108 private: 109 enum { alloc_min = 256}; // minimum size of allocations 110 111 Ch *putend_; // remembers (over seeks) the highest value of pptr() 112 bool is_allocated_; 113 ::std::ios_base::openmode mode_; 114 compat_allocator_type alloc_; // the allocator object 115 }; 116 117 118 // --- class basic_oaltstringstream ---------------------------------------- 119 template <class Ch, class Tr, class Alloc> 120 class basic_oaltstringstream 121 : private base_from_member< shared_ptr< basic_altstringbuf< Ch, Tr, Alloc> > >, 122 public ::std::basic_ostream<Ch, Tr> 123 { 124 class No_Op { 125 // used as no-op deleter for (not-owner) shared_pointers 126 public: 127 template<class T> operator ()(const T & arg)128 const T & operator()(const T & arg) { return arg; } 129 }; 130 typedef ::std::basic_ostream<Ch, Tr> stream_t; 131 typedef boost::base_from_member<boost::shared_ptr< 132 basic_altstringbuf<Ch,Tr, Alloc> > > 133 pbase_type; 134 typedef ::std::basic_string<Ch, Tr, Alloc> string_type; 135 typedef typename string_type::size_type size_type; 136 typedef basic_altstringbuf<Ch, Tr, Alloc> stringbuf_t; 137 public: 138 typedef Alloc allocator_type; basic_oaltstringstream()139 basic_oaltstringstream() 140 : pbase_type(new stringbuf_t), stream_t(rdbuf()) 141 { } basic_oaltstringstream(::boost::shared_ptr<stringbuf_t> buf)142 basic_oaltstringstream(::boost::shared_ptr<stringbuf_t> buf) 143 : pbase_type(buf), stream_t(rdbuf()) 144 { } basic_oaltstringstream(stringbuf_t * buf)145 basic_oaltstringstream(stringbuf_t * buf) 146 : pbase_type(buf, No_Op() ), stream_t(rdbuf()) 147 { } rdbuf() const148 stringbuf_t * rdbuf() const 149 { return pbase_type::member.get(); } clear_buffer()150 void clear_buffer() 151 { rdbuf()->clear_buffer(); } 152 153 // 0-copy access : begin() const154 Ch * begin() const 155 { return rdbuf()->begin(); } size() const156 size_type size() const 157 { return rdbuf()->size(); } cur_size() const158 size_type cur_size() const // stops at current position 159 { return rdbuf()->cur_size(); } 160 161 // copy buffer to string : str() const162 string_type str() const // [pbase, epptr[ 163 { return rdbuf()->str(); } cur_str() const164 string_type cur_str() const // [pbase, pptr[ 165 { return rdbuf()->cur_str(); } str(const string_type & s)166 void str(const string_type& s) 167 { rdbuf()->str(s); } 168 }; 169 170 } // N.S. io 171 } // N.S. boost 172 173 #include <boost/format/alt_sstream_impl.hpp> 174 175 #endif // include guard 176 177