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/core/allocator_access.hpp> 20 #include <boost/format/detail/compat_workarounds.hpp> 21 #include <boost/utility/base_from_member.hpp> 22 #include <boost/shared_ptr.hpp> 23 #include <boost/config.hpp> 24 #include <boost/assert.hpp> 25 26 namespace boost { 27 namespace io { 28 29 template<class Ch, class Tr=::std::char_traits<Ch>, 30 class Alloc=::std::allocator<Ch> > 31 class basic_altstringbuf; 32 33 template<class Ch, class Tr =::std::char_traits<Ch>, 34 class Alloc=::std::allocator<Ch> > 35 class basic_oaltstringstream; 36 37 38 template<class Ch, class Tr, class Alloc> 39 class basic_altstringbuf 40 : public ::std::basic_streambuf<Ch, Tr> 41 { 42 typedef ::std::basic_streambuf<Ch, Tr> streambuf_t; 43 typedef typename CompatAlloc<Alloc>::compatible_type compat_allocator_type; 44 typedef typename CompatTraits<Tr>::compatible_type compat_traits_type; 45 public: 46 typedef Ch char_type; 47 typedef Tr traits_type; 48 typedef typename compat_traits_type::int_type int_type; 49 typedef typename compat_traits_type::pos_type pos_type; 50 typedef typename compat_traits_type::off_type off_type; 51 typedef Alloc allocator_type; 52 typedef ::std::basic_string<Ch, Tr, Alloc> string_type; 53 typedef typename string_type::size_type size_type; 54 55 typedef ::std::streamsize streamsize; 56 57 basic_altstringbuf(std::ios_base::openmode mode=std::ios_base::in|std::ios_base::out)58 explicit basic_altstringbuf(std::ios_base::openmode mode 59 = std::ios_base::in | std::ios_base::out) 60 : putend_(NULL), is_allocated_(false), mode_(mode) 61 {} basic_altstringbuf(const string_type & s,::std::ios_base::openmode mode=::std::ios_base::in|::std::ios_base::out)62 explicit basic_altstringbuf(const string_type& s, 63 ::std::ios_base::openmode mode 64 = ::std::ios_base::in | ::std::ios_base::out) 65 : putend_(NULL), is_allocated_(false), mode_(mode) 66 { dealloc(); str(s); } ~basic_altstringbuf()67 virtual ~basic_altstringbuf() BOOST_NOEXCEPT_OR_NOTHROW 68 { dealloc(); } 69 using streambuf_t::pbase; 70 using streambuf_t::pptr; 71 using streambuf_t::epptr; 72 using streambuf_t::eback; 73 using streambuf_t::gptr; 74 using streambuf_t::egptr; 75 76 void clear_buffer(); 77 void str(const string_type& s); 78 79 // 0-copy access : 80 Ch * begin() const; 81 size_type size() const; 82 size_type cur_size() const; // stop at current pointer pend() const83 Ch * pend() const // the highest position reached by pptr() since creation 84 { return ((putend_ < pptr()) ? pptr() : putend_); } pcount() const85 size_type pcount() const 86 { return static_cast<size_type>( pptr() - pbase()) ;} 87 88 // copy buffer to string : str() const89 string_type str() const 90 { return string_type(begin(), size()); } cur_str() const91 string_type cur_str() const 92 { return string_type(begin(), cur_size()); } 93 protected: basic_altstringbuf(basic_altstringbuf * s,::std::ios_base::openmode mode=::std::ios_base::in|::std::ios_base::out)94 explicit basic_altstringbuf (basic_altstringbuf * s, 95 ::std::ios_base::openmode mode 96 = ::std::ios_base::in | ::std::ios_base::out) 97 : putend_(NULL), is_allocated_(false), mode_(mode) 98 { dealloc(); str(s); } 99 100 virtual pos_type seekoff(off_type off, ::std::ios_base::seekdir way, 101 ::std::ios_base::openmode which 102 = ::std::ios_base::in | ::std::ios_base::out); 103 virtual pos_type seekpos (pos_type pos, 104 ::std::ios_base::openmode which 105 = ::std::ios_base::in | ::std::ios_base::out); 106 virtual int_type underflow(); 107 virtual int_type pbackfail(int_type meta = compat_traits_type::eof()); 108 virtual int_type overflow(int_type meta = compat_traits_type::eof()); 109 void dealloc(); 110 private: 111 enum { alloc_min = 256}; // minimum size of allocations 112 113 Ch *putend_; // remembers (over seeks) the highest value of pptr() 114 bool is_allocated_; 115 ::std::ios_base::openmode mode_; 116 compat_allocator_type alloc_; // the allocator object 117 }; 118 119 120 // --- class basic_oaltstringstream ---------------------------------------- 121 template <class Ch, class Tr, class Alloc> 122 class basic_oaltstringstream 123 : private base_from_member< shared_ptr< basic_altstringbuf< Ch, Tr, Alloc> > >, 124 public ::std::basic_ostream<Ch, Tr> 125 { 126 class No_Op { 127 // used as no-op deleter for (not-owner) shared_pointers 128 public: 129 template<class T> operator ()(const T & arg)130 const T & operator()(const T & arg) { return arg; } 131 }; 132 typedef ::std::basic_ostream<Ch, Tr> stream_t; 133 typedef boost::base_from_member<boost::shared_ptr< 134 basic_altstringbuf<Ch,Tr, Alloc> > > 135 pbase_type; 136 typedef ::std::basic_string<Ch, Tr, Alloc> string_type; 137 typedef typename string_type::size_type size_type; 138 typedef basic_altstringbuf<Ch, Tr, Alloc> stringbuf_t; 139 public: 140 typedef Alloc allocator_type; basic_oaltstringstream()141 basic_oaltstringstream() 142 : pbase_type(new stringbuf_t), stream_t(pbase_type::member.get()) 143 { } basic_oaltstringstream(::boost::shared_ptr<stringbuf_t> buf)144 basic_oaltstringstream(::boost::shared_ptr<stringbuf_t> buf) 145 : pbase_type(buf), stream_t(pbase_type::member.get()) 146 { } basic_oaltstringstream(stringbuf_t * buf)147 basic_oaltstringstream(stringbuf_t * buf) 148 : pbase_type(buf, No_Op() ), stream_t(pbase_type::member.get()) 149 { } rdbuf() const150 stringbuf_t * rdbuf() const 151 { return pbase_type::member.get(); } clear_buffer()152 void clear_buffer() 153 { rdbuf()->clear_buffer(); } 154 155 // 0-copy access : begin() const156 Ch * begin() const 157 { return rdbuf()->begin(); } size() const158 size_type size() const 159 { return rdbuf()->size(); } cur_size() const160 size_type cur_size() const // stops at current position 161 { return rdbuf()->cur_size(); } 162 163 // copy buffer to string : str() const164 string_type str() const // [pbase, epptr[ 165 { return rdbuf()->str(); } cur_str() const166 string_type cur_str() const // [pbase, pptr[ 167 { return rdbuf()->cur_str(); } str(const string_type & s)168 void str(const string_type& s) 169 { rdbuf()->str(s); } 170 }; 171 172 } // N.S. io 173 } // N.S. boost 174 175 #include <boost/format/alt_sstream_impl.hpp> 176 177 #endif // include guard 178 179