1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
use crate::tensor_ops::TryStack;
pub struct Stacker<I> {
iter: I,
}
impl<I: Iterator> Iterator for Stacker<I>
where
I::Item: TryStack,
{
type Item = <I::Item as TryStack>::Stacked;
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|i| i.stack())
}
}
impl<I: ExactSizeIterator> ExactSizeIterator for Stacker<I>
where
Self: Iterator,
{
fn len(&self) -> usize {
self.iter.len()
}
}
/// Stack items of an [Iterator] where Self::Item impls [TryStack].
pub trait IteratorStackExt: Iterator {
/// Stacks items - depends on implementation of [TryStack] by the items.
///
/// Example implementations:
/// ```rust
/// # use dfdx::{data::IteratorStackExt, prelude::*};
/// # let dev: Cpu = Default::default();
/// let a: Tensor<Rank1<3>, f32, _> = dev.zeros();
/// let data = [[a.clone(), a.clone(), a]];
/// // we can call stack on each item in the iterator:
/// let _: Vec<Tensor<Rank2<3, 3>, f32, _>> = data.into_iter().stack().collect();
/// ```
fn stack(self) -> Stacker<Self>
where
Self: Sized,
{
Stacker { iter: self }
}
}
impl<I: Iterator> IteratorStackExt for I {}