windows_collections/
vector.rs1use super::*;
2use windows_core::*;
3
4struct StockVector<T>
5where
6 T: RuntimeType + 'static,
7 T::Default: Clone + PartialEq,
8{
9 values: std::sync::RwLock<Vec<T::Default>>,
10}
11
12implement_decl! {
13 impl<T> StockVector as StockVector_Impl: [
14 IVector<T>,
15 IIterable<T>,
16 ]
17 where T: RuntimeType + 'static, T::Default: Clone + PartialEq
18}
19
20impl<T> IIterable_Impl<T> for StockVector_Impl<T>
21where
22 T: RuntimeType,
23 T::Default: Clone + PartialEq,
24{
25 fn First(&self) -> Result<IIterator<T>> {
26 Ok(ComObject::new(StockVectorIterator {
27 owner: self.to_object(),
28 current: 0.into(),
29 })
30 .into_interface())
31 }
32}
33
34impl<T> IVector_Impl<T> for StockVector_Impl<T>
35where
36 T: RuntimeType,
37 T::Default: Clone + PartialEq,
38{
39 fn GetAt(&self, index: u32) -> Result<T> {
40 let values = self.values.read().unwrap();
41 let item = values
42 .get(index as usize)
43 .ok_or_else(|| Error::from(E_BOUNDS))?;
44 T::from_default(item)
45 }
46
47 fn Size(&self) -> Result<u32> {
48 Ok(self.values.read().unwrap().len().try_into()?)
49 }
50
51 fn GetView(&self) -> Result<IVectorView<T>> {
52 let snapshot = self.values.read().unwrap().clone();
53 Ok(IVectorView::<T>::from(snapshot))
54 }
55
56 fn IndexOf(&self, value: Ref<T>, result: &mut u32) -> Result<bool> {
57 let values = self.values.read().unwrap();
58 if let Some(index) = values
59 .iter()
60 .position(|element| element == ref_as_default::<T>(&value))
61 {
62 *result = index as u32;
63 Ok(true)
64 } else {
65 *result = 0;
66 Ok(false)
67 }
68 }
69
70 fn SetAt(&self, index: u32, value: Ref<T>) -> Result<()> {
71 let mut values = self.values.write().unwrap();
72 let item = values
73 .get_mut(index as usize)
74 .ok_or_else(|| Error::from(E_BOUNDS))?;
75 *item = ref_as_default::<T>(&value).clone();
76 Ok(())
77 }
78
79 fn InsertAt(&self, index: u32, value: Ref<T>) -> Result<()> {
80 let mut values = self.values.write().unwrap();
81 let index = index as usize;
82 if index > values.len() {
83 return Err(Error::from(E_BOUNDS));
84 }
85 values.insert(index, ref_as_default::<T>(&value).clone());
86 Ok(())
87 }
88
89 fn RemoveAt(&self, index: u32) -> Result<()> {
90 let mut values = self.values.write().unwrap();
91 if index as usize >= values.len() {
92 return Err(Error::from(E_BOUNDS));
93 }
94 values.remove(index as usize);
95 Ok(())
96 }
97
98 fn Append(&self, value: Ref<T>) -> Result<()> {
99 self.values
100 .write()
101 .unwrap()
102 .push(ref_as_default::<T>(&value).clone());
103 Ok(())
104 }
105
106 fn RemoveAtEnd(&self) -> Result<()> {
107 let mut values = self.values.write().unwrap();
108 if values.is_empty() {
109 return Err(Error::from(E_BOUNDS));
110 }
111 values.pop();
112 Ok(())
113 }
114
115 fn Clear(&self) -> Result<()> {
116 self.values.write().unwrap().clear();
117 Ok(())
118 }
119
120 fn GetMany(&self, start_index: u32, items: &mut [T::Default]) -> Result<u32> {
121 let values = self.values.read().unwrap();
122 let current = start_index as usize;
123
124 if current >= values.len() {
125 return Ok(0);
126 }
127
128 let actual = std::cmp::min(values.len() - current, items.len());
129 let (items, _) = items.split_at_mut(actual);
130 items.clone_from_slice(&values[current..current + actual]);
131 Ok(actual as u32)
132 }
133
134 fn ReplaceAll(&self, items: &[T::Default]) -> Result<()> {
135 let mut values = self.values.write().unwrap();
136 values.clear();
137 values.extend_from_slice(items);
138 Ok(())
139 }
140}
141
142struct StockVectorIterator<T>
143where
144 T: RuntimeType + 'static,
145 T::Default: Clone + PartialEq,
146{
147 owner: ComObject<StockVector<T>>,
148 current: std::sync::atomic::AtomicUsize,
149}
150
151implement_decl! {
152 impl<T> StockVectorIterator as StockVectorIterator_Impl: [
153 IIterator<T>,
154 ]
155 where T: RuntimeType + 'static, T::Default: Clone + PartialEq
156}
157
158impl<T> IIterator_Impl<T> for StockVectorIterator_Impl<T>
159where
160 T: RuntimeType,
161 T::Default: Clone + PartialEq,
162{
163 fn Current(&self) -> Result<T> {
164 let current = self.current.load(std::sync::atomic::Ordering::Relaxed);
165 let values = self.owner.values.read().unwrap();
166
167 if let Some(item) = values.get(current) {
168 T::from_default(item)
169 } else {
170 Err(Error::from(E_BOUNDS))
171 }
172 }
173
174 fn HasCurrent(&self) -> Result<bool> {
175 let current = self.current.load(std::sync::atomic::Ordering::Relaxed);
176 let values = self.owner.values.read().unwrap();
177 Ok(values.len() > current)
178 }
179
180 fn MoveNext(&self) -> Result<bool> {
181 let current = self.current.load(std::sync::atomic::Ordering::Relaxed);
182 let values = self.owner.values.read().unwrap();
183 let len = values.len();
184 drop(values);
185
186 if current < len {
187 self.current
188 .fetch_add(1, std::sync::atomic::Ordering::Relaxed);
189 }
190
191 Ok(len > current + 1)
192 }
193
194 fn GetMany(&self, items: &mut [T::Default]) -> Result<u32> {
195 let current = self.current.load(std::sync::atomic::Ordering::Relaxed);
196 let values = self.owner.values.read().unwrap();
197
198 if current >= values.len() {
199 return Ok(0);
200 }
201
202 let actual = std::cmp::min(values.len() - current, items.len());
203 let (items, _) = items.split_at_mut(actual);
204 items.clone_from_slice(&values[current..current + actual]);
205
206 self.current
207 .fetch_add(actual, std::sync::atomic::Ordering::Relaxed);
208
209 Ok(actual as u32)
210 }
211}
212
213impl<T> From<Vec<T::Default>> for IVector<T>
214where
215 T: RuntimeType,
216 T::Default: Clone + PartialEq,
217{
218 fn from(values: Vec<T::Default>) -> Self {
220 ComObject::new(StockVector {
221 values: std::sync::RwLock::new(values),
222 })
223 .into_interface()
224 }
225}