Fix const fns that were not const and add const ArrayVec::from

This commit is contained in:
Michael Pfaff 2024-03-15 20:35:12 -04:00
parent 01b794e81a
commit 7a6edb2cc1
1 changed files with 55 additions and 11 deletions

View File

@ -6,6 +6,7 @@
#![feature(const_mut_refs)]
#![feature(const_option)]
#![feature(const_refs_to_cell)]
#![feature(const_slice_from_raw_parts_mut)]
#![feature(const_slice_split_at_mut)]
#![feature(const_trait_impl)]
#![feature(effects)]
@ -23,7 +24,6 @@ use std::fmt::{Debug, Display};
use std::hash::Hash;
use std::mem::MaybeUninit;
use std::ops::{Deref, DerefMut};
use std::slice::SliceIndex;
#[derive(Copy)]
pub struct ArrayVec<T, const N: usize> {
@ -36,6 +36,32 @@ pub struct ArrayVec<T, const N: usize> {
// pub const EMPTY: ArrayVec<T, 0> = Self::new();
// }
#[inline(always)]
const unsafe fn slice_unchecked<T>(slice: &[T], offset: usize, len: Option<usize>) -> &[T] {
std::slice::from_raw_parts(
slice.as_ptr().add(offset),
match len {
Some(t) => t,
None => slice.len() - offset,
},
)
}
#[inline(always)]
const unsafe fn slice_unchecked_mut<T>(
slice: &mut [T],
offset: usize,
len: Option<usize>,
) -> &mut [T] {
std::slice::from_raw_parts_mut(
slice.as_mut_ptr().add(offset),
match len {
Some(t) => t,
None => slice.len() - offset,
},
)
}
impl<T, const N: usize> ArrayVec<T, N> {
#[inline]
pub const fn new() -> Self {
@ -48,14 +74,19 @@ impl<T, const N: usize> ArrayVec<T, N> {
#[inline]
pub const fn as_slice(&self) -> &[T] {
unsafe {
MaybeUninit::slice_assume_init_ref(&*(0..self.len).get_unchecked(self.data.as_slice()))
MaybeUninit::slice_assume_init_ref(slice_unchecked(&self.data, 0, Some(self.len)))
}
}
#[inline]
pub const fn as_slice_mut(&mut self) -> &mut [T] {
let slice: &mut [MaybeUninit<T>] = &mut self.data;
unsafe { MaybeUninit::slice_assume_init_mut(&mut *(0..self.len).get_unchecked_mut(slice)) }
unsafe {
MaybeUninit::slice_assume_init_mut(slice_unchecked_mut(
&mut self.data,
0,
Some(self.len),
))
}
}
#[inline]
@ -85,13 +116,12 @@ impl<T, const N: usize> ArrayVec<T, N> {
#[inline(always)]
pub const fn unused(&self) -> &[MaybeUninit<T>] {
unsafe { &*(self.len..).get_unchecked(self.data.as_slice()) }
unsafe { slice_unchecked(&self.data, self.len, None) }
}
#[inline(always)]
pub const fn unused_mut(&mut self) -> &mut [MaybeUninit<T>] {
let slice: &mut [MaybeUninit<T>] = &mut self.data;
unsafe { &mut *(self.len..).get_unchecked_mut(slice) }
unsafe { slice_unchecked_mut(&mut self.data, self.len, None) }
}
/// # Safety
@ -121,6 +151,14 @@ impl<T, const N: usize> ArrayVec<T, N> {
self.set_len(old_len + slice.len());
}
}
#[inline]
pub const fn from(value: [T; N]) -> Self {
Self {
len: value.len(),
data: MaybeUninit::transpose(MaybeUninit::new(value)),
}
}
}
impl<T: Clone, const N: usize> Clone for ArrayVec<T, N> {
@ -352,10 +390,7 @@ impl<const N: usize> Display for ArrayStr<N> {
impl<T, const N: usize> From<[T; N]> for ArrayVec<T, N> {
#[inline]
fn from(value: [T; N]) -> Self {
Self {
len: value.len(),
data: MaybeUninit::transpose(MaybeUninit::new(value)),
}
Self::from(value)
}
}
@ -488,3 +523,12 @@ impl<'a, const N: usize> TryFrom<char> for ArrayStr<N> {
// ArrayStr(self.0.concat(rhs.0))
// }
// }
#[cfg(test)]
mod tests {
use crate::ArrayVec;
const _FOO: ArrayVec<(), 4> = ArrayVec::from([(), (), (), ()]);
const _FOO_LEN: usize = _FOO.as_slice().len();
const _FOO_UNUSED: usize = _FOO.unused().len();
}