[−][src]Crate index_vec
This crate helps with defining "newtype"-style wrappers around usize
(or
other integers), and Vec<T>
so that some additional type safety can be
gained at zero cost.
It's was initially derived from some code in rustc
, but has diverged since
then.
Example / Overview
use index_vec::{IndexVec, index_vec}; index_vec::define_index_type! { // Define StrIdx to use only 32 bits internally (you can use usize, u16, // and even u8). pub struct StrIdx = u32; // The defaults are very reasonable, but this macro can let // you customize things quite a bit: // By default, creating a StrIdx would check an incoming `usize against // `u32::max_value()`, as u32 is the wrapped index type. Lets imagine that // StrIdx has to interface with an external system that uses signed ints. // We can change the checking behavior to complain on i32::max_value() // instead: MAX_INDEX = i32::max_value() as usize; // We can also disable checking all-together if we are more concerned with perf // than any overflow problems, or even do so, but only for debug builds: Quite // pointless here, but an okay example DISABLE_MAX_INDEX_CHECK = cfg!(not(debug_assertions)); // And more too, see this macro's docs for more info. } // Create a vector which can be accessed using `StrIdx`s. let mut strs: IndexVec<StrIdx, &'static str> = index_vec!["strs", "bar", "baz"]; // l is a `StrIdx` let l = strs.last_idx(); assert_eq!(strs[l], "baz"); let new_i = strs.push("quux"); assert_eq!(strs[new_i], "quux"); // Indices are mostly interoperable with `usize`, and support // a lot of what you might want to do to an index. // Comparison assert_eq!(StrIdx::new(0), 0usize); // Addition assert_eq!(StrIdx::new(0) + 1, 1usize); // Subtraction assert_eq!(StrIdx::new(1) - 1, 0usize); // Wrapping assert_eq!(StrIdx::new(5) % strs.len(), 1usize); // ...
Background
The goal is to help with the pattern of using a type FooIdx = usize
to
access a Vec<Foo>
with something that can statically prevent using a
FooIdx
in a Vec<Bar>
. It's most useful if you have a bunch of indices
referring to different sorts of vectors.
Much of the code for this is taken from rustc
's IndexVec
code, however
it's diverged a decent amount at this point. Some notable changes:
- No usage of unstable features.
- Different syntax for defining index types.
- More complete mirroring of Vec's API.
- Allows use of using other index types than
u32
/usize
. - More flexible behavior around how strictly some checks are performed,
Other crates
The indexed_vec
crate predates
this, and is a much closer copy of the code from rustc
. Unfortunately,
this means it does not compile on stable.
If you're looking for something further from a vec and closer to a map, you
might find handy
,
slotmap
, or
slab
to be closer what you want.
Modules
example_generated | This module is just for documentation purposes, and is hidden behind the
|
Macros
define_index_type | Generate the boilerplate for a newtyped index struct, for use with
|
index_vec | A macro equivalent to the stdlib's |
Structs
IndexVec | A Vec that only accepts indices of a specific type. |
Traits
Idx | Represents a wrapped value convertable to and from a |