]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // |
2 | // Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com) | |
3 | // | |
4 | // Distributed under the Boost Software License, Version 1.0. (See accompanying | |
5 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
6 | // | |
7 | ||
8 | // Test that header file is self-contained. | |
9 | #include <beast/core/buffer_cat.hpp> | |
10 | ||
11 | #include <beast/unit_test/suite.hpp> | |
12 | #include <boost/asio/buffer.hpp> | |
13 | #include <boost/asio/streambuf.hpp> | |
14 | #include <iterator> | |
15 | #include <list> | |
16 | #include <type_traits> | |
17 | #include <vector> | |
18 | ||
19 | namespace beast { | |
20 | ||
21 | class buffer_cat_test : public unit_test::suite | |
22 | { | |
23 | public: | |
24 | template<class Iterator> | |
25 | static | |
26 | std::reverse_iterator<Iterator> | |
27 | make_reverse_iterator(Iterator i) | |
28 | { | |
29 | return std::reverse_iterator<Iterator>(i); | |
30 | } | |
31 | ||
32 | template<class ConstBufferSequence> | |
33 | static | |
34 | std::size_t | |
35 | bsize1(ConstBufferSequence const& bs) | |
36 | { | |
37 | using boost::asio::buffer_size; | |
38 | std::size_t n = 0; | |
39 | for(auto it = bs.begin(); it != bs.end(); ++it) | |
40 | n += buffer_size(*it); | |
41 | return n; | |
42 | } | |
43 | ||
44 | template<class ConstBufferSequence> | |
45 | static | |
46 | std::size_t | |
47 | bsize2(ConstBufferSequence const& bs) | |
48 | { | |
49 | using boost::asio::buffer_size; | |
50 | std::size_t n = 0; | |
51 | for(auto it = bs.begin(); it != bs.end(); it++) | |
52 | n += buffer_size(*it); | |
53 | return n; | |
54 | } | |
55 | ||
56 | template<class ConstBufferSequence> | |
57 | static | |
58 | std::size_t | |
59 | bsize3(ConstBufferSequence const& bs) | |
60 | { | |
61 | using boost::asio::buffer_size; | |
62 | std::size_t n = 0; | |
63 | for(auto it = bs.end(); it != bs.begin();) | |
64 | n += buffer_size(*--it); | |
65 | return n; | |
66 | } | |
67 | ||
68 | template<class ConstBufferSequence> | |
69 | static | |
70 | std::size_t | |
71 | bsize4(ConstBufferSequence const& bs) | |
72 | { | |
73 | using boost::asio::buffer_size; | |
74 | std::size_t n = 0; | |
75 | for(auto it = bs.end(); it != bs.begin();) | |
76 | { | |
77 | it--; | |
78 | n += buffer_size(*it); | |
79 | } | |
80 | return n; | |
81 | } | |
82 | ||
83 | void testBufferCat() | |
84 | { | |
85 | using boost::asio::buffer_size; | |
86 | using boost::asio::const_buffer; | |
87 | char buf[10]; | |
88 | std::list<const_buffer> b1; | |
89 | std::vector<const_buffer> b2{ | |
90 | const_buffer{buf+0, 1}, | |
91 | const_buffer{buf+1, 2}}; | |
92 | std::list<const_buffer> b3; | |
93 | std::array<const_buffer, 3> b4{{ | |
94 | const_buffer{buf+3, 1}, | |
95 | const_buffer{buf+4, 2}, | |
96 | const_buffer{buf+6, 3}}}; | |
97 | std::list<const_buffer> b5{ | |
98 | const_buffer{buf+9, 1}}; | |
99 | std::list<const_buffer> b6; | |
100 | auto bs = buffer_cat( | |
101 | b1, b2, b3, b4, b5, b6); | |
102 | BEAST_EXPECT(buffer_size(bs) == 10); | |
103 | BEAST_EXPECT(bsize1(bs) == 10); | |
104 | BEAST_EXPECT(bsize2(bs) == 10); | |
105 | BEAST_EXPECT(bsize3(bs) == 10); | |
106 | BEAST_EXPECT(bsize4(bs) == 10); | |
107 | std::vector<const_buffer> v; | |
108 | for(auto iter = make_reverse_iterator(bs.end()); | |
109 | iter != make_reverse_iterator(bs.begin()); ++iter) | |
110 | v.emplace_back(*iter); | |
111 | BEAST_EXPECT(buffer_size(bs) == 10); | |
112 | decltype(bs) bs2(bs); | |
113 | auto bs3(std::move(bs)); | |
114 | { | |
115 | boost::asio::streambuf sb1, sb2; | |
116 | BEAST_EXPECT(buffer_size(buffer_cat( | |
117 | sb1.prepare(5), sb2.prepare(7))) == 12); | |
118 | sb1.commit(5); | |
119 | sb2.commit(7); | |
120 | BEAST_EXPECT(buffer_size(buffer_cat( | |
121 | sb1.data(), sb2.data())) == 12); | |
122 | } | |
123 | for(auto it = bs.begin(); it != bs.end(); ++it) | |
124 | { | |
125 | decltype(bs)::const_iterator copy; | |
126 | copy = it; | |
127 | BEAST_EXPECT(copy == it); | |
128 | copy = copy; | |
129 | BEAST_EXPECT(copy == it); | |
130 | } | |
131 | } | |
132 | ||
133 | void testIterators() | |
134 | { | |
135 | using boost::asio::buffer_size; | |
136 | using boost::asio::const_buffer; | |
137 | char buf[9]; | |
138 | std::vector<const_buffer> b1{ | |
139 | const_buffer{buf+0, 1}, | |
140 | const_buffer{buf+1, 2}}; | |
141 | std::array<const_buffer, 3> b2{{ | |
142 | const_buffer{buf+3, 1}, | |
143 | const_buffer{buf+4, 2}, | |
144 | const_buffer{buf+6, 3}}}; | |
145 | auto bs = buffer_cat(b1, b2); | |
146 | for(int n = 0; | |
147 | n <= std::distance(bs.begin(), bs.end()); ++n) | |
148 | { | |
149 | auto it = std::next(bs.begin(), n); | |
150 | decltype(it) it2(std::move(it)); | |
151 | it = std::move(it2); | |
152 | auto pit = ⁢ | |
153 | it = std::move(*pit); | |
154 | } | |
155 | try | |
156 | { | |
157 | std::size_t n = 0; | |
158 | for(auto it = bs.begin(); n < 100; ++it) | |
159 | ++n; | |
160 | fail(); | |
161 | } | |
162 | catch(std::exception const&) | |
163 | { | |
164 | pass(); | |
165 | } | |
166 | ||
167 | // decrement iterator | |
168 | { | |
169 | auto const rbegin = | |
170 | make_reverse_iterator(bs.end()); | |
171 | auto const rend = | |
172 | make_reverse_iterator(bs.begin()); | |
173 | std::size_t n = 0; | |
174 | for(auto it = rbegin; it != rend; ++it) | |
175 | n += buffer_size(*it); | |
176 | BEAST_EXPECT(n == 9); | |
177 | } | |
178 | ||
179 | try | |
180 | { | |
181 | std::size_t n = 0; | |
182 | for(auto it = bs.end(); n < 100; --it) | |
183 | ++n; | |
184 | fail(); | |
185 | } | |
186 | catch(std::exception const&) | |
187 | { | |
188 | pass(); | |
189 | } | |
190 | ||
191 | try | |
192 | { | |
193 | buffer_size(*bs.end()); | |
194 | fail(); | |
195 | } | |
196 | catch(std::exception const&) | |
197 | { | |
198 | pass(); | |
199 | } | |
200 | auto bs2 = bs; | |
201 | BEAST_EXPECT(bs.begin() != bs2.begin()); | |
202 | BEAST_EXPECT(bs.end() != bs2.end()); | |
203 | decltype(bs)::const_iterator it; | |
204 | decltype(bs2)::const_iterator it2; | |
205 | BEAST_EXPECT(it == it2); | |
206 | } | |
207 | ||
208 | void run() override | |
209 | { | |
210 | using boost::asio::const_buffer; | |
211 | using boost::asio::const_buffers_1; | |
212 | using boost::asio::mutable_buffer; | |
213 | using boost::asio::mutable_buffers_1; | |
214 | struct user_defined : mutable_buffer | |
215 | { | |
216 | }; | |
217 | ||
218 | // Check is_all_ConstBufferSequence | |
219 | static_assert( | |
220 | detail::is_all_ConstBufferSequence< | |
221 | const_buffers_1 | |
222 | >::value, ""); | |
223 | static_assert( | |
224 | detail::is_all_ConstBufferSequence< | |
225 | const_buffers_1, const_buffers_1 | |
226 | >::value, ""); | |
227 | static_assert( | |
228 | detail::is_all_ConstBufferSequence< | |
229 | mutable_buffers_1 | |
230 | >::value, ""); | |
231 | static_assert( | |
232 | detail::is_all_ConstBufferSequence< | |
233 | mutable_buffers_1, mutable_buffers_1 | |
234 | >::value, ""); | |
235 | static_assert( | |
236 | detail::is_all_ConstBufferSequence< | |
237 | const_buffers_1, mutable_buffers_1 | |
238 | >::value, ""); | |
239 | static_assert( | |
240 | ! detail::is_all_ConstBufferSequence< | |
241 | const_buffers_1, mutable_buffers_1, int | |
242 | >::value, ""); | |
243 | ||
244 | // Ensure that concatenating mutable buffer | |
245 | // sequences results in a mutable buffer sequence | |
246 | static_assert(std::is_same< | |
247 | mutable_buffer, | |
248 | decltype(buffer_cat( | |
249 | std::declval<mutable_buffer>(), | |
250 | std::declval<user_defined>(), | |
251 | std::declval<mutable_buffer>() | |
252 | ))::value_type>::value, ""); | |
253 | ||
254 | // Ensure that concatenating mixed buffer | |
255 | // sequences results in a const buffer sequence. | |
256 | static_assert(std::is_same< | |
257 | const_buffer, | |
258 | decltype(buffer_cat( | |
259 | std::declval<mutable_buffer>(), | |
260 | std::declval<user_defined>(), | |
261 | std::declval<const_buffer>() | |
262 | ))::value_type>::value, ""); | |
263 | ||
264 | testBufferCat(); | |
265 | testIterators(); | |
266 | } | |
267 | }; | |
268 | ||
269 | BEAST_DEFINE_TESTSUITE(buffer_cat,core,beast); | |
270 | ||
271 | } // beast |