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