windows_collections/
vector_view.rs1use super::*;
2use windows_core::*;
3
4struct StockVectorView<T>
5where
6 T: RuntimeType + 'static,
7 T::Default: Clone + PartialEq,
8{
9 values: Vec<T::Default>,
10}
11
12implement_decl! {
13 impl<T> StockVectorView as StockVectorView_Impl: [
14 IVectorView<T>,
15 IIterable<T>,
16 ]
17 where T: RuntimeType + 'static, T::Default: Clone + PartialEq
18}
19
20impl<T> IIterable_Impl<T> for StockVectorView_Impl<T>
21where
22 T: RuntimeType,
23 T::Default: Clone + PartialEq,
24{
25 fn First(&self) -> Result<IIterator<T>> {
26 Ok(ComObject::new(StockVectorViewIterator {
27 owner: self.to_object(),
28 current: 0.into(),
29 })
30 .into_interface())
31 }
32}
33
34impl<T> IVectorView_Impl<T> for StockVectorView_Impl<T>
35where
36 T: RuntimeType,
37 T::Default: Clone + PartialEq,
38{
39 fn GetAt(&self, index: u32) -> Result<T> {
40 let item = self
41 .values
42 .get(index as usize)
43 .ok_or_else(|| Error::from(E_BOUNDS))?;
44
45 T::from_default(item)
46 }
47
48 fn Size(&self) -> Result<u32> {
49 Ok(self.values.len().try_into()?)
50 }
51
52 fn IndexOf(&self, value: Ref<T>, result: &mut u32) -> Result<bool> {
53 if let Some(index) = self
54 .values
55 .iter()
56 .position(|element| element == ref_as_default::<T>(&value))
57 {
58 *result = index as u32;
59 Ok(true)
60 } else {
61 *result = 0;
62 Ok(false)
63 }
64 }
65
66 fn GetMany(&self, current: u32, values: &mut [T::Default]) -> Result<u32> {
67 let current = current as usize;
68
69 if current >= self.values.len() {
70 return Ok(0);
71 }
72
73 let actual = std::cmp::min(self.values.len() - current, values.len());
74 let (values, _) = values.split_at_mut(actual);
75 values.clone_from_slice(&self.values[current..current + actual]);
76 Ok(actual as u32)
77 }
78}
79
80struct StockVectorViewIterator<T>
81where
82 T: RuntimeType + 'static,
83 T::Default: Clone + PartialEq,
84{
85 owner: ComObject<StockVectorView<T>>,
86 current: std::sync::atomic::AtomicUsize,
87}
88
89implement_decl! {
90 impl<T> StockVectorViewIterator as StockVectorViewIterator_Impl: [
91 IIterator<T>,
92 ]
93 where T: RuntimeType + 'static, T::Default: Clone + PartialEq
94}
95
96impl<T> IIterator_Impl<T> for StockVectorViewIterator_Impl<T>
97where
98 T: RuntimeType,
99 T::Default: Clone + PartialEq,
100{
101 fn Current(&self) -> Result<T> {
102 let current = self.current.load(std::sync::atomic::Ordering::Relaxed);
103
104 if let Some(item) = self.owner.values.get(current) {
105 T::from_default(item)
106 } else {
107 Err(Error::from(E_BOUNDS))
108 }
109 }
110
111 fn HasCurrent(&self) -> Result<bool> {
112 let current = self.current.load(std::sync::atomic::Ordering::Relaxed);
113 Ok(self.owner.values.len() > current)
114 }
115
116 fn MoveNext(&self) -> Result<bool> {
117 let current = self.current.load(std::sync::atomic::Ordering::Relaxed);
118
119 if current < self.owner.values.len() {
120 self.current
121 .fetch_add(1, std::sync::atomic::Ordering::Relaxed);
122 }
123
124 Ok(self.owner.values.len() > current + 1)
125 }
126
127 fn GetMany(&self, values: &mut [T::Default]) -> Result<u32> {
128 let current = self.current.load(std::sync::atomic::Ordering::Relaxed);
129
130 if current >= self.owner.values.len() {
131 return Ok(0);
132 }
133
134 let actual = std::cmp::min(self.owner.values.len() - current, values.len());
135 let (values, _) = values.split_at_mut(actual);
136 values.clone_from_slice(&self.owner.values[current..current + actual]);
137
138 self.current
139 .fetch_add(actual, std::sync::atomic::Ordering::Relaxed);
140
141 Ok(actual as u32)
142 }
143}
144
145impl<T> From<Vec<T::Default>> for IVectorView<T>
146where
147 T: RuntimeType,
148 T::Default: Clone + PartialEq,
149{
150 fn from(values: Vec<T::Default>) -> Self {
152 ComObject::new(StockVectorView { values }).into_interface()
153 }
154}