Ugly, not-to-be-pushed sucking in of all of Boost to get windows to work.
[dyninst.git] / external / boost / iostreams / combine.hpp
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