Skip to content

Commit

Permalink
abox_convert_alloc_global_oom: many oomy From<...>s
Browse files Browse the repository at this point in the history
  • Loading branch information
MaulingMonkey committed May 23, 2023
1 parent 66c5205 commit fdb1846
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/boxed/_boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ mod abox_alloc;
mod abox_bytemuck;
mod abox_clone;
mod abox_cmp;
mod abox_convert_alloc_global_oom;
mod abox_convert_infallible_;
mod abox_convert_infallible_alloc;
mod abox_convert_infallible_std;
Expand Down
93 changes: 93 additions & 0 deletions src/boxed/abox_convert_alloc_global_oom.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
#![cfg(global_oom_handling)]

use crate::boxed::ABox;
use crate::meta::*;
use crate::fat::*;
use crate::util;
use crate::vec::AVec;

use core::ffi::CStr;
use core::ptr::NonNull;



impl<T: Copy, A: Alloc + Free + Default + ZstSupported> From<&[T]> for ABox<[T], A> {
fn from(value: &[T]) -> Self {
let len : usize = value.len();
let mut b = ABox::<T, A>::new_uninit_slice(len);
unsafe { core::ptr::copy_nonoverlapping(value.as_ptr(), b.as_mut_ptr().cast(), len) };
unsafe { b.assume_init() }
}
}

impl<A: Alloc + Free + Default + ZstSupported> From<&CStr> for ABox<CStr, A> {
fn from(value: &CStr) -> Self {
let bytes = value.to_bytes_with_nul();
let len = bytes.len();
let mut b = ABox::<u8, A>::new_uninit_slice(len);
unsafe { core::ptr::copy_nonoverlapping(value.as_ptr(), b.as_mut_ptr().cast(), len) };
let (data, allocator) = ABox::into_raw_with_allocator(b);
unsafe { ABox::from_raw_in(NonNull::new_unchecked(data.as_ptr() as *mut CStr), allocator) }
}
}

impl<A: Alloc + Free + Default + ZstSupported> From<&str> for ABox<str, A> {
fn from(value: &str) -> Self {
let bytes = value.as_bytes();
let len = bytes.len();
let mut b = ABox::<u8, A>::new_uninit_slice(len);
unsafe { core::ptr::copy_nonoverlapping(value.as_ptr(), b.as_mut_ptr().cast(), len) };
let (data, allocator) = ABox::into_raw_with_allocator(b);
unsafe { ABox::from_raw_in(NonNull::new_unchecked(data.as_ptr() as *mut str), allocator) }
}
}


impl<T, A: Alloc + Free + Default + ZstSupported, const N : usize> From<[T; N]> for ABox<[T], A> {
fn from(value: [T; N]) -> Self {
let mut b = ABox::<T, A>::new_uninit_slice(N);
unsafe { core::ptr::copy_nonoverlapping(value.as_ptr(), b.as_mut_ptr().cast(), N) };
core::mem::forget(value);
let (data, allocator) = ABox::into_raw_with_allocator(b);
let data = util::nn::slice_assume_init(data);
unsafe { ABox::from_raw_in(data, allocator) }
}
}

impl<T, A: Alloc + Free + Default > From <T > for ABox<T, A> { fn from(value: T) -> Self { Self::new(value) } }
impl<T, A: Realloc > From <AVec<T, A> > for ABox<[T], A> { fn from(value: AVec<T, A>) -> Self { value.into_boxed_slice() } }
// TODO: impl<T, A: Free, const N: usize> TryFrom<ABox<[T], A> > for ABox<[T; N], A> !Alloc
// TODO: impl<T, A: Free, const N: usize> TryFrom<AVec<T, A> > for ABox<[T; N], A> Shrink to fit

#[cfg(feature = "alloc")] mod alloc {
use crate::allocator::alloc::Global;
use super::*;

use ::alloc::borrow::Cow;
use ::alloc::boxed::Box;
use ::alloc::string::String;
use ::alloc::vec::Vec;

impl<T: Copy, A: Free + From<Global>> From<Cow<'_, [T] >> for ABox<[T], A> { fn from(value: Cow<'_, [T] >) -> Self { Self::from(Box::<[T] >::from(value)) } }
impl< A: Free + From<Global>> From<Cow<'_, CStr >> for ABox<CStr, A> { fn from(value: Cow<'_, CStr >) -> Self { Self::from(Box::<CStr >::from(value)) } }
impl< A: Free + From<Global>> From<Cow<'_, str >> for ABox<str, A> { fn from(value: Cow<'_, str >) -> Self { Self::from(Box::<str >::from(value)) } }
impl< A: Free + From<Global>> From<String > for ABox<str, A> { fn from(value: String ) -> Self { Self::from(Box::<str >::from(value)) } }
impl<T, A: Free + From<Global>> From<Vec<T> > for ABox<[T], A> { fn from(value: Vec<T> ) -> Self { Self::from(Box::<[T] >::from(value)) } }

// TODO: impl<T, A: Free + From<Global>, const N: usize> impl TryFrom<Box<[T]> > for ABox<[T; N], A> !Alloc
// TODO: impl<T, A: Free + From<Global>, const N: usize> impl TryFrom<Vec<T> > for ABox<[T; N], A> Shrink to fit
}

#[cfg(feature = "std")] mod std {
// TODO: impl From<&OsStr> for ABox<OsStr, A> - layout underspecified?
// TODO: impl From<&Path > for ABox<Path, A> - layout underspecified?

// TODO: impl From<&str> for ABox<dyn Error + ..., A>

// TODO: impl From<Cow<'_, OsStr> > for ABox<OsStr, A>
// TODO: impl From<Cow<'_, Path > > for ABox<Path, A>
// TODO: impl From<Cow<'_, str> > for ABox<dyn Error + ..., A>
// TODO: impl From<impl Error > for ABox<dyn Error + ..., A>
// TODO: impl From<OsString > for ABox<OsStr, A>
// TODO: impl From<PathBuf > for ABox<Path, A>
}
8 changes: 8 additions & 0 deletions src/util/nn.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//! [`NonNull`]-related utilities

use core::alloc::Layout;
use core::mem::MaybeUninit;
use core::ptr::NonNull;


Expand All @@ -12,6 +13,13 @@ pub /*const*/ fn slice_from_raw_parts<T>(data: NonNull<T>, len: usize) -> NonNul
unsafe { NonNull::new_unchecked(slice) }
}

pub /*const*/ fn slice_assume_init<T>(data: NonNull<[MaybeUninit<T>]>) -> NonNull<[T]> {
let len = data.len();
let ptr = data.as_ptr() as *mut MaybeUninit<T>;
let ptr = unsafe { NonNull::new_unchecked(ptr.cast()) };
slice_from_raw_parts(ptr, len)
}

pub fn dangling<T>(layout: Layout) -> NonNull<T> {
NonNull::new(layout.align() as _).unwrap_or(NonNull::dangling())
}

0 comments on commit fdb1846

Please sign in to comment.