Ugly, not-to-be-pushed sucking in of all of Boost to get windows to work.
[dyninst.git] / external / boost / iostreams / detail / adapter / concept_adapter.hpp
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
28 namespace boost { namespace iostreams { namespace detail {
29
30 template<typename Category> struct device_wrapper_impl;
31 template<typename Category> struct flt_wrapper_impl;
32
33 template<typename T>
34 class concept_adapter {
35 private:
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;
57 public:
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_); }
116 public:
117     value_type t_;
118 };
119
120 //------------------Specializations of device_wrapper_impl--------------------//
121
122 template<>
123 struct 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
160 template<>
161 struct 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
175 template<>
176 struct 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
191 template<>
192 struct 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
241 template<>
242 struct 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
256 template<>
257 struct 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