// Copyright 2016 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. use std::iter::{self, FromIterator}; use std::slice; use std::marker::PhantomData; use std::ops::{Index, IndexMut}; use std::fmt; use std::vec; use rustc_serialize as serialize; /// Represents some newtyped `usize` wrapper. /// /// (purpose: avoid mixing indexes for different bitvector domains.) pub trait Idx: Copy + 'static { fn new(usize) -> Self; fn index(self) -> usize; } impl Idx for usize { fn new(idx: usize) -> Self { idx } fn index(self) -> usize { self } } #[derive(Clone)] pub struct IndexVec { pub raw: Vec, _marker: PhantomData } impl serialize::Encodable for IndexVec { fn encode(&self, s: &mut S) -> Result<(), S::Error> { serialize::Encodable::encode(&self.raw, s) } } impl serialize::Decodable for IndexVec { fn decode(d: &mut D) -> Result { serialize::Decodable::decode(d).map(|v| { IndexVec { raw: v, _marker: PhantomData } }) } } impl fmt::Debug for IndexVec { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fmt::Debug::fmt(&self.raw, fmt) } } pub type Enumerated = iter::Map, IntoIdx>; impl IndexVec { #[inline] pub fn new() -> Self { IndexVec { raw: Vec::new(), _marker: PhantomData } } #[inline] pub fn with_capacity(capacity: usize) -> Self { IndexVec { raw: Vec::with_capacity(capacity), _marker: PhantomData } } #[inline] pub fn from_elem(elem: T, universe: &IndexVec) -> Self where T: Clone { IndexVec { raw: vec![elem; universe.len()], _marker: PhantomData } } #[inline] pub fn push(&mut self, d: T) -> I { let idx = I::new(self.len()); self.raw.push(d); idx } #[inline] pub fn len(&self) -> usize { self.raw.len() } #[inline] pub fn is_empty(&self) -> bool { self.raw.is_empty() } #[inline] pub fn into_iter(self) -> vec::IntoIter { self.raw.into_iter() } #[inline] pub fn into_iter_enumerated(self) -> Enumerated> { self.raw.into_iter().enumerate().map(IntoIdx { _marker: PhantomData }) } #[inline] pub fn iter(&self) -> slice::Iter { self.raw.iter() } #[inline] pub fn iter_enumerated(&self) -> Enumerated> { self.raw.iter().enumerate().map(IntoIdx { _marker: PhantomData }) } #[inline] pub fn iter_mut(&mut self) -> slice::IterMut { self.raw.iter_mut() } #[inline] pub fn iter_enumerated_mut(&mut self) -> Enumerated> { self.raw.iter_mut().enumerate().map(IntoIdx { _marker: PhantomData }) } #[inline] pub fn last(&self) -> Option { self.len().checked_sub(1).map(I::new) } } impl Index for IndexVec { type Output = T; #[inline] fn index(&self, index: I) -> &T { &self.raw[index.index()] } } impl IndexMut for IndexVec { #[inline] fn index_mut(&mut self, index: I) -> &mut T { &mut self.raw[index.index()] } } impl Extend for IndexVec { #[inline] fn extend>(&mut self, iter: J) { self.raw.extend(iter); } } impl FromIterator for IndexVec { #[inline] fn from_iter(iter: J) -> Self where J: IntoIterator { IndexVec { raw: FromIterator::from_iter(iter), _marker: PhantomData } } } 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.raw.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(mut self) -> slice::IterMut<'a, T> { self.raw.iter_mut() } } pub struct IntoIdx { _marker: PhantomData } impl FnOnce<((usize, T),)> for IntoIdx { type Output = (I, T); extern "rust-call" fn call_once(self, ((n, t),): ((usize, T),)) -> Self::Output { (I::new(n), t) } } impl FnMut<((usize, T),)> for IntoIdx { extern "rust-call" fn call_mut(&mut self, ((n, t),): ((usize, T),)) -> Self::Output { (I::new(n), t) } }