flat_buffer::clear preserves capacity

This commit is contained in:
Vinnie Falco
2019-02-07 11:47:57 -08:00
parent 27a6f57200
commit c3125e8358
4 changed files with 44 additions and 24 deletions

View File

@@ -4,6 +4,7 @@ Version 211:
* Improvements to test::stream * Improvements to test::stream
* Add stranded_stream * Add stranded_stream
* Add flat_stream * Add flat_stream
* flat_buffer::clear preserves capacity
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------

View File

@@ -370,13 +370,9 @@ public:
void void
shrink_to_fit(); shrink_to_fit();
/** Deallocate the internal buffer and reduce capacity to zero. /** Set the size of the readable and writable bytes 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.
This clears the buffer without changing capacity.
Buffer sequences previously obtained using @ref data or Buffer sequences previously obtained using @ref data or
@ref prepare become invalid. @ref prepare become invalid.

View File

@@ -66,7 +66,7 @@ template<class Allocator>
basic_flat_buffer<Allocator>:: basic_flat_buffer<Allocator>::
basic_flat_buffer(Allocator const& alloc) noexcept basic_flat_buffer(Allocator const& alloc) noexcept
: boost::empty_value<base_alloc_type>( : boost::empty_value<base_alloc_type>(
boost::empty_init_t(), alloc) boost::empty_init_t{}, alloc)
, begin_(nullptr) , begin_(nullptr)
, in_(nullptr) , in_(nullptr)
, out_(nullptr) , out_(nullptr)
@@ -83,7 +83,7 @@ basic_flat_buffer(
std::size_t limit, std::size_t limit,
Allocator const& alloc) noexcept Allocator const& alloc) noexcept
: boost::empty_value<base_alloc_type>( : boost::empty_value<base_alloc_type>(
boost::empty_init_t(), alloc) boost::empty_init_t{}, alloc)
, begin_(nullptr) , begin_(nullptr)
, in_(nullptr) , in_(nullptr)
, out_(nullptr) , out_(nullptr)
@@ -97,7 +97,7 @@ template<class Allocator>
basic_flat_buffer<Allocator>:: basic_flat_buffer<Allocator>::
basic_flat_buffer(basic_flat_buffer&& other) noexcept basic_flat_buffer(basic_flat_buffer&& other) noexcept
: boost::empty_value<base_alloc_type>( : boost::empty_value<base_alloc_type>(
boost::empty_init_t(), std::move(other.get())) boost::empty_init_t{}, std::move(other.get()))
, begin_(boost::exchange(other.begin_, nullptr)) , begin_(boost::exchange(other.begin_, nullptr))
, in_(boost::exchange(other.in_, nullptr)) , in_(boost::exchange(other.in_, nullptr))
, out_(boost::exchange(other.out_, nullptr)) , out_(boost::exchange(other.out_, nullptr))
@@ -113,7 +113,7 @@ basic_flat_buffer(
basic_flat_buffer&& other, basic_flat_buffer&& other,
Allocator const& alloc) Allocator const& alloc)
: boost::empty_value<base_alloc_type>( : boost::empty_value<base_alloc_type>(
boost::empty_init_t(), alloc) boost::empty_init_t{}, alloc)
{ {
if(this->get() != other.get()) if(this->get() != other.get())
{ {
@@ -125,6 +125,7 @@ basic_flat_buffer(
max_ = other.max_; max_ = other.max_;
copy_from(other); copy_from(other);
other.clear(); other.clear();
other.shrink_to_fit();
return; return;
} }
@@ -147,7 +148,7 @@ basic_flat_buffer(
template<class Allocator> template<class Allocator>
basic_flat_buffer<Allocator>:: basic_flat_buffer<Allocator>::
basic_flat_buffer(basic_flat_buffer const& other) basic_flat_buffer(basic_flat_buffer const& other)
: boost::empty_value<base_alloc_type>(boost::empty_init_t(), : boost::empty_value<base_alloc_type>(boost::empty_init_t{},
alloc_traits::select_on_container_copy_construction( alloc_traits::select_on_container_copy_construction(
other.get())) other.get()))
, begin_(nullptr) , begin_(nullptr)
@@ -166,7 +167,7 @@ basic_flat_buffer(
basic_flat_buffer const& other, basic_flat_buffer const& other,
Allocator const& alloc) Allocator const& alloc)
: boost::empty_value<base_alloc_type>( : boost::empty_value<base_alloc_type>(
boost::empty_init_t(), alloc) boost::empty_init_t{}, alloc)
, begin_(nullptr) , begin_(nullptr)
, in_(nullptr) , in_(nullptr)
, out_(nullptr) , out_(nullptr)
@@ -200,7 +201,7 @@ basic_flat_buffer(
basic_flat_buffer<OtherAlloc> const& other, basic_flat_buffer<OtherAlloc> const& other,
Allocator const& alloc) Allocator const& alloc)
: boost::empty_value<base_alloc_type>( : boost::empty_value<base_alloc_type>(
boost::empty_init_t(), alloc) boost::empty_init_t{}, alloc)
, begin_(nullptr) , begin_(nullptr)
, in_(nullptr) , in_(nullptr)
, out_(nullptr) , out_(nullptr)
@@ -292,13 +293,9 @@ void
basic_flat_buffer<Allocator>:: basic_flat_buffer<Allocator>::
clear() noexcept clear() noexcept
{ {
alloc_traits::deallocate( in_ = begin_;
this->get(), begin_, size()); out_ = begin_;
begin_ = nullptr; last_ = begin_;
in_ = nullptr;
out_ = nullptr;
last_ = nullptr;
end_ = nullptr;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -379,11 +376,21 @@ copy_from(
basic_flat_buffer<OtherAlloc> const& other) basic_flat_buffer<OtherAlloc> const& other)
{ {
std::size_t const n = other.size(); std::size_t const n = other.size();
if(begin_ && (n == 0 || n > capacity())) if(n == 0 || n > capacity())
clear();
if(n > capacity())
{ {
BOOST_ASSERT(! begin_); if(begin_ != nullptr)
{
alloc_traits::deallocate(
this->get(), begin_,
this->capacity());
begin_ = nullptr;
in_ = nullptr;
out_ = nullptr;
last_ = nullptr;
end_ = nullptr;
}
if(n == 0)
return;
begin_ = alloc(n); begin_ = alloc(n);
in_ = begin_; in_ = begin_;
out_ = begin_ + n; out_ = begin_ + n;
@@ -406,6 +413,7 @@ basic_flat_buffer<Allocator>::
move_assign(basic_flat_buffer& other, std::true_type) move_assign(basic_flat_buffer& other, std::true_type)
{ {
clear(); clear();
shrink_to_fit();
this->get() = std::move(other.get()); this->get() = std::move(other.get());
begin_ = other.begin_; begin_ = other.begin_;
in_ = other.in_; in_ = other.in_;
@@ -429,6 +437,7 @@ move_assign(basic_flat_buffer& other, std::false_type)
{ {
copy_from(other); copy_from(other);
other.clear(); other.clear();
other.shrink_to_fit();
} }
else else
{ {
@@ -452,6 +461,7 @@ basic_flat_buffer<Allocator>::
copy_assign(basic_flat_buffer const& other, std::false_type) copy_assign(basic_flat_buffer const& other, std::false_type)
{ {
clear(); clear();
shrink_to_fit();
max_ = other.max_; max_ = other.max_;
copy_from(other); copy_from(other);
} }

View File

@@ -409,6 +409,19 @@ public:
b.shrink_to_fit(); b.shrink_to_fit();
BEAST_EXPECT(b.capacity() == 0); BEAST_EXPECT(b.capacity() == 0);
} }
// clear
{
flat_buffer b;
BEAST_EXPECT(b.capacity() == 0);
b.prepare(50);
b.commit(50);
BEAST_EXPECT(b.size() == 50);
BEAST_EXPECT(b.capacity() == 50);
b.clear();
BEAST_EXPECT(b.size() == 0);
BEAST_EXPECT(b.capacity() == 50);
}
} }
void void