flatk/subset.rs
1use super::*;
2use std::convert::AsRef;
3
4/// A Set that is a non-contiguous subset of some larger collection.
5/// `B` can be any borrowed collection type that implements the [`Set`], and [`RemovePrefix`]
6/// traits.
7/// For iteration of subsets, the underlying type must also implement [`SplitFirst`] and
8/// [`SplitAt`] traits.
9///
10/// # Example
11///
12/// The following example shows how to create a `Subset` from a standard `Vec`.
13///
14/// ```rust
15/// use flatk::*;
16/// let v = vec![1,2,3,4,5];
17/// let subset = Subset::from_indices(vec![0,2,4], v.as_slice());
18/// let mut subset_iter = subset.iter();
19/// assert_eq!(Some(&1), subset_iter.next());
20/// assert_eq!(Some(&3), subset_iter.next());
21/// assert_eq!(Some(&5), subset_iter.next());
22/// assert_eq!(None, subset_iter.next());
23/// ```
24///
25/// The next example shows how to create a `Subset` from a [`UniChunked`] collection.
26///
27/// ```rust
28/// use flatk::*;
29/// let mut v = Chunked3::from_flat(vec![1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]);
30/// let mut subset = Subset::from_indices(vec![0,2,4], v.view_mut());
31/// {
32/// let subset_view = subset.view();
33/// let mut subset_iter = subset_view.iter();
34/// assert_eq!(Some(&[1,2,3]), subset_iter.next());
35/// assert_eq!(Some(&[7,8,9]), subset_iter.next());
36/// assert_eq!(Some(&[13,14,15]), subset_iter.next());
37/// assert_eq!(None, subset_iter.next());
38/// }
39/// *subset.view_mut().isolate(1) = [0; 3];
40/// assert_eq!(&[0,0,0], subset.view().at(1));
41/// ```
42///
43/// # Translation independence
44///
45/// This struct is very similar to [`Chunked`], with the main difference being that
46/// each index corresponds to a single element instead of a chunk starting point.
47///
48/// Translation independence refers to the need to ensure that indices remain valid after
49/// splitting. When the indices are owned or mutably borrowed, we could simply modify the indices
50/// when we split the subset, but when the indices are a borrowed slice, this is not possible. To
51/// resolve this, we chop the part of data below the first index to ensure that the first index
52/// serves as an offset to the rest of the indices, making the entire index array translation
53/// independent.
54///
55/// Because `Subset`s modify the underlying data storage, it can often be misleading when querying
56/// the underlying data at any given time using one of [`Storage`], [`StorageMut`] or
57/// [`StorageView`] traits.
58///
59/// For a more transparent data structure that preserves the original data set,
60/// use [`Select`]. To expose any characteristics of the contained `data` type, use a trait.
61/// See [`ChunkSize`] for an example.
62///
63/// [`Select`]: struct.Select.html
64/// [`ChunkSize`]: trait.ChunkSize.html
65/// [`Chunked`]: struct.Chunked.html
66/// [`Storage`]: trait.Storage.html
67/// [`StorageMut`]: trait.StorageMut.html
68/// [`StorageView`]: trait.StorageView.html
69#[derive(Copy, Clone, Debug, PartialEq)]
70pub struct Subset<S, I = Box<[usize]>> {
71 /// An optional set of indices.
72 ///
73 /// When this is `None`, the subset is considered to be entire.
74 /// Empty subsets are represented by a zero length array of indices: either `Some(&[])` or
75 /// `Some(Vec::new())`.
76 pub(crate) indices: Option<I>,
77 pub(crate) data: S,
78}
79
80/// A borrowed subset.
81pub type SubsetView<'a, S> = Subset<S, &'a [usize]>;
82
83impl<S, I> Subset<S, I> {
84 /// Convert this subset into its internal representation.
85 #[inline]
86 pub fn into_raw(self) -> (Option<I>, S) {
87 (self.indices, self.data)
88 }
89
90 /// Construct a subset from a set of indices and a data set.
91 ///
92 /// Note that independent of the value of the indices, the first element in the subset will be
93 /// the first element in `data`, and all subsequent elements are taken from `data[index -
94 /// first]` for each `index` in `indices` where `first` is the first index appearing in
95 /// `indices`.
96 ///
97 /// # Safety
98 ///
99 /// Constructing an invalid subset using this function isn't itself unsafe, however calling
100 /// various functions (except for [`Subset::validate`]) may be unsafe.
101 ///
102 /// The given indices must be unique and in accending sorted order.
103 /// All indices (minus the first) must be strictly less than the number of elements in `data`.
104 ///
105 /// The `Subset` can be validated explicitly after creation using [`Subset::validate`].
106 ///
107 /// [`Subset::validate`]: function.Subset.validate.html
108 #[inline]
109 pub unsafe fn from_raw(indices: Option<I>, data: S) -> Subset<S, I> {
110 Subset { indices, data }
111 }
112}
113
114impl<S: Set + RemovePrefix> Subset<S, Vec<usize>> {
115 /// Create a subset of elements from the original set given at the specified indices.
116 ///
117 /// # Example
118 ///
119 /// ```rust
120 /// use flatk::*;
121 /// let v = vec![1,2,3];
122 /// let subset = Subset::from_indices(vec![0,2], v.as_slice());
123 /// assert_eq!(1, subset[0]);
124 /// assert_eq!(3, subset[1]);
125 /// ```
126 pub fn from_indices(mut indices: Vec<usize>, mut data: S) -> Self {
127 // Ensure that indices are sorted and there are no duplicates.
128 // Failure to enforce this invariant can cause race conditions.
129
130 indices.sort_unstable();
131 indices.dedup();
132
133 if let Some(first) = indices.first() {
134 data.remove_prefix(*first);
135 }
136
137 Self::validate(Subset {
138 indices: Some(indices),
139 data,
140 })
141 }
142}
143
144impl<S: Set + RemovePrefix, I: AsRef<[usize]>> Subset<S, I> {
145 /// Create a subset of elements from the original collection corresponding to the given
146 /// indices.
147 ///
148 /// In contrast to `Subset::from_indices`, this function expects the indices
149 /// to be unique and in sorted order, instead of manully making it so.
150 ///
151 /// # Panics
152 ///
153 /// This function panics when given a collection of unsorted indices.
154 /// It also panics when indices are repeated.
155 ///
156 /// # Example
157 ///
158 /// ```rust
159 /// use flatk::*;
160 /// let v = vec![0,1,2,3];
161 /// let indices = vec![1,3];
162 ///
163 /// let subset_view = Subset::from_unique_ordered_indices(indices.as_slice(), v.as_slice());
164 /// assert_eq!(1, subset_view[0]);
165 /// assert_eq!(3, subset_view[1]);
166 ///
167 /// let subset = Subset::from_unique_ordered_indices(indices, v.as_slice());
168 /// assert_eq!(1, subset[0]);
169 /// assert_eq!(3, subset[1]);
170 /// ```
171 pub fn from_unique_ordered_indices(indices: I, mut data: S) -> Self {
172 // Ensure that indices are sorted and there are no duplicates.
173
174 assert!(Self::is_sorted(&indices));
175 assert!(!Self::has_duplicates(&indices));
176
177 if let Some(first) = indices.as_ref().first() {
178 data.remove_prefix(*first);
179 }
180
181 Self::validate(Subset {
182 indices: Some(indices),
183 data,
184 })
185 }
186}
187
188impl<S> Subset<S> {
189 /// Create a subset with all elements from the original set.
190 ///
191 /// # Example
192 ///
193 /// ```rust
194 /// use flatk::*;
195 /// let subset = Subset::all::<Box<_>>(vec![1,2,3]);
196 /// let subset_view = subset.view();
197 /// let mut subset_iter = subset_view.iter();
198 /// assert_eq!(Some(&1), subset_iter.next());
199 /// assert_eq!(Some(&2), subset_iter.next());
200 /// assert_eq!(Some(&3), subset_iter.next());
201 /// assert_eq!(None, subset_iter.next());
202 /// ```
203 #[inline]
204 pub fn all<I>(data: S) -> Subset<S, I> {
205 Subset {
206 indices: None,
207 data,
208 }
209 }
210
211 /// Create a subset with all elements from the original set.
212 ///
213 /// This version of `all` creates the `Subset` type with the default index type, since it
214 /// cannot be determined from the function arguments. In other words this function doesn't
215 /// require an additional generic parameter to be specified when the return type is ambiguous.
216 ///
217 /// # Example
218 ///
219 /// ```rust
220 /// use flatk::*;
221 /// let subset = Subset::all_def(vec![1,2,3]);
222 /// let subset_view = subset.view();
223 /// let mut subset_iter = subset_view.iter();
224 /// assert_eq!(Some(&1), subset_iter.next());
225 /// assert_eq!(Some(&2), subset_iter.next());
226 /// assert_eq!(Some(&3), subset_iter.next());
227 /// assert_eq!(None, subset_iter.next());
228 /// ```
229 #[inline]
230 pub fn all_def(data: S) -> Subset<S> {
231 Self::all(data)
232 }
233}
234
235impl<S: Set, I: AsRef<[usize]>> Subset<S, I> {
236 /// Find an element in the subset by its index in the superset. Return the index of the element
237 /// in the subset if found.
238 /// Since subset indices are always in sorted order, this function performs a binary search.
239 ///
240 /// # Examples
241 ///
242 /// In the following simple example the element `3` is found at superset index `2` which is
243 /// located at index `1` in the subset.
244 ///
245 /// ```
246 /// use flatk::*;
247 /// let superset = vec![1,2,3,4,5,6];
248 /// let subset = Subset::from_unique_ordered_indices(vec![1,2,5], superset);
249 /// assert_eq!(Some(1), subset.find_by_index(2));
250 /// assert_eq!(None, subset.find_by_index(3));
251 /// ```
252 ///
253 /// Note that the superset index refers to the indices with which the subset was created. This
254 /// means that even after we have split the subset, the input indices are expected to refer to
255 /// the original subset. The following example demonstrates this by splitting the original
256 /// subset in the pervious example.
257 ///
258 /// ```
259 /// use flatk::*;
260 /// let superset = vec![1,2,3,4,5,6];
261 /// let subset = Subset::from_unique_ordered_indices(vec![1,2,5], superset);
262 /// let (_, r) = subset.view().split_at(1);
263 /// assert_eq!(Some(0), r.find_by_index(2));
264 /// assert_eq!(None, r.find_by_index(3));
265 /// ```
266 pub fn find_by_index(&self, index: usize) -> Option<usize> {
267 match &self.indices {
268 Some(indices) => indices.as_ref().binary_search(&index).ok(),
269 None => {
270 // If the subset is entire, then we know the element is contained.
271 Some(index)
272 }
273 }
274 }
275}
276
277impl<'a, S, I: AsRef<[usize]>> Subset<S, I> {
278 /// A helper function that checks if a given collection of indices has duplicates.
279 /// It is assumed that the given indices are already in sorted order.
280 fn has_duplicates(indices: &I) -> bool {
281 let mut index_iter = indices.as_ref().iter().cloned();
282 if let Some(mut prev) = index_iter.next() {
283 for cur in index_iter {
284 if cur == prev {
285 return true;
286 } else {
287 prev = cur;
288 }
289 }
290 }
291 false
292 }
293
294 /// Checks that the given set of indices are sorted.
295 // TODO: replace this with std version when RFC 2351 lands
296 // (https://github.com/rust-lang/rust/issues/53485)
297 #[inline]
298 fn is_sorted(indices: &I) -> bool {
299 Self::is_sorted_by(indices, |a, b| a.partial_cmp(b))
300 }
301
302 /// Checks that the given set of indices are sorted by the given compare function.
303 #[allow(clippy::while_let_on_iterator)]
304 fn is_sorted_by<F>(indices: &I, mut compare: F) -> bool
305 where
306 F: FnMut(&usize, &usize) -> Option<std::cmp::Ordering>,
307 {
308 let mut iter = indices.as_ref().iter();
309 let mut last = match iter.next() {
310 Some(e) => e,
311 None => return true,
312 };
313
314 while let Some(curr) = iter.next() {
315 if compare(last, curr)
316 .map(|o| o == std::cmp::Ordering::Greater)
317 .unwrap_or(true)
318 {
319 return false;
320 }
321 last = curr;
322 }
323
324 true
325 }
326}
327
328impl<'a, S: Set, I> Subset<S, I> {
329 /// Get a references to the underlying indices. If `None` is returned, then
330 /// this subset spans the entire domain `data`.
331 #[inline]
332 pub fn indices(&self) -> Option<&I> {
333 self.indices.as_ref()
334 }
335
336 /// Return the superset of this `Subset`. This is just the set it was created with.
337 #[inline]
338 pub fn into_super(self) -> S {
339 self.data
340 }
341}
342
343impl<'a, S: Set, I: AsRef<[usize]>> Subset<S, I> {
344 /// Panics if this subset is invald.
345 #[inline]
346 fn validate(self) -> Self {
347 if let Some(ref indices) = self.indices {
348 let indices = indices.as_ref();
349 if let Some(first) = indices.first() {
350 for &i in indices.iter() {
351 assert!(i - *first < self.data.len(), "Subset index out of bounds.");
352 }
353 }
354 }
355 self
356 }
357}
358
359// Note to self:
360// To enable a collection to be chunked, we need to implement:
361// Set, View, SplitAt
362// For mutability we also need ViewMut,
363// For UniChunked we need:
364// Set, Vew, IntoStaticChunkIterator
365
366/// Required for `Chunked` and `UniChunked` subsets.
367impl<S: Set, I: AsRef<[usize]>> Set for Subset<S, I> {
368 type Elem = S::Elem;
369 type Atom = S::Atom;
370 /// Get the length of this subset.
371 ///
372 /// # Example
373 ///
374 /// ```rust
375 /// use flatk::*;
376 /// let v = vec![1,2,3,4,5];
377 /// let subset = Subset::from_indices(vec![0,2,4], v.as_slice());
378 /// assert_eq!(3, subset.len());
379 /// ```
380 #[inline]
381 fn len(&self) -> usize {
382 self.indices
383 .as_ref()
384 .map_or(self.data.len(), |indices| indices.as_ref().len())
385 }
386}
387
388/// Required for `Chunked` and `UniChunked` subsets.
389impl<'a, S, I> View<'a> for Subset<S, I>
390where
391 S: View<'a>,
392 I: AsRef<[usize]>,
393{
394 type Type = Subset<S::Type, &'a [usize]>;
395 #[inline]
396 fn view(&'a self) -> Self::Type {
397 // Note: it is assumed that the first index corresponds to the first
398 // element in data, regardless of what the value of the index is.
399 Subset {
400 indices: self.indices.as_ref().map(|indices| indices.as_ref()),
401 data: self.data.view(),
402 }
403 }
404}
405
406impl<'a, S, I> ViewMut<'a> for Subset<S, I>
407where
408 S: ViewMut<'a>,
409 I: AsRef<[usize]>,
410{
411 type Type = Subset<S::Type, &'a [usize]>;
412 /// Create a mutable view into this subset.
413 ///
414 /// # Example
415 ///
416 /// ```rust
417 /// use flatk::*;
418 /// let mut v = vec![1,2,3,4,5];
419 /// let mut subset = Subset::from_indices(vec![0,2,4], v.as_mut_slice());
420 /// let mut view = subset.view_mut();
421 /// for i in view.iter_mut() {
422 /// *i += 1;
423 /// }
424 /// assert_eq!(v, vec![2,2,4,4,6]);
425 /// ```
426 #[inline]
427 fn view_mut(&'a mut self) -> Self::Type {
428 // Note: it is assumed that the first index corresponds to the first
429 // element in data, regardless of what the value of the index is.
430 Subset {
431 indices: self.indices.as_ref().map(|indices| indices.as_ref()),
432 data: self.data.view_mut(),
433 }
434 }
435}
436
437/// This impl enables `Chunked` `Subset`s
438impl<V> SplitAt for SubsetView<'_, V>
439where
440 V: Set + SplitAt,
441{
442 /// Split this subset into two at the given index `mid`.
443 ///
444 /// # Example
445 ///
446 /// ```rust
447 /// use flatk::*;
448 /// let v = vec![1,2,3,4,5];
449 /// let indices = vec![0,2,4];
450 /// let subset = Subset::from_unique_ordered_indices(indices.as_slice(), v.as_slice());
451 /// let (l, r) = subset.split_at(1);
452 /// let mut iter_l = l.iter();
453 /// assert_eq!(Some(&1), iter_l.next());
454 /// assert_eq!(None, iter_l.next());
455 /// let mut iter_r = r.iter();
456 /// assert_eq!(Some(&3), iter_r.next());
457 /// assert_eq!(Some(&5), iter_r.next());
458 /// assert_eq!(None, iter_r.next());
459 /// ```
460 #[inline]
461 fn split_at(self, mid: usize) -> (Self, Self) {
462 if let Some(indices) = self.indices {
463 let (indices_l, indices_r) = indices.split_at(mid);
464 let n = self.data.len();
465 let offset = indices_r
466 .first()
467 .map(|first| *first - *indices_l.first().unwrap_or(first))
468 .unwrap_or(n);
469 let (data_l, data_r) = self.data.split_at(offset);
470 (
471 Subset {
472 indices: Some(indices_l),
473 data: data_l,
474 },
475 Subset {
476 indices: Some(indices_r),
477 data: data_r,
478 },
479 )
480 } else {
481 let (data_l, data_r) = self.data.split_at(mid);
482 (
483 Subset {
484 indices: None,
485 data: data_l,
486 },
487 Subset {
488 indices: None,
489 data: data_r,
490 },
491 )
492 }
493 }
494}
495
496/// This impl enables `Subset`s of `Subset`s
497impl<S, I> SplitFirst for Subset<S, I>
498where
499 I: SplitFirst + AsRef<[usize]>,
500 <I as SplitFirst>::First: std::borrow::Borrow<usize>,
501 S: Set + SplitAt + SplitFirst,
502{
503 type First = S::First;
504
505 /// Split the first element of this subset.
506 #[inline]
507 fn split_first(self) -> Option<(Self::First, Self)> {
508 use std::borrow::Borrow;
509 let Subset { data, indices } = self;
510 if let Some(indices) = indices {
511 indices.split_first().map(|(first_index, rest_indices)| {
512 let n = data.len();
513 let offset = rest_indices
514 .as_ref()
515 .first()
516 .map(|next| *next - *first_index.borrow())
517 .unwrap_or(n);
518 let (data_l, data_r) = data.split_at(offset);
519 (
520 data_l.split_first().unwrap().0,
521 Subset {
522 indices: Some(rest_indices),
523 data: data_r,
524 },
525 )
526 })
527 } else {
528 data.split_first().map(|(first, rest)| {
529 (
530 first,
531 Subset {
532 indices: None,
533 data: rest,
534 },
535 )
536 })
537 }
538 }
539}
540
541impl<S: Set + RemovePrefix, I: RemovePrefix + AsRef<[usize]>> RemovePrefix for Subset<S, I> {
542 /// This function will panic if `n` is larger than `self.len()`.
543 #[inline]
544 fn remove_prefix(&mut self, n: usize) {
545 if n == 0 {
546 return;
547 }
548 match self.indices {
549 Some(ref mut indices) => {
550 let first = indices.as_ref()[0]; // Will panic if out of bounds.
551 indices.remove_prefix(n);
552 let data_len = self.data.len();
553 let next = indices.as_ref().get(0).unwrap_or(&data_len);
554 self.data.remove_prefix(*next - first);
555 }
556 None => {
557 self.data.remove_prefix(n);
558 }
559 }
560 }
561}
562
563impl<'a, S, I> Subset<S, I>
564where
565 Self: Set + ViewIterator<'a>,
566{
567 /// The typical way to use this function is to clone from a `SubsetView`
568 /// into an owned `S` type.
569 ///
570 /// # Panics
571 ///
572 /// This function panics if `other` has a length unequal to `self.len()`.
573 ///
574 /// # Example
575 ///
576 /// ```rust
577 /// use flatk::*;
578 /// let v = vec![1,2,3,4,5];
579 /// let indices = vec![0,2,4];
580 /// let subset = Subset::from_unique_ordered_indices(indices.as_slice(), v.as_slice());
581 /// let mut owned = vec![0; 4];
582 /// subset.clone_into_other(&mut owned[..3]); // Need 3 elements to avoid panics.
583 /// let mut iter_owned = owned.iter();
584 /// assert_eq!(owned, vec![1,3,5,0]);
585 /// ```
586 pub fn clone_into_other<V>(&'a self, other: &'a mut V)
587 where
588 V: Set + ViewMutIterator<'a> + ?Sized,
589 <Self as ViewIterator<'a>>::Item: CloneIntoOther<<V as ViewMutIterator<'a>>::Item>,
590 {
591 assert_eq!(other.len(), self.len());
592 for (mut theirs, mine) in other.view_mut_iter().zip(self.view_iter()) {
593 mine.clone_into_other(&mut theirs);
594 }
595 }
596}
597
598/*
599 * Indexing operators for convenience. Users familiar with indexing by `usize`
600 * may find these implementations convenient.
601 */
602
603impl<'a, S, O> GetIndex<'a, Subset<S, O>> for usize
604where
605 O: AsRef<[usize]>,
606 S: Get<'a, usize>,
607{
608 type Output = <S as Get<'a, usize>>::Output;
609
610 #[inline]
611 fn get(self, subset: &Subset<S, O>) -> Option<Self::Output> {
612 // TODO: too much bounds checking here, add a get_unchecked call to GetIndex.
613 if let Some(ref indices) = subset.indices {
614 indices.as_ref().get(0).and_then(|&first| {
615 indices
616 .as_ref()
617 .get(self)
618 .and_then(|&cur| Get::get(&subset.data, cur - first))
619 })
620 } else {
621 Get::get(&subset.data, self)
622 }
623 }
624}
625
626impl<'a, S, O> GetIndex<'a, Subset<S, O>> for &usize
627where
628 O: AsRef<[usize]>,
629 S: Get<'a, usize>,
630{
631 type Output = <S as Get<'a, usize>>::Output;
632
633 #[inline]
634 fn get(self, subset: &Subset<S, O>) -> Option<Self::Output> {
635 GetIndex::get(*self, subset)
636 }
637}
638
639impl<S, O> IsolateIndex<Subset<S, O>> for usize
640where
641 O: AsRef<[usize]>,
642 S: Isolate<usize>,
643{
644 type Output = <S as Isolate<usize>>::Output;
645
646 #[inline]
647 unsafe fn isolate_unchecked(self, subset: Subset<S, O>) -> Self::Output {
648 let Subset { indices, data } = subset;
649 Isolate::isolate_unchecked(
650 data,
651 if let Some(ref indices) = indices {
652 let cur = indices.as_ref().get_unchecked(self);
653 let first = indices.as_ref().get_unchecked(0);
654 cur - first
655 } else {
656 self
657 },
658 )
659 }
660
661 #[inline]
662 fn try_isolate(self, subset: Subset<S, O>) -> Option<Self::Output> {
663 let Subset { indices, data } = subset;
664 Isolate::try_isolate(
665 data,
666 if let Some(ref indices) = indices {
667 let cur = indices.as_ref().get(self)?;
668 // SAFETY: self must be at least zero, and we just checked it above.
669 let first = unsafe { indices.as_ref().get_unchecked(0) };
670 cur - first
671 } else {
672 self
673 },
674 )
675 }
676}
677
678impl_isolate_index_for_static_range!(impl<S, O> for Subset<S, O>);
679
680//impl<S, I, O> Isolate<I> for Subset<S, O>
681//where
682// I: IsolateIndex<Self>,
683//{
684// type Output = I::Output;
685//
686// fn try_isolate(self, range: I) -> Option<Self::Output> {
687// range.try_isolate(self)
688// }
689//}
690
691macro_rules! impl_index_fn {
692 ($self:ident, $idx:ident, $index_fn:ident) => {
693 $self
694 .data
695 .$index_fn($self.indices.as_ref().map_or($idx, |indices| {
696 let indices = indices.as_ref();
697 indices[$idx] - *indices.first().unwrap()
698 }))
699 };
700}
701
702impl<'a, S, I> std::ops::Index<usize> for Subset<S, I>
703where
704 S: std::ops::Index<usize> + Set + ValueType,
705 I: AsRef<[usize]>,
706{
707 type Output = S::Output;
708
709 /// Immutably index the subset.
710 ///
711 /// # Panics
712 ///
713 /// This function panics if the index is out of bounds or if the subset is empty.
714 ///
715 /// # Example
716 ///
717 /// ```rust
718 /// use flatk::*;
719 /// let c = Chunked2::from_flat((1..=12).collect::<Vec<_>>());
720 /// let subset = Subset::from_indices(vec![0,2,4], c.view());
721 /// assert_eq!([1,2], subset[0]);
722 /// assert_eq!([5,6], subset[1]);
723 /// assert_eq!([9,10], subset[2]);
724 /// ```
725 #[inline]
726 fn index(&self, idx: usize) -> &Self::Output {
727 impl_index_fn!(self, idx, index)
728 }
729}
730
731impl<'a, S, I> std::ops::IndexMut<usize> for Subset<S, I>
732where
733 S: std::ops::IndexMut<usize> + Set + ValueType,
734 I: AsRef<[usize]>,
735{
736 /// Mutably index the subset.
737 ///
738 /// # Panics
739 ///
740 /// This function panics if the index is out of bounds or if the subset is empty.
741 ///
742 /// # Example
743 ///
744 /// ```rust
745 /// use flatk::*;
746 /// let mut v = vec![1,2,3,4,5];
747 /// let mut subset = Subset::from_indices(vec![0,2,4], v.as_mut_slice());
748 /// assert_eq!(subset[1], 3);
749 /// subset[1] = 100;
750 /// assert_eq!(subset[0], 1);
751 /// assert_eq!(subset[1], 100);
752 /// assert_eq!(subset[2], 5);
753 /// ```
754 #[inline]
755 fn index_mut(&mut self, idx: usize) -> &mut Self::Output {
756 impl_index_fn!(self, idx, index_mut)
757 }
758}
759
760impl<'a, T, I> std::ops::Index<usize> for Subset<&'a [T], I>
761where
762 I: AsRef<[usize]>,
763{
764 type Output = T;
765 /// Immutably index the subset.
766 ///
767 /// # Panics
768 ///
769 /// This function panics if the index is out of bounds or if the subset is empty.
770 ///
771 /// # Example
772 ///
773 /// ```rust
774 /// use flatk::*;
775 /// let v = vec![1,2,3,4,5];
776 /// let subset = Subset::from_indices(vec![0,2,4], v.as_slice());
777 /// assert_eq!(3, subset[1]);
778 /// ```
779 #[inline]
780 fn index(&self, idx: usize) -> &Self::Output {
781 impl_index_fn!(self, idx, index)
782 }
783}
784
785impl<'a, T, I> std::ops::Index<usize> for Subset<&'a mut [T], I>
786where
787 I: AsRef<[usize]>,
788{
789 type Output = T;
790 /// Immutably index the subset.
791 ///
792 /// # Panics
793 ///
794 /// This function panics if the index is out of bounds or if the subset is empty.
795 ///
796 /// # Example
797 ///
798 /// ```rust
799 /// use flatk::*;
800 /// let mut v = vec![1,2,3,4,5];
801 /// let mut subset = Subset::from_indices(vec![0,2,4], v.as_mut_slice());
802 /// assert_eq!(3, subset[1]);
803 /// ```
804 #[inline]
805 fn index(&self, idx: usize) -> &Self::Output {
806 impl_index_fn!(self, idx, index)
807 }
808}
809
810impl<'a, T, I> std::ops::IndexMut<usize> for Subset<&'a mut [T], I>
811where
812 I: AsRef<[usize]>,
813{
814 /// Mutably index the subset.
815 ///
816 /// # Panics
817 ///
818 /// This function panics if the index is out of bounds or if the subset is empty.
819 ///
820 /// # Example
821 ///
822 /// ```rust
823 /// use flatk::*;
824 /// let mut v = vec![1,2,3,4,5];
825 /// let mut subset = Subset::from_indices(vec![0,2,4], v.as_mut_slice());
826 /// assert_eq!(subset[1], 3);
827 /// subset[1] = 100;
828 /// assert_eq!(subset[0], 1);
829 /// assert_eq!(subset[1], 100);
830 /// assert_eq!(subset[2], 5);
831 /// ```
832 #[inline]
833 fn index_mut(&mut self, idx: usize) -> &mut Self::Output {
834 impl_index_fn!(self, idx, index_mut)
835 }
836}
837
838/*
839 * Iteration
840 */
841
842impl<S, I> IntoIterator for Subset<S, I>
843where
844 S: SplitAt + SplitFirst + Set + Dummy,
845 I: SplitFirst + Clone,
846 <I as SplitFirst>::First: std::borrow::Borrow<usize>,
847{
848 type Item = S::First;
849 type IntoIter = SubsetIter<S, I>;
850
851 /// Convert a `Subset` into an iterator.
852 ///
853 /// # Example
854 ///
855 /// ```rust
856 /// use flatk::*;
857 /// let mut s = Subset::from_unique_ordered_indices(vec![1,3,5], vec![1,2,3,4,5,6]);
858 /// let mut iter = s.view().into_iter();
859 /// assert_eq!(Some(&2), iter.next());
860 /// assert_eq!(Some(&4), iter.next());
861 /// assert_eq!(Some(&6), iter.next());
862 /// assert_eq!(None, iter.next());
863 /// ```
864 #[inline]
865 fn into_iter(self) -> Self::IntoIter {
866 SubsetIter {
867 indices: self.indices,
868 data: self.data,
869 }
870 }
871}
872
873// Iterator for `Subset`s
874pub struct SubsetIter<S, I> {
875 indices: Option<I>,
876 data: S,
877}
878
879// TODO: This can be made more efficient with two distinct iterators, thus eliminating the branch
880// on indices.
881impl<S, I> Iterator for SubsetIter<S, I>
882where
883 S: SplitAt + SplitFirst + Set + Dummy,
884 I: SplitFirst + Clone,
885 <I as SplitFirst>::First: std::borrow::Borrow<usize>,
886{
887 type Item = S::First;
888
889 #[inline]
890 fn next(&mut self) -> Option<Self::Item> {
891 use std::borrow::Borrow;
892 let SubsetIter { indices, data } = self;
893 let data_slice = std::mem::replace(data, unsafe { Dummy::dummy() });
894 match indices {
895 Some(ref mut indices) => indices.clone().split_first().map(|(first, rest)| {
896 let (item, right) = data_slice.split_first().expect("Corrupt subset");
897 if let Some((second, _)) = rest.clone().split_first() {
898 let (_, r) = right.split_at(*second.borrow() - *first.borrow() - 1);
899 *data = r;
900 } else {
901 // No more elements, the rest is empty, just discard the rest of data.
902 // An alternative implementation simply assigns data to the empty version of S.
903 // This would require additional traits so we settle for this possibly less
904 // efficient version for now.
905 let n = right.len();
906 let (_, r) = right.split_at(n);
907 *data = r;
908 }
909 *indices = rest;
910 item
911 }),
912 None => data_slice.split_first().map(|(item, rest)| {
913 *data = rest;
914 item
915 }),
916 }
917 }
918}
919
920// Iterator for `Subset` indices.
921pub enum SubsetIndexIter<'a> {
922 All(std::ops::Range<usize>),
923 Sub(&'a [usize]),
924}
925
926impl<'a> Iterator for SubsetIndexIter<'a> {
927 type Item = usize;
928
929 #[inline]
930 fn next(&mut self) -> Option<Self::Item> {
931 match self {
932 SubsetIndexIter::Sub(ref mut indices) => indices.split_first().map(|(first, rest)| {
933 *indices = rest;
934 *first
935 }),
936 SubsetIndexIter::All(ref mut rng) => rng.next(),
937 }
938 }
939 #[inline]
940 fn nth(&mut self, n: usize) -> Option<Self::Item> {
941 match self {
942 SubsetIndexIter::Sub(ref mut indices) => {
943 if n >= indices.len() {
944 None
945 } else {
946 // SAFETY: the bounds are checked above.
947 unsafe {
948 let item = *indices.get_unchecked(n);
949 *indices = indices.get_unchecked(n + 1..);
950 Some(item)
951 }
952 }
953 }
954 SubsetIndexIter::All(ref mut rng) => rng.nth(n),
955 }
956 }
957}
958
959impl<'a, S, I> Subset<S, I>
960where
961 S: Set + View<'a>,
962 I: AsRef<[usize]>,
963{
964 /// Immutably iterate over a borrowed subset.
965 ///
966 /// # Example
967 ///
968 /// ```rust
969 /// use flatk::*;
970 /// let mut v = vec![1,2,3,4,5];
971 /// let mut subset = Subset::from_indices(vec![0,2,4], v.as_mut_slice());
972 /// let mut iter = subset.iter();
973 /// assert_eq!(Some(&1), iter.next());
974 /// assert_eq!(Some(&3), iter.next());
975 /// assert_eq!(Some(&5), iter.next());
976 /// assert_eq!(None, iter.next());
977 /// ```
978 #[inline]
979 pub fn iter(&'a self) -> SubsetIter<S::Type, &'a [usize]> {
980 SubsetIter {
981 indices: self.indices.as_ref().map(|indices| indices.as_ref()),
982 data: self.data.view(),
983 }
984 }
985
986 /// Immutably iterate over the indices stored by this subset.
987 ///
988 /// The returned indices point to the superset from which this subset was created.
989 ///
990 /// # Example
991 ///
992 /// ```rust
993 /// use flatk::*;
994 /// let mut v = vec![1,2,3,4,5];
995 /// let mut subset = Subset::from_indices(vec![0,2,4], v.as_mut_slice());
996 /// let mut iter = subset.index_iter();
997 /// assert_eq!(Some(0), iter.next());
998 /// assert_eq!(Some(2), iter.next());
999 /// assert_eq!(Some(4), iter.next());
1000 /// assert_eq!(None, iter.next());
1001 /// ```
1002 ///
1003 /// This also works if the subset is entire:
1004 ///
1005 /// ```
1006 /// use flatk::*;
1007 /// let mut v = vec![1,2,3,4,5];
1008 /// let mut subset = Subset::all_def(v.as_slice());
1009 /// let mut iter = subset.index_iter();
1010 /// assert_eq!(Some(0), iter.next());
1011 /// assert_eq!(Some(3), iter.nth(2));
1012 /// assert_eq!(Some(4), iter.next());
1013 /// assert_eq!(None, iter.next());
1014 /// ```
1015 #[inline]
1016 pub fn index_iter(&'a self) -> SubsetIndexIter<'a> {
1017 match self.indices {
1018 Some(ref indices) => SubsetIndexIter::Sub(indices.as_ref()),
1019 None => SubsetIndexIter::All(0..self.data.len()),
1020 }
1021 }
1022}
1023
1024impl<'a, S, I> Subset<S, I>
1025where
1026 S: Set + ViewMut<'a>,
1027 I: AsRef<[usize]>,
1028{
1029 /// Mutably iterate over a borrowed subset.
1030 ///
1031 /// # Example
1032 ///
1033 /// ```rust
1034 /// use flatk::*;
1035 /// let mut v = vec![1,2,3,4,5];
1036 /// let mut subset = Subset::from_indices(vec![0,2,4], v.as_mut_slice());
1037 /// for i in subset.iter_mut() {
1038 /// *i += 1;
1039 /// }
1040 /// assert_eq!(v, vec![2,2,4,4,6]);
1041 /// ```
1042 #[inline]
1043 pub fn iter_mut(&'a mut self) -> SubsetIter<<S as ViewMut<'a>>::Type, &'a [usize]> {
1044 SubsetIter {
1045 indices: self.indices.as_ref().map(|indices| indices.as_ref()),
1046 data: self.data.view_mut(),
1047 }
1048 }
1049}
1050
1051impl<'a, S, I> ViewIterator<'a> for Subset<S, I>
1052where
1053 S: Set + View<'a>,
1054 I: AsRef<[usize]>,
1055 <S as View<'a>>::Type: SplitAt + SplitFirst + Set + Dummy,
1056{
1057 type Item = <<S as View<'a>>::Type as SplitFirst>::First;
1058 type Iter = SubsetIter<S::Type, &'a [usize]>;
1059
1060 #[inline]
1061 fn view_iter(&'a self) -> Self::Iter {
1062 self.iter()
1063 }
1064}
1065
1066impl<'a, S, I> ViewMutIterator<'a> for Subset<S, I>
1067where
1068 S: Set + ViewMut<'a>,
1069 I: AsRef<[usize]>,
1070 <S as ViewMut<'a>>::Type: SplitAt + SplitFirst + Set + Dummy,
1071{
1072 type Item = <<S as ViewMut<'a>>::Type as SplitFirst>::First;
1073 type Iter = SubsetIter<S::Type, &'a [usize]>;
1074
1075 #[inline]
1076 fn view_mut_iter(&'a mut self) -> Self::Iter {
1077 self.iter_mut()
1078 }
1079}
1080
1081impl<S: Dummy, I> Dummy for Subset<S, I> {
1082 #[inline]
1083 unsafe fn dummy() -> Self {
1084 Subset {
1085 data: Dummy::dummy(),
1086 indices: None,
1087 }
1088 }
1089}
1090
1091impl<S: Truncate, I: Truncate> Truncate for Subset<S, I> {
1092 #[inline]
1093 fn truncate(&mut self, new_len: usize) {
1094 match &mut self.indices {
1095 // The target data remains untouched.
1096 Some(indices) => indices.truncate(new_len),
1097 // Since the subset is entire it's ok to truncate the underlying data.
1098 None => self.data.truncate(new_len),
1099 }
1100 }
1101}
1102
1103/*
1104 * Conversions
1105 */
1106
1107// TODO: Add conversions for other subsets.
1108
1109//impl<T> From<T> for Subset<T> {
1110// fn from(v: T) -> Subset<T> {
1111// Subset::all(v)
1112// }
1113//}
1114
1115/// Pass through the conversion for structure type `Subset`.
1116impl<S: StorageInto<T>, I, T> StorageInto<T> for Subset<S, I> {
1117 type Output = Subset<S::Output, I>;
1118 #[inline]
1119 fn storage_into(self) -> Self::Output {
1120 Subset {
1121 data: self.data.storage_into(),
1122 indices: self.indices,
1123 }
1124 }
1125}
1126
1127impl<S: MapStorage<Out>, I, Out> MapStorage<Out> for Subset<S, I> {
1128 type Input = S::Input;
1129 type Output = Subset<S::Output, I>;
1130 #[inline]
1131 fn map_storage<F: FnOnce(Self::Input) -> Out>(self, f: F) -> Self::Output {
1132 Subset {
1133 data: self.data.map_storage(f),
1134 indices: self.indices,
1135 }
1136 }
1137}
1138
1139/*
1140 * Data access
1141 */
1142
1143impl<'a, S: StorageView<'a>, I> StorageView<'a> for Subset<S, I> {
1144 type StorageView = S::StorageView;
1145 /// Return a view to the underlying storage type.
1146 ///
1147 /// # Example
1148 ///
1149 /// ```rust
1150 /// use flatk::*;
1151 /// let v = vec![1,2,3,4,5,6,7,8,9,10,11,12];
1152 /// let s0 = Chunked3::from_flat(v.clone());
1153 /// let s1 = Subset::from_indices(vec![0, 2, 3], s0.clone());
1154 /// assert_eq!(s1.storage_view(), v.as_slice());
1155 /// ```
1156 #[inline]
1157 fn storage_view(&'a self) -> Self::StorageView {
1158 self.data.storage_view()
1159 }
1160}
1161
1162impl<S: Storage, I> Storage for Subset<S, I> {
1163 type Storage = S::Storage;
1164 /// Return an immutable reference to the underlying storage type.
1165 ///
1166 /// # Example
1167 ///
1168 /// ```rust
1169 /// use flatk::*;
1170 /// let v = vec![1,2,3,4,5,6,7,8,9,10,11,12];
1171 /// let s0 = Chunked3::from_flat(v.clone());
1172 /// let s1 = Subset::from_indices(vec![0, 2, 3], s0.clone());
1173 /// assert_eq!(s1.storage(), &v);
1174 /// ```
1175 #[inline]
1176 fn storage(&self) -> &Self::Storage {
1177 self.data.storage()
1178 }
1179}
1180
1181impl<S: StorageMut, I> StorageMut for Subset<S, I> {
1182 /// Return a mutable reference to the underlying storage type.
1183 ///
1184 /// # Example
1185 ///
1186 /// ```rust
1187 /// use flatk::*;
1188 /// let mut v = vec![1,2,3,4,5,6,7,8,9,10,11,12];
1189 /// let mut s0 = Chunked3::from_flat(v.clone());
1190 /// let mut s1 = Subset::from_indices(vec![0, 2, 3], s0.clone());
1191 /// assert_eq!(s1.storage_mut(), &mut v);
1192 /// ```
1193 #[inline]
1194 fn storage_mut(&mut self) -> &mut Self::Storage {
1195 self.data.storage_mut()
1196 }
1197}
1198
1199/*
1200 * Subsets of uniformly chunked collections
1201 */
1202
1203impl<S: ChunkSize, I> ChunkSize for Subset<S, I> {
1204 #[inline]
1205 fn chunk_size(&self) -> usize {
1206 self.data.chunk_size()
1207 }
1208}
1209
1210impl<S: ChunkSize, I, N: Dimension> Subset<UniChunked<S, N>, I> {
1211 #[inline]
1212 pub fn inner_chunk_size(&self) -> usize {
1213 self.data.inner_chunk_size()
1214 }
1215}
1216
1217/*
1218 * Convert views to owned types
1219 */
1220
1221impl<S: IntoOwned, I: IntoOwned> IntoOwned for Subset<S, I> {
1222 type Owned = Subset<S::Owned, I::Owned>;
1223
1224 #[inline]
1225 fn into_owned(self) -> Self::Owned {
1226 Subset {
1227 indices: self.indices.map(|x| x.into_owned()),
1228 data: self.data.into_owned(),
1229 }
1230 }
1231}
1232
1233impl<S, I> IntoOwnedData for Subset<S, I>
1234where
1235 S: IntoOwnedData,
1236{
1237 type OwnedData = Subset<S::OwnedData, I>;
1238 #[inline]
1239 fn into_owned_data(self) -> Self::OwnedData {
1240 Subset {
1241 indices: self.indices,
1242 data: self.data.into_owned_data(),
1243 }
1244 }
1245}
1246
1247/*
1248 * Impls for uniformly chunked sparse types
1249 */
1250
1251impl<S, I, M> UniChunkable<M> for Subset<S, I> {
1252 type Chunk = Subset<S, I>;
1253}
1254
1255#[cfg(test)]
1256mod tests {
1257 use super::*;
1258
1259 #[test]
1260 fn subset_of_subsets_iter() {
1261 let set = vec![1, 2, 3, 4, 5, 6];
1262 let subset = Subset::from_unique_ordered_indices(vec![1, 3, 5], set);
1263 let subsubset = Subset::from_unique_ordered_indices(vec![0, 2], subset);
1264 let mut iter = subsubset.iter();
1265 assert_eq!(Some(&2), iter.next());
1266 assert_eq!(Some(&6), iter.next());
1267 assert_eq!(None, iter.next());
1268 }
1269}