summaryrefslogtreecommitdiff
path: root/asl
diff options
context:
space:
mode:
authorSteven Le Rouzic <steven.lerouzic@gmail.com>2024-12-17 23:30:44 +0100
committerSteven Le Rouzic <steven.lerouzic@gmail.com>2024-12-20 15:35:58 +0100
commit6d69512c6ff58ee8a7c1266257db5bf94cc91886 (patch)
tree56107a97d41993417b620b88970c8d6cf7b15127 /asl
parent7c9e871eb66de64e7a1861fd1faebcd5524fed96 (diff)
Refactor a bunch of memory utilities
Diffstat (limited to 'asl')
-rw-r--r--asl/allocator.cpp2
-rw-r--r--asl/box.hpp9
-rw-r--r--asl/buffer.hpp25
-rw-r--r--asl/maybe_uninit.hpp7
-rw-r--r--asl/memory.hpp51
-rw-r--r--asl/option.hpp9
6 files changed, 61 insertions, 42 deletions
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<T>)
- {
- m_ptr->~T();
- }
+ destruct(m_ptr);
m_alloc.dealloc(m_ptr, layout::of<T>());
m_ptr = nullptr;
}
@@ -92,7 +89,7 @@ constexpr box<T, Allocator> make_box_in(Allocator allocator, Args&&... args)
requires constructible_from<T, Args&&...>
{
void* raw_ptr = allocator.alloc(layout::of<T>());
- T* ptr = new (raw_ptr) T(ASL_FWD(args)...);
+ auto* ptr = construct_at<T>(raw_ptr, ASL_FWD(args)...);
return box(ptr, ASL_MOVE(allocator));
}
@@ -102,7 +99,7 @@ constexpr box<T, Allocator> make_box(Args&&... args)
{
Allocator allocator{};
void* raw_ptr = allocator.alloc(layout::of<T>());
- T* ptr = new (raw_ptr) T{ ASL_FWD(args)... };
+ auto* ptr = construct_at<T>(raw_ptr, ASL_FWD(args)...);
return box<T>(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<T*>(m_allocator.alloc(new_layout));
- // @Todo Move this logic somewhere else. Make move/destruct/etc. abstractions.
-
- if constexpr (trivially_copyable<T>)
- {
- auto init_layout = layout::array<T>(current_size);
- memcpy(new_data, old_data, init_layout.size);
- }
- else
- {
- static_assert(move_constructible<T>);
- 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<T>)
- {
- 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<typename... Args>
constexpr void init_unsafe(Args&&... args) &
{
- new(uninit_ptr()) T(ASL_FWD(args)...);
+ construct_at<T>(uninit_ptr(), ASL_FWD(args)...);
}
// @Safety Must be called only when in initialized state.
constexpr void uninit_unsafe() &
{
- if constexpr (!trivially_destructible<T>)
- {
- 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<isize_t>(__builtin_strlen(s));
}
+template<typename T, typename... Args>
+constexpr T* construct_at(void* ptr, Args&&... args)
+ requires constructible_from<T, Args&&...>
+{
+ return new (ptr) T{ ASL_FWD(args)... };
+}
+
+template<typename T>
+constexpr void destruct(T* data)
+{
+ if constexpr (!trivially_destructible<T>)
+ {
+ data->~T();
+ }
+}
+
+template<typename T>
+constexpr void destruct_n(T* data, isize_t n)
+{
+ if constexpr (!trivially_destructible<T>)
+ {
+ for (isize_t i = 0; i < n; ++i)
+ {
+ destruct(data + i);
+ }
+ }
+}
+
+template<typename T>
+constexpr void relocate_uninit_n(T* to, T* from, isize_t n)
+{
+ if constexpr (trivially_copyable<T>)
+ {
+ memcpy(to, from, size_of<T> * n);
+ }
+ else
+ {
+ static_assert(move_constructible<T>);
+ for (isize_t i = 0; i < n; ++i)
+ {
+ // NOLINTNEXTLINE(*-pointer-arithmetic)
+ construct_at<T>(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<T>(&m_payload, ASL_FWD(args)...);
}
else
{
@@ -389,11 +389,8 @@ public:
}
else
{
- if constexpr (!trivially_destructible<T>)
- {
- (&m_payload)->~T();
- }
- new (&m_payload) T(niche{});
+ destruct(&m_payload);
+ construct_at<T>(&m_payload, niche{});
}
}
else