Indexical is a library for efficiently working with indexed collections of objects. "Indexed" means that the domain of objects is finite, and you can assign a numeric index to each object. This enables the use of efficient data structures like bit-sets.
Indexical is a layer on top of existing bit-set libraries like bitvec and [rustc_index]. Those data structures only "understand" indexes, not the objects represented by the index. Indexical provides utilities for converting between the object domain and the index domain.
Example
use ;
use Rc;
// First, define a custom type.
;
// Second, define a new index for your custom type.
define_index_type!
// Third, create an indexed domain from a collection of objects.
let domain = new;
// Finally, you can make a set! Notice how you can pass either a `MyString`
// or a `StringIndex` to `set.insert(..)` and `set.contains(..)`.
let mut set = new;
set.insert;
set.insert;
assert!;
Design
The key idea is that the [IndexedDomain] is wrapped in a reference-counted pointer like Rc and shared pervasively
across all Indexical types. All types can then use the [IndexedDomain] to convert between indexes and objects.
[IndexSet] and [IndexMatrix] are generic with respect to two things:
- The choice of bit-set implementation. By default, Indexical includes the [
bitvec] crate and provides the [impls::BitvecIndexSet] type. You can provide your own bit-set implementation via the [BitSet] trait. - The choice of reference-counted pointer. By default, Indexical uses the
Rcpointer via the [RcFamily] type. You can choose to use the [ArcFamily] if you need concurrency. You can also implement your own pointer family.
[rustc_index]: (https://doc.rust-lang.org/nightly/nightly-rustc/rustc_index