source: NonGTP/Boost/boost/iostreams/traits.hpp @ 857

Revision 857, 8.5 KB checked in by igarcia, 18 years ago (diff)
Line 
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
40namespace boost { namespace iostreams {       
41
42//------------------Definitions of predicates for streams and stream buffers--//
43
44#ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //--------------------------------//
45
46BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_istream, std::basic_istream, 2)
47BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_ostream, std::basic_ostream, 2)
48BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_iostream, std::basic_iostream, 2)
49BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_streambuf, std::basic_streambuf, 2)
50BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_stringstream, std::basic_stringstream, 3)
51BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_stringbuf, std::basic_stringbuf, 3)
52
53#else // #ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //-----------------------//
54
55BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_istream, std::istream, 0)
56BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_ostream, std::ostream, 0)
57BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_iostream, std::iostream, 0)
58BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_streambuf, std::streambuf, 0)
59
60#endif // #ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //----------------------//
61
62template<typename T>
63struct is_std_io
64    : mpl::or_< is_istream<T>, is_ostream<T>, is_streambuf<T> >
65    { };
66
67namespace detail {
68
69template<typename T, typename Tr>
70class linked_streambuf;
71
72BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_linked, linked_streambuf, 2)
73
74} // End namespace detail.
75                   
76//------------------Definitions of char_type_of-------------------------------//
77
78namespace detail {
79
80template<typename T>
81struct 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
88template<typename T>
89struct 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
97template<typename T>
98struct 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
110template<typename Iter>
111struct 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
117template<typename T>
118struct 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
137namespace detail {
138
139template<typename T>
140struct member_category { typedef typename T::category type; };
141
142} // End namespace detail.
143
144template<typename T>
145struct 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//
169template<typename T>
170inline 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
175template<typename T>
176struct 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
189namespace detail {
190
191template<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    /**/
197BOOST_IOSTREAMS_MODE_HELPER(input, 1)
198BOOST_IOSTREAMS_MODE_HELPER(output, 2)
199BOOST_IOSTREAMS_MODE_HELPER(bidirectional, 3)
200BOOST_IOSTREAMS_MODE_HELPER(input_seekable, 4)
201BOOST_IOSTREAMS_MODE_HELPER(output_seekable, 5)
202BOOST_IOSTREAMS_MODE_HELPER(seekable, 6)
203BOOST_IOSTREAMS_MODE_HELPER(dual_seekable, 7)
204BOOST_IOSTREAMS_MODE_HELPER(bidirectional_seekable, 8)
205BOOST_IOSTREAMS_MODE_HELPER(dual_use, 9)
206#undef BOOST_IOSTREAMS_MODE_HELPER
207
208template<typename T>
209struct 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
216template<typename T> // Borland 5.6.4 requires this circumlocution.
217struct mode_of : detail::io_mode_impl< detail::io_mode_id<T>::value > { };
218                   
219//------------------Definition of is_device, is_filter and is_direct----------//
220
221namespace detail {
222
223template<typename T, typename Tag>
224struct has_trait_impl {
225    typedef typename category_of<T>::type category;
226    BOOST_STATIC_CONSTANT(bool, value = (is_convertible<category, Tag>::value));
227};
228
229template<typename T, typename Tag>
230struct has_trait
231    : mpl::bool_<has_trait_impl<T, Tag>::value>
232    { };
233
234} // End namespace detail.
235
236template<typename T>
237struct is_device : detail::has_trait<T, device_tag> { };
238
239template<typename T>
240struct is_filter : detail::has_trait<T, filter_tag> { };
241
242template<typename T>
243struct 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
Note: See TracBrowser for help on using the repository browser.