basic_pointerbuf.hpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. //-----------------------------------------------------------------------------
  2. // boost detail/templated_streams.hpp header file
  3. // See http://www.boost.org for updates, documentation, and revision history.
  4. //-----------------------------------------------------------------------------
  5. //
  6. // Copyright (c) 2013 John Maddock, Antony Polukhin
  7. //
  8. //
  9. // Distributed under the Boost Software License, Version 1.0. (See
  10. // accompanying file LICENSE_1_0.txt or copy at
  11. // http://www.boost.org/LICENSE_1_0.txt)
  12. #ifndef BOOST_DETAIL_BASIC_POINTERBUF_HPP
  13. #define BOOST_DETAIL_BASIC_POINTERBUF_HPP
  14. // MS compatible compilers support #pragma once
  15. #if defined(_MSC_VER)
  16. # pragma once
  17. #endif
  18. #include "boost/config.hpp"
  19. #include <streambuf>
  20. namespace boost { namespace detail {
  21. //
  22. // class basic_pointerbuf:
  23. // acts as a stream buffer which wraps around a pair of pointers:
  24. //
  25. template <class charT, class BufferT >
  26. class basic_pointerbuf : public BufferT {
  27. protected:
  28. typedef BufferT base_type;
  29. typedef basic_pointerbuf<charT, BufferT> this_type;
  30. typedef typename base_type::int_type int_type;
  31. typedef typename base_type::char_type char_type;
  32. typedef typename base_type::pos_type pos_type;
  33. typedef ::std::streamsize streamsize;
  34. typedef typename base_type::off_type off_type;
  35. public:
  36. basic_pointerbuf() : base_type() { this_type::setbuf(0, 0); }
  37. const charT* getnext() { return this->gptr(); }
  38. #ifndef BOOST_NO_USING_TEMPLATE
  39. using base_type::pptr;
  40. using base_type::pbase;
  41. #else
  42. charT* pptr() const { return base_type::pptr(); }
  43. charT* pbase() const { return base_type::pbase(); }
  44. #endif
  45. protected:
  46. // VC mistakenly assumes that `setbuf` and other functions are not referenced.
  47. // Marking those functions with `inline` suppresses the warnings.
  48. // There must be no harm from marking virtual functions as inline: inline virtual
  49. // call can be inlined ONLY when the compiler knows the "exact class".
  50. inline base_type* setbuf(char_type* s, streamsize n);
  51. inline typename this_type::pos_type seekpos(pos_type sp, ::std::ios_base::openmode which);
  52. inline typename this_type::pos_type seekoff(off_type off, ::std::ios_base::seekdir way, ::std::ios_base::openmode which);
  53. private:
  54. basic_pointerbuf& operator=(const basic_pointerbuf&);
  55. basic_pointerbuf(const basic_pointerbuf&);
  56. };
  57. template<class charT, class BufferT>
  58. BufferT*
  59. basic_pointerbuf<charT, BufferT>::setbuf(char_type* s, streamsize n)
  60. {
  61. this->setg(s, s, s + n);
  62. return this;
  63. }
  64. template<class charT, class BufferT>
  65. typename basic_pointerbuf<charT, BufferT>::pos_type
  66. basic_pointerbuf<charT, BufferT>::seekoff(off_type off, ::std::ios_base::seekdir way, ::std::ios_base::openmode which)
  67. {
  68. typedef typename boost::int_t<sizeof(way) * CHAR_BIT>::least cast_type;
  69. if(which & ::std::ios_base::out)
  70. return pos_type(off_type(-1));
  71. std::ptrdiff_t size = this->egptr() - this->eback();
  72. std::ptrdiff_t pos = this->gptr() - this->eback();
  73. charT* g = this->eback();
  74. switch(static_cast<cast_type>(way))
  75. {
  76. case ::std::ios_base::beg:
  77. if((off < 0) || (off > size))
  78. return pos_type(off_type(-1));
  79. else
  80. this->setg(g, g + off, g + size);
  81. break;
  82. case ::std::ios_base::end:
  83. if((off < 0) || (off > size))
  84. return pos_type(off_type(-1));
  85. else
  86. this->setg(g, g + size - off, g + size);
  87. break;
  88. case ::std::ios_base::cur:
  89. {
  90. std::ptrdiff_t newpos = static_cast<std::ptrdiff_t>(pos + off);
  91. if((newpos < 0) || (newpos > size))
  92. return pos_type(off_type(-1));
  93. else
  94. this->setg(g, g + newpos, g + size);
  95. break;
  96. }
  97. default: ;
  98. }
  99. #ifdef BOOST_MSVC
  100. #pragma warning(push)
  101. #pragma warning(disable:4244)
  102. #endif
  103. return static_cast<pos_type>(this->gptr() - this->eback());
  104. #ifdef BOOST_MSVC
  105. #pragma warning(pop)
  106. #endif
  107. }
  108. template<class charT, class BufferT>
  109. typename basic_pointerbuf<charT, BufferT>::pos_type
  110. basic_pointerbuf<charT, BufferT>::seekpos(pos_type sp, ::std::ios_base::openmode which)
  111. {
  112. if(which & ::std::ios_base::out)
  113. return pos_type(off_type(-1));
  114. off_type size = static_cast<off_type>(this->egptr() - this->eback());
  115. charT* g = this->eback();
  116. if(off_type(sp) <= size)
  117. {
  118. this->setg(g, g + off_type(sp), g + size);
  119. }
  120. return pos_type(off_type(-1));
  121. }
  122. }} // namespace boost::detail
  123. #endif // BOOST_DETAIL_BASIC_POINTERBUF_HPP