ossrv_pub/boost_apis/boost/iostreams/tee.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 #ifndef BOOST_IOSTREAMS_TEE_HPP_INCLUDED
       
     8 #define BOOST_IOSTREAMS_TEE_HPP_INCLUDED
       
     9 
       
    10 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
       
    11 # pragma once
       
    12 #endif
       
    13 
       
    14 #include <cassert>
       
    15 #include <boost/config.hpp>  // BOOST_DEDUCE_TYPENAME.
       
    16 #include <boost/iostreams/categories.hpp>
       
    17 #include <boost/iostreams/detail/adapter/basic_adapter.hpp>
       
    18 #include <boost/iostreams/detail/call_traits.hpp>
       
    19 #include <boost/iostreams/detail/closer.hpp>
       
    20 #include <boost/iostreams/operations.hpp>
       
    21 #include <boost/iostreams/pipeline.hpp>
       
    22 #include <boost/iostreams/traits.hpp>
       
    23 #include <boost/static_assert.hpp>
       
    24 #include <boost/type_traits/is_convertible.hpp>
       
    25 #include <boost/type_traits/is_same.hpp>
       
    26 
       
    27 namespace boost { namespace iostreams {
       
    28 
       
    29 //
       
    30 // Template name: tee_filter.
       
    31 // Template paramters:
       
    32 //      Device - A blocking Sink.
       
    33 //
       
    34 template<typename Device>
       
    35 class tee_filter : public detail::basic_adapter<Device> {
       
    36 public:
       
    37     typedef typename detail::param_type<Device>::type  param_type;
       
    38     typedef typename char_type_of<Device>::type        char_type;
       
    39     struct category
       
    40         : multichar_output_filter_tag,
       
    41           closable_tag,
       
    42           flushable_tag,
       
    43           localizable_tag,
       
    44           optimally_buffered_tag
       
    45         { };
       
    46 
       
    47     BOOST_STATIC_ASSERT((
       
    48         is_convertible< // Using mode_of causes failures on VC6-7.0.
       
    49             BOOST_DEDUCED_TYPENAME iostreams::category_of<Device>::type, output
       
    50         >::value
       
    51     ));
       
    52 
       
    53     explicit tee_filter(param_type dev) 
       
    54         : detail::basic_adapter<Device>(dev) 
       
    55         { }
       
    56 
       
    57     template<typename Sink>
       
    58     std::streamsize write(Sink& snk, const char_type* s, std::streamsize n)
       
    59     {
       
    60         std::streamsize result = iostreams::write(snk, s, n);
       
    61         std::streamsize result2 = iostreams::write(this->component(), s, result);
       
    62         (void) result2; // Suppress 'unused variable' warning.
       
    63         assert(result == result2);
       
    64         return result;
       
    65     }
       
    66 
       
    67     template<typename Next>
       
    68     void close( Next&,
       
    69                 BOOST_IOS::openmode which =
       
    70                     BOOST_IOS::in | BOOST_IOS::out )
       
    71     { iostreams::close(this->component(), which); }
       
    72 
       
    73     template<typename Sink>
       
    74     bool flush(Sink& snk)
       
    75     {
       
    76         bool r1 = iostreams::flush(snk);
       
    77         bool r2 = iostreams::flush(this->component());
       
    78         return r1 && r2;
       
    79     }
       
    80 };
       
    81 BOOST_IOSTREAMS_PIPABLE(tee_filter, 1)
       
    82 
       
    83 //
       
    84 // Template name: tee_device.
       
    85 // Template paramters:
       
    86 //      Sink1 - A blocking Sink.
       
    87 //      Sink2 - A blocking Sink.
       
    88 //
       
    89 template<typename Sink1, typename Sink2>
       
    90 class tee_device {
       
    91 public:
       
    92     typedef typename detail::param_type<Sink1>::type  param_type1;
       
    93     typedef typename detail::param_type<Sink2>::type  param_type2;
       
    94     typedef typename detail::value_type<Sink1>::type  value_type1;
       
    95     typedef typename detail::value_type<Sink2>::type  value_type2;
       
    96     typedef typename char_type_of<Sink1>::type        char_type;
       
    97     BOOST_STATIC_ASSERT((
       
    98         is_same<
       
    99             char_type, 
       
   100             BOOST_DEDUCED_TYPENAME char_type_of<Sink2>::type
       
   101         >::value
       
   102     ));
       
   103     BOOST_STATIC_ASSERT((
       
   104         is_convertible< // Using mode_of causes failures on VC6-7.0.
       
   105             BOOST_DEDUCED_TYPENAME iostreams::category_of<Sink1>::type, output
       
   106         >::value
       
   107     ));
       
   108     BOOST_STATIC_ASSERT((
       
   109         is_convertible< // Using mode_of causes failures on VC6-7.0.
       
   110             BOOST_DEDUCED_TYPENAME iostreams::category_of<Sink2>::type, output
       
   111         >::value
       
   112     ));
       
   113     struct category
       
   114         : output,
       
   115           device_tag,
       
   116           closable_tag,
       
   117           flushable_tag,
       
   118           localizable_tag,
       
   119           optimally_buffered_tag
       
   120         { };
       
   121     tee_device(param_type1 sink1, param_type2 sink2) 
       
   122         : sink1_(sink1), sink2_(sink2)
       
   123         { }
       
   124     std::streamsize write(const char_type* s, std::streamsize n)
       
   125     {
       
   126         std::streamsize result1 = iostreams::write(sink1_, s, n);
       
   127         std::streamsize result2 = iostreams::write(sink2_, s, n);
       
   128         (void) result1; // Suppress 'unused variable' warning.
       
   129         (void) result2;
       
   130         assert(result1 == n && result2 == n);
       
   131         return n;
       
   132     }
       
   133     void close(BOOST_IOS::openmode which = BOOST_IOS::in | BOOST_IOS::out)
       
   134     { 
       
   135         detail::external_closer<Sink2> close2(sink2_, which);
       
   136         detail::external_closer<Sink1> close1(sink1_, which);
       
   137     }
       
   138     bool flush()
       
   139     {
       
   140         bool r1 = iostreams::flush(sink1_);
       
   141         bool r2 = iostreams::flush(sink2_);
       
   142         return r1 && r2;
       
   143     }
       
   144     template<typename Locale>
       
   145     void imbue(const Locale& loc)
       
   146     {
       
   147         iostreams::imbue(sink1_, loc);
       
   148         iostreams::imbue(sink2_, loc);
       
   149     }
       
   150     std::streamsize optimal_buffer_size() const 
       
   151     {
       
   152         return (std::max) ( iostreams::optimal_buffer_size(sink1_), 
       
   153                             iostreams::optimal_buffer_size(sink2_) );
       
   154     }
       
   155 private:
       
   156     value_type1 sink1_;
       
   157     value_type2 sink2_;
       
   158 };
       
   159 
       
   160 template<typename Sink>
       
   161 tee_filter<Sink> tee(const Sink& snk) 
       
   162 { return tee_filter<Sink>(snk); }
       
   163 
       
   164 template<typename Sink1, typename Sink2>
       
   165 tee_device<Sink1, Sink2> tee(const Sink1& sink1, const Sink2& sink2) 
       
   166 { return tee_device<Sink1, Sink2>(sink1, sink2); }
       
   167 
       
   168 } } // End namespaces iostreams, boost.
       
   169 
       
   170 #endif // #ifndef BOOST_IOSTREAMS_TEE_HPP_INCLUDED