osom_alloc_std/
lib.rs

1//! This crate provides [`StdAllocator`] struct with the standard
2//! [`Allocator`][`osom_alloc::Allocator`] implementation.
3//!
4//! This crate is `#![no_std]`, however it does use
5//!
6//! ```rust
7//! extern crate alloc;
8//! ```
9//!
10//! external dependency.
11#![deny(warnings)]
12#![warn(clippy::all, clippy::pedantic)]
13#![allow(clippy::inline_always)]
14#![no_std]
15
16extern crate alloc;
17
18use core::{alloc::Layout, ptr::NonNull};
19
20use osom_alloc::{AllocationError, Allocator};
21
22/// The default implementation of [`Allocator`] trait,
23/// that calls standard [`alloc`] crate under the hood.
24#[derive(Debug, Default, Clone, Copy)]
25#[repr(C)]
26pub struct StdAllocator;
27
28unsafe impl Allocator for StdAllocator {
29    type SpecificAllocationError = AllocationError;
30
31    #[inline]
32    fn allocate(&self, layout: Layout) -> Result<NonNull<u8>, Self::SpecificAllocationError> {
33        let ptr = unsafe { alloc::alloc::alloc(layout) };
34        if ptr.is_null() {
35            return Err(AllocationError);
36        }
37        let ptr = unsafe { NonNull::new_unchecked(ptr) };
38        Ok(ptr)
39    }
40
41    #[inline(always)]
42    unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
43        unsafe { alloc::alloc::dealloc(ptr.as_ptr(), layout) };
44    }
45
46    #[inline]
47    unsafe fn resize(
48        &self,
49        ptr: NonNull<u8>,
50        old_layout: Layout,
51        new_layout: Layout,
52    ) -> Result<NonNull<u8>, Self::SpecificAllocationError> {
53        unsafe {
54            let new_ptr = if old_layout.align() == new_layout.align() {
55                let new_ptr = alloc::alloc::realloc(ptr.as_ptr(), old_layout, new_layout.size());
56                if new_ptr.is_null() {
57                    return Err(AllocationError);
58                }
59                NonNull::new_unchecked(new_ptr)
60            } else {
61                let new_ptr = self.allocate(new_layout)?;
62                new_ptr.copy_from_nonoverlapping(ptr, new_layout.size());
63                self.deallocate(ptr, old_layout);
64                new_ptr
65            };
66
67            Ok(new_ptr)
68        }
69    }
70}