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:
Vinnie Falco committed 2018-12-19 20:59:20 -08:00
1 parent 74293fb8a5
commit 594a92e515
10 files changed
+386 -389

No files matched your search

+18 -2
View File
@@ -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.
+24 -16
View File
@@ -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
+63 -46
View File
@@ -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>::
+20 -14
View File
@@ -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;
};