Chris@16
|
1 // (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
|
Chris@16
|
2 // (C) Copyright 2003-2007 Jonathan Turkanis
|
Chris@16
|
3 // Distributed under the Boost Software License, Version 1.0. (See accompanying
|
Chris@16
|
4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
|
Chris@16
|
5
|
Chris@16
|
6 // See http://www.boost.org/libs/iostreams for documentation.
|
Chris@16
|
7
|
Chris@16
|
8 #ifndef BOOST_IOSTREAMS_DETAIL_CONCEPT_ADAPTER_HPP_INCLUDED
|
Chris@16
|
9 #define BOOST_IOSTREAMS_DETAIL_CONCEPT_ADAPTER_HPP_INCLUDED
|
Chris@16
|
10
|
Chris@16
|
11 #include <boost/config.hpp> // SFINAE.
|
Chris@16
|
12 #include <boost/iostreams/concepts.hpp>
|
Chris@16
|
13 #include <boost/iostreams/categories.hpp>
|
Chris@16
|
14 #include <boost/iostreams/detail/adapter/non_blocking_adapter.hpp>
|
Chris@16
|
15 #include <boost/iostreams/detail/call_traits.hpp>
|
Chris@16
|
16 #include <boost/iostreams/detail/char_traits.hpp>
|
Chris@16
|
17 #include <boost/iostreams/detail/dispatch.hpp>
|
Chris@16
|
18 #include <boost/iostreams/detail/error.hpp>
|
Chris@16
|
19 #include <boost/iostreams/detail/streambuf.hpp> // pubsync.
|
Chris@16
|
20 #include <boost/iostreams/detail/config/unreachable_return.hpp>
|
Chris@16
|
21 #include <boost/iostreams/device/null.hpp>
|
Chris@16
|
22 #include <boost/iostreams/traits.hpp>
|
Chris@16
|
23 #include <boost/iostreams/operations.hpp>
|
Chris@16
|
24 #include <boost/mpl/if.hpp>
|
Chris@16
|
25 #include <boost/static_assert.hpp>
|
Chris@16
|
26 #include <boost/throw_exception.hpp>
|
Chris@16
|
27
|
Chris@16
|
28 // Must come last.
|
Chris@16
|
29 #include <boost/iostreams/detail/config/disable_warnings.hpp> // MSVC.
|
Chris@16
|
30
|
Chris@16
|
31
|
Chris@16
|
32 namespace boost { namespace iostreams { namespace detail {
|
Chris@16
|
33
|
Chris@16
|
34 template<typename Category> struct device_wrapper_impl;
|
Chris@16
|
35 template<typename Category> struct flt_wrapper_impl;
|
Chris@16
|
36
|
Chris@16
|
37 template<typename T>
|
Chris@16
|
38 class concept_adapter {
|
Chris@16
|
39 private:
|
Chris@16
|
40 typedef typename detail::value_type<T>::type value_type;
|
Chris@16
|
41 typedef typename dispatch<T, input, output>::type input_tag;
|
Chris@16
|
42 typedef typename dispatch<T, output, input>::type output_tag;
|
Chris@16
|
43 typedef typename
|
Chris@16
|
44 mpl::if_<
|
Chris@16
|
45 is_device<T>,
|
Chris@16
|
46 device_wrapper_impl<input_tag>,
|
Chris@16
|
47 flt_wrapper_impl<input_tag>
|
Chris@16
|
48 >::type input_impl;
|
Chris@16
|
49 typedef typename
|
Chris@16
|
50 mpl::if_<
|
Chris@16
|
51 is_device<T>,
|
Chris@16
|
52 device_wrapper_impl<output_tag>,
|
Chris@16
|
53 flt_wrapper_impl<output_tag>
|
Chris@16
|
54 >::type output_impl;
|
Chris@16
|
55 typedef typename
|
Chris@16
|
56 mpl::if_<
|
Chris@16
|
57 is_device<T>,
|
Chris@16
|
58 device_wrapper_impl<any_tag>,
|
Chris@16
|
59 flt_wrapper_impl<any_tag>
|
Chris@16
|
60 >::type any_impl;
|
Chris@16
|
61 public:
|
Chris@16
|
62 typedef typename char_type_of<T>::type char_type;
|
Chris@16
|
63 typedef typename category_of<T>::type category;
|
Chris@16
|
64
|
Chris@16
|
65 explicit concept_adapter(const reference_wrapper<T>& ref) : t_(ref.get())
|
Chris@16
|
66 { BOOST_STATIC_ASSERT(is_std_io<T>::value); }
|
Chris@16
|
67 explicit concept_adapter(const T& t) : t_(t)
|
Chris@16
|
68 { BOOST_STATIC_ASSERT(!is_std_io<T>::value); }
|
Chris@16
|
69
|
Chris@16
|
70 T& operator*() { return t_; }
|
Chris@16
|
71 T* operator->() { return &t_; }
|
Chris@16
|
72
|
Chris@16
|
73 std::streamsize read(char_type* s, std::streamsize n)
|
Chris@16
|
74 { return this->read(s, n, (basic_null_source<char_type>*) 0); }
|
Chris@16
|
75
|
Chris@16
|
76 template<typename Source>
|
Chris@16
|
77 std::streamsize read(char_type* s, std::streamsize n, Source* src)
|
Chris@16
|
78 { return input_impl::read(t_, src, s, n); }
|
Chris@16
|
79
|
Chris@16
|
80 std::streamsize write(const char_type* s, std::streamsize n)
|
Chris@16
|
81 { return this->write(s, n, (basic_null_sink<char_type>*) 0); }
|
Chris@16
|
82
|
Chris@16
|
83 template<typename Sink>
|
Chris@16
|
84 std::streamsize write(const char_type* s, std::streamsize n, Sink* snk)
|
Chris@16
|
85 { return output_impl::write(t_, snk, s, n); }
|
Chris@16
|
86
|
Chris@16
|
87 std::streampos seek( stream_offset off, BOOST_IOS::seekdir way,
|
Chris@16
|
88 BOOST_IOS::openmode which )
|
Chris@16
|
89 {
|
Chris@16
|
90 return this->seek( off, way, which,
|
Chris@16
|
91 (basic_null_device<char_type, seekable>*) 0);
|
Chris@16
|
92 }
|
Chris@16
|
93
|
Chris@16
|
94 template<typename Device>
|
Chris@16
|
95 std::streampos seek( stream_offset off, BOOST_IOS::seekdir way,
|
Chris@16
|
96 BOOST_IOS::openmode which, Device* dev )
|
Chris@16
|
97 { return any_impl::seek(t_, dev, off, way, which); }
|
Chris@16
|
98
|
Chris@16
|
99 void close(BOOST_IOS::openmode which)
|
Chris@16
|
100 { this->close(which, (basic_null_device<char_type, seekable>*) 0); }
|
Chris@16
|
101
|
Chris@16
|
102 template<typename Device>
|
Chris@16
|
103 void close(BOOST_IOS::openmode which, Device* dev)
|
Chris@16
|
104 { any_impl::close(t_, dev, which); }
|
Chris@16
|
105
|
Chris@16
|
106 template<typename Device>
|
Chris@16
|
107 bool flush( Device* dev )
|
Chris@16
|
108 {
|
Chris@16
|
109 bool result = any_impl::flush(t_, dev);
|
Chris@16
|
110 if (dev && dev->BOOST_IOSTREAMS_PUBSYNC() == -1)
|
Chris@16
|
111 result = false;
|
Chris@16
|
112 return result;
|
Chris@16
|
113 }
|
Chris@16
|
114
|
Chris@16
|
115 template<typename Locale> // Avoid dependency on <locale>
|
Chris@16
|
116 void imbue(const Locale& loc) { iostreams::imbue(t_, loc); }
|
Chris@16
|
117
|
Chris@16
|
118 std::streamsize optimal_buffer_size() const
|
Chris@16
|
119 { return iostreams::optimal_buffer_size(t_); }
|
Chris@16
|
120 public:
|
Chris@16
|
121 concept_adapter& operator=(const concept_adapter&);
|
Chris@16
|
122 value_type t_;
|
Chris@16
|
123 };
|
Chris@16
|
124
|
Chris@16
|
125 //------------------Specializations of device_wrapper_impl--------------------//
|
Chris@16
|
126
|
Chris@16
|
127 template<>
|
Chris@16
|
128 struct device_wrapper_impl<any_tag> {
|
Chris@16
|
129 template<typename Device, typename Dummy>
|
Chris@16
|
130 static std::streampos
|
Chris@16
|
131 seek( Device& dev, Dummy*, stream_offset off,
|
Chris@16
|
132 BOOST_IOS::seekdir way, BOOST_IOS::openmode which )
|
Chris@16
|
133 {
|
Chris@16
|
134 typedef typename category_of<Device>::type category;
|
Chris@16
|
135 return seek(dev, off, way, which, category());
|
Chris@16
|
136 }
|
Chris@16
|
137
|
Chris@16
|
138 template<typename Device>
|
Chris@16
|
139 static std::streampos
|
Chris@16
|
140 seek( Device&, stream_offset, BOOST_IOS::seekdir,
|
Chris@16
|
141 BOOST_IOS::openmode, any_tag )
|
Chris@16
|
142 {
|
Chris@16
|
143 boost::throw_exception(cant_seek());
|
Chris@16
|
144 BOOST_IOSTREAMS_UNREACHABLE_RETURN(0)
|
Chris@16
|
145 }
|
Chris@16
|
146
|
Chris@16
|
147 template<typename Device>
|
Chris@16
|
148 static std::streampos
|
Chris@16
|
149 seek( Device& dev, stream_offset off,
|
Chris@16
|
150 BOOST_IOS::seekdir way, BOOST_IOS::openmode which,
|
Chris@16
|
151 random_access )
|
Chris@16
|
152 {
|
Chris@16
|
153 return iostreams::seek(dev, off, way, which);
|
Chris@16
|
154 }
|
Chris@16
|
155
|
Chris@16
|
156 template<typename Device, typename Dummy>
|
Chris@16
|
157 static void close(Device& dev, Dummy*, BOOST_IOS::openmode which)
|
Chris@16
|
158 { iostreams::close(dev, which); }
|
Chris@16
|
159
|
Chris@16
|
160 template<typename Device, typename Dummy>
|
Chris@16
|
161 static bool flush(Device& dev, Dummy*)
|
Chris@16
|
162 { return iostreams::flush(dev); }
|
Chris@16
|
163 };
|
Chris@16
|
164
|
Chris@16
|
165
|
Chris@16
|
166 template<>
|
Chris@16
|
167 struct device_wrapper_impl<input> : device_wrapper_impl<any_tag> {
|
Chris@16
|
168 template<typename Device, typename Dummy>
|
Chris@16
|
169 static std::streamsize
|
Chris@16
|
170 read( Device& dev, Dummy*, typename char_type_of<Device>::type* s,
|
Chris@16
|
171 std::streamsize n )
|
Chris@16
|
172 { return iostreams::read(dev, s, n); }
|
Chris@16
|
173
|
Chris@16
|
174 template<typename Device, typename Dummy>
|
Chris@16
|
175 static std::streamsize
|
Chris@16
|
176 write( Device&, Dummy*, const typename char_type_of<Device>::type*,
|
Chris@16
|
177 std::streamsize )
|
Chris@16
|
178 { boost::throw_exception(cant_write());
|
Chris@16
|
179 BOOST_IOSTREAMS_UNREACHABLE_RETURN(0) }
|
Chris@16
|
180 };
|
Chris@16
|
181
|
Chris@16
|
182 template<>
|
Chris@16
|
183 struct device_wrapper_impl<output> {
|
Chris@16
|
184 template<typename Device, typename Dummy>
|
Chris@16
|
185 static std::streamsize
|
Chris@16
|
186 read(Device&, Dummy*, typename char_type_of<Device>::type*, std::streamsize)
|
Chris@16
|
187 { boost::throw_exception(cant_read());
|
Chris@16
|
188 BOOST_IOSTREAMS_UNREACHABLE_RETURN(0) }
|
Chris@16
|
189
|
Chris@16
|
190 template<typename Device, typename Dummy>
|
Chris@16
|
191 static std::streamsize
|
Chris@16
|
192 write( Device& dev, Dummy*, const typename char_type_of<Device>::type* s,
|
Chris@16
|
193 std::streamsize n )
|
Chris@16
|
194 { return iostreams::write(dev, s, n); }
|
Chris@16
|
195 };
|
Chris@16
|
196
|
Chris@16
|
197 //------------------Specializations of flt_wrapper_impl--------------------//
|
Chris@16
|
198
|
Chris@16
|
199 template<>
|
Chris@16
|
200 struct flt_wrapper_impl<any_tag> {
|
Chris@16
|
201 template<typename Filter, typename Device>
|
Chris@16
|
202 static std::streampos
|
Chris@16
|
203 seek( Filter& f, Device* dev, stream_offset off,
|
Chris@16
|
204 BOOST_IOS::seekdir way, BOOST_IOS::openmode which )
|
Chris@16
|
205 {
|
Chris@16
|
206 typedef typename category_of<Filter>::type category;
|
Chris@16
|
207 return seek(f, dev, off, way, which, category());
|
Chris@16
|
208 }
|
Chris@16
|
209
|
Chris@16
|
210 template<typename Filter, typename Device>
|
Chris@16
|
211 static std::streampos
|
Chris@16
|
212 seek( Filter&, Device*, stream_offset,
|
Chris@16
|
213 BOOST_IOS::seekdir, BOOST_IOS::openmode, any_tag )
|
Chris@16
|
214 { boost::throw_exception(cant_seek());
|
Chris@16
|
215 BOOST_IOSTREAMS_UNREACHABLE_RETURN(0) }
|
Chris@16
|
216
|
Chris@16
|
217 template<typename Filter, typename Device>
|
Chris@16
|
218 static std::streampos
|
Chris@16
|
219 seek( Filter& f, Device* dev, stream_offset off,
|
Chris@16
|
220 BOOST_IOS::seekdir way, BOOST_IOS::openmode which,
|
Chris@16
|
221 random_access tag )
|
Chris@16
|
222 {
|
Chris@16
|
223 typedef typename category_of<Filter>::type category;
|
Chris@16
|
224 return seek(f, dev, off, way, which, tag, category());
|
Chris@16
|
225 }
|
Chris@16
|
226
|
Chris@16
|
227 template<typename Filter, typename Device>
|
Chris@16
|
228 static std::streampos
|
Chris@16
|
229 seek( Filter& f, Device* dev, stream_offset off,
|
Chris@16
|
230 BOOST_IOS::seekdir way, BOOST_IOS::openmode,
|
Chris@16
|
231 random_access, any_tag )
|
Chris@16
|
232 { return f.seek(*dev, off, way); }
|
Chris@16
|
233
|
Chris@16
|
234 template<typename Filter, typename Device>
|
Chris@16
|
235 static std::streampos
|
Chris@16
|
236 seek( Filter& f, Device* dev, stream_offset off,
|
Chris@16
|
237 BOOST_IOS::seekdir way, BOOST_IOS::openmode which,
|
Chris@16
|
238 random_access, two_sequence )
|
Chris@16
|
239 { return f.seek(*dev, off, way, which); }
|
Chris@16
|
240
|
Chris@16
|
241 template<typename Filter, typename Device>
|
Chris@16
|
242 static void close(Filter& f, Device* dev, BOOST_IOS::openmode which)
|
Chris@16
|
243 { iostreams::close(f, *dev, which); }
|
Chris@16
|
244
|
Chris@16
|
245 template<typename Filter, typename Device>
|
Chris@16
|
246 static bool flush(Filter& f, Device* dev)
|
Chris@16
|
247 { return iostreams::flush(f, *dev); }
|
Chris@16
|
248 };
|
Chris@16
|
249
|
Chris@16
|
250 template<>
|
Chris@16
|
251 struct flt_wrapper_impl<input> {
|
Chris@16
|
252 template<typename Filter, typename Source>
|
Chris@16
|
253 static std::streamsize
|
Chris@16
|
254 read( Filter& f, Source* src, typename char_type_of<Filter>::type* s,
|
Chris@16
|
255 std::streamsize n )
|
Chris@16
|
256 { return iostreams::read(f, *src, s, n); }
|
Chris@16
|
257
|
Chris@16
|
258 template<typename Filter, typename Sink>
|
Chris@16
|
259 static std::streamsize
|
Chris@16
|
260 write( Filter&, Sink*, const typename char_type_of<Filter>::type*,
|
Chris@16
|
261 std::streamsize )
|
Chris@16
|
262 { boost::throw_exception(cant_write());
|
Chris@16
|
263 BOOST_IOSTREAMS_UNREACHABLE_RETURN(0) }
|
Chris@16
|
264 };
|
Chris@16
|
265
|
Chris@16
|
266 template<>
|
Chris@16
|
267 struct flt_wrapper_impl<output> {
|
Chris@16
|
268 template<typename Filter, typename Source>
|
Chris@16
|
269 static std::streamsize
|
Chris@16
|
270 read(Filter&, Source*, typename char_type_of<Filter>::type*,std::streamsize)
|
Chris@16
|
271 { boost::throw_exception(cant_read());
|
Chris@16
|
272 BOOST_IOSTREAMS_UNREACHABLE_RETURN(0) }
|
Chris@16
|
273
|
Chris@16
|
274 template<typename Filter, typename Sink>
|
Chris@16
|
275 static std::streamsize
|
Chris@16
|
276 write( Filter& f, Sink* snk, const typename char_type_of<Filter>::type* s,
|
Chris@16
|
277 std::streamsize n )
|
Chris@16
|
278 { return iostreams::write(f, *snk, s, n); }
|
Chris@16
|
279 };
|
Chris@16
|
280
|
Chris@16
|
281 //----------------------------------------------------------------------------//
|
Chris@16
|
282
|
Chris@16
|
283 } } } // End namespaces detail, iostreams, boost.
|
Chris@16
|
284
|
Chris@16
|
285 #include <boost/iostreams/detail/config/enable_warnings.hpp> // MSVC.
|
Chris@16
|
286
|
Chris@16
|
287 #endif // #ifndef BOOST_IOSTREAMS_DETAIL_CONCEPT_ADAPTER_HPP_INCLUDED
|