forked from boostorg/beast
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:
1 parent
74293fb8a5
commit
594a92e515
10 files changed
+386
-389
No files matched your search
@@ -83,7 +83,7 @@ class basic_flat_buffer
|
||||
|
||||
static
|
||||
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);
|
||||
}
|
||||
@@ -370,6 +370,23 @@ public:
|
||||
void
|
||||
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
|
||||
template<class Alloc>
|
||||
friend
|
||||
@@ -506,7 +523,6 @@ private:
|
||||
void swap(basic_flat_buffer&, std::true_type);
|
||||
void swap(basic_flat_buffer&, std::false_type);
|
||||
char* alloc(std::size_t n);
|
||||
void clear();
|
||||
};
|
||||
|
||||
/// A flat buffer which uses the default allocator.
|
||||
|
||||
@@ -254,7 +254,7 @@ reserve(std::size_t n)
|
||||
{
|
||||
if(max_ < n)
|
||||
max_ = n;
|
||||
if(capacity() < n)
|
||||
if(n > capacity())
|
||||
prepare(n - size());
|
||||
}
|
||||
|
||||
@@ -287,6 +287,20 @@ shrink_to_fit()
|
||||
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>
|
||||
@@ -310,7 +324,11 @@ prepare(std::size_t n) ->
|
||||
// after a memmove,
|
||||
// existing capacity is sufficient
|
||||
if(len > 0)
|
||||
{
|
||||
BOOST_ASSERT(begin_);
|
||||
BOOST_ASSERT(in_);
|
||||
std::memmove(begin_, in_, len);
|
||||
}
|
||||
in_ = begin_;
|
||||
out_ = in_ + len;
|
||||
last_ = out_ + n;
|
||||
@@ -375,7 +393,11 @@ copy_from(
|
||||
in_ = begin_;
|
||||
out_ = begin_ + n;
|
||||
last_ = begin_ + n;
|
||||
std::memcpy(begin_, other.begin_, n);
|
||||
if(begin_)
|
||||
{
|
||||
BOOST_ASSERT(other.begin_);
|
||||
std::memcpy(begin_, other.begin_, n);
|
||||
}
|
||||
}
|
||||
|
||||
template<class Allocator>
|
||||
@@ -495,20 +517,6 @@ alloc(std::size_t 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
|
||||
} // boost
|
||||
|
||||
|
||||
@@ -148,10 +148,11 @@ class basic_multi_buffer<Allocator>::readable_bytes
|
||||
}
|
||||
|
||||
public:
|
||||
using value_type = typename std::conditional<
|
||||
isMutable,
|
||||
net::mutable_buffer,
|
||||
net::const_buffer>::type;
|
||||
using value_type = typename
|
||||
std::conditional<
|
||||
isMutable,
|
||||
net::mutable_buffer,
|
||||
net::const_buffer>::type;
|
||||
|
||||
class const_iterator;
|
||||
|
||||
@@ -228,9 +229,7 @@ public:
|
||||
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;
|
||||
|
||||
const_iterator(
|
||||
@@ -314,7 +313,7 @@ class basic_multi_buffer<Allocator>::mutable_buffers_type
|
||||
}
|
||||
|
||||
public:
|
||||
using value_type = mutable_buffer;
|
||||
using value_type = net::mutable_buffer;
|
||||
|
||||
class const_iterator;
|
||||
|
||||
@@ -335,8 +334,8 @@ class basic_multi_buffer<Allocator>::mutable_buffers_type::const_iterator
|
||||
typename list_type::const_iterator it_;
|
||||
|
||||
public:
|
||||
using value_type =
|
||||
typename mutable_buffers_type::value_type;
|
||||
using value_type = typename
|
||||
mutable_buffers_type::value_type;
|
||||
using pointer = value_type const*;
|
||||
using reference = value_type;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
@@ -344,9 +343,7 @@ public:
|
||||
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;
|
||||
|
||||
const_iterator(
|
||||
@@ -468,6 +465,23 @@ basic_multi_buffer<Allocator>::
|
||||
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>
|
||||
basic_multi_buffer<Allocator>::
|
||||
basic_multi_buffer(
|
||||
@@ -672,6 +686,8 @@ void
|
||||
basic_multi_buffer<Allocator>::
|
||||
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()))
|
||||
BOOST_THROW_EXCEPTION(std::length_error(
|
||||
"A basic_multi_buffer exceeded the allocator's maximum size"));
|
||||
@@ -683,16 +699,17 @@ reserve(std::size_t n)
|
||||
total += out_->size() - out_pos_;
|
||||
if(n <= total)
|
||||
return;
|
||||
auto it = out_;
|
||||
while(++it != list_.end())
|
||||
for(auto it = out_;;)
|
||||
{
|
||||
if(++it == list_.end())
|
||||
break;
|
||||
total += it->size();
|
||||
if(n <= total)
|
||||
return;
|
||||
}
|
||||
}
|
||||
BOOST_ASSERT(n > total);
|
||||
(void)prepare(n - total);
|
||||
(void)prepare(n - size());
|
||||
}
|
||||
|
||||
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>
|
||||
auto
|
||||
basic_multi_buffer<Allocator>::
|
||||
prepare(size_type n) ->
|
||||
mutable_buffers_type
|
||||
{
|
||||
if(in_size_ + n > max_)
|
||||
if(in_size_ > max_ || n > (max_ - in_size_))
|
||||
BOOST_THROW_EXCEPTION(std::length_error{
|
||||
"A basic_multi_buffer exceeded its maximum size"});
|
||||
"basic_multi_buffer too long"});
|
||||
list_type reuse;
|
||||
std::size_t total = in_size_;
|
||||
// put all empty buffers on reuse list
|
||||
@@ -943,22 +974,6 @@ copy_from(basic_multi_buffer<OtherAlloc> const& other)
|
||||
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>
|
||||
void
|
||||
basic_multi_buffer<Allocator>::
|
||||
@@ -983,6 +998,22 @@ move_assign(basic_multi_buffer& other, std::true_type) noexcept
|
||||
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>
|
||||
void
|
||||
basic_multi_buffer<Allocator>::
|
||||
@@ -1093,20 +1124,6 @@ alloc(std::size_t 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>
|
||||
void
|
||||
basic_multi_buffer<Allocator>::
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace beast {
|
||||
desired size. The behavior and implementation of this
|
||||
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:
|
||||
|
||||
@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 size_type = typename alloc_traits::size_type;
|
||||
using const_buffer = net::const_buffer;
|
||||
using mutable_buffer = net::mutable_buffer;
|
||||
|
||||
using pocma = typename
|
||||
alloc_traits::propagate_on_container_move_assignment;
|
||||
@@ -128,11 +126,7 @@ public:
|
||||
@ref max_size will return the largest value which may
|
||||
be passed to the allocator's `allocate` function.
|
||||
*/
|
||||
basic_multi_buffer() noexcept(default_nothrow)
|
||||
: max_(alloc_traits::max_size(this->get()))
|
||||
, out_(list_.end())
|
||||
{
|
||||
}
|
||||
basic_multi_buffer() noexcept(default_nothrow);
|
||||
|
||||
/** Constructor
|
||||
|
||||
@@ -143,11 +137,7 @@ public:
|
||||
*/
|
||||
explicit
|
||||
basic_multi_buffer(
|
||||
std::size_t limit) noexcept(default_nothrow)
|
||||
: max_(limit)
|
||||
, out_(list_.end())
|
||||
{
|
||||
}
|
||||
std::size_t limit) noexcept(default_nothrow);
|
||||
|
||||
/** Constructor
|
||||
|
||||
@@ -392,6 +382,23 @@ public:
|
||||
void
|
||||
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
|
||||
template<class Alloc>
|
||||
friend
|
||||
@@ -536,7 +543,6 @@ private:
|
||||
void swap(basic_multi_buffer&, std::false_type) noexcept;
|
||||
void delete_list() noexcept;
|
||||
char* alloc(std::size_t n);
|
||||
void clear() noexcept;
|
||||
void debug_check() const;
|
||||
};
|
||||
|
||||
|
||||
Reference in new issue
Block a user