nstd-sys 0.13.0

Cross platform general purpose C library written in Rust.
Documentation
#ifndef NSTD_CORE_ALLOC_H
#define NSTD_CORE_ALLOC_H
#include "../nstd.h"
#include "optional.h"

/// Describes a valid layout for a block of memory.
typedef struct {
    /// The size of the memory block.
    NSTDUInt size;
    /// The alignment of the memory block.
    NSTDUInt align;
} NSTDAllocLayout;

/// Represents an optional value of type `NSTDAllocLayout`.
NSTDOptional(NSTDAllocLayout) NSTDOptionalAllocLayout;

/// Describes an error returned from allocation functions.
typedef enum {
    /// No error occurred.
    NSTD_ALLOC_ERROR_NONE,
    /// Allocating or reallocating failed.
    NSTD_ALLOC_ERROR_OUT_OF_MEMORY,
    /// Deallocating memory failed.
    NSTD_ALLOC_ERROR_MEMORY_NOT_FOUND,
    /// Getting a handle to a heap failed.
    NSTD_ALLOC_ERROR_HEAP_NOT_FOUND,
    /// A heap is invalid.
    NSTD_ALLOC_ERROR_INVALID_HEAP,
    /// An allocation function received input parameters that resulted in an invalid memory layout.
    NSTD_ALLOC_ERROR_INVALID_LAYOUT
} NSTDAllocError;

/// A structure of function pointers making up an allocator's virtual function table.
typedef struct {
    /// An opaque pointer to the allocator's state.
    NSTDAny state;
    /// Allocates a new block of memory.
    ///
    /// If allocation fails, a null pointer is returned.
    ///
    /// If allocation succeeds, this returns a pointer to the new memory that is suitably aligned
    /// for `layout`'s alignment and the number of bytes allocated is at least equal to `layout`'s
    /// size.
    ///
    /// # Parameters:
    ///
    /// - `NSTDAllocLayout layout` - Describes the memory layout to allocate for.
    ///
    /// # Returns
    ///
    /// `NSTDAnyMut ptr` - A pointer to the allocated memory, null on error.
    ///
    /// # Safety
    ///
    /// - Behavior is undefined if `layout`'s size is zero.
    ///
    /// - The new memory buffer should be considered uninitialized.
    NSTDAnyMut (*allocate)(NSTDAny, NSTDAllocLayout);
    /// Allocates a new block of zero-initialized memory.
    ///
    /// If allocation fails, a null pointer is returned.
    ///
    /// If allocation succeeds, this returns a pointer to the new memory that is suitably aligned
    /// for `layout`'s alignment and the number of bytes allocated is at least equal to `layout`'s
    /// size.
    ///
    /// # Parameters:
    ///
    /// - `NSTDAllocLayout layout` - Describes the memory layout to allocate for.
    ///
    /// # Returns
    ///
    /// `NSTDAnyMut ptr` - A pointer to the allocated memory, null on error.
    ///
    /// # Safety
    ///
    /// Behavior is undefined if `layout`'s size is zero.
    NSTDAnyMut (*allocate_zeroed)(NSTDAny, NSTDAllocLayout);
    /// Reallocates memory that was previously allocated by this allocator.
    ///
    /// On successful reallocation, `ptr` will point to the new memory location and
    /// `NSTD_ALLOC_ERROR_NONE` will be returned. If this is not the case and reallocation fails,
    /// the pointer will remain untouched and the appropriate error is returned.
    ///
    /// # Parameters:
    ///
    /// - `NSTDAnyMut *ptr` - A pointer to the allocated memory.
    ///
    /// - `NSTDAllocLayout old_layout` - Describes the previous memory layout.
    ///
    /// - `NSTDAllocLayout new_layout` - Describes the new memory layout to allocate for.
    ///
    /// # Returns
    ///
    /// `NSTDAllocError errc` - The allocation operation error code.
    ///
    /// # Safety
    ///
    /// - Behavior is undefined if `new_layout`'s size is zero.
    ///
    /// - Behavior is undefined if `ptr` is not a pointer to memory allocated by this allocator.
    ///
    /// - `old_layout` must be the same value that was used to allocate the memory buffer.
    NSTDAllocError (*reallocate)(NSTDAny, NSTDAnyMut *, NSTDAllocLayout, NSTDAllocLayout);
    /// Deallocates memory that was previously allocated by this allocator.
    ///
    /// # Parameters:
    ///
    /// - `NSTDAnyMut ptr` - A pointer to the allocated memory.
    ///
    /// - `NSTDAllocLayout layout` - Describes the layout of memory that `ptr` points to.
    ///
    /// # Returns
    ///
    /// `NSTDAllocError errc` - The allocation operation error code.
    ///
    /// # Safety
    ///
    /// - Behavior is undefined if `ptr` is not a pointer to memory allocated by this allocator.
    ///
    /// - `layout` must be the same value that was used to allocate the memory buffer.
    NSTDAllocError (*deallocate)(NSTDAny, NSTDAnyMut, NSTDAllocLayout);
} NSTDAllocator;

