Make classes derived from buffer<T> final to silence the virtual destructor warning. (#1937)

Co-authored-by: Bart Siwek <bsiwek@cisco.com>
This commit is contained in:
Bart Siwek 2020-10-16 02:41:56 +02:00 committed by GitHub
parent 811c8b58c5
commit 271eff149f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 11 additions and 15 deletions

View File

@ -761,7 +761,7 @@ class fixed_buffer_traits {
// A buffer that writes to an output iterator when flushed. // A buffer that writes to an output iterator when flushed.
template <typename OutputIt, typename T, typename Traits = buffer_traits> template <typename OutputIt, typename T, typename Traits = buffer_traits>
class iterator_buffer : public Traits, public buffer<T> { class iterator_buffer final : public Traits, public buffer<T> {
private: private:
OutputIt out_; OutputIt out_;
enum { buffer_size = 256 }; enum { buffer_size = 256 };
@ -787,7 +787,7 @@ class iterator_buffer : public Traits, public buffer<T> {
size_t count() const { return Traits::count() + this->size(); } size_t count() const { return Traits::count() + this->size(); }
}; };
template <typename T> class iterator_buffer<T*, T> : public buffer<T> { template <typename T> class iterator_buffer<T*, T> final : public buffer<T> {
protected: protected:
void grow(size_t) final FMT_OVERRIDE {} void grow(size_t) final FMT_OVERRIDE {}
@ -801,7 +801,7 @@ template <typename T> class iterator_buffer<T*, T> : public buffer<T> {
template <typename Container> template <typename Container>
class iterator_buffer<std::back_insert_iterator<Container>, class iterator_buffer<std::back_insert_iterator<Container>,
enable_if_t<is_contiguous<Container>::value, enable_if_t<is_contiguous<Container>::value,
typename Container::value_type>> typename Container::value_type>> final
: public buffer<typename Container::value_type> { : public buffer<typename Container::value_type> {
private: private:
Container& container_; Container& container_;
@ -823,7 +823,7 @@ class iterator_buffer<std::back_insert_iterator<Container>,
}; };
// A buffer that counts the number of code units written discarding the output. // A buffer that counts the number of code units written discarding the output.
template <typename T = char> class counting_buffer : public buffer<T> { template <typename T = char> class counting_buffer final : public buffer<T> {
private: private:
enum { buffer_size = 256 }; enum { buffer_size = 256 };
T data_[buffer_size]; T data_[buffer_size];

View File

@ -651,7 +651,7 @@ enum { inline_buffer_size = 500 };
*/ */
template <typename T, size_t SIZE = inline_buffer_size, template <typename T, size_t SIZE = inline_buffer_size,
typename Allocator = std::allocator<T>> typename Allocator = std::allocator<T>>
class basic_memory_buffer : public detail::buffer<T> { class basic_memory_buffer final : public detail::buffer<T> {
private: private:
T store_[SIZE]; T store_[SIZE];

View File

@ -378,7 +378,7 @@ struct ostream_params {
static constexpr detail::buffer_size buffer_size; static constexpr detail::buffer_size buffer_size;
// A fast output stream which is not thread-safe. // A fast output stream which is not thread-safe.
class ostream : private detail::buffer<char> { class ostream final : private detail::buffer<char> {
private: private:
file file_; file file_;

View File

@ -78,7 +78,7 @@ TEST(BufferTest, Indestructible) {
"buffer's destructor is protected"); "buffer's destructor is protected");
} }
template <typename T> struct mock_buffer : buffer<T> { template <typename T> struct mock_buffer final : buffer<T> {
MOCK_METHOD1(do_grow, size_t(size_t capacity)); MOCK_METHOD1(do_grow, size_t(size_t capacity));
void grow(size_t capacity) { this->set(this->data(), do_grow(capacity)); } void grow(size_t capacity) { this->set(this->data(), do_grow(capacity)); }
@ -368,7 +368,7 @@ TEST(ArgTest, PointerArg) {
struct check_custom { struct check_custom {
test_result operator()( test_result operator()(
fmt::basic_format_arg<fmt::format_context>::handle h) const { fmt::basic_format_arg<fmt::format_context>::handle h) const {
struct test_buffer : fmt::detail::buffer<char> { struct test_buffer final : fmt::detail::buffer<char> {
char data[10]; char data[10];
test_buffer() : fmt::detail::buffer<char>(data, 0, 10) {} test_buffer() : fmt::detail::buffer<char>(data, 0, 10) {}
void grow(size_t) {} void grow(size_t) {}

View File

@ -293,12 +293,8 @@ TEST(MemoryBufferTest, MoveAssignment) {
TEST(MemoryBufferTest, Grow) { TEST(MemoryBufferTest, Grow) {
typedef allocator_ref<mock_allocator<int>> Allocator; typedef allocator_ref<mock_allocator<int>> Allocator;
typedef basic_memory_buffer<int, 10, Allocator> Base;
mock_allocator<int> alloc; mock_allocator<int> alloc;
struct TestMemoryBuffer : Base { basic_memory_buffer<int, 10, Allocator> buffer((Allocator(&alloc)));
TestMemoryBuffer(Allocator alloc) : Base(alloc) {}
using Base::grow;
} buffer((Allocator(&alloc)));
buffer.resize(7); buffer.resize(7);
using fmt::detail::to_unsigned; using fmt::detail::to_unsigned;
for (int i = 0; i < 7; ++i) buffer[to_unsigned(i)] = i * i; for (int i = 0; i < 7; ++i) buffer[to_unsigned(i)] = i * i;
@ -306,7 +302,7 @@ TEST(MemoryBufferTest, Grow) {
int mem[20]; int mem[20];
mem[7] = 0xdead; mem[7] = 0xdead;
EXPECT_CALL(alloc, allocate(20)).WillOnce(Return(mem)); EXPECT_CALL(alloc, allocate(20)).WillOnce(Return(mem));
buffer.grow(20); buffer.try_reserve(20);
EXPECT_EQ(20u, buffer.capacity()); EXPECT_EQ(20u, buffer.capacity());
// Check if size elements have been copied // Check if size elements have been copied
for (int i = 0; i < 7; ++i) EXPECT_EQ(i * i, buffer[to_unsigned(i)]); for (int i = 0; i < 7; ++i) EXPECT_EQ(i * i, buffer[to_unsigned(i)]);

View File

@ -150,7 +150,7 @@ TEST(OStreamTest, WriteToOStreamMaxSize) {
std::streamsize max_streamsize = fmt::detail::max_value<std::streamsize>(); std::streamsize max_streamsize = fmt::detail::max_value<std::streamsize>();
if (max_size <= fmt::detail::to_unsigned(max_streamsize)) return; if (max_size <= fmt::detail::to_unsigned(max_streamsize)) return;
struct test_buffer : fmt::detail::buffer<char> { struct test_buffer final : fmt::detail::buffer<char> {
explicit test_buffer(size_t size) explicit test_buffer(size_t size)
: fmt::detail::buffer<char>(nullptr, size, size) {} : fmt::detail::buffer<char>(nullptr, size, size) {}
void grow(size_t) {} void grow(size_t) {}