seek.hpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. // (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
  2. // (C) Copyright 2003-2007 Jonathan Turkanis
  3. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  4. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
  5. // See http://www.boost.org/libs/iostreams for documentation.
  6. #ifndef BOOST_IOSTREAMS_SEEK_HPP_INCLUDED
  7. #define BOOST_IOSTREAMS_SEEK_HPP_INCLUDED
  8. #if defined(_MSC_VER)
  9. # pragma once
  10. #endif
  11. #include <boost/config.hpp> // DEDUCED_TYPENAME, MSVC.
  12. #include <boost/integer_traits.hpp>
  13. #include <boost/iostreams/categories.hpp>
  14. #include <boost/iostreams/detail/dispatch.hpp>
  15. #include <boost/iostreams/detail/ios.hpp> // streamsize, seekdir, openmode.
  16. #include <boost/iostreams/detail/streambuf.hpp>
  17. #include <boost/iostreams/detail/wrap_unwrap.hpp>
  18. #include <boost/iostreams/operations_fwd.hpp>
  19. #include <boost/iostreams/positioning.hpp>
  20. #include <boost/mpl/if.hpp>
  21. // Must come last.
  22. #include <boost/iostreams/detail/config/disable_warnings.hpp>
  23. namespace boost { namespace iostreams {
  24. namespace detail {
  25. template<typename T>
  26. struct seek_device_impl;
  27. template<typename T>
  28. struct seek_filter_impl;
  29. } // End namespace detail.
  30. template<typename T>
  31. inline std::streampos
  32. seek( T& t, stream_offset off, BOOST_IOS::seekdir way,
  33. BOOST_IOS::openmode which = BOOST_IOS::in | BOOST_IOS::out )
  34. {
  35. using namespace detail;
  36. return seek_device_impl<T>::seek(detail::unwrap(t), off, way, which);
  37. }
  38. template<typename T, typename Device>
  39. inline std::streampos
  40. seek( T& t, Device& dev, stream_offset off, BOOST_IOS::seekdir way,
  41. BOOST_IOS::openmode which = BOOST_IOS::in | BOOST_IOS::out )
  42. {
  43. using namespace detail;
  44. return seek_filter_impl<T>::seek(detail::unwrap(t), dev, off, way, which);
  45. }
  46. namespace detail {
  47. //------------------Definition of seek_device_impl----------------------------//
  48. template<typename T>
  49. struct seek_device_impl
  50. : mpl::if_<
  51. is_custom<T>,
  52. operations<T>,
  53. seek_device_impl<
  54. BOOST_DEDUCED_TYPENAME
  55. dispatch<
  56. T, iostream_tag, istream_tag, ostream_tag,
  57. streambuf_tag, two_head, any_tag
  58. >::type
  59. >
  60. >::type
  61. { };
  62. struct seek_impl_basic_ios {
  63. template<typename T>
  64. static std::streampos seek( T& t, stream_offset off,
  65. BOOST_IOS::seekdir way,
  66. BOOST_IOS::openmode which )
  67. {
  68. if ( way == BOOST_IOS::beg &&
  69. ( off < integer_traits<std::streamoff>::const_min ||
  70. off > integer_traits<std::streamoff>::const_max ) )
  71. {
  72. return t.rdbuf()->pubseekpos(offset_to_position(off));
  73. } else {
  74. return t.rdbuf()->pubseekoff(off, way, which);
  75. }
  76. }
  77. };
  78. template<>
  79. struct seek_device_impl<iostream_tag> : seek_impl_basic_ios { };
  80. template<>
  81. struct seek_device_impl<istream_tag> : seek_impl_basic_ios { };
  82. template<>
  83. struct seek_device_impl<ostream_tag> : seek_impl_basic_ios { };
  84. template<>
  85. struct seek_device_impl<streambuf_tag> {
  86. template<typename T>
  87. static std::streampos seek( T& t, stream_offset off,
  88. BOOST_IOS::seekdir way,
  89. BOOST_IOS::openmode which )
  90. {
  91. if ( way == BOOST_IOS::beg &&
  92. ( off < integer_traits<std::streamoff>::const_min ||
  93. off > integer_traits<std::streamoff>::const_max ) )
  94. {
  95. return t.BOOST_IOSTREAMS_PUBSEEKPOS(offset_to_position(off));
  96. } else {
  97. return t.BOOST_IOSTREAMS_PUBSEEKOFF(off, way, which);
  98. }
  99. }
  100. };
  101. template<>
  102. struct seek_device_impl<two_head> {
  103. template<typename T>
  104. static std::streampos seek( T& t, stream_offset off,
  105. BOOST_IOS::seekdir way,
  106. BOOST_IOS::openmode which )
  107. { return t.seek(off, way, which); }
  108. };
  109. template<>
  110. struct seek_device_impl<any_tag> {
  111. template<typename T>
  112. static std::streampos seek( T& t, stream_offset off,
  113. BOOST_IOS::seekdir way,
  114. BOOST_IOS::openmode )
  115. { return t.seek(off, way); }
  116. };
  117. //------------------Definition of seek_filter_impl----------------------------//
  118. template<typename T>
  119. struct seek_filter_impl
  120. : mpl::if_<
  121. is_custom<T>,
  122. operations<T>,
  123. seek_filter_impl<
  124. BOOST_DEDUCED_TYPENAME
  125. dispatch<T, two_head, any_tag>::type
  126. >
  127. >::type
  128. { };
  129. template<>
  130. struct seek_filter_impl<two_head> {
  131. template<typename T, typename Device>
  132. static std::streampos seek( T& t, Device& d,
  133. stream_offset off,
  134. BOOST_IOS::seekdir way,
  135. BOOST_IOS::openmode which )
  136. { return t.seek(d, off, way, which); }
  137. };
  138. template<>
  139. struct seek_filter_impl<any_tag> {
  140. template<typename T, typename Device>
  141. static std::streampos seek( T& t, Device& d,
  142. stream_offset off,
  143. BOOST_IOS::seekdir way,
  144. BOOST_IOS::openmode )
  145. { return t.seek(d, off, way); }
  146. };
  147. } // End namespace detail.
  148. } } // End namespaces iostreams, boost.
  149. #include <boost/iostreams/detail/config/enable_warnings.hpp>
  150. #endif // #ifndef BOOST_IOSTREAMS_SEEK_HPP_INCLUDED