Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:38:53

0001 // (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
0002 // (C) Copyright 2003-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 // To do: add support for random-access.
0009 
0010 #ifndef BOOST_IOSTREAMS_COMBINE_HPP_INCLUDED
0011 #define BOOST_IOSTREAMS_COMBINE_HPP_INCLUDED
0012 
0013 #if defined(_MSC_VER)
0014 # pragma once
0015 #endif              
0016 
0017 #include <boost/config.hpp> // NO_STD_LOCALE, DEDUCED_TYPENAME.
0018 #ifndef BOOST_NO_STD_LOCALE
0019 # include <locale>
0020 #endif
0021 #include <boost/iostreams/detail/ios.hpp>   
0022 #include <boost/iostreams/detail/wrap_unwrap.hpp>       
0023 #include <boost/iostreams/traits.hpp>         
0024 #include <boost/iostreams/operations.hpp>        
0025 #include <boost/mpl/if.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 // Must come last.
0031 #include <boost/iostreams/detail/config/disable_warnings.hpp>
0032 
0033 namespace boost { namespace iostreams {
0034 
0035 namespace detail {
0036 
0037 //
0038 // Template name: combined_device.
0039 // Description: Model of Device defined in terms of a Source/Sink pair.
0040 // Template parameters:
0041 //      Source - A model of Source, with the same char_type and traits_type
0042 //          as Sink.
0043 //      Sink - A model of Sink, with the same char_type and traits_type
0044 //          as Source.
0045 //
0046 template<typename Source, typename Sink>
0047 class combined_device {
0048 private:
0049     typedef typename category_of<Source>::type  in_category;
0050     typedef typename category_of<Sink>::type    out_category;
0051     typedef typename char_type_of<Sink>::type   sink_char_type;
0052 public:
0053     typedef typename char_type_of<Source>::type char_type;
0054     struct category
0055         : bidirectional, 
0056           device_tag, 
0057           closable_tag, 
0058           localizable_tag
0059         { };
0060     BOOST_STATIC_ASSERT(is_device<Source>::value);
0061     BOOST_STATIC_ASSERT(is_device<Sink>::value);
0062     BOOST_STATIC_ASSERT((is_convertible<in_category, input>::value));
0063     BOOST_STATIC_ASSERT((is_convertible<out_category, output>::value));
0064     BOOST_STATIC_ASSERT((is_same<char_type, sink_char_type>::value));
0065     combined_device(const Source& src, const Sink& snk);
0066     std::streamsize read(char_type* s, std::streamsize n);
0067     std::streamsize write(const char_type* s, std::streamsize n);
0068     void close(BOOST_IOS::openmode);
0069     #ifndef BOOST_NO_STD_LOCALE
0070         void imbue(const std::locale& loc);
0071     #endif
0072 private:
0073     Source  src_;
0074     Sink    sink_;
0075 };
0076 
0077 //
0078 // Template name: combined_filter.
0079 // Description: Model of Device defined in terms of a Source/Sink pair.
0080 // Template parameters:
0081 //      InputFilter - A model of InputFilter, with the same char_type as 
0082 //          OutputFilter.
0083 //      OutputFilter - A model of OutputFilter, with the same char_type as 
0084 //          InputFilter.
0085 //
0086 template<typename InputFilter, typename OutputFilter>
0087 class combined_filter {
0088 private:
0089     typedef typename category_of<InputFilter>::type    in_category;
0090     typedef typename category_of<OutputFilter>::type   out_category;
0091     typedef typename char_type_of<OutputFilter>::type  output_char_type;
0092 public:
0093     typedef typename char_type_of<InputFilter>::type   char_type;
0094     struct category 
0095         : multichar_bidirectional_filter_tag,
0096           closable_tag, 
0097           localizable_tag
0098         { };
0099     BOOST_STATIC_ASSERT(is_filter<InputFilter>::value);
0100     BOOST_STATIC_ASSERT(is_filter<OutputFilter>::value);
0101     BOOST_STATIC_ASSERT((is_convertible<in_category, input>::value));
0102     BOOST_STATIC_ASSERT((is_convertible<out_category, output>::value));
0103     BOOST_STATIC_ASSERT((is_same<char_type, output_char_type>::value));
0104     combined_filter(const InputFilter& in, const OutputFilter& out);
0105 
0106     template<typename Source>
0107     std::streamsize read(Source& src, char_type* s, std::streamsize n)
0108     { return boost::iostreams::read(in_, src, s, n); }
0109 
0110     template<typename Sink>
0111     std::streamsize write(Sink& snk, const char_type* s, std::streamsize n)
0112     { return boost::iostreams::write(out_, snk, s, n); }
0113 
0114     template<typename Sink>
0115     void close(Sink& snk, BOOST_IOS::openmode which)
0116     {
0117         if (which == BOOST_IOS::in) {
0118             if (is_convertible<in_category, dual_use>::value) {
0119                 iostreams::close(in_, snk, BOOST_IOS::in);
0120             } else {
0121                 detail::close_all(in_, snk);
0122             }
0123         }
0124         if (which == BOOST_IOS::out) {
0125             if (is_convertible<out_category, dual_use>::value) {
0126                 iostreams::close(out_, snk, BOOST_IOS::out);
0127             } else {
0128                 detail::close_all(out_, snk);
0129             }
0130         }
0131     }
0132     #ifndef BOOST_NO_STD_LOCALE
0133         void imbue(const std::locale& loc);
0134     #endif
0135 private:
0136     InputFilter   in_;
0137     OutputFilter  out_;
0138 };
0139 
0140 template<typename In, typename Out>
0141 struct combination_traits 
0142     : mpl::if_<
0143           is_device<In>,
0144           combined_device<
0145               typename wrapped_type<In>::type,
0146               typename wrapped_type<Out>::type
0147           >,
0148           combined_filter<
0149               typename wrapped_type<In>::type,
0150               typename wrapped_type<Out>::type
0151           >
0152       >
0153     { };
0154 
0155 } // End namespace detail.
0156 
0157 template<typename In, typename Out>
0158 struct combination : detail::combination_traits<In, Out>::type {
0159     typedef typename detail::combination_traits<In, Out>::type  base_type;
0160     typedef typename detail::wrapped_type<In>::type          in_type;
0161     typedef typename detail::wrapped_type<Out>::type         out_type;
0162     combination(const in_type& in, const out_type& out)
0163         : base_type(in, out) { }
0164 };
0165 
0166 namespace detail {
0167 
0168 // Workaround for VC6 ETI bug.
0169 template<typename In, typename Out>
0170 struct combine_traits {
0171     typedef combination<
0172                 BOOST_DEDUCED_TYPENAME detail::unwrapped_type<In>::type, 
0173                 BOOST_DEDUCED_TYPENAME detail::unwrapped_type<Out>::type
0174             > type;
0175 };
0176 
0177 } // End namespace detail.
0178 
0179 //
0180 // Template name: combine.
0181 // Description: Takes a Source/Sink pair or InputFilter/OutputFilter pair and
0182 //      returns a Source or Filter which performs input using the first member
0183 //      of the pair and output using the second member of the pair.
0184 // Template parameters:
0185 //      In - A model of Source or InputFilter, with the same char_type as Out.
0186 //      Out - A model of Sink or OutputFilter, with the same char_type as In.
0187 //
0188 template<typename In, typename Out>
0189 typename detail::combine_traits<In, Out>::type
0190 combine(const In& in, const Out& out) 
0191 { 
0192     typedef typename detail::combine_traits<In, Out>::type return_type;
0193     return return_type(in, out); 
0194 }
0195 
0196 //----------------------------------------------------------------------------//
0197 
0198 namespace detail {
0199 
0200 //--------------Implementation of combined_device-----------------------------//
0201 
0202 template<typename Source, typename Sink>
0203 inline combined_device<Source, Sink>::combined_device
0204     (const Source& src, const Sink& snk)
0205     : src_(src), sink_(snk) { }
0206 
0207 template<typename Source, typename Sink>
0208 inline std::streamsize
0209 combined_device<Source, Sink>::read(char_type* s, std::streamsize n)
0210 { return iostreams::read(src_, s, n); }
0211 
0212 template<typename Source, typename Sink>
0213 inline std::streamsize
0214 combined_device<Source, Sink>::write(const char_type* s, std::streamsize n)
0215 { return iostreams::write(sink_, s, n); }
0216 
0217 template<typename Source, typename Sink>
0218 inline void
0219 combined_device<Source, Sink>::close(BOOST_IOS::openmode which)
0220 { 
0221     if (which == BOOST_IOS::in)
0222         detail::close_all(src_); 
0223     if (which == BOOST_IOS::out)
0224         detail::close_all(sink_); 
0225 }
0226 
0227 #ifndef BOOST_NO_STD_LOCALE
0228     template<typename Source, typename Sink>
0229     void combined_device<Source, Sink>::imbue(const std::locale& loc)
0230     {
0231         iostreams::imbue(src_, loc);
0232         iostreams::imbue(sink_, loc);
0233     }
0234 #endif
0235 
0236 //--------------Implementation of filter_pair---------------------------------//
0237 
0238 template<typename InputFilter, typename OutputFilter>
0239 inline combined_filter<InputFilter, OutputFilter>::combined_filter
0240     (const InputFilter& in, const OutputFilter& out) : in_(in), out_(out)
0241     { }
0242 
0243 #ifndef BOOST_NO_STD_LOCALE
0244     template<typename InputFilter, typename OutputFilter>
0245     void combined_filter<InputFilter, OutputFilter>::imbue
0246         (const std::locale& loc)
0247     {
0248         iostreams::imbue(in_, loc);
0249         iostreams::imbue(out_, loc);
0250     }
0251 #endif
0252 
0253 
0254 } // End namespace detail.
0255 
0256 } } // End namespaces iostreams, boost.
0257 
0258 #include <boost/iostreams/detail/config/enable_warnings.hpp>
0259 
0260 #endif // #ifndef BOOST_IOSTREAMS_COMBINE_HPP_INCLUDED