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/buffer_cat.hpp>
11 #include <beast/unit_test/suite.hpp>
12 #include <boost/asio/buffer.hpp>
13 #include <boost/asio/streambuf.hpp>
16 #include <type_traits>
21 class buffer_cat_test
: public unit_test::suite
24 template<class Iterator
>
26 std::reverse_iterator
<Iterator
>
27 make_reverse_iterator(Iterator i
)
29 return std::reverse_iterator
<Iterator
>(i
);
32 template<class ConstBufferSequence
>
35 bsize1(ConstBufferSequence
const& bs
)
37 using boost::asio::buffer_size
;
39 for(auto it
= bs
.begin(); it
!= bs
.end(); ++it
)
40 n
+= buffer_size(*it
);
44 template<class ConstBufferSequence
>
47 bsize2(ConstBufferSequence
const& bs
)
49 using boost::asio::buffer_size
;
51 for(auto it
= bs
.begin(); it
!= bs
.end(); it
++)
52 n
+= buffer_size(*it
);
56 template<class ConstBufferSequence
>
59 bsize3(ConstBufferSequence
const& bs
)
61 using boost::asio::buffer_size
;
63 for(auto it
= bs
.end(); it
!= bs
.begin();)
64 n
+= buffer_size(*--it
);
68 template<class ConstBufferSequence
>
71 bsize4(ConstBufferSequence
const& bs
)
73 using boost::asio::buffer_size
;
75 for(auto it
= bs
.end(); it
!= bs
.begin();)
78 n
+= buffer_size(*it
);
85 using boost::asio::buffer_size
;
86 using boost::asio::const_buffer
;
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
));
115 boost::asio::streambuf sb1
, sb2
;
116 BEAST_EXPECT(buffer_size(buffer_cat(
117 sb1
.prepare(5), sb2
.prepare(7))) == 12);
120 BEAST_EXPECT(buffer_size(buffer_cat(
121 sb1
.data(), sb2
.data())) == 12);
123 for(auto it
= bs
.begin(); it
!= bs
.end(); ++it
)
125 decltype(bs
)::const_iterator copy
;
127 BEAST_EXPECT(copy
== it
);
129 BEAST_EXPECT(copy
== it
);
135 using boost::asio::buffer_size
;
136 using boost::asio::const_buffer
;
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
);
147 n
<= std::distance(bs
.begin(), bs
.end()); ++n
)
149 auto it
= std::next(bs
.begin(), n
);
150 decltype(it
) it2(std::move(it
));
153 it
= std::move(*pit
);
158 for(auto it
= bs
.begin(); n
< 100; ++it
)
162 catch(std::exception
const&)
167 // decrement iterator
170 make_reverse_iterator(bs
.end());
172 make_reverse_iterator(bs
.begin());
174 for(auto it
= rbegin
; it
!= rend
; ++it
)
175 n
+= buffer_size(*it
);
176 BEAST_EXPECT(n
== 9);
182 for(auto it
= bs
.end(); n
< 100; --it
)
186 catch(std::exception
const&)
193 buffer_size(*bs
.end());
196 catch(std::exception
const&)
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
);
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
218 // Check is_all_ConstBufferSequence
220 detail::is_all_ConstBufferSequence
<
224 detail::is_all_ConstBufferSequence
<
225 const_buffers_1
, const_buffers_1
228 detail::is_all_ConstBufferSequence
<
232 detail::is_all_ConstBufferSequence
<
233 mutable_buffers_1
, mutable_buffers_1
236 detail::is_all_ConstBufferSequence
<
237 const_buffers_1
, mutable_buffers_1
240 ! detail::is_all_ConstBufferSequence
<
241 const_buffers_1
, mutable_buffers_1
, int
244 // Ensure that concatenating mutable buffer
245 // sequences results in a mutable buffer sequence
246 static_assert(std::is_same
<
249 std::declval
<mutable_buffer
>(),
250 std::declval
<user_defined
>(),
251 std::declval
<mutable_buffer
>()
252 ))::value_type
>::value
, "");
254 // Ensure that concatenating mixed buffer
255 // sequences results in a const buffer sequence.
256 static_assert(std::is_same
<
259 std::declval
<mutable_buffer
>(),
260 std::declval
<user_defined
>(),
261 std::declval
<const_buffer
>()
262 ))::value_type
>::value
, "");
269 BEAST_DEFINE_TESTSUITE(buffer_cat
,core
,beast
);