#[cfg(feature = "rustc_serialize")] use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; use std::borrow::{Borrow, BorrowMut}; use std::fmt; use std::hash::Hash; use std::marker::PhantomData; use std::ops::{Deref, DerefMut, RangeBounds}; use std::slice; use std::vec; use crate::{Idx, IndexSlice}; /// An owned contiguous collection of `T`s, indexed by `I` rather than by `usize`. /// /// While it's possible to use `u32` or `usize` directly for `I`, /// you almost certainly want to use a [`newtype_index!`]-generated type instead. /// /// [`newtype_index!`]: ../macro.newtype_index.html #[derive(Clone, PartialEq, Eq, Hash)] #[repr(transparent)] pub struct IndexVec { pub raw: Vec, _marker: PhantomData, } impl IndexVec { #[inline] pub const fn new() -> Self { IndexVec::from_raw(Vec::new()) } #[inline] pub const fn from_raw(raw: Vec) -> Self { IndexVec { raw, _marker: PhantomData } } #[inline] pub fn with_capacity(capacity: usize) -> Self { IndexVec::from_raw(Vec::with_capacity(capacity)) } /// Creates a new vector with a copy of `elem` for each index in `universe`. /// /// Thus `IndexVec::from_elem(elem, &universe)` is equivalent to /// `IndexVec::::from_elem_n(elem, universe.len())`. That can help /// type inference as it ensures that the resulting vector uses the same /// index type as `universe`, rather than something potentially surprising. /// /// For example, if you want to store data for each local in a MIR body, /// using `let mut uses = IndexVec::from_elem(vec![], &body.local_decls);` /// ensures that `uses` is an `IndexVec`, and thus can give /// better error messages later if one accidentally mismatches indices. #[inline] pub fn from_elem(elem: T, universe: &IndexSlice) -> Self where T: Clone, { IndexVec::from_raw(vec![elem; universe.len()]) } #[inline] pub fn from_elem_n(elem: T, n: usize) -> Self where T: Clone, { IndexVec::from_raw(vec![elem; n]) } /// Create an `IndexVec` with `n` elements, where the value of each /// element is the result of `func(i)`. (The underlying vector will /// be allocated only once, with a capacity of at least `n`.) #[inline] pub fn from_fn_n(func: impl FnMut(I) -> T, n: usize) -> Self { IndexVec::from_raw((0..n).map(I::new).map(func).collect()) } #[inline] pub fn as_slice(&self) -> &IndexSlice { IndexSlice::from_raw(&self.raw) } #[inline] pub fn as_mut_slice(&mut self) -> &mut IndexSlice { IndexSlice::from_raw_mut(&mut self.raw) } #[inline] pub fn push(&mut self, d: T) -> I { let idx = self.next_index(); self.raw.push(d); idx } #[inline] pub fn pop(&mut self) -> Option { self.raw.pop() } #[inline] pub fn into_iter(self) -> vec::IntoIter { self.raw.into_iter() } #[inline] pub fn into_iter_enumerated( self, ) -> impl DoubleEndedIterator + ExactSizeIterator { self.raw.into_iter().enumerate().map(|(n, t)| (I::new(n), t)) } #[inline] pub fn drain>(&mut self, range: R) -> impl Iterator + '_ { self.raw.drain(range) } #[inline] pub fn drain_enumerated>( &mut self, range: R, ) -> impl Iterator + '_ { let begin = match range.start_bound() { std::ops::Bound::Included(i) => *i, std::ops::Bound::Excluded(i) => i.checked_add(1).unwrap(), std::ops::Bound::Unbounded => 0, }; self.raw.drain(range).enumerate().map(move |(n, t)| (I::new(begin + n), t)) } #[inline] pub fn shrink_to_fit(&mut self) { self.raw.shrink_to_fit() } #[inline] pub fn truncate(&mut self, a: usize) { self.raw.truncate(a) } pub fn convert_index_type(self) -> IndexVec { IndexVec::from_raw(self.raw) } /// Grows the index vector so that it contains an entry for /// `elem`; if that is already true, then has no /// effect. Otherwise, inserts new values as needed by invoking /// `fill_value`. /// /// Returns a reference to the `elem` entry. #[inline] pub fn ensure_contains_elem(&mut self, elem: I, fill_value: impl FnMut() -> T) -> &mut T { let min_new_len = elem.index() + 1; if self.len() < min_new_len { self.raw.resize_with(min_new_len, fill_value); } &mut self[elem] } #[inline] pub fn resize(&mut self, new_len: usize, value: T) where T: Clone, { self.raw.resize(new_len, value) } #[inline] pub fn resize_to_elem(&mut self, elem: I, fill_value: impl FnMut() -> T) { let min_new_len = elem.index() + 1; self.raw.resize_with(min_new_len, fill_value); } } /// `IndexVec` is often used as a map, so it provides some map-like APIs. impl IndexVec> { #[inline] pub fn insert(&mut self, index: I, value: T) -> Option { self.ensure_contains_elem(index, || None).replace(value) } #[inline] pub fn get_or_insert_with(&mut self, index: I, value: impl FnOnce() -> T) -> &mut T { self.ensure_contains_elem(index, || None).get_or_insert_with(value) } #[inline] pub fn remove(&mut self, index: I) -> Option { self.get_mut(index)?.take() } } impl fmt::Debug for IndexVec { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Debug::fmt(&self.raw, fmt) } } impl Deref for IndexVec { type Target = IndexSlice; #[inline] fn deref(&self) -> &Self::Target { self.as_slice() } } impl DerefMut for IndexVec { #[inline] fn deref_mut(&mut self) -> &mut Self::Target { self.as_mut_slice() } } impl Borrow> for IndexVec { fn borrow(&self) -> &IndexSlice { self } } impl BorrowMut> for IndexVec { fn borrow_mut(&mut self) -> &mut IndexSlice { self } } impl Extend for IndexVec { #[inline] fn extend>(&mut self, iter: J) { self.raw.extend(iter); } #[inline] #[cfg(feature = "nightly")] fn extend_one(&mut self, item: T) { self.raw.push(item); } #[inline] #[cfg(feature = "nightly")] fn extend_reserve(&mut self, additional: usize) { self.raw.reserve(additional); } } impl FromIterator for IndexVec { #[inline] fn from_iter(iter: J) -> Self where J: IntoIterator, { IndexVec::from_raw(Vec::from_iter(iter)) } } impl IntoIterator for IndexVec { type Item = T; type IntoIter = vec::IntoIter; #[inline] fn into_iter(self) -> vec::IntoIter { self.raw.into_iter() } } impl<'a, I: Idx, T> IntoIterator for &'a IndexVec { type Item = &'a T; type IntoIter = slice::Iter<'a, T>; #[inline] fn into_iter(self) -> slice::Iter<'a, T> { self.iter() } } impl<'a, I: Idx, T> IntoIterator for &'a mut IndexVec { type Item = &'a mut T; type IntoIter = slice::IterMut<'a, T>; #[inline] fn into_iter(self) -> slice::IterMut<'a, T> { self.iter_mut() } } impl Default for IndexVec { #[inline] fn default() -> Self { IndexVec::new() } } impl From<[T; N]> for IndexVec { #[inline] fn from(array: [T; N]) -> Self { IndexVec::from_raw(array.into()) } } #[cfg(feature = "rustc_serialize")] impl> Encodable for IndexVec { fn encode(&self, s: &mut S) { Encodable::encode(&self.raw, s); } } #[cfg(feature = "rustc_serialize")] impl> Decodable for IndexVec { fn decode(d: &mut D) -> Self { IndexVec::from_raw(Vec::::decode(d)) } } // Whether `IndexVec` is `Send` depends only on the data, // not the phantom data. unsafe impl Send for IndexVec where T: Send {} #[cfg(test)] mod tests;