summaryrefslogtreecommitdiff
path: root/asl
diff options
context:
space:
mode:
authorSteven Le Rouzic <steven.lerouzic@gmail.com>2024-12-30 00:05:38 +0100
committerSteven Le Rouzic <steven.lerouzic@gmail.com>2024-12-30 00:06:11 +0100
commit739f53210466415affd5b0ebd5b3da5c251d232c (patch)
treedb0ea8fae292c70421a4a163b3c283708f98e214 /asl
parent7e8cd10685908570d7af41255b08ed4709323771 (diff)
Buffer clear & destructor
Diffstat (limited to 'asl')
-rw-r--r--asl/buffer.hpp41
-rw-r--r--asl/tests/buffer_tests.cpp58
2 files changed, 84 insertions, 15 deletions
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<is_object T, allocator Allocator = DefaultAllocator>
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<T> <= align_of<T*>);
static_assert(align_of<T*> == align_of<isize_t>);
static_assert(align_of<T*> == align_of<size_t>);
@@ -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<T>(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<int32_t> 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<DestructorObserver> buf;
+ static_assert(asl::buffer<DestructorObserver>::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<DestructorObserver> buf;
+ static_assert(asl::buffer<DestructorObserver>::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);
+}