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.)
6 // See http://www.boost.org/libs/iostreams for documentation.
8 #ifndef BOOST_IOSTREAMS_DETAIL_CONCEPT_ADAPTER_HPP_INCLUDED
9 #define BOOST_IOSTREAMS_DETAIL_CONCEPT_ADAPTER_HPP_INCLUDED
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/device/null.hpp>
21 #include <boost/iostreams/traits.hpp>
22 #include <boost/iostreams/operations.hpp>
23 #include <boost/mpl/if.hpp>
24 #include <boost/static_assert.hpp>
27 #include <boost/iostreams/detail/config/disable_warnings.hpp> // MSVC.
29 namespace boost
{ namespace iostreams
{ namespace detail
{
31 template<typename Category
> struct device_wrapper_impl
;
32 template<typename Category
> struct flt_wrapper_impl
;
35 class concept_adapter
{
37 typedef typename
detail::value_type
<T
>::type value_type
;
38 typedef typename dispatch
<T
, input
, output
>::type input_tag
;
39 typedef typename dispatch
<T
, output
, input
>::type output_tag
;
43 device_wrapper_impl
<input_tag
>,
44 flt_wrapper_impl
<input_tag
>
49 device_wrapper_impl
<output_tag
>,
50 flt_wrapper_impl
<output_tag
>
55 device_wrapper_impl
<any_tag
>,
56 flt_wrapper_impl
<any_tag
>
59 typedef typename char_type_of
<T
>::type char_type
;
60 typedef typename category_of
<T
>::type category
;
62 explicit concept_adapter(const reference_wrapper
<T
>& ref
) : t_(ref
.get())
63 { BOOST_STATIC_ASSERT(is_std_io
<T
>::value
); }
64 explicit concept_adapter(const T
& t
) : t_(t
)
65 { BOOST_STATIC_ASSERT(!is_std_io
<T
>::value
); }
67 T
& operator*() { return t_
; }
68 T
* operator->() { return &t_
; }
70 std::streamsize
read(char_type
* s
, std::streamsize n
)
71 { return this->read(s
, n
, (basic_null_source
<char_type
>*) 0); }
73 template<typename Source
>
74 std::streamsize
read(char_type
* s
, std::streamsize n
, Source
* src
)
75 { return input_impl::read(t_
, src
, s
, n
); }
77 std::streamsize
write(const char_type
* s
, std::streamsize n
)
78 { return this->write(s
, n
, (basic_null_sink
<char_type
>*) 0); }
80 template<typename Sink
>
81 std::streamsize
write(const char_type
* s
, std::streamsize n
, Sink
* snk
)
82 { return output_impl::write(t_
, snk
, s
, n
); }
84 std::streampos
seek( stream_offset off
, BOOST_IOS::seekdir way
,
85 BOOST_IOS::openmode which
)
87 return this->seek( off
, way
, which
,
88 (basic_null_device
<char_type
, seekable
>*) 0);
91 template<typename Device
>
92 std::streampos
seek( stream_offset off
, BOOST_IOS::seekdir way
,
93 BOOST_IOS::openmode which
, Device
* dev
)
94 { return any_impl::seek(t_
, dev
, off
, way
, which
); }
96 void close(BOOST_IOS::openmode which
)
97 { this->close(which
, (basic_null_device
<char_type
, seekable
>*) 0); }
99 template<typename Device
>
100 void close(BOOST_IOS::openmode which
, Device
* dev
)
101 { any_impl::close(t_
, dev
, which
); }
103 bool flush( BOOST_IOSTREAMS_BASIC_STREAMBUF(char_type
,
104 BOOST_IOSTREAMS_CHAR_TRAITS(char_type
))* sb
)
106 bool result
= any_impl::flush(t_
, sb
);
107 if (sb
&& sb
->BOOST_IOSTREAMS_PUBSYNC() == -1)
112 template<typename Locale
> // Avoid dependency on <locale>
113 void imbue(const Locale
& loc
) { iostreams::imbue(t_
, loc
); }
115 std::streamsize
optimal_buffer_size() const
116 { return iostreams::optimal_buffer_size(t_
); }
118 concept_adapter
& operator=(const concept_adapter
&);
122 //------------------Specializations of device_wrapper_impl--------------------//
125 struct device_wrapper_impl
<any_tag
> {
126 template<typename Device
, typename Dummy
>
127 static std::streampos
128 seek( Device
& dev
, Dummy
*, stream_offset off
,
129 BOOST_IOS::seekdir way
, BOOST_IOS::openmode which
)
131 typedef typename category_of
<Device
>::type category
;
132 return seek(dev
, off
, way
, which
, category());
135 template<typename Device
>
136 static std::streampos
137 seek( Device
&, stream_offset
, BOOST_IOS::seekdir
,
138 BOOST_IOS::openmode
, any_tag
)
143 template<typename Device
>
144 static std::streampos
145 seek( Device
& dev
, stream_offset off
,
146 BOOST_IOS::seekdir way
, BOOST_IOS::openmode which
,
149 return iostreams::seek(dev
, off
, way
, which
);
152 template<typename Device
, typename Dummy
>
153 static void close(Device
& dev
, Dummy
*, BOOST_IOS::openmode which
)
154 { iostreams::close(dev
, which
); }
156 template<typename Device
, typename Dummy
>
157 static bool flush(Device
& dev
, Dummy
*)
158 { return iostreams::flush(dev
); }
163 struct device_wrapper_impl
<input
> : device_wrapper_impl
<any_tag
> {
164 template<typename Device
, typename Dummy
>
165 static std::streamsize
166 read( Device
& dev
, Dummy
*, typename char_type_of
<Device
>::type
* s
,
168 { return iostreams::read(dev
, s
, n
); }
170 template<typename Device
, typename Dummy
>
171 static std::streamsize
172 write( Device
&, Dummy
*, const typename char_type_of
<Device
>::type
*,
174 { throw cant_write(); }
178 struct device_wrapper_impl
<output
> {
179 template<typename Device
, typename Dummy
>
180 static std::streamsize
181 read(Device
&, Dummy
*, typename char_type_of
<Device
>::type
*, std::streamsize
)
182 { throw cant_read(); }
184 template<typename Device
, typename Dummy
>
185 static std::streamsize
186 write( Device
& dev
, Dummy
*, const typename char_type_of
<Device
>::type
* s
,
188 { return iostreams::write(dev
, s
, n
); }
191 //------------------Specializations of flt_wrapper_impl--------------------//
194 struct flt_wrapper_impl
<any_tag
> {
195 template<typename Filter
, typename Device
>
196 static std::streampos
197 seek( Filter
& f
, Device
* dev
, stream_offset off
,
198 BOOST_IOS::seekdir way
, BOOST_IOS::openmode which
)
200 typedef typename category_of
<Filter
>::type category
;
201 return seek(f
, dev
, off
, way
, which
, category());
204 template<typename Filter
, typename Device
>
205 static std::streampos
206 seek( Filter
&, Device
*, stream_offset
,
207 BOOST_IOS::seekdir
, BOOST_IOS::openmode
, any_tag
)
208 { throw cant_seek(); }
210 template<typename Filter
, typename Device
>
211 static std::streampos
212 seek( Filter
& f
, Device
* dev
, stream_offset off
,
213 BOOST_IOS::seekdir way
, BOOST_IOS::openmode which
,
216 typedef typename category_of
<Filter
>::type category
;
217 return seek(f
, dev
, off
, way
, which
, tag
, category());
220 template<typename Filter
, typename Device
>
221 static std::streampos
222 seek( Filter
& f
, Device
* dev
, stream_offset off
,
223 BOOST_IOS::seekdir way
, BOOST_IOS::openmode
,
224 random_access
, any_tag
)
225 { return f
.seek(*dev
, off
, way
); }
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 which
,
231 random_access
, two_sequence
)
232 { return f
.seek(*dev
, off
, way
, which
); }
234 template<typename Filter
, typename Device
>
235 static void close(Filter
& f
, Device
* dev
, BOOST_IOS::openmode which
)
236 { iostreams::close(f
, *dev
, which
); }
238 template<typename Filter
, typename Device
>
239 static bool flush(Filter
& f
, Device
* dev
)
240 { return iostreams::flush(f
, *dev
); }
244 struct flt_wrapper_impl
<input
> {
245 template<typename Filter
, typename Source
>
246 static std::streamsize
247 read( Filter
& f
, Source
* src
, typename char_type_of
<Filter
>::type
* s
,
249 { return iostreams::read(f
, *src
, s
, n
); }
251 template<typename Filter
, typename Sink
>
252 static std::streamsize
253 write( Filter
&, Sink
*, const typename char_type_of
<Filter
>::type
*,
255 { throw cant_write(); }
259 struct flt_wrapper_impl
<output
> {
260 template<typename Filter
, typename Source
>
261 static std::streamsize
262 read(Filter
&, Source
*, typename char_type_of
<Filter
>::type
*,std::streamsize
)
263 { throw cant_read(); }
265 template<typename Filter
, typename Sink
>
266 static std::streamsize
267 write( Filter
& f
, Sink
* snk
, const typename char_type_of
<Filter
>::type
* s
,
269 { return iostreams::write(f
, *snk
, s
, n
); }
272 //----------------------------------------------------------------------------//
274 } } } // End namespaces detail, iostreams, boost.
276 #include <boost/iostreams/detail/config/enable_warnings.hpp> // MSVC.
278 #endif // #ifndef BOOST_IOSTREAMS_DETAIL_CONCEPT_ADAPTER_HPP_INCLUDED