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