thunderation 0.1.0

Fast arena-based map with compact generational indices
Documentation
# Thunderation 🌩️

[![Documentation](https://docs.rs/thunderation/badge.svg)](https://docs.rs/thunderation)
[![Crates.io](https://img.shields.io/crates/v/thunderation.svg)](https://crates.io/crates/thunderation)
[![License](https://img.shields.io/crates/l/thunderation.svg)](https://codeberg.org/BillyDM/thunderation/src/branch/main/LICENSE-MIT)
[![NO AI](https://raw.githubusercontent.com/nuxy/no-ai-badge/master/badge.svg)](https://github.com/nuxy/no-ai-badge)

Thunderation is a generational arena forked from
[Thunderdome](https://crates.io/crates/thunderdome). It adds a few
improvements like unique key type identifiers, improved methods, and the removal
of all unsafe code.

It provides constant time insertion,
lookup, and removal via small (8 byte) keys returned from `Arena`.

Thunderation's key type, `Key`, is still 8 bytes when put inside of an
`Option<T>` thanks to Rust's `NonZero*` types.

# Why use this over [slotmap]https://crates.io/crates/slotmap?

The main reason is when you need to get and set values by their slot index
in addition to generational keys. If you do not need this, consider using
slotmap instead.

# Basic Examples

```rust
use thunderation::{Arena, Key};

// Define a unique key type identifier. This prevents keys from
// being used in Arena's they don't belong to.
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
pub struct MyKey;

// Create an arena with the given key type and the storage type.
let mut arena = Arena::<MyKey, &'static str>::new();

let foo = arena.insert("Foo");
let bar = arena.insert("Bar");

assert_eq!(arena[foo], "Foo");
assert_eq!(arena[bar], "Bar");

// Methods to get/set items by slot index are also available.
let (key, value) = arena.get_by_slot(foo.slot()).unwrap();
assert_eq!(key, foo);
assert_eq!(value, &"Foo");

arena[bar] = "Replaced";
assert_eq!(arena[bar], "Replaced");

let foo_value = arena.remove(foo);
assert_eq!(foo_value, Some("Foo"));

// The slot previously used by foo will be reused for baz
let baz = arena.insert("Baz");
assert_eq!(arena[baz], "Baz");

// foo is no longer a valid key
assert_eq!(arena.get(foo), None);
```

# Comparison With Similar Crates

| Feature                      | Thunderation | Thunderdome | generational-arena | typed-generational-arena | slotmap | slab |
|------------------------------|--------------|-------------|--------------------|--------------------------|---------|------|
| Generational¹                | Yes          | Yes         | Yes                | Yes                      | Yes     | No   |
| `size_of::<Key>()`           | 8            | 8           | 16                 | varies                   | 8       | 8    |
| `size_of::<Option<Key>>()`   | 8            | 8           | 24                 | varies                   | 8       | 16   |
| Max elements                 | 2³²          | 2³²         | 2⁶⁴                | 2⁶⁴                      | 2³²     | 2⁶⁴  |
| Non-`Copy` values            | Yes          | Yes         | Yes                | Yes                      | Yes     | Yes  |
| `no_std` support             | Yes          | Yes         | Yes                | Yes                      | Yes     | Yes  |
| Uniquely typed keys          | Yes          | No          | No                 | Yes                      | Yes     | No   |
| Get/set values by slot index | Yes          | Yes         | No                 | No                       | No      | Yes  |
| Zero unsafe used             | Yes          | No          | Yes                | Yes                      | No      | No   |
| Serde support                | No           | No          | Yes                | Yes                      | Yes     | No   |

> 1. Generational indices help solve the [ABA
> Problem](https://en.wikipedia.org/wiki/ABA_problem), which can cause dangling
> keys to mistakenly access newly-inserted data.

# Crate Features
* `std` (default): Use the standard library. Disable to make this crate `no-std` compatible.

## License

Licensed under either of

 * Apache License, Version 2.0, ([LICENSE-APACHE]LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
 * MIT license ([LICENSE-MIT]LICENSE-MIT or http://opensource.org/licenses/MIT)

at your option.