1pub use std::convert::{From,Into,TryFrom,TryInto};
42use super::{is_unique, multi};
43pub use super::SubsetError;
44
45#[derive(Debug)]
49pub struct Subset<'a, T> {
50 pub(crate) m: multi::Subset<'a, T>
51}
52
53
54impl<'a, T> Subset<'a, T> {
55 pub fn new(set: &'a [T], idxs: &'a [usize]) -> Result<Self, SubsetError> {
75 multi::Subset::new(set, idxs)?.try_into()
76 }
77 pub unsafe fn new_unchecked(set: &'a [T], idxs: &'a [usize]) -> Self {
80 multi::Subset::new_unchecked(set, idxs).to_unique_unchecked()
81 }
82 pub fn set(&self) -> &[T] {
84 self.m.set()
85 }
86 pub fn idxs(&self) -> &[usize] {
88 self.m.idxs()
89 }
90 pub fn iter(&self) -> multi::Iter<T> {
92 self.m.iter()
93 }
94}
95
96
97impl<'a, T> From<SubsetMut<'a, T>> for Subset<'a, T> {
98 fn from(s: SubsetMut<'a, T>) -> Self {
99 Self {
100 m: s.m.into()
101 }
102 }
103}
104
105
106impl<'a, T> TryFrom<multi::Subset<'a, T>> for Subset<'a, T> {
107 type Error = SubsetError;
108 fn try_from(s: multi::Subset<'a, T>) -> Result<Self, SubsetError> {
109 if is_unique(s.idxs) {
110 Ok(unsafe{s.to_unique_unchecked()})
111 } else {
112 Err(SubsetError::NotUnique)
113 }
114 }
115}
116
117
118impl<'a, T> TryFrom<multi::SubsetMut<'a, T>> for Subset<'a, T> {
119 type Error = SubsetError;
120 fn try_from(s: multi::SubsetMut<'a, T>) -> Result<Self, SubsetError> {
121 if is_unique(s.idxs) {
122 Ok(unsafe{s.to_unique_unchecked()})
123 } else {
124 Err(SubsetError::NotUnique)
125 }
126 }
127}
128
129
130impl<'a, T> IntoIterator for &'a Subset<'a, T> {
131 type Item = &'a T;
132 type IntoIter = multi::Iter<'a, T>;
133 fn into_iter(self) -> multi::Iter<'a, T> {
134 self.iter()
135 }
136}
137
138
139#[derive(Debug)]
143pub struct SubsetMut<'a, T> {
144 pub(crate) m: multi::SubsetMut<'a, T>
145}
146
147pub struct IterMut<'a, T> {
149 ptr: *mut T, iter: std::slice::Iter<'a, usize>
151}
152
153impl<'a, T> SubsetMut<'a, T> {
154 pub fn new(set: &'a mut [T], idxs: &'a [usize]) -> Result<Self, SubsetError> {
175 multi::SubsetMut::new(set, idxs)?.try_into()
176 }
177 pub unsafe fn new_unchecked(set: &'a mut [T], idxs: &'a [usize]) -> Self {
180 multi::SubsetMut::new_unchecked(set, idxs).to_unique_mut_unchecked()
181 }
182 pub fn set(&mut self) -> &mut [T] {
184 self.m.set()
185 }
186 pub fn idxs(&self) -> &[usize] {
188 self.m.idxs()
189 }
190 pub fn iter(&self) -> multi::Iter<T> {
192 self.m.iter()
193 }
194 pub fn iter_mut(&mut self) -> IterMut<T> {
196 IterMut {
197 ptr: self.m.set.as_mut_ptr(),
198 iter: self.m.idxs.iter()
199 }
200 }
201}
202
203
204impl<'a, T> TryFrom<multi::SubsetMut<'a, T>> for SubsetMut<'a, T> {
205 type Error = SubsetError;
206 fn try_from(s: multi::SubsetMut<'a, T>) -> Result<Self, SubsetError> {
207 if is_unique(s.idxs) {
208 Ok(unsafe{s.to_unique_mut_unchecked()})
209 } else {
210 Err(SubsetError::NotUnique)
211 }
212 }
213}
214
215
216impl<'a, T: 'a> Iterator for IterMut<'a, T> {
217 type Item = &'a mut T;
218 fn next(&mut self) -> Option<&'a mut T> {
219 unsafe {
220 match self.iter.next() {
221 None => None,
222 Some(idx) => Some(&mut *self.ptr.offset(*idx as isize))
223 }
224 }
225 }
226}
227
228
229impl<'a, T: 'a> DoubleEndedIterator for IterMut<'a, T> {
230 fn next_back(&mut self) -> Option<&'a mut T> {
231 unsafe {
232 match self.iter.next_back() {
233 None => None,
234 Some(idx) => Some(&mut *self.ptr.offset(*idx as isize))
235 }
236 }
237 }
238}
239
240
241impl<'a, T> IntoIterator for &'a SubsetMut<'a, T> {
242 type Item = &'a T;
243 type IntoIter = multi::Iter<'a, T>;
244 fn into_iter(self) -> multi::Iter<'a, T> {
245 self.iter()
246 }
247}
248
249
250impl<'a, T> IntoIterator for &'a mut SubsetMut<'a, T> {
251 type Item = &'a mut T;
252 type IntoIter = IterMut<'a, T>;
253 fn into_iter(self) -> IterMut<'a, T> {
254 self.iter_mut()
255 }
256}
257
258
259
260#[cfg(test)]
261mod tests {
262
263 use super::*;
264
265 #[test]
266 fn test_set() {
267 let set = vec![9, 8, 7, 6, 5, 4, 3, 2, 1, 0];
268 let idxs = vec![2, 2];
269 assert_eq!(Subset::new(&set, &idxs).err(), Some(SubsetError::NotUnique));
270 let idxs = vec![10];
271 assert_eq!(Subset::new(&set, &idxs).err(), Some(SubsetError::OutOfBounds));
272 let idxs = vec![2, 4, 7];
273 let subset = Subset::new(&set, &idxs).unwrap();
274 let mut sum = 0;
275 for e in subset.iter() {
276 sum += e;
277 }
278 assert_eq!(sum, 14);
279 let mut sum = 0;
280 for e in subset.iter().map(|v| 2*v).rev() {
281 sum += e;
282 }
283 assert_eq!(sum, 28);
284 }
285
286 #[test]
287 fn test_mut() {
288 let mut set = vec![9, 8, 7, 6, 5, 4, 3, 2, 1, 0];
289 let idxs = vec![2, 2];
290 assert_eq!(SubsetMut::new(&mut set, &idxs).err(), Some(SubsetError::NotUnique));
291 let idxs = vec![10];
292 assert_eq!(SubsetMut::new(&mut set, &idxs).err(), Some(SubsetError::OutOfBounds));
293 let idxs = vec![2, 4, 7];
294 let mut subset = SubsetMut::new(&mut set, &idxs).unwrap();
295 let mut iter = subset.iter_mut();
296 let r1 = iter.next().unwrap();
297 let r2 = iter.next().unwrap();
298 *r1 = 19;
299 *r2 = 33;
300 assert_eq!(subset.set(), vec![9, 8, 19, 6, 33, 4, 3, 2, 1, 0].as_slice());
301 let mut sum = 0;
302 for e in subset.iter().map(|v| 2* *v).rev() {
303 sum += e;
304 }
305 assert_eq!(sum, 108);
306 let result_into: crate::multi::SubsetMut<_> = subset.into();
307 assert!(result_into.is_unique());
308 assert_eq!(result_into.iter().fold(0, |accum, v| accum + *v), 54);
309 }
310}