2 // Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
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)
8 // Test that header file is self-contained.
9 #include <beast/core/streambuf.hpp>
11 #include "buffer_test.hpp"
12 #include <beast/core/buffer_concepts.hpp>
13 #include <beast/core/to_string.hpp>
14 #include <beast/unit_test/suite.hpp>
15 #include <boost/asio/buffer.hpp>
23 static_assert(is_DynamicBuffer
<streambuf
>::value
, "");
25 struct test_allocator_info
27 std::size_t ncopy
= 0;
28 std::size_t nmove
= 0;
29 std::size_t nselect
= 0;
33 bool Assign
, bool Move
, bool Swap
, bool Select
>
37 bool Assign
, bool Move
, bool Swap
, bool Select
>
38 struct test_allocator_base
43 bool Assign
, bool Move
, bool Swap
>
44 struct test_allocator_base
<T
, Assign
, Move
, Swap
, true>
47 test_allocator
<T
, Assign
, Move
, Swap
, true>
48 select_on_container_copy_construction(
49 test_allocator
<T
, Assign
, Move
, Swap
, true> const& a
)
51 return test_allocator
<T
, Assign
, Move
, Swap
, true>{};
56 bool Assign
, bool Move
, bool Swap
, bool Select
>
57 class test_allocator
: public test_allocator_base
<
58 T
, Assign
, Move
, Swap
, Select
>
61 std::shared_ptr
<test_allocator_info
> info_
;
63 template<class, bool, bool, bool, bool>
64 friend class test_allocator
;
68 using propagate_on_container_copy_assignment
=
69 std::integral_constant
<bool, Assign
>;
70 using propagate_on_container_move_assignment
=
71 std::integral_constant
<bool, Move
>;
72 using propagate_on_container_swap
=
73 std::integral_constant
<bool, Swap
>;
78 using other
= test_allocator
<
79 U
, Assign
, Move
, Swap
, Select
>;
89 , info_(std::make_shared
<test_allocator_info
>())
93 test_allocator(test_allocator
const& u
) noexcept
101 test_allocator(test_allocator
<
102 U
, Assign
, Move
, Swap
, Select
> const& u
) noexcept
109 test_allocator(test_allocator
&& t
)
117 allocate(std::size_t n
)
119 return static_cast<value_type
*>(
120 ::operator new (n
*sizeof(value_type
)));
124 deallocate(value_type
* p
, std::size_t) noexcept
126 ::operator delete(p
);
135 test_allocator_info
const*
142 class basic_streambuf_test
: public beast::unit_test::suite
145 template<class Alloc1
, class Alloc2
>
148 eq(basic_streambuf
<Alloc1
> const& sb1
,
149 basic_streambuf
<Alloc2
> const& sb2
)
151 return to_string(sb1
.data()) == to_string(sb2
.data());
154 template<class ConstBufferSequence
>
156 expect_size(std::size_t n
, ConstBufferSequence
const& buffers
)
158 BEAST_EXPECT(test::size_pre(buffers
) == n
);
159 BEAST_EXPECT(test::size_post(buffers
) == n
);
160 BEAST_EXPECT(test::size_rev_pre(buffers
) == n
);
161 BEAST_EXPECT(test::size_rev_post(buffers
) == n
);
164 template<class U
, class V
>
167 self_assign(U
& u
, V
&& v
)
169 u
= std::forward
<V
>(v
);
172 void testSpecialMembers()
174 using boost::asio::buffer
;
175 std::string
const s
= "Hello, world";
176 BEAST_EXPECT(s
.size() == 12);
177 for(std::size_t i
= 1; i
< 12; ++i
) {
178 for(std::size_t x
= 1; x
< 4; ++x
) {
179 for(std::size_t y
= 1; y
< 4; ++y
) {
180 std::size_t z
= s
.size() - (x
+ y
);
183 sb
.commit(buffer_copy(sb
.prepare(x
), buffer(s
.data(), x
)));
184 sb
.commit(buffer_copy(sb
.prepare(y
), buffer(s
.data()+x
, y
)));
185 sb
.commit(buffer_copy(sb
.prepare(z
), buffer(s
.data()+x
+y
, z
)));
186 BEAST_EXPECT(to_string(sb
.data()) == s
);
189 BEAST_EXPECT(eq(sb
, sb2
));
194 BEAST_EXPECT(eq(sb
, sb2
));
197 streambuf
sb2(std::move(sb
));
198 BEAST_EXPECT(to_string(sb2
.data()) == s
);
199 expect_size(0, sb
.data());
201 BEAST_EXPECT(to_string(sb
.data()) == s
);
202 expect_size(0, sb2
.data());
205 BEAST_EXPECT(to_string(sb
.data()) == s
);
206 self_assign(sb
, std::move(sb
));
207 BEAST_EXPECT(to_string(sb
.data()) == s
);
215 catch(std::exception
const&)
223 // VFALCO This needs work
226 test_allocator
<char, false, false, false, false>;
227 using sb_type
= basic_streambuf
<alloc_type
>;
229 BEAST_EXPECT(sb
.get_allocator().id() == 1);
233 test_allocator
<char, false, false, false, false>;
234 using sb_type
= basic_streambuf
<alloc_type
>;
236 BEAST_EXPECT(sb
.get_allocator().id() == 2);
238 BEAST_EXPECT(sb2
.get_allocator().id() == 2);
239 sb_type
sb3(sb
, alloc_type
{});
246 using boost::asio::buffer_size
;
249 BEAST_EXPECT(buffer_size(sb
.prepare(5)) == 5);
250 BEAST_EXPECT(buffer_size(sb
.prepare(8)) == 8);
251 BEAST_EXPECT(buffer_size(sb
.prepare(7)) == 7);
256 BEAST_EXPECT(test::buffer_count(sb
.prepare(5)) == 2);
257 BEAST_EXPECT(test::buffer_count(sb
.prepare(8)) == 3);
258 BEAST_EXPECT(test::buffer_count(sb
.prepare(4)) == 2);
268 expect_size(1, sb
.data());
274 expect_size(5, sb
.prepare(5));
276 expect_size(3, sb
.data());
278 expect_size(2, sb
.data());
283 using boost::asio::buffer
;
284 using boost::asio::buffer_size
;
285 std::string
const s
= "Hello, world";
286 BEAST_EXPECT(s
.size() == 12);
287 for(std::size_t i
= 1; i
< 12; ++i
) {
288 for(std::size_t x
= 1; x
< 4; ++x
) {
289 for(std::size_t y
= 1; y
< 4; ++y
) {
290 for(std::size_t t
= 1; t
< 4; ++ t
) {
291 for(std::size_t u
= 1; u
< 4; ++ u
) {
292 std::size_t z
= s
.size() - (x
+ y
);
293 std::size_t v
= s
.size() - (t
+ u
);
297 auto d
= sb
.prepare(z
);
298 BEAST_EXPECT(buffer_size(d
) == z
);
301 auto d
= sb
.prepare(0);
302 BEAST_EXPECT(buffer_size(d
) == 0);
305 auto d
= sb
.prepare(y
);
306 BEAST_EXPECT(buffer_size(d
) == y
);
309 auto d
= sb
.prepare(x
);
310 BEAST_EXPECT(buffer_size(d
) == x
);
311 sb
.commit(buffer_copy(d
, buffer(s
.data(), x
)));
313 BEAST_EXPECT(sb
.size() == x
);
314 BEAST_EXPECT(buffer_size(sb
.data()) == sb
.size());
316 auto d
= sb
.prepare(x
);
317 BEAST_EXPECT(buffer_size(d
) == x
);
320 auto d
= sb
.prepare(0);
321 BEAST_EXPECT(buffer_size(d
) == 0);
324 auto d
= sb
.prepare(z
);
325 BEAST_EXPECT(buffer_size(d
) == z
);
328 auto d
= sb
.prepare(y
);
329 BEAST_EXPECT(buffer_size(d
) == y
);
330 sb
.commit(buffer_copy(d
, buffer(s
.data()+x
, y
)));
333 BEAST_EXPECT(sb
.size() == x
+ y
);
334 BEAST_EXPECT(buffer_size(sb
.data()) == sb
.size());
336 auto d
= sb
.prepare(x
);
337 BEAST_EXPECT(buffer_size(d
) == x
);
340 auto d
= sb
.prepare(y
);
341 BEAST_EXPECT(buffer_size(d
) == y
);
344 auto d
= sb
.prepare(0);
345 BEAST_EXPECT(buffer_size(d
) == 0);
348 auto d
= sb
.prepare(z
);
349 BEAST_EXPECT(buffer_size(d
) == z
);
350 sb
.commit(buffer_copy(d
, buffer(s
.data()+x
+y
, z
)));
353 BEAST_EXPECT(sb
.size() == x
+ y
+ z
);
354 BEAST_EXPECT(buffer_size(sb
.data()) == sb
.size());
355 BEAST_EXPECT(to_string(sb
.data()) == s
);
358 auto d
= sb
.prepare(0);
359 BEAST_EXPECT(buffer_size(d
) == 0);
361 BEAST_EXPECT(to_string(sb
.data()) == s
.substr(t
, std::string::npos
));
363 BEAST_EXPECT(to_string(sb
.data()) == s
.substr(t
+ u
, std::string::npos
));
365 BEAST_EXPECT(to_string(sb
.data()) == "");
368 auto d
= sb
.prepare(0);
369 BEAST_EXPECT(buffer_size(d
) == 0);
377 using boost::asio::buffer_size
;
383 expect_size(3, sb
.data());
385 expect_size(3, sb
.prepare(3));
387 BEAST_EXPECT(test::buffer_count(sb
.data()) == 4);
390 void testOutputStream()
394 BEAST_EXPECT(to_string(sb
.data()) == "x");
399 using boost::asio::buffer_size
;
402 BEAST_EXPECT(sb
.alloc_size() == 10);
403 BEAST_EXPECT(read_size_helper(sb
, 1) == 1);
404 BEAST_EXPECT(read_size_helper(sb
, 10) == 10);
405 BEAST_EXPECT(read_size_helper(sb
, 20) == 20);
406 BEAST_EXPECT(read_size_helper(sb
, 1000) == 512);
409 BEAST_EXPECT(read_size_helper(sb
, 10) == 7);
410 BEAST_EXPECT(read_size_helper(sb
, 1000) == 7);
414 BEAST_EXPECT(sb
.alloc_size() == 1000);
415 BEAST_EXPECT(read_size_helper(sb
, 1) == 1);
416 BEAST_EXPECT(read_size_helper(sb
, 1000) == 1000);
417 BEAST_EXPECT(read_size_helper(sb
, 2000) == 1000);
419 BEAST_EXPECT(read_size_helper(sb
, 1) == 1);
420 BEAST_EXPECT(read_size_helper(sb
, 1000) == 1000);
421 BEAST_EXPECT(read_size_helper(sb
, 2000) == 1000);
423 BEAST_EXPECT(read_size_helper(sb
, 1) == 1);
424 BEAST_EXPECT(read_size_helper(sb
, 1000) == 997);
425 BEAST_EXPECT(read_size_helper(sb
, 2000) == 997);
427 BEAST_EXPECT(read_size_helper(sb
, 1) == 1);
428 BEAST_EXPECT(read_size_helper(sb
, 1000) == 997);
429 BEAST_EXPECT(read_size_helper(sb
, 2000) == 997);
433 BEAST_EXPECT(sb
.alloc_size() == 2);
434 BEAST_EXPECT(test::buffer_count(sb
.prepare(2)) == 1);
435 BEAST_EXPECT(test::buffer_count(sb
.prepare(3)) == 2);
436 BEAST_EXPECT(buffer_size(sb
.prepare(5)) == 5);
437 BEAST_EXPECT(read_size_helper(sb
, 10) == 6);
441 [](streambuf
const& sb
)
443 return sb
.capacity() - sb
.size();
446 BEAST_EXPECT(sb
.alloc_size() == 100);
447 BEAST_EXPECT(avail(sb
) == 0);
449 BEAST_EXPECT(avail(sb
) == 100);
451 BEAST_EXPECT(avail(sb
) == 0);
453 BEAST_EXPECT(avail(sb
) == 0);
455 BEAST_EXPECT(sb
.alloc_size() == 200);
457 BEAST_EXPECT(avail(sb
) == 200);
463 testSpecialMembers();
475 BEAST_DEFINE_TESTSUITE(basic_streambuf
,core
,beast
);