trait-obj-list 0.1.2

List of unsized trait objects, stored in a flat array
Documentation
<!-- cargo-rdme start -->

A list of objects that all implement a trait, stored in one buffer.

Provides the [`DynList`](https://docs.rs/trait-obj-list/latest/trait_obj_list/struct.DynList.html) data structure. This can be thought
of a `Vec<T>` where `T` is some `dyn Trait`. Different implementors of the
trait can be added to the vec, and iterating the vector will return `dyn Trait`
references.

Unlike, for example, a `Vec<Box<dyn Trait>>`, a `DynList` will store all of
the values in one flat array, allowing for more efficient allocation and
iteration.

The tradeoff is that a `DynList` is not as flexible as a `Vec` in how it can
be accessed. Because items in the list take up a variable amount of size,
random access is not as efficient, and items can only be pushed onto the end
of the list.

```rust
let mut list = DynList::<dyn Any>::new();
list.push(123i32);
list.push(String::from("Hello world!"));
list.push(true);

for item in list.iter() {
    if let Some(item) = item.downcast_ref::<i32>() {
        println!("{}", *item + 7);
    } else if let Some(item) = item.downcast_ref::<String>() {
        println!("Text: {item}");
    } else if let Some(item) = item.downcast_ref::<bool>() {
        println!("{}", !*item);
    }
}
```

# List Types

The second generic argument to `DynList` is the internal structure, to select
the tradeoffs between storage size and access. The following types are available:

* `DoubleLinked`: The default. Stores the trait metadata, trait data, and a
  length at the end. Allows iterating the list in both directions, but has slightly more
  overhead than `SingleLinked`.
* `SingleLinked`: Stores the trait metadata and data, and nothing else. This
  is the most comapact representation, but only allows iteration in list order.

# Stable Rust Limitations

On stable Rust, the `ptr_meta` feature is required. This uses the `ptr_meta`
crate to get the metadata of wide pointers, and so only works with traits that
implement `ptr_meta::Pointee`. `ptr_meta` provides an implementation for `Any`
and `Error` (plus their `Send` and `Sync` variants), but others will need to
use the `ptr_meta::pointee` attribute.

Additionally, `DynList::push` requires that the pushed type implement
[`FromImpl`](https://docs.rs/trait-obj-list/latest/trait_obj_list/trait.FromImpl.html). The trait can be implemented for all sized types implementing
a certain trait via the `impl_from_impl` macro.

On nightly Rust, the `ptr_meta` feature can be omitted, in which case the
`ptr_metadata` and `unsize` unstable features are used to lift these limitations.
In this case, `DynList` will work with any trait and type.

# Safety

This crate uses `unsafe` a lot, due to having to manage allocations manually and work
with dynamically sized types. To help ensure soundness, the test suite is checked with
miri, so that any unsound accesses are caught and fixed.

<!-- cargo-rdme end -->