1 // Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
12 use std::iter::{self, FromIterator};
14 use std::marker::PhantomData;
15 use std::ops::{Index, IndexMut, Range};
20 use rustc_serialize as serialize;
22 /// Represents some newtyped `usize` wrapper.
24 /// (purpose: avoid mixing indexes for different bitvector domains.)
25 pub trait Idx: Copy + 'static + Eq + Debug {
26 fn new(usize) -> Self;
27 fn index(self) -> usize;
31 fn new(idx: usize) -> Self { idx }
32 fn index(self) -> usize { self }
36 fn new(idx: usize) -> Self { assert!(idx <= u32::MAX as usize); idx as u32 }
37 fn index(self) -> usize { self as usize }
41 pub struct IndexVec<I: Idx, T> {
43 _marker: PhantomData<Fn(&I)>
46 impl<I: Idx, T: serialize::Encodable> serialize::Encodable for IndexVec<I, T> {
47 fn encode<S: serialize::Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
48 serialize::Encodable::encode(&self.raw, s)
52 impl<I: Idx, T: serialize::Decodable> serialize::Decodable for IndexVec<I, T> {
53 fn decode<D: serialize::Decoder>(d: &mut D) -> Result<Self, D::Error> {
54 serialize::Decodable::decode(d).map(|v| {
55 IndexVec { raw: v, _marker: PhantomData }
60 impl<I: Idx, T: fmt::Debug> fmt::Debug for IndexVec<I, T> {
61 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
62 fmt::Debug::fmt(&self.raw, fmt)
66 pub type Enumerated<I, J> = iter::Map<iter::Enumerate<J>, IntoIdx<I>>;
68 impl<I: Idx, T> IndexVec<I, T> {
70 pub fn new() -> Self {
71 IndexVec { raw: Vec::new(), _marker: PhantomData }
75 pub fn with_capacity(capacity: usize) -> Self {
76 IndexVec { raw: Vec::with_capacity(capacity), _marker: PhantomData }
80 pub fn from_elem<S>(elem: T, universe: &IndexVec<I, S>) -> Self
83 IndexVec { raw: vec![elem; universe.len()], _marker: PhantomData }
87 pub fn from_elem_n(elem: T, n: usize) -> Self
90 IndexVec { raw: vec![elem; n], _marker: PhantomData }
94 pub fn push(&mut self, d: T) -> I {
95 let idx = I::new(self.len());
101 pub fn len(&self) -> usize {
106 pub fn is_empty(&self) -> bool {
111 pub fn into_iter(self) -> vec::IntoIter<T> {
116 pub fn into_iter_enumerated(self) -> Enumerated<I, vec::IntoIter<T>>
118 self.raw.into_iter().enumerate().map(IntoIdx { _marker: PhantomData })
122 pub fn iter(&self) -> slice::Iter<T> {
127 pub fn iter_enumerated(&self) -> Enumerated<I, slice::Iter<T>>
129 self.raw.iter().enumerate().map(IntoIdx { _marker: PhantomData })
133 pub fn indices(&self) -> iter::Map<Range<usize>, IntoIdx<I>> {
134 (0..self.len()).map(IntoIdx { _marker: PhantomData })
138 pub fn iter_mut(&mut self) -> slice::IterMut<T> {
143 pub fn iter_enumerated_mut(&mut self) -> Enumerated<I, slice::IterMut<T>>
145 self.raw.iter_mut().enumerate().map(IntoIdx { _marker: PhantomData })
149 pub fn last(&self) -> Option<I> {
150 self.len().checked_sub(1).map(I::new)
154 pub fn shrink_to_fit(&mut self) {
155 self.raw.shrink_to_fit()
159 pub fn swap(&mut self, a: usize, b: usize) {
164 pub fn truncate(&mut self, a: usize) {
169 impl<I: Idx, T> Index<I> for IndexVec<I, T> {
173 fn index(&self, index: I) -> &T {
174 &self.raw[index.index()]
178 impl<I: Idx, T> IndexMut<I> for IndexVec<I, T> {
180 fn index_mut(&mut self, index: I) -> &mut T {
181 &mut self.raw[index.index()]
185 impl<I: Idx, T> Extend<T> for IndexVec<I, T> {
187 fn extend<J: IntoIterator<Item = T>>(&mut self, iter: J) {
188 self.raw.extend(iter);
192 impl<I: Idx, T> FromIterator<T> for IndexVec<I, T> {
194 fn from_iter<J>(iter: J) -> Self where J: IntoIterator<Item=T> {
195 IndexVec { raw: FromIterator::from_iter(iter), _marker: PhantomData }
199 impl<I: Idx, T> IntoIterator for IndexVec<I, T> {
201 type IntoIter = vec::IntoIter<T>;
204 fn into_iter(self) -> vec::IntoIter<T> {
210 impl<'a, I: Idx, T> IntoIterator for &'a IndexVec<I, T> {
212 type IntoIter = slice::Iter<'a, T>;
215 fn into_iter(self) -> slice::Iter<'a, T> {
220 impl<'a, I: Idx, T> IntoIterator for &'a mut IndexVec<I, T> {
221 type Item = &'a mut T;
222 type IntoIter = slice::IterMut<'a, T>;
225 fn into_iter(mut self) -> slice::IterMut<'a, T> {
230 pub struct IntoIdx<I: Idx> { _marker: PhantomData<fn(&I)> }
231 impl<I: Idx, T> FnOnce<((usize, T),)> for IntoIdx<I> {
232 type Output = (I, T);
234 extern "rust-call" fn call_once(self, ((n, t),): ((usize, T),)) -> Self::Output {
239 impl<I: Idx, T> FnMut<((usize, T),)> for IntoIdx<I> {
240 extern "rust-call" fn call_mut(&mut self, ((n, t),): ((usize, T),)) -> Self::Output {
245 impl<I: Idx> FnOnce<(usize,)> for IntoIdx<I> {
248 extern "rust-call" fn call_once(self, (n,): (usize,)) -> Self::Output {
253 impl<I: Idx> FnMut<(usize,)> for IntoIdx<I> {
254 extern "rust-call" fn call_mut(&mut self, (n,): (usize,)) -> Self::Output {