use ambassador::delegatable_trait;
use impl_tools::autoimpl;
use std::borrow::Borrow;
use super::iter::BidiIterator;
use crate::{debug_assert_bounds, panic_if_out_of_bounds};
#[autoimpl(for<T: trait + ?Sized> &T, &mut T, Box<T>)]
#[delegatable_trait]
pub trait Types {
type Input: for<'a> PartialEq<Self::Output<'a>> + PartialEq + ?Sized;
type Output<'a>: PartialEq<Self::Input> + PartialEq;
}
#[autoimpl(for<T: trait + ?Sized> &T, &mut T, Box<T>)]
#[delegatable_trait]
pub trait IndexedSeq: Types {
fn get(&self, index: usize) -> Self::Output<'_> {
panic_if_out_of_bounds!(index, self.len());
unsafe { self.get_unchecked(index) }
}
unsafe fn get_unchecked(&self, index: usize) -> Self::Output<'_>;
fn len(&self) -> usize;
fn is_empty(&self) -> bool {
self.len() == 0
}
fn first_value(&self) -> Option<Self::Output<'_>> {
if self.is_empty() {
None
} else {
Some(unsafe { self.get_unchecked(0) })
}
}
fn last_value(&self) -> Option<Self::Output<'_>> {
if self.is_empty() {
None
} else {
Some(unsafe { self.get_unchecked(self.len() - 1) })
}
}
}
#[autoimpl(for<T: trait + ?Sized> &T, &mut T, Box<T>)]
#[delegatable_trait]
pub trait IndexedDict: Types {
fn index_of(&self, value: impl Borrow<Self::Input>) -> Option<usize>;
fn contains(&self, value: impl Borrow<Self::Input>) -> bool {
self.index_of(value).is_some()
}
}
pub trait SuccUnchecked: Types
where
Self::Input: for<'a> PartialOrd<Self::Output<'a>> + PartialOrd,
for<'a> Self::Output<'a>: PartialOrd<Self::Input> + PartialOrd,
{
type Iter<'a>: Iterator<Item = Self::Output<'a>>
where
Self: 'a;
type BidiIter<'a>: BidiIterator<Item = Self::Output<'a>>
where
Self: 'a;
unsafe fn succ_unchecked<const STRICT: bool>(
&self,
value: impl Borrow<Self::Input>,
) -> (usize, Self::Output<'_>);
unsafe fn iter_from_succ_unchecked<const STRICT: bool>(
&self,
value: impl Borrow<Self::Input>,
) -> (usize, Self::Iter<'_>);
unsafe fn iter_bidi_from_succ_unchecked<const STRICT: bool>(
&self,
value: impl Borrow<Self::Input>,
) -> (usize, Self::BidiIter<'_>);
}
impl<T: SuccUnchecked + ?Sized> SuccUnchecked for &T
where
T::Input: for<'a> PartialOrd<T::Output<'a>> + PartialOrd,
for<'a> T::Output<'a>: PartialOrd<T::Input> + PartialOrd,
{
type Iter<'a>
= T::Iter<'a>
where
Self: 'a;
type BidiIter<'a>
= T::BidiIter<'a>
where
Self: 'a;
#[inline(always)]
unsafe fn succ_unchecked<const STRICT: bool>(
&self,
value: impl Borrow<Self::Input>,
) -> (usize, Self::Output<'_>) {
unsafe { (*self).succ_unchecked::<STRICT>(value) }
}
#[inline(always)]
unsafe fn iter_from_succ_unchecked<const STRICT: bool>(
&self,
value: impl Borrow<Self::Input>,
) -> (usize, Self::Iter<'_>) {
unsafe { (*self).iter_from_succ_unchecked::<STRICT>(value) }
}
#[inline(always)]
unsafe fn iter_bidi_from_succ_unchecked<const STRICT: bool>(
&self,
value: impl Borrow<Self::Input>,
) -> (usize, Self::BidiIter<'_>) {
unsafe { (*self).iter_bidi_from_succ_unchecked::<STRICT>(value) }
}
}
#[delegatable_trait]
pub trait Succ: SuccUnchecked
where
Self::Input: for<'a> PartialOrd<Self::Output<'a>> + PartialOrd,
for<'a> Self::Output<'a>: PartialOrd<Self::Input> + PartialOrd,
{
fn succ(&self, value: impl Borrow<Self::Input>) -> Option<(usize, Self::Output<'_>)>;
fn succ_strict(&self, value: impl Borrow<Self::Input>) -> Option<(usize, Self::Output<'_>)>;
fn iter_from_succ(&self, value: impl Borrow<Self::Input>) -> Option<(usize, Self::Iter<'_>)>;
fn iter_from_succ_strict(
&self,
value: impl Borrow<Self::Input>,
) -> Option<(usize, Self::Iter<'_>)>;
fn iter_bidi_from_succ(
&self,
value: impl Borrow<Self::Input>,
) -> Option<(usize, Self::BidiIter<'_>)>;
fn iter_bidi_from_succ_strict(
&self,
value: impl Borrow<Self::Input>,
) -> Option<(usize, Self::BidiIter<'_>)>;
}
impl<T: Succ + ?Sized> Succ for &T
where
T::Input: for<'a> PartialOrd<T::Output<'a>> + PartialOrd,
for<'a> T::Output<'a>: PartialOrd<T::Input> + PartialOrd,
{
#[inline(always)]
fn succ(&self, value: impl Borrow<Self::Input>) -> Option<(usize, Self::Output<'_>)> {
(*self).succ(value)
}
#[inline(always)]
fn succ_strict(&self, value: impl Borrow<Self::Input>) -> Option<(usize, Self::Output<'_>)> {
(*self).succ_strict(value)
}
#[inline(always)]
fn iter_from_succ(&self, value: impl Borrow<Self::Input>) -> Option<(usize, Self::Iter<'_>)> {
(*self).iter_from_succ(value)
}
#[inline(always)]
fn iter_from_succ_strict(
&self,
value: impl Borrow<Self::Input>,
) -> Option<(usize, Self::Iter<'_>)> {
(*self).iter_from_succ_strict(value)
}
#[inline(always)]
fn iter_bidi_from_succ(
&self,
value: impl Borrow<Self::Input>,
) -> Option<(usize, Self::BidiIter<'_>)> {
(*self).iter_bidi_from_succ(value)
}
#[inline(always)]
fn iter_bidi_from_succ_strict(
&self,
value: impl Borrow<Self::Input>,
) -> Option<(usize, Self::BidiIter<'_>)> {
(*self).iter_bidi_from_succ_strict(value)
}
}
pub trait PredUnchecked: Types
where
Self::Input: for<'a> PartialOrd<Self::Output<'a>> + PartialOrd,
for<'a> Self::Output<'a>: PartialOrd<Self::Input> + PartialOrd,
{
type BackIter<'a>: Iterator<Item = Self::Output<'a>>
where
Self: 'a;
type BidiIter<'a>: BidiIterator<Item = Self::Output<'a>>
where
Self: 'a;
unsafe fn pred_unchecked<const STRICT: bool>(
&self,
value: impl Borrow<Self::Input>,
) -> (usize, Self::Output<'_>);
unsafe fn iter_back_from_pred_unchecked<const STRICT: bool>(
&self,
value: impl Borrow<Self::Input>,
) -> (usize, Self::BackIter<'_>);
unsafe fn iter_bidi_from_pred_unchecked<const STRICT: bool>(
&self,
value: impl Borrow<Self::Input>,
) -> (usize, Self::BidiIter<'_>);
}
impl<T: PredUnchecked + ?Sized> PredUnchecked for &T
where
T::Input: for<'a> PartialOrd<T::Output<'a>> + PartialOrd,
for<'a> T::Output<'a>: PartialOrd<T::Input> + PartialOrd,
{
type BackIter<'a>
= T::BackIter<'a>
where
Self: 'a;
type BidiIter<'a>
= T::BidiIter<'a>
where
Self: 'a;
#[inline(always)]
unsafe fn pred_unchecked<const STRICT: bool>(
&self,
value: impl Borrow<Self::Input>,
) -> (usize, Self::Output<'_>) {
unsafe { (*self).pred_unchecked::<STRICT>(value) }
}
#[inline(always)]
unsafe fn iter_back_from_pred_unchecked<const STRICT: bool>(
&self,
value: impl Borrow<Self::Input>,
) -> (usize, Self::BackIter<'_>) {
unsafe { (*self).iter_back_from_pred_unchecked::<STRICT>(value) }
}
#[inline(always)]
unsafe fn iter_bidi_from_pred_unchecked<const STRICT: bool>(
&self,
value: impl Borrow<Self::Input>,
) -> (usize, Self::BidiIter<'_>) {
unsafe { (*self).iter_bidi_from_pred_unchecked::<STRICT>(value) }
}
}
#[delegatable_trait]
pub trait Pred: PredUnchecked
where
Self::Input: for<'a> PartialOrd<Self::Output<'a>> + PartialOrd,
for<'a> Self::Output<'a>: PartialOrd<Self::Input> + PartialOrd,
{
fn pred(&self, value: impl Borrow<Self::Input>) -> Option<(usize, Self::Output<'_>)>;
fn pred_strict(&self, value: impl Borrow<Self::Input>) -> Option<(usize, Self::Output<'_>)>;
fn iter_back_from_pred(
&self,
value: impl Borrow<Self::Input>,
) -> Option<(usize, Self::BackIter<'_>)>;
fn iter_back_from_pred_strict(
&self,
value: impl Borrow<Self::Input>,
) -> Option<(usize, Self::BackIter<'_>)>;
fn iter_bidi_from_pred(
&self,
value: impl Borrow<Self::Input>,
) -> Option<(usize, Self::BidiIter<'_>)>;
fn iter_bidi_from_pred_strict(
&self,
value: impl Borrow<Self::Input>,
) -> Option<(usize, Self::BidiIter<'_>)>;
}
impl<T: Pred + ?Sized> Pred for &T
where
T::Input: for<'a> PartialOrd<T::Output<'a>> + PartialOrd,
for<'a> T::Output<'a>: PartialOrd<T::Input> + PartialOrd,
{
#[inline(always)]
fn pred(&self, value: impl Borrow<Self::Input>) -> Option<(usize, Self::Output<'_>)> {
(*self).pred(value)
}
#[inline(always)]
fn pred_strict(&self, value: impl Borrow<Self::Input>) -> Option<(usize, Self::Output<'_>)> {
(*self).pred_strict(value)
}
#[inline(always)]
fn iter_back_from_pred(
&self,
value: impl Borrow<Self::Input>,
) -> Option<(usize, Self::BackIter<'_>)> {
(*self).iter_back_from_pred(value)
}
#[inline(always)]
fn iter_back_from_pred_strict(
&self,
value: impl Borrow<Self::Input>,
) -> Option<(usize, Self::BackIter<'_>)> {
(*self).iter_back_from_pred_strict(value)
}
#[inline(always)]
fn iter_bidi_from_pred(
&self,
value: impl Borrow<Self::Input>,
) -> Option<(usize, Self::BidiIter<'_>)> {
(*self).iter_bidi_from_pred(value)
}
#[inline(always)]
fn iter_bidi_from_pred_strict(
&self,
value: impl Borrow<Self::Input>,
) -> Option<(usize, Self::BidiIter<'_>)> {
(*self).iter_bidi_from_pred_strict(value)
}
}
macro_rules! impl_types {
($($ty:ty),*) => {$(
impl Types for [$ty] {
type Input = $ty;
type Output<'a> = $ty;
}
impl Types for Vec<$ty> {
type Input = $ty;
type Output<'a> = $ty;
}
impl<const N: usize> Types for [$ty; N] {
type Input = $ty;
type Output<'a> = $ty;
}
)*};
}
impl_types!(u8, u16, u32, u64, u128, usize);
impl_types!(i8, i16, i32, i64, i128, isize);
macro_rules! impl_indexed_seq {
($($ty:ty),*) => {$(
impl IndexedSeq for [$ty] {
fn get(&self, index: usize) -> Self::Output<'_> {
self[index]
}
unsafe fn get_unchecked(&self, index: usize) -> Self::Output<'_> {
debug_assert_bounds!(index, self.len());
unsafe { *self.get_unchecked(index) }
}
fn len(&self) -> usize {
self.len()
}
fn is_empty(&self) -> bool {
self.is_empty()
}
}
impl IndexedSeq for Vec<$ty> {
fn get(&self, index: usize) -> Self::Output<'_> {
self[index]
}
unsafe fn get_unchecked(&self, index: usize) -> Self::Output<'_> {
use std::ops::Deref;
debug_assert_bounds!(index, self.len());
unsafe { *self.deref().get_unchecked(index) }
}
fn len(&self) -> usize {
self.len()
}
fn is_empty(&self) -> bool {
self.is_empty()
}
}
impl<const N: usize> IndexedSeq for [$ty; N] {
fn get(&self, index: usize) -> Self::Output<'_> {
self[index]
}
unsafe fn get_unchecked(&self, index: usize) -> Self::Output<'_> {
debug_assert_bounds!(index, self.len());
unsafe { *self.as_slice().get_unchecked(index) }
}
fn len(&self) -> usize {
self.as_slice().len()
}
fn is_empty(&self) -> bool {
self.as_slice().is_empty()
}
}
)*};
}
impl_indexed_seq!(u8, u16, u32, u64, u128, usize);
impl_indexed_seq!(i8, i16, i32, i64, i128, isize);