use core::{
num::NonZeroUsize,
ops::{Deref, DerefMut},
slice,
};
use crate::{NonEmpty, Slice};
impl<T> Eq for NonEmpty<[T]> where T: Eq {}
macro_rules! forward {
($($(#[$meta:meta])* pub const fn $ident:ident(&self) -> $ty:ty);* $(;)?) => {
$(
$(#[$meta])*
pub const fn $ident(&self) -> $ty {
match self.as_slice().$ident() {
Some(it) => it,
None => unsafe { crate::unreachable() },
}
}
)*
}
}
macro_rules! forward_mut {
($($(#[$meta:meta])* pub fn $ident:ident(&mut self) -> $ty:ty);* $(;)?) => {
$(
$(#[$meta])*
pub fn $ident(&mut self) -> $ty {
match self.as_mut_slice().$ident() {
Some(it) => it,
None => unsafe { crate::unreachable() },
}
}
)*
}
}
impl<T> Slice<T> {
crate::map_non_empty! {
const
new(&[T]) -> &Self: Self::new_unchecked;
new_mut(&mut [T]) -> &mut Self: Self::new_mut_unchecked;
}
crate::transmuting! {
const
new_unchecked(&[T]) -> &Self;
new_mut_unchecked(&mut [T]) -> &mut Self;
}
pub const fn of(item: &T) -> &Self {
let shared = slice::from_ref(item);
unsafe { Self::new_unchecked(shared) }
}
pub fn of_mut(item: &mut T) -> &mut Self {
let shared = slice::from_mut(item);
unsafe { Self::new_mut_unchecked(shared) }
}
const fn check(&self) {
debug_assert!(!self.inner.is_empty());
}
pub const fn as_slice(&self) -> &[T] {
self.check();
&self.inner
}
pub fn as_mut_slice(&mut self) -> &mut [T] {
self.check();
&mut self.inner
}
pub const fn len_ne(&self) -> NonZeroUsize {
unsafe { crate::non_zero_usize(self.inner.len()) }
}
forward! {
pub const fn first(&self) -> &T;
pub const fn split_first(&self) -> (&T, &[T]);
pub const fn split_last(&self) -> (&T, &[T]);
pub const fn last(&self) -> &T;
}
forward_mut! {
pub fn first_mut(&mut self) -> &mut T ;
pub fn split_first_mut(&mut self) -> (&mut T, &mut [T]);
pub fn split_last_mut(&mut self) -> (&mut T, &mut [T]);
pub fn last_mut(&mut self) -> &mut T;
}
}
impl<T> Slice<T> {
pub fn iter_ne(&self) -> NonEmpty<core::slice::Iter<T>> {
NonEmpty { inner: self.iter() }
}
pub fn iter_mut_ne(&mut self) -> NonEmpty<core::slice::IterMut<'_, T>> {
NonEmpty {
inner: self.iter_mut(),
}
}
#[cfg(feature = "alloc")]
#[cfg_attr(do_doc_cfg, doc(cfg(feature = "alloc")))]
pub fn into_iter_ne(self: alloc::boxed::Box<Self>) -> NonEmpty<alloc::vec::IntoIter<T>> {
crate::Vec::from(self).into_iter_ne()
}
}
impl<T> Deref for Slice<T> {
type Target = [T];
fn deref(&self) -> &Self::Target {
self.as_slice()
}
}
impl<T> DerefMut for Slice<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
self.as_mut_slice()
}
}
crate::as_ref_as_mut! {
<T> for Slice<T> as [T];
<T> for Slice<T> as Self;
}
crate::borrow_borrow_mut! {
<T> for Slice<T> as [T];
}
crate::slice_iter! {
<T> for Slice<T>
}
#[cfg(feature = "alloc")]
#[cfg_attr(do_doc_cfg, doc(cfg(feature = "alloc")))]
impl<T> IntoIterator for alloc::boxed::Box<Slice<T>> {
type Item = T;
type IntoIter = alloc::vec::IntoIter<T>;
fn into_iter(self) -> Self::IntoIter {
crate::Vec::<T>::from(self).into_iter()
}
}
#[cfg(feature = "alloc")]
#[cfg_attr(do_doc_cfg, doc(cfg(feature = "alloc")))]
impl<T> alloc::borrow::ToOwned for Slice<T>
where
T: Clone,
{
type Owned = crate::Vec<T>;
fn to_owned(&self) -> Self::Owned {
self.into()
}
}
mod partial_eq_std {
use super::*;
impl<T, U> PartialEq<[U]> for Slice<T>
where
T: PartialEq<U>,
{
fn eq(&self, other: &[U]) -> bool {
<[_] as PartialEq<[_]>>::eq(self, other)
}
}
impl<T, U, const N: usize> PartialEq<[U; N]> for Slice<T>
where
T: PartialEq<U>,
{
fn eq(&self, other: &[U; N]) -> bool {
<[_] as PartialEq<[_]>>::eq(self, other)
}
}
#[cfg(feature = "alloc")]
#[cfg_attr(do_doc_cfg, doc(cfg(feature = "alloc")))]
impl<T, U> PartialEq<alloc::vec::Vec<U>> for Slice<T>
where
T: PartialEq<U>,
{
fn eq(&self, other: &alloc::vec::Vec<U>) -> bool {
<[_] as PartialEq<[_]>>::eq(self, other)
}
}
impl<T, U> PartialEq<Slice<T>> for [U]
where
U: PartialEq<T>,
{
fn eq(&self, other: &Slice<T>) -> bool {
<[_] as PartialEq<[_]>>::eq(self, other)
}
}
impl<T, U, const N: usize> PartialEq<Slice<T>> for [U; N]
where
U: PartialEq<T>,
{
fn eq(&self, other: &Slice<T>) -> bool {
<[_] as PartialEq<[_]>>::eq(self, other)
}
}
#[cfg(feature = "alloc")]
#[cfg_attr(do_doc_cfg, doc(cfg(feature = "alloc")))]
impl<T, U> PartialEq<Slice<T>> for alloc::vec::Vec<U>
where
U: PartialEq<T>,
{
fn eq(&self, other: &Slice<T>) -> bool {
<[_] as PartialEq<[_]>>::eq(self, other)
}
}
}
mod cmp_std {
use core::cmp::Ordering;
use super::*;
impl<T> PartialOrd<[T]> for Slice<T>
where
T: PartialOrd,
{
fn partial_cmp(&self, other: &[T]) -> Option<Ordering> {
<[_] as PartialOrd<[_]>>::partial_cmp(self, other)
}
}
impl<T, const N: usize> PartialOrd<[T; N]> for Slice<T>
where
T: PartialOrd,
{
fn partial_cmp(&self, other: &[T; N]) -> Option<Ordering> {
<[_] as PartialOrd<[_]>>::partial_cmp(self, other)
}
}
#[cfg(feature = "alloc")]
#[cfg_attr(do_doc_cfg, doc(cfg(feature = "alloc")))]
impl<T> PartialOrd<alloc::vec::Vec<T>> for Slice<T>
where
T: PartialOrd,
{
fn partial_cmp(&self, other: &alloc::vec::Vec<T>) -> Option<Ordering> {
<[_] as PartialOrd<[_]>>::partial_cmp(self, other)
}
}
impl<T> PartialOrd<Slice<T>> for [T]
where
T: PartialOrd,
{
fn partial_cmp(&self, other: &Slice<T>) -> Option<Ordering> {
<[_] as PartialOrd<[_]>>::partial_cmp(self, other)
}
}
impl<T, const N: usize> PartialOrd<Slice<T>> for [T; N]
where
T: PartialOrd,
{
fn partial_cmp(&self, other: &Slice<T>) -> Option<Ordering> {
<[_] as PartialOrd<[_]>>::partial_cmp(self, other)
}
}
#[cfg(feature = "alloc")]
#[cfg_attr(do_doc_cfg, doc(cfg(feature = "alloc")))]
impl<T> PartialOrd<Slice<T>> for alloc::vec::Vec<T>
where
T: PartialOrd,
{
fn partial_cmp(&self, other: &Slice<T>) -> Option<Ordering> {
<[_] as PartialOrd<[_]>>::partial_cmp(self, other)
}
}
}
#[cfg(feature = "alloc")]
#[cfg_attr(do_doc_cfg, doc(cfg(feature = "alloc")))]
impl<T> Clone for alloc::boxed::Box<Slice<T>>
where
T: Clone,
{
fn clone(&self) -> Self {
let src = self.to_vec();
unsafe { crate::Vec::new_unchecked(src) }.into_boxed_slice()
}
}
mod convert_std {
#[cfg(feature = "alloc")]
use alloc::boxed::Box;
use crate::Error;
use super::*;
impl<'a, T> TryFrom<&'a [T]> for &'a Slice<T> {
type Error = Error;
fn try_from(value: &'a [T]) -> Result<Self, Self::Error> {
Slice::new(value).ok_or(Error(()))
}
}
impl<'a, T> TryFrom<&'a mut [T]> for &'a mut Slice<T> {
type Error = Error;
fn try_from(value: &'a mut [T]) -> Result<Self, Self::Error> {
Slice::new_mut(value).ok_or(Error(()))
}
}
#[cfg(feature = "alloc")]
#[cfg_attr(do_doc_cfg, doc(cfg(feature = "alloc")))]
impl<T> TryFrom<Box<[T]>> for Box<Slice<T>> {
type Error = Error;
fn try_from(value: Box<[T]>) -> Result<Self, Self::Error> {
match crate::Vec::new(value.into_vec()) {
Ok(it) => Ok(it.into_boxed_slice()),
Err(_) => Err(Error(())),
}
}
}
impl<'a, T> From<&'a Slice<T>> for &'a [T] {
fn from(value: &'a Slice<T>) -> Self {
value.as_slice()
}
}
impl<'a, T> From<&'a mut Slice<T>> for &'a mut [T] {
fn from(value: &'a mut Slice<T>) -> Self {
value.as_mut_slice()
}
}
#[cfg(feature = "alloc")]
#[cfg_attr(do_doc_cfg, doc(cfg(feature = "alloc")))]
impl<T> From<Box<Slice<T>>> for Box<[T]> {
fn from(value: Box<Slice<T>>) -> Self {
crate::Vec::from(value).into_vec().into_boxed_slice()
}
}
}