use core::cmp::Ordering;
use core::hint::unreachable_unchecked;
use core::mem::size_of;
use core::num::NonZeroUsize;
use core::slice;
pub struct NonEmptyMutSlice<'a, T: Sized> {
pub(crate) inner: &'a mut [T],
}
const _SIZE: () = {
const FOO: [(); 1] = [()];
const SIZE: usize = size_of::<NonEmptyMutSlice<'_, &str>>();
#[cfg(target_pointer_width = "64")]
let idx = !(SIZE == 16) as usize;
#[cfg(target_pointer_width = "32")]
let idx = !(SIZE == 8) as usize;
FOO[idx]
};
const _BUILTIN_TRAITS: () = {
impl<'a, T: Eq> Eq for NonEmptyMutSlice<'a, T> {}
impl<'a, T: PartialEq> PartialEq for NonEmptyMutSlice<'a, T> {
fn eq(&self, other: &Self) -> bool {
self.as_slice().eq(other.as_slice())
}
}
impl<'a, T: Ord> Ord for NonEmptyMutSlice<'a, T> {
fn cmp(&self, other: &Self) -> Ordering {
self.as_slice().cmp(other.as_slice())
}
}
impl<'a, T: PartialOrd> PartialOrd for NonEmptyMutSlice<'a, T> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.as_slice().partial_cmp(other.as_slice())
}
}
impl<'a, T> AsRef<[T]> for NonEmptyMutSlice<'a, T> {
fn as_ref(&self) -> &[T] {
self.as_slice()
}
}
};
impl<'a, T: Sized> NonEmptyMutSlice<'a, T> {
pub fn from_mut(e: &'a mut T) -> Self {
Self {
inner: slice::from_mut(e),
}
}
pub fn from_slice(slice: &'a mut [T]) -> Self {
Self::from_slice_checked(slice).expect("slice shouldn't be empty")
}
pub fn from_slice_checked(slice: &'a mut [T]) -> Option<Self> {
if slice.is_empty() {
return None;
}
Some(Self { inner: slice })
}
pub fn as_ptr(&self) -> *const T {
self.inner.as_ptr()
}
pub fn as_mut_ptr(&mut self) -> *mut T {
self.inner.as_mut_ptr()
}
pub fn as_slice(&self) -> &[T] {
self.inner
}
pub fn as_mut_slice(&mut self) -> &mut [T] {
self.inner
}
pub fn len(&self) -> NonZeroUsize {
unsafe { NonZeroUsize::new_unchecked(self.inner.len()) }
}
pub fn is_empty(&self) -> bool {
false
}
pub fn first(&self) -> &T {
match self.inner {
[ref first, ..] => first,
[] => unsafe { unreachable_unchecked() },
}
}
pub fn first_mut(&mut self) -> &mut T {
match self.inner {
[first, ..] => first,
[] => unsafe { unreachable_unchecked() },
}
}
pub fn last(&self) -> &T {
match self.inner {
[.., ref last] => last,
[] => unsafe { unreachable_unchecked() },
}
}
pub fn last_mut(&mut self) -> &mut T {
match self.inner {
[.., last] => last,
[] => unsafe { unreachable_unchecked() },
}
}
pub fn split_first(&self) -> (&T, &[T]) {
match self.inner {
[ref first, ref rest @ ..] => (first, rest),
[] => unsafe { unreachable_unchecked() },
}
}
pub fn split_first_mut(&mut self) -> (&mut T, &mut [T]) {
match self.inner {
[first, rest @ ..] => (first, rest),
[] => unsafe { unreachable_unchecked() },
}
}
pub fn split_last(&self) -> (&T, &[T]) {
match self.inner {
[ref rest @ .., ref last] => (last, rest),
[] => unsafe { unreachable_unchecked() },
}
}
pub fn split_last_mut(&mut self) -> (&mut T, &mut [T]) {
match self.inner {
[rest @ .., last] => (last, rest),
[] => unsafe { unreachable_unchecked() },
}
}
}