blob: 6ff19b1af19fc144aa8e187629ca7c70ad9dc5a4 [file] [log] [blame]
Jeff Thompson86b6d642013-10-17 15:01:56 -07001// (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 NDNBOOST_IOSTREAMS_SEEK_HPP_INCLUDED
9#define NDNBOOST_IOSTREAMS_SEEK_HPP_INCLUDED
10
11#if defined(_MSC_VER) && (_MSC_VER >= 1020)
12# pragma once
13#endif
14
15#include <ndnboost/config.hpp> // DEDUCED_TYPENAME, MSVC.
16#include <ndnboost/integer_traits.hpp>
17#include <ndnboost/iostreams/categories.hpp>
18#include <ndnboost/iostreams/detail/dispatch.hpp>
19#include <ndnboost/iostreams/detail/ios.hpp> // streamsize, seekdir, openmode.
20#include <ndnboost/iostreams/detail/streambuf.hpp>
21#include <ndnboost/iostreams/detail/wrap_unwrap.hpp>
22#include <ndnboost/iostreams/operations_fwd.hpp>
23#include <ndnboost/iostreams/positioning.hpp>
24#include <ndnboost/mpl/if.hpp>
25
26// Must come last.
27#include <ndnboost/iostreams/detail/config/disable_warnings.hpp>
28
29namespace ndnboost { 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, NDNBOOST_IOS::seekdir way,
44 NDNBOOST_IOS::openmode which = NDNBOOST_IOS::in | NDNBOOST_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, NDNBOOST_IOS::seekdir way,
53 NDNBOOST_IOS::openmode which = NDNBOOST_IOS::in | NDNBOOST_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 NDNBOOST_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 NDNBOOST_IOS::seekdir way,
82 NDNBOOST_IOS::openmode which )
83 {
84 if ( way == NDNBOOST_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 NDNBOOST_IOS::seekdir way,
109 NDNBOOST_IOS::openmode which )
110 {
111 if ( way == NDNBOOST_IOS::beg &&
112 ( off < integer_traits<std::streamoff>::const_min ||
113 off > integer_traits<std::streamoff>::const_max ) )
114 {
115 return t.NDNBOOST_IOSTREAMS_PUBSEEKPOS(offset_to_position(off));
116 } else {
117 return t.NDNBOOST_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 NDNBOOST_IOS::seekdir way,
127 NDNBOOST_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 NDNBOOST_IOS::seekdir way,
136 NDNBOOST_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 NDNBOOST_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 NDNBOOST_IOS::seekdir way,
160 NDNBOOST_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 NDNBOOST_IOS::seekdir way,
170 NDNBOOST_IOS::openmode )
171 { return t.seek(d, off, way); }
172};
173
174} // End namespace detail.
175
176} } // End namespaces iostreams, boost.
177
178#include <ndnboost/iostreams/detail/config/enable_warnings.hpp>
179
180#endif // #ifndef NDNBOOST_IOSTREAMS_SEEK_HPP_INCLUDED