Skip to content

Commit 480068c

Browse files
committed
Auto merge of #109787 - scottmcm:index-slice, r=cjgillot
Add `IndexSlice` to go with `IndexVec` Moves the methods that don't need full `IndexVec`-ness over to `IndexSlice`, and have `IndexVec` deref to `IndexSlice` so everything keeps working. Doing this for later use in rust-lang/compiler-team#606, where I'm hitting a bunch of things that are just slices and thus there's no way to index with the `FieldIdx`.
2 parents 22a7a19 + 408e2ac commit 480068c

File tree

1 file changed

+160
-70
lines changed
  • compiler/rustc_index/src

1 file changed

+160
-70
lines changed

compiler/rustc_index/src/vec.rs

+160-70
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::fmt;
55
use std::fmt::Debug;
66
use std::hash::Hash;
77
use std::marker::PhantomData;
8-
use std::ops::{Index, IndexMut, RangeBounds};
8+
use std::ops::{Deref, DerefMut, Index, IndexMut, RangeBounds};
99
use std::slice;
1010
use std::vec;
1111

@@ -52,15 +52,27 @@ impl Idx for u32 {
5252
}
5353

5454
#[derive(Clone, PartialEq, Eq, Hash)]
55+
#[repr(transparent)]
5556
pub struct IndexVec<I: Idx, T> {
5657
pub raw: Vec<T>,
5758
_marker: PhantomData<fn(&I)>,
5859
}
5960

61+
#[derive(PartialEq, Eq, Hash)]
62+
#[repr(transparent)]
63+
pub struct IndexSlice<I: Idx, T> {
64+
_marker: PhantomData<fn(&I)>,
65+
pub raw: [T],
66+
}
67+
6068
// Whether `IndexVec` is `Send` depends only on the data,
6169
// not the phantom data.
6270
unsafe impl<I: Idx, T> Send for IndexVec<I, T> where T: Send {}
6371

