From 739f53210466415affd5b0ebd5b3da5c251d232c Mon Sep 17 00:00:00 2001 From: Steven Le Rouzic Date: Mon, 30 Dec 2024 00:05:38 +0100 Subject: Buffer clear & destructor --- asl/buffer.hpp | 41 +++++++++++++++++++++----------- asl/tests/buffer_tests.cpp | 58 ++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 84 insertions(+), 15 deletions(-) (limited to 'asl') diff --git a/asl/buffer.hpp b/asl/buffer.hpp index 12cbb80..d2226b1 100644 --- a/asl/buffer.hpp +++ b/asl/buffer.hpp @@ -12,10 +12,18 @@ namespace asl template class buffer { - T* m_data{}; isize_t m_capacity{}; + static constexpr size_t kOnHeapMask = 0x8000'0000'0000'0000ULL; + + // bit 63 : 1 = on heap, 0 = inline + // bits [62:56] : size when inline + // bits [62:0] : size when on heap + size_t m_size_encoded_{}; + + ASL_NO_UNIQUE_ADDRESS Allocator m_allocator; + public: static constexpr isize_t kInlineCapacity = []() { // 1 byte is used for size inline in m_size_encoded. @@ -26,15 +34,6 @@ public: }(); private: - static constexpr size_t kOnHeapMask = 0x8000'0000'0000'0000ULL; - - // bit 63 : 1 = on heap, 0 = inline - // bits [62:56] : size when inline - // bits [62:0] : size when on heap - size_t m_size_encoded_{}; - - ASL_NO_UNIQUE_ADDRESS Allocator m_allocator; - static_assert(align_of <= align_of); static_assert(align_of == align_of); static_assert(align_of == align_of); @@ -114,10 +113,17 @@ public: : m_allocator{ASL_MOVE(allocator)} {} - // @Todo Destructor - // @Todo clear + ~buffer() + { + clear(); + if (is_on_heap() && m_data != nullptr) + { + auto current_layout = layout::array(m_capacity); + m_allocator.dealloc(m_data, current_layout); + } + } + // @Todo Copy/move constructor & assignment - // @Todo Do leak checks on Linux constexpr isize_t size() const { @@ -136,6 +142,15 @@ public: } } + void clear() + { + isize_t current_size = size(); + if (current_size == 0) { return; } + + destruct_n(data(), current_size); + set_size(0); + } + void reserve_capacity(isize_t new_capacity) { ASL_ASSERT(new_capacity >= 0); diff --git a/asl/tests/buffer_tests.cpp b/asl/tests/buffer_tests.cpp index b677402..4c2d2c1 100644 --- a/asl/tests/buffer_tests.cpp +++ b/asl/tests/buffer_tests.cpp @@ -1,7 +1,7 @@ #include "asl/buffer.hpp" -#include "asl/print.hpp" #include "asl/testing/testing.hpp" +#include "asl/tests/test_types.hpp" struct Big { @@ -171,4 +171,58 @@ ASL_TEST(push_move) ASL_TEST_EXPECT(b[4].moved == 0); } -// @Todo Test push with non trivial move (non copy) types +ASL_TEST(clear) +{ + asl::buffer b; + ASL_TEST_EXPECT(b.size() == 0); + + b.push(1); + b.push(2); + b.push(3); + b.push(4); + b.push(5); + b.push(6); + b.push(7); + ASL_TEST_EXPECT(b.size() == 7); + + b.clear(); + ASL_TEST_EXPECT(b.size() == 0); +} + +ASL_TEST(clear_destructor_small) +{ + bool d0 = false; + bool d1 = false; + + asl::buffer buf; + static_assert(asl::buffer::kInlineCapacity >= 2); + + buf.push(&d0); + buf.push(&d1); + + buf.clear(); + ASL_TEST_EXPECT(d0 == true); + ASL_TEST_EXPECT(d1 == true); +} + +ASL_TEST(clear_destructor_heap) +{ + bool d0 = false; + bool d1 = false; + bool d2 = false; + + asl::buffer buf; + static_assert(asl::buffer::kInlineCapacity < 3); + + buf.push(&d0); + buf.push(&d1); + buf.push(&d2); + ASL_TEST_EXPECT(d0 == false); + ASL_TEST_EXPECT(d1 == false); + ASL_TEST_EXPECT(d2 == false); + + buf.clear(); + ASL_TEST_EXPECT(d0 == true); + ASL_TEST_EXPECT(d1 == true); + ASL_TEST_EXPECT(d2 == true); +} -- cgit