mirror of
https://github.com/boostorg/beast.git
synced 2025-07-31 05:17:26 +02:00
Refactor multi_buffer
This commit is contained in:
10
CHANGELOG.md
10
CHANGELOG.md
@ -1,3 +1,13 @@
|
|||||||
|
Version 286:
|
||||||
|
|
||||||
|
* Refactor multi_buffer
|
||||||
|
|
||||||
|
API Changes:
|
||||||
|
|
||||||
|
* multi_buffer::mutable_data_type is deprecated. Use multi_buffer::mutable_buffers_type instead
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
Version 285:
|
Version 285:
|
||||||
|
|
||||||
* Translate some win32 errors to net error codes
|
* Translate some win32 errors to net error codes
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include <boost/throw_exception.hpp>
|
#include <boost/throw_exception.hpp>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <exception>
|
#include <exception>
|
||||||
|
#include <iterator>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
@ -98,17 +99,155 @@ namespace beast {
|
|||||||
|
|
||||||
template<class Allocator>
|
template<class Allocator>
|
||||||
template<bool isMutable>
|
template<bool isMutable>
|
||||||
class basic_multi_buffer<Allocator>::readable_bytes
|
class basic_multi_buffer<Allocator>::subrange
|
||||||
{
|
{
|
||||||
basic_multi_buffer const* b_;
|
basic_multi_buffer const* b_;
|
||||||
|
const_iter begin_;
|
||||||
|
const_iter end_;
|
||||||
|
size_type begin_pos_; // offset in begin_
|
||||||
|
size_type last_pos_; // offset in std::prev(end_)
|
||||||
|
|
||||||
friend class basic_multi_buffer;
|
friend class basic_multi_buffer;
|
||||||
|
|
||||||
explicit
|
subrange(
|
||||||
readable_bytes(
|
basic_multi_buffer const& b,
|
||||||
basic_multi_buffer const& b) noexcept
|
size_type pos,
|
||||||
|
size_type n) noexcept
|
||||||
: b_(&b)
|
: b_(&b)
|
||||||
{
|
{
|
||||||
|
auto const set_empty = [&]
|
||||||
|
{
|
||||||
|
begin_ = b_->list_.end();
|
||||||
|
end_ = b_->list_.end();
|
||||||
|
begin_pos_ = 0;
|
||||||
|
last_pos_ = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// VFALCO Handle this trivial case of
|
||||||
|
// pos larger than total size, otherwise
|
||||||
|
// the addition to pos can overflow.
|
||||||
|
//if(pos >= b_->in_size_)
|
||||||
|
// skip unused prefix
|
||||||
|
pos = pos + b_->in_pos_;
|
||||||
|
|
||||||
|
// iterate the buffers
|
||||||
|
auto it = b_->list_.begin();
|
||||||
|
|
||||||
|
// is the list empty?
|
||||||
|
if(it == b_->list_.end())
|
||||||
|
{
|
||||||
|
set_empty();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// is the requested size zero?
|
||||||
|
if(n == 0)
|
||||||
|
{
|
||||||
|
set_empty();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// get last buffer and its size
|
||||||
|
auto const last =
|
||||||
|
std::prev(b_->list_.end());
|
||||||
|
auto const last_end =
|
||||||
|
[&]
|
||||||
|
{
|
||||||
|
if(b_->out_end_ == 0)
|
||||||
|
return last->size();
|
||||||
|
return b_->out_end_;
|
||||||
|
}();
|
||||||
|
|
||||||
|
// only one buffer in list?
|
||||||
|
if(it == last)
|
||||||
|
{
|
||||||
|
if(pos >= last_end)
|
||||||
|
{
|
||||||
|
set_empty();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
begin_ = it;
|
||||||
|
begin_pos_ = pos;
|
||||||
|
end_ = std::next(it);
|
||||||
|
if(n > last_end - pos)
|
||||||
|
last_pos_ = last_end;
|
||||||
|
else
|
||||||
|
last_pos_ = pos + n;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
// is pos in this buffer?
|
||||||
|
if(pos < it->size())
|
||||||
|
{
|
||||||
|
begin_ = it;
|
||||||
|
begin_pos_ = pos;
|
||||||
|
|
||||||
|
// does this buffer satisfy n?
|
||||||
|
auto const avail =
|
||||||
|
it->size() - pos;
|
||||||
|
if(n <= avail)
|
||||||
|
{
|
||||||
|
end_ = ++it;
|
||||||
|
last_pos_ = pos + n;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
n -= avail;
|
||||||
|
++it;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos -= it->size();
|
||||||
|
++it;
|
||||||
|
|
||||||
|
// did we reach the last buffer?
|
||||||
|
if(it == last)
|
||||||
|
{
|
||||||
|
// is pos past the end?
|
||||||
|
if(pos >= last_end)
|
||||||
|
{
|
||||||
|
set_empty();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// satisfy the request
|
||||||
|
begin_ = it;
|
||||||
|
begin_pos_ = pos;
|
||||||
|
end_ = std::next(it);
|
||||||
|
if(n < last_end - pos)
|
||||||
|
last_pos_ = pos + n;
|
||||||
|
else
|
||||||
|
last_pos_ = last_end;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// find pos+n
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
if(it == last)
|
||||||
|
{
|
||||||
|
end_ = ++it;
|
||||||
|
if(n >= last_end)
|
||||||
|
last_pos_ = last_end;
|
||||||
|
else
|
||||||
|
last_pos_ = n;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(n <= it->size())
|
||||||
|
{
|
||||||
|
end_ = ++it;
|
||||||
|
last_pos_ = n;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
n -= it->size();
|
||||||
|
++it;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -120,39 +259,55 @@ public:
|
|||||||
|
|
||||||
class const_iterator;
|
class const_iterator;
|
||||||
|
|
||||||
readable_bytes() = delete;
|
subrange() = delete;
|
||||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1910)
|
#if BOOST_WORKAROUND(BOOST_MSVC, < 1910)
|
||||||
readable_bytes(readable_bytes const& other)
|
subrange(subrange const& other)
|
||||||
: b_(other.b_)
|
: b_(other.b_)
|
||||||
|
, begin_(other.begin_)
|
||||||
|
, end_(other.end_)
|
||||||
|
, begin_pos_(other.begin_pos_)
|
||||||
|
, last_pos_(other.last_pos_)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
readable_bytes& operator=(readable_bytes const& other)
|
subrange& operator=(subrange const& other)
|
||||||
{
|
{
|
||||||
b_ = other.b_;
|
b_ = other.b_;
|
||||||
|
begin_ = other.begin_;
|
||||||
|
end_ = other.end_;
|
||||||
|
begin_pos_ = other.begin_pos_;
|
||||||
|
last_pos_ = other.last_pos_;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
readable_bytes(readable_bytes const&) = default;
|
subrange(subrange const&) = default;
|
||||||
readable_bytes& operator=(readable_bytes const&) = default;
|
subrange& operator=(subrange const&) = default;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template<
|
template<
|
||||||
bool isMutable_ = isMutable,
|
bool isMutable_ = isMutable,
|
||||||
class = typename std::enable_if<! isMutable_>::type>
|
class = typename std::enable_if<! isMutable_>::type>
|
||||||
readable_bytes(
|
subrange(
|
||||||
readable_bytes<true> const& other) noexcept
|
subrange<true> const& other) noexcept
|
||||||
: b_(other.b_)
|
: b_(other.b_)
|
||||||
{
|
, begin_(other.begin_)
|
||||||
|
, end_(other.end_)
|
||||||
|
, begin_pos_(other.begin_pos_)
|
||||||
|
, last_pos_(other.last_pos_)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
template<
|
template<
|
||||||
bool isMutable_ = isMutable,
|
bool isMutable_ = isMutable,
|
||||||
class = typename std::enable_if<! isMutable_>::type>
|
class = typename std::enable_if<! isMutable_>::type>
|
||||||
readable_bytes& operator=(
|
subrange& operator=(
|
||||||
readable_bytes<true> const& other) noexcept
|
subrange<true> const& other) noexcept
|
||||||
{
|
{
|
||||||
b_ = other.b_;
|
b_ = other.b_;
|
||||||
|
begin_ = other.begin_;
|
||||||
|
end_ = other.end_;
|
||||||
|
begin_pos_ = other.begin_pos_;
|
||||||
|
last_pos_ = other.last_pos_;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,15 +331,25 @@ template<class Allocator>
|
|||||||
template<bool isMutable>
|
template<bool isMutable>
|
||||||
class
|
class
|
||||||
basic_multi_buffer<Allocator>::
|
basic_multi_buffer<Allocator>::
|
||||||
readable_bytes<isMutable>::
|
subrange<isMutable>::
|
||||||
const_iterator
|
const_iterator
|
||||||
{
|
{
|
||||||
basic_multi_buffer const* b_ = nullptr;
|
friend class subrange;
|
||||||
|
|
||||||
|
subrange const* sr_ = nullptr;
|
||||||
typename list_type::const_iterator it_;
|
typename list_type::const_iterator it_;
|
||||||
|
|
||||||
|
const_iterator(
|
||||||
|
subrange const& sr, typename
|
||||||
|
list_type::const_iterator const& it) noexcept
|
||||||
|
: sr_(&sr)
|
||||||
|
, it_(it)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using value_type =
|
using value_type =
|
||||||
typename readable_bytes::value_type;
|
typename subrange::value_type;
|
||||||
using pointer = value_type const*;
|
using pointer = value_type const*;
|
||||||
using reference = value_type;
|
using reference = value_type;
|
||||||
using difference_type = std::ptrdiff_t;
|
using difference_type = std::ptrdiff_t;
|
||||||
@ -197,22 +362,16 @@ public:
|
|||||||
const_iterator& operator=(
|
const_iterator& operator=(
|
||||||
const_iterator const& other) = default;
|
const_iterator const& other) = default;
|
||||||
|
|
||||||
const_iterator(
|
bool
|
||||||
basic_multi_buffer const& b, typename
|
operator==(
|
||||||
list_type::const_iterator const& it) noexcept
|
const_iterator const& other) const noexcept
|
||||||
: b_(&b)
|
|
||||||
, it_(it)
|
|
||||||
{
|
{
|
||||||
|
return sr_ == other.sr_ && it_ == other.it_;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
operator==(const_iterator const& other) const noexcept
|
operator!=(
|
||||||
{
|
const_iterator const& other) const noexcept
|
||||||
return b_ == other.b_ && it_ == other.it_;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
operator!=(const_iterator const& other) const noexcept
|
|
||||||
{
|
{
|
||||||
return !(*this == other);
|
return !(*this == other);
|
||||||
}
|
}
|
||||||
@ -220,125 +379,17 @@ public:
|
|||||||
reference
|
reference
|
||||||
operator*() const noexcept
|
operator*() const noexcept
|
||||||
{
|
{
|
||||||
auto const& e = *it_;
|
value_type result;
|
||||||
return value_type{e.data(),
|
BOOST_ASSERT(sr_->last_pos_ != 0);
|
||||||
(b_->out_ == b_->list_.end() ||
|
if(it_ == std::prev(sr_->end_))
|
||||||
&e != &*b_->out_) ? e.size() : b_->out_pos_} +
|
result = {
|
||||||
(&e == &*b_->list_.begin() ? b_->in_pos_ : 0);
|
it_->data(), sr_->last_pos_ };
|
||||||
}
|
else
|
||||||
|
result = {
|
||||||
pointer
|
it_->data(), it_->size() };
|
||||||
operator->() const = delete;
|
if(it_ == sr_->begin_)
|
||||||
|
result += sr_->begin_pos_;
|
||||||
const_iterator&
|
return result;
|
||||||
operator++() noexcept
|
|
||||||
{
|
|
||||||
++it_;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
const_iterator
|
|
||||||
operator++(int) noexcept
|
|
||||||
{
|
|
||||||
auto temp = *this;
|
|
||||||
++(*this);
|
|
||||||
return temp;
|
|
||||||
}
|
|
||||||
|
|
||||||
const_iterator&
|
|
||||||
operator--() noexcept
|
|
||||||
{
|
|
||||||
--it_;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
const_iterator
|
|
||||||
operator--(int) noexcept
|
|
||||||
{
|
|
||||||
auto temp = *this;
|
|
||||||
--(*this);
|
|
||||||
return temp;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
template<class Allocator>
|
|
||||||
class basic_multi_buffer<Allocator>::mutable_buffers_type
|
|
||||||
{
|
|
||||||
basic_multi_buffer const* b_;
|
|
||||||
|
|
||||||
friend class basic_multi_buffer;
|
|
||||||
|
|
||||||
explicit
|
|
||||||
mutable_buffers_type(
|
|
||||||
basic_multi_buffer const& b) noexcept
|
|
||||||
: b_(&b)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
using value_type = net::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 noexcept;
|
|
||||||
const_iterator end() const noexcept;
|
|
||||||
};
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
template<class Allocator>
|
|
||||||
class basic_multi_buffer<Allocator>::mutable_buffers_type::const_iterator
|
|
||||||
{
|
|
||||||
basic_multi_buffer const* b_ = nullptr;
|
|
||||||
typename list_type::const_iterator it_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
using value_type = typename
|
|
||||||
mutable_buffers_type::value_type;
|
|
||||||
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 const& other) = default;
|
|
||||||
const_iterator& operator=(const_iterator const& other) = default;
|
|
||||||
|
|
||||||
const_iterator(
|
|
||||||
basic_multi_buffer const& b,
|
|
||||||
typename list_type::const_iterator const& it) noexcept
|
|
||||||
: b_(&b)
|
|
||||||
, it_(it)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
operator==(const_iterator const& other) const noexcept
|
|
||||||
{
|
|
||||||
return b_ == other.b_ && it_ == other.it_;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
operator!=(const_iterator const& other) const noexcept
|
|
||||||
{
|
|
||||||
return !(*this == other);
|
|
||||||
}
|
|
||||||
|
|
||||||
reference
|
|
||||||
operator*() const noexcept
|
|
||||||
{
|
|
||||||
auto const& e = *it_;
|
|
||||||
return value_type{e.data(),
|
|
||||||
&e == &*std::prev(b_->list_.end()) ?
|
|
||||||
b_->out_end_ : e.size()} +
|
|
||||||
(&e == &*b_->out_ ? b_->out_pos_ : 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pointer
|
pointer
|
||||||
@ -381,44 +432,24 @@ template<class Allocator>
|
|||||||
template<bool isMutable>
|
template<bool isMutable>
|
||||||
auto
|
auto
|
||||||
basic_multi_buffer<Allocator>::
|
basic_multi_buffer<Allocator>::
|
||||||
readable_bytes<isMutable>::
|
subrange<isMutable>::
|
||||||
begin() const noexcept ->
|
begin() const noexcept ->
|
||||||
const_iterator
|
const_iterator
|
||||||
{
|
{
|
||||||
return const_iterator{*b_, b_->list_.begin()};
|
return const_iterator(
|
||||||
|
*this, begin_);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Allocator>
|
template<class Allocator>
|
||||||
template<bool isMutable>
|
template<bool isMutable>
|
||||||
auto
|
auto
|
||||||
basic_multi_buffer<Allocator>::
|
basic_multi_buffer<Allocator>::
|
||||||
readable_bytes<isMutable>::
|
subrange<isMutable>::
|
||||||
end() const noexcept ->
|
end() const noexcept ->
|
||||||
const_iterator
|
const_iterator
|
||||||
{
|
{
|
||||||
return const_iterator{*b_, b_->out_ ==
|
return const_iterator(
|
||||||
b_->list_.end() ? b_->list_.end() :
|
*this, end_);
|
||||||
std::next(b_->out_)};
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Allocator>
|
|
||||||
auto
|
|
||||||
basic_multi_buffer<Allocator>::
|
|
||||||
mutable_buffers_type::
|
|
||||||
begin() const noexcept ->
|
|
||||||
const_iterator
|
|
||||||
{
|
|
||||||
return const_iterator{*b_, b_->out_};
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Allocator>
|
|
||||||
auto
|
|
||||||
basic_multi_buffer<Allocator>::
|
|
||||||
mutable_buffers_type::
|
|
||||||
end() const noexcept ->
|
|
||||||
const_iterator
|
|
||||||
{
|
|
||||||
return const_iterator{*b_, b_->list_.end()};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@ -631,16 +662,18 @@ basic_multi_buffer<Allocator>::
|
|||||||
data() const noexcept ->
|
data() const noexcept ->
|
||||||
const_buffers_type
|
const_buffers_type
|
||||||
{
|
{
|
||||||
return const_buffers_type(*this);
|
return const_buffers_type(
|
||||||
|
*this, 0, in_size_);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Allocator>
|
template<class Allocator>
|
||||||
auto
|
auto
|
||||||
basic_multi_buffer<Allocator>::
|
basic_multi_buffer<Allocator>::
|
||||||
data() noexcept ->
|
data() noexcept ->
|
||||||
mutable_data_type
|
mutable_buffers_type
|
||||||
{
|
{
|
||||||
return mutable_data_type(*this);
|
return mutable_buffers_type(
|
||||||
|
*this, 0, in_size_);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Allocator>
|
template<class Allocator>
|
||||||
@ -818,6 +851,7 @@ basic_multi_buffer<Allocator>::
|
|||||||
prepare(size_type n) ->
|
prepare(size_type n) ->
|
||||||
mutable_buffers_type
|
mutable_buffers_type
|
||||||
{
|
{
|
||||||
|
auto const n0 = n;
|
||||||
if(in_size_ > max_ || n > (max_ - in_size_))
|
if(in_size_ > max_ || n > (max_ - in_size_))
|
||||||
BOOST_THROW_EXCEPTION(std::length_error{
|
BOOST_THROW_EXCEPTION(std::length_error{
|
||||||
"basic_multi_buffer too long"});
|
"basic_multi_buffer too long"});
|
||||||
@ -878,7 +912,7 @@ prepare(size_type n) ->
|
|||||||
destroy(reuse);
|
destroy(reuse);
|
||||||
if(n > 0)
|
if(n > 0)
|
||||||
{
|
{
|
||||||
static auto const growth_factor = 2.0f;
|
auto const growth_factor = 2.0f;
|
||||||
auto const size =
|
auto const size =
|
||||||
(std::min<std::size_t>)(
|
(std::min<std::size_t>)(
|
||||||
max_ - total,
|
max_ - total,
|
||||||
@ -897,7 +931,12 @@ prepare(size_type n) ->
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return mutable_buffers_type(*this);
|
auto const result =
|
||||||
|
mutable_buffers_type(
|
||||||
|
*this, in_size_, n0);
|
||||||
|
BOOST_ASSERT(
|
||||||
|
net::buffer_size(result) == n0);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Allocator>
|
template<class Allocator>
|
||||||
|
@ -111,7 +111,7 @@ class basic_multi_buffer
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<bool>
|
template<bool>
|
||||||
class readable_bytes;
|
class subrange;
|
||||||
|
|
||||||
using size_type = typename
|
using size_type = typename
|
||||||
detail::allocator_traits<Allocator>::size_type;
|
detail::allocator_traits<Allocator>::size_type;
|
||||||
@ -156,6 +156,23 @@ class basic_multi_buffer
|
|||||||
size_type out_end_ = 0; // output end offset in list_.back()
|
size_type out_end_ = 0; // output end offset in list_.back()
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
#if BOOST_BEAST_DOXYGEN
|
||||||
|
/// The ConstBufferSequence used to represent the readable bytes.
|
||||||
|
using const_buffers_type = __implementation_defined__;
|
||||||
|
|
||||||
|
/// The MutableBufferSequence used to represent the writable bytes.
|
||||||
|
using mutable_buffers_type = __implementation_defined__;
|
||||||
|
#else
|
||||||
|
using const_buffers_type = subrange<false>;
|
||||||
|
|
||||||
|
using mutable_buffers_type = subrange<true>;
|
||||||
|
|
||||||
|
#ifdef BOOST_BEAST_ALLOW_DEPRECATED
|
||||||
|
using mutable_data_type = subrange<true>;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/// The type of allocator used.
|
/// The type of allocator used.
|
||||||
using allocator_type = Allocator;
|
using allocator_type = Allocator;
|
||||||
|
|
||||||
@ -447,21 +464,6 @@ public:
|
|||||||
|
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
#if BOOST_BEAST_DOXYGEN
|
|
||||||
/// The ConstBufferSequence used to represent the readable bytes.
|
|
||||||
using const_buffers_type = __implementation_defined__;
|
|
||||||
|
|
||||||
/// The MutableBufferSequence used to represent the readable bytes.
|
|
||||||
using mutable_data_type = __implementation_defined__;
|
|
||||||
|
|
||||||
/// The MutableBufferSequence used to represent the writable bytes.
|
|
||||||
using mutable_buffers_type = __implementation_defined__;
|
|
||||||
#else
|
|
||||||
using const_buffers_type = readable_bytes<false>;
|
|
||||||
using mutable_data_type = readable_bytes<true>;
|
|
||||||
class mutable_buffers_type;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// Returns the number of readable bytes.
|
/// Returns the number of readable bytes.
|
||||||
size_type
|
size_type
|
||||||
size() const noexcept
|
size() const noexcept
|
||||||
@ -501,7 +503,7 @@ public:
|
|||||||
|
|
||||||
@note The sequence may contain multiple contiguous memory regions.
|
@note The sequence may contain multiple contiguous memory regions.
|
||||||
*/
|
*/
|
||||||
mutable_data_type
|
mutable_buffers_type
|
||||||
data() noexcept;
|
data() noexcept;
|
||||||
|
|
||||||
/** Returns a mutable buffer sequence representing writable bytes.
|
/** Returns a mutable buffer sequence representing writable bytes.
|
||||||
|
@ -25,6 +25,7 @@ public:
|
|||||||
{
|
{
|
||||||
multi_buffer b;
|
multi_buffer b;
|
||||||
ostream(b) << "Hello, ";
|
ostream(b) << "Hello, ";
|
||||||
|
BEAST_EXPECT(buffers_to_string(b.data()) == "Hello, ");
|
||||||
ostream(b) << "world!";
|
ostream(b) << "world!";
|
||||||
BEAST_EXPECT(buffers_to_string(b.data()) == "Hello, world!");
|
BEAST_EXPECT(buffers_to_string(b.data()) == "Hello, world!");
|
||||||
}
|
}
|
||||||
|
@ -37,10 +37,10 @@ public:
|
|||||||
|
|
||||||
#if ! BOOST_WORKAROUND(BOOST_LIBSTDCXX_VERSION, < 50000) && \
|
#if ! BOOST_WORKAROUND(BOOST_LIBSTDCXX_VERSION, < 50000) && \
|
||||||
! BOOST_WORKAROUND(BOOST_MSVC, < 1910)
|
! BOOST_WORKAROUND(BOOST_MSVC, < 1910)
|
||||||
BOOST_STATIC_ASSERT(std::is_trivially_copyable<
|
// BOOST_STATIC_ASSERT(std::is_trivially_copyable<
|
||||||
multi_buffer::const_buffers_type>::value);
|
// multi_buffer::const_buffers_type>::value);
|
||||||
BOOST_STATIC_ASSERT(std::is_trivially_copyable<
|
// BOOST_STATIC_ASSERT(std::is_trivially_copyable<
|
||||||
multi_buffer::mutable_data_type>::value);
|
// multi_buffer::mutable_data_type>::value);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template<class Alloc1, class Alloc2>
|
template<class Alloc1, class Alloc2>
|
||||||
@ -816,13 +816,11 @@ public:
|
|||||||
void
|
void
|
||||||
run() override
|
run() override
|
||||||
{
|
{
|
||||||
#if 1
|
|
||||||
testShrinkToFit();
|
testShrinkToFit();
|
||||||
testDynamicBuffer();
|
testDynamicBuffer();
|
||||||
testMembers();
|
testMembers();
|
||||||
testMatrix1();
|
testMatrix1();
|
||||||
testMatrix2();
|
testMatrix2();
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user