72+
// Whether `IndexSlice` is `Send` depends only on the data,
73+
// not the phantom data.
74+
unsafe impl<I: Idx, T> Send for IndexSlice<I, T> where T: Send {}
75+
6476
#[cfg(feature = "rustc_serialize")]
6577
impl<S: Encoder, I: Idx, T: Encodable<S>> Encodable<S> for IndexVec<I, T> {
6678
fn encode(&self, s: &mut S) {
@@ -122,6 +134,16 @@ impl<I: Idx, T> IndexVec<I, T> {
122134
Self::from_raw(indices.map(func).collect())
123135
}
124136

137+
#[inline]
138+
pub fn as_slice(&self) -> &IndexSlice<I, T> {
139+
IndexSlice::from_raw(&self.raw)
140+
}
141+
142+
#[inline]
143+
pub fn as_mut_slice(&mut self) -> &mut IndexSlice<I, T> {
144+
IndexSlice::from_raw_mut(&mut self.raw)
145+
}
146+
125147
#[inline]
126148
pub fn push(&mut self, d: T) -> I {
127149
let idx = I::new(self.len());
@@ -135,32 +157,119 @@ impl<I: Idx, T> IndexVec<I, T> {
135157
}
136158

137159
#[inline]
138-
pub fn len(&self) -> usize {
139-
self.raw.len()
160+
pub fn into_iter(self) -> vec::IntoIter<T> {
161+
self.raw.into_iter()
140162
}
141163

142-
/// Gives the next index that will be assigned when `push` is
143-
/// called.
144164
#[inline]
145-
pub fn next_index(&self) -> I {
146-
I::new(self.len())
165+
pub fn into_iter_enumerated(
166+
self,
167+
) -> impl DoubleEndedIterator<Item = (I, T)> + ExactSizeIterator {
168+
self.raw.into_iter().enumerate().map(|(n, t)| (I::new(n), t))
147169
}
148170

149171
#[inline]
150-
pub fn is_empty(&self) -> bool {
151-
self.raw.is_empty()
172+
pub fn drain<'a, R: RangeBounds<usize>>(
173+
&'a mut self,
174+
range: R,
175+
) -> impl Iterator<Item = T> + 'a {
176+
self.raw.drain(range)
152177
}
153178

154179
#[inline]
155-
pub fn into_iter(self) -> vec::IntoIter<T> {
156-
self.raw.into_iter()
180+
pub fn drain_enumerated<'a, R: RangeBounds<usize>>(
181+
&'a mut self,
182+
range: R,
183+
) -> impl Iterator<Item = (I, T)> + 'a {
184+
let begin = match range.start_bound() {
185+
std::ops::Bound::Included(i) => *i,
186+
std::ops::Bound::Excluded(i) => i.checked_add(1).unwrap(),
187+
std::ops::Bound::Unbounded => 0,
188+
};
189+
self.raw.drain(range).enumerate().map(move |(n, t)| (I::new(begin + n), t))
157190
}
158191

159192
#[inline]
160-
pub fn into_iter_enumerated(
161-
self,
162-
) -> impl DoubleEndedIterator<Item = (I, T)> + ExactSizeIterator {
163-
self.raw.into_iter().enumerate().map(|(n, t)| (I::new(n), t))
193+
pub fn shrink_to_fit(&mut self) {
194+
self.raw.shrink_to_fit()
195+
}
196+
197+
#[inline]
198+
pub fn truncate(&mut self, a: usize) {
199+
self.raw.truncate(a)
200+
}
201+
202+
pub fn convert_index_type<Ix: Idx>(self) -> IndexVec<Ix, T> {
203+
IndexVec { raw: self.raw, _marker: PhantomData }
204+
}
205+
206+
/// Grows the index vector so that it contains an entry for
207+
/// `elem`; if that is already true, then has no
208+
/// effect. Otherwise, inserts new values as needed by invoking
209+
/// `fill_value`.
210+
#[inline]
211+
pub fn ensure_contains_elem(&mut self, elem: I, fill_value: impl FnMut() -> T) {
212+
let min_new_len = elem.index() + 1;
213+
if self.len() < min_new_len {
214+
self.raw.resize_with(min_new_len, fill_value);
215+
}
216+
}
217+
218+
#[inline]
219+
pub fn resize_to_elem(&mut self, elem: I, fill_value: impl FnMut() -> T) {
220+
let min_new_len = elem.index() + 1;
221+
self.raw.resize_with(min_new_len, fill_value);
222+
}
223+
}
224+
225+
impl<I: Idx, T> Deref for IndexVec<I, T> {
226+
type Target = IndexSlice<I, T>;
227+
228+
#[inline]
229+
fn deref(&self) -> &Self::Target {
230+
self.as_slice()
231+
}
232+
}
233+
234+
impl<I: Idx, T> DerefMut for IndexVec<I, T> {
235+
#[inline]
236+
fn deref_mut(&mut self) -> &mut Self::Target {
237+
self.as_mut_slice()
238+
}
239+
}
240+
241+
impl<I: Idx, T> IndexSlice<I, T> {
242+
#[inline]
243+
pub fn from_raw(raw: &[T]) -> &Self {
244+
let ptr: *const [T] = raw;
245+
// SAFETY: `IndexSlice` is `repr(transparent)` over a normal slice
246+
unsafe { &*(ptr as *const Self) }
247+
}
248+
249+
#[inline]
250+
pub fn from_raw_mut(raw: &mut [T]) -> &mut Self {
251+
let ptr: *mut [T] = raw;
252+
// SAFETY: `IndexSlice` is `repr(transparent)` over a normal slice
253+
unsafe { &mut *(ptr as *mut Self) }
254+
}
255+
256+
#[inline]
257+
pub fn len(&self) -> usize {
258+
self.raw.len()
259+
}
260+
261+
/// Gives the next index that will be assigned when `push` is called.
262+
///
263+
/// Manual bounds checks can be done using `idx < slice.next_index()`
264+
/// (as opposed to `idx.index() < slice.len()`).
265+
#[inline]
266+
pub fn next_index(&self) -> I {
267+
I::new(self.len())
268+
}
269+
270+
#[inline]
271+
pub fn is_empty(&self) -> bool {
272+
self.raw.is_empty()
164273
}
165274

166275
#[inline]
@@ -194,47 +303,16 @@ impl<I: Idx, T> IndexVec<I, T> {
194303
self.raw.iter_mut().enumerate().map(|(n, t)| (I::new(n), t))
195304
}
196305

197-
#[inline]
198-
pub fn drain<'a, R: RangeBounds<usize>>(
199-
&'a mut self,
200-
range: R,
201-
) -> impl Iterator<Item = T> + 'a {
202-
self.raw.drain(range)
203-
}
204-
205-
#[inline]
206-
pub fn drain_enumerated<'a, R: RangeBounds<usize>>(
207-
&'a mut self,
208-
range: R,
209-
) -> impl Iterator<Item = (I, T)> + 'a {
210-
let begin = match range.start_bound() {
211-
std::ops::Bound::Included(i) => *i,
212-
std::ops::Bound::Excluded(i) => i.checked_add(1).unwrap(),
213-
std::ops::Bound::Unbounded => 0,
214-
};
215-
self.raw.drain(range).enumerate().map(move |(n, t)| (I::new(begin + n), t))
216-
}
217-
218306
#[inline]
219307
pub fn last_index(&self) -> Option<I> {
220308
self.len().checked_sub(1).map(I::new)
221309
}
222310

