indexvec/
idx_vec.rs

1use crate::Idx;
2use std::marker::PhantomData;
3use std::ops::{Index, IndexMut, Range, RangeBounds};
4use std::{iter, slice, vec};
5
6#[derive(Clone, Debug, PartialEq, Eq, Hash)]
7pub struct IndexVec<I: Idx, T> {
8    pub raw: Vec<T>,
9    _marker: PhantomData<I>,
10}
11
12impl<I: Idx, T> Default for IndexVec<I, T> {
13    #[inline]
14    fn default() -> Self {
15        Self::new()
16    }
17}
18
19impl<I: Idx, T> IndexVec<I, T> {
20    #[inline]
21    pub fn new() -> Self {
22        IndexVec {
23            raw: Vec::new(),
24            _marker: PhantomData,
25        }
26    }
27
28    #[inline]
29    pub fn from_raw(raw: Vec<T>) -> Self {
30        IndexVec {
31            raw,
32            _marker: PhantomData,
33        }
34    }
35
36    #[inline]
37    pub fn with_capacity(capacity: usize) -> Self {
38        IndexVec {
39            raw: Vec::with_capacity(capacity),
40            _marker: PhantomData,
41        }
42    }
43
44    /// Create an `IndexVec` with `n` elements, where the value of each
45    /// element is the result of `func(i)`. (The underlying vector will
46    /// be allocated only once, with a capacity of at least `n`.)
47    #[inline]
48    pub fn from_fn_n(func: impl FnMut(I) -> T, n: usize) -> Self {
49        let indices = (0..n).map(I::new);
50        Self::from_raw(indices.map(func).collect())
51    }
52
53    #[inline]
54    pub fn push(&mut self, d: T) -> I {
55        let idx = I::new(self.len());
56        self.raw.push(d);
57        idx
58    }
59
60    #[inline]
61    pub fn pop(&mut self) -> Option<T> {
62        self.raw.pop()
63    }
64
65    #[inline]
66    pub fn len(&self) -> usize {
67        self.raw.len()
68    }
69
70    /// Gives the next index that will be assigned when `push` is
71    /// called.
72    #[inline]
73    pub fn next_index(&self) -> I {
74        I::new(self.len())
75    }
76
77    #[inline]
78    pub fn is_empty(&self) -> bool {
79        self.raw.is_empty()
80    }
81
82    #[inline]
83    pub fn into_iter(self) -> vec::IntoIter<T> {
84        self.raw.into_iter()
85    }
86
87    #[inline]
88    pub fn into_iter_enumerated(self) -> Enumerated<I, vec::IntoIter<T>> {
89        self.raw.into_iter().enumerate().map(IntoIdx {
90            _marker: PhantomData,
91        })
92    }
93
94    #[inline]
95    pub fn iter(&self) -> slice::Iter<'_, T> {
96        self.raw.iter()
97    }
98
99    #[inline]
100    pub fn iter_enumerated(&self) -> Enumerated<I, slice::Iter<'_, T>> {
101        self.raw.iter().enumerate().map(IntoIdx {
102            _marker: PhantomData,
103        })
104    }
105
106    #[inline]
107    pub fn indices(&self) -> iter::Map<Range<usize>, IntoIdx<I>> {
108        (0..self.len()).map(IntoIdx {
109            _marker: PhantomData,
110        })
111    }
112
113    #[inline]
114    pub fn iter_mut(&mut self) -> slice::IterMut<'_, T> {
115        self.raw.iter_mut()
116    }
117
118    #[inline]
119    pub fn iter_enumerated_mut(&mut self) -> Enumerated<I, slice::IterMut<'_, T>> {
120        self.raw.iter_mut().enumerate().map(IntoIdx {
121            _marker: PhantomData,
122        })
123    }
124
125    #[inline]
126    pub fn drain<'a, R: RangeBounds<usize>>(
127        &'a mut self,
128        range: R,
129    ) -> impl Iterator<Item = T> + 'a {
130        self.raw.drain(range)
131    }
132
133    #[inline]
134    pub fn drain_enumerated<'a, R: RangeBounds<usize>>(
135        &'a mut self,
136        range: R,
137    ) -> impl Iterator<Item = (I, T)> + 'a {
138        self.raw.drain(range).enumerate().map(IntoIdx {
139            _marker: PhantomData,
140        })
141    }
142
143    #[inline]
144    pub fn last(&self) -> Option<I> {
145        self.len().checked_sub(1).map(I::new)
146    }
147
148    #[inline]
149    pub fn shrink_to_fit(&mut self) {
150        self.raw.shrink_to_fit()
151    }
152
153    #[inline]
154    pub fn swap(&mut self, a: I, b: I) {
155        self.raw.swap(a.index(), b.index())
156    }
157
158    #[inline]
159    pub fn truncate(&mut self, a: usize) {
160        self.raw.truncate(a)
161    }
162
163    #[inline]
164    pub fn get(&self, index: I) -> Option<&T> {
165        self.raw.get(index.index())
166    }
167
168    #[inline]
169    pub fn get_mut(&mut self, index: I) -> Option<&mut T> {
170        self.raw.get_mut(index.index())
171    }
172
173    pub fn convert_index_type<Ix: Idx>(self) -> IndexVec<Ix, T> {
174        IndexVec {
175            raw: self.raw,
176            _marker: PhantomData,
177        }
178    }
179
180    /// Grows the index vector so that it contains an entry for
181    /// `elem`; if that is already true, then has no
182    /// effect. Otherwise, inserts new values as needed by invoking
183    /// `fill_value`.
184    #[inline]
185    pub fn ensure_contains_elem(&mut self, elem: I, fill_value: impl FnMut() -> T) {
186        let min_new_len = elem.index() + 1;
187        if self.len() < min_new_len {
188            self.raw.resize_with(min_new_len, fill_value);
189        }
190    }
191
192    #[inline]
193    pub fn resize_to_elem(&mut self, elem: I, fill_value: impl FnMut() -> T) {
194        let min_new_len = elem.index() + 1;
195        self.raw.resize_with(min_new_len, fill_value);
196    }
197}
198
199impl<I: Idx, T> Index<I> for IndexVec<I, T> {
200    type Output = T;
201
202    #[inline]
203    fn index(&self, index: I) -> &T {
204        &self.raw[index.index()]
205    }
206}
207
208impl<I: Idx, T> IndexMut<I> for IndexVec<I, T> {
209    #[inline]
210    fn index_mut(&mut self, index: I) -> &mut T {
211        &mut self.raw[index.index()]
212    }
213}
214
215pub type Enumerated<I, J> = iter::Map<iter::Enumerate<J>, IntoIdx<I>>;
216
217pub struct IntoIdx<I: Idx> {
218    _marker: PhantomData<fn(I)>,
219}
220
221impl<I: Idx, T> FnOnce<((usize, T),)> for IntoIdx<I> {
222    type Output = (I, T);
223
224    extern "rust-call" fn call_once(self, ((n, t),): ((usize, T),)) -> Self::Output {
225        (I::new(n), t)
226    }
227}
228
229impl<I: Idx, T> FnMut<((usize, T),)> for IntoIdx<I> {
230    extern "rust-call" fn call_mut(&mut self, ((n, t),): ((usize, T),)) -> Self::Output {
231        (I::new(n), t)
232    }
233}
234
235impl<I: Idx> FnOnce<(usize,)> for IntoIdx<I> {
236    type Output = I;
237
238    extern "rust-call" fn call_once(self, (n,): (usize,)) -> Self::Output {
239        I::new(n)
240    }
241}
242
243impl<I: Idx> FnMut<(usize,)> for IntoIdx<I> {
244    extern "rust-call" fn call_mut(&mut self, (n,): (usize,)) -> Self::Output {
245        I::new(n)
246    }
247}