alt_sstream.hpp 7.4 KB

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