index_vec
Note: Currently in alpha, but will probably stabilize by the end of the week or so
A more type-safe version of using Vec
, for when usize
s are getting you down.
This library mainly provides IndexVec<I, T>
, which wraps Vec
so that it's
accessed with I
and not usize
.
It also defines a macro for defining new index types (for use with IndexVec). Mostly outputting boilerplate.
```rust use indexvec::{IndexVec, indexvec};
// Define a custom index type. indexvec::defineindex_type! { // In this case, use a u32 instead of a usize. pub struct StrIdx(u32); // Note that this macro has a decent amount of configurability, so // be sure to read its documentation if you think it's doing // something you don't want. }
// Create a vector which can be accessed using StrIdx
s.
let mut strs: IndexVec
// l is a StrIdx
let l = strs.lastidx();
asserteq!(strs[l], "baz");
let newi = strs.push("quux"); asserteq!(strs[new_i], "quux");
// Indices are mostly interoperable with usize
, and support
// a lot of what you might want to do to an index. (Note that
// it does not support these with other index wrappers --
// that seems too likely to lead to bugs).
// Comparison asserteq!(StrIdx::new(0), 0usize); // Addition asserteq!(StrIdx::new(0) + 1, 1usize);
// Subtraction (Note that by default, the index will panic on overflow, // but that can be configured in the macro) assert_eq!(StrIdx::new(1) - 1, 0usize);
// Wrapping assert_eq!(StrIdx::new(5) % strs.len(), 1usize); // ... ```
The goal is to replace 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. The largest differences are:
u32
(usize
, u32
, u16
, and u8
are
all supported).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.
This is based on code from rustc
's source, and retains it's status as
dual-licensed under MIT (LICENSE-MIT) / Apache 2.0 (LICENSE-APACHE).