index_vec

Docs

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 usizes 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.

Example / Overview

```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 StrIdxs. let mut strs: IndexVec = index_vec!["strs", "bar", "baz"];

// 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); // ... ```

Background

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:

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.

License

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).