File indexing completed on 2025-01-18 09:38:54
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_IOSTREAMS_SEEK_HPP_INCLUDED
0009 #define BOOST_IOSTREAMS_SEEK_HPP_INCLUDED
0010
0011 #if defined(_MSC_VER)
0012 # pragma once
0013 #endif
0014
0015 #include <boost/config.hpp> // DEDUCED_TYPENAME, MSVC.
0016 #include <boost/integer_traits.hpp>
0017 #include <boost/iostreams/categories.hpp>
0018 #include <boost/iostreams/detail/dispatch.hpp>
0019 #include <boost/iostreams/detail/ios.hpp> // streamsize, seekdir, openmode.
0020 #include <boost/iostreams/detail/streambuf.hpp>
0021 #include <boost/iostreams/detail/wrap_unwrap.hpp>
0022 #include <boost/iostreams/operations_fwd.hpp>
0023 #include <boost/iostreams/positioning.hpp>
0024 #include <boost/mpl/if.hpp>
0025
0026
0027 #include <boost/iostreams/detail/config/disable_warnings.hpp>
0028
0029 namespace boost { namespace iostreams {
0030
0031 namespace detail {
0032
0033 template<typename T>
0034 struct seek_device_impl;
0035
0036 template<typename T>
0037 struct seek_filter_impl;
0038
0039 }
0040
0041 template<typename T>
0042 inline std::streampos
0043 seek( T& t, stream_offset off, BOOST_IOS::seekdir way,
0044 BOOST_IOS::openmode which = BOOST_IOS::in | BOOST_IOS::out )
0045 {
0046 using namespace detail;
0047 return seek_device_impl<T>::seek(detail::unwrap(t), off, way, which);
0048 }
0049
0050 template<typename T, typename Device>
0051 inline std::streampos
0052 seek( T& t, Device& dev, stream_offset off, BOOST_IOS::seekdir way,
0053 BOOST_IOS::openmode which = BOOST_IOS::in | BOOST_IOS::out )
0054 {
0055 using namespace detail;
0056 return seek_filter_impl<T>::seek(detail::unwrap(t), dev, off, way, which);
0057 }
0058
0059 namespace detail {
0060
0061
0062
0063 template<typename T>
0064 struct seek_device_impl
0065 : mpl::if_<
0066 is_custom<T>,
0067 operations<T>,
0068 seek_device_impl<
0069 BOOST_DEDUCED_TYPENAME
0070 dispatch<
0071 T, iostream_tag, istream_tag, ostream_tag,
0072 streambuf_tag, two_head, any_tag
0073 >::type
0074 >
0075 >::type
0076 { };
0077
0078 struct seek_impl_basic_ios {
0079 template<typename T>
0080 static std::streampos seek( T& t, stream_offset off,
0081 BOOST_IOS::seekdir way,
0082 BOOST_IOS::openmode which )
0083 {
0084 if ( way == BOOST_IOS::beg &&
0085 ( off < integer_traits<std::streamoff>::const_min ||
0086 off > integer_traits<std::streamoff>::const_max ) )
0087 {
0088 return t.rdbuf()->pubseekpos(offset_to_position(off));
0089 } else {
0090 return t.rdbuf()->pubseekoff(off, way, which);
0091 }
0092 }
0093 };
0094
0095 template<>
0096 struct seek_device_impl<iostream_tag> : seek_impl_basic_ios { };
0097
0098 template<>
0099 struct seek_device_impl<istream_tag> : seek_impl_basic_ios { };
0100
0101 template<>
0102 struct seek_device_impl<ostream_tag> : seek_impl_basic_ios { };
0103
0104 template<>
0105 struct seek_device_impl<streambuf_tag> {
0106 template<typename T>
0107 static std::streampos seek( T& t, stream_offset off,
0108 BOOST_IOS::seekdir way,
0109 BOOST_IOS::openmode which )
0110 {
0111 if ( way == BOOST_IOS::beg &&
0112 ( off < integer_traits<std::streamoff>::const_min ||
0113 off > integer_traits<std::streamoff>::const_max ) )
0114 {
0115 return t.BOOST_IOSTREAMS_PUBSEEKPOS(offset_to_position(off));
0116 } else {
0117 return t.BOOST_IOSTREAMS_PUBSEEKOFF(off, way, which);
0118 }
0119 }
0120 };
0121
0122 template<>
0123 struct seek_device_impl<two_head> {
0124 template<typename T>
0125 static std::streampos seek( T& t, stream_offset off,
0126 BOOST_IOS::seekdir way,
0127 BOOST_IOS::openmode which )
0128 { return t.seek(off, way, which); }
0129 };
0130
0131 template<>
0132 struct seek_device_impl<any_tag> {
0133 template<typename T>
0134 static std::streampos seek( T& t, stream_offset off,
0135 BOOST_IOS::seekdir way,
0136 BOOST_IOS::openmode )
0137 { return t.seek(off, way); }
0138 };
0139
0140
0141
0142 template<typename T>
0143 struct seek_filter_impl
0144 : mpl::if_<
0145 is_custom<T>,
0146 operations<T>,
0147 seek_filter_impl<
0148 BOOST_DEDUCED_TYPENAME
0149 dispatch<T, two_head, any_tag>::type
0150 >
0151 >::type
0152 { };
0153
0154 template<>
0155 struct seek_filter_impl<two_head> {
0156 template<typename T, typename Device>
0157 static std::streampos seek( T& t, Device& d,
0158 stream_offset off,
0159 BOOST_IOS::seekdir way,
0160 BOOST_IOS::openmode which )
0161 { return t.seek(d, off, way, which); }
0162 };
0163
0164 template<>
0165 struct seek_filter_impl<any_tag> {
0166 template<typename T, typename Device>
0167 static std::streampos seek( T& t, Device& d,
0168 stream_offset off,
0169 BOOST_IOS::seekdir way,
0170 BOOST_IOS::openmode )
0171 { return t.seek(d, off, way); }
0172 };
0173
0174 }
0175
0176 } }
0177
0178 #include <boost/iostreams/detail/config/enable_warnings.hpp>
0179
0180 #endif