use super::*; use windows_core::*; #[implement(IIterable)] struct StockIterable where T: RuntimeType + 'static, T::Default: Clone, { values: Vec, } impl IIterable_Impl for StockIterable_Impl where T: RuntimeType, T::Default: Clone, { fn First(&self) -> Result> { Ok(ComObject::new(StockIterator { owner: self.to_object(), current: 0.into(), }) .into_interface()) } } #[implement(IIterator)] struct StockIterator where T: RuntimeType + 'static, T::Default: Clone, { owner: ComObject>, current: std::sync::atomic::AtomicUsize, } impl IIterator_Impl for StockIterator_Impl where T: RuntimeType, T::Default: Clone, { fn Current(&self) -> Result { let owner: &StockIterable = &self.owner; let current = self.current.load(std::sync::atomic::Ordering::Relaxed); if self.owner.values.len() > current { T::from_default(&owner.values[current]) } else { Err(Error::from(E_BOUNDS)) } } fn HasCurrent(&self) -> Result { let owner: &StockIterable = &self.owner; let current = self.current.load(std::sync::atomic::Ordering::Relaxed); Ok(owner.values.len() > current) } fn MoveNext(&self) -> Result { let owner: &StockIterable = &self.owner; let current = self.current.load(std::sync::atomic::Ordering::Relaxed); if current < owner.values.len() { self.current .fetch_add(1, std::sync::atomic::Ordering::Relaxed); } Ok(owner.values.len() > current + 1) } fn GetMany(&self, values: &mut [T::Default]) -> Result { let owner: &StockIterable = &self.owner; let current = self.current.load(std::sync::atomic::Ordering::Relaxed); let actual = std::cmp::min(owner.values.len() - current, values.len()); let (values, _) = values.split_at_mut(actual); values.clone_from_slice(&owner.values[current..current + actual]); self.current .fetch_add(actual, std::sync::atomic::Ordering::Relaxed); Ok(actual as u32) } } impl From> for IIterable where T: RuntimeType, T::Default: Clone, { fn from(values: Vec) -> Self { ComObject::new(StockIterable { values }).into_interface() } }