/rust/registry/src/index.crates.io-1949cf8c6b5b557f/oxc_index-5.0.0/src/lib.rs
Line | Count | Source |
1 | | //! This crate is a fork of `index_vec`, <https://github.com/thomcc/index_vec> |
2 | | //! It helps with defining "newtype"-style wrappers around `usize` (or |
3 | | //! other integers), `Vec<T>`, and `[T]` so that some additional type safety can |
4 | | //! be gained at zero cost. |
5 | | //! |
6 | | //! ## Example / Overview |
7 | | //! ```rust |
8 | | //! use oxc_index::{IndexVec, IndexSlice, index_vec}; |
9 | | //! |
10 | | //! oxc_index::define_index_type! { |
11 | | //! // Define StrIdx to use only 32 bits internally (you can use usize, u16, |
12 | | //! // and even u8). |
13 | | //! pub struct StrIdx = u32; |
14 | | //! |
15 | | //! // The defaults are very reasonable, but this macro can let |
16 | | //! // you customize things quite a bit: |
17 | | //! |
18 | | //! // By default, creating a StrIdx would check an incoming `usize against |
19 | | //! // `u32::max_value()`, as u32 is the wrapped index type. Lets imagine that |
20 | | //! // StrIdx has to interface with an external system that uses signed ints. |
21 | | //! // We can change the checking behavior to complain on i32::max_value() |
22 | | //! // instead: |
23 | | //! MAX_INDEX = i32::max_value() as usize; |
24 | | //! |
25 | | //! // We can also disable checking all-together if we are more concerned with perf |
26 | | //! // than any overflow problems, or even do so, but only for debug builds: Quite |
27 | | //! // pointless here, but an okay example |
28 | | //! DISABLE_MAX_INDEX_CHECK = cfg!(not(debug_assertions)); |
29 | | //! |
30 | | //! // And more too, see this macro's docs for more info. |
31 | | //! } |
32 | | //! |
33 | | //! // Create a vector which can be accessed using `StrIdx`s. |
34 | | //! let mut strs: IndexVec<StrIdx, &'static str> = index_vec!["strs", "bar", "baz"]; |
35 | | //! |
36 | | //! // l is a `StrIdx` |
37 | | //! let l = strs.last_idx(); |
38 | | //! assert_eq!(strs[l], "baz"); |
39 | | //! |
40 | | //! let new_i = strs.push("quux"); |
41 | | //! assert_eq!(strs[new_i], "quux"); |
42 | | //! |
43 | | //! // The slice APIs are wrapped as well. |
44 | | //! let s: &IndexSlice<StrIdx, [&'static str]> = &strs[StrIdx::new(1)..]; |
45 | | //! assert_eq!(s[StrIdx::new(0)], "bar"); |
46 | | //! |
47 | | //! // Indices are mostly interoperable with `usize`, and support |
48 | | //! // a lot of what you might want to do to an index. |
49 | | //! |
50 | | //! // Comparison |
51 | | //! assert_eq!(StrIdx::new(0), 0usize); |
52 | | //! |
53 | | //! // Addition |
54 | | //! assert_eq!(StrIdx::new(0) + 1, 1usize); |
55 | | //! |
56 | | //! // Subtraction |
57 | | //! assert_eq!(StrIdx::new(1) - 1, 0usize); |
58 | | //! |
59 | | //! // Wrapping |
60 | | //! assert_eq!(StrIdx::new(5) % strs.len(), 1usize); |
61 | | //! // ... |
62 | | //! ``` |
63 | | //! ## Background |
64 | | //! |
65 | | //! The goal is to help with the pattern of using a `type FooIdx = usize` to |
66 | | //! access a `Vec<Foo>` with something that can statically prevent using a |
67 | | //! `FooIdx` in a `Vec<Bar>`. It's most useful if you have a bunch of indices |
68 | | //! referring to different sorts of vectors. |
69 | | //! |
70 | | //! The code was originally based on `rustc`'s `IndexVec` code, however that has |
71 | | //! been almost entirely rewritten (except for the cases where it's trivial, |
72 | | //! e.g. the Vec wrapper). |
73 | | //! |
74 | | //! ## Other crates |
75 | | //! |
76 | | //! The [`indexed_vec`](https://crates.io/crates/indexed_vec) crate predates |
77 | | //! this, and is a much closer copy of the code from `rustc`. Unfortunately, |
78 | | //! this means it does not compile on stable. |
79 | | //! |
80 | | //! If you're looking for something further from a vec and closer to a map, you |
81 | | //! might find [`handy`](https://crates.io/crates/handy), |
82 | | //! [`slotmap`](https://crates.io/crates/slotmap), or |
83 | | //! [`slab`](https://crates.io/crates/slab) to be closer what you want. |
84 | | //! |
85 | | //! ## FAQ |
86 | | //! |
87 | | //! #### Wouldn't `define_index_type` be better as a proc macro? |
88 | | //! |
89 | | //! Probably. It's not a proc macro because I tend to avoid them where possible |
90 | | //! due to wanting to minimize compile times. If the issues around proc-macro |
91 | | //! compile times are fixed, then I'll revisit this. |
92 | | //! |
93 | | //! I also may eventually add a proc-macro feature which is not required, but |
94 | | //! avoids some of the grossness. |
95 | | //! |
96 | | //! #### Does `define_index_type` do too much? |
97 | | //! |
98 | | //! Possibly. It defines a type, implements a bunch of functions on it, and |
99 | | //! quite a few traits. That said, it's intended to be a very painless journey |
100 | | //! from `Vec<T>` + `usize` to `IndexVec<I, T>`. If it left it up to the |
101 | | //! developer to do those things, it would be too annoying to be worth using. |
102 | | //! |
103 | | //! #### The syntax for the options in `define_index_type` is terrible. |
104 | | //! |
105 | | //! I'm open to suggestions. |
106 | | //! |
107 | | //! #### Does it support no_std? |
108 | | //! |
109 | | //! Yes, although it uses `extern crate alloc;`, of course. |
110 | | //! |
111 | | //! #### Does it support serde? |
112 | | //! |
113 | | //! Yes, but only if you turn on the `serialize` feature. |
114 | | //! |
115 | | //! #### Does it support NonMaxU32? |
116 | | //! |
117 | | //! Yes! With the `nonmax` feature enabled, you can use the `define_nonmax_u32_index_type!` macro |
118 | | //! to create index types backed by `NonMaxU32` from the `nonmax` crate. This is useful for |
119 | | //! memory-efficient `Option<Index>` representations. |
120 | | //! |
121 | | //! ```rust,ignore |
122 | | //! oxc_index::define_nonmax_u32_index_type! { |
123 | | //! pub struct MyIndex; |
124 | | //! } |
125 | | //! ``` |
126 | | //! |
127 | | //! #### What features are planned? |
128 | | //! |
129 | | //! Planned is a bit strong but here are the things I would find useful. |
130 | | //! |
131 | | //! - Support any remaining parts of the slice/vec api. |
132 | | //! - Add typesafe wrappers for SmallVec/ArrayVec (behind a cargo `feature`, of |
133 | | //! course). |
134 | | //! - Better syntax for the define_index_type macro (no concrete ideas). |
135 | | //! - Allow the generated type to be a tuple struct, or use a specific field |
136 | | //! name. |
137 | | //! - Allow use of indices for string types (the primary benefit here would |
138 | | //! probably be the ability to e.g. use u32 without too much pain rather than |
139 | | //! mixing up indices from different strings -- but you never know!) |
140 | | //! - ... |
141 | | //! |
142 | | #![allow(clippy::inline_always)] |
143 | | #![allow(clippy::partialeq_ne_impl)] |
144 | | #![no_std] |
145 | | extern crate alloc; |
146 | | |
147 | | use alloc::{ |
148 | | borrow::{Cow, ToOwned}, |
149 | | boxed::Box, |
150 | | vec, |
151 | | vec::Vec, |
152 | | }; |
153 | | use core::{ |
154 | | borrow::{Borrow, BorrowMut}, |
155 | | fmt, |
156 | | fmt::Debug, |
157 | | hash::Hash, |
158 | | iter::{self, FromIterator}, |
159 | | marker::PhantomData, |
160 | | ops::Range, |
161 | | slice, |
162 | | }; |
163 | | mod idxslice; |
164 | | mod indexing; |
165 | | pub use idxslice::{IndexBox, IndexSlice}; |
166 | | pub use indexing::{IdxRangeBounds, IdxSliceIndex}; |
167 | | #[cfg(feature = "nonmax")] |
168 | | pub use nonmax; |
169 | | #[cfg(feature = "rayon")] |
170 | | pub use rayon_impl::*; |
171 | | #[cfg(feature = "serde")] |
172 | | pub use serde; |
173 | | #[cfg(feature = "rayon")] |
174 | | mod rayon_impl; |
175 | | |
176 | | #[macro_use] |
177 | | mod macros; |
178 | | |
179 | | /// Represents a wrapped value convertible to and from a `usize`. |
180 | | /// |
181 | | /// Generally you implement this via the [`define_index_type!`] macro, rather |
182 | | /// than manually implementing it. |
183 | | /// |
184 | | /// # Overflow |
185 | | /// |
186 | | /// `Idx` impls are allowed to be smaller than `usize`, which means converting |
187 | | /// `usize` to an `Idx` implementation might have to handle overflow. |
188 | | /// |
189 | | /// The way overflow is handled is up to the implementation of `Idx`, but it's |
190 | | /// generally panicking, unless it was turned off via the |
191 | | /// `DISABLE_MAX_INDEX_CHECK` option in [`define_index_type!`]. If you need more |
192 | | /// subtle handling than this, then you're on your own (or, well, either handle |
193 | | /// it earlier, or pick a bigger index type). |
194 | | /// |
195 | | /// Note: I'm open for suggestions on how to handle this case, but do not want |
196 | | /// the typical cases (E.g. Idx is a newtyped `usize` or `u32`), to become more |
197 | | /// complex. |
198 | | pub trait Idx: Copy + 'static + Ord + Debug + Hash { |
199 | | /// The maximum value that can be represented by this index type. |
200 | | const MAX: usize; |
201 | | |
202 | | /// Construct an index from a `usize` without bounds checking. |
203 | | /// |
204 | | /// # SAFETY |
205 | | /// The caller must ensure that `idx <= Self::MAX`. |
206 | | unsafe fn from_usize_unchecked(idx: usize) -> Self; |
207 | | |
208 | | /// Get the underlying index. This is equivalent to `Into<usize>` |
209 | | fn index(self) -> usize; |
210 | | |
211 | | /// Construct an Index from a `usize`. This is equivalent to `From<usize>`. |
212 | | /// |
213 | | /// Note that this will panic if `idx` does not fit (unless checking has |
214 | | /// been disabled, as mentioned above). Also note that `Idx` implementations |
215 | | /// are free to define what "fit" means as they desire. |
216 | 0 | fn from_usize(idx: usize) -> Self { |
217 | 0 | assert!(idx <= Self::MAX); |
218 | | // SAFETY: We checked `idx` is valid |
219 | 0 | unsafe { Self::from_usize_unchecked(idx) } |
220 | 0 | } Unexecuted instantiation: <oxc_syntax::class::ClassId as oxc_index::Idx>::from_usize Unexecuted instantiation: <oxc_syntax::class::ElementId as oxc_index::Idx>::from_usize Unexecuted instantiation: <oxc_syntax::node::NodeId as oxc_index::Idx>::from_usize Unexecuted instantiation: <oxc_syntax::reference::ReferenceId as oxc_index::Idx>::from_usize Unexecuted instantiation: <oxc_syntax::scope::ScopeId as oxc_index::Idx>::from_usize Unexecuted instantiation: <oxc_syntax::symbol::SymbolId as oxc_index::Idx>::from_usize |
221 | | } |
222 | | |
223 | | /// A macro equivalent to the stdlib's `vec![]`, but producing an `IndexVec`. |
224 | | #[macro_export] |
225 | | macro_rules! index_vec { |
226 | | ($($tokens:tt)*) => { |
227 | | $crate::IndexVec::from_vec(vec![$($tokens)*]) |
228 | | } |
229 | | } |
230 | | |
231 | | /// A macro similar to the stdlib's `vec![]`, but producing an |
232 | | /// `Box<IndexSlice<I, [T]>>` (That is, an `IndexBox<I, [T]>`). |
233 | | #[macro_export] |
234 | | macro_rules! index_box { |
235 | | ($($tokens:tt)*) => { |
236 | | $crate::IndexVec::from_vec(vec![$($tokens)*]).into_boxed_slice() |
237 | | } |
238 | | } |
239 | | |
240 | | /// A Vec that only accepts indices of a specific type. |
241 | | /// |
242 | | /// This is a thin wrapper around `Vec`, to the point where the backing vec is a |
243 | | /// public property (called `raw`). This is in part because I know this API is |
244 | | /// not a complete mirror of Vec's (patches welcome). In the worst case, you can |
245 | | /// always do what you need to the Vec itself. |
246 | | /// |
247 | | /// Note that this implements Deref/DerefMut to [`IndexSlice`], and so all the |
248 | | /// methods on IndexSlice are available as well. See it's documentation for some |
249 | | /// further information. |
250 | | /// |
251 | | /// The following extensions to the Vec APIs are added (in addition to the ones |
252 | | /// mentioned in IndexSlice's documentation): |
253 | | /// |
254 | | /// - [`IndexVec::next_idx`], [`IndexSlice::last_idx`] give the next and most |
255 | | /// recent index returned by `push`. |
256 | | /// - [`IndexVec::push`] returns the index the item was inserted at. |
257 | | #[derive(PartialEq, Eq, PartialOrd, Ord, Hash)] |
258 | | pub struct IndexVec<I: Idx, T> { |
259 | | /// Our wrapped Vec. |
260 | | pub raw: Vec<T>, |
261 | | _marker: PhantomData<fn(&I)>, |
262 | | } |
263 | | |
264 | | // SAFETY: Whether `IndexVec` is `Send` depends only on the data, |
265 | | // not the phantom data. |
266 | | unsafe impl<I: Idx, T> Send for IndexVec<I, T> where T: Send {} |
267 | | |
268 | | impl<I: Idx, T: fmt::Debug> fmt::Debug for IndexVec<I, T> { |
269 | | fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
270 | | fmt::Debug::fmt(&self.raw, fmt) |
271 | | } |
272 | | } |
273 | | type Enumerated<Iter, I, T> = iter::Map<iter::Enumerate<Iter>, fn((usize, T)) -> (I, T)>; |
274 | | |
275 | | impl<I: Idx, T> IndexVec<I, T> { |
276 | | /// Construct a new IndexVec. |
277 | | #[inline] |
278 | 1.42M | pub const fn new() -> Self { |
279 | 1.42M | IndexVec { raw: Vec::new(), _marker: PhantomData } |
280 | 1.42M | } Unexecuted instantiation: <oxc_index::IndexVec<oxc_codegen::sourcemap_builder::ColumnOffsetsId, oxc_codegen::sourcemap_builder::ColumnOffsets>>::new <oxc_index::IndexVec<oxc_syntax::node::NodeId, oxc_syntax::node::NodeId>>::new Line | Count | Source | 278 | 177k | pub const fn new() -> Self { | 279 | 177k | IndexVec { raw: Vec::new(), _marker: PhantomData } | 280 | 177k | } |
<oxc_index::IndexVec<oxc_syntax::node::NodeId, oxc_syntax::node::NodeFlags>>::new Line | Count | Source | 278 | 177k | pub const fn new() -> Self { | 279 | 177k | IndexVec { raw: Vec::new(), _marker: PhantomData } | 280 | 177k | } |
<oxc_index::IndexVec<oxc_syntax::node::NodeId, oxc_semantic::node::AstNode>>::new Line | Count | Source | 278 | 177k | pub const fn new() -> Self { | 279 | 177k | IndexVec { raw: Vec::new(), _marker: PhantomData } | 280 | 177k | } |
<oxc_index::IndexVec<oxc_syntax::class::ClassId, oxc_index::IndexVec<oxc_syntax::class::ElementId, oxc_semantic::class::table::Element>>>::new Line | Count | Source | 278 | 177k | pub const fn new() -> Self { | 279 | 177k | IndexVec { raw: Vec::new(), _marker: PhantomData } | 280 | 177k | } |
<oxc_index::IndexVec<oxc_syntax::class::ClassId, alloc::vec::Vec<oxc_semantic::class::table::PrivateIdentifierReference>>>::new Line | Count | Source | 278 | 177k | pub const fn new() -> Self { | 279 | 177k | IndexVec { raw: Vec::new(), _marker: PhantomData } | 280 | 177k | } |
<oxc_index::IndexVec<oxc_syntax::class::ClassId, oxc_syntax::node::NodeId>>::new Line | Count | Source | 278 | 177k | pub const fn new() -> Self { | 279 | 177k | IndexVec { raw: Vec::new(), _marker: PhantomData } | 280 | 177k | } |
Unexecuted instantiation: <oxc_index::IndexVec<oxc_syntax::class::ElementId, oxc_semantic::class::table::Element>>::new <oxc_index::IndexVec<oxc_syntax::scope::ScopeId, oxc_allocator::hash_map::HashMap<oxc_str::ident::Ident, oxc_syntax::symbol::SymbolId, oxc_str::ident_hasher::IdentBuildHasher>>>::new Line | Count | Source | 278 | 177k | pub const fn new() -> Self { | 279 | 177k | IndexVec { raw: Vec::new(), _marker: PhantomData } | 280 | 177k | } |
<oxc_index::IndexVec<oxc_syntax::reference::ReferenceId, oxc_syntax::reference::Reference>>::new Line | Count | Source | 278 | 177k | pub const fn new() -> Self { | 279 | 177k | IndexVec { raw: Vec::new(), _marker: PhantomData } | 280 | 177k | } |
|
281 | | |
282 | | /// Construct a `IndexVec` from a `Vec<T>`. |
283 | | /// |
284 | | /// Panics if it's length is too large for our index type. |
285 | | #[inline] |
286 | | pub fn from_vec(vec: Vec<T>) -> Self { |
287 | | // See if `I::from_usize` might be upset by this length. |
288 | | let _ = I::from_usize(vec.len()); |
289 | | IndexVec { raw: vec, _marker: PhantomData } |
290 | | } |
291 | | |
292 | | /// Construct an IndexVec that can hold at least `capacity` items before |
293 | | /// reallocating. See [`Vec::with_capacity`]. |
294 | | #[inline] |
295 | | pub fn with_capacity(capacity: usize) -> Self { |
296 | | IndexVec { raw: Vec::with_capacity(capacity), _marker: PhantomData } |
297 | | } |
298 | | |
299 | | /// Similar to `self.into_iter().enumerate()` but with indices of `I` and |
300 | | /// not `usize`. |
301 | | #[inline(always)] |
302 | | pub fn into_iter_enumerated(self) -> Enumerated<vec::IntoIter<T>, I, T> { |
303 | | self.raw.into_iter().enumerate().map(|(i, t)| (I::from_usize(i), t)) |
304 | | } |
305 | | |
306 | | /// Creates a splicing iterator that replaces the specified range in the |
307 | | /// vector with the given `replace_with` iterator and yields the removed |
308 | | /// items. See [`Vec::splice`] |
309 | | #[inline] |
310 | | pub fn splice<R, It>( |
311 | | &mut self, |
312 | | range: R, |
313 | | replace_with: It, |
314 | | ) -> vec::Splice<'_, <It as IntoIterator>::IntoIter> |
315 | | where |
316 | | It: IntoIterator<Item = T>, |
317 | | R: IdxRangeBounds<I>, |
318 | | { |
319 | | self.raw.splice(range.into_range(), replace_with) |
320 | | } |
321 | | |
322 | | /// Similar to `self.drain(r).enumerate()` but with indices of `I` and not |
323 | | /// `usize`. |
324 | | #[inline] |
325 | | pub fn drain_enumerated<R: IdxRangeBounds<I>>( |
326 | | &mut self, |
327 | | range: R, |
328 | | ) -> Enumerated<vec::Drain<'_, T>, I, T> { |
329 | | self.raw.drain(range.into_range()).enumerate().map(|(i, t)| (I::from_usize(i), t)) |
330 | | } |
331 | | |
332 | | /// Gives the next index that will be assigned when `push` is |
333 | | /// called. |
334 | | #[inline] |
335 | | pub fn next_idx(&self) -> I { |
336 | | I::from_usize(self.len()) |
337 | | } |
338 | | |
339 | | /// Get a the storage as a `&[T]` |
340 | | #[inline(always)] |
341 | | pub fn as_raw_slice(&self) -> &[T] { |
342 | | &self.raw |
343 | | } |
344 | | |
345 | | /// Get a the storage as a `&mut [T]` |
346 | | #[inline(always)] |
347 | | pub fn as_raw_slice_mut(&mut self) -> &mut [T] { |
348 | | &mut self.raw |
349 | | } |
350 | | |
351 | | /// Equivalent to accessing our `raw` field, but as a function. |
352 | | #[inline(always)] |
353 | | pub const fn as_vec(&self) -> &Vec<T> { |
354 | | &self.raw |
355 | | } |
356 | | |
357 | | /// Equivalent to accessing our `raw` field mutably, but as a function, if |
358 | | /// that's what you'd prefer. |
359 | | #[inline(always)] |
360 | | pub const fn as_mut_vec(&mut self) -> &mut Vec<T> { |
361 | | &mut self.raw |
362 | | } |
363 | | |
364 | | /// Push a new item onto the vector, and return it's index. |
365 | | #[inline] |
366 | 8.88M | pub fn push(&mut self, d: T) -> I { |
367 | 8.88M | let len = self.len(); |
368 | | // SAFETY: The length of a Vec is always valid for indexing. |
369 | | // If len > I::MAX, the Vec would have panicked on allocation long before this point, |
370 | | // as it cannot allocate more than isize::MAX bytes (and typically much less). |
371 | 8.88M | let idx = unsafe { I::from_usize_unchecked(len) }; |
372 | 8.88M | self.raw.push(d); |
373 | 8.88M | idx |
374 | 8.88M | } Unexecuted instantiation: <oxc_index::IndexVec<oxc_codegen::sourcemap_builder::ColumnOffsetsId, oxc_codegen::sourcemap_builder::ColumnOffsets>>::push <oxc_index::IndexVec<oxc_syntax::node::NodeId, oxc_syntax::node::NodeId>>::push Line | Count | Source | 366 | 2.69M | pub fn push(&mut self, d: T) -> I { | 367 | 2.69M | let len = self.len(); | 368 | | // SAFETY: The length of a Vec is always valid for indexing. | 369 | | // If len > I::MAX, the Vec would have panicked on allocation long before this point, | 370 | | // as it cannot allocate more than isize::MAX bytes (and typically much less). | 371 | 2.69M | let idx = unsafe { I::from_usize_unchecked(len) }; | 372 | 2.69M | self.raw.push(d); | 373 | 2.69M | idx | 374 | 2.69M | } |
<oxc_index::IndexVec<oxc_syntax::node::NodeId, oxc_syntax::node::NodeFlags>>::push Line | Count | Source | 366 | 2.69M | pub fn push(&mut self, d: T) -> I { | 367 | 2.69M | let len = self.len(); | 368 | | // SAFETY: The length of a Vec is always valid for indexing. | 369 | | // If len > I::MAX, the Vec would have panicked on allocation long before this point, | 370 | | // as it cannot allocate more than isize::MAX bytes (and typically much less). | 371 | 2.69M | let idx = unsafe { I::from_usize_unchecked(len) }; | 372 | 2.69M | self.raw.push(d); | 373 | 2.69M | idx | 374 | 2.69M | } |
<oxc_index::IndexVec<oxc_syntax::node::NodeId, oxc_semantic::node::AstNode>>::push Line | Count | Source | 366 | 2.69M | pub fn push(&mut self, d: T) -> I { | 367 | 2.69M | let len = self.len(); | 368 | | // SAFETY: The length of a Vec is always valid for indexing. | 369 | | // If len > I::MAX, the Vec would have panicked on allocation long before this point, | 370 | | // as it cannot allocate more than isize::MAX bytes (and typically much less). | 371 | 2.69M | let idx = unsafe { I::from_usize_unchecked(len) }; | 372 | 2.69M | self.raw.push(d); | 373 | 2.69M | idx | 374 | 2.69M | } |
Unexecuted instantiation: <oxc_index::IndexVec<oxc_syntax::class::ClassId, oxc_index::IndexVec<oxc_syntax::class::ElementId, oxc_semantic::class::table::Element>>>::push Unexecuted instantiation: <oxc_index::IndexVec<oxc_syntax::class::ClassId, alloc::vec::Vec<oxc_semantic::class::table::PrivateIdentifierReference>>>::push Unexecuted instantiation: <oxc_index::IndexVec<oxc_syntax::class::ClassId, oxc_syntax::node::NodeId>>::push Unexecuted instantiation: <oxc_index::IndexVec<oxc_syntax::class::ElementId, oxc_semantic::class::table::Element>>::push <oxc_index::IndexVec<oxc_syntax::scope::ScopeId, oxc_allocator::hash_map::HashMap<oxc_str::ident::Ident, oxc_syntax::symbol::SymbolId, oxc_str::ident_hasher::IdentBuildHasher>>>::push Line | Count | Source | 366 | 265k | pub fn push(&mut self, d: T) -> I { | 367 | 265k | let len = self.len(); | 368 | | // SAFETY: The length of a Vec is always valid for indexing. | 369 | | // If len > I::MAX, the Vec would have panicked on allocation long before this point, | 370 | | // as it cannot allocate more than isize::MAX bytes (and typically much less). | 371 | 265k | let idx = unsafe { I::from_usize_unchecked(len) }; | 372 | 265k | self.raw.push(d); | 373 | 265k | idx | 374 | 265k | } |
<oxc_index::IndexVec<oxc_syntax::reference::ReferenceId, oxc_syntax::reference::Reference>>::push Line | Count | Source | 366 | 550k | pub fn push(&mut self, d: T) -> I { | 367 | 550k | let len = self.len(); | 368 | | // SAFETY: The length of a Vec is always valid for indexing. | 369 | | // If len > I::MAX, the Vec would have panicked on allocation long before this point, | 370 | | // as it cannot allocate more than isize::MAX bytes (and typically much less). | 371 | 550k | let idx = unsafe { I::from_usize_unchecked(len) }; | 372 | 550k | self.raw.push(d); | 373 | 550k | idx | 374 | 550k | } |
|
375 | | |
376 | | /// Pops the last item off, returning it. See [`Vec::pop`]. |
377 | | #[inline] |
378 | | pub fn pop(&mut self) -> Option<T> { |
379 | | self.raw.pop() |
380 | | } |
381 | | |
382 | | /// Converts the vector into an owned [`IndexSlice`], dropping excess capacity. |
383 | | #[inline] |
384 | | pub fn into_boxed_slice(self) -> Box<IndexSlice<I, [T]>> { |
385 | | let b = self.raw.into_boxed_slice(); |
386 | | // SAFETY: `IndexSlice` is a thin wrapper around `[T]` with the added marker for the index. |
387 | | unsafe { Box::from_raw(Box::into_raw(b) as *mut IndexSlice<I, [T]>) } |
388 | | } |
389 | | |
390 | | /// Return an iterator that removes the items from the requested range. See |
391 | | /// [`Vec::drain`]. |
392 | | /// |
393 | | /// See also [`IndexVec::drain_enumerated`], which gives you indices (of the |
394 | | /// correct type) as you iterate. |
395 | | #[inline] |
396 | | pub fn drain<R: IdxRangeBounds<I>>(&mut self, range: R) -> vec::Drain<'_, T> { |
397 | | self.raw.drain(range.into_range()) |
398 | | } |
399 | | |
400 | | /// Shrinks the capacity of the vector as much as possible. |
401 | | #[inline] |
402 | | pub fn shrink_to_fit(&mut self) { |
403 | | self.raw.shrink_to_fit(); |
404 | | } |
405 | | |
406 | | /// Shrinks the capacity of the vector with a lower bound. |
407 | | #[inline] |
408 | | pub fn shrink_to(&mut self, min_capacity: usize) { |
409 | | self.raw.shrink_to(min_capacity); |
410 | | } |
411 | | |
412 | | /// Shortens the vector, keeping the first `len` elements and dropping |
413 | | /// the rest. See [`Vec::truncate`] |
414 | | #[inline] |
415 | | pub fn truncate(&mut self, a: usize) { |
416 | | self.raw.truncate(a); |
417 | | } |
418 | | |
419 | | /// Clear our vector. See [`Vec::clear`]. |
420 | | #[inline] |
421 | | pub fn clear(&mut self) { |
422 | | self.raw.clear(); |
423 | | } |
424 | | |
425 | | /// Reserve capacity for `c` more elements. See [`Vec::reserve`] |
426 | | #[inline] |
427 | 693k | pub fn reserve(&mut self, c: usize) { |
428 | 693k | self.raw.reserve(c); |
429 | 693k | } <oxc_index::IndexVec<oxc_syntax::node::NodeId, oxc_syntax::node::NodeId>>::reserve Line | Count | Source | 427 | 112k | pub fn reserve(&mut self, c: usize) { | 428 | 112k | self.raw.reserve(c); | 429 | 112k | } |
<oxc_index::IndexVec<oxc_syntax::node::NodeId, oxc_syntax::node::NodeFlags>>::reserve Line | Count | Source | 427 | 112k | pub fn reserve(&mut self, c: usize) { | 428 | 112k | self.raw.reserve(c); | 429 | 112k | } |
<oxc_index::IndexVec<oxc_syntax::node::NodeId, oxc_semantic::node::AstNode>>::reserve Line | Count | Source | 427 | 112k | pub fn reserve(&mut self, c: usize) { | 428 | 112k | self.raw.reserve(c); | 429 | 112k | } |
<oxc_index::IndexVec<oxc_syntax::scope::ScopeId, oxc_allocator::hash_map::HashMap<oxc_str::ident::Ident, oxc_syntax::symbol::SymbolId, oxc_str::ident_hasher::IdentBuildHasher>>>::reserve Line | Count | Source | 427 | 177k | pub fn reserve(&mut self, c: usize) { | 428 | 177k | self.raw.reserve(c); | 429 | 177k | } |
<oxc_index::IndexVec<oxc_syntax::reference::ReferenceId, oxc_syntax::reference::Reference>>::reserve Line | Count | Source | 427 | 177k | pub fn reserve(&mut self, c: usize) { | 428 | 177k | self.raw.reserve(c); | 429 | 177k | } |
|
430 | | |
431 | | /// Get a ref to the item at the provided index, or None for out of bounds. |
432 | | #[inline] |
433 | 0 | pub fn get<J: IdxSliceIndex<I, T>>(&self, index: J) -> Option<&J::Output> { |
434 | 0 | index.get(self.as_slice()) |
435 | 0 | } |
436 | | |
437 | | /// Get a mut ref to the item at the provided index, or None for out of |
438 | | /// bounds |
439 | | #[inline] |
440 | | pub fn get_mut<J: IdxSliceIndex<I, T>>(&mut self, index: J) -> Option<&mut J::Output> { |
441 | | index.get_mut(self.as_mut_slice()) |
442 | | } |
443 | | |
444 | | /// Resize ourselves in-place to `new_len`. See [`Vec::resize`]. |
445 | | #[inline] |
446 | | pub fn resize(&mut self, new_len: usize, value: T) |
447 | | where |
448 | | T: Clone, |
449 | | { |
450 | | self.raw.resize(new_len, value); |
451 | | } |
452 | | |
453 | | /// Resize ourselves in-place to `new_len`. See [`Vec::resize_with`]. |
454 | | #[inline] |
455 | | pub fn resize_with<F: FnMut() -> T>(&mut self, new_len: usize, f: F) { |
456 | | self.raw.resize_with(new_len, f); |
457 | | } |
458 | | |
459 | | /// Moves all the elements of `other` into `Self`, leaving `other` empty. |
460 | | /// See [`Vec::append`]. |
461 | | #[inline] |
462 | | pub fn append(&mut self, other: &mut Self) { |
463 | | self.raw.append(&mut other.raw); |
464 | | } |
465 | | |
466 | | /// Splits the collection into two at the given index. See |
467 | | /// [`Vec::split_off`]. |
468 | | #[inline] |
469 | | #[must_use] |
470 | | pub fn split_off(&mut self, idx: I) -> Self { |
471 | | Self::from_vec(self.raw.split_off(idx.index())) |
472 | | } |
473 | | |
474 | | /// Remove the item at `index`. See [`Vec::remove`]. |
475 | | #[inline] |
476 | | pub fn remove(&mut self, index: I) -> T { |
477 | | self.raw.remove(index.index()) |
478 | | } |
479 | | |
480 | | /// Remove the item at `index` without maintaining order. See |
481 | | /// [`Vec::swap_remove`]. |
482 | | #[inline] |
483 | | pub fn swap_remove(&mut self, index: I) -> T { |
484 | | self.raw.swap_remove(index.index()) |
485 | | } |
486 | | |
487 | | /// Insert an item at `index`. See [`Vec::insert`]. |
488 | | #[inline] |
489 | | pub fn insert(&mut self, index: I, element: T) { |
490 | | self.raw.insert(index.index(), element); |
491 | | } |
492 | | |
493 | | /// Append all items in the slice to the end of our vector. |
494 | | /// |
495 | | /// See [`Vec::extend_from_slice`]. |
496 | | #[inline] |
497 | | pub fn extend_from_slice(&mut self, other: &IndexSlice<I, [T]>) |
498 | | where |
499 | | T: Clone, |
500 | | { |
501 | | self.raw.extend_from_slice(&other.raw); |
502 | | } |
503 | | |
504 | | /// Forwards to the `Vec::retain` implementation. |
505 | | #[inline] |
506 | | pub fn retain<F: FnMut(&T) -> bool>(&mut self, f: F) { |
507 | | self.raw.retain(f); |
508 | | } |
509 | | |
510 | | /// Forwards to the `Vec::dedup_by_key` implementation. |
511 | | #[inline] |
512 | | pub fn dedup_by_key<F: FnMut(&mut T) -> K, K: PartialEq>(&mut self, key: F) { |
513 | | self.raw.dedup_by_key(key); |
514 | | } |
515 | | |
516 | | /// Forwards to the `Vec::dedup` implementation. |
517 | | #[inline] |
518 | | pub fn dedup(&mut self) |
519 | | where |
520 | | T: PartialEq, |
521 | | { |
522 | | self.raw.dedup(); |
523 | | } |
524 | | |
525 | | /// Forwards to the `Vec::dedup_by` implementation. |
526 | | #[inline] |
527 | | pub fn dedup_by<F: FnMut(&mut T, &mut T) -> bool>(&mut self, same_bucket: F) { |
528 | | self.raw.dedup_by(same_bucket); |
529 | | } |
530 | | |
531 | | /// Get a IndexSlice over this vector. See `as_raw_slice` for converting to |
532 | | /// a `&[T]` (or access `self.raw`). |
533 | | #[inline(always)] |
534 | 118k | pub fn as_slice(&self) -> &IndexSlice<I, [T]> { |
535 | 118k | IndexSlice::new(&self.raw) |
536 | 118k | } Unexecuted instantiation: <oxc_index::IndexVec<oxc_syntax::class::ClassId, std::collections::hash::map::HashMap<alloc::string::String, oxc_str::compact_str::CompactStr, rustc_hash::FxBuildHasher>>>::as_slice <oxc_index::IndexVec<oxc_syntax::node::NodeId, oxc_syntax::node::NodeId>>::as_slice Line | Count | Source | 534 | 118k | pub fn as_slice(&self) -> &IndexSlice<I, [T]> { | 535 | 118k | IndexSlice::new(&self.raw) | 536 | 118k | } |
|
537 | | |
538 | | /// Get a mutable IndexSlice over this vector. See `as_raw_slice_mut` for |
539 | | /// converting to a `&mut [T]` (or access `self.raw`). |
540 | | #[inline(always)] |
541 | | pub fn as_mut_slice(&mut self) -> &mut IndexSlice<I, [T]> { |
542 | | IndexSlice::new_mut(&mut self.raw) |
543 | | } |
544 | | } |
545 | | |
546 | | impl<I: Idx, T> Default for IndexVec<I, T> { |
547 | | #[inline] |
548 | 1.06M | fn default() -> Self { |
549 | 1.06M | Self::new() |
550 | 1.06M | } <oxc_index::IndexVec<oxc_syntax::node::NodeId, oxc_syntax::node::NodeId> as core::default::Default>::default Line | Count | Source | 548 | 177k | fn default() -> Self { | 549 | 177k | Self::new() | 550 | 177k | } |
<oxc_index::IndexVec<oxc_syntax::node::NodeId, oxc_syntax::node::NodeFlags> as core::default::Default>::default Line | Count | Source | 548 | 177k | fn default() -> Self { | 549 | 177k | Self::new() | 550 | 177k | } |
<oxc_index::IndexVec<oxc_syntax::node::NodeId, oxc_semantic::node::AstNode> as core::default::Default>::default Line | Count | Source | 548 | 177k | fn default() -> Self { | 549 | 177k | Self::new() | 550 | 177k | } |
<oxc_index::IndexVec<oxc_syntax::class::ClassId, oxc_index::IndexVec<oxc_syntax::class::ElementId, oxc_semantic::class::table::Element>> as core::default::Default>::default Line | Count | Source | 548 | 177k | fn default() -> Self { | 549 | 177k | Self::new() | 550 | 177k | } |
<oxc_index::IndexVec<oxc_syntax::class::ClassId, alloc::vec::Vec<oxc_semantic::class::table::PrivateIdentifierReference>> as core::default::Default>::default Line | Count | Source | 548 | 177k | fn default() -> Self { | 549 | 177k | Self::new() | 550 | 177k | } |
<oxc_index::IndexVec<oxc_syntax::class::ClassId, oxc_syntax::node::NodeId> as core::default::Default>::default Line | Count | Source | 548 | 177k | fn default() -> Self { | 549 | 177k | Self::new() | 550 | 177k | } |
Unexecuted instantiation: <oxc_index::IndexVec<oxc_syntax::class::ElementId, oxc_semantic::class::table::Element> as core::default::Default>::default |
551 | | } |
552 | | |
553 | | impl<I: Idx, T> Extend<T> for IndexVec<I, T> { |
554 | | #[inline] |
555 | | fn extend<J: IntoIterator<Item = T>>(&mut self, iter: J) { |
556 | | self.raw.extend(iter); |
557 | | } |
558 | | } |
559 | | |
560 | | impl<'a, I: Idx, T: 'a + Copy> Extend<&'a T> for IndexVec<I, T> { |
561 | | #[inline] |
562 | | fn extend<J: IntoIterator<Item = &'a T>>(&mut self, iter: J) { |
563 | | self.raw.extend(iter); |
564 | | } |
565 | | } |
566 | | |
567 | | impl<I: Idx, T> FromIterator<T> for IndexVec<I, T> { |
568 | | #[inline] |
569 | 0 | fn from_iter<J>(iter: J) -> Self |
570 | 0 | where |
571 | 0 | J: IntoIterator<Item = T>, |
572 | | { |
573 | 0 | IndexVec { raw: FromIterator::from_iter(iter), _marker: PhantomData } |
574 | 0 | } |
575 | | } |
576 | | |
577 | | impl<I: Idx, T> IntoIterator for IndexVec<I, T> { |
578 | | type IntoIter = vec::IntoIter<T>; |
579 | | type Item = T; |
580 | | |
581 | | #[inline] |
582 | | fn into_iter(self) -> vec::IntoIter<T> { |
583 | | self.raw.into_iter() |
584 | | } |
585 | | } |
586 | | |
587 | | impl<'a, I: Idx, T> IntoIterator for &'a IndexVec<I, T> { |
588 | | type IntoIter = slice::Iter<'a, T>; |
589 | | type Item = &'a T; |
590 | | |
591 | | #[inline] |
592 | 0 | fn into_iter(self) -> slice::Iter<'a, T> { |
593 | 0 | self.raw.iter() |
594 | 0 | } |
595 | | } |
596 | | |
597 | | impl<'a, I: Idx, T> IntoIterator for &'a mut IndexVec<I, T> { |
598 | | type IntoIter = slice::IterMut<'a, T>; |
599 | | type Item = &'a mut T; |
600 | | |
601 | | #[inline] |
602 | 0 | fn into_iter(self) -> slice::IterMut<'a, T> { |
603 | 0 | self.raw.iter_mut() |
604 | 0 | } |
605 | | } |
606 | | |
607 | | impl<I: Idx, T> From<IndexVec<I, T>> for Box<IndexSlice<I, [T]>> { |
608 | | #[inline] |
609 | | fn from(src: IndexVec<I, T>) -> Self { |
610 | | src.into_boxed_slice() |
611 | | } |
612 | | } |
613 | | |
614 | | impl<I: Idx, T> From<Box<IndexSlice<I, [T]>>> for IndexVec<I, T> { |
615 | | #[inline] |
616 | | fn from(src: Box<IndexSlice<I, [T]>>) -> Self { |
617 | | src.into_vec() |
618 | | } |
619 | | } |
620 | | |
621 | | impl<'a, I: Idx, T> From<Cow<'a, IndexSlice<I, [T]>>> for IndexVec<I, T> |
622 | | where |
623 | | IndexSlice<I, [T]>: ToOwned<Owned = IndexVec<I, T>>, |
624 | | { |
625 | | #[inline] |
626 | | fn from(s: Cow<'a, IndexSlice<I, [T]>>) -> IndexVec<I, T> { |
627 | | s.into_owned() |
628 | | } |
629 | | } |
630 | | |
631 | | impl<'a, I: Idx, T: Clone> From<&'a IndexSlice<I, [T]>> for IndexVec<I, T> { |
632 | | #[inline] |
633 | | fn from(src: &'a IndexSlice<I, [T]>) -> Self { |
634 | | src.to_owned() |
635 | | } |
636 | | } |
637 | | impl<'a, I: Idx, T: Clone> From<&'a mut IndexSlice<I, [T]>> for IndexVec<I, T> { |
638 | | #[inline] |
639 | | fn from(src: &'a mut IndexSlice<I, [T]>) -> Self { |
640 | | src.to_owned() |
641 | | } |
642 | | } |
643 | | |
644 | | impl<I: Idx, T> From<Vec<T>> for IndexVec<I, T> { |
645 | | #[inline] |
646 | | fn from(v: Vec<T>) -> Self { |
647 | | Self { raw: v, _marker: PhantomData } |
648 | | } |
649 | | } |
650 | | |
651 | | impl<I: Idx, T: Clone> Clone for IndexVec<I, T> { |
652 | | #[inline] |
653 | 0 | fn clone(&self) -> Self { |
654 | 0 | Self { raw: self.raw.clone(), _marker: PhantomData } |
655 | 0 | } |
656 | | |
657 | | #[inline] |
658 | | fn clone_from(&mut self, o: &Self) { |
659 | | self.raw.clone_from(&o.raw); |
660 | | } |
661 | | } |
662 | | |
663 | | impl<I: Idx, A> AsRef<[A]> for IndexVec<I, A> { |
664 | | #[inline] |
665 | | fn as_ref(&self) -> &[A] { |
666 | | &self.raw |
667 | | } |
668 | | } |
669 | | |
670 | | impl<I: Idx, A> AsMut<[A]> for IndexVec<I, A> { |
671 | | #[inline] |
672 | | fn as_mut(&mut self) -> &mut [A] { |
673 | | &mut self.raw |
674 | | } |
675 | | } |
676 | | |
677 | | impl<I: Idx, A> AsRef<IndexSlice<I, [A]>> for IndexVec<I, A> { |
678 | | #[inline] |
679 | | fn as_ref(&self) -> &IndexSlice<I, [A]> { |
680 | | IndexSlice::new(&self.raw) |
681 | | } |
682 | | } |
683 | | |
684 | | impl<I: Idx, A> AsMut<IndexSlice<I, [A]>> for IndexVec<I, A> { |
685 | | #[inline] |
686 | | fn as_mut(&mut self) -> &mut IndexSlice<I, [A]> { |
687 | | IndexSlice::new_mut(&mut self.raw) |
688 | | } |
689 | | } |
690 | | |
691 | | impl<I: Idx, A> core::ops::Deref for IndexVec<I, A> { |
692 | | type Target = IndexSlice<I, [A]>; |
693 | | |
694 | | #[inline] |
695 | 20.1M | fn deref(&self) -> &IndexSlice<I, [A]> { |
696 | 20.1M | IndexSlice::new(&self.raw) |
697 | 20.1M | } Unexecuted instantiation: <oxc_index::IndexVec<oxc_codegen::sourcemap_builder::ColumnOffsetsId, oxc_codegen::sourcemap_builder::ColumnOffsets> as core::ops::deref::Deref>::deref <oxc_index::IndexVec<oxc_syntax::node::NodeId, oxc_syntax::node::NodeId> as core::ops::deref::Deref>::deref Line | Count | Source | 695 | 6.22M | fn deref(&self) -> &IndexSlice<I, [A]> { | 696 | 6.22M | IndexSlice::new(&self.raw) | 697 | 6.22M | } |
<oxc_index::IndexVec<oxc_syntax::node::NodeId, oxc_syntax::node::NodeFlags> as core::ops::deref::Deref>::deref Line | Count | Source | 695 | 2.69M | fn deref(&self) -> &IndexSlice<I, [A]> { | 696 | 2.69M | IndexSlice::new(&self.raw) | 697 | 2.69M | } |
<oxc_index::IndexVec<oxc_syntax::node::NodeId, oxc_semantic::node::AstNode> as core::ops::deref::Deref>::deref Line | Count | Source | 695 | 4.82M | fn deref(&self) -> &IndexSlice<I, [A]> { | 696 | 4.82M | IndexSlice::new(&self.raw) | 697 | 4.82M | } |
Unexecuted instantiation: <oxc_index::IndexVec<oxc_syntax::class::ClassId, oxc_index::IndexVec<oxc_syntax::class::ElementId, oxc_semantic::class::table::Element>> as core::ops::deref::Deref>::deref Unexecuted instantiation: <oxc_index::IndexVec<oxc_syntax::class::ClassId, alloc::vec::Vec<oxc_semantic::class::table::PrivateIdentifierReference>> as core::ops::deref::Deref>::deref Unexecuted instantiation: <oxc_index::IndexVec<oxc_syntax::class::ClassId, oxc_syntax::node::NodeId> as core::ops::deref::Deref>::deref Unexecuted instantiation: <oxc_index::IndexVec<oxc_syntax::class::ElementId, oxc_semantic::class::table::Element> as core::ops::deref::Deref>::deref <oxc_index::IndexVec<oxc_syntax::scope::ScopeId, oxc_allocator::hash_map::HashMap<oxc_str::ident::Ident, oxc_syntax::symbol::SymbolId, oxc_str::ident_hasher::IdentBuildHasher>> as core::ops::deref::Deref>::deref Line | Count | Source | 695 | 1.96M | fn deref(&self) -> &IndexSlice<I, [A]> { | 696 | 1.96M | IndexSlice::new(&self.raw) | 697 | 1.96M | } |
<oxc_index::IndexVec<oxc_syntax::reference::ReferenceId, oxc_syntax::reference::Reference> as core::ops::deref::Deref>::deref Line | Count | Source | 695 | 4.47M | fn deref(&self) -> &IndexSlice<I, [A]> { | 696 | 4.47M | IndexSlice::new(&self.raw) | 697 | 4.47M | } |
|
698 | | } |
699 | | |
700 | | impl<I: Idx, A> core::ops::DerefMut for IndexVec<I, A> { |
701 | | #[inline] |
702 | 454k | fn deref_mut(&mut self) -> &mut IndexSlice<I, [A]> { |
703 | 454k | IndexSlice::new_mut(&mut self.raw) |
704 | 454k | } Unexecuted instantiation: <oxc_index::IndexVec<oxc_syntax::class::ClassId, oxc_index::IndexVec<oxc_syntax::class::ElementId, oxc_semantic::class::table::Element>> as core::ops::deref::DerefMut>::deref_mut Unexecuted instantiation: <oxc_index::IndexVec<oxc_syntax::class::ClassId, alloc::vec::Vec<oxc_semantic::class::table::PrivateIdentifierReference>> as core::ops::deref::DerefMut>::deref_mut <oxc_index::IndexVec<oxc_syntax::scope::ScopeId, oxc_allocator::hash_map::HashMap<oxc_str::ident::Ident, oxc_syntax::symbol::SymbolId, oxc_str::ident_hasher::IdentBuildHasher>> as core::ops::deref::DerefMut>::deref_mut Line | Count | Source | 702 | 181k | fn deref_mut(&mut self) -> &mut IndexSlice<I, [A]> { | 703 | 181k | IndexSlice::new_mut(&mut self.raw) | 704 | 181k | } |
<oxc_index::IndexVec<oxc_syntax::reference::ReferenceId, oxc_syntax::reference::Reference> as core::ops::deref::DerefMut>::deref_mut Line | Count | Source | 702 | 273k | fn deref_mut(&mut self) -> &mut IndexSlice<I, [A]> { | 703 | 273k | IndexSlice::new_mut(&mut self.raw) | 704 | 273k | } |
|
705 | | } |
706 | | |
707 | | impl<I: Idx, T> Borrow<IndexSlice<I, [T]>> for IndexVec<I, T> { |
708 | | #[inline] |
709 | | fn borrow(&self) -> &IndexSlice<I, [T]> { |
710 | | self.as_slice() |
711 | | } |
712 | | } |
713 | | |
714 | | impl<I: Idx, T> BorrowMut<IndexSlice<I, [T]>> for IndexVec<I, T> { |
715 | | #[inline] |
716 | | fn borrow_mut(&mut self) -> &mut IndexSlice<I, [T]> { |
717 | | self.as_mut_slice() |
718 | | } |
719 | | } |
720 | | |
721 | | macro_rules! impl_partialeq { |
722 | | ($Lhs: ty, $Rhs: ty) => { |
723 | | impl<'a, 'b, A, B, I: Idx> PartialEq<$Rhs> for $Lhs |
724 | | where |
725 | | A: PartialEq<B>, |
726 | | { |
727 | | #[inline] |
728 | | fn eq(&self, other: &$Rhs) -> bool { |
729 | | self[..] == other[..] |
730 | | } |
731 | | |
732 | | #[inline] |
733 | | fn ne(&self, other: &$Rhs) -> bool { |
734 | | self[..] != other[..] |
735 | | } |
736 | | } |
737 | | }; |
738 | | } |
739 | | |
740 | | macro_rules! impl_partialeq2 { |
741 | | ($Lhs: ty, $Rhs: ty) => { |
742 | | impl<'a, 'b, A, B, I: Idx, J: Idx> PartialEq<$Rhs> for $Lhs |
743 | | where |
744 | | A: PartialEq<B>, |
745 | | { |
746 | | #[inline] |
747 | | fn eq(&self, other: &$Rhs) -> bool { |
748 | | self.raw[..] == other.raw[..] |
749 | | } |
750 | | |
751 | | #[inline] |
752 | | fn ne(&self, other: &$Rhs) -> bool { |
753 | | self.raw[..] != other.raw[..] |
754 | | } |
755 | | } |
756 | | }; |
757 | | } |
758 | | |
759 | | impl_partialeq! { IndexVec<I, A>, Vec<B> } |
760 | | impl_partialeq! { IndexVec<I, A>, &'b [B] } |
761 | | impl_partialeq! { IndexVec<I, A>, &'b mut [B] } |
762 | | |
763 | | impl_partialeq2! { IndexVec<I, A>, &'b IndexSlice<J, [B]> } |
764 | | impl_partialeq2! { IndexVec<I, A>, &'b mut IndexSlice<J, [B]> } |
765 | | |
766 | | impl_partialeq! { &'a IndexSlice<I, [A]>, Vec<B> } |
767 | | impl_partialeq! { &'a mut IndexSlice<I, [A]>, Vec<B> } |
768 | | |
769 | | impl_partialeq! { IndexSlice<I, [A]>, &'b [B] } |
770 | | impl_partialeq! { IndexSlice<I, [A]>, &'b mut [B] } |
771 | | |
772 | | impl_partialeq2! { &'a IndexSlice<I, [A]>, IndexVec<J, B> } |
773 | | impl_partialeq2! { &'a mut IndexSlice<I, [A]>, IndexVec<J, B> } |
774 | | |
775 | | impl_partialeq2! { IndexSlice<I, [A]>, &'a IndexSlice<J, [B]> } |
776 | | impl_partialeq2! { IndexSlice<I, [A]>, &'a mut IndexSlice<J, [B]> } |
777 | | |
778 | | macro_rules! array_impls { |
779 | | ($($N: expr_2021)+) => {$( |
780 | | impl_partialeq! { IndexVec<I, A>, [B; $N] } |
781 | | impl_partialeq! { IndexVec<I, A>, &'b [B; $N] } |
782 | | impl_partialeq! { IndexSlice<I, [A]>, [B; $N] } |
783 | | impl_partialeq! { IndexSlice<I, [A]>, &'b [B; $N] } |
784 | | // impl_partialeq! { &'a IndexSlice<I, [A]>, [B; $N] } |
785 | | // impl_partialeq! { &'a IndexSlice<I, [A]>, &'b [B; $N] } |
786 | | )+}; |
787 | | } |
788 | | |
789 | | array_impls! { |
790 | | 0 1 2 3 4 5 6 7 8 9 |
791 | | 10 11 12 13 14 15 16 17 18 19 |
792 | | 20 21 22 23 24 25 26 27 28 29 |
793 | | 30 31 32 |
794 | | } |
795 | | |
796 | | #[inline(never)] |
797 | | #[cold] |
798 | | #[doc(hidden)] |
799 | | pub fn __max_check_fail(u: usize, max: usize) -> ! { |
800 | | panic!("index_vec index overflow: {} is outside the range [0, {})", u, max,) |
801 | | } |
802 | | |
803 | | #[cfg(feature = "serde")] |
804 | | impl<I: Idx, T: crate::serde::ser::Serialize> crate::serde::ser::Serialize for IndexVec<I, T> { |
805 | | fn serialize<S: crate::serde::ser::Serializer>( |
806 | | &self, |
807 | | serializer: S, |
808 | | ) -> Result<S::Ok, S::Error> { |
809 | | self.raw.serialize(serializer) |
810 | | } |
811 | | } |
812 | | |
813 | | #[cfg(feature = "serde")] |
814 | | impl<'de, I: Idx, T: crate::serde::de::Deserialize<'de>> crate::serde::de::Deserialize<'de> |
815 | | for IndexVec<I, T> |
816 | | { |
817 | | fn deserialize<D: crate::serde::de::Deserializer<'de>>( |
818 | | deserializer: D, |
819 | | ) -> Result<Self, D::Error> { |
820 | | Vec::deserialize(deserializer).map(Self::from_vec) |
821 | | } |
822 | | } |
823 | | |
824 | | #[cfg(feature = "serde")] |
825 | | impl<I: Idx, T: crate::serde::ser::Serialize> crate::serde::ser::Serialize for IndexBox<I, T> { |
826 | | fn serialize<S: crate::serde::ser::Serializer>( |
827 | | &self, |
828 | | serializer: S, |
829 | | ) -> Result<S::Ok, S::Error> { |
830 | | self.raw.serialize(serializer) |
831 | | } |
832 | | } |
833 | | |
834 | | #[cfg(feature = "serde")] |
835 | | impl<'de, I: Idx, T: crate::serde::de::Deserialize<'de>> crate::serde::de::Deserialize<'de> |
836 | | for IndexBox<I, [T]> |
837 | | { |
838 | | fn deserialize<D: crate::serde::de::Deserializer<'de>>( |
839 | | deserializer: D, |
840 | | ) -> Result<Self, D::Error> { |
841 | | Box::<[T]>::deserialize(deserializer).map(Into::into) |
842 | | } |
843 | | } |
844 | | |
845 | | #[cfg(test)] |
846 | | #[expect(clippy::legacy_numeric_constants)] |
847 | | mod test { |
848 | | use super::*; |
849 | | |
850 | | define_index_type! { |
851 | | pub struct TestIdx = u32; |
852 | | } |
853 | | |
854 | | #[test] |
855 | | fn test_resize() { |
856 | | let mut v = IndexVec::<TestIdx, u32>::with_capacity(10); |
857 | | assert_eq!(v.len(), 0); |
858 | | assert!(v.is_empty()); |
859 | | |
860 | | v.push(1); |
861 | | assert_eq!(v.len(), 1); |
862 | | |
863 | | v.resize(5, 1); |
864 | | assert_eq!(v.len(), 5); |
865 | | assert_eq!(v.as_slice(), &[1, 1, 1, 1, 1]); |
866 | | |
867 | | v.shrink_to_fit(); |
868 | | assert_eq!(v.len(), 5); |
869 | | } |
870 | | |
871 | | #[test] |
872 | | fn test_push_pop() { |
873 | | let mut v = IndexVec::<TestIdx, u32>::new(); |
874 | | v.push(1); |
875 | | assert_eq!(v.pop(), Some(1)); |
876 | | } |
877 | | |
878 | | #[test] |
879 | | fn test_clear() { |
880 | | let mut v: IndexVec<TestIdx, u32> = [1, 2, 3].into_iter().collect(); |
881 | | assert_eq!(v.len(), 3); |
882 | | |
883 | | v.clear(); |
884 | | assert_eq!(v.len(), 0); |
885 | | assert_eq!(v.as_slice(), &[]); |
886 | | assert_eq!(v, IndexVec::<TestIdx, u32>::new()); |
887 | | } |
888 | | } |