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}