annotate DEPENDENCIES/generic/include/boost/iostreams/tee.hpp @ 133:4acb5d8d80b6 tip

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