windows_collections/
iterable.rs1use super::*;
2use windows_core::*;
3
4struct StockIterable<T>
5where
6 T: RuntimeType + 'static,
7 T::Default: Clone,
8{
9 values: Vec<T::Default>,
10}
11
12implement_decl! {
13 impl<T> StockIterable as StockIterable_Impl: [
14 IIterable<T>,
15 ]
16 where T: RuntimeType + 'static, T::Default: Clone
17}
18
19impl<T> IIterable_Impl<T> for StockIterable_Impl<T>
20where
21 T: RuntimeType,
22 T::Default: Clone,
23{
24 fn First(&self) -> Result<IIterator<T>> {
25 Ok(ComObject::new(StockIterator {
26 owner: self.to_object(),
27 current: 0.into(),
28 })
29 .into_interface())
30 }
31}
32
33struct StockIterator<T>
34where
35 T: RuntimeType + 'static,
36 T::Default: Clone,
37{
38 owner: ComObject<StockIterable<T>>,
39 current: std::sync::atomic::AtomicUsize,
40}
41
42implement_decl! {
43 impl<T> StockIterator as StockIterator_Impl: [
44 IIterator<T>,
45 ]
46 where T: RuntimeType + 'static, T::Default: Clone
47}
48
49impl<T> IIterator_Impl<T> for StockIterator_Impl<T>
50where
51 T: RuntimeType,
52 T::Default: Clone,
53{
54 fn Current(&self) -> Result<T> {
55 let owner: &StockIterable<T> = &self.owner;
56 let current = self.current.load(std::sync::atomic::Ordering::Relaxed);
57
58 if self.owner.values.len() > current {
59 T::from_default(&owner.values[current])
60 } else {
61 Err(Error::from(E_BOUNDS))
62 }
63 }
64
65 fn HasCurrent(&self) -> Result<bool> {
66 let owner: &StockIterable<T> = &self.owner;
67 let current = self.current.load(std::sync::atomic::Ordering::Relaxed);
68
69 Ok(owner.values.len() > current)
70 }
71
72 fn MoveNext(&self) -> Result<bool> {
73 let owner: &StockIterable<T> = &self.owner;
74 let current = self.current.load(std::sync::atomic::Ordering::Relaxed);
75
76 if current < owner.values.len() {
77 self.current
78 .fetch_add(1, std::sync::atomic::Ordering::Relaxed);
79 }
80
81 Ok(owner.values.len() > current + 1)
82 }
83
84 fn GetMany(&self, values: &mut [T::Default]) -> Result<u32> {
85 let owner: &StockIterable<T> = &self.owner;
86 let current = self.current.load(std::sync::atomic::Ordering::Relaxed);
87
88 if current >= owner.values.len() {
89 return Ok(0);
90 }
91
92 let actual = std::cmp::min(owner.values.len() - current, values.len());
93 let (values, _) = values.split_at_mut(actual);
94 values.clone_from_slice(&owner.values[current..current + actual]);
95
96 self.current
97 .fetch_add(actual, std::sync::atomic::Ordering::Relaxed);
98
99 Ok(actual as u32)
100 }
101}
102
103impl<T> From<Vec<T::Default>> for IIterable<T>
104where
105 T: RuntimeType,
106 T::Default: Clone,
107{
108 fn from(values: Vec<T::Default>) -> Self {
110 ComObject::new(StockIterable { values }).into_interface()
111 }
112}