source: NonGTP/Boost/boost/iostreams/seek.hpp @ 857

Revision 857, 5.5 KB checked in by igarcia, 18 years ago (diff)
Line 
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
28namespace boost { namespace iostreams {
29
30namespace detail {
31
32template<typename T>
33struct seek_device_impl;
34
35template<typename T>
36struct seek_filter_impl;
37
38} // End namespace detail.
39
40template<typename T>
41inline std::streampos
42seek( 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
49template<typename T, typename Device>
50inline std::streampos
51seek( 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
58namespace detail {
59
60//------------------Definition of seek_device_impl----------------------------//
61
62template<typename T>
63struct 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
77struct 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
94template<>
95struct seek_device_impl<iostream_tag> : seek_impl_basic_ios { };
96
97template<>
98struct seek_device_impl<istream_tag> : seek_impl_basic_ios { };
99
100template<>
101struct seek_device_impl<ostream_tag> : seek_impl_basic_ios { };
102
103template<>
104struct 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
121template<>
122struct 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
130template<>
131struct 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
141template<typename T>
142struct 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
153template<>
154struct 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
163template<>
164struct 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
Note: See TracBrowser for help on using the repository browser.