/// Creates a new memory layout from a size and alignment.
///
/// # Parameters:
///
/// - `NSTDUInt size` - The size of the memory block.
///
/// - `NSTDUInt align` - The alignment of the memory block.
///
/// # Returns
///
/// `NSTDOptionalAllocLayout layout` - The memory layout on success, or an uninitialized "none"
/// variant if either `size` is greater than `NSTDInt`'s max value or `align` is not a power of two.
NSTDAPI NSTDOptionalAllocLayout nstd_core_alloc_layout_new(NSTDUInt size, NSTDUInt align);

/// Creates a new memory layout from a size and alignment without performing safety checks.
///
/// # Parameters:
///
/// - `NSTDUInt size` - The size of the memory block.
///
/// - `NSTDUInt align` - The alignment of the memory block.
///
/// # Returns
///
/// `NSTDAllocLayout layout` - The memory layout.
///
/// # Safety
///
/// - `size` must not be greater than `NSTDInt`'s max value.
///
/// - `align` must be a nonzero power of two.
NSTDAPI NSTDAllocLayout nstd_core_alloc_layout_new_unchecked(NSTDUInt size, NSTDUInt align);

/// Creates a new memory layout for an array of elements.
///
/// # Parameters:
///
/// - `NSTDUInt size` - The size of each element in the array.
///
/// - `NSTDUInt align` - The alignment of each element in the array.
///
/// - `NSTDUInt len` - The length of the array to create a memory layout for.
///
/// # Returns
///
/// `NSTDOptionalAllocLayout layout` - The memory layout on success, or an uninitialized "none"
/// variant if the calculated size is greater than `NSTDInt`'s max value, `size` is not a multiple
/// of `align`, or `align` is not a power of two.
NSTDAPI NSTDOptionalAllocLayout
nstd_core_alloc_layout_array(NSTDUInt size, NSTDUInt align, NSTDUInt len);

/// Creates a new memory layout for an array of elements without performing safety checks.
///
/// # Parameters:
///
/// - `NSTDUInt size` - The size of each element in the array.
///
/// - `NSTDUInt align` - The alignment of each element in the array.
///
/// - `NSTDUInt len` - The length of the array to create a memory layout for.
///
/// # Returns
///
/// `NSTDAllocLayout layout` - The new memory layout.
///
/// # Panics
///
/// This operation will panic if `align` is 0.
///
/// # Safety
///
/// - `align` must be a power of two.
///
/// - `size` must be a multiple of `align`.
///
/// - The calculated size must not be greater than `NSTDInt`'s max value.
NSTDAPI NSTDAllocLayout
nstd_core_alloc_layout_array_unchecked(NSTDUInt size, NSTDUInt align, NSTDUInt len);

/// Returns the size of an `NSTDAllocLayout`.
///
/// # Parameters:
///
/// - `NSTDAllocLayout layout` - The memory layout.
///
/// # Returns
///
/// `NSTDUInt size` - The layout's size.
NSTDAPI NSTDUInt nstd_core_alloc_layout_size(NSTDAllocLayout layout);

/// Returns the alignment of an `NSTDAllocLayout`.
///
/// # Parameters:
///
/// - `NSTDAllocLayout layout` - The memory layout.
///
/// # Returns
///
/// `NSTDUInt align` - The layout's alignment.
NSTDAPI NSTDUInt nstd_core_alloc_layout_align(NSTDAllocLayout layout);

#endif