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