use core::ops::Range;
use std::vec;
use value_traits::slices::*;
mod common;
pub use common::*;
#[test]
fn test_slices() {
let mut s = vec![1_i32, 2, 3];
assert_eq!(test_usize(s.as_slice()), 1);
let t = s.as_slice();
assert_eq!(test_range(&t), &[1, 2]);
assert_eq!(test_usize_range(&t), (1, [1, 2].as_ref()));
assert_eq!(test_len(&t), 3);
let t = s.as_mut_slice();
assert_eq!(test_range_mut(t), &mut [1, 2]);
}
fn test_usize(s: impl SliceByValue<Value = i32>) -> i32 {
s.index_value(0_usize)
}
fn test_range<'a, S>(s: &S) -> &[i32]
where
S: SliceByValueSubslice,
S: for<'b> SliceByValueSubsliceGat<'b, Subslice = &'b [i32]>,
{
let a = &s.index_subslice(0..2);
let _ = s.index_subslice(0..3); a
}
fn test_range_mut<'a, S>(s: &mut S) -> &mut [i32]
where
S: SliceByValueSubsliceRangeMut<Range<usize>> + ?Sized,
S: for<'b> SliceByValueSubsliceGatMut<'b, SubsliceMut = &'b mut [i32]>,
{
(s.index_subslice_mut(0..2)) as _
}
fn test_usize_range<'a, S>(s: &S) -> (i32, &[i32])
where
S: SliceByValue<Value = i32>,
S: SliceByValueSubslice,
S: for<'b> SliceByValueSubsliceGat<'b, Subslice = &'b [i32]>,
{
(s.index_value(0_usize), s.index_subslice(0..2))
}
fn test_len<'a, S>(s: &S) -> usize
where
S: SliceByValueSubslice,
S: for<'b> SliceByValueSubsliceGat<'b, Subslice = &'b [i32]>,
{
s.len()
}
#[test]
#[cfg(any(feature = "std", feature = "alloc"))]
fn test_iter() {
let s = [1_i32, 2, 3];
generic_iter(&s.to_vec(), &s);
}
use value_traits::{Iterators, IteratorsMut, Subslices, SubslicesMut};
#[derive(Subslices, Iterators, SubslicesMut, IteratorsMut)]
#[value_traits_subslices_mut(bound = "T: Copy")]
#[value_traits_iterators_mut(bound = "T: Copy")]
pub struct Sbv<T: Clone = usize>(Vec<T>);
#[derive(Subslices, SubslicesMut, Iterators, IteratorsMut)]
#[value_traits_subslices_mut(bound = "T: Copy")]
#[value_traits_iterators_mut(bound = "T: Copy")]
pub struct Sbv2<T: Clone>(Vec<T>);
macro_rules! impl_slice {
($ty:ident) => {
impl<T: Clone> SliceByValue for $ty<T> {
type Value = T;
fn len(&self) -> usize {
self.0.len()
}
unsafe fn get_value_unchecked(&self, index: usize) -> Self::Value {
unsafe { self.0.as_slice().get_value_unchecked(index) }
}
}
impl<T: Clone> SliceByValueMut for $ty<T>
where
T: Copy,
{
unsafe fn set_value_unchecked(&mut self, index: usize, value: Self::Value) {
self.0.as_mut_slice().set_value(index, value)
}
unsafe fn replace_value_unchecked(
&mut self,
index: usize,
value: Self::Value,
) -> Self::Value {
self.0.as_mut_slice().replace_value(index, value)
}
type ChunksMut<'a>
= core::slice::ChunksMut<'a, T>
where
Self: 'a;
type ChunksMutError = core::convert::Infallible;
fn try_chunks_mut(
&mut self,
chunk_size: usize,
) -> Result<Self::ChunksMut<'_>, Self::ChunksMutError> {
Ok(self.0.chunks_mut(chunk_size))
}
}
};
}
impl_slice!(Sbv);
impl_slice!(Sbv2);
#[test]
fn test_sbv_subslices() {
let expected = [1_i32, 2, 3, 4, 5];
let mut s = Sbv(expected.to_vec());
generic_get(&s, &expected);
generic_slice(&s, &expected);
generic_mut(&mut s);
generic_slice_mut(&mut s);
generic_get(s.index_subslice(..), &expected);
generic_slice(s.index_subslice(..), &expected);
generic_derived_iter(s.index_subslice(..), &expected);
generic_get(s.index_subslice(1..4), &expected[1..4]);
generic_derived_iter(s.index_subslice(1..4), &expected[1..4]);
generic_get(s.index_subslice_mut(..), &expected);
generic_slice(s.index_subslice_mut(..), &expected);
generic_mut(s.index_subslice_mut(..));
generic_slice_mut(s.index_subslice_mut(..));
generic_derived_iter(s.index_subslice_mut(..), &expected);
generic_get(s.index_subslice_mut(1..4), &expected[1..4]);
generic_derived_iter(s.index_subslice_mut(1..4), &expected[1..4]);
let mut t = s.index_subslice_mut(1..3); assert_eq!(t.len(), 2);
assert_eq!(t.index_value(0), 2);
assert_eq!(t.index_value(1), 3);
t.set_value(1, 4);
let u = t.index_subslice(1..);
assert_eq!(u.len(), 1);
assert_eq!(u.index_value(0), 4);
}
#[test]
fn test_subslice_iter_partial_range() {
let s = Sbv(vec![10, 20, 30, 40, 50]);
let sub = s.index_subslice(1..4);
let values: Vec<_> = value_traits::iter::IterateByValue::iter_value(&sub).collect();
assert_eq!(values, vec![20, 30, 40]);
let sub = s.index_subslice(2..3);
let values: Vec<_> = value_traits::iter::IterateByValue::iter_value(&sub).collect();
assert_eq!(values, vec![30]);
let sub = s.index_subslice(3..3);
let values: Vec<_> = value_traits::iter::IterateByValue::iter_value(&sub).collect();
assert!(values.is_empty());
let mut s = Sbv(vec![10, 20, 30, 40, 50]);
let sub_mut = s.index_subslice_mut(2..5);
let values: Vec<_> = value_traits::iter::IterateByValue::iter_value(&sub_mut).collect();
assert_eq!(values, vec![30, 40, 50]);
let s = Sbv(vec![10, 20, 30, 40, 50]);
let sub = s.index_subslice(1..4); let sub_sub = sub.index_subslice(1..3); let values: Vec<_> = value_traits::iter::IterateByValue::iter_value(&sub_sub).collect();
assert_eq!(values, vec![30, 40]);
}
#[test]
fn test_subslice_iter_value_from() {
let s = Sbv(vec![10, 20, 30, 40, 50]);
let sub = s.index_subslice(1..4); let values: Vec<_> = value_traits::iter::IterateByValueFrom::iter_value_from(&sub, 1).collect();
assert_eq!(values, vec![30, 40]);
let values: Vec<_> = value_traits::iter::IterateByValueFrom::iter_value_from(&sub, 0).collect();
assert_eq!(values, vec![20, 30, 40]);
}
#[test]
#[allow(clippy::iter_nth_zero)] fn test_derived_iter_nth() {
let s = Sbv(vec![10, 20, 30, 40, 50]);
let sub = s.index_subslice(..);
let mut iter = value_traits::iter::IterateByValue::iter_value(&sub);
assert_eq!(iter.nth(0), Some(10));
assert_eq!(iter.nth(1), Some(30)); assert_eq!(iter.nth(0), Some(40));
assert_eq!(iter.nth(0), Some(50));
assert_eq!(iter.nth(0), None);
let sub = s.index_subslice(2..5); let mut iter = value_traits::iter::IterateByValue::iter_value(&sub);
assert_eq!(iter.nth(0), Some(30));
assert_eq!(iter.nth(0), Some(40));
assert_eq!(iter.nth(0), Some(50));
assert_eq!(iter.nth(0), None);
let sub = s.index_subslice(2..5); let mut iter = value_traits::iter::IterateByValue::iter_value(&sub);
assert_eq!(iter.nth(3), None); assert_eq!(iter.nth(0), None);
let sub = s.index_subslice(2..5);
let mut iter = value_traits::iter::IterateByValue::iter_value(&sub);
assert_eq!(iter.nth(100), None);
let sub = s.index_subslice(1..4); let mut iter = value_traits::iter::IterateByValue::iter_value(&sub);
assert_eq!(iter.nth(1), Some(30));
assert_eq!(iter.len(), 1);
assert_eq!(iter.nth(0), Some(40));
assert_eq!(iter.nth(0), None);
let mut s = Sbv(vec![10, 20, 30, 40, 50]);
let sub_mut = s.index_subslice_mut(2..5);
let mut iter = value_traits::iter::IterateByValue::iter_value(&sub_mut);
assert_eq!(iter.nth(2), Some(50));
assert_eq!(iter.nth(0), None);
}
#[test]
fn test_derived_iter_fused() {
let s = Sbv(vec![10, 20]);
let sub = s.index_subslice(..);
let mut iter = value_traits::iter::IterateByValue::iter_value(&sub);
assert_eq!(iter.next(), Some(10));
assert_eq!(iter.next(), Some(20));
assert_eq!(iter.next(), None);
assert_eq!(iter.next(), None);
assert_eq!(iter.next(), None);
let sub = s.index_subslice(..);
let mut iter = value_traits::iter::IterateByValue::iter_value(&sub);
assert_eq!(iter.next_back(), Some(20));
assert_eq!(iter.next_back(), Some(10));
assert_eq!(iter.next_back(), None);
assert_eq!(iter.next_back(), None);
let sub = s.index_subslice(..);
let mut iter = value_traits::iter::IterateByValue::iter_value(&sub);
assert_eq!(iter.next(), Some(10));
assert_eq!(iter.next_back(), Some(20));
assert_eq!(iter.next(), None);
assert_eq!(iter.next_back(), None);
}
#[test]
fn test_copy_out_of_bounds() {
let src = vec![1_i32, 2, 3, 4, 5];
let mut dst = vec![0_i32; 5];
src.copy(1, &mut dst, 2, 2);
assert_eq!(dst, vec![0, 0, 2, 3, 0]);
let mut dst = vec![0_i32; 5];
src.copy(10, &mut dst, 0, 5);
assert_eq!(dst, vec![0, 0, 0, 0, 0]);
let mut dst = vec![0_i32; 5];
src.copy(0, &mut dst, 10, 5);
assert_eq!(dst, vec![0, 0, 0, 0, 0]);
let mut dst = vec![0_i32; 5];
src.copy(5, &mut dst, 0, 5);
assert_eq!(dst, vec![0, 0, 0, 0, 0]);
let mut dst = vec![0_i32; 5];
src.copy(0, &mut dst, 5, 5);
assert_eq!(dst, vec![0, 0, 0, 0, 0]);
let mut dst = vec![0_i32; 5];
src.copy(0, &mut dst, 0, 0);
assert_eq!(dst, vec![0, 0, 0, 0, 0]);
let mut dst = vec![0_i32; 5];
src.copy(3, &mut dst, 0, 100);
assert_eq!(dst, vec![4, 5, 0, 0, 0]);
let mut dst = vec![0_i32; 3];
src.copy(0, &mut dst, 1, 100);
assert_eq!(dst, vec![0, 1, 2]);
}
#[derive(Subslices, Iterators)]
pub enum Sbv3 {
OnlyThis,
}
impl SliceByValue for Sbv3 {
type Value = usize;
fn len(&self) -> usize {
100
}
unsafe fn get_value_unchecked(&self, index: usize) -> Self::Value {
index
}
}
#[derive(Subslices, Iterators)]
pub union Sbv4 {
_only_this: usize,
}
impl SliceByValue for Sbv4 {
type Value = usize;
fn len(&self) -> usize {
100
}
unsafe fn get_value_unchecked(&self, index: usize) -> Self::Value {
index
}
}
#[test]
fn test_derived_iter_count() {
let s = Sbv(vec![10, 20, 30, 40, 50]);
let sub = s.index_subslice(..);
assert_eq!(
value_traits::iter::IterateByValue::iter_value(&sub).count(),
5
);
let sub = s.index_subslice(1..4);
assert_eq!(
value_traits::iter::IterateByValue::iter_value(&sub).count(),
3
);
let sub = s.index_subslice(2..2);
assert_eq!(
value_traits::iter::IterateByValue::iter_value(&sub).count(),
0
);
let sub = s.index_subslice(..);
let mut iter = value_traits::iter::IterateByValue::iter_value(&sub);
iter.next();
iter.next();
assert_eq!(iter.count(), 3);
}
#[test]
fn test_derived_iter_last() {
let s = Sbv(vec![10, 20, 30, 40, 50]);
let sub = s.index_subslice(..);
assert_eq!(
value_traits::iter::IterateByValue::iter_value(&sub).last(),
Some(50)
);
let sub = s.index_subslice(1..4);
assert_eq!(
value_traits::iter::IterateByValue::iter_value(&sub).last(),
Some(40)
);
let sub = s.index_subslice(3..4);
assert_eq!(
value_traits::iter::IterateByValue::iter_value(&sub).last(),
Some(40)
);
let sub = s.index_subslice(2..2);
assert_eq!(
value_traits::iter::IterateByValue::iter_value(&sub).last(),
None
);
}
#[test]
fn test_derived_iter_nth_back() {
let s = Sbv(vec![10, 20, 30, 40, 50]);
let sub = s.index_subslice(1..4); let mut iter = value_traits::iter::IterateByValue::iter_value(&sub);
assert_eq!(iter.nth_back(0), Some(40));
assert_eq!(iter.nth_back(0), Some(30));
assert_eq!(iter.nth_back(0), Some(20));
assert_eq!(iter.nth_back(0), None);
let sub = s.index_subslice(..); let mut iter = value_traits::iter::IterateByValue::iter_value(&sub);
assert_eq!(iter.nth_back(1), Some(40)); assert_eq!(iter.len(), 3); assert_eq!(iter.nth_back(2), Some(10)); assert_eq!(iter.nth_back(0), None);
let sub = s.index_subslice(2..5); let mut iter = value_traits::iter::IterateByValue::iter_value(&sub);
assert_eq!(iter.nth_back(3), None); assert_eq!(iter.len(), 0);
let sub = s.index_subslice(2..5);
let mut iter = value_traits::iter::IterateByValue::iter_value(&sub);
assert_eq!(iter.nth_back(100), None);
assert_eq!(iter.len(), 0);
let sub = s.index_subslice(..); let mut iter = value_traits::iter::IterateByValue::iter_value(&sub);
assert_eq!(iter.next(), Some(10));
assert_eq!(iter.nth_back(0), Some(50));
assert_eq!(iter.len(), 3); assert_eq!(iter.nth_back(1), Some(30)); assert_eq!(iter.len(), 1); assert_eq!(iter.next(), Some(20));
assert_eq!(iter.next(), None);
let mut s = Sbv(vec![10, 20, 30, 40, 50]);
let sub_mut = s.index_subslice_mut(1..4); let mut iter = value_traits::iter::IterateByValue::iter_value(&sub_mut);
assert_eq!(iter.nth_back(1), Some(30)); assert_eq!(iter.nth_back(0), Some(20));
assert_eq!(iter.nth_back(0), None);
}
#[test]
#[allow(clippy::unnecessary_fold)] fn test_derived_iter_fold() {
let s = Sbv(vec![10, 20, 30, 40, 50]);
let sub = s.index_subslice(..);
let sum = value_traits::iter::IterateByValue::iter_value(&sub).fold(0_i32, |acc, x| acc + x);
assert_eq!(sum, 150);
let sub = s.index_subslice(1..4); let sum = value_traits::iter::IterateByValue::iter_value(&sub).fold(0_i32, |acc, x| acc + x);
assert_eq!(sum, 90);
let sub = s.index_subslice(2..5); let collected =
value_traits::iter::IterateByValue::iter_value(&sub).fold(Vec::new(), |mut acc, x| {
acc.push(x);
acc
});
assert_eq!(collected, vec![30, 40, 50]);
let sub = s.index_subslice(3..3);
let sum = value_traits::iter::IterateByValue::iter_value(&sub).fold(42_i32, |acc, x| acc + x);
assert_eq!(sum, 42);
}
#[test]
fn test_derived_iter_for_each() {
let s = Sbv(vec![10, 20, 30, 40, 50]);
let sub = s.index_subslice(1..4); let mut collected = Vec::new();
value_traits::iter::IterateByValue::iter_value(&sub).for_each(|x| collected.push(x));
assert_eq!(collected, vec![20, 30, 40]);
let sub = s.index_subslice(2..2);
let mut collected = Vec::new();
value_traits::iter::IterateByValue::iter_value(&sub).for_each(|x| collected.push(x));
assert!(collected.is_empty());
}
#[test]
fn test_derived_iter_rfold() {
let s = Sbv(vec![10, 20, 30, 40, 50]);
let sub = s.index_subslice(1..4); let reversed =
value_traits::iter::IterateByValue::iter_value(&sub).rfold(Vec::new(), |mut acc, x| {
acc.push(x);
acc
});
assert_eq!(reversed, vec![40, 30, 20]);
let sub = s.index_subslice(..);
let sum = value_traits::iter::IterateByValue::iter_value(&sub).rfold(0_i32, |acc, x| acc + x);
assert_eq!(sum, 150);
let sub = s.index_subslice(3..3);
let sum = value_traits::iter::IterateByValue::iter_value(&sub).rfold(42_i32, |acc, x| acc + x);
assert_eq!(sum, 42);
let s = Sbv(vec![1, 2, 3]);
let sub = s.index_subslice(..);
let result = value_traits::iter::IterateByValue::iter_value(&sub)
.rfold(String::new(), |acc, x| format!("{x}{acc}"));
assert_eq!(result, "123");
}