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.)
5
6// See http://www.boost.org/libs/iostreams for documentation.
7
8//
9// Contains metafunctions char_type_of, category_of and mode_of used for
10// deducing the i/o category and i/o mode of a model of Filter or Device.
11//
12// Also contains several utility metafunctions, functions and macros.
13//
14
15#ifndef BOOST_IOSTREAMS_IO_TRAITS_HPP_INCLUDED
16#define BOOST_IOSTREAMS_IO_TRAITS_HPP_INCLUDED
17
18#if defined(_MSC_VER) && (_MSC_VER >= 1020)
19# pragma once
20#endif
21
22#include <iosfwd> // stream types, char_traits.
23#include <boost/config.hpp> // partial spec, deduced typename.
24#include <boost/detail/workaround.hpp>
25#include <boost/iostreams/categories.hpp>
26#include <boost/iostreams/detail/bool_trait_def.hpp>
27#include <boost/iostreams/detail/config/wide_streams.hpp>
28#include <boost/iostreams/detail/is_iterator_range.hpp>
29#include <boost/iostreams/detail/select.hpp>
30#include <boost/iostreams/detail/select_by_size.hpp>
31#include <boost/iostreams/detail/wrap_unwrap.hpp>
32#include <boost/iostreams/traits_fwd.hpp>
33#include <boost/mpl/bool.hpp>
34#include <boost/mpl/eval_if.hpp>
35#include <boost/mpl/identity.hpp>
36#include <boost/mpl/int.hpp>
37#include <boost/mpl/or.hpp>
38#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
39# include <boost/range/iterator_range.hpp>
40# include <boost/range/value_type.hpp>
41#endif // #if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
42#include <boost/ref.hpp>
43#include <boost/type_traits/is_convertible.hpp>
44
45// Must come last.
46#include <boost/iostreams/detail/config/disable_warnings.hpp>
47
48namespace boost { namespace iostreams {
49
50//----------Definitions of predicates for streams and stream buffers----------//
51
52#ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //--------------------------------//
53
54BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_istream, std::basic_istream, 2)
55BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_ostream, std::basic_ostream, 2)
56BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_iostream, std::basic_iostream, 2)
57BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_streambuf, std::basic_streambuf, 2)
58BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_ifstream, std::basic_ifstream, 2)
59BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_ofstream, std::basic_ofstream, 2)
60BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_fstream, std::basic_fstream, 2)
61BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_filebuf, std::basic_filebuf, 2)
62BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_istringstream, std::basic_istringstream, 3)
63BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_ostringstream, std::basic_ostringstream, 3)
64BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_stringstream, std::basic_stringstream, 3)
65BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_stringbuf, std::basic_stringbuf, 3)
66
67#else // #ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //-----------------------//
68
69BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_istream, std::istream, 0)
70BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_ostream, std::ostream, 0)
71BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_iostream, std::iostream, 0)
72BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_streambuf, std::streambuf, 0)
73
74#endif // #ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //----------------------//
75
76template<typename T>
77struct is_std_io
78 : mpl::or_< is_istream<T>, is_ostream<T>, is_streambuf<T> >
79 { };
80
81template<typename T>
82struct is_std_file_device
83 : mpl::or_<
84 is_ifstream<T>,
85 is_ofstream<T>,
86 is_fstream<T>,
87 is_filebuf<T>
88 >
89 { };
90
91template<typename T>
92struct is_std_string_device
93 : mpl::or_<
94 is_istringstream<T>,
95 is_ostringstream<T>,
96 is_stringstream<T>,
97 is_stringbuf<T>
98 >
99 { };
100
101template<typename Device, typename Tr, typename Alloc>
102struct stream;
103
104template<typename T, typename Tr, typename Alloc, typename Mode>
105class stream_buffer;
106
107template< typename Mode, typename Ch, typename Tr,
108 typename Alloc, typename Access >
109class filtering_stream;
110
111template< typename Mode, typename Ch, typename Tr,
112 typename Alloc, typename Access >
113class wfiltering_stream;
114
115template< typename Mode, typename Ch, typename Tr,
116 typename Alloc, typename Access >
117class filtering_streambuf;
118
119template< typename Mode, typename Ch, typename Tr,
120 typename Alloc, typename Access >
121class filtering_wstreambuf;
122
123namespace detail {
124
125template<typename T, typename Tr>
126class linked_streambuf;
127
128BOOST_IOSTREAMS_BOOL_TRAIT_DEF( is_boost_stream,
129 boost::iostreams::stream,
130 3 )
131BOOST_IOSTREAMS_BOOL_TRAIT_DEF( is_boost_stream_buffer,
132 boost::iostreams::stream_buffer,
133 4 )
134BOOST_IOSTREAMS_BOOL_TRAIT_DEF( is_filtering_stream_impl,
135 boost::iostreams::filtering_stream,
136 5 )
137BOOST_IOSTREAMS_BOOL_TRAIT_DEF( is_filtering_wstream_impl,
138 boost::iostreams::wfiltering_stream,
139 5 )
140BOOST_IOSTREAMS_BOOL_TRAIT_DEF( is_filtering_streambuf_impl,
141 boost::iostreams::filtering_streambuf,
142 5 )
143BOOST_IOSTREAMS_BOOL_TRAIT_DEF( is_filtering_wstreambuf_impl,
144 boost::iostreams::filtering_wstreambuf,
145 5 )
146BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_linked, linked_streambuf, 2)
147
148template<typename T>
149struct is_filtering_stream
150 : mpl::or_<
151 is_filtering_stream_impl<T>,
152 is_filtering_wstream_impl<T>
153 >
154 { };
155
156template<typename T>
157struct is_filtering_streambuf
158 : mpl::or_<
159 is_filtering_streambuf_impl<T>,
160 is_filtering_wstreambuf_impl<T>
161 >
162 { };
163
164template<typename T>
165struct is_boost
166 : mpl::or_<
167 is_boost_stream<T>,
168 is_boost_stream_buffer<T>,
169 is_filtering_stream<T>,
170 is_filtering_streambuf<T>
171 >
172 { };
173
174} // End namespace detail.
175
176//------------------Definitions of char_type_of-------------------------------//
177
178namespace detail {
179
180template<typename T>
181struct member_char_type { typedef typename T::char_type type; };
182
183} // End namespace detail.
184
185#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION //---------------------------//
186# ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //-------------------------------//
187
188template<typename T>
189struct char_type_of
190 : detail::member_char_type<
191 typename detail::unwrapped_type<T>::type
192 >
193 { };
194
195# else // # ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //---------------------//
196
197template<typename T>
198struct char_type_of {
199 typedef typename detail::unwrapped_type<T>::type U;
200 typedef typename
201 mpl::eval_if<
202 is_std_io<U>,
203 mpl::identity<char>,
204 detail::member_char_type<U>
205 >::type type;
206};
207
208# endif // # ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //--------------------//
209
210template<typename Iter>
211struct char_type_of< iterator_range<Iter> > {
212 typedef typename iterator_value<Iter>::type type;
213};
214
215#else // #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION //------------------//
216
217template<typename T>
218struct char_type_of {
219 template<typename U>
220 struct get_value_type {
221 #if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
222 typedef typename range_value<U>::type type;
223 #endif // #if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
224 };
225 typedef typename
226 mpl::eval_if<
227 is_iterator_range<T>,
228 get_value_type<T>,
229 detail::member_char_type<
230 BOOST_DEDUCED_TYPENAME detail::unwrapped_type<T>::type
231 >
232 >::type type;
233};
234
235#endif // #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION //-----------------//
236
237//------------------Definitions of category_of--------------------------------//
238
239namespace detail {
240
241template<typename T>
242struct member_category { typedef typename T::category type; };
243
244} // End namespace detail.
245
246template<typename T>
247struct category_of {
248 template<typename U>
249 struct member_category {
250 typedef typename U::category type;
251 };
252 typedef typename detail::unwrapped_type<T>::type U;
253 typedef typename
254 mpl::eval_if<
255 mpl::and_<
256 is_std_io<U>,
257 mpl::not_< detail::is_boost<U> >
258 >,
259 iostreams::select< // Disambiguation for Tru64
260 is_filebuf<U>, filebuf_tag,
261 is_ifstream<U>, ifstream_tag,
262 is_ofstream<U>, ofstream_tag,
263 is_fstream<U>, fstream_tag,
264 is_stringbuf<U>, stringbuf_tag,
265 is_istringstream<U>, istringstream_tag,
266 is_ostringstream<U>, ostringstream_tag,
267 is_stringstream<U>, stringstream_tag,
268 is_streambuf<U>, generic_streambuf_tag,
269 is_iostream<U>, generic_iostream_tag,
270 is_istream<U>, generic_istream_tag,
271 is_ostream<U>, generic_ostream_tag
272 >,
273 detail::member_category<U>
274 >::type type;
275};
276
277// Partial specialization for reference wrappers
278#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION //---------------------------//
279
280template<typename T>
281struct category_of< reference_wrapper<T> >
282 : category_of<T>
283 { };
284
285#endif // #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION //-----------------//
286
287//------------------Definition of get_category--------------------------------//
288
289//
290// Returns an object of type category_of<T>::type.
291//
292template<typename T>
293inline typename category_of<T>::type get_category(const T&)
294{ typedef typename category_of<T>::type category; return category(); }
295
296//------------------Definition of int_type_of---------------------------------//
297
298template<typename T>
299struct int_type_of {
300#ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES
301 typedef std::char_traits<
302 BOOST_DEDUCED_TYPENAME char_type_of<T>::type
303 > traits_type;
304 typedef typename traits_type::int_type type;
305#else
306 typedef int type;
307#endif
308};
309
310//------------------Definition of mode_of-------------------------------------//
311
312namespace detail {
313
314template<int N> struct io_mode_impl;
315
316#define BOOST_IOSTREAMS_MODE_HELPER(tag_, id_) \
317 case_<id_> io_mode_impl_helper(tag_); \
318 template<> struct io_mode_impl<id_> { typedef tag_ type; }; \
319 /**/
320BOOST_IOSTREAMS_MODE_HELPER(input, 1)
321BOOST_IOSTREAMS_MODE_HELPER(output, 2)
322BOOST_IOSTREAMS_MODE_HELPER(bidirectional, 3)
323BOOST_IOSTREAMS_MODE_HELPER(input_seekable, 4)
324BOOST_IOSTREAMS_MODE_HELPER(output_seekable, 5)
325BOOST_IOSTREAMS_MODE_HELPER(seekable, 6)
326BOOST_IOSTREAMS_MODE_HELPER(dual_seekable, 7)
327BOOST_IOSTREAMS_MODE_HELPER(bidirectional_seekable, 8)
328BOOST_IOSTREAMS_MODE_HELPER(dual_use, 9)
329#undef BOOST_IOSTREAMS_MODE_HELPER
330
331template<typename T>
332struct io_mode_id {
333 typedef typename category_of<T>::type category;
334 BOOST_SELECT_BY_SIZE(int, value, detail::io_mode_impl_helper(category()));
335};
336
337} // End namespace detail.
338
339template<typename T> // Borland 5.6.4 requires this circumlocution.
340struct mode_of : detail::io_mode_impl< detail::io_mode_id<T>::value > { };
341
342// Partial specialization for reference wrappers
343#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION //---------------------------//
344
345template<typename T>
346struct mode_of< reference_wrapper<T> >
347 : mode_of<T>
348 { };
349
350#endif // #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION //-----------------//
351
352//------------------Definition of is_device, is_filter and is_direct----------//
353
354namespace detail {
355
356template<typename T, typename Tag>
357struct has_trait_impl {
358 typedef typename category_of<T>::type category;
359 BOOST_STATIC_CONSTANT(bool, value = (is_convertible<category, Tag>::value));
360};
361
362template<typename T, typename Tag>
363struct has_trait
364 : mpl::bool_<has_trait_impl<T, Tag>::value>
365 { };
366
367} // End namespace detail.
368
369template<typename T>
370struct is_device : detail::has_trait<T, device_tag> { };
371
372template<typename T>
373struct is_filter : detail::has_trait<T, filter_tag> { };
374
375template<typename T>
376struct is_direct : detail::has_trait<T, direct_tag> { };
377
378//------------------Definition of BOOST_IOSTREAMS_STREAMBUF_TYPEDEFS----------//
379
380#define BOOST_IOSTREAMS_STREAMBUF_TYPEDEFS(Tr) \
381 typedef Tr traits_type; \
382 typedef typename traits_type::int_type int_type; \
383 typedef typename traits_type::off_type off_type; \
384 typedef typename traits_type::pos_type pos_type; \
385 /**/
386
387} } // End namespaces iostreams, boost.
388
389#include <boost/iostreams/detail/config/enable_warnings.hpp>
390
391#endif // #ifndef BOOST_IOSTREAMS_IO_TRAITS_HPP_INCLUDED
392

source code of boost/boost/iostreams/traits.hpp