forked from boostorg/beast
Tune up static_buffer (API Change):
The static buffer is updated: * reset() is no longer a member. Use b.consume(b.size()) instead. * Simplified implementaton, uses asio instead of custom types * Better stream performance: consuming the input makes room available in the output. This class is now suitable for HTTP reads. These changes permit the static_buffer wrapper to adapt a user memory buffer if desired, including a stack based array. The static_buffer_n class may also be used for this purpose, it comes with its own storage.
This commit is contained in:
@@ -16,7 +16,7 @@ namespace beast {
|
||||
|
||||
/* Memory is laid out thusly:
|
||||
|
||||
p_ ..|.. in_ ..|.. out_ ..|.. last_ ..|.. end_
|
||||
begin_ ..|.. in_ ..|.. out_ ..|.. last_ ..|.. end_
|
||||
*/
|
||||
|
||||
namespace detail {
|
||||
@@ -41,13 +41,13 @@ void
|
||||
basic_flat_buffer<Allocator>::
|
||||
move_from(basic_flat_buffer& other)
|
||||
{
|
||||
p_ = other.p_;
|
||||
begin_ = other.begin_;
|
||||
in_ = other.in_;
|
||||
out_ = other.out_;
|
||||
last_ = out_;
|
||||
end_ = other.end_;
|
||||
max_ = other.max_;
|
||||
other.p_ = nullptr;
|
||||
other.begin_ = nullptr;
|
||||
other.in_ = nullptr;
|
||||
other.out_ = nullptr;
|
||||
other.last_ = nullptr;
|
||||
@@ -65,16 +65,16 @@ copy_from(basic_flat_buffer<
|
||||
auto const n = other.size();
|
||||
if(n > 0)
|
||||
{
|
||||
p_ = alloc_traits::allocate(
|
||||
begin_ = alloc_traits::allocate(
|
||||
this->member(), n);
|
||||
in_ = p_;
|
||||
out_ = p_ + n;
|
||||
in_ = begin_;
|
||||
out_ = begin_ + n;
|
||||
last_ = out_;
|
||||
end_ = out_;
|
||||
std::memcpy(in_, other.in_, n);
|
||||
return;
|
||||
}
|
||||
p_ = nullptr;
|
||||
begin_ = nullptr;
|
||||
in_ = nullptr;
|
||||
out_ = nullptr;
|
||||
last_ = nullptr;
|
||||
@@ -85,9 +85,9 @@ template<class Allocator>
|
||||
basic_flat_buffer<Allocator>::
|
||||
~basic_flat_buffer()
|
||||
{
|
||||
if(p_)
|
||||
if(begin_)
|
||||
alloc_traits::deallocate(
|
||||
this->member(), p_, dist(p_, end_));
|
||||
this->member(), begin_, dist(begin_, end_));
|
||||
}
|
||||
|
||||
template<class Allocator>
|
||||
@@ -160,7 +160,7 @@ basic_flat_buffer(
|
||||
template<class Allocator>
|
||||
basic_flat_buffer<Allocator>::
|
||||
basic_flat_buffer(std::size_t limit)
|
||||
: p_(nullptr)
|
||||
: begin_(nullptr)
|
||||
, in_(nullptr)
|
||||
, out_(nullptr)
|
||||
, last_(nullptr)
|
||||
@@ -176,7 +176,7 @@ basic_flat_buffer(Allocator const& alloc,
|
||||
std::size_t limit)
|
||||
: detail::empty_base_optimization<
|
||||
allocator_type>(alloc)
|
||||
, p_(nullptr)
|
||||
, begin_(nullptr)
|
||||
, in_(nullptr)
|
||||
, out_(nullptr)
|
||||
, last_(nullptr)
|
||||
@@ -204,8 +204,8 @@ prepare(std::size_t n) ->
|
||||
// after a memmove,
|
||||
// existing capacity is sufficient
|
||||
if(len > 0)
|
||||
std::memmove(p_, in_, len);
|
||||
in_ = p_;
|
||||
std::memmove(begin_, in_, len);
|
||||
in_ = begin_;
|
||||
out_ = in_ + len;
|
||||
last_ = out_ + n;
|
||||
return {out_, n};
|
||||
@@ -220,19 +220,19 @@ prepare(std::size_t n) ->
|
||||
detail::next_pow2(len + n), min_size));
|
||||
auto const p = alloc_traits::allocate(
|
||||
this->member(), new_size);
|
||||
if(p_)
|
||||
if(begin_)
|
||||
{
|
||||
BOOST_ASSERT(p);
|
||||
BOOST_ASSERT(in_);
|
||||
std::memcpy(p, in_, len);
|
||||
alloc_traits::deallocate(
|
||||
this->member(), p_, capacity());
|
||||
this->member(), begin_, capacity());
|
||||
}
|
||||
p_ = p;
|
||||
in_ = p_;
|
||||
begin_ = p;
|
||||
in_ = begin_;
|
||||
out_ = in_ + len;
|
||||
last_ = out_ + n;
|
||||
end_ = p_ + new_size;
|
||||
end_ = begin_ + new_size;
|
||||
return {out_, n};
|
||||
}
|
||||
|
||||
@@ -243,8 +243,8 @@ consume(std::size_t n)
|
||||
{
|
||||
if(n >= dist(in_, out_))
|
||||
{
|
||||
in_ = p_;
|
||||
out_ = p_;
|
||||
in_ = begin_;
|
||||
out_ = begin_;
|
||||
return;
|
||||
}
|
||||
in_ += n;
|
||||
@@ -266,19 +266,19 @@ reserve(std::size_t n)
|
||||
auto const p = alloc_traits::allocate(
|
||||
this->member(), new_size);
|
||||
auto const len = size();
|
||||
if(p_)
|
||||
if(begin_)
|
||||
{
|
||||
BOOST_ASSERT(p_);
|
||||
BOOST_ASSERT(begin_);
|
||||
BOOST_ASSERT(in_);
|
||||
std::memcpy(p, in_, len);
|
||||
alloc_traits::deallocate(
|
||||
this->member(), p_, capacity());
|
||||
this->member(), begin_, capacity());
|
||||
}
|
||||
p_ = p;
|
||||
in_ = p_;
|
||||
out_ = p_ + len;
|
||||
begin_ = p;
|
||||
in_ = begin_;
|
||||
out_ = begin_ + len;
|
||||
last_ = out_;
|
||||
end_ = p_ + new_size;
|
||||
end_ = begin_ + new_size;
|
||||
}
|
||||
|
||||
template<class Allocator>
|
||||
@@ -292,7 +292,7 @@ shrink_to_fit()
|
||||
char* p;
|
||||
if(len > 0)
|
||||
{
|
||||
BOOST_ASSERT(p_);
|
||||
BOOST_ASSERT(begin_);
|
||||
BOOST_ASSERT(in_);
|
||||
p = alloc_traits::allocate(
|
||||
this->member(), len);
|
||||
@@ -303,10 +303,10 @@ shrink_to_fit()
|
||||
p = nullptr;
|
||||
}
|
||||
alloc_traits::deallocate(
|
||||
this->member(), p_, dist(p_, end_));
|
||||
p_ = p;
|
||||
in_ = p_;
|
||||
out_ = p_ + len;
|
||||
this->member(), begin_, dist(begin_, end_));
|
||||
begin_ = p;
|
||||
in_ = begin_;
|
||||
out_ = begin_ + len;
|
||||
last_ = out_;
|
||||
end_ = out_;
|
||||
}
|
||||
|
||||
@@ -18,288 +18,85 @@
|
||||
|
||||
namespace beast {
|
||||
|
||||
class static_buffer::const_buffers_type
|
||||
{
|
||||
std::size_t n_;
|
||||
std::uint8_t const* p_;
|
||||
/* Memory is laid out thusly:
|
||||
|
||||
public:
|
||||
using value_type = boost::asio::const_buffer;
|
||||
|
||||
class const_iterator;
|
||||
|
||||
const_buffers_type() = delete;
|
||||
const_buffers_type(
|
||||
const_buffers_type const&) = default;
|
||||
const_buffers_type& operator=(
|
||||
const_buffers_type const&) = default;
|
||||
|
||||
const_iterator
|
||||
begin() const;
|
||||
|
||||
const_iterator
|
||||
end() const;
|
||||
|
||||
private:
|
||||
friend class static_buffer;
|
||||
|
||||
const_buffers_type(
|
||||
std::uint8_t const* p, std::size_t n)
|
||||
: n_(n)
|
||||
, p_(p)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class static_buffer::const_buffers_type::const_iterator
|
||||
{
|
||||
std::size_t n_ = 0;
|
||||
std::uint8_t const* p_ = nullptr;
|
||||
|
||||
public:
|
||||
using value_type = boost::asio::const_buffer;
|
||||
using pointer = value_type const*;
|
||||
using reference = value_type;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using iterator_category =
|
||||
std::bidirectional_iterator_tag;
|
||||
|
||||
const_iterator() = default;
|
||||
const_iterator(const_iterator&& other) = default;
|
||||
const_iterator(const_iterator const& other) = default;
|
||||
const_iterator& operator=(const_iterator&& other) = default;
|
||||
const_iterator& operator=(const_iterator const& other) = default;
|
||||
|
||||
bool
|
||||
operator==(const_iterator const& other) const
|
||||
{
|
||||
return p_ == other.p_;
|
||||
}
|
||||
|
||||
bool
|
||||
operator!=(const_iterator const& other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
reference
|
||||
operator*() const
|
||||
{
|
||||
return value_type{p_, n_};
|
||||
}
|
||||
|
||||
pointer
|
||||
operator->() const = delete;
|
||||
|
||||
const_iterator&
|
||||
operator++()
|
||||
{
|
||||
p_ += n_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const_iterator
|
||||
operator++(int)
|
||||
{
|
||||
auto temp = *this;
|
||||
++(*this);
|
||||
return temp;
|
||||
}
|
||||
|
||||
const_iterator&
|
||||
operator--()
|
||||
{
|
||||
p_ -= n_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const_iterator
|
||||
operator--(int)
|
||||
{
|
||||
auto temp = *this;
|
||||
--(*this);
|
||||
return temp;
|
||||
}
|
||||
|
||||
private:
|
||||
friend class const_buffers_type;
|
||||
|
||||
const_iterator(
|
||||
std::uint8_t const* p, std::size_t n)
|
||||
: n_(n)
|
||||
, p_(p)
|
||||
{
|
||||
}
|
||||
};
|
||||
begin_ ..|.. in_ ..|.. out_ ..|.. last_ ..|.. end_
|
||||
*/
|
||||
|
||||
inline
|
||||
auto
|
||||
static_buffer::const_buffers_type::begin() const ->
|
||||
const_iterator
|
||||
{
|
||||
return const_iterator{p_, n_};
|
||||
}
|
||||
|
||||
inline
|
||||
auto
|
||||
static_buffer::const_buffers_type::end() const ->
|
||||
const_iterator
|
||||
{
|
||||
return const_iterator{p_ + n_, n_};
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
class static_buffer::mutable_buffers_type
|
||||
{
|
||||
std::size_t n_;
|
||||
std::uint8_t* p_;
|
||||
|
||||
public:
|
||||
using value_type = boost::asio::mutable_buffer;
|
||||
|
||||
class const_iterator;
|
||||
|
||||
mutable_buffers_type() = delete;
|
||||
mutable_buffers_type(
|
||||
mutable_buffers_type const&) = default;
|
||||
mutable_buffers_type& operator=(
|
||||
mutable_buffers_type const&) = default;
|
||||
|
||||
const_iterator
|
||||
begin() const;
|
||||
|
||||
const_iterator
|
||||
end() const;
|
||||
|
||||
private:
|
||||
friend class static_buffer;
|
||||
|
||||
mutable_buffers_type(
|
||||
std::uint8_t* p, std::size_t n)
|
||||
: n_(n)
|
||||
, p_(p)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class static_buffer::mutable_buffers_type::const_iterator
|
||||
{
|
||||
std::size_t n_ = 0;
|
||||
std::uint8_t* p_ = nullptr;
|
||||
|
||||
public:
|
||||
using value_type = boost::asio::mutable_buffer;
|
||||
using pointer = value_type const*;
|
||||
using reference = value_type;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using iterator_category =
|
||||
std::bidirectional_iterator_tag;
|
||||
|
||||
const_iterator() = default;
|
||||
const_iterator(const_iterator&& other) = default;
|
||||
const_iterator(const_iterator const& other) = default;
|
||||
const_iterator& operator=(const_iterator&& other) = default;
|
||||
const_iterator& operator=(const_iterator const& other) = default;
|
||||
|
||||
bool
|
||||
operator==(const_iterator const& other) const
|
||||
{
|
||||
return p_ == other.p_;
|
||||
}
|
||||
|
||||
bool
|
||||
operator!=(const_iterator const& other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
reference
|
||||
operator*() const
|
||||
{
|
||||
return value_type{p_, n_};
|
||||
}
|
||||
|
||||
pointer
|
||||
operator->() const = delete;
|
||||
|
||||
const_iterator&
|
||||
operator++()
|
||||
{
|
||||
p_ += n_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const_iterator
|
||||
operator++(int)
|
||||
{
|
||||
auto temp = *this;
|
||||
++(*this);
|
||||
return temp;
|
||||
}
|
||||
|
||||
const_iterator&
|
||||
operator--()
|
||||
{
|
||||
p_ -= n_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const_iterator
|
||||
operator--(int)
|
||||
{
|
||||
auto temp = *this;
|
||||
--(*this);
|
||||
return temp;
|
||||
}
|
||||
|
||||
private:
|
||||
friend class mutable_buffers_type;
|
||||
|
||||
const_iterator(std::uint8_t* p, std::size_t n)
|
||||
: n_(n)
|
||||
, p_(p)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
inline
|
||||
auto
|
||||
static_buffer::mutable_buffers_type::begin() const ->
|
||||
const_iterator
|
||||
{
|
||||
return const_iterator{p_, n_};
|
||||
}
|
||||
|
||||
inline
|
||||
auto
|
||||
static_buffer::mutable_buffers_type::end() const ->
|
||||
const_iterator
|
||||
{
|
||||
return const_iterator{p_ + n_, n_};
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
inline
|
||||
auto
|
||||
static_buffer::data() const ->
|
||||
static_buffer::
|
||||
data() const ->
|
||||
const_buffers_type
|
||||
{
|
||||
return const_buffers_type{in_,
|
||||
static_cast<std::size_t>(out_ - in_)};
|
||||
return {in_, dist(in_, out_)};
|
||||
}
|
||||
|
||||
inline
|
||||
auto
|
||||
static_buffer::prepare(std::size_t n) ->
|
||||
static_buffer::
|
||||
prepare(std::size_t n) ->
|
||||
mutable_buffers_type
|
||||
{
|
||||
if(n > static_cast<std::size_t>(end_ - out_))
|
||||
return prepare_impl(n);
|
||||
}
|
||||
|
||||
inline
|
||||
void
|
||||
static_buffer::
|
||||
reset(void* p, std::size_t n)
|
||||
{
|
||||
reset_impl(p, n);
|
||||
}
|
||||
|
||||
template<class>
|
||||
void
|
||||
static_buffer::
|
||||
reset_impl(void* p, std::size_t n)
|
||||
{
|
||||
begin_ =
|
||||
reinterpret_cast<char*>(p);
|
||||
in_ = begin_;
|
||||
out_ = begin_;
|
||||
last_ = begin_;
|
||||
end_ = begin_ + n;
|
||||
}
|
||||
|
||||
template<class>
|
||||
auto
|
||||
static_buffer::
|
||||
prepare_impl(std::size_t n) ->
|
||||
mutable_buffers_type
|
||||
{
|
||||
if(n <= dist(out_, end_))
|
||||
{
|
||||
last_ = out_ + n;
|
||||
return {out_, n};
|
||||
}
|
||||
auto const len = size();
|
||||
if(n > capacity() - len)
|
||||
BOOST_THROW_EXCEPTION(std::length_error{
|
||||
"static_buffer overflow"});
|
||||
if(len > 0)
|
||||
std::memmove(begin_, in_, len);
|
||||
in_ = begin_;
|
||||
out_ = in_ + len;
|
||||
last_ = out_ + n;
|
||||
return mutable_buffers_type{out_, n};
|
||||
return {out_, n};
|
||||
}
|
||||
|
||||
template<class>
|
||||
void
|
||||
static_buffer::
|
||||
consume_impl(std::size_t n)
|
||||
{
|
||||
if(n >= size())
|
||||
{
|
||||
in_ = begin_;
|
||||
out_ = in_;
|
||||
return;
|
||||
}
|
||||
in_ += n;
|
||||
}
|
||||
|
||||
} // beast
|
||||
|
||||
Reference in New Issue
Block a user