Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:44:34

0001 // (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
0002 // (C) Copyright 2005-2007 Jonathan Turkanis
0003 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0004 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
0005 
0006 // See http://www.boost.org/libs/iostreams for documentation.
0007 
0008 #ifndef BOOST_IOSTREAMS_TEE_HPP_INCLUDED
0009 #define BOOST_IOSTREAMS_TEE_HPP_INCLUDED
0010 
0011 #if defined(_MSC_VER)
0012 # pragma once
0013 #endif
0014 
0015 #include <boost/assert.hpp>
0016 #include <boost/config.hpp>  // BOOST_DEDUCE_TYPENAME.
0017 #include <boost/iostreams/categories.hpp>
0018 #include <boost/iostreams/detail/adapter/device_adapter.hpp>
0019 #include <boost/iostreams/detail/adapter/filter_adapter.hpp>
0020 #include <boost/iostreams/detail/call_traits.hpp>
0021 #include <boost/iostreams/detail/execute.hpp>
0022 #include <boost/iostreams/detail/functional.hpp>  // call_close_all 
0023 #include <boost/iostreams/operations.hpp>
0024 #include <boost/iostreams/pipeline.hpp>
0025 #include <boost/iostreams/traits.hpp>
0026 #include <boost/static_assert.hpp>
0027 #include <boost/type_traits/is_convertible.hpp>
0028 #include <boost/type_traits/is_same.hpp>
0029 
0030 namespace boost { namespace iostreams {
0031 
0032 //
0033 // Template name: tee_filter.
0034 // Template parameters:
0035 //      Device - A blocking Sink.
0036 //
0037 template<typename Device>
0038 class tee_filter : public detail::filter_adapter<Device> {
0039 public:
0040     typedef typename detail::param_type<Device>::type  param_type;
0041     typedef typename char_type_of<Device>::type        char_type;
0042     struct category
0043         : dual_use_filter_tag,
0044           multichar_tag,
0045           closable_tag,
0046           flushable_tag,
0047           localizable_tag,
0048           optimally_buffered_tag
0049         { };
0050 
0051     BOOST_STATIC_ASSERT(is_device<Device>::value);
0052     BOOST_STATIC_ASSERT((
0053         is_convertible< // Using mode_of causes failures on VC6-7.0.
0054             BOOST_DEDUCED_TYPENAME iostreams::category_of<Device>::type, output
0055         >::value
0056     ));
0057 
0058     explicit tee_filter(param_type dev) 
0059         : detail::filter_adapter<Device>(dev) 
0060         { }
0061 
0062     template<typename Source>
0063     std::streamsize read(Source& src, char_type* s, std::streamsize n)
0064     {
0065         std::streamsize result = iostreams::read(src, s, n);
0066         if (result != -1) {
0067             std::streamsize result2 = iostreams::write(this->component(), s, result);
0068             (void) result2; // Suppress 'unused variable' warning.
0069             BOOST_ASSERT(result == result2);
0070         }
0071         return result;
0072     }
0073 
0074     template<typename Sink>
0075     std::streamsize write(Sink& snk, const char_type* s, std::streamsize n)
0076     {
0077         std::streamsize result = iostreams::write(snk, s, n);
0078         std::streamsize result2 = iostreams::write(this->component(), s, result);
0079         (void) result2; // Suppress 'unused variable' warning.
0080         BOOST_ASSERT(result == result2);
0081         return result;
0082     }
0083 
0084     template<typename Next>
0085     void close(Next&, BOOST_IOS::openmode)
0086     { 
0087         detail::close_all(this->component());
0088     }
0089 
0090     template<typename Sink>
0091     bool flush(Sink& snk)
0092     {
0093         bool r1 = iostreams::flush(snk);
0094         bool r2 = iostreams::flush(this->component());
0095         return r1 && r2;
0096     }
0097 };
0098 BOOST_IOSTREAMS_PIPABLE(tee_filter, 1)
0099 
0100 //
0101 // Template name: tee_device.
0102 // Template parameters:
0103 //      Device - A blocking Device.
0104 //      Sink - A blocking Sink.
0105 //
0106 template<typename Device, typename Sink>
0107 class tee_device {
0108 public:
0109     typedef typename detail::param_type<Device>::type  device_param;
0110     typedef typename detail::param_type<Sink>::type    sink_param;
0111     typedef typename detail::value_type<Device>::type  device_value;
0112     typedef typename detail::value_type<Sink>::type    sink_value;
0113     typedef typename char_type_of<Device>::type        char_type;
0114     typedef typename
0115             mpl::if_<
0116                  is_convertible<
0117                      BOOST_DEDUCED_TYPENAME 
0118                          iostreams::category_of<Device>::type, 
0119                      output
0120                  >,
0121                  output,
0122                  input
0123             >::type                                    mode;
0124     BOOST_STATIC_ASSERT(is_device<Device>::value);
0125     BOOST_STATIC_ASSERT(is_device<Sink>::value);
0126     BOOST_STATIC_ASSERT((
0127         is_same<
0128             char_type, 
0129             BOOST_DEDUCED_TYPENAME char_type_of<Sink>::type
0130         >::value
0131     ));
0132     BOOST_STATIC_ASSERT((
0133         is_convertible<
0134             BOOST_DEDUCED_TYPENAME iostreams::category_of<Sink>::type, 
0135             output
0136         >::value
0137     ));
0138     struct category
0139         : mode,
0140           device_tag,
0141           closable_tag,
0142           flushable_tag,
0143           localizable_tag,
0144           optimally_buffered_tag
0145         { };
0146     tee_device(device_param device, sink_param sink) 
0147         : dev_(device), sink_(sink)
0148         { }
0149     std::streamsize read(char_type* s, std::streamsize n)
0150     {
0151         BOOST_STATIC_ASSERT((
0152             is_convertible<
0153                 BOOST_DEDUCED_TYPENAME iostreams::category_of<Device>::type, input
0154             >::value
0155         ));
0156         std::streamsize result1 = iostreams::read(dev_, s, n);
0157         if (result1 != -1) {
0158             std::streamsize result2 = iostreams::write(sink_, s, result1);
0159             (void) result1; // Suppress 'unused variable' warning.
0160             (void) result2;
0161             BOOST_ASSERT(result1 == result2);
0162         }
0163         return result1;
0164     }
0165     std::streamsize write(const char_type* s, std::streamsize n)
0166     {
0167         BOOST_STATIC_ASSERT((
0168             is_convertible<
0169                 BOOST_DEDUCED_TYPENAME iostreams::category_of<Device>::type, output
0170             >::value
0171         ));
0172         std::streamsize result1 = iostreams::write(dev_, s, n);
0173         std::streamsize result2 = iostreams::write(sink_, s, n);
0174         (void) result1; // Suppress 'unused variable' warning.
0175         (void) result2;
0176         BOOST_ASSERT(result1 == n && result2 == n);
0177         return n;
0178     }
0179     void close()
0180     {
0181         detail::execute_all( detail::call_close_all(dev_),
0182                              detail::call_close_all(sink_) );
0183     }
0184     bool flush()
0185     {
0186         bool r1 = iostreams::flush(dev_);
0187         bool r2 = iostreams::flush(sink_);
0188         return r1 && r2;
0189     }
0190     template<typename Locale>
0191     void imbue(const Locale& loc)
0192     {
0193         iostreams::imbue(dev_, loc);
0194         iostreams::imbue(sink_, loc);
0195     }
0196     std::streamsize optimal_buffer_size() const 
0197     {
0198         return (std::max) ( iostreams::optimal_buffer_size(dev_), 
0199                             iostreams::optimal_buffer_size(sink_) );
0200     }
0201 private:
0202     device_value  dev_;
0203     sink_value    sink_;
0204 };
0205 
0206 template<typename Sink>
0207 tee_filter<Sink> tee(Sink& snk) 
0208 { return tee_filter<Sink>(snk); }
0209 
0210 template<typename Sink>
0211 tee_filter<Sink> tee(const Sink& snk) 
0212 { return tee_filter<Sink>(snk); }
0213 
0214 template<typename Device, typename Sink>
0215 tee_device<Device, Sink> tee(Device& dev, Sink& sink) 
0216 { return tee_device<Device, Sink>(dev, sink); }
0217 
0218 template<typename Device, typename Sink>
0219 tee_device<Device, Sink> tee(const Device& dev, Sink& sink) 
0220 { return tee_device<Device, Sink>(dev, sink); }
0221 
0222 template<typename Device, typename Sink>
0223 tee_device<Device, Sink> tee(Device& dev, const Sink& sink) 
0224 { return tee_device<Device, Sink>(dev, sink); }
0225 
0226 template<typename Device, typename Sink>
0227 tee_device<Device, Sink> tee(const Device& dev, const Sink& sink) 
0228 { return tee_device<Device, Sink>(dev, sink); }
0229 
0230 } } // End namespaces iostreams, boost.
0231 
0232 #endif // #ifndef BOOST_IOSTREAMS_TEE_HPP_INCLUDED