• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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