A list of objects that all implement a trait, stored in one buffer.
Provides the DynList 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.
let mut list = new;
list.push;
list.push;
list.push;
for item in list.iter
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 thanSingleLinked.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. 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.