Ugly, not-to-be-pushed sucking in of all of Boost to get windows to work.
[dyninst.git] / external / boost / iostreams / read.hpp
1 // (C) Copyright Jonathan Turkanis 2005.
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_READ_HPP_INCLUDED
8 #define BOOST_IOSTREAMS_READ_HPP_INCLUDED
9
10 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
11 # pragma once
12 #endif
13
14 #include <boost/config.hpp>  // DEDUCED_TYPENAME, MSVC.
15 #include <boost/detail/workaround.hpp>
16 #include <boost/iostreams/char_traits.hpp>
17 #include <boost/iostreams/detail/char_traits.hpp>
18 #include <boost/iostreams/detail/dispatch.hpp>
19 #include <boost/iostreams/detail/ios.hpp>  // streamsize.
20 #include <boost/iostreams/detail/streambuf.hpp>
21 #include <boost/iostreams/detail/wrap_unwrap.hpp>
22 #include <boost/iostreams/operations_fwd.hpp>
23 #include <boost/mpl/if.hpp>
24
25 // Must come last.
26 #include <boost/iostreams/detail/config/disable_warnings.hpp>
27
28 #if BOOST_WORKAROUND(BOOST_MSVC, < 1300) //-----------------------------------//
29 # include <boost/iostreams/detail/vc6/read.hpp>
30 #else // #if BOOST_WORKAROUND(BOOST_MSVC, < 1300) //--------------------------//
31
32 namespace boost { namespace iostreams {
33
34 namespace detail {
35
36 template<typename T>
37 struct read_device_impl;
38
39 template<typename T>
40 struct read_filter_impl;
41
42 } // End namespace detail.
43
44 template<typename T>
45 typename int_type_of<T>::type get(T& t)
46 { return detail::read_device_impl<T>::get(detail::unwrap(t)); }
47
48 template<typename T>
49 inline std::streamsize
50 read(T& t, typename char_type_of<T>::type* s, std::streamsize n)
51 { return detail::read_device_impl<T>::read(detail::unwrap(t), s, n); }
52
53 template<typename T, typename Source>
54 std::streamsize
55 read(T& t, Source& src, typename char_type_of<T>::type* s, std::streamsize n)
56 { return detail::read_filter_impl<T>::read(detail::unwrap(t), src, s, n); }
57
58 template<typename T>
59 bool putback(T& t, typename char_type_of<T>::type c)
60 { return detail::read_device_impl<T>::putback(detail::unwrap(t), c); }
61
62 //----------------------------------------------------------------------------//
63
64 namespace detail {
65
66 // Helper function for adding -1 as EOF indicator.
67 inline std::streamsize check_eof(std::streamsize n) { return n != 0 ? n : -1; }
68
69 // Helper templates for reading from streambufs.
70 template<bool IsLinked>
71 struct true_eof_impl;
72
73 template<>
74 struct true_eof_impl<true> {
75     template<typename T>
76     static bool true_eof(T& t) { return t.true_eof(); }
77 };
78
79 template<>
80 struct true_eof_impl<false> {
81     template<typename T>
82     static bool true_eof(T& t) { return true; }
83 };
84
85 template<typename T>
86 inline bool true_eof(T& t)
87 {
88     const bool linked = is_linked<T>::value;
89     return true_eof_impl<linked>::true_eof(t);
90 }
91
92 //------------------Definition of read_device_impl----------------------------//
93
94 template<typename T>
95 struct read_device_impl
96     : mpl::if_<
97           detail::is_custom<T>,
98           operations<T>,
99           read_device_impl<
100               BOOST_DEDUCED_TYPENAME
101               detail::dispatch<
102                   T, istream_tag, streambuf_tag, input
103               >::type
104           >
105       >::type
106     { };
107
108 template<>
109 struct read_device_impl<istream_tag> {
110     template<typename T>
111     static typename int_type_of<T>::type get(T& t)
112     { return t.get(); }
113
114     template<typename T>
115     static std::streamsize
116     read(T& t, typename char_type_of<T>::type* s, std::streamsize n)
117     { return check_eof(t.rdbuf()->sgetn(s, n)); }
118
119     template<typename T>
120     static bool putback(T& t, typename char_type_of<T>::type c)
121     {
122         typedef typename char_type_of<T>::type          char_type;
123         typedef BOOST_IOSTREAMS_CHAR_TRAITS(char_type)  traits_type;
124         return !traits_type::eq_int_type( t.rdbuf()->sputbackc(c),
125                                           traits_type::eof() );
126     }
127 };
128
129 template<>
130 struct read_device_impl<streambuf_tag> {
131     template<typename T>
132     static typename int_type_of<T>::type
133     get(T& t)
134     {   // gcc 2.95 needs namespace qualification for char_traits.
135         typedef typename char_type_of<T>::type     char_type;
136         typedef iostreams::char_traits<char_type>  traits_type;
137         typename int_type_of<T>::type c;
138         return !traits_type::is_eof(c = t.sbumpc()) ||
139                 detail::true_eof(t)
140                     ?
141                 c : traits_type::would_block();
142     }
143
144     template<typename T>
145     static std::streamsize
146     read(T& t, typename char_type_of<T>::type* s, std::streamsize n)
147     {
148         std::streamsize amt;
149         return (amt = t.sgetn(s, n)) != 0 ?
150             amt :
151             detail::true_eof(t) ?
152                 -1 :
153                 0;
154     }
155
156     template<typename T>
157     static bool putback(T& t, typename char_type_of<T>::type c)
158     {   // gcc 2.95 needs namespace qualification for char_traits.
159         typedef typename char_type_of<T>::type     char_type;
160         typedef iostreams::char_traits<char_type>  traits_type;
161         return !traits_type::is_eof(t.sputbackc(c));
162     }
163 };
164
165 template<>
166 struct read_device_impl<input> {
167     template<typename T>
168     static typename int_type_of<T>::type
169     get(T& t)
170     {   // gcc 2.95 needs namespace qualification for char_traits.
171         typedef typename char_type_of<T>::type     char_type;
172         typedef iostreams::char_traits<char_type>  traits_type;
173         char_type c;
174         std::streamsize amt;
175         return (amt = t.read(&c, 1)) == 1 ?
176             traits_type::to_int_type(c) :
177             amt == -1 ?
178                 traits_type::eof() :
179                 traits_type::would_block();
180     }
181
182     template<typename T>
183     static std::streamsize
184     read(T& t, typename char_type_of<T>::type* s, std::streamsize n)
185     { return t.read(s, n); }
186
187     template<typename T>
188     static bool putback(T& t, typename char_type_of<T>::type c)
189     {   // T must be Peekable.
190         return t.putback(c);
191     }
192 };
193
194 //------------------Definition of read_filter_impl----------------------------//
195
196 template<typename T>
197 struct read_filter_impl
198     : mpl::if_<
199           detail::is_custom<T>,
200           operations<T>,
201           read_filter_impl<
202               BOOST_DEDUCED_TYPENAME
203               detail::dispatch<
204                   T, multichar_tag, any_tag
205               >::type
206           >
207       >::type
208     { };
209
210 template<>
211 struct read_filter_impl<multichar_tag> {
212     template<typename T, typename Source>
213     static std::streamsize read
214        (T& t, Source& src, typename char_type_of<T>::type* s, std::streamsize n)
215     { return t.read(src, s, n); }
216 };
217
218 template<>
219 struct read_filter_impl<any_tag> {
220     template<typename T, typename Source>
221     static std::streamsize read
222        (T& t, Source& src, typename char_type_of<T>::type* s, std::streamsize n)
223     {   // gcc 2.95 needs namespace qualification for char_traits.
224         typedef typename char_type_of<T>::type     char_type;
225         typedef iostreams::char_traits<char_type>  traits_type;
226         for (std::streamsize off = 0; off < n; ++off) {
227             typename traits_type::int_type c = t.get(src);
228             if (traits_type::is_eof(c))
229                 return check_eof(off);
230             if (traits_type::would_block(c))
231                 return off;
232             s[off] = traits_type::to_char_type(c);
233         }
234         return n;
235     }
236 };
237
238 } // End namespace detail.
239
240 } } // End namespaces iostreams, boost.
241
242 #endif // #if BOOST_WORKAROUND(BOOST_MSVC, < 1300) //-------------------------//
243
244 #include <boost/iostreams/detail/config/enable_warnings.hpp>
245
246 #endif // #ifndef BOOST_IOSTREAMS_READ_HPP_INCLUDED