From c3125e835836f417f16e5f6e849daec6a8cd5063 Mon Sep 17 00:00:00 2001 From: Vinnie Falco Date: Thu, 7 Feb 2019 11:47:57 -0800 Subject: [PATCH] flat_buffer::clear preserves capacity --- CHANGELOG.md | 1 + include/boost/beast/core/flat_buffer.hpp | 8 +--- include/boost/beast/core/impl/flat_buffer.hpp | 46 +++++++++++-------- test/beast/core/flat_buffer.cpp | 13 ++++++ 4 files changed, 44 insertions(+), 24 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dd2bb89a..1a4f4d32 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ Version 211: * Improvements to test::stream * Add stranded_stream * Add flat_stream +* flat_buffer::clear preserves capacity -------------------------------------------------------------------------------- diff --git a/include/boost/beast/core/flat_buffer.hpp b/include/boost/beast/core/flat_buffer.hpp index 6dba0a42..3e7a6aba 100644 --- a/include/boost/beast/core/flat_buffer.hpp +++ b/include/boost/beast/core/flat_buffer.hpp @@ -370,13 +370,9 @@ 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. + /** Set the size of the readable and writable bytes to zero. + This clears the buffer without changing capacity. Buffer sequences previously obtained using @ref data or @ref prepare become invalid. diff --git a/include/boost/beast/core/impl/flat_buffer.hpp b/include/boost/beast/core/impl/flat_buffer.hpp index cd64fc7f..16d458c6 100644 --- a/include/boost/beast/core/impl/flat_buffer.hpp +++ b/include/boost/beast/core/impl/flat_buffer.hpp @@ -66,7 +66,7 @@ template basic_flat_buffer:: basic_flat_buffer(Allocator const& alloc) noexcept : boost::empty_value( - boost::empty_init_t(), alloc) + boost::empty_init_t{}, alloc) , begin_(nullptr) , in_(nullptr) , out_(nullptr) @@ -83,7 +83,7 @@ basic_flat_buffer( std::size_t limit, Allocator const& alloc) noexcept : boost::empty_value( - boost::empty_init_t(), alloc) + boost::empty_init_t{}, alloc) , begin_(nullptr) , in_(nullptr) , out_(nullptr) @@ -97,7 +97,7 @@ template basic_flat_buffer:: basic_flat_buffer(basic_flat_buffer&& other) noexcept : boost::empty_value( - boost::empty_init_t(), std::move(other.get())) + boost::empty_init_t{}, std::move(other.get())) , begin_(boost::exchange(other.begin_, nullptr)) , in_(boost::exchange(other.in_, nullptr)) , out_(boost::exchange(other.out_, nullptr)) @@ -113,7 +113,7 @@ basic_flat_buffer( basic_flat_buffer&& other, Allocator const& alloc) : boost::empty_value( - boost::empty_init_t(), alloc) + boost::empty_init_t{}, alloc) { if(this->get() != other.get()) { @@ -125,6 +125,7 @@ basic_flat_buffer( max_ = other.max_; copy_from(other); other.clear(); + other.shrink_to_fit(); return; } @@ -147,7 +148,7 @@ basic_flat_buffer( template basic_flat_buffer:: basic_flat_buffer(basic_flat_buffer const& other) - : boost::empty_value(boost::empty_init_t(), + : boost::empty_value(boost::empty_init_t{}, alloc_traits::select_on_container_copy_construction( other.get())) , begin_(nullptr) @@ -166,7 +167,7 @@ basic_flat_buffer( basic_flat_buffer const& other, Allocator const& alloc) : boost::empty_value( - boost::empty_init_t(), alloc) + boost::empty_init_t{}, alloc) , begin_(nullptr) , in_(nullptr) , out_(nullptr) @@ -200,7 +201,7 @@ basic_flat_buffer( basic_flat_buffer const& other, Allocator const& alloc) : boost::empty_value( - boost::empty_init_t(), alloc) + boost::empty_init_t{}, alloc) , begin_(nullptr) , in_(nullptr) , out_(nullptr) @@ -292,13 +293,9 @@ void basic_flat_buffer:: clear() noexcept { - alloc_traits::deallocate( - this->get(), begin_, size()); - begin_ = nullptr; - in_ = nullptr; - out_ = nullptr; - last_ = nullptr; - end_ = nullptr; + in_ = begin_; + out_ = begin_; + last_ = begin_; } //------------------------------------------------------------------------------ @@ -379,11 +376,21 @@ copy_from( basic_flat_buffer const& other) { std::size_t const n = other.size(); - if(begin_ && (n == 0 || n > capacity())) - clear(); - if(n > capacity()) + if(n == 0 || 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); in_ = begin_; out_ = begin_ + n; @@ -406,6 +413,7 @@ basic_flat_buffer:: move_assign(basic_flat_buffer& other, std::true_type) { clear(); + shrink_to_fit(); this->get() = std::move(other.get()); begin_ = other.begin_; in_ = other.in_; @@ -429,6 +437,7 @@ move_assign(basic_flat_buffer& other, std::false_type) { copy_from(other); other.clear(); + other.shrink_to_fit(); } else { @@ -452,6 +461,7 @@ basic_flat_buffer:: copy_assign(basic_flat_buffer const& other, std::false_type) { clear(); + shrink_to_fit(); max_ = other.max_; copy_from(other); } diff --git a/test/beast/core/flat_buffer.cpp b/test/beast/core/flat_buffer.cpp index b02d2a71..ab1a22dc 100644 --- a/test/beast/core/flat_buffer.cpp +++ b/test/beast/core/flat_buffer.cpp @@ -409,6 +409,19 @@ public: b.shrink_to_fit(); 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