extern crate alloc;
use alloc::vec::Vec;
use core::cmp::Ordering;
use core::hint::unreachable_unchecked;
use core::mem::size_of;
use core::num::NonZeroUsize;
use crate::{NonEmptyMutSlice, NonEmptySlice};
pub struct NonEmptyVec<T: Sized> {
inner: Vec<T>,
}
const _SIZE: () = {
const FOO: [(); 1] = [()];
const SIZE: usize = size_of::<NonEmptyVec<&str>>();
#[cfg(target_pointer_width = "64")]
let idx = !(SIZE == 24) as usize;
#[cfg(target_pointer_width = "32")]
let idx = !(SIZE == 12) as usize;
FOO[idx]
};
const _BUILTIN_TRAITS: () = {
impl<T: Clone> Clone for NonEmptyVec<T> {
fn clone(&self) -> Self {
Self::from_vec(self.to_vec())
}
}
impl<T: Eq> Eq for NonEmptyVec<T> {}
impl<T: PartialEq> PartialEq for NonEmptyVec<T> {
fn eq(&self, other: &Self) -> bool {
self.as_slice().eq(other.as_slice())
}
}
impl<T: Ord> Ord for NonEmptyVec<T> {
fn cmp(&self, other: &Self) -> Ordering {
self.as_slice().cmp(other.as_slice())
}
}
impl<T: PartialOrd> PartialOrd for NonEmptyVec<T> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.as_slice().partial_cmp(other.as_slice())
}
}
impl<T> AsRef<[T]> for NonEmptyVec<T> {
fn as_ref(&self) -> &[T] {
self.as_slice()
}
}
};
impl<T: Sized> NonEmptyVec<T> {
pub fn from_vec(vec: Vec<T>) -> Self {
match Self::from_vec_checked(vec) {
Ok(v) => v,
Err(_) => panic!("vec shouldn't be empty"),
}
}
pub fn from_vec_checked(vec: Vec<T>) -> Result<Self, Vec<T>> {
if vec.is_empty() {
return Err(vec);
}
Ok(Self { inner: vec })
}
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_nonempty_slice(&self) -> NonEmptySlice<'_, T> {
NonEmptySlice { inner: &self.inner }
}
pub fn as_nonempty_mut_slice(&mut self) -> NonEmptyMutSlice<'_, T> {
NonEmptyMutSlice { inner: &mut self.inner }
}
pub fn as_slice(&self) -> &[T] {
self.inner.as_slice()
}
pub fn as_mut_slice(&mut self) -> &mut [T] {
self.inner.as_mut_slice()
}
pub fn len(&self) -> NonZeroUsize {
unsafe { NonZeroUsize::new_unchecked(self.inner.len()) }
}
pub fn is_empty(&self) -> bool {
false
}
pub fn capacity(&self) -> NonZeroUsize {
unsafe { NonZeroUsize::new_unchecked(self.inner.capacity()) }
}
pub fn into_vec(self) -> Vec<T> {
self.inner
}
pub fn to_vec(&self) -> Vec<T>
where
T: Clone,
{
self.as_slice().to_vec()
}
pub fn first(&self) -> &T {
match self.as_slice() {
[first, ..] => first,
[] => unsafe { unreachable_unchecked() },
}
}
pub fn first_mut(&mut self) -> &mut T {
match self.as_mut_slice() {
[first, ..] => first,
[] => unsafe { unreachable_unchecked() },
}
}
pub fn last(&self) -> &T {
match self.as_slice() {
[.., last] => last,
[] => unsafe { unreachable_unchecked() },
}
}
pub fn last_mut(&mut self) -> &mut T {
match self.as_mut_slice() {
[.., last] => last,
[] => unsafe { unreachable_unchecked() },
}
}
pub fn split_first(&self) -> (&T, &[T]) {
match self.as_slice() {
[first, rest @ ..] => (first, rest),
[] => unsafe { unreachable_unchecked() },
}
}
pub fn split_first_mut(&mut self) -> (&mut T, &mut [T]) {
match self.as_mut_slice() {
[first, rest @ ..] => (first, rest),
[] => unsafe { unreachable_unchecked() },
}
}
pub fn split_last(&self) -> (&T, &[T]) {
match self.as_slice() {
[rest @ .., last] => (last, rest),
[] => unsafe { unreachable_unchecked() },
}
}
pub fn split_last_mut(&mut self) -> (&mut T, &mut [T]) {
match self.as_mut_slice() {
[rest @ .., last] => (last, rest),
[] => unsafe { unreachable_unchecked() },
}
}
}