Buffer clear & destructor
This commit is contained in:
@ -12,10 +12,18 @@ namespace asl
|
|||||||
template<is_object T, allocator Allocator = DefaultAllocator>
|
template<is_object T, allocator Allocator = DefaultAllocator>
|
||||||
class buffer
|
class buffer
|
||||||
{
|
{
|
||||||
|
|
||||||
T* m_data{};
|
T* m_data{};
|
||||||
isize_t m_capacity{};
|
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:
|
public:
|
||||||
static constexpr isize_t kInlineCapacity = []() {
|
static constexpr isize_t kInlineCapacity = []() {
|
||||||
// 1 byte is used for size inline in m_size_encoded.
|
// 1 byte is used for size inline in m_size_encoded.
|
||||||
@ -26,15 +34,6 @@ public:
|
|||||||
}();
|
}();
|
||||||
|
|
||||||
private:
|
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<T*>);
|
||||||
static_assert(align_of<T*> == align_of<isize_t>);
|
static_assert(align_of<T*> == align_of<isize_t>);
|
||||||
static_assert(align_of<T*> == align_of<size_t>);
|
static_assert(align_of<T*> == align_of<size_t>);
|
||||||
@ -114,10 +113,17 @@ public:
|
|||||||
: m_allocator{ASL_MOVE(allocator)}
|
: m_allocator{ASL_MOVE(allocator)}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// @Todo Destructor
|
~buffer()
|
||||||
// @Todo clear
|
{
|
||||||
|
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 Copy/move constructor & assignment
|
||||||
// @Todo Do leak checks on Linux
|
|
||||||
|
|
||||||
constexpr isize_t size() const
|
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)
|
void reserve_capacity(isize_t new_capacity)
|
||||||
{
|
{
|
||||||
ASL_ASSERT(new_capacity >= 0);
|
ASL_ASSERT(new_capacity >= 0);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include "asl/buffer.hpp"
|
#include "asl/buffer.hpp"
|
||||||
#include "asl/print.hpp"
|
|
||||||
|
|
||||||
#include "asl/testing/testing.hpp"
|
#include "asl/testing/testing.hpp"
|
||||||
|
#include "asl/tests/test_types.hpp"
|
||||||
|
|
||||||
struct Big
|
struct Big
|
||||||
{
|
{
|
||||||
@ -171,4 +171,58 @@ ASL_TEST(push_move)
|
|||||||
ASL_TEST_EXPECT(b[4].moved == 0);
|
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);
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user