mirror of
https://github.com/boostorg/beast.git
synced 2025-08-02 14:24:31 +02:00
Tidy up multi_buffer:
* Improved tests * Refactor some declaration material * basic_multi_buffer::clear is public and * Fix flat_buffer::reserve * flat_buffer::clear is public
This commit is contained in:
@@ -16,6 +16,7 @@ Version 200
|
|||||||
* Fix ostream prepare calculation for low limits
|
* Fix ostream prepare calculation for low limits
|
||||||
* Tidy up flat_static_buffer tests
|
* Tidy up flat_static_buffer tests
|
||||||
* Add more tests for dynamic buffers
|
* Add more tests for dynamic buffers
|
||||||
|
* Tidy up multi_buffer
|
||||||
|
|
||||||
API Changes:
|
API Changes:
|
||||||
|
|
||||||
|
@@ -83,7 +83,7 @@ class basic_flat_buffer
|
|||||||
|
|
||||||
static
|
static
|
||||||
std::size_t
|
std::size_t
|
||||||
dist(char const* first, char const* last)
|
dist(char const* first, char const* last) noexcept
|
||||||
{
|
{
|
||||||
return static_cast<std::size_t>(last - first);
|
return static_cast<std::size_t>(last - first);
|
||||||
}
|
}
|
||||||
@@ -370,6 +370,23 @@ public:
|
|||||||
void
|
void
|
||||||
shrink_to_fit();
|
shrink_to_fit();
|
||||||
|
|
||||||
|
/** Deallocate the internal buffer and reduce capacity to zero.
|
||||||
|
|
||||||
|
This function deallocates the dynamically allocated
|
||||||
|
internal buffer, and reduces the capacity to zero without
|
||||||
|
affecting the maximum size. The readable and writable
|
||||||
|
bytes will be empty after the object is cleared.
|
||||||
|
|
||||||
|
Buffer sequences previously obtained using @ref data or
|
||||||
|
@ref prepare become invalid.
|
||||||
|
|
||||||
|
@par Exception Safety
|
||||||
|
|
||||||
|
No-throw guarantee.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
clear() noexcept;
|
||||||
|
|
||||||
/// Exchange two dynamic buffers
|
/// Exchange two dynamic buffers
|
||||||
template<class Alloc>
|
template<class Alloc>
|
||||||
friend
|
friend
|
||||||
@@ -506,7 +523,6 @@ private:
|
|||||||
void swap(basic_flat_buffer&, std::true_type);
|
void swap(basic_flat_buffer&, std::true_type);
|
||||||
void swap(basic_flat_buffer&, std::false_type);
|
void swap(basic_flat_buffer&, std::false_type);
|
||||||
char* alloc(std::size_t n);
|
char* alloc(std::size_t n);
|
||||||
void clear();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A flat buffer which uses the default allocator.
|
/// A flat buffer which uses the default allocator.
|
||||||
|
@@ -254,7 +254,7 @@ reserve(std::size_t n)
|
|||||||
{
|
{
|
||||||
if(max_ < n)
|
if(max_ < n)
|
||||||
max_ = n;
|
max_ = n;
|
||||||
if(capacity() < n)
|
if(n > capacity())
|
||||||
prepare(n - size());
|
prepare(n - size());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -287,6 +287,20 @@ shrink_to_fit()
|
|||||||
end_ = out_;
|
end_ = out_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class Allocator>
|
||||||
|
void
|
||||||
|
basic_flat_buffer<Allocator>::
|
||||||
|
clear() noexcept
|
||||||
|
{
|
||||||
|
alloc_traits::deallocate(
|
||||||
|
this->get(), begin_, size());
|
||||||
|
begin_ = nullptr;
|
||||||
|
in_ = nullptr;
|
||||||
|
out_ = nullptr;
|
||||||
|
last_ = nullptr;
|
||||||
|
end_ = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
template<class Allocator>
|
template<class Allocator>
|
||||||
@@ -310,7 +324,11 @@ prepare(std::size_t n) ->
|
|||||||
// after a memmove,
|
// after a memmove,
|
||||||
// existing capacity is sufficient
|
// existing capacity is sufficient
|
||||||
if(len > 0)
|
if(len > 0)
|
||||||
|
{
|
||||||
|
BOOST_ASSERT(begin_);
|
||||||
|
BOOST_ASSERT(in_);
|
||||||
std::memmove(begin_, in_, len);
|
std::memmove(begin_, in_, len);
|
||||||
|
}
|
||||||
in_ = begin_;
|
in_ = begin_;
|
||||||
out_ = in_ + len;
|
out_ = in_ + len;
|
||||||
last_ = out_ + n;
|
last_ = out_ + n;
|
||||||
@@ -375,7 +393,11 @@ copy_from(
|
|||||||
in_ = begin_;
|
in_ = begin_;
|
||||||
out_ = begin_ + n;
|
out_ = begin_ + n;
|
||||||
last_ = begin_ + n;
|
last_ = begin_ + n;
|
||||||
|
if(begin_)
|
||||||
|
{
|
||||||
|
BOOST_ASSERT(other.begin_);
|
||||||
std::memcpy(begin_, other.begin_, n);
|
std::memcpy(begin_, other.begin_, n);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Allocator>
|
template<class Allocator>
|
||||||
@@ -495,20 +517,6 @@ alloc(std::size_t n)
|
|||||||
return alloc_traits::allocate(this->get(), n);
|
return alloc_traits::allocate(this->get(), n);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Allocator>
|
|
||||||
void
|
|
||||||
basic_flat_buffer<Allocator>::
|
|
||||||
clear()
|
|
||||||
{
|
|
||||||
alloc_traits::deallocate(
|
|
||||||
this->get(), begin_, size());
|
|
||||||
begin_ = nullptr;
|
|
||||||
in_ = nullptr;
|
|
||||||
out_ = nullptr;
|
|
||||||
last_ = nullptr;
|
|
||||||
end_ = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // beast
|
} // beast
|
||||||
} // boost
|
} // boost
|
||||||
|
|
||||||
|
@@ -148,7 +148,8 @@ class basic_multi_buffer<Allocator>::readable_bytes
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using value_type = typename std::conditional<
|
using value_type = typename
|
||||||
|
std::conditional<
|
||||||
isMutable,
|
isMutable,
|
||||||
net::mutable_buffer,
|
net::mutable_buffer,
|
||||||
net::const_buffer>::type;
|
net::const_buffer>::type;
|
||||||
@@ -228,9 +229,7 @@ public:
|
|||||||
std::bidirectional_iterator_tag;
|
std::bidirectional_iterator_tag;
|
||||||
|
|
||||||
const_iterator() = default;
|
const_iterator() = default;
|
||||||
const_iterator(const_iterator&& other) = default;
|
|
||||||
const_iterator(const_iterator const& other) = default;
|
const_iterator(const_iterator const& other) = default;
|
||||||
const_iterator& operator=(const_iterator&& other) = default;
|
|
||||||
const_iterator& operator=(const_iterator const& other) = default;
|
const_iterator& operator=(const_iterator const& other) = default;
|
||||||
|
|
||||||
const_iterator(
|
const_iterator(
|
||||||
@@ -314,7 +313,7 @@ class basic_multi_buffer<Allocator>::mutable_buffers_type
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using value_type = mutable_buffer;
|
using value_type = net::mutable_buffer;
|
||||||
|
|
||||||
class const_iterator;
|
class const_iterator;
|
||||||
|
|
||||||
@@ -335,8 +334,8 @@ class basic_multi_buffer<Allocator>::mutable_buffers_type::const_iterator
|
|||||||
typename list_type::const_iterator it_;
|
typename list_type::const_iterator it_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using value_type =
|
using value_type = typename
|
||||||
typename mutable_buffers_type::value_type;
|
mutable_buffers_type::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;
|
||||||
@@ -344,9 +343,7 @@ public:
|
|||||||
std::bidirectional_iterator_tag;
|
std::bidirectional_iterator_tag;
|
||||||
|
|
||||||
const_iterator() = default;
|
const_iterator() = default;
|
||||||
const_iterator(const_iterator&& other) = default;
|
|
||||||
const_iterator(const_iterator const& other) = default;
|
const_iterator(const_iterator const& other) = default;
|
||||||
const_iterator& operator=(const_iterator&& other) = default;
|
|
||||||
const_iterator& operator=(const_iterator const& other) = default;
|
const_iterator& operator=(const_iterator const& other) = default;
|
||||||
|
|
||||||
const_iterator(
|
const_iterator(
|
||||||
@@ -468,6 +465,23 @@ basic_multi_buffer<Allocator>::
|
|||||||
delete_list();
|
delete_list();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class Allocator>
|
||||||
|
basic_multi_buffer<Allocator>::
|
||||||
|
basic_multi_buffer() noexcept(default_nothrow)
|
||||||
|
: max_(alloc_traits::max_size(this->get()))
|
||||||
|
, out_(list_.end())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Allocator>
|
||||||
|
basic_multi_buffer<Allocator>::
|
||||||
|
basic_multi_buffer(
|
||||||
|
std::size_t limit) noexcept(default_nothrow)
|
||||||
|
: max_(limit)
|
||||||
|
, out_(list_.end())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
template<class Allocator>
|
template<class Allocator>
|
||||||
basic_multi_buffer<Allocator>::
|
basic_multi_buffer<Allocator>::
|
||||||
basic_multi_buffer(
|
basic_multi_buffer(
|
||||||
@@ -672,6 +686,8 @@ void
|
|||||||
basic_multi_buffer<Allocator>::
|
basic_multi_buffer<Allocator>::
|
||||||
reserve(std::size_t n)
|
reserve(std::size_t n)
|
||||||
{
|
{
|
||||||
|
// VFALCO The amount needs to be adjusted for
|
||||||
|
// the sizeof(element) plus padding
|
||||||
if(n > alloc_traits::max_size(this->get()))
|
if(n > alloc_traits::max_size(this->get()))
|
||||||
BOOST_THROW_EXCEPTION(std::length_error(
|
BOOST_THROW_EXCEPTION(std::length_error(
|
||||||
"A basic_multi_buffer exceeded the allocator's maximum size"));
|
"A basic_multi_buffer exceeded the allocator's maximum size"));
|
||||||
@@ -683,16 +699,17 @@ reserve(std::size_t n)
|
|||||||
total += out_->size() - out_pos_;
|
total += out_->size() - out_pos_;
|
||||||
if(n <= total)
|
if(n <= total)
|
||||||
return;
|
return;
|
||||||
auto it = out_;
|
for(auto it = out_;;)
|
||||||
while(++it != list_.end())
|
|
||||||
{
|
{
|
||||||
|
if(++it == list_.end())
|
||||||
|
break;
|
||||||
total += it->size();
|
total += it->size();
|
||||||
if(n <= total)
|
if(n <= total)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BOOST_ASSERT(n > total);
|
BOOST_ASSERT(n > total);
|
||||||
(void)prepare(n - total);
|
(void)prepare(n - size());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Allocator>
|
template<class Allocator>
|
||||||
@@ -717,15 +734,29 @@ shrink_to_fit() noexcept
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class Allocator>
|
||||||
|
void
|
||||||
|
basic_multi_buffer<Allocator>::
|
||||||
|
clear() noexcept
|
||||||
|
{
|
||||||
|
delete_list();
|
||||||
|
list_.clear();
|
||||||
|
out_ = list_.end();
|
||||||
|
in_size_ = 0;
|
||||||
|
in_pos_ = 0;
|
||||||
|
out_pos_ = 0;
|
||||||
|
out_end_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
template<class Allocator>
|
template<class Allocator>
|
||||||
auto
|
auto
|
||||||
basic_multi_buffer<Allocator>::
|
basic_multi_buffer<Allocator>::
|
||||||
prepare(size_type n) ->
|
prepare(size_type n) ->
|
||||||
mutable_buffers_type
|
mutable_buffers_type
|
||||||
{
|
{
|
||||||
if(in_size_ + n > max_)
|
if(in_size_ > max_ || n > (max_ - in_size_))
|
||||||
BOOST_THROW_EXCEPTION(std::length_error{
|
BOOST_THROW_EXCEPTION(std::length_error{
|
||||||
"A basic_multi_buffer exceeded its maximum size"});
|
"basic_multi_buffer too long"});
|
||||||
list_type reuse;
|
list_type reuse;
|
||||||
std::size_t total = in_size_;
|
std::size_t total = in_size_;
|
||||||
// put all empty buffers on reuse list
|
// put all empty buffers on reuse list
|
||||||
@@ -943,22 +974,6 @@ copy_from(basic_multi_buffer<OtherAlloc> const& other)
|
|||||||
prepare(other.size()), other.data()));
|
prepare(other.size()), other.data()));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Allocator>
|
|
||||||
void
|
|
||||||
basic_multi_buffer<Allocator>::
|
|
||||||
move_assign(basic_multi_buffer& other, std::false_type)
|
|
||||||
{
|
|
||||||
if(this->get() != other.get())
|
|
||||||
{
|
|
||||||
copy_from(other);
|
|
||||||
other.clear();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
move_assign(other, std::true_type{});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Allocator>
|
template<class Allocator>
|
||||||
void
|
void
|
||||||
basic_multi_buffer<Allocator>::
|
basic_multi_buffer<Allocator>::
|
||||||
@@ -983,6 +998,22 @@ move_assign(basic_multi_buffer& other, std::true_type) noexcept
|
|||||||
other.out_end_ = 0;
|
other.out_end_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class Allocator>
|
||||||
|
void
|
||||||
|
basic_multi_buffer<Allocator>::
|
||||||
|
move_assign(basic_multi_buffer& other, std::false_type)
|
||||||
|
{
|
||||||
|
if(this->get() != other.get())
|
||||||
|
{
|
||||||
|
copy_from(other);
|
||||||
|
other.clear();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
move_assign(other, std::true_type{});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template<class Allocator>
|
template<class Allocator>
|
||||||
void
|
void
|
||||||
basic_multi_buffer<Allocator>::
|
basic_multi_buffer<Allocator>::
|
||||||
@@ -1093,20 +1124,6 @@ alloc(std::size_t n)
|
|||||||
return alloc_traits::allocate(this->get(), n);
|
return alloc_traits::allocate(this->get(), n);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Allocator>
|
|
||||||
void
|
|
||||||
basic_multi_buffer<Allocator>::
|
|
||||||
clear() noexcept
|
|
||||||
{
|
|
||||||
delete_list();
|
|
||||||
list_.clear();
|
|
||||||
out_ = list_.end();
|
|
||||||
in_size_ = 0;
|
|
||||||
in_pos_ = 0;
|
|
||||||
out_pos_ = 0;
|
|
||||||
out_end_ = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Allocator>
|
template<class Allocator>
|
||||||
void
|
void
|
||||||
basic_multi_buffer<Allocator>::
|
basic_multi_buffer<Allocator>::
|
||||||
|
@@ -40,7 +40,7 @@ namespace beast {
|
|||||||
desired size. The behavior and implementation of this
|
desired size. The behavior and implementation of this
|
||||||
container is most similar to `std::deque`.
|
container is most similar to `std::deque`.
|
||||||
|
|
||||||
Objects of this type meet the requirements of @b DynamicBuffer
|
Objects of this type meet the requirements of <em>DynamicBuffer</em>
|
||||||
and have the following additional properties:
|
and have the following additional properties:
|
||||||
|
|
||||||
@li A mutable buffer sequence representing the readable
|
@li A mutable buffer sequence representing the readable
|
||||||
@@ -90,8 +90,6 @@ class basic_multi_buffer
|
|||||||
using const_iter = typename list_type::const_iterator;
|
using const_iter = typename list_type::const_iterator;
|
||||||
|
|
||||||
using size_type = typename alloc_traits::size_type;
|
using size_type = typename alloc_traits::size_type;
|
||||||
using const_buffer = net::const_buffer;
|
|
||||||
using mutable_buffer = net::mutable_buffer;
|
|
||||||
|
|
||||||
using pocma = typename
|
using pocma = typename
|
||||||
alloc_traits::propagate_on_container_move_assignment;
|
alloc_traits::propagate_on_container_move_assignment;
|
||||||
@@ -128,11 +126,7 @@ public:
|
|||||||
@ref max_size will return the largest value which may
|
@ref max_size will return the largest value which may
|
||||||
be passed to the allocator's `allocate` function.
|
be passed to the allocator's `allocate` function.
|
||||||
*/
|
*/
|
||||||
basic_multi_buffer() noexcept(default_nothrow)
|
basic_multi_buffer() noexcept(default_nothrow);
|
||||||
: max_(alloc_traits::max_size(this->get()))
|
|
||||||
, out_(list_.end())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Constructor
|
/** Constructor
|
||||||
|
|
||||||
@@ -143,11 +137,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
explicit
|
explicit
|
||||||
basic_multi_buffer(
|
basic_multi_buffer(
|
||||||
std::size_t limit) noexcept(default_nothrow)
|
std::size_t limit) noexcept(default_nothrow);
|
||||||
: max_(limit)
|
|
||||||
, out_(list_.end())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Constructor
|
/** Constructor
|
||||||
|
|
||||||
@@ -392,6 +382,23 @@ public:
|
|||||||
void
|
void
|
||||||
shrink_to_fit() noexcept;
|
shrink_to_fit() noexcept;
|
||||||
|
|
||||||
|
/** Deallocate all buffers and reduce capacity to zero.
|
||||||
|
|
||||||
|
This function deallocates all dynamically allocated
|
||||||
|
buffers, and reduces the capacity to zero without
|
||||||
|
affecting the maximum size. The readable and writable
|
||||||
|
bytes will be empty after the object is cleared.
|
||||||
|
|
||||||
|
Buffer sequences previously obtained using @ref data or
|
||||||
|
@ref prepare become invalid.
|
||||||
|
|
||||||
|
@par Exception Safety
|
||||||
|
|
||||||
|
No-throw guarantee.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
clear() noexcept;
|
||||||
|
|
||||||
/// Exchange two dynamic buffers
|
/// Exchange two dynamic buffers
|
||||||
template<class Alloc>
|
template<class Alloc>
|
||||||
friend
|
friend
|
||||||
@@ -536,7 +543,6 @@ private:
|
|||||||
void swap(basic_multi_buffer&, std::false_type) noexcept;
|
void swap(basic_multi_buffer&, std::false_type) noexcept;
|
||||||
void delete_list() noexcept;
|
void delete_list() noexcept;
|
||||||
char* alloc(std::size_t n);
|
char* alloc(std::size_t n);
|
||||||
void clear() noexcept;
|
|
||||||
void debug_check() const;
|
void debug_check() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -103,88 +103,16 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
namespace test {
|
|
||||||
|
|
||||||
template<class DynamicBuffer>
|
|
||||||
void
|
|
||||||
write_buffer(DynamicBuffer& b, string_view s)
|
|
||||||
{
|
|
||||||
b.commit(net::buffer_copy(
|
|
||||||
b.prepare(s.size()), net::buffer(
|
|
||||||
s.data(), s.size())));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class ConstBufferSequence>
|
template<class ConstBufferSequence>
|
||||||
typename std::enable_if<
|
std::size_t
|
||||||
net::is_const_buffer_sequence<ConstBufferSequence>::value,
|
buffers_length(
|
||||||
std::size_t>::type
|
ConstBufferSequence const& buffers)
|
||||||
buffer_count(ConstBufferSequence const& buffers)
|
|
||||||
{
|
{
|
||||||
return std::distance(buffers.begin(), buffers.end());
|
return std::distance(
|
||||||
|
net::buffer_sequence_begin(buffers),
|
||||||
|
net::buffer_sequence_end(buffers));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class ConstBufferSequence>
|
|
||||||
typename std::enable_if<
|
|
||||||
net::is_const_buffer_sequence<ConstBufferSequence>::value,
|
|
||||||
std::size_t>::type
|
|
||||||
size_pre(ConstBufferSequence const& buffers)
|
|
||||||
{
|
|
||||||
std::size_t n = 0;
|
|
||||||
for(auto it = buffers.begin(); it != buffers.end(); ++it)
|
|
||||||
{
|
|
||||||
typename ConstBufferSequence::const_iterator it0(std::move(it));
|
|
||||||
typename ConstBufferSequence::const_iterator it1(it0);
|
|
||||||
typename ConstBufferSequence::const_iterator it2;
|
|
||||||
it2 = it1;
|
|
||||||
n += net::buffer_size(*it2);
|
|
||||||
it = std::move(it2);
|
|
||||||
}
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class ConstBufferSequence>
|
|
||||||
typename std::enable_if<
|
|
||||||
net::is_const_buffer_sequence<ConstBufferSequence>::value,
|
|
||||||
std::size_t>::type
|
|
||||||
size_post(ConstBufferSequence const& buffers)
|
|
||||||
{
|
|
||||||
std::size_t n = 0;
|
|
||||||
for(auto it = buffers.begin(); it != buffers.end(); it++)
|
|
||||||
n += net::buffer_size(*it);
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class ConstBufferSequence>
|
|
||||||
typename std::enable_if<
|
|
||||||
net::is_const_buffer_sequence<ConstBufferSequence>::value,
|
|
||||||
std::size_t>::type
|
|
||||||
size_rev_pre(ConstBufferSequence const& buffers)
|
|
||||||
{
|
|
||||||
std::size_t n = 0;
|
|
||||||
for(auto it = buffers.end(); it != buffers.begin();)
|
|
||||||
n += net::buffer_size(*--it);
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class ConstBufferSequence>
|
|
||||||
typename std::enable_if<
|
|
||||||
net::is_const_buffer_sequence<ConstBufferSequence>::value,
|
|
||||||
std::size_t>::type
|
|
||||||
size_rev_post(ConstBufferSequence const& buffers)
|
|
||||||
{
|
|
||||||
std::size_t n = 0;
|
|
||||||
for(auto it = buffers.end(); it != buffers.begin();)
|
|
||||||
{
|
|
||||||
it--;
|
|
||||||
n += net::buffer_size(*it);
|
|
||||||
}
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // test
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
@@ -28,17 +28,6 @@ namespace beast {
|
|||||||
class buffers_cat_test : public unit_test::suite
|
class buffers_cat_test : public unit_test::suite
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
template<class ConstBufferSequence>
|
|
||||||
static
|
|
||||||
std::size_t
|
|
||||||
buffers_length(
|
|
||||||
ConstBufferSequence const& buffers)
|
|
||||||
{
|
|
||||||
return std::distance(
|
|
||||||
net::buffer_sequence_begin(buffers),
|
|
||||||
net::buffer_sequence_end(buffers));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
testDefaultIterators()
|
testDefaultIterators()
|
||||||
{
|
{
|
||||||
|
@@ -69,7 +69,6 @@ public:
|
|||||||
|
|
||||||
// in-place init
|
// in-place init
|
||||||
{
|
{
|
||||||
using namespace test;
|
|
||||||
buffers_suffix<buffers_cat_view<
|
buffers_suffix<buffers_cat_view<
|
||||||
net::const_buffer,
|
net::const_buffer,
|
||||||
net::const_buffer>> cb(
|
net::const_buffer>> cb(
|
||||||
@@ -106,8 +105,9 @@ public:
|
|||||||
bool
|
bool
|
||||||
eq(Buffers1 const& lhs, Buffers2 const& rhs)
|
eq(Buffers1 const& lhs, Buffers2 const& rhs)
|
||||||
{
|
{
|
||||||
using namespace test;
|
return
|
||||||
return buffers_to_string(lhs) == buffers_to_string(rhs);
|
buffers_to_string(lhs) ==
|
||||||
|
buffers_to_string(rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@@ -32,20 +32,8 @@ class multi_buffer_test : public beast::unit_test::suite
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
BOOST_STATIC_ASSERT(
|
BOOST_STATIC_ASSERT(
|
||||||
net::is_dynamic_buffer<
|
is_mutable_dynamic_buffer<multi_buffer>::value);
|
||||||
multi_buffer>::value);
|
|
||||||
BOOST_STATIC_ASSERT(
|
|
||||||
net::is_const_buffer_sequence<
|
|
||||||
multi_buffer::const_buffers_type>::value);
|
|
||||||
BOOST_STATIC_ASSERT(
|
|
||||||
net::is_mutable_buffer_sequence<
|
|
||||||
multi_buffer::mutable_data_type>::value);
|
|
||||||
BOOST_STATIC_ASSERT(
|
|
||||||
net::is_mutable_buffer_sequence<
|
|
||||||
multi_buffer::mutable_buffers_type>::value);
|
|
||||||
BOOST_STATIC_ASSERT(std::is_convertible<
|
|
||||||
multi_buffer::mutable_data_type,
|
|
||||||
multi_buffer::const_buffers_type>::value);
|
|
||||||
#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<
|
||||||
@@ -57,214 +45,19 @@ public:
|
|||||||
template<class Alloc1, class Alloc2>
|
template<class Alloc1, class Alloc2>
|
||||||
static
|
static
|
||||||
bool
|
bool
|
||||||
eq(basic_multi_buffer<Alloc1> const& mb1,
|
eq( basic_multi_buffer<Alloc1> const& mb1,
|
||||||
basic_multi_buffer<Alloc2> const& mb2)
|
basic_multi_buffer<Alloc2> const& mb2)
|
||||||
{
|
{
|
||||||
return buffers_to_string(mb1.data()) ==
|
return buffers_to_string(mb1.data()) ==
|
||||||
buffers_to_string(mb2.data());
|
buffers_to_string(mb2.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class ConstBufferSequence>
|
|
||||||
void
|
void
|
||||||
expect_size(std::size_t n, ConstBufferSequence const& buffers)
|
testDynamicBuffer()
|
||||||
{
|
{
|
||||||
BEAST_EXPECT(test::size_pre(buffers) == n);
|
multi_buffer b(30);
|
||||||
BEAST_EXPECT(test::size_post(buffers) == n);
|
BEAST_EXPECT(b.max_size() == 30);
|
||||||
BEAST_EXPECT(test::size_rev_pre(buffers) == n);
|
test_dynamic_buffer(*this, b);
|
||||||
BEAST_EXPECT(test::size_rev_post(buffers) == n);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class U, class V>
|
|
||||||
static
|
|
||||||
void
|
|
||||||
self_assign(U& u, V&& v)
|
|
||||||
{
|
|
||||||
u = std::forward<V>(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class DynamicBuffer>
|
|
||||||
void
|
|
||||||
testMutableData()
|
|
||||||
{
|
|
||||||
DynamicBuffer b;
|
|
||||||
DynamicBuffer const& cb = b;
|
|
||||||
ostream(b) << "Hello";
|
|
||||||
BOOST_STATIC_ASSERT(
|
|
||||||
net::is_const_buffer_sequence<
|
|
||||||
decltype(cb.data())>::value &&
|
|
||||||
! net::is_mutable_buffer_sequence<
|
|
||||||
decltype(cb.data())>::value);
|
|
||||||
BOOST_STATIC_ASSERT(
|
|
||||||
net::is_const_buffer_sequence<
|
|
||||||
decltype(cb.cdata())>::value &&
|
|
||||||
! net::is_mutable_buffer_sequence<
|
|
||||||
decltype(cb.cdata())>::value);
|
|
||||||
BOOST_STATIC_ASSERT(
|
|
||||||
net::is_mutable_buffer_sequence<
|
|
||||||
decltype(b.data())>::value);
|
|
||||||
|
|
||||||
std::for_each(
|
|
||||||
net::buffers_iterator<decltype(b.data())>::begin(b.data()),
|
|
||||||
net::buffers_iterator<decltype(b.data())>::end(b.data()),
|
|
||||||
[](char& c)
|
|
||||||
{
|
|
||||||
c = static_cast<char>(std::toupper(c));
|
|
||||||
});
|
|
||||||
BEAST_EXPECT(buffers_to_string(b.data()) == "HELLO");
|
|
||||||
BEAST_EXPECT(buffers_to_string(b.cdata()) == "HELLO");
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
testMatrix1()
|
|
||||||
{
|
|
||||||
using namespace test;
|
|
||||||
using net::buffer;
|
|
||||||
std::string const s = "Hello, world";
|
|
||||||
BEAST_EXPECT(s.size() == 12);
|
|
||||||
for(std::size_t i = 1; i < 12; ++i) {
|
|
||||||
for(std::size_t x = 1; x < 4; ++x) {
|
|
||||||
for(std::size_t y = 1; y < 4; ++y) {
|
|
||||||
std::size_t z = s.size() - (x + y);
|
|
||||||
{
|
|
||||||
multi_buffer b;
|
|
||||||
b.commit(buffer_copy(b.prepare(x), buffer(s.data(), x)));
|
|
||||||
b.commit(buffer_copy(b.prepare(y), buffer(s.data()+x, y)));
|
|
||||||
b.commit(buffer_copy(b.prepare(z), buffer(s.data()+x+y, z)));
|
|
||||||
BEAST_EXPECT(buffers_to_string(b.data()) == s);
|
|
||||||
{
|
|
||||||
multi_buffer mb2{b};
|
|
||||||
BEAST_EXPECT(eq(b, mb2));
|
|
||||||
}
|
|
||||||
{
|
|
||||||
multi_buffer mb2;
|
|
||||||
mb2 = b;
|
|
||||||
BEAST_EXPECT(eq(b, mb2));
|
|
||||||
}
|
|
||||||
{
|
|
||||||
multi_buffer mb2{std::move(b)};
|
|
||||||
BEAST_EXPECT(buffers_to_string(mb2.data()) == s);
|
|
||||||
expect_size(0, b.data());
|
|
||||||
b = std::move(mb2);
|
|
||||||
BEAST_EXPECT(buffers_to_string(b.data()) == s);
|
|
||||||
expect_size(0, mb2.data());
|
|
||||||
}
|
|
||||||
self_assign(b, b);
|
|
||||||
BEAST_EXPECT(buffers_to_string(b.data()) == s);
|
|
||||||
self_assign(b, std::move(b));
|
|
||||||
BEAST_EXPECT(buffers_to_string(b.data()) == s);
|
|
||||||
}
|
|
||||||
}}}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
testMatrix2()
|
|
||||||
{
|
|
||||||
using namespace test;
|
|
||||||
using net::buffer;
|
|
||||||
using net::buffer_size;
|
|
||||||
std::string const s = "Hello, world";
|
|
||||||
BEAST_EXPECT(s.size() == 12);
|
|
||||||
for(std::size_t i = 1; i < 12; ++i) {
|
|
||||||
for(std::size_t x = 1; x < 4; ++x) {
|
|
||||||
for(std::size_t y = 1; y < 4; ++y) {
|
|
||||||
for(std::size_t t = 1; t < 4; ++ t) {
|
|
||||||
for(std::size_t u = 1; u < 4; ++ u) {
|
|
||||||
std::size_t z = s.size() - (x + y);
|
|
||||||
std::size_t v = s.size() - (t + u);
|
|
||||||
{
|
|
||||||
multi_buffer b;
|
|
||||||
{
|
|
||||||
auto d = b.prepare(z);
|
|
||||||
BEAST_EXPECT(buffer_size(d) == z);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
auto d = b.prepare(0);
|
|
||||||
BEAST_EXPECT(buffer_size(d) == 0);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
auto d = b.prepare(y);
|
|
||||||
BEAST_EXPECT(buffer_size(d) == y);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
auto d = b.prepare(x);
|
|
||||||
BEAST_EXPECT(buffer_size(d) == x);
|
|
||||||
b.commit(buffer_copy(d, buffer(s.data(), x)));
|
|
||||||
}
|
|
||||||
BEAST_EXPECT(b.size() == x);
|
|
||||||
BEAST_EXPECT(buffer_size(b.data()) == b.size());
|
|
||||||
{
|
|
||||||
auto d = b.prepare(x);
|
|
||||||
BEAST_EXPECT(buffer_size(d) == x);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
auto d = b.prepare(0);
|
|
||||||
BEAST_EXPECT(buffer_size(d) == 0);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
auto d = b.prepare(z);
|
|
||||||
BEAST_EXPECT(buffer_size(d) == z);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
auto d = b.prepare(y);
|
|
||||||
BEAST_EXPECT(buffer_size(d) == y);
|
|
||||||
b.commit(buffer_copy(d, buffer(s.data()+x, y)));
|
|
||||||
}
|
|
||||||
b.commit(1);
|
|
||||||
BEAST_EXPECT(b.size() == x + y);
|
|
||||||
BEAST_EXPECT(buffer_size(b.data()) == b.size());
|
|
||||||
{
|
|
||||||
auto d = b.prepare(x);
|
|
||||||
BEAST_EXPECT(buffer_size(d) == x);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
auto d = b.prepare(y);
|
|
||||||
BEAST_EXPECT(buffer_size(d) == y);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
auto d = b.prepare(0);
|
|
||||||
BEAST_EXPECT(buffer_size(d) == 0);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
auto d = b.prepare(z);
|
|
||||||
BEAST_EXPECT(buffer_size(d) == z);
|
|
||||||
b.commit(buffer_copy(d, buffer(s.data()+x+y, z)));
|
|
||||||
}
|
|
||||||
b.commit(2);
|
|
||||||
BEAST_EXPECT(b.size() == x + y + z);
|
|
||||||
BEAST_EXPECT(buffer_size(b.data()) == b.size());
|
|
||||||
BEAST_EXPECT(buffers_to_string(b.data()) == s);
|
|
||||||
b.consume(t);
|
|
||||||
{
|
|
||||||
auto d = b.prepare(0);
|
|
||||||
BEAST_EXPECT(buffer_size(d) == 0);
|
|
||||||
}
|
|
||||||
BEAST_EXPECT(buffers_to_string(b.data()) == s.substr(t, std::string::npos));
|
|
||||||
b.consume(u);
|
|
||||||
BEAST_EXPECT(buffers_to_string(b.data()) == s.substr(t + u, std::string::npos));
|
|
||||||
b.consume(v);
|
|
||||||
BEAST_EXPECT(buffers_to_string(b.data()) == "");
|
|
||||||
b.consume(1);
|
|
||||||
{
|
|
||||||
auto d = b.prepare(0);
|
|
||||||
BEAST_EXPECT(buffer_size(d) == 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}}}}}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
testIterators()
|
|
||||||
{
|
|
||||||
using net::buffer_size;
|
|
||||||
multi_buffer b;
|
|
||||||
b.prepare(1);
|
|
||||||
b.commit(1);
|
|
||||||
b.prepare(2);
|
|
||||||
b.commit(2);
|
|
||||||
expect_size(3, b.data());
|
|
||||||
b.prepare(1);
|
|
||||||
expect_size(3, b.prepare(3));
|
|
||||||
b.commit(2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -297,6 +90,14 @@ public:
|
|||||||
BEAST_EXPECT(b.get_allocator() == a1);
|
BEAST_EXPECT(b.get_allocator() == a1);
|
||||||
BEAST_EXPECT(b.get_allocator() != unequal_t{});
|
BEAST_EXPECT(b.get_allocator() != unequal_t{});
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
unequal_t a1;
|
||||||
|
basic_multi_buffer<unequal_t> b{500, a1};
|
||||||
|
BEAST_EXPECT(b.capacity() == 0);
|
||||||
|
BEAST_EXPECT(b.max_size() == 500);
|
||||||
|
BEAST_EXPECT(b.get_allocator() == a1);
|
||||||
|
BEAST_EXPECT(b.get_allocator() != unequal_t{});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// move construction
|
// move construction
|
||||||
@@ -384,6 +185,18 @@ public:
|
|||||||
BEAST_EXPECT(b1.capacity() == 0);
|
BEAST_EXPECT(b1.capacity() == 0);
|
||||||
BEAST_EXPECT(buffers_to_string(b2.data()) == "Hello");
|
BEAST_EXPECT(buffers_to_string(b2.data()) == "Hello");
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
using na_t = test::test_allocator<char,
|
||||||
|
false, true, false, true, true>;
|
||||||
|
basic_multi_buffer<na_t> b1;
|
||||||
|
ostream(b1) << "Hello";
|
||||||
|
basic_multi_buffer<na_t> b2;
|
||||||
|
b2 = std::move(b1);
|
||||||
|
BEAST_EXPECT(b1.get_allocator() != b2.get_allocator());
|
||||||
|
BEAST_EXPECT(b1.size() == 0);
|
||||||
|
BEAST_EXPECT(b1.capacity() == 0);
|
||||||
|
BEAST_EXPECT(buffers_to_string(b2.data()) == "Hello");
|
||||||
|
}
|
||||||
{
|
{
|
||||||
// propagate_on_container_move_assignment : true
|
// propagate_on_container_move_assignment : true
|
||||||
using pocma_t = test::test_allocator<char,
|
using pocma_t = test::test_allocator<char,
|
||||||
@@ -451,6 +264,34 @@ public:
|
|||||||
BEAST_EXPECT(b.max_size() == 32);
|
BEAST_EXPECT(b.max_size() == 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// allocator max_size
|
||||||
|
{
|
||||||
|
basic_multi_buffer<equal_t> b;
|
||||||
|
auto a = b.get_allocator();
|
||||||
|
BOOST_STATIC_ASSERT(
|
||||||
|
! std::is_const<decltype(a)>::value);
|
||||||
|
a->max_size = 30;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
b.prepare(1000);
|
||||||
|
fail("", __FILE__, __LINE__);
|
||||||
|
}
|
||||||
|
catch(std::length_error const&)
|
||||||
|
{
|
||||||
|
pass();
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
b.reserve(1000);
|
||||||
|
fail("", __FILE__, __LINE__);
|
||||||
|
}
|
||||||
|
catch(std::length_error const&)
|
||||||
|
{
|
||||||
|
pass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// prepare
|
// prepare
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
@@ -527,6 +368,23 @@ public:
|
|||||||
|
|
||||||
// commit
|
// commit
|
||||||
{
|
{
|
||||||
|
{
|
||||||
|
multi_buffer b;
|
||||||
|
b.prepare(16);
|
||||||
|
b.commit(16);
|
||||||
|
auto const n =
|
||||||
|
b.capacity() - b.size();
|
||||||
|
b.prepare(n);
|
||||||
|
b.commit(n);
|
||||||
|
auto const size =
|
||||||
|
b.size();
|
||||||
|
auto const capacity =
|
||||||
|
b.capacity();
|
||||||
|
b.commit(1);
|
||||||
|
BEAST_EXPECT(b.size() == size);
|
||||||
|
BEAST_EXPECT(b.capacity() == capacity);
|
||||||
|
}
|
||||||
|
|
||||||
multi_buffer b;
|
multi_buffer b;
|
||||||
b.prepare(1000);
|
b.prepare(1000);
|
||||||
BEAST_EXPECT(b.capacity() >= 1000);
|
BEAST_EXPECT(b.capacity() >= 1000);
|
||||||
@@ -589,6 +447,21 @@ public:
|
|||||||
b.commit(20);
|
b.commit(20);
|
||||||
b.reserve(50);
|
b.reserve(50);
|
||||||
BEAST_EXPECT(b.capacity() >= 50);
|
BEAST_EXPECT(b.capacity() >= 50);
|
||||||
|
BEAST_EXPECT(b.size() > 1);
|
||||||
|
auto capacity = b.capacity();
|
||||||
|
b.reserve(b.size() - 1);
|
||||||
|
BEAST_EXPECT(b.capacity() == capacity);
|
||||||
|
b.reserve(b.capacity() + 1);
|
||||||
|
BEAST_EXPECT(b.capacity() > capacity);
|
||||||
|
capacity = b.capacity();
|
||||||
|
BEAST_EXPECT(buffers_length(
|
||||||
|
b.prepare(b.capacity() + 200)) > 1);
|
||||||
|
BEAST_EXPECT(b.capacity() > capacity);
|
||||||
|
b.reserve(b.capacity() + 2);
|
||||||
|
BEAST_EXPECT(b.capacity() > capacity);
|
||||||
|
capacity = b.capacity();
|
||||||
|
b.reserve(b.capacity());
|
||||||
|
BEAST_EXPECT(b.capacity() == capacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
// shrink to fit
|
// shrink to fit
|
||||||
@@ -619,6 +492,23 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// clear
|
||||||
|
{
|
||||||
|
multi_buffer b;
|
||||||
|
b.prepare(50);
|
||||||
|
BEAST_EXPECT(b.capacity() >= 50);
|
||||||
|
b.clear();
|
||||||
|
BEAST_EXPECT(b.size() == 0);
|
||||||
|
BEAST_EXPECT(b.capacity() == 0);
|
||||||
|
b.prepare(80);
|
||||||
|
b.commit(30);
|
||||||
|
BEAST_EXPECT(b.size() == 30);
|
||||||
|
BEAST_EXPECT(b.capacity() >= 80);
|
||||||
|
b.clear();
|
||||||
|
BEAST_EXPECT(b.size() == 0);
|
||||||
|
BEAST_EXPECT(b.capacity() == 0);
|
||||||
|
}
|
||||||
|
|
||||||
// swap
|
// swap
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
@@ -683,14 +573,158 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
testMatrix1()
|
||||||
|
{
|
||||||
|
using net::buffer_size;
|
||||||
|
|
||||||
|
string_view s = "Hello, world";
|
||||||
|
BEAST_EXPECT(s.size() == 12);
|
||||||
|
for(std::size_t i = 1; i < 12; ++i) {
|
||||||
|
for(std::size_t x = 1; x < 4; ++x) {
|
||||||
|
for(std::size_t y = 1; y < 4; ++y) {
|
||||||
|
std::size_t z = s.size() - (x + y);
|
||||||
|
{
|
||||||
|
multi_buffer b;
|
||||||
|
b.commit(net::buffer_copy(
|
||||||
|
b.prepare(x), net::buffer(s.data(), x)));
|
||||||
|
b.commit(net::buffer_copy(
|
||||||
|
b.prepare(y), net::buffer(s.data()+x, y)));
|
||||||
|
b.commit(net::buffer_copy(
|
||||||
|
b.prepare(z), net::buffer(s.data()+x+y, z)));
|
||||||
|
BEAST_EXPECT(buffers_to_string(b.data()) == s);
|
||||||
|
{
|
||||||
|
multi_buffer mb2{b};
|
||||||
|
BEAST_EXPECT(eq(b, mb2));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
multi_buffer mb2;
|
||||||
|
mb2 = b;
|
||||||
|
BEAST_EXPECT(eq(b, mb2));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
multi_buffer mb2{std::move(b)};
|
||||||
|
BEAST_EXPECT(buffers_to_string(mb2.data()) == s);
|
||||||
|
BEAST_EXPECT(b.size() == 0);
|
||||||
|
BEAST_EXPECT(buffer_size(b.data()) == 0);
|
||||||
|
b = std::move(mb2);
|
||||||
|
BEAST_EXPECT(buffers_to_string(b.data()) == s);
|
||||||
|
BEAST_EXPECT(mb2.size() == 0);
|
||||||
|
BEAST_EXPECT(buffer_size(mb2.data()) == 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}}}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
testMatrix2()
|
||||||
|
{
|
||||||
|
using namespace test;
|
||||||
|
using net::buffer;
|
||||||
|
using net::buffer_size;
|
||||||
|
std::string const s = "Hello, world";
|
||||||
|
BEAST_EXPECT(s.size() == 12);
|
||||||
|
for(std::size_t i = 1; i < 12; ++i) {
|
||||||
|
for(std::size_t x = 1; x < 4; ++x) {
|
||||||
|
for(std::size_t y = 1; y < 4; ++y) {
|
||||||
|
for(std::size_t t = 1; t < 4; ++ t) {
|
||||||
|
for(std::size_t u = 1; u < 4; ++ u) {
|
||||||
|
std::size_t z = s.size() - (x + y);
|
||||||
|
std::size_t v = s.size() - (t + u);
|
||||||
|
{
|
||||||
|
multi_buffer b;
|
||||||
|
{
|
||||||
|
auto d = b.prepare(z);
|
||||||
|
BEAST_EXPECT(buffer_size(d) == z);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto d = b.prepare(0);
|
||||||
|
BEAST_EXPECT(buffer_size(d) == 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto d = b.prepare(y);
|
||||||
|
BEAST_EXPECT(buffer_size(d) == y);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto d = b.prepare(x);
|
||||||
|
BEAST_EXPECT(buffer_size(d) == x);
|
||||||
|
b.commit(buffer_copy(d, buffer(s.data(), x)));
|
||||||
|
}
|
||||||
|
BEAST_EXPECT(b.size() == x);
|
||||||
|
BEAST_EXPECT(buffer_size(b.data()) == b.size());
|
||||||
|
{
|
||||||
|
auto d = b.prepare(x);
|
||||||
|
BEAST_EXPECT(buffer_size(d) == x);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto d = b.prepare(0);
|
||||||
|
BEAST_EXPECT(buffer_size(d) == 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto d = b.prepare(z);
|
||||||
|
BEAST_EXPECT(buffer_size(d) == z);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto d = b.prepare(y);
|
||||||
|
BEAST_EXPECT(buffer_size(d) == y);
|
||||||
|
b.commit(buffer_copy(d, buffer(s.data()+x, y)));
|
||||||
|
}
|
||||||
|
b.commit(1);
|
||||||
|
BEAST_EXPECT(b.size() == x + y);
|
||||||
|
BEAST_EXPECT(buffer_size(b.data()) == b.size());
|
||||||
|
{
|
||||||
|
auto d = b.prepare(x);
|
||||||
|
BEAST_EXPECT(buffer_size(d) == x);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto d = b.prepare(y);
|
||||||
|
BEAST_EXPECT(buffer_size(d) == y);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto d = b.prepare(0);
|
||||||
|
BEAST_EXPECT(buffer_size(d) == 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto d = b.prepare(z);
|
||||||
|
BEAST_EXPECT(buffer_size(d) == z);
|
||||||
|
b.commit(buffer_copy(d, buffer(s.data()+x+y, z)));
|
||||||
|
}
|
||||||
|
b.commit(2);
|
||||||
|
BEAST_EXPECT(b.size() == x + y + z);
|
||||||
|
BEAST_EXPECT(buffer_size(b.data()) == b.size());
|
||||||
|
BEAST_EXPECT(buffers_to_string(b.data()) == s);
|
||||||
|
b.consume(t);
|
||||||
|
{
|
||||||
|
auto d = b.prepare(0);
|
||||||
|
BEAST_EXPECT(buffer_size(d) == 0);
|
||||||
|
}
|
||||||
|
BEAST_EXPECT(buffers_to_string(b.data()) ==
|
||||||
|
s.substr(t, std::string::npos));
|
||||||
|
b.consume(u);
|
||||||
|
BEAST_EXPECT(buffers_to_string(b.data()) ==
|
||||||
|
s.substr(t + u, std::string::npos));
|
||||||
|
b.consume(v);
|
||||||
|
BEAST_EXPECT(buffers_to_string(b.data()).empty());
|
||||||
|
b.consume(1);
|
||||||
|
{
|
||||||
|
auto d = b.prepare(0);
|
||||||
|
BEAST_EXPECT(buffer_size(d) == 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}}}}}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
run() override
|
run() override
|
||||||
{
|
{
|
||||||
|
testDynamicBuffer();
|
||||||
|
testMembers();
|
||||||
testMatrix1();
|
testMatrix1();
|
||||||
testMatrix2();
|
testMatrix2();
|
||||||
|
#if 0
|
||||||
testIterators();
|
testIterators();
|
||||||
testMembers();
|
|
||||||
testMutableData<multi_buffer>();
|
testMutableData<multi_buffer>();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -87,7 +87,6 @@ public:
|
|||||||
void
|
void
|
||||||
testStaticBuffer()
|
testStaticBuffer()
|
||||||
{
|
{
|
||||||
using namespace test;
|
|
||||||
using net::buffer;
|
using net::buffer;
|
||||||
using net::buffer_size;
|
using net::buffer_size;
|
||||||
char buf[12];
|
char buf[12];
|
||||||
@@ -195,7 +194,6 @@ public:
|
|||||||
void
|
void
|
||||||
testBuffer()
|
testBuffer()
|
||||||
{
|
{
|
||||||
using namespace test;
|
|
||||||
string_view const s = "Hello, world!";
|
string_view const s = "Hello, world!";
|
||||||
|
|
||||||
// static_buffer_base
|
// static_buffer_base
|
||||||
@@ -234,9 +232,9 @@ public:
|
|||||||
// cause memmove
|
// cause memmove
|
||||||
{
|
{
|
||||||
static_buffer<10> b;
|
static_buffer<10> b;
|
||||||
write_buffer(b, "12345");
|
ostream(b) << "12345";
|
||||||
b.consume(3);
|
b.consume(3);
|
||||||
write_buffer(b, "67890123");
|
ostream(b) << "67890123";
|
||||||
BEAST_EXPECT(buffers_to_string(b.data()) == "4567890123");
|
BEAST_EXPECT(buffers_to_string(b.data()) == "4567890123");
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user