diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4e88f105..cf49fc24 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,6 +3,7 @@
* Add Appveyor build scripts and badge
* Tidy up MSVC CMake configuration
* Make close_code a proper enum
+* Add flat_streambuf
--------------------------------------------------------------------------------
diff --git a/doc/quickref.xml b/doc/quickref.xml
index 874c5a69..cabad789 100644
--- a/doc/quickref.xml
+++ b/doc/quickref.xml
@@ -165,6 +165,7 @@
Classes
async_completion
+ basic_flat_streambuf
basic_streambuf
buffers_adapter
consuming_buffers
@@ -173,6 +174,7 @@
error_category
error_code
error_condition
+ flat_streambuf
handler_alloc
handler_ptr
static_streambuf
diff --git a/doc/types/DynamicBuffer.qbk b/doc/types/DynamicBuffer.qbk
index 792c2591..009abbdd 100644
--- a/doc/types/DynamicBuffer.qbk
+++ b/doc/types/DynamicBuffer.qbk
@@ -19,7 +19,9 @@ The interface to this concept is intended to permit the following
implementation strategies:
* A single contiguous octet array, which is reallocated as necessary to
- accommodate changes in the size of the octet sequence.
+ accommodate changes in the size of the octet sequence. This is the
+ implementation approach currently offered by
+ [link beast.ref.basic_flat_streambuf `basic_flat_streambuf`].
* A sequence of one or more octet arrays, where each array is of the same
size. Additional octet array objects are appended to the sequence to
diff --git a/include/beast/core.hpp b/include/beast/core.hpp
index 9377cd99..b0dd3fc3 100644
--- a/include/beast/core.hpp
+++ b/include/beast/core.hpp
@@ -17,6 +17,7 @@
#include
#include
#include
+#include
#include
#include
#include
diff --git a/include/beast/core/flat_streambuf.hpp b/include/beast/core/flat_streambuf.hpp
new file mode 100644
index 00000000..496adc00
--- /dev/null
+++ b/include/beast/core/flat_streambuf.hpp
@@ -0,0 +1,310 @@
+//
+// Copyright (c) 2013-2016 Vinnie Falco (vinnie dot falco at gmail dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BEAST_FLAT_STREAMBUF_HPP
+#define BEAST_FLAT_STREAMBUF_HPP
+
+#include
+#include
+#include
+#include
+#include
+
+namespace beast {
+
+/** A linear dynamic buffer.
+
+ Objects of this type meet the requirements of @b DynamicBuffer
+ and offer additional invariants:
+
+ @li Buffer sequences returned by @ref data and @ref prepare
+ will always be of length one.
+
+ @li A configurable maximum buffer size may be set upon
+ construction. Attempts to exceed the buffer size will throw
+ `std::length_error`.
+
+ @note This class is designed for use with algorithms that
+ take dynamic buffers as parameters, and are optimized
+ for the case where the input sequence or output sequence
+ is stored in a single contiguous buffer.
+*/
+template
+class basic_flat_streambuf
+#if ! GENERATING_DOCS
+ : private detail::empty_base_optimization<
+ typename std::allocator_traits::
+ template rebind_alloc>
+#endif
+{
+public:
+#if GENERATING_DOCS
+ /// The type of allocator used.
+ using allocator_type = Allocator;
+#else
+ using allocator_type = typename
+ std::allocator_traits::
+ template rebind_alloc;
+#endif
+
+private:
+ enum
+ {
+ min_size = 512
+ };
+
+ template
+ friend class basic_flat_streambuf;
+
+ using alloc_traits =
+ std::allocator_traits;
+
+ static
+ inline
+ std::size_t
+ dist(char const* first, char const* last)
+ {
+ return static_cast(last - first);
+ }
+
+ char* p_;
+ char* in_;
+ char* out_;
+ char* last_;
+ char* end_;
+ std::size_t max_;
+
+public:
+ /// The type used to represent the input sequence as a list of buffers.
+ using const_buffers_type = boost::asio::const_buffers_1;
+
+ /// The type used to represent the output sequence as a list of buffers.
+ using mutable_buffers_type = boost::asio::mutable_buffers_1;
+
+ /// Copy assignment (disallowed).
+ basic_flat_streambuf&
+ operator=(basic_flat_streambuf const&) = delete;
+
+ /// Destructor.
+ ~basic_flat_streambuf();
+
+ /** Move constructor.
+
+ The new object will have the same input sequence
+ and an empty output sequence.
+
+ @note After the move, the moved-from object will
+ have a capacity of zero, an empty input sequence,
+ and an empty output sequence.
+ */
+ basic_flat_streambuf(basic_flat_streambuf&&);
+
+ /** Move constructor.
+
+ The new object will have the same input sequence
+ and an empty output sequence.
+
+ @note After the move, the moved-from object will
+ have a capacity of zero, an empty input sequence,
+ and an empty output sequence.
+
+ @param alloc The allocator to associate with the
+ stream buffer.
+ */
+ basic_flat_streambuf(basic_flat_streambuf&&,
+ Allocator const& alloc);
+
+ /** Copy constructor.
+
+ The new object will have a copy of the input sequence
+ and an empty output sequence.
+ */
+ basic_flat_streambuf(basic_flat_streambuf const&);
+
+ /** Copy constructor.
+
+ The new object will have a copy of the input sequence
+ and an empty output sequence.
+
+ @param alloc The allocator to associate with the
+ stream buffer.
+ */
+ basic_flat_streambuf(basic_flat_streambuf const&,
+ Allocator const& alloc);
+
+ /** Copy constructor.
+
+ The new object will have a copy of the input sequence
+ and an empty output sequence.
+ */
+ template
+ basic_flat_streambuf(
+ basic_flat_streambuf const&);
+
+ /** Copy constructor.
+
+ The new object will have a copy of the input sequence
+ and an empty output sequence.
+
+ @param alloc The allocator to associate with the
+ stream buffer.
+ */
+ template
+ basic_flat_streambuf(
+ basic_flat_streambuf const&,
+ Allocator const& alloc);
+
+ /** Construct a flat stream buffer.
+
+ No allocation is performed; the buffer will have
+ empty input and output sequences.
+
+ @param limit An optional non-zero value specifying the
+ maximum of the sum of the input and output sequence sizes
+ that can be allocated. If unspecified, the largest
+ possible value of `std::size_t` is used.
+ */
+ explicit
+ basic_flat_streambuf(std::size_t limit = (
+ std::numeric_limits::max)());
+
+ /** Construct a flat stream buffer.
+
+ No allocation is performed; the buffer will have
+ empty input and output sequences.
+
+ @param alloc The allocator to associate with the
+ stream buffer.
+
+ @param limit An optional non-zero value specifying the
+ maximum of the sum of the input and output sequence sizes
+ that can be allocated. If unspecified, the largest
+ possible value of `std::size_t` is used.
+ */
+ basic_flat_streambuf(Allocator const& alloc,
+ std::size_t limit = (
+ std::numeric_limits::max)());
+
+ /// Returns a copy of the associated allocator.
+ allocator_type
+ get_allocator() const
+ {
+ return this->member();
+ }
+
+ /// Returns the size of the input sequence.
+ std::size_t
+ size() const
+ {
+ return dist(in_, out_);
+ }
+
+ /// Return the maximum sum of the input and output sequence sizes.
+ std::size_t
+ max_size() const
+ {
+ return max_;
+ }
+
+ /// Return the maximum sum of input and output sizes that can be held without an allocation.
+ std::size_t
+ capacity() const
+ {
+ return dist(p_, end_);
+ }
+
+ /// Get a list of buffers that represent the input sequence.
+ const_buffers_type
+ data() const
+ {
+ return {in_, dist(in_, out_)};
+ }
+
+ /** Get a list of buffers that represent the output sequence, with the given size.
+
+ @throws std::length_error if `size() + n` exceeds `max_size()`.
+
+ @note All previous buffers sequences obtained from
+ calls to @ref data or @ref prepare are invalidated.
+ */
+ mutable_buffers_type
+ prepare(std::size_t n);
+
+ /** Move bytes from the output sequence to the input sequence.
+
+ @param n The number of bytes to move. If this is larger than
+ the number of bytes in the output sequences, then the entire
+ output sequences is moved.
+
+ @note All previous buffers sequences obtained from
+ calls to @ref data or @ref prepare are invalidated.
+ */
+ void
+ commit(std::size_t n)
+ {
+ out_ += (std::min)(n, dist(out_, last_));
+ }
+
+ /** Remove bytes from the input sequence.
+
+ If `n` is greater than the number of bytes in the input
+ sequence, all bytes in the input sequence are removed.
+
+ @note All previous buffers sequences obtained from
+ calls to @ref data or @ref prepare are invalidated.
+ */
+ void
+ consume(std::size_t n);
+
+ /** Reserve space in the stream.
+
+ This reallocates the buffer if necessary.
+
+ @note All previous buffers sequences obtained from
+ calls to @ref data or @ref prepare are invalidated.
+
+ @param n The number of bytes to reserve. Upon success,
+ the capacity will be at least `n`.
+
+ @throws std::length_error if `n` exceeds `max_size()`.
+ */
+ void
+ reserve(std::size_t n);
+
+ /** Reallocate the buffer to fit the input sequence.
+
+ @note All previous buffers sequences obtained from
+ calls to @ref data or @ref prepare are invalidated.
+ */
+ void
+ shrink_to_fit();
+
+ // Helper for boost::asio::read_until
+ template
+ friend
+ std::size_t
+ read_size_helper(basic_flat_streambuf<
+ OtherAlloc> const&, std::size_t);
+
+private:
+ void
+ move_from(basic_flat_streambuf& other);
+
+ template
+ void
+ copy_from(basic_flat_streambuf<
+ OtherAlloc> const& other);
+};
+
+using flat_streambuf =
+ basic_flat_streambuf>;
+
+} // beast
+
+#include
+
+#endif
diff --git a/include/beast/core/impl/flat_streambuf.ipp b/include/beast/core/impl/flat_streambuf.ipp
new file mode 100644
index 00000000..8a9cf79d
--- /dev/null
+++ b/include/beast/core/impl/flat_streambuf.ipp
@@ -0,0 +1,316 @@
+//
+// Copyright (c) 2013-2016 Vinnie Falco (vinnie dot falco at gmail dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BEAST_IMPL_FLAT_STREAMBUF_HPP
+#define BEAST_IMPL_FLAT_STREAMBUF_HPP
+
+#include
+#include
+
+namespace beast {
+
+/* Memory is laid out thusly:
+
+ p_ ..|.. in_ ..|.. out_ ..|.. last_ ..|.. end_
+*/
+
+namespace detail {
+
+inline
+std::size_t
+next_pow2(std::size_t x)
+{
+ std::size_t n = 0;
+ while(x > 0)
+ {
+ ++n;
+ x >>= 1;
+ }
+ return std::size_t{1} << n;
+}
+
+} // detail
+
+template
+void
+basic_flat_streambuf::
+move_from(basic_flat_streambuf& other)
+{
+ p_ = other.p_;
+ in_ = other.in_;
+ out_ = other.out_;
+ last_ = out_;
+ end_ = other.end_;
+ max_ = other.max_;
+ other.p_ = nullptr;
+ other.in_ = nullptr;
+ other.out_ = nullptr;
+ other.last_ = nullptr;
+ other.end_ = nullptr;
+}
+
+template
+template
+void
+basic_flat_streambuf::
+copy_from(basic_flat_streambuf<
+ OtherAlloc> const& other)
+{
+ max_ = other.max_;
+ auto const n = other.size();
+ if(n > 0)
+ {
+ p_ = alloc_traits::allocate(
+ this->member(), n);
+ in_ = p_;
+ out_ = p_ + n;
+ last_ = out_;
+ end_ = out_;
+ std::memcpy(in_, other.in_, n);
+ return;
+ }
+ p_ = nullptr;
+ in_ = nullptr;
+ out_ = nullptr;
+ last_ = nullptr;
+ end_ = nullptr;
+}
+
+template
+basic_flat_streambuf::
+~basic_flat_streambuf()
+{
+ if(p_)
+ alloc_traits::deallocate(
+ this->member(), p_, dist(p_, end_));
+}
+
+template
+basic_flat_streambuf::
+basic_flat_streambuf(basic_flat_streambuf&& other)
+ : detail::empty_base_optimization<
+ allocator_type>(std::move(other.member()))
+{
+ move_from(other);
+}
+
+template
+basic_flat_streambuf::
+basic_flat_streambuf(basic_flat_streambuf&& other,
+ Allocator const& alloc)
+ : detail::empty_base_optimization<
+ allocator_type>(alloc)
+{
+ if(this->member() != other.member())
+ {
+ copy_from(other);
+ return;
+ }
+ move_from(other);
+}
+
+template
+basic_flat_streambuf::
+basic_flat_streambuf(
+ basic_flat_streambuf const& other)
+ : detail::empty_base_optimization(
+ alloc_traits::select_on_container_copy_construction(
+ other.member()))
+{
+ copy_from(other);
+}
+
+template
+basic_flat_streambuf::
+basic_flat_streambuf(
+ basic_flat_streambuf const& other,
+ Allocator const& alloc)
+ : detail::empty_base_optimization<
+ allocator_type>(alloc)
+{
+ copy_from(other);
+}
+
+template
+template
+basic_flat_streambuf::
+basic_flat_streambuf(
+ basic_flat_streambuf const& other)
+{
+ copy_from(other);
+}
+
+template
+template
+basic_flat_streambuf::
+basic_flat_streambuf(
+ basic_flat_streambuf const& other,
+ Allocator const& alloc)
+ : detail::empty_base_optimization<
+ allocator_type>(alloc)
+{
+ copy_from(other);
+}
+
+template
+basic_flat_streambuf::
+basic_flat_streambuf(std::size_t limit)
+ : p_(nullptr)
+ , in_(nullptr)
+ , out_(nullptr)
+ , last_(nullptr)
+ , end_(nullptr)
+ , max_(limit)
+{
+ BOOST_ASSERT(limit >= 1);
+}
+
+template
+basic_flat_streambuf::
+basic_flat_streambuf(Allocator const& alloc,
+ std::size_t limit)
+ : detail::empty_base_optimization<
+ allocator_type>(alloc)
+ , p_(nullptr)
+ , in_(nullptr)
+ , out_(nullptr)
+ , last_(nullptr)
+ , end_(nullptr)
+ , max_(limit)
+{
+ BOOST_ASSERT(limit >= 1);
+}
+
+template
+auto
+basic_flat_streambuf::
+prepare(std::size_t n) ->
+ mutable_buffers_type
+{
+ if(n <= dist(out_, end_))
+ {
+ last_ = out_ + n;
+ return{out_, n};
+ }
+ auto const len = size();
+ if(n <= dist(p_, end_) - len)
+ {
+ if(len > 0)
+ std::memmove(p_, in_, len);
+ in_ = p_;
+ out_ = in_ + len;
+ last_ = out_ + n;
+ return {out_, n};
+ }
+ if(n > max_ - len)
+ throw std::length_error{
+ "flat_streambuf overflow"};
+ auto const new_size = (std::min)(max_,
+ std::max(
+ detail::next_pow2(len + n), min_size));
+ auto const p = alloc_traits::allocate(
+ this->member(), new_size);
+ std::memcpy(p, in_, len);
+ alloc_traits::deallocate(
+ this->member(), p_, dist(p_, end_));
+ p_ = p;
+ in_ = p_;
+ out_ = in_ + len;
+ last_ = out_ + n;
+ end_ = p_ + new_size;
+ return {out_, n};
+}
+
+template
+void
+basic_flat_streambuf::
+consume(std::size_t n)
+{
+ if(n >= dist(in_, out_))
+ {
+ in_ = p_;
+ out_ = p_;
+ return;
+ }
+ in_ += n;
+}
+
+template
+void
+basic_flat_streambuf::
+reserve(std::size_t n)
+{
+ if(n <= dist(p_, end_))
+ return;
+ if(n > max_)
+ throw std::length_error{
+ "flat_streambuf overflow"};
+ auto const new_size = (std::min)(max_,
+ std::max(
+ detail::next_pow2(n), min_size));
+ auto const p = alloc_traits::allocate(
+ this->member(), new_size);
+ auto const len = size();
+ if(len > 0)
+ std::memcpy(p, in_, len);
+ alloc_traits::deallocate(
+ this->member(), p_, dist(p_, end_));
+ p_ = p;
+ in_ = p_;
+ out_ = p_ + len;
+ last_ = out_;
+ end_ = p_ + new_size;
+}
+
+template
+void
+basic_flat_streambuf::
+shrink_to_fit()
+{
+ auto const len = size();
+ if(len == dist(p_, end_))
+ return;
+ char* p;
+ if(len > 0)
+ {
+ p = alloc_traits::allocate(
+ this->member(), len);
+ std::memcpy(p, in_, len);
+ }
+ else
+ {
+ p = nullptr;
+ }
+ alloc_traits::deallocate(
+ this->member(), p_, dist(p_, end_));
+ p_ = p;
+ in_ = p_;
+ out_ = p_ + len;
+ last_ = out_;
+ end_ = out_;
+}
+
+template
+std::size_t
+read_size_helper(basic_flat_streambuf<
+ Allocator> const& fb, std::size_t max_size)
+{
+ BOOST_ASSERT(max_size >= 1);
+ auto const len = fb.size();
+ auto const avail = fb.capacity() - len;
+ if (avail > 0)
+ return (std::min)(avail, max_size);
+ auto size = (std::min)(
+ fb.capacity() * 2, fb.max_size()) - len;
+ if(size == 0)
+ size = 1;
+ return (std::min)(size, max_size);
+}
+
+} // beast
+
+#endif
diff --git a/test/Jamfile b/test/Jamfile
index 018ec76f..cae47088 100644
--- a/test/Jamfile
+++ b/test/Jamfile
@@ -25,6 +25,7 @@ unit-test core-tests :
core/consuming_buffers.cpp
core/dynabuf_readstream.cpp
core/error.cpp
+ core/flat_streambuf.cpp
core/handler_alloc.cpp
core/handler_concepts.cpp
core/handler_ptr.cpp
diff --git a/test/core/CMakeLists.txt b/test/core/CMakeLists.txt
index 766627e3..cf1e24cf 100644
--- a/test/core/CMakeLists.txt
+++ b/test/core/CMakeLists.txt
@@ -18,6 +18,7 @@ add_executable (core-tests
consuming_buffers.cpp
dynabuf_readstream.cpp
error.cpp
+ flat_streambuf.cpp
handler_alloc.cpp
handler_concepts.cpp
handler_ptr.cpp
diff --git a/test/core/flat_streambuf.cpp b/test/core/flat_streambuf.cpp
new file mode 100644
index 00000000..c6c034aa
--- /dev/null
+++ b/test/core/flat_streambuf.cpp
@@ -0,0 +1,171 @@
+//
+// Copyright (c) 2013-2016 Vinnie Falco (vinnie dot falco at gmail dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+// Test that header file is self-contained.
+#include
+
+#include "buffer_test.hpp"
+#include
+#include
+
+namespace beast {
+
+static_assert(is_DynamicBuffer::value,
+ "DynamicBuffer requirements not met");
+
+class flat_streambuf_test : public beast::unit_test::suite
+{
+public:
+ template
+ static
+ bool
+ eq(basic_flat_streambuf const& sb1,
+ basic_flat_streambuf const& sb2)
+ {
+ return to_string(sb1.data()) == to_string(sb2.data());
+ }
+
+ void
+ testSpecialMembers()
+ {
+ using boost::asio::buffer;
+ using boost::asio::buffer_copy;
+ {
+ flat_streambuf fb{10};
+ BEAST_EXPECT(fb.max_size() == 10);
+ }
+ {
+ flat_streambuf fb{1024};
+ BEAST_EXPECT(fb.max_size() == 1024);
+ }
+ std::string const s = "Hello, world!";
+ for(std::size_t i = 1; i < s.size() - 1; ++i)
+ {
+ flat_streambuf fb{1024};
+ fb.commit(buffer_copy(
+ fb.prepare(i), buffer(s)));
+ fb.commit(buffer_copy(
+ fb.prepare(s.size() - i),
+ buffer(s.data() + i, s.size() - i)));
+ BEAST_EXPECT(to_string(fb.data()) == s);
+ {
+ flat_streambuf fb2{fb};
+ BEAST_EXPECT(eq(fb2, fb));
+ flat_streambuf fb3{std::move(fb2)};
+ BEAST_EXPECT(eq(fb3, fb));
+ BEAST_EXPECT(! eq(fb2, fb3));
+ BEAST_EXPECT(fb2.size() == 0);
+ }
+
+ using alloc_type = std::allocator;
+ using type =
+ basic_flat_streambuf;
+ alloc_type alloc;
+ {
+ type fba{alloc, 1};
+ BEAST_EXPECT(fba.max_size() == 1);
+ }
+ {
+ type fba{alloc, 1024};
+ BEAST_EXPECT(fba.max_size() == 1024);
+ }
+ {
+ type fb2{fb};
+ BEAST_EXPECT(eq(fb2, fb));
+ type fb3{std::move(fb2)};
+ BEAST_EXPECT(eq(fb3, fb));
+ BEAST_EXPECT(! eq(fb2, fb3));
+ BEAST_EXPECT(fb2.size() == 0);
+ }
+ {
+ type fb2{fb, alloc};
+ BEAST_EXPECT(eq(fb2, fb));
+ type fb3{std::move(fb2), alloc};
+ BEAST_EXPECT(eq(fb3, fb));
+ BEAST_EXPECT(! eq(fb2, fb3));
+ BEAST_EXPECT(fb2.size() == 0);
+ }
+ }
+ }
+
+ void
+ testStream()
+ {
+ using boost::asio::buffer_size;
+
+ flat_streambuf fb{100};
+ BEAST_EXPECT(fb.size() == 0);
+ BEAST_EXPECT(fb.capacity() == 0);
+
+ BEAST_EXPECT(buffer_size(fb.prepare(100)) == 100);
+ BEAST_EXPECT(fb.size() == 0);
+ BEAST_EXPECT(fb.capacity() > 0);
+
+ fb.commit(20);
+ BEAST_EXPECT(fb.size() == 20);
+ BEAST_EXPECT(fb.capacity() == 100);
+
+ fb.consume(5);
+ BEAST_EXPECT(fb.size() == 15);
+ BEAST_EXPECT(fb.capacity() == 100);
+
+ fb.prepare(80);
+ fb.commit(80);
+ BEAST_EXPECT(fb.size() == 95);
+ BEAST_EXPECT(fb.capacity() == 100);
+
+ fb.shrink_to_fit();
+ BEAST_EXPECT(fb.size() == 95);
+ BEAST_EXPECT(fb.capacity() == 95);
+ }
+
+ void
+ testPrepare()
+ {
+ flat_streambuf fb{100};
+ fb.prepare(20);
+ BEAST_EXPECT(fb.capacity() == 100);
+ fb.commit(10);
+ BEAST_EXPECT(fb.capacity() == 100);
+ fb.consume(4);
+ BEAST_EXPECT(fb.capacity() == 100);
+ fb.prepare(14);
+ BEAST_EXPECT(fb.size() == 6);
+ BEAST_EXPECT(fb.capacity() == 100);
+ fb.consume(10);
+ BEAST_EXPECT(fb.size() == 0);
+ BEAST_EXPECT(fb.capacity() == 100);
+ }
+
+ void
+ testMax()
+ {
+ flat_streambuf fb{1};
+ try
+ {
+ fb.prepare(2);
+ fail("", __FILE__, __LINE__);
+ }
+ catch(std::length_error const&)
+ {
+ pass();
+ }
+ }
+
+ void
+ run() override
+ {
+ testSpecialMembers();
+ testStream();
+ testPrepare();
+ testMax();
+ }
+};
+
+BEAST_DEFINE_TESTSUITE(flat_streambuf,core,beast);
+
+} // beast
diff --git a/test/core/streambuf.cpp b/test/core/streambuf.cpp
index eb295161..ee162672 100644
--- a/test/core/streambuf.cpp
+++ b/test/core/streambuf.cpp
@@ -172,8 +172,6 @@ public:
void testSpecialMembers()
{
using boost::asio::buffer;
- using boost::asio::buffer_cast;
- using boost::asio::buffer_size;
std::string const s = "Hello, world";
BEAST_EXPECT(s.size() == 12);
for(std::size_t i = 1; i < 12; ++i) {
@@ -263,7 +261,6 @@ public:
void testCommit()
{
- using boost::asio::buffer_size;
streambuf sb(2);
sb.prepare(2);
sb.prepare(5);
@@ -273,7 +270,6 @@ public:
void testConsume()
{
- using boost::asio::buffer_size;
streambuf sb(1);
expect_size(5, sb.prepare(5));
sb.commit(3);
@@ -285,7 +281,6 @@ public:
void testMatrix()
{
using boost::asio::buffer;
- using boost::asio::buffer_cast;
using boost::asio::buffer_size;
std::string const s = "Hello, world";
BEAST_EXPECT(s.size() == 12);