100 lines
4.7 KiB
C++
100 lines
4.7 KiB
C++
#pragma once
|
|
|
|
#include "Internal/heap_allocator.inl.h"
|
|
#include "Algorithm.h"
|
|
|
|
namespace baselib
|
|
{
|
|
BASELIB_CPP_INTERFACE
|
|
{
|
|
// Heap allocator implementation providing platform dependent system heap allocation.
|
|
//
|
|
// Allocations are guaranteed to be aligned to at least the value of `default_alignment`.
|
|
// For optimal performance, platform aligned allocation calls are only used when `default_alignment` exceeds platform minimum alignment guarantee.
|
|
// This allocator is a stateless allocator (empty class).
|
|
//
|
|
// Notes on operation failure of allocator methods:
|
|
// Operation failures will currently trigger process abort by the underlying system.
|
|
// As a result the heap allocator currently will never return `nullptr`/`false` to signal failure, as is standard behaviour (nor any error state information).
|
|
//
|
|
template<uint32_t default_alignment = 8>
|
|
class heap_allocator
|
|
{
|
|
using impl = detail::heap_allocator<default_alignment>;
|
|
static_assert((default_alignment <= impl::max_alignment), "'default_alignment' exceeded max value");
|
|
static_assert((default_alignment != 0), "'default_alignment' must not be a zero value");
|
|
static_assert(::baselib::Algorithm::IsPowerOfTwo(default_alignment), "'default_alignment' must be a power of two value");
|
|
|
|
public:
|
|
// Allocated memory is guaranteed to always be aligned to at least the value of `alignment`.
|
|
static constexpr uint32_t alignment = default_alignment;
|
|
|
|
// Typedefs
|
|
typedef Baselib_ErrorState error_state;
|
|
|
|
// Allocates a memory block large enough to hold `size` number of bytes. Zero size is valid.
|
|
//
|
|
// \returns Address to memory block of allocated memory.
|
|
void* allocate(size_t size) const
|
|
{
|
|
error_state result = Baselib_ErrorState_Create();
|
|
return impl::allocate(size, &result);
|
|
}
|
|
|
|
// Allocates a memory block large enough to hold `size` number of bytes. Zero size is valid.
|
|
//
|
|
// \returns Address to memory block of allocated memory.
|
|
void* allocate(size_t size, error_state *error_state_ptr) const
|
|
{
|
|
return impl::allocate(size, error_state_ptr);
|
|
}
|
|
|
|
// Reallocates previously allocated or reallocated memory block pointer reference `ptr` from `old_size` to `new_size` number of bytes.
|
|
// Passing `nullptr` in `ptr` yield the same result as calling `allocate`.
|
|
//
|
|
// \returns Address to memory block of reallocated memory.
|
|
void* reallocate(void* ptr, size_t old_size, size_t new_size) const
|
|
{
|
|
error_state result = Baselib_ErrorState_Create();
|
|
return impl::reallocate(ptr, old_size, new_size, &result);
|
|
}
|
|
|
|
// Reallocates previously allocated or reallocated memory block pointer reference `ptr` from `old_size` to `new_size` number of bytes.
|
|
// Passing `nullptr` in `ptr` yield the same result as calling `allocate`.
|
|
//
|
|
// \returns Address to memory block of reallocated memory.
|
|
void* reallocate(void* ptr, size_t old_size, size_t new_size, error_state *error_state_ptr) const
|
|
{
|
|
return impl::reallocate(ptr, old_size, new_size, error_state_ptr);
|
|
}
|
|
|
|
// Deallocates memory block previously allocated or reallocated with `size` pointed to by `ptr`.
|
|
// Passing `nullptr` in `ptr` result in a no-op.
|
|
//
|
|
// \returns Always returns `true` (see notes on operation failure).
|
|
bool deallocate(void* ptr, size_t size) const
|
|
{
|
|
error_state result = Baselib_ErrorState_Create();
|
|
return impl::deallocate(ptr, size, &result);
|
|
}
|
|
|
|
// Deallocates memory block previously allocated or reallocated with `size` pointed to by `ptr`.
|
|
// Passing `nullptr` in `ptr` result in a no-op.
|
|
//
|
|
// \returns Always returns `true` (see notes on operation failure).
|
|
bool deallocate(void* ptr, size_t size, error_state *error_state_ptr) const
|
|
{
|
|
return impl::deallocate(ptr, size, error_state_ptr);
|
|
}
|
|
|
|
// Calculate optimal allocation size given `size`.
|
|
//
|
|
// \returns Optimal size when allocating memory given `size`.
|
|
constexpr size_t optimal_size(size_t size) const
|
|
{
|
|
return impl::optimal_size(size);
|
|
}
|
|
};
|
|
}
|
|
}
|