/usr/include/boost/iostreams/tee.hpp is in libboost1.62-dev 1.62.0+dfsg-5.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 | // (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
// (C) Copyright 2005-2007 Jonathan Turkanis
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
// See http://www.boost.org/libs/iostreams for documentation.
#ifndef BOOST_IOSTREAMS_TEE_HPP_INCLUDED
#define BOOST_IOSTREAMS_TEE_HPP_INCLUDED
#if defined(_MSC_VER)
# pragma once
#endif
#include <boost/assert.hpp>
#include <boost/config.hpp> // BOOST_DEDUCE_TYPENAME.
#include <boost/iostreams/categories.hpp>
#include <boost/iostreams/detail/adapter/device_adapter.hpp>
#include <boost/iostreams/detail/adapter/filter_adapter.hpp>
#include <boost/iostreams/detail/call_traits.hpp>
#include <boost/iostreams/detail/execute.hpp>
#include <boost/iostreams/detail/functional.hpp> // call_close_all
#include <boost/iostreams/operations.hpp>
#include <boost/iostreams/pipeline.hpp>
#include <boost/iostreams/traits.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/type_traits/is_same.hpp>
namespace boost { namespace iostreams {
//
// Template name: tee_filter.
// Template parameters:
// Device - A blocking Sink.
//
template<typename Device>
class tee_filter : public detail::filter_adapter<Device> {
public:
typedef typename detail::param_type<Device>::type param_type;
typedef typename char_type_of<Device>::type char_type;
struct category
: dual_use_filter_tag,
multichar_tag,
closable_tag,
flushable_tag,
localizable_tag,
optimally_buffered_tag
{ };
BOOST_STATIC_ASSERT(is_device<Device>::value);
BOOST_STATIC_ASSERT((
is_convertible< // Using mode_of causes failures on VC6-7.0.
BOOST_DEDUCED_TYPENAME iostreams::category_of<Device>::type, output
>::value
));
explicit tee_filter(param_type dev)
: detail::filter_adapter<Device>(dev)
{ }
template<typename Source>
std::streamsize read(Source& src, char_type* s, std::streamsize n)
{
std::streamsize result = iostreams::read(src, s, n);
if (result != -1) {
std::streamsize result2 = iostreams::write(this->component(), s, result);
(void) result2; // Suppress 'unused variable' warning.
BOOST_ASSERT(result == result2);
}
return result;
}
template<typename Sink>
std::streamsize write(Sink& snk, const char_type* s, std::streamsize n)
{
std::streamsize result = iostreams::write(snk, s, n);
std::streamsize result2 = iostreams::write(this->component(), s, result);
(void) result2; // Suppress 'unused variable' warning.
BOOST_ASSERT(result == result2);
return result;
}
template<typename Next>
void close(Next&, BOOST_IOS::openmode)
{
detail::close_all(this->component());
}
template<typename Sink>
bool flush(Sink& snk)
{
bool r1 = iostreams::flush(snk);
bool r2 = iostreams::flush(this->component());
return r1 && r2;
}
};
BOOST_IOSTREAMS_PIPABLE(tee_filter, 1)
//
// Template name: tee_device.
// Template parameters:
// Device - A blocking Device.
// Sink - A blocking Sink.
//
template<typename Device, typename Sink>
class tee_device {
public:
typedef typename detail::param_type<Device>::type device_param;
typedef typename detail::param_type<Sink>::type sink_param;
typedef typename detail::value_type<Device>::type device_value;
typedef typename detail::value_type<Sink>::type sink_value;
typedef typename char_type_of<Device>::type char_type;
typedef typename
mpl::if_<
is_convertible<
BOOST_DEDUCED_TYPENAME
iostreams::category_of<Device>::type,
output
>,
output,
input
>::type mode;
BOOST_STATIC_ASSERT(is_device<Device>::value);
BOOST_STATIC_ASSERT(is_device<Sink>::value);
BOOST_STATIC_ASSERT((
is_same<
char_type,
BOOST_DEDUCED_TYPENAME char_type_of<Sink>::type
>::value
));
BOOST_STATIC_ASSERT((
is_convertible<
BOOST_DEDUCED_TYPENAME iostreams::category_of<Sink>::type,
output
>::value
));
struct category
: mode,
device_tag,
closable_tag,
flushable_tag,
localizable_tag,
optimally_buffered_tag
{ };
tee_device(device_param device, sink_param sink)
: dev_(device), sink_(sink)
{ }
std::streamsize read(char_type* s, std::streamsize n)
{
BOOST_STATIC_ASSERT((
is_convertible<
BOOST_DEDUCED_TYPENAME iostreams::category_of<Device>::type, input
>::value
));
std::streamsize result1 = iostreams::read(dev_, s, n);
if (result1 != -1) {
std::streamsize result2 = iostreams::write(sink_, s, result1);
(void) result1; // Suppress 'unused variable' warning.
(void) result2;
BOOST_ASSERT(result1 == result2);
}
return result1;
}
std::streamsize write(const char_type* s, std::streamsize n)
{
BOOST_STATIC_ASSERT((
is_convertible<
BOOST_DEDUCED_TYPENAME iostreams::category_of<Device>::type, output
>::value
));
std::streamsize result1 = iostreams::write(dev_, s, n);
std::streamsize result2 = iostreams::write(sink_, s, n);
(void) result1; // Suppress 'unused variable' warning.
(void) result2;
BOOST_ASSERT(result1 == n && result2 == n);
return n;
}
void close()
{
detail::execute_all( detail::call_close_all(dev_),
detail::call_close_all(sink_) );
}
bool flush()
{
bool r1 = iostreams::flush(dev_);
bool r2 = iostreams::flush(sink_);
return r1 && r2;
}
template<typename Locale>
void imbue(const Locale& loc)
{
iostreams::imbue(dev_, loc);
iostreams::imbue(sink_, loc);
}
std::streamsize optimal_buffer_size() const
{
return (std::max) ( iostreams::optimal_buffer_size(dev_),
iostreams::optimal_buffer_size(sink_) );
}
private:
device_value dev_;
sink_value sink_;
};
template<typename Sink>
tee_filter<Sink> tee(Sink& snk)
{ return tee_filter<Sink>(snk); }
template<typename Sink>
tee_filter<Sink> tee(const Sink& snk)
{ return tee_filter<Sink>(snk); }
template<typename Device, typename Sink>
tee_device<Device, Sink> tee(Device& dev, Sink& sink)
{ return tee_device<Device, Sink>(dev, sink); }
template<typename Device, typename Sink>
tee_device<Device, Sink> tee(const Device& dev, Sink& sink)
{ return tee_device<Device, Sink>(dev, sink); }
template<typename Device, typename Sink>
tee_device<Device, Sink> tee(Device& dev, const Sink& sink)
{ return tee_device<Device, Sink>(dev, sink); }
template<typename Device, typename Sink>
tee_device<Device, Sink> tee(const Device& dev, const Sink& sink)
{ return tee_device<Device, Sink>(dev, sink); }
} } // End namespaces iostreams, boost.
#endif // #ifndef BOOST_IOSTREAMS_TEE_HPP_INCLUDED
|