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