os/ossrv/ossrv_pub/boost_apis/boost/iostreams/compose.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 2005.
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
// Note: bidirectional streams are not supported.
sl@0
     8
sl@0
     9
#ifndef BOOST_IOSTREAMS_COMPOSE_HPP_INCLUDED
sl@0
    10
#define BOOST_IOSTREAMS_COMPOSE_HPP_INCLUDED
sl@0
    11
sl@0
    12
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
sl@0
    13
# pragma once
sl@0
    14
#endif
sl@0
    15
sl@0
    16
#include <algorithm>          // min.
sl@0
    17
#include <utility>            // pair.
sl@0
    18
#include <boost/config.hpp>   // DEDUCED_TYPENAME.
sl@0
    19
#include <boost/iostreams/categories.hpp>
sl@0
    20
#include <boost/iostreams/detail/adapter/direct_adapter.hpp>
sl@0
    21
#include <boost/iostreams/detail/call_traits.hpp>
sl@0
    22
#include <boost/iostreams/detail/closer.hpp>
sl@0
    23
#include <boost/iostreams/detail/enable_if_stream.hpp>
sl@0
    24
#include <boost/iostreams/operations.hpp>
sl@0
    25
#include <boost/iostreams/traits.hpp>      // mode_of, is_direct.
sl@0
    26
#include <boost/mpl/if.hpp>
sl@0
    27
#include <boost/ref.hpp>
sl@0
    28
#include <boost/static_assert.hpp>
sl@0
    29
#include <boost/type_traits/is_convertible.hpp>
sl@0
    30
sl@0
    31
