source: NonGTP/Boost/boost/iostreams/combine.hpp @ 857

Revision 857, 7.6 KB checked in by igarcia, 18 years ago (diff)
Line 
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
29namespace boost { namespace iostreams {
30
31namespace 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//
42template<typename Source, typename Sink>
43class combined_device {
44public:
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
59private:
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//
75template<typename InputFilter, typename OutputFilter>
76class combined_filter {
77private:
78    typedef typename category_of<InputFilter>::type    in_category;
79    typedef typename category_of<OutputFilter>::type   out_category;
80public:
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
108private:
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
115template<typename In, typename Out>
116struct 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
132template<typename In, typename Out>
133struct 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
141namespace detail {
142
143// Workaround for VC6 ETI bug.
144template<typename In, typename Out>
145struct 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//
163template<typename In, typename Out>
164typename detail::combine_traits<In, Out>::type
165combine(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
173namespace detail {
174
175//--------------Implementation of combined_device-----------------------------//
176
177template<typename Source, typename Sink>
178inline combined_device<Source, Sink>::combined_device
179    (const Source& src, const Sink& snk)
180    : src_(src), sink_(snk) { }
181
182template<typename Source, typename Sink>
183inline std::streamsize
184combined_device<Source, Sink>::read(char_type* s, std::streamsize n)
185{ return iostreams::read(src_, s, n); }
186
187template<typename Source, typename Sink>
188inline std::streamsize
189combined_device<Source, Sink>::write(const char_type* s, std::streamsize n)
190{ return iostreams::write(sink_, s, n); }
191
192template<typename Source, typename Sink>
193inline void
194combined_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
213template<typename InputFilter, typename OutputFilter>
214inline 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
Note: See TracBrowser for help on using the repository browser.