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.)
6 // See http://www.boost.org/libs/iostreams for documentation.
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.
12 // Also contains several utility metafunctions, functions and macros.
15 #ifndef BOOST_IOSTREAMS_IO_TRAITS_HPP_INCLUDED
16 #define BOOST_IOSTREAMS_IO_TRAITS_HPP_INCLUDED
18 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
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>
46 #include <boost/iostreams/detail/config/disable_warnings.hpp>
48 namespace boost
{ namespace iostreams
{
50 //----------Definitions of predicates for streams and stream buffers----------//
52 #ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //--------------------------------//
54 BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_istream
, std::basic_istream
, 2)
55 BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_ostream
, std::basic_ostream
, 2)
56 BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_iostream
, std::basic_iostream
, 2)
57 BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_streambuf
, std::basic_streambuf
, 2)
58 BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_ifstream
, std::basic_ifstream
, 2)
59 BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_ofstream
, std::basic_ofstream
, 2)
60 BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_fstream
, std::basic_fstream
, 2)
61 BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_filebuf
, std::basic_filebuf
, 2)
62 BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_istringstream
, std::basic_istringstream
, 3)
63 BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_ostringstream
, std::basic_ostringstream
, 3)
64 BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_stringstream
, std::basic_stringstream
, 3)
65 BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_stringbuf
, std::basic_stringbuf
, 3)
67 #else // #ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //-----------------------//
69 BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_istream
, std::istream
, 0)
70 BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_ostream
, std::ostream
, 0)
71 BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_iostream
, std::iostream
, 0)
72 BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_streambuf
, std::streambuf
, 0)
74 #endif // #ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //----------------------//
78 : mpl::or_
< is_istream
<T
>, is_ostream
<T
>, is_streambuf
<T
> >
82 struct is_std_file_device
92 struct is_std_string_device
101 template<typename Device
, typename Tr
, typename Alloc
>
104 template<typename T
, typename Tr
, typename Alloc
, typename Mode
>
107 template< typename Mode
, typename Ch
, typename Tr
,
108 typename Alloc
, typename Access
>
109 class filtering_stream
;
111 template< typename Mode
, typename Ch
, typename Tr
,
112 typename Alloc
, typename Access
>
113 class wfiltering_stream
;
115 template< typename Mode
, typename Ch
, typename Tr
,
116 typename Alloc
, typename Access
>
117 class filtering_streambuf
;
119 template< typename Mode
, typename Ch
, typename Tr
,
120 typename Alloc
, typename Access
>
121 class filtering_wstreambuf
;
125 template<typename T
, typename Tr
>
126 class linked_streambuf
;
128 BOOST_IOSTREAMS_BOOL_TRAIT_DEF( is_boost_stream
,
129 boost::iostreams::stream
,
131 BOOST_IOSTREAMS_BOOL_TRAIT_DEF( is_boost_stream_buffer
,
132 boost::iostreams::stream_buffer
,
134 BOOST_IOSTREAMS_BOOL_TRAIT_DEF( is_filtering_stream_impl
,
135 boost::iostreams::filtering_stream
,
137 BOOST_IOSTREAMS_BOOL_TRAIT_DEF( is_filtering_wstream_impl
,
138 boost::iostreams::wfiltering_stream
,
140 BOOST_IOSTREAMS_BOOL_TRAIT_DEF( is_filtering_streambuf_impl
,
141 boost::iostreams::filtering_streambuf
,
143 BOOST_IOSTREAMS_BOOL_TRAIT_DEF( is_filtering_wstreambuf_impl
,
144 boost::iostreams::filtering_wstreambuf
,
146 BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_linked
, linked_streambuf
, 2)
149 struct is_filtering_stream
151 is_filtering_stream_impl
<T
>,
152 is_filtering_wstream_impl
<T
>
157 struct is_filtering_streambuf
159 is_filtering_streambuf_impl
<T
>,
160 is_filtering_wstreambuf_impl
<T
>
168 is_boost_stream_buffer
<T
>,
169 is_filtering_stream
<T
>,
170 is_filtering_streambuf
<T
>
174 } // End namespace detail.
176 //------------------Definitions of char_type_of-------------------------------//
181 struct member_char_type
{ typedef typename
T::char_type type
; };
183 } // End namespace detail.
185 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION //---------------------------//
186 # ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //-------------------------------//
190 : detail::member_char_type
<
191 typename
detail::unwrapped_type
<T
>::type
195 # else // # ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //---------------------//
198 struct char_type_of
{
199 typedef typename
detail::unwrapped_type
<T
>::type U
;
204 detail::member_char_type
<U
>
208 # endif // # ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //--------------------//
210 template<typename Iter
>
211 struct char_type_of
< iterator_range
<Iter
> > {
212 typedef typename iterator_value
<Iter
>::type type
;
215 #else // #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION //------------------//
218 struct char_type_of
{
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)
227 is_iterator_range
<T
>,
229 detail::member_char_type
<
230 BOOST_DEDUCED_TYPENAME
detail::unwrapped_type
<T
>::type
235 #endif // #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION //-----------------//
237 //------------------Definitions of category_of--------------------------------//
242 struct member_category
{ typedef typename
T::category type
; };
244 } // End namespace detail.
249 struct member_category
{
250 typedef typename
U::category type
;
252 typedef typename
detail::unwrapped_type
<T
>::type U
;
257 mpl::not_
< detail::is_boost
<U
> >
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
273 detail::member_category
<U
>
277 // Partial specialization for reference wrappers
278 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION //---------------------------//
281 struct category_of
< reference_wrapper
<T
> >
285 #endif // #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION //-----------------//
287 //------------------Definition of get_category--------------------------------//
290 // Returns an object of type category_of<T>::type.
293 inline typename category_of
<T
>::type
get_category(const T
&)
294 { typedef typename category_of
<T
>::type category
; return category(); }
296 //------------------Definition of int_type_of---------------------------------//
300 #ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES
301 typedef std::char_traits
<
302 BOOST_DEDUCED_TYPENAME char_type_of
<T
>::type
304 typedef typename
traits_type::int_type type
;
310 //------------------Definition of mode_of-------------------------------------//
314 template<int N
> struct io_mode_impl
;
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; }; \
320 BOOST_IOSTREAMS_MODE_HELPER(input
, 1)
321 BOOST_IOSTREAMS_MODE_HELPER(output
, 2)
322 BOOST_IOSTREAMS_MODE_HELPER(bidirectional
, 3)
323 BOOST_IOSTREAMS_MODE_HELPER(input_seekable
, 4)
324 BOOST_IOSTREAMS_MODE_HELPER(output_seekable
, 5)
325 BOOST_IOSTREAMS_MODE_HELPER(seekable
, 6)
326 BOOST_IOSTREAMS_MODE_HELPER(dual_seekable
, 7)
327 BOOST_IOSTREAMS_MODE_HELPER(bidirectional_seekable
, 8)
328 BOOST_IOSTREAMS_MODE_HELPER(dual_use
, 9)
329 #undef BOOST_IOSTREAMS_MODE_HELPER
333 typedef typename category_of
<T
>::type category
;
334 BOOST_SELECT_BY_SIZE(int, value
, detail::io_mode_impl_helper(category()));
337 } // End namespace detail.
339 template<typename T
> // Borland 5.6.4 requires this circumlocution.
340 struct mode_of
: detail::io_mode_impl
< detail::io_mode_id
<T
>::value
> { };
342 // Partial specialization for reference wrappers
343 #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION //---------------------------//
346 struct mode_of
< reference_wrapper
<T
> >
350 #endif // #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION //-----------------//
352 //------------------Definition of is_device, is_filter and is_direct----------//
356 template<typename T
, typename Tag
>
357 struct has_trait_impl
{
358 typedef typename category_of
<T
>::type category
;
359 BOOST_STATIC_CONSTANT(bool, value
= (is_convertible
<category
, Tag
>::value
));
362 template<typename T
, typename Tag
>
364 : mpl::bool_
<has_trait_impl
<T
, Tag
>::value
>
367 } // End namespace detail.
370 struct is_device
: detail::has_trait
<T
, device_tag
> { };
373 struct is_filter
: detail::has_trait
<T
, filter_tag
> { };
376 struct is_direct
: detail::has_trait
<T
, direct_tag
> { };
378 //------------------Definition of BOOST_IOSTREAMS_STREAMBUF_TYPEDEFS----------//
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; \
387 } } // End namespaces iostreams, boost.
389 #include <boost/iostreams/detail/config/enable_warnings.hpp>
391 #endif // #ifndef BOOST_IOSTREAMS_IO_TRAITS_HPP_INCLUDED