source: NonGTP/Boost/boost/iostreams/detail/resolve.hpp @ 857

Revision 857, 8.4 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#ifndef BOOST_IOSTREAMS_DETAIL_RESOLVE_HPP_INCLUDED
8#define BOOST_IOSTREAMS_DETAIL_RESOLVE_HPP_INCLUDED
9
10#if defined(_MSC_VER) && (_MSC_VER >= 1020)
11# pragma once
12#endif             
13
14#include <boost/config.hpp> // partial spec, put size_t in std.
15#include <cstddef>          // std::size_t.
16#include <boost/detail/is_incrementable.hpp>
17#include <boost/detail/workaround.hpp>
18#include <boost/iostreams/detail/adapter/mode_adapter.hpp>
19#include <boost/iostreams/detail/adapter/output_iterator_adapter.hpp>
20#include <boost/iostreams/detail/adapter/range_adapter.hpp>
21#include <boost/iostreams/detail/config/gcc.hpp>
22#include <boost/iostreams/detail/config/overload_resolution.hpp>
23#include <boost/iostreams/detail/config/wide_streams.hpp>
24#include <boost/iostreams/detail/enable_if_stream.hpp>
25#include <boost/iostreams/detail/is_dereferenceable.hpp>
26#include <boost/iostreams/detail/is_iterator_range.hpp>
27#include <boost/iostreams/detail/select.hpp>
28#include <boost/iostreams/detail/wrap_unwrap.hpp>
29#include <boost/iostreams/device/array.hpp>
30#include <boost/iostreams/traits.hpp>
31#include <boost/mpl/and.hpp>
32#include <boost/mpl/bool.hpp> // true_.
33#include <boost/mpl/if.hpp>
34#include <boost/range/iterator_range.hpp>
35#include <boost/type_traits/is_array.hpp>
36
37// Must come last.
38#include <boost/iostreams/detail/config/disable_warnings.hpp> // VC7.1 C4224.
39
40namespace boost { namespace iostreams { namespace detail {
41
42//------------------Definition of resolve-------------------------------------//
43
44#ifndef BOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION //-------------------------//
45
46template<typename Mode, typename Ch, typename T>
47struct resolve_traits {
48    typedef typename
49            mpl::if_<
50                boost::detail::is_incrementable<T>,
51                output_iterator_adapter<Mode, Ch, T>,
52                const T&
53            >::type type;
54};
55
56# ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //-------------------------------//
57
58template<typename Mode, typename Ch, typename T>
59typename resolve_traits<Mode, Ch, T>::type
60resolve( const T& t
61         BOOST_IOSTREAMS_DISABLE_IF_STREAM(T)
62
63         // I suspect that the compilers which require this workaround may
64         // be correct, but I'm not sure why :(
65         #if BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, BOOST_TESTED_AT(810)) ||\
66             BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205)) || \
67             BOOST_WORKAROUND(BOOST_IOSTREAMS_GCC, BOOST_TESTED_AT(400)) \
68             /**/
69         , typename disable_if< is_iterator_range<T> >::type* = 0
70         #endif
71         )
72{
73    typedef typename resolve_traits<Mode, Ch, T>::type return_type;
74    return return_type(t);
75}
76
77template<typename Mode, typename Ch, typename Tr>
78mode_adapter< Mode, std::basic_streambuf<Ch, Tr> >
79resolve(std::basic_streambuf<Ch, Tr>& sb)
80{ return mode_adapter< Mode, std::basic_streambuf<Ch, Tr> >(wrap(sb)); }
81
82template<typename Mode, typename Ch, typename Tr>
83mode_adapter< Mode, std::basic_istream<Ch, Tr> >
84resolve(std::basic_istream<Ch, Tr>& is)
85{ return mode_adapter< Mode, std::basic_istream<Ch, Tr> >(wrap(is)); }
86
87template<typename Mode, typename Ch, typename Tr>
88mode_adapter< Mode, std::basic_ostream<Ch, Tr> >
89resolve(std::basic_ostream<Ch, Tr>& os)
90{ return mode_adapter< Mode, std::basic_ostream<Ch, Tr> >(wrap(os)); }
91
92template<typename Mode, typename Ch, typename Tr>
93mode_adapter< Mode, std::basic_iostream<Ch, Tr> >
94resolve(std::basic_iostream<Ch, Tr>& io)
95{ return mode_adapter< Mode, std::basic_iostream<Ch, Tr> >(wrap(io)); }
96
97template<typename Mode, typename Ch, std::size_t N>
98array_adapter<Mode, Ch> resolve(Ch (&array)[N])
99{ return array_adapter<Mode, Ch>(array); }
100
101template<typename Mode, typename Ch, typename Iter>
102range_adapter< Mode, boost::iterator_range<Iter> >
103resolve(const boost::iterator_range<Iter>& rng)
104{ return range_adapter< Mode, boost::iterator_range<Iter> >(rng); }
105
106# else // # ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //---------------------//
107
108template<typename Mode, typename Ch, typename T>
109typename resolve_traits<Mode, Ch, T>::type
110resolve( const T& t
111         BOOST_IOSTREAMS_DISABLE_IF_STREAM(T)
112         #if defined(__GNUC__)
113         , typename disable_if< is_iterator_range<T> >::type* = 0
114         #endif
115         )
116{
117    typedef typename resolve_traits<Mode, Ch, T>::type return_type;
118    return return_type(t);
119}
120
121template<typename Mode, typename Ch>
122mode_adapter<Mode, std::streambuf>
123resolve(std::streambuf& sb)
124{ return mode_adapter<Mode, std::streambuf>(wrap(sb)); }
125
126template<typename Mode, typename Ch>
127mode_adapter<Mode, std::istream>
128resolve(std::istream& is)
129{ return mode_adapter<Mode, std::istream>(wrap(is)); }
130
131template<typename Mode, typename Ch>
132mode_adapter<Mode, std::ostream>
133resolve(std::ostream& os)
134{ return mode_adapter<Mode, std::ostream>(wrap(os)); }
135
136template<typename Mode, typename Ch>
137mode_adapter<Mode, std::iostream>
138resolve(std::iostream& io)
139{ return mode_adapter<Mode, std::iostream>(wrap(io)); }
140
141template<typename Mode, typename Ch, std::size_t N>
142array_adapter<Mode, Ch> resolve(Ch (&array)[N])
143{ return array_adapter<Mode, Ch>(array); }
144
145template<typename Mode, typename Ch, typename Iter>
146range_adapter< Mode, boost::iterator_range<Iter> >
147resolve(const boost::iterator_range<Iter>& rng)
148{ return range_adapter< Mode, boost::iterator_range<Iter> >(rng); }
149
150# endif // # ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //--------------------//
151#else // #ifndef BOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION //----------------//
152
153template<typename Mode, typename Ch, typename T>
154struct resolve_traits {
155    // Note: test for is_iterator_range must come before test for output
156    // iterator.
157    typedef typename
158            iostreams::select<  // Disambiguation for Tru64.
159                is_std_io<T>,
160                mode_adapter<Mode, T>,
161                is_iterator_range<T>,
162                range_adapter<Mode, T>,
163                is_dereferenceable<T>,
164                output_iterator_adapter<Mode, Ch, T>,
165                is_array<T>,
166                array_adapter<Mode, T>,
167                else_,
168                #if !BOOST_WORKAROUND(__BORLANDC__, < 0x600)
169                    const T&
170                #else
171                    T
172                #endif
173            >::type type;
174};
175
176template<typename Mode, typename Ch, typename T>
177typename resolve_traits<Mode, Ch, T>::type
178resolve(const T& t, mpl::true_)
179{   // Bad overload resolution.
180    typedef typename resolve_traits<Mode, Ch, T>::type return_type;
181    return return_type(wrap(const_cast<T&>(t)));
182}
183
184template<typename Mode, typename Ch, typename T>
185typename resolve_traits<Mode, Ch, T>::type
186resolve(const T& t, mpl::false_)
187{
188    typedef typename resolve_traits<Mode, Ch, T>::type return_type;
189    return return_type(t);
190}
191
192template<typename Mode, typename Ch, typename T>
193typename resolve_traits<Mode, Ch, T>::type
194resolve(const T& t BOOST_IOSTREAMS_DISABLE_IF_STREAM(T))
195{ return resolve<Mode, Ch>(t, is_std_io<T>()); }
196
197# if !BOOST_WORKAROUND(__BORLANDC__, < 0x600) && \
198     !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) && \
199     !defined(__GNUC__) // ---------------------------------------------------//
200
201template<typename Mode, typename Ch, typename T>
202typename resolve_traits<Mode, Ch, T>::type
203resolve(T& t, mpl::true_)
204{
205    typedef typename resolve_traits<Mode, Ch, T>::type return_type;
206    return return_type(wrap(t));
207}
208
209template<typename Mode, typename Ch, typename T>
210typename resolve_traits<Mode, Ch, T>::type
211resolve(T& t, mpl::false_)
212{
213    typedef typename resolve_traits<Mode, Ch, T>::type return_type;
214    return return_type(t);
215}
216
217template<typename Mode, typename Ch, typename T>
218typename resolve_traits<Mode, Ch, T>::type
219resolve(T& t BOOST_IOSTREAMS_ENABLE_IF_STREAM(T))
220{ return resolve<Mode, Ch>(t, is_std_io<T>()); }
221
222# endif // Borland 5.x, VC6-7.0 or GCC 2.9x //--------------------------------//
223#endif // #ifndef BOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION //---------------//
224
225} } } // End namespaces detail, iostreams, boost.
226
227#include <boost/iostreams/detail/config/enable_warnings.hpp> // VC7.1 4224.
228
229#endif // BOOST_IOSTREAMS_DETAIL_RESOLVE_HPP_INCLUDED
Note: See TracBrowser for help on using the repository browser.