use super::Slice;
use crate::tensor::Shape;
use alloc::vec::Vec;
pub trait SliceArg {
fn into_slices(self, shape: &Shape) -> Vec<Slice>;
}
impl<S: Into<Slice> + Clone> SliceArg for &[S] {
fn into_slices(self, shape: &Shape) -> Vec<Slice> {
assert!(
self.len() <= shape.num_dims(),
"Too many slices provided for shape, got {} but expected at most {}",
self.len(),
shape.num_dims()
);
shape
.iter()
.enumerate()
.map(|(i, dim_size)| {
let slice = if i >= self.len() {
Slice::full()
} else {
self[i].clone().into()
};
let clamped_range = slice.to_range(*dim_size);
Slice::new(
clamped_range.start as isize,
Some(clamped_range.end as isize),
slice.step(),
)
})
.collect::<Vec<_>>()
}
}
impl SliceArg for &Vec<Slice> {
fn into_slices(self, shape: &Shape) -> Vec<Slice> {
self.as_slice().into_slices(shape)
}
}
impl<const R: usize, T> SliceArg for [T; R]
where
T: Into<Slice> + Clone,
{
fn into_slices(self, shape: &Shape) -> Vec<Slice> {
self.as_slice().into_slices(shape)
}
}
impl<T> SliceArg for T
where
T: Into<Slice>,
{
fn into_slices(self, shape: &Shape) -> Vec<Slice> {
let slice: Slice = self.into();
[slice].as_slice().into_slices(shape)
}
}