mirror of
https://github.com/Noratrieb/vechonk.git
synced 2026-01-14 16:45:10 +01:00
alloc/dealloc
This commit is contained in:
parent
0764c02fa5
commit
b6cd4a1d06
3 changed files with 102 additions and 6 deletions
|
|
@ -1,2 +1,3 @@
|
||||||
[toolchain]
|
[toolchain]
|
||||||
channel = "nightly-2021-12-19"
|
channel = "nightly-2021-12-19"
|
||||||
|
components = ["miri"]
|
||||||
83
src/lib.rs
83
src/lib.rs
|
|
@ -1,5 +1,6 @@
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![feature(ptr_metadata, ptr_internals)]
|
#![feature(ptr_metadata)]
|
||||||
|
#![deny(unsafe_op_in_unsafe_fn)]
|
||||||
|
|
||||||
//!
|
//!
|
||||||
//! A `Vec<T: ?Sized>`
|
//! A `Vec<T: ?Sized>`
|
||||||
|
|
@ -32,15 +33,85 @@
|
||||||
//! |_________________________________________|
|
//! |_________________________________________|
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
|
mod test;
|
||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|
||||||
|
use core::alloc::Layout;
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
use core::ptr::{NonNull};
|
use core::num::NonZeroUsize;
|
||||||
use alloc::vec::Vec;
|
use core::ptr::NonNull;
|
||||||
|
|
||||||
/// chonky af
|
/// chonky af
|
||||||
struct Vechonk<T: ?Sized> {
|
///
|
||||||
size: usize,
|
/// only works for copy types, but this is WIP and will be removed
|
||||||
|
pub struct Vechonk<T: ?Sized + Copy> {
|
||||||
|
ptr: NonNull<u8>,
|
||||||
|
len: usize,
|
||||||
cap: usize,
|
cap: usize,
|
||||||
ptrs: Vec<NonNull<T>>
|
_marker: PhantomData<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: ?Sized + Copy> Vechonk<T> {
|
||||||
|
pub fn len(&self) -> usize {
|
||||||
|
self.len
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
// SAFETY: 1 is not 0
|
||||||
|
ptr: unsafe { NonNull::new_unchecked(1 as *mut u8) },
|
||||||
|
len: 0,
|
||||||
|
cap: 0,
|
||||||
|
_marker: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_capacity(capacity: usize) -> Self {
|
||||||
|
let mut vechonk = Self::new();
|
||||||
|
|
||||||
|
if capacity == 0 {
|
||||||
|
return vechonk;
|
||||||
|
}
|
||||||
|
|
||||||
|
// SAFETY: capacity has been checked to not be 0 and the len is 0
|
||||||
|
unsafe {
|
||||||
|
vechonk.grow_to(NonZeroUsize::new_unchecked(capacity));
|
||||||
|
}
|
||||||
|
vechonk
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Grows the `Vechonk` to a new capacity. This will not copy any elements. This will put the `Vechonk`
|
||||||
|
/// into an invalid state, since the `len` is still the length of the old allocation.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
/// The caller must either set the `len` to zero, or copy the elements to the new allocation by saving
|
||||||
|
/// `self.ptr` before calling this function.
|
||||||
|
unsafe fn grow_to(&mut self, size: NonZeroUsize) {
|
||||||
|
// SAFETY: 1 is not 0 and a power of two. `size > usize::MAX` must always be true
|
||||||
|
let layout = unsafe { Layout::from_size_align_unchecked(size.get(), 1) };
|
||||||
|
|
||||||
|
// SAFETY: layout is guaranteed to have a non-zero size
|
||||||
|
let alloced_ptr = unsafe { alloc::alloc::alloc(layout) };
|
||||||
|
|
||||||
|
self.ptr =
|
||||||
|
NonNull::new(alloced_ptr).unwrap_or_else(|| alloc::alloc::handle_alloc_error(layout));
|
||||||
|
|
||||||
|
self.cap = size.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// we can only drop copy for now because destructors 🤮
|
||||||
|
impl<T: ?Sized + Copy> Drop for Vechonk<T> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
if self.cap == 0 {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// SAFETY: 1 is not 0 and a power of two. `size > usize::MAX` must always be true
|
||||||
|
let layout = unsafe { Layout::from_size_align_unchecked(self.cap, 1) };
|
||||||
|
|
||||||
|
unsafe { alloc::alloc::dealloc(self.ptr.as_ptr(), layout) };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
24
src/test.rs
Normal file
24
src/test.rs
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
#![cfg(test)]
|
||||||
|
|
||||||
|
use crate::Vechonk;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn new() {
|
||||||
|
let chonk = Vechonk::<()>::new();
|
||||||
|
|
||||||
|
assert_eq!(chonk.len(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn zero_capacity() {
|
||||||
|
let chonk = Vechonk::<()>::with_capacity(0);
|
||||||
|
|
||||||
|
assert_eq!(chonk.len(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn some_capacity() {
|
||||||
|
let chonk = Vechonk::<()>::with_capacity(100);
|
||||||
|
|
||||||
|
assert_eq!(chonk.len(), 0);
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue