use std::num::NonZeroUsize;
use crate::non_empty_vec::*;
#[repr(transparent)]
#[derive(Hash)]
pub struct NonEmptySlice<T>(pub(crate) [T]);
impl<T> NonEmptySlice<T> {
#[inline]
pub const unsafe fn from_slice_unchecked(slice: &[T]) -> &NonEmptySlice<T> {
unsafe { std::mem::transmute(slice) }
}
#[inline]
pub unsafe fn from_slice_unchecked_mut(slice: &mut [T]) -> &mut NonEmptySlice<T> {
unsafe { std::mem::transmute(slice) }
}
#[inline]
pub const fn try_from_slice(slice: &[T]) -> Result<&NonEmptySlice<T>, &[T]> {
if slice.is_empty() {
Err(slice)
} else {
Ok(unsafe { NonEmptySlice::from_slice_unchecked(slice) })
}
}
#[inline]
pub fn try_from_slice_mut(slice: &mut [T]) -> Result<&mut NonEmptySlice<T>, &mut [T]> {
if slice.is_empty() {
Err(slice)
} else {
Ok(unsafe { NonEmptySlice::from_slice_unchecked_mut(slice) })
}
}
#[inline]
pub fn from_arr<const N: usize>(arr: &[T; N]) -> &NonEmptySlice<T> {
const { assert!(N > 0, "Length of array must be non-zero to create NonEmptySlice."); }
unsafe { NonEmptySlice::from_slice_unchecked(arr) }
}
#[inline]
pub const fn get_slice(&self) -> &[T] {
&self.0
}
#[inline]
pub fn get_slice_mut(&mut self) -> &mut [T] {
&mut self.0
}
#[inline]
pub const fn len(&self) -> NonZeroUsize {
unsafe { NonZeroUsize::new_unchecked(self.0.len()) }
}
#[inline]
pub const fn get_len(&self) -> usize {
self.len().get()
}
#[inline]
pub const fn has_just_1_element(&self) -> bool {
self.get_len() == 1
}
#[inline]
pub fn first(&self) -> &T {
unsafe { self.get_unchecked(0) }
}
#[inline]
pub fn first_mut(&mut self) -> &mut T {
unsafe { self.get_unchecked_mut(0) }
}
#[inline]
pub fn last(&self) -> &T {
unsafe { self.get_unchecked(self.get_len() - 1) }
}
#[inline]
pub fn last_mut(&mut self) -> &mut T {
let last_index = self.get_len() - 1;
unsafe { self.get_unchecked_mut(last_index) }
}
#[inline]
pub fn to_vec(&self) -> NonEmptyVec<T> where T: Clone {
NonEmptyVec(self.0.to_vec())
}
#[inline]
pub fn into_vec(self: Box<Self>) -> NonEmptyVec<T> {
let mut self_box = std::mem::ManuallyDrop::new(self);
let vec = unsafe { Vec::<T>::from_raw_parts(self_box.0.as_mut_ptr(), self_box.0.len(), self_box.0.len()) };
NonEmptyVec(vec)
}
#[inline]
pub fn repeat(&self, n: NonZeroUsize) -> NonEmptyVec<T> where T: Copy {
NonEmptyVec(self.0.repeat(n.get()))
}
}
impl<T> std::ops::Deref for NonEmptySlice<T> {
type Target = [T];
#[inline]
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T> std::ops::DerefMut for NonEmptySlice<T> {
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl<T: std::fmt::Debug> std::fmt::Debug for NonEmptySlice<T> {
#[inline]
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", &self.0)
}
}
impl<T> std::ops::Index<usize> for NonEmptySlice<T> {
type Output = T;
#[inline]
fn index(&self, index: usize) -> &Self::Output {
&self.0[index]
}
}
impl<T> std::ops::IndexMut<usize> for NonEmptySlice<T> {
#[inline]
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
&mut self.0[index]
}
}
impl<T> std::ops::Index<std::ops::RangeFull> for NonEmptySlice<T> {
type Output = NonEmptySlice<T>;
#[inline]
fn index(&self, _index: std::ops::RangeFull) -> &Self::Output {
self
}
}
impl<T> std::ops::IndexMut<std::ops::RangeFull> for NonEmptySlice<T> {
#[inline]
fn index_mut(&mut self, _index: std::ops::RangeFull) -> &mut Self::Output {
self
}
}
impl<T> std::ops::Index<std::ops::RangeToInclusive<usize>> for NonEmptySlice<T> {
type Output = NonEmptySlice<T>;
#[inline]
fn index(&self, index: std::ops::RangeToInclusive<usize>) -> &Self::Output {
unsafe { NonEmptySlice::from_slice_unchecked(&self.0[index]) }
}
}
impl<T> std::ops::IndexMut<std::ops::RangeToInclusive<usize>> for NonEmptySlice<T> {
#[inline]
fn index_mut(&mut self, index: std::ops::RangeToInclusive<usize>) -> &mut Self::Output {
unsafe { NonEmptySlice::from_slice_unchecked_mut(&mut self.0[index]) }
}
}
impl<'a, T> TryFrom<&'a [T]> for &'a NonEmptySlice<T> {
type Error = &'a [T];
fn try_from(slice: &'a [T]) -> Result<Self, Self::Error> {
NonEmptySlice::try_from_slice(slice)
}
}
impl<'a, T> TryFrom<&'a mut [T]> for &'a NonEmptySlice<T> {
type Error = &'a mut [T];
fn try_from(slice: &'a mut [T]) -> Result<Self, Self::Error> {
NonEmptySlice::try_from_slice_mut(slice).map(|x| &*x)
}
}
impl<'a, T> TryFrom<&'a mut [T]> for &'a mut NonEmptySlice<T> {
type Error = &'a mut [T];
fn try_from(slice: &'a mut [T]) -> Result<Self, Self::Error> {
NonEmptySlice::try_from_slice_mut(slice)
}
}
impl<'a, T> From<&'a NonEmptySlice<T>> for &'a [T] {
fn from(non_empty_slice: &'a NonEmptySlice<T>) -> &'a [T] {
non_empty_slice
}
}
impl<'a, T> From<&'a mut NonEmptySlice<T>> for &'a [T] {
fn from(non_empty_slice: &'a mut NonEmptySlice<T>) -> &'a [T] {
non_empty_slice
}
}
impl<'a, T> From<&'a mut NonEmptySlice<T>> for &'a mut [T] {
fn from(non_empty_slice: &'a mut NonEmptySlice<T>) -> &'a mut [T] {
non_empty_slice
}
}
impl<'a, T: Clone, const N: usize> From<&'a [T; N]> for &'a NonEmptySlice<T> {
#[inline]
fn from(value: &'a [T; N]) -> Self {
NonEmptySlice::from_arr(value)
}
}