ossrv_pub/boost_apis/boost/iostreams/combine.hpp
changeset 31 ce057bb09d0b
parent 0 e4d67989cc36
equal deleted inserted replaced
30:e20de85af2ee 31:ce057bb09d0b
       
     1 // (C) Copyright Jonathan Turkanis 2003.
       
     2 // Distributed under the Boost Software License, Version 1.0. (See accompanying
       
     3 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
       
     4 
       
     5 // See http://www.boost.org/libs/iostreams for documentation.
       
     6 
       
     7 // To do: add support for random-access.
       
     8 
       
     9 #ifndef BOOST_IOSTREAMS_COMBINE_HPP_INCLUDED
       
    10 #define BOOST_IOSTREAMS_COMBINE_HPP_INCLUDED
       
    11 
       
    12 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
       
    13 # pragma once
       
    14 #endif              
       
    15 
       
    16 #include <boost/config.hpp> // NO_STD_LOCALE, DEDUCED_TYPENAME.
       
    17 #ifndef BOOST_NO_STD_LOCALE
       
    18 # include <locale>
       
    19 #endif
       
    20 #include <boost/iostreams/detail/ios.hpp>   
       
    21 #include <boost/iostreams/detail/wrap_unwrap.hpp>       
       
    22 #include <boost/iostreams/traits.hpp>         
       
    23 #include <boost/iostreams/operations.hpp>        
       
    24 #include <boost/mpl/if.hpp>    
       
    25 #include <boost/static_assert.hpp>  
       
    26 #include <boost/type_traits/is_convertible.hpp>
       
    27 #include <boost/type_traits/is_same.hpp> 
       
    28 
       
    29 namespace boost { namespace iostreams {
       
    30 
       
    31 namespace detail {
       
    32 
       
    33 //
       
    34 // Template name: combined_device.
       
    35 // Description: Model of Device defined in terms of a Source/Sink pair.
       
    36 // Template paramters:
       
    37 //      Source - A model of Source, with the same char_type and traits_type
       
    38 //          as Sink.
       
    39 //      Sink - A model of Sink, with the same char_type and traits_type
       
    40 //          as Source.
       
    41 //
       
    42 template<typename Source, typename Sink>
       
    43 class combined_device {
       
    44 public:
       
    45     typedef typename char_type_of<Source>::type char_type;
       
    46     struct category
       
    47         : bidirectional, 
       
    48           device_tag, 
       
    49           closable_tag, 
       
    50           localizable_tag
       
    51         { };
       
    52     combined_device(const Source& src, const Sink& snk);
       
    53     std::streamsize read(char_type* s, std::streamsize n);
       
    54     std::streamsize write(const char_type* s, std::streamsize n);
       
    55     void close(BOOST_IOS::openmode);
       
    56     #ifndef BOOST_NO_STD_LOCALE
       
    57         void imbue(const std::locale& loc);
       
    58     #endif
       
    59 private:
       
    60     typedef typename char_type_of<Sink>::type sink_char_type;
       
    61     BOOST_STATIC_ASSERT((is_same<char_type, sink_char_type>::value));
       
    62     Source  src_;
       
    63     Sink    sink_;
       
    64 };
       
    65 
       
    66 //
       
    67 // Template name: combined_filter.
       
    68 // Description: Model of Device defined in terms of a Source/Sink pair.
       
    69 // Template paramters:
       
    70 //      InputFilter - A model of InputFilter, with the same char_type as 
       
    71 //          OutputFilter.
       
    72 //      OutputFilter - A model of OutputFilter, with the same char_type as 
       
    73 //          InputFilter.
       
    74 //
       
    75 template<typename InputFilter, typename OutputFilter>
       
    76 class combined_filter {
       
    77 private:
       
    78     typedef typename category_of<InputFilter>::type    in_category;
       
    79     typedef typename category_of<OutputFilter>::type   out_category;
       
    80 public:
       
    81     typedef typename char_type_of<InputFilter>::type   char_type;
       
    82     struct category 
       
    83         : multichar_bidirectional_filter_tag,
       
    84           closable_tag, 
       
    85           localizable_tag
       
    86         { };
       
    87     combined_filter(const InputFilter& in, const OutputFilter& out);
       
    88 
       
    89     template<typename Source>
       
    90     std::streamsize read(Source& src, char_type* s, std::streamsize n)
       
    91     { return boost::iostreams::read(in_, src, s, n); }
       
    92 
       
    93     template<typename Sink>
       
    94     std::streamsize write(Sink& snk, const char_type* s, std::streamsize n)
       
    95     { return boost::iostreams::write(out_, snk, s, n); }
       
    96 
       
    97     template<typename Sink>
       
    98     void close(Sink& snk, BOOST_IOS::openmode which)
       
    99         {
       
   100             if (which & BOOST_IOS::in)
       
   101                 iostreams::close(in_, snk, which);
       
   102             if (which & BOOST_IOS::out)
       
   103                 iostreams::close(out_, snk, which);
       
   104         }
       
   105     #ifndef BOOST_NO_STD_LOCALE
       
   106         void imbue(const std::locale& loc);
       
   107     #endif
       
   108 private:
       
   109     typedef typename char_type_of<OutputFilter>::type  output_char_type;
       
   110     BOOST_STATIC_ASSERT((is_same<char_type, output_char_type>::value));
       
   111     InputFilter   in_;
       
   112     OutputFilter  out_;
       
   113 };
       
   114 
       
   115 template<typename In, typename Out>
       
   116 struct combination_traits 
       
   117     : mpl::if_<
       
   118           is_device<In>,
       
   119           combined_device<
       
   120               typename wrapped_type<In>::type,
       
   121               typename wrapped_type<Out>::type
       
   122           >,
       
   123           combined_filter<
       
   124               typename wrapped_type<In>::type,
       
   125               typename wrapped_type<Out>::type
       
   126           >
       
   127       >
       
   128     { };
       
   129 
       
   130 } // End namespace detail.
       
   131 
       
   132 template<typename In, typename Out>
       
   133 struct combination : detail::combination_traits<In, Out>::type {
       
   134     typedef typename detail::combination_traits<In, Out>::type  base_type;
       
   135     typedef typename detail::wrapped_type<In>::type          in_type;
       
   136     typedef typename detail::wrapped_type<Out>::type         out_type;
       
   137     combination(const in_type& in, const out_type& out)
       
   138         : base_type(in, out) { }
       
   139 };
       
   140 
       
   141 namespace detail {
       
   142 
       
   143 // Workaround for VC6 ETI bug.
       
   144 template<typename In, typename Out>
       
   145 struct combine_traits {
       
   146     typedef combination<
       
   147                 BOOST_DEDUCED_TYPENAME detail::unwrapped_type<In>::type, 
       
   148                 BOOST_DEDUCED_TYPENAME detail::unwrapped_type<Out>::type
       
   149             > type;
       
   150 };
       
   151 
       
   152 } // End namespace detail.
       
   153 
       
   154 //
       
   155 // Template name: combine.
       
   156 // Description: Takes a Source/Sink pair or InputFilter/OutputFilter pair and
       
   157 //      returns a Reource or Filter which performs input using the first member
       
   158 //      of the pair and output using the second member of the pair.
       
   159 // Template paramters:
       
   160 //      In - A model of Source or InputFilter, with the same char_type as Out.
       
   161 //      Out - A model of Sink or OutputFilter, with the same char_type as In.
       
   162 //
       
   163 template<typename In, typename Out>
       
   164 typename detail::combine_traits<In, Out>::type
       
   165 combine(const In& in, const Out& out) 
       
   166 { 
       
   167     typedef typename detail::combine_traits<In, Out>::type return_type;
       
   168     return return_type(in, out); 
       
   169 }
       
   170 
       
   171 //----------------------------------------------------------------------------//
       
   172 
       
   173 namespace detail {
       
   174 
       
   175 //--------------Implementation of combined_device-----------------------------//
       
   176 
       
   177 template<typename Source, typename Sink>
       
   178 inline combined_device<Source, Sink>::combined_device
       
   179     (const Source& src, const Sink& snk)
       
   180     : src_(src), sink_(snk) { }
       
   181 
       
   182 template<typename Source, typename Sink>
       
   183 inline std::streamsize
       
   184 combined_device<Source, Sink>::read(char_type* s, std::streamsize n)
       
   185 { return iostreams::read(src_, s, n); }
       
   186 
       
   187 template<typename Source, typename Sink>
       
   188 inline std::streamsize
       
   189 combined_device<Source, Sink>::write(const char_type* s, std::streamsize n)
       
   190 { return iostreams::write(sink_, s, n); }
       
   191 
       
   192 template<typename Source, typename Sink>
       
   193 inline void
       
   194 combined_device<Source, Sink>::close(BOOST_IOS::openmode which)
       
   195 { 
       
   196     if (which & BOOST_IOS::in)
       
   197         iostreams::close(src_, which); 
       
   198     if (which & BOOST_IOS::out)
       
   199         iostreams::close(sink_, which); 
       
   200 }
       
   201 
       
   202 #ifndef BOOST_NO_STD_LOCALE
       
   203     template<typename Source, typename Sink>
       
   204     void combined_device<Source, Sink>::imbue(const std::locale& loc)
       
   205     {
       
   206         iostreams::imbue(src_, loc);
       
   207         iostreams::imbue(sink_, loc);
       
   208     }
       
   209 #endif
       
   210 
       
   211 //--------------Implementation of filter_pair---------------------------------//
       
   212 
       
   213 template<typename InputFilter, typename OutputFilter>
       
   214 inline combined_filter<InputFilter, OutputFilter>::combined_filter
       
   215     (const InputFilter& in, const OutputFilter& out) : in_(in), out_(out)
       
   216     { }
       
   217 
       
   218 #ifndef BOOST_NO_STD_LOCALE
       
   219     template<typename InputFilter, typename OutputFilter>
       
   220     void combined_filter<InputFilter, OutputFilter>::imbue
       
   221         (const std::locale& loc)
       
   222     {
       
   223         iostreams::imbue(in_, loc);
       
   224         iostreams::imbue(out_, loc);
       
   225     }
       
   226 #endif
       
   227 
       
   228 
       
   229 } // End namespace detail.
       
   230 
       
   231 } } // End namespaces iostreams, boost.
       
   232 
       
   233 #endif // #ifndef BOOST_IOSTREAMS_COMBINE_HPP_INCLUDED