223-
#[inline]
224-
pub fn shrink_to_fit(&mut self) {
225-
self.raw.shrink_to_fit()
226-
}
227-
228311
#[inline]
229312
pub fn swap(&mut self, a: I, b: I) {
230313
self.raw.swap(a.index(), b.index())
231314
}
232315

233-
#[inline]
234-
pub fn truncate(&mut self, a: usize) {
235-
self.raw.truncate(a)
236-
}
237-
238316
#[inline]
239317
pub fn get(&self, index: I) -> Option<&T> {
240318
self.raw.get(index.index())
@@ -274,28 +352,6 @@ impl<I: Idx, T> IndexVec<I, T> {
274352
let ptr = self.raw.as_mut_ptr();
275353
unsafe { (&mut *ptr.add(ai), &mut *ptr.add(bi), &mut *ptr.add(ci)) }
276354
}
277-
278-
pub fn convert_index_type<Ix: Idx>(self) -> IndexVec<Ix, T> {
279-
IndexVec { raw: self.raw, _marker: PhantomData }
280-
}
281-
282-
/// Grows the index vector so that it contains an entry for
283-
/// `elem`; if that is already true, then has no
284-
/// effect. Otherwise, inserts new values as needed by invoking
285-
/// `fill_value`.
286-
#[inline]
287-
pub fn ensure_contains_elem(&mut self, elem: I, fill_value: impl FnMut() -> T) {
288-
let min_new_len = elem.index() + 1;
289-
if self.len() < min_new_len {
290-
self.raw.resize_with(min_new_len, fill_value);
291-
}
292-
}
293-
294-
#[inline]
295-
pub fn resize_to_elem(&mut self, elem: I, fill_value: impl FnMut() -> T) {
296-
let min_new_len = elem.index() + 1;
297-
self.raw.resize_with(min_new_len, fill_value);
298-
}
299355
}
300356

301357
/// `IndexVec` is often used as a map, so it provides some map-like APIs.
@@ -336,7 +392,7 @@ impl<I: Idx, T: Ord> IndexVec<I, T> {
336392
}
337393
}
338394

339-
impl<I: Idx, T> Index<I> for IndexVec<I, T> {
395+
impl<I: Idx, T> Index<I> for IndexSlice<I, T> {
340396
type Output = T;
341397

342398
#[inline]
@@ -345,7 +401,7 @@ impl<I: Idx, T> Index<I> for IndexVec<I, T> {
345401
}
346402
}
347403

348-
impl<I: Idx, T> IndexMut<I> for IndexVec<I, T> {
404+
impl<I: Idx, T> IndexMut<I> for IndexSlice<I, T> {
349405
#[inline]
350406
fn index_mut(&mut self, index: I) -> &mut T {
351407
&mut self.raw[index.index()]
@@ -359,6 +415,20 @@ impl<I: Idx, T> Default for IndexVec<I, T> {
359415
}
360416
}
361417

418+
impl<I: Idx, T> Default for &IndexSlice<I, T> {
419+
#[inline]
420+
fn default() -> Self {
421+
IndexSlice::from_raw(Default::default())
422+
}
423+
}
424+
425+
impl<I: Idx, T> Default for &mut IndexSlice<I, T> {
426+
#[inline]
427+
fn default() -> Self {
428+
IndexSlice::from_raw_mut(Default::default())
429+
}
430+
}
431+
362432
impl<I: Idx, T> Extend<T> for IndexVec<I, T> {
363433
#[inline]
364434
fn extend<J: IntoIterator<Item = T>>(&mut self, iter: J) {
@@ -418,5 +488,25 @@ impl<'a, I: Idx, T> IntoIterator for &'a mut IndexVec<I, T> {
418488
}
419489
}
420490

491+
impl<'a, I: Idx, T> IntoIterator for &'a IndexSlice<I, T> {
492+
type Item = &'a T;
493+
type IntoIter = slice::Iter<'a, T>;
494+
495+
#[inline]
496+
fn into_iter(self) -> slice::Iter<'a, T> {
497+
self.raw.iter()
498+
}
499+
}
500+
501+
impl<'a, I: Idx, T> IntoIterator for &'a mut IndexSlice<I, T> {
502+
type Item = &'a mut T;
503+
type IntoIter = slice::IterMut<'a, T>;
504+
505+
#[inline]
506+
fn into_iter(self) -> slice::IterMut<'a, T> {
507+
self.raw.iter_mut()
508+
}
509+
}
510+
421511
#[cfg(test)]
422512
mod tests;

0 commit comments

Comments
 (0)