use crate::traits::*;
use core::marker::PhantomData;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Wrapper<S, N>(S, PhantomData<N>);
impl<S, N> Wrapper<S, N> {
#[inline]
pub fn unwrap(self) -> S {
self.0
}
}
impl<S, N> From<S> for Wrapper<S, N>
where
S: DerefSequence<N>,
{
#[inline]
fn from(sequence: S) -> Self {
Self(sequence, PhantomData)
}
}
impl<S, N> AsRef<S> for Wrapper<S, N> {
#[inline]
fn as_ref(&self) -> &S {
&self.0
}
}
impl<S, N> AsMut<S> for Wrapper<S, N> {
#[inline]
fn as_mut(&mut self) -> &mut S {
&mut self.0
}
}
impl<S, N> IntoIterator for Wrapper<S, N>
where
S: DerefSequence<N> + IntoIterator,
{
type Item = S::Item;
type IntoIter = S::IntoIter;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}
impl<'this, S, N> SequenceTypes<'this> for Wrapper<S, N>
where
S: DerefSequence<N>,
S::Sequence: SequenceTypes<'this>,
{
type Item = <S::Sequence as SequenceTypes<'this>>::Item;
type Iter = <S::Sequence as SequenceTypes<'this>>::Iter;
}
impl<'this, S, N> MutSequenceTypes<'this> for Wrapper<S, N>
where
S: DerefSequence<N>,
S::Sequence: MutSequenceTypes<'this>,
{
type MutItem = <S::Sequence as MutSequenceTypes<'this>>::MutItem;
type IterMut = <S::Sequence as MutSequenceTypes<'this>>::IterMut;
}
impl<S, N> Sequence for Wrapper<S, N>
where
S: DerefSequence<N>,
{
#[inline]
fn len(&self) -> usize {
self.0.deref_sqnc().len()
}
#[inline]
fn is_empty(&self) -> bool {
self.0.deref_sqnc().is_empty()
}
#[inline]
fn get(&self, index: usize) -> Option<<Self as SequenceTypes<'_>>::Item> {
self.0.deref_sqnc().get(index)
}
#[inline]
fn rget(&self, rindex: usize) -> Option<<Self as SequenceTypes<'_>>::Item> {
self.0.deref_sqnc().rget(rindex)
}
#[inline]
fn first(&self) -> Option<<Self as SequenceTypes<'_>>::Item> {
self.0.deref_sqnc().first()
}
#[inline]
fn last(&self) -> Option<<Self as SequenceTypes<'_>>::Item> {
self.0.deref_sqnc().last()
}
#[inline]
fn iter(&self) -> <Self as SequenceTypes<'_>>::Iter {
self.0.deref_sqnc().iter()
}
#[inline]
fn min<'a>(&'a self) -> Option<<Self as SequenceTypes<'a>>::Item>
where
<Self as SequenceTypes<'a>>::Item: Ord,
{
self.0.deref_sqnc().min()
}
#[inline]
fn max<'a>(&'a self) -> Option<<Self as SequenceTypes<'a>>::Item>
where
<Self as SequenceTypes<'a>>::Item: Ord,
{
self.0.deref_sqnc().max()
}
}
impl<S, N> MutSequence for Wrapper<S, N>
where
S: DerefMutSequence<N>,
S::Sequence: MutSequence,
{
#[inline]
fn get_mut(&mut self, index: usize) -> Option<<Self as MutSequenceTypes<'_>>::MutItem> {
self.0.deref_mut_sqnc().get_mut(index)
}
#[inline]
fn rget_mut(&mut self, rindex: usize) -> Option<<Self as MutSequenceTypes<'_>>::MutItem> {
self.0.deref_mut_sqnc().rget_mut(rindex)
}
#[inline]
fn first_mut(&mut self) -> Option<<Self as MutSequenceTypes<'_>>::MutItem> {
self.0.deref_mut_sqnc().first_mut()
}
#[inline]
fn last_mut(&mut self) -> Option<<Self as MutSequenceTypes<'_>>::MutItem> {
self.0.deref_mut_sqnc().last_mut()
}
#[inline]
fn iter_mut(&mut self) -> <Self as MutSequenceTypes<'_>>::IterMut {
self.0.deref_mut_sqnc().iter_mut()
}
}
unsafe impl<S, N> UniqueSequence for Wrapper<S, N>
where
S: DerefSequence<N>,
S::Sequence: UniqueSequence,
{
}
pub fn wrap<S, N>(sequence: S) -> Wrapper<S, N>
where
S: DerefSequence<N>,
{
Wrapper(sequence, PhantomData)
}
#[cfg(test)]
mod tests {
use super::Wrapper;
use crate::traits::*;
#[test]
fn unwrap() {
assert_eq!(Wrapper::from(2..5).unwrap(), 2..5);
}
#[test]
fn as_ref() {
assert_eq!(Wrapper::from(2..5).as_ref(), &(2..5));
}
#[test]
fn as_mut() {
let mut x = [2, 3, 4];
let mut y = Wrapper::from(&mut x);
*y.as_mut().get_mut(0).unwrap() = 5;
assert_eq!(x, [5, 3, 4]);
}
#[test]
fn into_iter() {
assert!(Wrapper::from(2..5).into_iter().eq(2..5));
}
#[test]
fn len() {
assert_eq!(Wrapper::from(2..5).len(), 3);
}
#[test]
fn is_empty() {
assert_eq!(Wrapper::from(2..5).is_empty(), false);
assert_eq!(Wrapper::from(2..2).is_empty(), true);
}
#[test]
fn get() {
let x = Wrapper::from(2..5);
assert_eq!(x.get(0), Some(2));
assert_eq!(x.get(1), Some(3));
assert_eq!(x.get(2), Some(4));
assert_eq!(x.get(3), None);
}
#[test]
fn rget() {
let x = Wrapper::from(2..5);
assert_eq!(x.rget(0), Some(4));
assert_eq!(x.rget(1), Some(3));
assert_eq!(x.rget(2), Some(2));
assert_eq!(x.rget(3), None);
}
#[test]
fn first() {
assert_eq!(Wrapper::from(2..5).first(), Some(2));
assert_eq!(Wrapper::from(2..2).first(), None);
}
#[test]
fn last() {
assert_eq!(Wrapper::from(2..5).last(), Some(4));
assert_eq!(Wrapper::from(2..2).last(), None);
}
#[test]
fn get_mut() {
let mut x = [2, 3, 4];
let mut y = Wrapper::from(&mut x);
*y.get_mut(0).unwrap() = 5;
*y.get_mut(1).unwrap() = 6;
*y.get_mut(2).unwrap() = 7;
assert!(y.get_mut(3).is_none());
assert_eq!(x, [5, 6, 7]);
}
#[test]
fn rget_mut() {
let mut x = [2, 3, 4];
let mut y = Wrapper::from(&mut x);
*y.rget_mut(0).unwrap() = 7;
*y.rget_mut(1).unwrap() = 6;
*y.rget_mut(2).unwrap() = 5;
assert!(y.rget_mut(3).is_none());
assert_eq!(x, [5, 6, 7]);
}
#[test]
fn first_mut() {
let mut x = [2, 3, 4];
let mut y = Wrapper::from(&mut x);
*y.first_mut().unwrap() = 5;
assert_eq!(x, [5, 3, 4]);
let mut z: Wrapper<[usize; 0], _> = Wrapper::from([]);
assert_eq!(z.first_mut(), None);
}
#[test]
fn last_mut() {
let mut x = [2, 3, 4];
let mut y = Wrapper::from(&mut x);
*y.last_mut().unwrap() = 7;
assert_eq!(x, [2, 3, 7]);
let mut z: Wrapper<[usize; 0], _> = Wrapper::from([]);
assert_eq!(z.last_mut(), None);
}
#[test]
fn iter() {
assert!(Wrapper::from(2..5).iter().eq(2..5));
}
#[test]
fn iter_mut() {
let mut x = [2, 3, 4];
Wrapper::from(&mut x).iter_mut().for_each(|v| *v += 3);
assert!(x.iter().eq([&5, &6, &7]));
}
#[test]
fn min() {
assert_eq!(Wrapper::from(2..5).min(), Some(2));
assert_eq!(Wrapper::from(2..2).min(), None);
}
#[test]
fn max() {
assert_eq!(Wrapper::from(2..5).max(), Some(4));
assert_eq!(Wrapper::from(2..2).max(), None);
}
#[test]
fn wrap() {
struct SmartPointer<T>(T);
impl<T> core::ops::Deref for SmartPointer<T> {
type Target = T;
fn deref(&self) -> &T {
&self.0
}
}
let x = SmartPointer([2, 3, 4]);
assert_eq!(Sequence::get(&super::wrap(x), 0), Some(&2));
let x = SmartPointer([2, 3, 4]);
let y = SmartPointer(x);
assert_eq!(Sequence::get(&super::wrap(y), 0), Some(&2));
}
}