From b2eddfabffeb78fc5b49f9c17d70175d2dfed2e0 Mon Sep 17 00:00:00 2001 From: Steven Le Rouzic Date: Tue, 31 Dec 2024 01:16:12 +0100 Subject: Some work on buffer move --- asl/buffer.hpp | 59 +++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 48 insertions(+), 11 deletions(-) (limited to 'asl/buffer.hpp') diff --git a/asl/buffer.hpp b/asl/buffer.hpp index d2226b1..9020a99 100644 --- a/asl/buffer.hpp +++ b/asl/buffer.hpp @@ -23,13 +23,15 @@ class buffer size_t m_size_encoded_{}; ASL_NO_UNIQUE_ADDRESS Allocator m_allocator; + + static constexpr isize_t kInlineRegionSize = size_of + size_of + size_of; public: static constexpr isize_t kInlineCapacity = []() { // 1 byte is used for size inline in m_size_encoded. // This is enough because we have at most 24 bytes available, // so 23 chars of capacity. - const isize_t available_size = size_of + size_of + size_of - 1; + const isize_t available_size = kInlineRegionSize - 1; return available_size / size_of; }(); @@ -89,20 +91,24 @@ private: return data() + sz; } + constexpr void set_size_inline(isize_t new_size) + { + ASL_ASSERT(new_size >= 0 && new_size <= kInlineCapacity); + size_t size_encoded = (load_size_encoded() & size_t{0x00ff'ffff'ffff'ffff}) | (bit_cast(new_size) << 56); + store_size_encoded(size_encoded); + } + constexpr void set_size(isize_t new_size) { ASL_ASSERT(new_size >= 0); ASL_ASSERT_RELEASE(new_size <= capacity()); - size_t size_encoded = load_size_encoded(); - if (kInlineCapacity == 0 || is_on_heap(size_encoded)) + if (kInlineCapacity == 0 || is_on_heap()) { store_size_encoded(encode_size_heap(new_size)); } else { - ASL_ASSERT(new_size <= kInlineCapacity); - size_encoded = (size_encoded & size_t{0x00ff'ffff'ffff'ffff}) | (bit_cast(new_size) << 56); - store_size_encoded(size_encoded); + set_size_inline(new_size); } } @@ -113,16 +119,34 @@ public: : m_allocator{ASL_MOVE(allocator)} {} - ~buffer() + constexpr buffer(buffer&& other) + : buffer(ASL_MOVE(other.m_allocator)) { - clear(); - if (is_on_heap() && m_data != nullptr) + if (other.is_on_heap()) + { + // @Todo Test this + destroy(); + m_data = other.m_data; + m_capacity = other.m_capacity; + set_size(other.size()); + } + else if (trivially_move_constructible) + { + // @Todo Test this + destroy(); + asl::memcpy(this, &other, kInlineRegionSize); + } + else { - auto current_layout = layout::array(m_capacity); - m_allocator.dealloc(m_data, current_layout); + // @Todo } } + ~buffer() + { + destroy(); + } + // @Todo Copy/move constructor & assignment constexpr isize_t size() const @@ -151,6 +175,19 @@ public: set_size(0); } + void destroy() + { + clear(); + if (is_on_heap()) + { + if (m_data != nullptr) + { + auto current_layout = layout::array(m_capacity); + m_allocator.dealloc(m_data, current_layout); + } + } + } + void reserve_capacity(isize_t new_capacity) { ASL_ASSERT(new_capacity >= 0); -- cgit