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