From 6d69512c6ff58ee8a7c1266257db5bf94cc91886 Mon Sep 17 00:00:00 2001 From: Steven Le Rouzic Date: Tue, 17 Dec 2024 23:30:44 +0100 Subject: Refactor a bunch of memory utilities --- asl/allocator.cpp | 2 +- asl/box.hpp | 9 +++------ asl/buffer.hpp | 25 +------------------------ asl/maybe_uninit.hpp | 7 ++----- asl/memory.hpp | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ asl/option.hpp | 9 +++------ 6 files changed, 61 insertions(+), 42 deletions(-) (limited to 'asl') diff --git a/asl/allocator.cpp b/asl/allocator.cpp index 8fbca4e..7479bd7 100644 --- a/asl/allocator.cpp +++ b/asl/allocator.cpp @@ -24,7 +24,7 @@ void* asl::GlobalHeap::alloc(const layout& layout) return ptr; } -void* asl::GlobalHeap::realloc(void* old_ptr, const layout& old_layout, const layout& new_layout) +void* asl::GlobalHeap::realloc(void* old_ptr, [[maybe_unused]] const layout& old_layout, const layout& new_layout) { #if ASL_OS_WINDOWS return ::_aligned_realloc(old_ptr, diff --git a/asl/box.hpp b/asl/box.hpp index 7556d76..198fada 100644 --- a/asl/box.hpp +++ b/asl/box.hpp @@ -58,10 +58,7 @@ public: { if (m_ptr != nullptr) { - if constexpr (!trivially_destructible) - { - m_ptr->~T(); - } + destruct(m_ptr); m_alloc.dealloc(m_ptr, layout::of()); m_ptr = nullptr; } @@ -92,7 +89,7 @@ constexpr box make_box_in(Allocator allocator, Args&&... args) requires constructible_from { void* raw_ptr = allocator.alloc(layout::of()); - T* ptr = new (raw_ptr) T(ASL_FWD(args)...); + auto* ptr = construct_at(raw_ptr, ASL_FWD(args)...); return box(ptr, ASL_MOVE(allocator)); } @@ -102,7 +99,7 @@ constexpr box make_box(Args&&... args) { Allocator allocator{}; void* raw_ptr = allocator.alloc(layout::of()); - T* ptr = new (raw_ptr) T{ ASL_FWD(args)... }; + auto* ptr = construct_at(raw_ptr, ASL_FWD(args)...); return box(ptr, ASL_MOVE(allocator)); } diff --git a/asl/buffer.hpp b/asl/buffer.hpp index 04444f0..8ee2869 100644 --- a/asl/buffer.hpp +++ b/asl/buffer.hpp @@ -132,30 +132,7 @@ public: T* new_data = reinterpret_cast(m_allocator.alloc(new_layout)); - // @Todo Move this logic somewhere else. Make move/destruct/etc. abstractions. - - if constexpr (trivially_copyable) - { - auto init_layout = layout::array(current_size); - memcpy(new_data, old_data, init_layout.size); - } - else - { - static_assert(move_constructible); - for (isize_t i = 0; i < current_size; ++i) - { - // NOLINTNEXTLINE(*-pointer-arithmetic) - new(new_data + i) T(ASL_MOVE(old_data[i])); - } - } - - if constexpr (!trivially_destructible) - { - for (isize_t i = 0; i < current_size; ++i) - { - (old_data + i)->~T(); - } - } + relocate_uninit_n(new_data, old_data, current_size); if (currently_on_heap) { diff --git a/asl/maybe_uninit.hpp b/asl/maybe_uninit.hpp index 0ab09ee..cedd96f 100644 --- a/asl/maybe_uninit.hpp +++ b/asl/maybe_uninit.hpp @@ -47,16 +47,13 @@ public: template constexpr void init_unsafe(Args&&... args) & { - new(uninit_ptr()) T(ASL_FWD(args)...); + construct_at(uninit_ptr(), ASL_FWD(args)...); } // @Safety Must be called only when in initialized state. constexpr void uninit_unsafe() & { - if constexpr (!trivially_destructible) - { - init_ptr_unsafe()->~T(); - } + destruct(init_ptr_unsafe()); } }; diff --git a/asl/memory.hpp b/asl/memory.hpp index 23aa392..7601a7f 100644 --- a/asl/memory.hpp +++ b/asl/memory.hpp @@ -1,6 +1,9 @@ #pragma once #include "asl/integers.hpp" +#include "asl/meta.hpp" +#include "asl/layout.hpp" +#include "asl/utility.hpp" constexpr void* operator new(size_t, void* ptr) { @@ -25,5 +28,53 @@ constexpr isize_t strlen(const char* s) return static_cast(__builtin_strlen(s)); } +template +constexpr T* construct_at(void* ptr, Args&&... args) + requires constructible_from +{ + return new (ptr) T{ ASL_FWD(args)... }; +} + +template +constexpr void destruct(T* data) +{ + if constexpr (!trivially_destructible) + { + data->~T(); + } +} + +template +constexpr void destruct_n(T* data, isize_t n) +{ + if constexpr (!trivially_destructible) + { + for (isize_t i = 0; i < n; ++i) + { + destruct(data + i); + } + } +} + +template +constexpr void relocate_uninit_n(T* to, T* from, isize_t n) +{ + if constexpr (trivially_copyable) + { + memcpy(to, from, size_of * n); + } + else + { + static_assert(move_constructible); + for (isize_t i = 0; i < n; ++i) + { + // NOLINTNEXTLINE(*-pointer-arithmetic) + construct_at(to + i, ASL_MOVE(from[i])); + } + } + + destruct_n(from, n); +} + } // namespace asl diff --git a/asl/option.hpp b/asl/option.hpp index f2af9ee..b22b295 100644 --- a/asl/option.hpp +++ b/asl/option.hpp @@ -88,7 +88,7 @@ class option if constexpr (kHasInlinePayload) { - new (&m_payload) T(ASL_FWD(args)...); + construct_at(&m_payload, ASL_FWD(args)...); } else { @@ -389,11 +389,8 @@ public: } else { - if constexpr (!trivially_destructible) - { - (&m_payload)->~T(); - } - new (&m_payload) T(niche{}); + destruct(&m_payload); + construct_at(&m_payload, niche{}); } } else -- cgit