alt_sstream.hpp 7.4 KB

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