basic_pointerbuf.hpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  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. using base_type::pptr;
  39. using base_type::pbase;
  40. protected:
  41. // VC mistakenly assumes that `setbuf` and other functions are not referenced.
  42. // Marking those functions with `inline` suppresses the warnings.
  43. // There must be no harm from marking virtual functions as inline: inline virtual
  44. // call can be inlined ONLY when the compiler knows the "exact class".
  45. inline base_type* setbuf(char_type* s, streamsize n) BOOST_OVERRIDE;
  46. inline typename this_type::pos_type seekpos(pos_type sp, ::std::ios_base::openmode which) BOOST_OVERRIDE;
  47. inline typename this_type::pos_type seekoff(off_type off, ::std::ios_base::seekdir way, ::std::ios_base::openmode which) BOOST_OVERRIDE;
  48. private:
  49. basic_pointerbuf& operator=(const basic_pointerbuf&);
  50. basic_pointerbuf(const basic_pointerbuf&);
  51. };
  52. template<class charT, class BufferT>
  53. BufferT*
  54. basic_pointerbuf<charT, BufferT>::setbuf(char_type* s, streamsize n)
  55. {
  56. this->setg(s, s, s + n);
  57. return this;
  58. }
  59. template<class charT, class BufferT>
  60. typename basic_pointerbuf<charT, BufferT>::pos_type
  61. basic_pointerbuf<charT, BufferT>::seekoff(off_type off, ::std::ios_base::seekdir way, ::std::ios_base::openmode which)
  62. {
  63. typedef typename boost::int_t<sizeof(way) * CHAR_BIT>::least cast_type;
  64. if(which & ::std::ios_base::out)
  65. return pos_type(off_type(-1));
  66. std::ptrdiff_t size = this->egptr() - this->eback();
  67. std::ptrdiff_t pos = this->gptr() - this->eback();
  68. charT* g = this->eback();
  69. switch(static_cast<cast_type>(way))
  70. {
  71. case ::std::ios_base::beg:
  72. if((off < 0) || (off > size))
  73. return pos_type(off_type(-1));
  74. else
  75. this->setg(g, g + off, g + size);
  76. break;
  77. case ::std::ios_base::end:
  78. if((off < 0) || (off > size))
  79. return pos_type(off_type(-1));
  80. else
  81. this->setg(g, g + size - off, g + size);
  82. break;
  83. case ::std::ios_base::cur:
  84. {
  85. std::ptrdiff_t newpos = static_cast<std::ptrdiff_t>(pos + off);
  86. if((newpos < 0) || (newpos > size))
  87. return pos_type(off_type(-1));
  88. else
  89. this->setg(g, g + newpos, g + size);
  90. break;
  91. }
  92. default: ;
  93. }
  94. #ifdef BOOST_MSVC
  95. #pragma warning(push)
  96. #pragma warning(disable:4244)
  97. #endif
  98. return static_cast<pos_type>(this->gptr() - this->eback());
  99. #ifdef BOOST_MSVC
  100. #pragma warning(pop)
  101. #endif
  102. }
  103. template<class charT, class BufferT>
  104. typename basic_pointerbuf<charT, BufferT>::pos_type
  105. basic_pointerbuf<charT, BufferT>::seekpos(pos_type sp, ::std::ios_base::openmode which)
  106. {
  107. if(which & ::std::ios_base::out)
  108. return pos_type(off_type(-1));
  109. off_type size = static_cast<off_type>(this->egptr() - this->eback());
  110. charT* g = this->eback();
  111. if(off_type(sp) <= size)
  112. {
  113. this->setg(g, g + off_type(sp), g + size);
  114. }
  115. return pos_type(off_type(-1));
  116. }
  117. }} // namespace boost::detail
  118. #endif // BOOST_DETAIL_BASIC_POINTERBUF_HPP