alt_sstream.hpp 7.3 KB

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