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
6// See http://www.boost.org/libs/iostreams for documentation.
7
8#ifndef BOOST_IOSTREAMS_SEEK_HPP_INCLUDED
9#define BOOST_IOSTREAMS_SEEK_HPP_INCLUDED
10
11#if defined(_MSC_VER) && (_MSC_VER >= 1020)
12# pragma once
13#endif
14
15#include <boost/config.hpp> // DEDUCED_TYPENAME, MSVC.
16#include <boost/integer_traits.hpp>
17#include <boost/iostreams/categories.hpp>
18#include <boost/iostreams/detail/dispatch.hpp>
19#include <boost/iostreams/detail/ios.hpp> // streamsize, seekdir, openmode.
20#include <boost/iostreams/detail/streambuf.hpp>
21#include <boost/iostreams/detail/wrap_unwrap.hpp>
22#include <boost/iostreams/operations_fwd.hpp>
23#include <boost/iostreams/positioning.hpp>
24#include <boost/mpl/if.hpp>
25
26// Must come last.
27#include <boost/iostreams/detail/config/disable_warnings.hpp>
28
29namespace boost { namespace iostreams {
30
31namespace detail {
32
33template<typename T>
34struct seek_device_impl;
35
36template<typename T>
37struct seek_filter_impl;
38
39} // End namespace detail.
40
41template<typename T>
42inline std::streampos
43seek( T& t, stream_offset off, BOOST_IOS::seekdir way,
44 BOOST_IOS::openmode which = BOOST_IOS::in | BOOST_IOS::out )
45{
46 using namespace detail;
47 return seek_device_impl<T>::seek(detail::unwrap(t), off, way, which);
48}
49
50template<typename T, typename Device>
51inline std::streampos
52seek( T& t, Device& dev, stream_offset off, BOOST_IOS::seekdir way,
53 BOOST_IOS::openmode which = BOOST_IOS::in | BOOST_IOS::out )
54{
55 using namespace detail;
56 return seek_filter_impl<T>::seek(detail::unwrap(t), dev, off, way, which);
57}
58
59namespace detail {
60
61//------------------Definition of seek_device_impl----------------------------//
62
63template<typename T>
64struct seek_device_impl
65 : mpl::if_<
66 is_custom<T>,
67 operations<T>,
68 seek_device_impl<
69 BOOST_DEDUCED_TYPENAME
70 dispatch<
71 T, iostream_tag, istream_tag, ostream_tag,
72 streambuf_tag, two_head, any_tag
73 >::type
74 >
75 >::type
76 { };
77
78struct seek_impl_basic_ios {
79 template<typename T>
80 static std::streampos seek( T& t, stream_offset off,
81 BOOST_IOS::seekdir way,
82 BOOST_IOS::openmode which )
83 {
84 if ( way == BOOST_IOS::beg &&
85 ( off < integer_traits<std::streamoff>::const_min ||
86 off > integer_traits<std::streamoff>::const_max ) )
87 {
88 return t.rdbuf()->pubseekpos(offset_to_position(off));
89 } else {
90 return t.rdbuf()->pubseekoff(off, way, which);
91 }
92 }
93};
94
95template<>
96struct seek_device_impl<iostream_tag> : seek_impl_basic_ios { };
97
98template<>
99struct seek_device_impl<istream_tag> : seek_impl_basic_ios { };
100
101template<>
102struct seek_device_impl<ostream_tag> : seek_impl_basic_ios { };
103
104template<>
105struct seek_device_impl<streambuf_tag> {
106 template<typename T>
107 static std::streampos seek( T& t, stream_offset off,
108 BOOST_IOS::seekdir way,
109 BOOST_IOS::openmode which )
110 {
111 if ( way == BOOST_IOS::beg &&
112 ( off < integer_traits<std::streamoff>::const_min ||
113 off > integer_traits<std::streamoff>::const_max ) )
114 {
115 return t.BOOST_IOSTREAMS_PUBSEEKPOS(offset_to_position(off));
116 } else {
117 return t.BOOST_IOSTREAMS_PUBSEEKOFF(off, way, which);
118 }
119 }
120};
121
122template<>
123struct seek_device_impl<two_head> {
124 template<typename T>
125 static std::streampos seek( T& t, stream_offset off,
126 BOOST_IOS::seekdir way,
127 BOOST_IOS::openmode which )
128 { return t.seek(off, way, which); }
129};
130
131template<>
132struct seek_device_impl<any_tag> {
133 template<typename T>
134 static std::streampos seek( T& t, stream_offset off,
135 BOOST_IOS::seekdir way,
136 BOOST_IOS::openmode )
137 { return t.seek(off, way); }
138};
139
140//------------------Definition of seek_filter_impl----------------------------//
141
142template<typename T>
143struct seek_filter_impl
144 : mpl::if_<
145 is_custom<T>,
146 operations<T>,
147 seek_filter_impl<
148 BOOST_DEDUCED_TYPENAME
149 dispatch<T, two_head, any_tag>::type
150 >
151 >::type
152 { };
153
154template<>
155struct seek_filter_impl<two_head> {
156 template<typename T, typename Device>
157 static std::streampos seek( T& t, Device& d,
158 stream_offset off,
159 BOOST_IOS::seekdir way,
160 BOOST_IOS::openmode which )
161 { return t.seek(d, off, way, which); }
162};
163
164template<>
165struct seek_filter_impl<any_tag> {
166 template<typename T, typename Device>
167 static std::streampos seek( T& t, Device& d,
168 stream_offset off,
169 BOOST_IOS::seekdir way,
170 BOOST_IOS::openmode )
171 { return t.seek(d, off, way); }
172};
173
174} // End namespace detail.
175
176} } // End namespaces iostreams, boost.
177
178#include <boost/iostreams/detail/config/enable_warnings.hpp>
179
180#endif // #ifndef BOOST_IOSTREAMS_SEEK_HPP_INCLUDED
181

source code of boost/boost/iostreams/seek.hpp