use core::{ops::{Add, AddAssign, Sub, SubAssign}, slice::Iter, str::Chars};
pub trait SliceLike: Copy {
type Idx: Add<Output = Self::Idx> + AddAssign + Sub<Output = Self::Idx> +
SubAssign + PartialEq + PartialOrd + From<bool> + Default + Copy;
type RefItem: Copy;
type Iter: Iterator<Item = Self::RefItem>;
fn slice_idx_from_offset(self, idx: usize) -> Self::Idx;
fn slice_iter(self) -> Self::Iter;
fn slice_first_if(self, pred: impl FnOnce(Self::RefItem) -> bool + Copy) -> Option<(Self::RefItem, Self)>;
fn slice_find_pred(self, pred: impl FnMut(Self::RefItem) -> bool + Copy) -> Option<Self::Idx>;
fn slice_len(self) -> Self::Idx;
fn slice_from(self, from: Self::Idx) -> Self;
fn slice_to(self, to: Self::Idx) -> Self;
fn slice_split_at(self, at: Self::Idx) -> (Self, Self);
fn slice_is_empty(&self) -> bool;
}
impl<'a, A> SliceLike for &'a [A] {
type Idx = usize;
type RefItem = &'a A;
type Iter = Iter<'a, A>;
#[inline(always)]
fn slice_idx_from_offset(self, idx: usize) -> Self::Idx {
idx
}
fn slice_iter(self) -> Self::Iter {
self.iter()
}
fn slice_first_if(self, pred: impl FnOnce(Self::RefItem) -> bool + Copy) -> Option<(Self::RefItem, Self)> {
self.split_first().filter(|x| pred(x.0))
}
fn slice_find_pred(self, pred: impl FnMut(Self::RefItem) -> bool + Copy) -> Option<usize> {
self.iter().position(pred)
}
fn slice_len(self) -> usize {
self.len()
}
fn slice_from(self, from: usize) -> Self {
&self[from..]
}
fn slice_to(self, to: usize) -> Self {
&self[..to]
}
fn slice_split_at(self, at: usize) -> (Self, Self) {
self.split_at(at)
}
fn slice_is_empty(&self) -> bool {
self.is_empty()
}
}
impl<'a> SliceLike for &'a str {
type Idx = usize;
type RefItem = char;
type Iter = Chars<'a>;
#[inline(always)]
fn slice_idx_from_offset(self, idx: usize) -> Self::Idx {
idx
}
fn slice_iter(self) -> Self::Iter {
self.chars()
}
fn slice_first_if(self, pred: impl FnOnce(Self::RefItem) -> bool + Copy) -> Option<(Self::RefItem, Self)> {
let mut chars = self.chars();
let first = chars.next()?;
pred(first).then_some((first, chars.as_str()))
}
fn slice_find_pred(self, pred: impl FnMut(Self::RefItem) -> bool + Copy) -> Option<usize> {
self.find(pred)
}
fn slice_len(self) -> usize {
self.len()
}
fn slice_from(self, from: usize) -> Self {
&self[from..]
}
fn slice_to(self, to: usize) -> Self {
&self[..to]
}
fn slice_split_at(self, at: usize) -> (Self, Self) {
self.split_at(at)
}
fn slice_is_empty(&self) -> bool {
self.is_empty()
}
}