Coverage Report

Created: 2026-10-28 07:08

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
}