|
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 // |
|
8 // Contains metafunctions char_type_of, category_of and mode_of used for |
|
9 // deducing the i/o category and i/o mode of a model of Filter or Device. |
|
10 // |
|
11 // Also contains several utility metafunctions, functions and macros. |
|
12 // |
|
13 |
|
14 #ifndef BOOST_IOSTREAMS_IO_TRAITS_HPP_INCLUDED |
|
15 #define BOOST_IOSTREAMS_IO_TRAITS_HPP_INCLUDED |
|
16 |
|
17 #if defined(_MSC_VER) && (_MSC_VER >= 1020) |
|
18 # pragma once |
|
19 #endif |
|
20 |
|
21 #include <iosfwd> // stream types, char_traits. |
|
22 #include <boost/config.hpp> // partial spec, deduced typename. |
|
23 #include <boost/iostreams/categories.hpp> |
|
24 #include <boost/iostreams/detail/bool_trait_def.hpp> |
|
25 #include <boost/iostreams/detail/config/wide_streams.hpp> |
|
26 #include <boost/iostreams/detail/is_iterator_range.hpp> |
|
27 #include <boost/iostreams/detail/select.hpp> |
|
28 #include <boost/iostreams/detail/select_by_size.hpp> |
|
29 #include <boost/iostreams/detail/wrap_unwrap.hpp> |
|
30 #include <boost/iostreams/traits_fwd.hpp> |
|
31 #include <boost/mpl/bool.hpp> |
|
32 #include <boost/mpl/eval_if.hpp> |
|
33 #include <boost/mpl/identity.hpp> |
|
34 #include <boost/mpl/int.hpp> |
|
35 #include <boost/mpl/or.hpp> |
|
36 #include <boost/range/iterator_range.hpp> |
|
37 #include <boost/range/value_type.hpp> |
|
38 #include <boost/type_traits/is_convertible.hpp> |
|
39 |
|
40 namespace boost { namespace iostreams { |
|
41 |
|
42 //------------------Definitions of predicates for streams and stream buffers--// |
|
43 |
|
44 #ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //--------------------------------// |
|
45 |
|
46 BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_istream, std::basic_istream, 2) |
|
47 BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_ostream, std::basic_ostream, 2) |
|
48 BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_iostream, std::basic_iostream, 2) |
|
49 BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_streambuf, std::basic_streambuf, 2) |
|
50 BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_stringstream, std::basic_stringstream, 3) |
|
51 BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_stringbuf, std::basic_stringbuf, 3) |
|
52 |
|
53 #else // #ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //-----------------------// |
|
54 |
|
55 BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_istream, std::istream, 0) |
|
56 BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_ostream, std::ostream, 0) |
|
57 BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_iostream, std::iostream, 0) |
|
58 BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_streambuf, std::streambuf, 0) |
|
59 |
|
60 #endif // #ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //----------------------// |
|
61 |
|
62 template<typename T> |
|
63 struct is_std_io |
|
64 : mpl::or_< is_istream<T>, is_ostream<T>, is_streambuf<T> > |
|
65 { }; |
|
66 |
|
67 namespace detail { |
|
68 |
|
69 template<typename T, typename Tr> |
|
70 class linked_streambuf; |
|
71 |
|
72 BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_linked, linked_streambuf, 2) |
|
73 |
|
74 } // End namespace detail. |
|
75 |
|
76 //------------------Definitions of char_type_of-------------------------------// |
|
77 |
|
78 namespace detail { |
|
79 |
|
80 template<typename T> |
|
81 struct member_char_type { typedef typename T::char_type type; }; |
|
82 |
|
83 } // End namespace detail. |
|
84 |
|
85 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION //---------------------------// |
|
86 # ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //-------------------------------// |
|
87 |
|
88 template<typename T> |
|
89 struct char_type_of |
|
90 : detail::member_char_type< |
|
91 typename detail::unwrapped_type<T>::type |
|
92 > |
|
93 { }; |
|
94 |
|
95 # else // # ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //---------------------// |
|
96 |
|
97 template<typename T> |
|
98 struct char_type_of { |
|
99 typedef typename detail::unwrapped_type<T>::type U; |
|
100 typedef typename |
|
101 mpl::eval_if< |
|
102 is_std_io<U>, |
|
103 mpl::identity<char>, |
|
104 detail::member_char_type<U> |
|
105 >::type type; |
|
106 }; |
|
107 |
|
108 # endif // # ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //--------------------// |
|
109 |
|
110 template<typename Iter> |
|
111 struct char_type_of< iterator_range<Iter> > { |
|
112 typedef typename iterator_value<Iter>::type type; |
|
113 }; |
|
114 |
|
115 #else // #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION //------------------// |
|
116 |
|
117 template<typename T> |
|
118 struct char_type_of { |
|
119 template<typename U> |
|
120 struct get_value_type { |
|
121 typedef typename range_value<U>::type type; |
|
122 }; |
|
123 typedef typename |
|
124 mpl::eval_if< |
|
125 is_iterator_range<T>, |
|
126 get_value_type<T>, |
|
127 detail::member_char_type< |
|
128 BOOST_DEDUCED_TYPENAME detail::unwrapped_type<T>::type |
|
129 > |
|
130 >::type type; |
|
131 }; |
|
132 |
|
133 #endif // #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION //-----------------// |
|
134 |
|
135 //------------------Definitions of category_of--------------------------------// |
|
136 |
|
137 namespace detail { |
|
138 |
|
139 template<typename T> |
|
140 struct member_category { typedef typename T::category type; }; |
|
141 |
|
142 } // End namespace detail. |
|
143 |
|
144 template<typename T> |
|
145 struct category_of { |
|
146 template<typename U> |
|
147 struct member_category { |
|
148 typedef typename U::category type; |
|
149 }; |
|
150 typedef typename detail::unwrapped_type<T>::type U; |
|
151 typedef typename |
|
152 mpl::eval_if< |
|
153 is_std_io<U>, |
|
154 iostreams::select< // Disambiguation for Tru64 |
|
155 is_iostream<U>, iostream_tag, |
|
156 is_istream<U>, istream_tag, |
|
157 is_ostream<U>, ostream_tag, |
|
158 is_streambuf<U>, streambuf_tag |
|
159 >, |
|
160 detail::member_category<U> |
|
161 >::type type; |
|
162 }; |
|
163 |
|
164 //------------------Definition of get_category--------------------------------// |
|
165 |
|
166 // |
|
167 // Returns an object of type category_of<T>::type. |
|
168 // |
|
169 template<typename T> |
|
170 inline typename category_of<T>::type get_category(const T&) |
|
171 { typedef typename category_of<T>::type category; return category(); } |
|
172 |
|
173 //------------------Definition of int_type_of---------------------------------// |
|
174 |
|
175 template<typename T> |
|
176 struct int_type_of { |
|
177 #ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES |
|
178 typedef std::char_traits< |
|
179 BOOST_DEDUCED_TYPENAME char_type_of<T>::type |
|
180 > traits_type; |
|
181 typedef typename traits_type::int_type type; |
|
182 #else |
|
183 typedef int type; |
|
184 #endif |
|
185 }; |
|
186 |
|
187 //------------------Definition of mode----------------------------------------// |
|
188 |
|
189 namespace detail { |
|
190 |
|
191 template<int N> struct io_mode_impl; |
|
192 |
|
193 #define BOOST_IOSTREAMS_MODE_HELPER(tag_, id_) \ |
|
194 case_<id_> io_mode_impl_helper(tag_); \ |
|
195 template<> struct io_mode_impl<id_> { typedef tag_ type; }; \ |
|
196 /**/ |
|
197 BOOST_IOSTREAMS_MODE_HELPER(input, 1) |
|
198 BOOST_IOSTREAMS_MODE_HELPER(output, 2) |
|
199 BOOST_IOSTREAMS_MODE_HELPER(bidirectional, 3) |
|
200 BOOST_IOSTREAMS_MODE_HELPER(input_seekable, 4) |
|
201 BOOST_IOSTREAMS_MODE_HELPER(output_seekable, 5) |
|
202 BOOST_IOSTREAMS_MODE_HELPER(seekable, 6) |
|
203 BOOST_IOSTREAMS_MODE_HELPER(dual_seekable, 7) |
|
204 BOOST_IOSTREAMS_MODE_HELPER(bidirectional_seekable, 8) |
|
205 BOOST_IOSTREAMS_MODE_HELPER(dual_use, 9) |
|
206 #undef BOOST_IOSTREAMS_MODE_HELPER |
|
207 |
|
208 template<typename T> |
|
209 struct io_mode_id { |
|
210 typedef typename category_of<T>::type category; |
|
211 BOOST_SELECT_BY_SIZE(int, value, detail::io_mode_impl_helper(category())); |
|
212 }; |
|
213 |
|
214 } // End namespace detail. |
|
215 |
|
216 template<typename T> // Borland 5.6.4 requires this circumlocution. |
|
217 struct mode_of : detail::io_mode_impl< detail::io_mode_id<T>::value > { }; |
|
218 |
|
219 //------------------Definition of is_device, is_filter and is_direct----------// |
|
220 |
|
221 namespace detail { |
|
222 |
|
223 template<typename T, typename Tag> |
|
224 struct has_trait_impl { |
|
225 typedef typename category_of<T>::type category; |
|
226 BOOST_STATIC_CONSTANT(bool, value = (is_convertible<category, Tag>::value)); |
|
227 }; |
|
228 |
|
229 template<typename T, typename Tag> |
|
230 struct has_trait |
|
231 : mpl::bool_<has_trait_impl<T, Tag>::value> |
|
232 { }; |
|
233 |
|
234 } // End namespace detail. |
|
235 |
|
236 template<typename T> |
|
237 struct is_device : detail::has_trait<T, device_tag> { }; |
|
238 |
|
239 template<typename T> |
|
240 struct is_filter : detail::has_trait<T, filter_tag> { }; |
|
241 |
|
242 template<typename T> |
|
243 struct is_direct : detail::has_trait<T, direct_tag> { }; |
|
244 |
|
245 //------------------Definition of BOOST_IOSTREAMS_STREAMBUF_TYPEDEFS----------// |
|
246 |
|
247 #define BOOST_IOSTREAMS_STREAMBUF_TYPEDEFS(Tr) \ |
|
248 typedef Tr traits_type; \ |
|
249 typedef typename traits_type::int_type int_type; \ |
|
250 typedef typename traits_type::off_type off_type; \ |
|
251 typedef typename traits_type::pos_type pos_type; \ |
|
252 /**/ |
|
253 |
|
254 } } // End namespaces iostreams, boost. |
|
255 |
|
256 #endif // #ifndef BOOST_IOSTREAMS_IO_TRAITS_HPP_INCLUDED |