Skip to content

Commit

Permalink
Merge branch 'const-array-ctor'
Browse files Browse the repository at this point in the history
  • Loading branch information
agerasev committed Aug 16, 2024
2 parents 6a689ea + 7936744 commit 6f637f1
Show file tree
Hide file tree
Showing 6 changed files with 31 additions and 17 deletions.
7 changes: 4 additions & 3 deletions src/rb/local.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ struct End {
}

impl End {
fn new(index: usize) -> Self {
const fn new(index: usize) -> Self {
Self {
index: Cell::new(index),
held: Cell::new(false),
Expand All @@ -49,8 +49,9 @@ impl<S: Storage> LocalRb<S> {
///
/// The items in storage inside `read..write` range must be initialized, items outside this range must be uninitialized.
/// `read` and `write` positions must be valid (see implementation details).
pub unsafe fn from_raw_parts(storage: S, read: usize, write: usize) -> Self {
assert!(!storage.is_empty());
///
/// `storage` length must be non-zero.
pub const unsafe fn from_raw_parts(storage: S, read: usize, write: usize) -> Self {
Self {
storage,
read: End::new(read),
Expand Down
7 changes: 6 additions & 1 deletion src/rb/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@ macro_rules! rb_impl_init {
($type:ident) => {
impl<T, const N: usize> Default for $type<crate::storage::Array<T, N>> {
fn default() -> Self {
unsafe { Self::from_raw_parts(crate::utils::uninit_array().into(), usize::default(), usize::default()) }
Self::new()
}
}
impl<T, const N: usize> $type<crate::storage::Array<T, N>> {
pub const fn new() -> Self {
unsafe { Self::from_raw_parts(crate::storage::Array::new(crate::utils::uninit_array()), 0, 0) }
}
}

Expand Down
5 changes: 3 additions & 2 deletions src/rb/shared.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,9 @@ impl<S: Storage> SharedRb<S> {
///
/// The items in storage inside `read..write` range must be initialized, items outside this range must be uninitialized.
/// `read` and `write` positions must be valid (see implementation details).
pub unsafe fn from_raw_parts(storage: S, read: usize, write: usize) -> Self {
assert!(!storage.is_empty());
///
/// `storage` length must be non-zero.
pub const unsafe fn from_raw_parts(storage: S, read: usize, write: usize) -> Self {
Self {
storage,
read_index: CachePadded::new(AtomicUsize::new(read)),
Expand Down
5 changes: 5 additions & 0 deletions src/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,11 @@ pub struct Owning<T: ?Sized> {
unsafe impl<T: ?Sized> Sync for Owning<T> where T: Send {}
impl<T> From<T> for Owning<T> {
fn from(value: T) -> Self {
Self::new(value)
}
}
impl<T> Owning<T> {
pub const fn new(value: T) -> Self {
Self {
data: UnsafeCell::new(value),
}
Expand Down
3 changes: 3 additions & 0 deletions src/tests/new.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ use crate::{storage::Array, traits::*};
#[cfg(feature = "alloc")]
use alloc::vec::Vec;

#[allow(clippy::declare_interior_mutable_const)]
const _RB: Rb<Array<i32, 4>> = Rb::<Array<i32, 4>>::new();

#[test]
fn new_static() {
let rb = Rb::<Array<i32, 2>>::default();
Expand Down
21 changes: 10 additions & 11 deletions src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use core::{
};

// TODO: Remove on `maybe_uninit_uninit_array` stabilization.
pub fn uninit_array<T, const N: usize>() -> [MaybeUninit<T>; N] {
pub const fn uninit_array<T, const N: usize>() -> [MaybeUninit<T>; N] {
unsafe { MaybeUninit::<[MaybeUninit<T>; N]>::uninit().assume_init() }
}

Expand Down Expand Up @@ -39,21 +39,20 @@ pub fn move_uninit_slice<T>(dst: &mut [MaybeUninit<T>], src: &[MaybeUninit<T>])
}

pub fn array_to_uninit<T, const N: usize>(value: [T; N]) -> [MaybeUninit<T>; N] {
let value = mem::ManuallyDrop::new(value);
let ptr = &value as *const _ as *const [MaybeUninit<T>; N];
unsafe { ptr.read() }
let value = MaybeUninit::new(value);
let this = &value as *const _ as *const [MaybeUninit<T>; N];
unsafe { this.read() }
}

#[cfg(feature = "alloc")]
pub fn vec_to_uninit<T>(value: Vec<T>) -> Vec<MaybeUninit<T>> {
let value = mem::ManuallyDrop::new(value);
let ptr = &value as *const _ as *const Vec<MaybeUninit<T>>;
unsafe { ptr.read() }
pub fn vec_to_uninit<T>(mut value: Vec<T>) -> Vec<MaybeUninit<T>> {
let (ptr, len, cap) = (value.as_mut_ptr() as *mut MaybeUninit<T>, value.len(), value.capacity());
mem::forget(value);
unsafe { Vec::from_raw_parts(ptr, len, cap) }
}

#[cfg(feature = "alloc")]
pub fn boxed_slice_to_uninit<T>(value: Box<[T]>) -> Box<[MaybeUninit<T>]> {
let value = mem::ManuallyDrop::new(value);
let ptr = &value as *const _ as *const Box<[MaybeUninit<T>]>;
unsafe { ptr.read() }
let ptr = Box::into_raw(value) as *mut [MaybeUninit<T>];
unsafe { Box::from_raw(ptr) }
}

0 comments on commit 6f637f1

Please sign in to comment.