source: NonGTP/Boost/boost/iostreams/detail/adapter/concept_adapter.hpp @ 857

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