namespace boost { namespace iostreams {
sl@0
    32
sl@0
    33
namespace detail {
sl@0
    34
sl@0
    35
template<typename Filter, typename Device>
sl@0
    36
struct composite_mode {
sl@0
    37
    typedef typename mode_of<Filter>::type           filter_mode;
sl@0
    38
    typedef typename mode_of<Device>::type           device_mode;
sl@0
    39
    typedef is_convertible<filter_mode, dual_use>    is_dual_use;
sl@0
    40
    typedef typename
sl@0
    41
            mpl::if_<
sl@0
    42
                is_convertible<device_mode, input>,
sl@0
    43
                input,
sl@0
    44
                output
sl@0
    45
            >::type                                  type;
sl@0
    46
};
sl@0
    47
sl@0
    48
//
sl@0
    49
// Template name: composite_device.
sl@0
    50
// Description: Provides a Device view of a Filter, Device pair.
sl@0
    51
// Template paramters:
sl@0
    52
//      Filter - A model of Filter.
sl@0
    53
//      Device - An indirect model of Device.
sl@0
    54
//
sl@0
    55
template< typename Filter,
sl@0
    56
          typename Device,
sl@0
    57
          typename Mode =
sl@0
    58
              BOOST_DEDUCED_TYPENAME composite_mode<Filter, Device>::type >
sl@0
    59
class composite_device {
sl@0
    60
private:
sl@0
    61
    typedef typename detail::param_type<Device>::type       param_type;
sl@0
    62
    typedef typename
sl@0
    63
            iostreams::select<  // Disambiguation for Tru64.
sl@0
    64
                is_direct<Device>,  direct_adapter<Device>,
sl@0
    65
                is_std_io<Device>,  Device&,
sl@0
    66
                else_,              Device
sl@0
    67
            >::type                                         value_type;
sl@0
    68
public:
sl@0
    69
    typedef typename char_type_of<Filter>::type             char_type;
sl@0
    70
    struct category
sl@0
    71
        : Mode,
sl@0
    72
          device_tag,
sl@0
    73
          closable_tag,
sl@0
    74
          flushable_tag,
sl@0
    75
          localizable_tag,
sl@0
    76
          optimally_buffered_tag
sl@0
    77
        { };
sl@0
    78
    composite_device(const Filter& flt, param_type dev);
sl@0
    79
    std::streamsize read(char_type* s, std::streamsize n);
sl@0
    80
    std::streamsize write(const char_type* s, std::streamsize n);
sl@0
    81
    stream_offset seek( stream_offset off, BOOST_IOS::seekdir way,
sl@0
    82
                        BOOST_IOS::openmode which =
sl@0
    83
                            BOOST_IOS::in | BOOST_IOS::out );
sl@0
    84
sl@0
    85
    void close();
sl@0
    86
    void close(BOOST_IOS::openmode which);
sl@0
    87
    bool flush();
sl@0
    88
    std::streamsize optimal_buffer_size() const;
sl@0
    89
sl@0
    90
    template<typename Locale> // Avoid dependency on <locale>
sl@0
    91
    void imbue(const Locale& loc)
sl@0
    92
    {
sl@0
    93
        iostreams::imbue(filter_, loc);
sl@0
    94
        iostreams::imbue(device_, loc);
sl@0
    95
    }
sl@0
    96
sl@0
    97
    Filter& first() { return filter_; }
sl@0
    98
    Device& second() { return device_; }
sl@0
    99
private:
sl@0
   100
    Filter      filter_;
sl@0
   101
    value_type  device_;
sl@0
   102
};
sl@0
   103
sl@0
   104
//
sl@0
   105
// Template name: composite_device.
sl@0
   106
// Description: Provides a Device view of a Filter, Device pair.
sl@0
   107
// Template paramters:
sl@0
   108
//      Filter - A model of Filter.
sl@0
   109
//      Device - An indirect model of Device.
sl@0
   110
//
sl@0
   111
template<typename Filter1, typename Filter2>
sl@0
   112
class composite_filter {
sl@0
   113
private:
sl@0
   114
     typedef reference_wrapper<Filter2>           filter_ref;
sl@0
   115
public:
sl@0
   116
    typedef typename char_type_of<Filter1>::type  char_type;
sl@0
   117
    struct category
sl@0
   118
        : mode_of<Filter1>::type,
sl@0
   119
          filter_tag,
sl@0
   120
          multichar_tag,
sl@0
   121
          closable_tag,
sl@0
   122
          flushable_tag,
sl@0
   123
          localizable_tag,
sl@0
   124
          optimally_buffered_tag
sl@0
   125
        { };
sl@0
   126
    composite_filter(const Filter1& filter1, const Filter2& filter2)
sl@0
   127
        : filter1_(filter1), filter2_(filter2)
sl@0
   128
        { }
sl@0
   129
sl@0
   130
    template<typename Source>
sl@0
   131
    std::streamsize read(Source& src, char_type* s, std::streamsize n)
sl@0
   132
    {
sl@0
   133
        composite_device<filter_ref, Source> cmp(boost::ref(filter2_), src);
sl@0
   134
        return iostreams::read(filter1_, cmp, s, n);
sl@0
   135
    }
sl@0
   136
sl@0
   137
    template<typename Sink>
sl@0
   138
    std::streamsize write(Sink& snk, const char_type* s, std::streamsize n)
sl@0
   139
    {
sl@0
   140
        composite_device<filter_ref, Sink> cmp(boost::ref(filter2_), snk);
sl@0
   141
        return iostreams::write(filter1_, cmp, s, n);
sl@0
   142
    }
sl@0
   143
sl@0
   144
    template<typename Device>
sl@0
   145
    stream_offset seek( Device& dev, stream_offset off, BOOST_IOS::seekdir way,
sl@0
   146
                        BOOST_IOS::openmode which =
sl@0
   147
                            BOOST_IOS::in | BOOST_IOS::out )
sl@0
   148
    {
sl@0
   149
        composite_device<filter_ref, Device> cmp(boost::ref(filter2_), dev);
sl@0
   150
        return iostreams::seek(filter1_, cmp, off, way, which);
sl@0
   151
    }
sl@0
   152
sl@0
   153
    template<typename Device>
sl@0
   154
    void close( Device& dev,
sl@0
   155
                BOOST_IOS::openmode which =
sl@0
   156
                    BOOST_IOS::in | BOOST_IOS::out )
sl@0
   157
    {
sl@0
   158
        composite_device<filter_ref, Device> cmp(boost::ref(filter2_), dev);
sl@0
   159
        iostreams::close(filter1_, cmp, which);
sl@0
   160
    }
sl@0
   161
sl@0
   162
    template<typename Device>
sl@0
   163
    bool flush(Device& dev)
sl@0
   164
    {
sl@0
   165
        composite_device<Filter2, Device> cmp(filter2_, dev);
sl@0
   166
        return iostreams::flush(filter1_, cmp);
sl@0
   167
    }
sl@0
   168
sl@0
   169
    std::streamsize optimal_buffer_size() const
sl@0
   170
    {
sl@0
   171
        std::streamsize first = iostreams::optimal_buffer_size(filter1_);
sl@0
   172
        std::streamsize second = iostreams::optimal_buffer_size(filter2_);
sl@0
   173
        return first < second ? second : first;
sl@0
   174
    }
sl@0
   175
sl@0
   176
    template<typename Locale> // Avoid dependency on <locale>
sl@0
   177
    void imbue(const Locale& loc)
sl@0
   178
    {   // To do: consider using RAII.
sl@0
   179
        iostreams::imbue(filter1_, loc);
sl@0
   180
        iostreams::imbue(filter2_, loc);
sl@0
   181
    }
sl@0
   182
sl@0
   183
    Filter1& first() { return filter1_; }
sl@0
   184
    Filter2& second() { return filter2_; }
sl@0
   185
private:
sl@0
   186
    Filter1  filter1_;
sl@0
   187
    Filter2  filter2_;
sl@0
   188
};
sl@0
   189
sl@0
   190
template<typename Filter, typename FilterOrDevice>
sl@0
   191
struct composite_traits
sl@0
   192
    : mpl::if_<
sl@0
   193
          is_device<FilterOrDevice>,
sl@0
   194
          composite_device<Filter, FilterOrDevice>,
sl@0
   195
          composite_filter<Filter, FilterOrDevice>
sl@0
   196
      >
sl@0
   197
    { };
sl@0
   198
sl@0
   199
} // End namespace detail.
sl@0
   200
sl@0
   201
template<typename Filter, typename FilterOrDevice>
sl@0
   202
struct composite : detail::composite_traits<Filter, FilterOrDevice>::type {
sl@0
   203
    typedef typename detail::param_type<FilterOrDevice>::type param_type;
sl@0
   204
    typedef typename detail::composite_traits<Filter, FilterOrDevice>::type base;
sl@0
   205
    composite(const Filter& flt, param_type dev)
sl@0
   206
        : base(flt, dev)
sl@0
   207
        { }
sl@0
   208
};
sl@0
   209
sl@0
   210
//--------------Implementation of compose-------------------------------------//
sl@0
   211
sl@0
   212
// Note: The following workarounds are patterned after resolve.hpp. It has not
sl@0
   213
// yet been confirmed that they are necessary.
sl@0
   214
sl@0
   215
#ifndef BOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION //-------------------------//
sl@0
   216
# ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //-------------------------------//
sl@0
   217
sl@0
   218
template<typename Filter, typename FilterOrDevice>
sl@0
   219
composite<Filter, FilterOrDevice>
sl@0
   220
compose( const Filter& filter, const FilterOrDevice& fod
sl@0
   221
         BOOST_IOSTREAMS_DISABLE_IF_STREAM(FilterOrDevice) )
sl@0
   222
{ return composite<Filter, FilterOrDevice>(filter, fod); }
sl@0
   223
sl@0
   224
template<typename Filter, typename Ch, typename Tr>
sl@0
   225
composite< Filter, std::basic_streambuf<Ch, Tr> >
sl@0
   226
compose(const Filter& filter, std::basic_streambuf<Ch, Tr>& sb)
sl@0
   227
{ return composite< Filter, std::basic_streambuf<Ch, Tr> >(filter, sb); }
sl@0
   228
sl@0
   229
template<typename Filter, typename Ch, typename Tr>
sl@0
   230
composite< Filter, std::basic_istream<Ch, Tr> >
sl@0
   231
compose(const Filter& filter, std::basic_istream<Ch, Tr>& is)
sl@0
   232
{ return composite< Filter, std::basic_istream<Ch, Tr> >(filter, is); }
sl@0
   233
sl@0
   234
template<typename Filter, typename Ch, typename Tr>
sl@0
   235
composite< Filter, std::basic_ostream<Ch, Tr> >
sl@0
   236
compose(const Filter& filter, std::basic_ostream<Ch, Tr>& os)
sl@0
   237
{ return composite< Filter, std::basic_ostream<Ch, Tr> >(filter, os); }
sl@0
   238
sl@0
   239
template<typename Filter, typename Ch, typename Tr>
sl@0
   240
composite< Filter, std::basic_iostream<Ch, Tr> >
sl@0
   241
compose(const Filter& filter, std::basic_iostream<Ch, Tr>& io)
sl@0
   242
{ return composite< Filter, std::basic_iostream<Ch, Tr> >(filter, io); }
sl@0
   243
sl@0
   244
# else // # ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //---------------------//
sl@0
   245
sl@0
   246
template<typename Filter, typename FilterOrDevice>
sl@0
   247
composite<Filter, FilterOrDevice>
sl@0
   248
compose( const Filter& filter, const FilterOrDevice& fod
sl@0
   249
         BOOST_IOSTREAMS_DISABLE_IF_STREAM(FilterOrDevice) )
sl@0
   250
{ return composite<Filter, FilterOrDevice>(filter, fod); }
sl@0
   251
sl@0
   252
template<typename Filter>
sl@0
   253
composite<Filter, std::streambuf>
sl@0
   254
compose(const Filter& filter, std::streambuf& sb)
sl@0
   255
{ return composite<Filter, std::streambuf>(filter, sb); }
sl@0
   256
sl@0
   257
template<typename Filter>
sl@0
   258
composite<Filter, std::istream>
sl@0
   259
compose(const Filter& filter, std::istream& is)
sl@0
   260
{ return composite<Filter, std::istream>(filter, is); }
sl@0
   261
sl@0
   262
template<typename Filter>
sl@0
   263
composite<Filter, std::ostream>
sl@0
   264
compose(const Filter& filter, std::ostream& os)
sl@0
   265
{ return composite<Filter, std::ostream>(filter, os); }
sl@0
   266
sl@0
   267
template<typename Filter>
sl@0
   268
composite<Filter, std::iostream>
sl@0
   269
compose(const Filter& filter, std::iostream& io)
sl@0
   270
{ return composite<Filter, std::iostream>(filter, io); }
sl@0
   271
sl@0
   272
# endif // # ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //--------------------//
sl@0
   273
#else // #ifndef BOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION //----------------//
sl@0
   274
sl@0
   275
template<typename Filter, typename Stream>
sl@0
   276
composite<Filter, Stream>
sl@0
   277
compose(const Filter& flt, const Stream& strm, mpl::true_)
sl@0
   278
{   // Bad overload resolution.
sl@0
   279
    return composite<Filter, Stream>(flt, const_cast<Stream&>(strm));
sl@0
   280
}
sl@0
   281
sl@0
   282
template<typename Filter, typename FilterOrDevice>
sl@0
   283
composite<Filter, FilterOrDevice>
sl@0
   284
compose(const Filter& flt, const FilterOrDevice& fod, mpl::false_)
sl@0
   285
{ return composite<Filter, FilterOrDevice>(flt, fod); }
sl@0
   286
sl@0
   287
template<typename Filter, typename FilterOrDevice>
sl@0
   288
composite<Filter, FilterOrDevice>
sl@0
   289
compose( const Filter& flt, const FilterOrDevice& fod
sl@0
   290
         BOOST_IOSTREAMS_DISABLE_IF_STREAM(T) )
sl@0
   291
{ return compose(flt, fod, is_std_io<FilterOrDevice>()); }
sl@0
   292
sl@0
   293
# if !BOOST_WORKAROUND(__BORLANDC__, < 0x600) && \
sl@0
   294
     !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) && \
sl@0
   295
     !defined(__GNUC__) // ---------------------------------------------------//
sl@0
   296
sl@0
   297
template<typename Filter, typename FilterOrDevice>
sl@0
   298
composite<Filter, FilterOrDevice>
sl@0
   299
compose (const Filter& filter, FilterOrDevice& fod)
sl@0
   300
{ return composite<Filter, FilterOrDevice>(filter, fod); }
sl@0
   301
sl@0
   302
# endif // Borland 5.x, VC6-7.0 or GCC 2.9x //--------------------------------//
sl@0
   303
#endif // #ifndef BOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION //---------------//
sl@0
   304
sl@0
   305
//----------------------------------------------------------------------------//
sl@0
   306
sl@0
   307
namespace detail {
sl@0
   308
sl@0
   309
//--------------Implementation of composite_device---------------------------//
sl@0
   310
sl@0
   311
template<typename Filter, typename Device, typename Mode>
sl@0
   312
composite_device<Filter, Device, Mode>::composite_device
sl@0
   313
    (const Filter& flt, param_type dev)
sl@0
   314
    : filter_(flt), device_(dev)
sl@0
   315
    { }
sl@0
   316
sl@0
   317
template<typename Filter, typename Device, typename Mode>
sl@0
   318
inline std::streamsize composite_device<Filter, Device, Mode>::read
sl@0
   319
    (char_type* s, std::streamsize n)
sl@0
   320
{ return iostreams::read(filter_, device_, s, n); }
sl@0
   321
sl@0
   322
template<typename Filter, typename Device, typename Mode>
sl@0
   323
inline std::streamsize composite_device<Filter, Device, Mode>::write
sl@0
   324
    (const char_type* s, std::streamsize n)
sl@0
   325
{ return iostreams::write(filter_, device_, s, n); }
sl@0
   326
sl@0
   327
template<typename Filter, typename Device, typename Mode>
sl@0
   328
stream_offset composite_device<Filter, Device, Mode>::seek
sl@0
   329
    (stream_offset off, BOOST_IOS::seekdir way, BOOST_IOS::openmode which)
sl@0
   330
{ return iostreams::seek(filter_, device_, off, way, which); }
sl@0
   331
sl@0
   332
template<typename Filter, typename Device, typename Mode>
sl@0
   333
void composite_device<Filter, Device, Mode>::close()
sl@0
   334
{
sl@0
   335
    typedef typename mode_of<Device>::type device_mode;
sl@0
   336
    BOOST_IOS::openmode which =
sl@0
   337
        is_convertible<device_mode, input>() ?
sl@0
   338
            BOOST_IOS::in :
sl@0
   339
            BOOST_IOS::out;
sl@0
   340
    close(which);
sl@0
   341
}
sl@0
   342
sl@0
   343
template<typename Filter, typename Device, typename Mode>
sl@0
   344
void composite_device<Filter, Device, Mode>::close(BOOST_IOS::openmode which)
sl@0
   345
{
sl@0
   346
    bool                                 nothrow = false;
sl@0
   347
    external_closer<value_type>          close_device(device_, which, nothrow);
sl@0
   348
    external_closer<Filter, value_type>  close_filter(filter_, device_, which, nothrow);
sl@0
   349
}
sl@0
   350
sl@0
   351
template<typename Filter, typename Device, typename Mode>
sl@0
   352
bool composite_device<Filter, Device, Mode>::flush()
sl@0
   353
{   // To do: consider using RAII.
sl@0
   354
    bool r1 = iostreams::flush(filter_, device_);
sl@0
   355
    bool r2 = iostreams::flush(device_);
sl@0
   356
    return r1 && r2;
sl@0
   357
}
sl@0
   358
sl@0
   359
template<typename Filter, typename Device, typename Mode>
sl@0
   360
std::streamsize
sl@0
   361
composite_device<Filter, Device, Mode>::optimal_buffer_size() const
sl@0
   362
{ return iostreams::optimal_buffer_size(device_); }
sl@0
   363
sl@0
   364
} // End namespace detail.
sl@0
   365
sl@0
   366
} } // End namespaces iostreams, boost.
sl@0
   367
sl@0
   368
#endif // #ifndef BOOST_IOSTREAMS_COMPOSE_HPP_INCLUDED