Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/iostreams/invert.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
15:663ca0da4350 | 16:2665513ce2d3 |
---|---|
1 // (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) | |
2 // (C) Copyright 2003-2007 Jonathan Turkanis | |
3 // Distributed under the Boost Software License, Version 1.0. (See accompanying | |
4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.) | |
5 | |
6 // See http://www.boost.org/libs/iostreams for documentation. | |
7 | |
8 #ifndef BOOST_IOSTREAMS_INVERT_HPP_INCLUDED | |
9 #define BOOST_IOSTREAMS_INVERT_HPP_INCLUDED | |
10 | |
11 #if defined(_MSC_VER) && (_MSC_VER >= 1020) | |
12 # pragma once | |
13 #endif | |
14 | |
15 #include <algorithm> // copy, min. | |
16 #include <boost/assert.hpp> | |
17 #include <boost/config.hpp> // BOOST_DEDUCED_TYPENAME. | |
18 #include <boost/detail/workaround.hpp> // default_filter_buffer_size. | |
19 #include <boost/iostreams/char_traits.hpp> | |
20 #include <boost/iostreams/compose.hpp> | |
21 #include <boost/iostreams/constants.hpp> | |
22 #include <boost/iostreams/device/array.hpp> | |
23 #include <boost/iostreams/detail/buffer.hpp> | |
24 #include <boost/iostreams/detail/counted_array.hpp> | |
25 #include <boost/iostreams/detail/execute.hpp> | |
26 #include <boost/iostreams/detail/functional.hpp> // clear_flags, call_reset | |
27 #include <boost/mpl/if.hpp> | |
28 #include <boost/ref.hpp> | |
29 #include <boost/shared_ptr.hpp> | |
30 #include <boost/type_traits/is_convertible.hpp> | |
31 | |
32 // Must come last. | |
33 #include <boost/iostreams/detail/config/disable_warnings.hpp> // MSVC. | |
34 | |
35 namespace boost { namespace iostreams { | |
36 | |
37 // | |
38 // Template name: inverse. | |
39 // Template parameters: | |
40 // Filter - A model of InputFilter or OutputFilter. | |
41 // Description: Generates an InputFilter from an OutputFilter or | |
42 // vice versa. | |
43 // | |
44 template<typename Filter> | |
45 class inverse { | |
46 private: | |
47 BOOST_STATIC_ASSERT(is_filter<Filter>::value); | |
48 typedef typename category_of<Filter>::type base_category; | |
49 typedef reference_wrapper<Filter> filter_ref; | |
50 public: | |
51 typedef typename char_type_of<Filter>::type char_type; | |
52 typedef typename int_type_of<Filter>::type int_type; | |
53 typedef char_traits<char_type> traits_type; | |
54 typedef typename | |
55 mpl::if_< | |
56 is_convertible< | |
57 base_category, | |
58 input | |
59 >, | |
60 output, | |
61 input | |
62 >::type mode; | |
63 struct category | |
64 : mode, | |
65 filter_tag, | |
66 multichar_tag, | |
67 closable_tag | |
68 { }; | |
69 explicit inverse( const Filter& filter, | |
70 std::streamsize buffer_size = | |
71 default_filter_buffer_size) | |
72 : pimpl_(new impl(filter, buffer_size)) | |
73 { } | |
74 | |
75 template<typename Source> | |
76 std::streamsize read(Source& src, char* s, std::streamsize n) | |
77 { | |
78 typedef detail::counted_array_sink<char_type> array_sink; | |
79 typedef composite<filter_ref, array_sink> filtered_array_sink; | |
80 | |
81 BOOST_ASSERT((flags() & f_write) == 0); | |
82 if (flags() == 0) { | |
83 flags() = f_read; | |
84 buf().set(0, 0); | |
85 } | |
86 | |
87 filtered_array_sink snk(filter(), array_sink(s, n)); | |
88 int_type status; | |
89 for ( status = traits_type::good(); | |
90 snk.second().count() < n && status == traits_type::good(); ) | |
91 { | |
92 status = buf().fill(src); | |
93 buf().flush(snk); | |
94 } | |
95 return snk.second().count() == 0 && | |
96 status == traits_type::eof() | |
97 ? | |
98 -1 | |
99 : | |
100 snk.second().count(); | |
101 } | |
102 | |
103 template<typename Sink> | |
104 std::streamsize write(Sink& dest, const char* s, std::streamsize n) | |
105 { | |
106 typedef detail::counted_array_source<char_type> array_source; | |
107 typedef composite<filter_ref, array_source> filtered_array_source; | |
108 | |
109 BOOST_ASSERT((flags() & f_read) == 0); | |
110 if (flags() == 0) { | |
111 flags() = f_write; | |
112 buf().set(0, 0); | |
113 } | |
114 | |
115 filtered_array_source src(filter(), array_source(s, n)); | |
116 for (bool good = true; src.second().count() < n && good; ) { | |
117 buf().fill(src); | |
118 good = buf().flush(dest); | |
119 } | |
120 return src.second().count(); | |
121 } | |
122 | |
123 template<typename Device> | |
124 void close(Device& dev) | |
125 { | |
126 detail::execute_all( | |
127 detail::flush_buffer(buf(), dev, (flags() & f_write) != 0), | |
128 detail::call_close_all(pimpl_->filter_, dev), | |
129 detail::clear_flags(flags()) | |
130 ); | |
131 } | |
132 private: | |
133 filter_ref filter() { return boost::ref(pimpl_->filter_); } | |
134 detail::buffer<char_type>& buf() { return pimpl_->buf_; } | |
135 int& flags() { return pimpl_->flags_; } | |
136 | |
137 enum flags_ { | |
138 f_read = 1, f_write = 2 | |
139 }; | |
140 | |
141 struct impl { | |
142 impl(const Filter& filter, std::streamsize n) | |
143 : filter_(filter), buf_(n), flags_(0) | |
144 { buf_.set(0, 0); } | |
145 Filter filter_; | |
146 detail::buffer<char_type> buf_; | |
147 int flags_; | |
148 }; | |
149 shared_ptr<impl> pimpl_; | |
150 }; | |
151 | |
152 // | |
153 // Template name: invert. | |
154 // Template parameters: | |
155 // Filter - A model of InputFilter or OutputFilter. | |
156 // Description: Returns an instance of an appropriate specialization of inverse. | |
157 // | |
158 template<typename Filter> | |
159 inverse<Filter> invert(const Filter& f) { return inverse<Filter>(f); } | |
160 | |
161 //----------------------------------------------------------------------------// | |
162 | |
163 } } // End namespaces iostreams, boost. | |
164 | |
165 #include <boost/iostreams/detail/config/enable_warnings.hpp> // MSVC. | |
166 | |
167 #endif // #ifndef BOOST_IOSTREAMS_INVERT_HPP_INCLUDED |