# vecshard
Split Vecs in O(1) time.
You can split a [`Vec`] into two using [`Vec::split_off`](std::vec::Vec::split_off),
but since most allocators can't just go and split up an allocation, this needs to allocate space
for a second [`Vec`] and, even worse, copy the relevant elements over, which takes O(n) time.
You could also split it into slices using `Vec::split_at` or
`Vec::split_at_mut`, but this will not give you owned
data you can move around or move out of at will.
This crate provides a way to split a [`Vec`] into two owned [`VecShard`]s that
behave similar to Vecs that takes constant time.
The catch is that the [`VecShard`]s use reference counting to determine when the last of them is dropped.
Only then is the memory from the original [`Vec`] deallocated.
The individual items in the shards, however, are dropped as soon as the shard is dropped.
This functionality is provided through an extension trait for [`Vec`], [`ShardExt`](crate::ShardExt).
## Basic Example
```rust
use vecshard::ShardExt;
let animals = vec!["penguin", "owl", "toucan", "turtle", "spider", "mosquitto"];
// split the vec into 2 shards
let (cool_animals, uncool_animals) = animals.split_inplace_at(4);
// shards can be indexed as usual
assert_eq!(cool_animals[3], "turtle");
assert_eq!(uncool_animals[0], "spider");
// ..including with a range as index
assert_eq!(cool_animals[1..3], ["owl", "toucan"]);
// they deref into slices, so you can use them as such:
assert_eq!(cool_animals.len(), 4);
assert!(uncool_animals.ends_with(&["mosquitto"]));
// shards can also be split up again:
let (cool_birds, cool_reptiles) = cool_animals.split_inplace_at(3);
assert_eq!(*cool_birds, ["penguin", "owl", "toucan"]);
assert_eq!(*cool_reptiles, ["turtle"]);
```
## Conversion
Shards can be freely converted both [`From`](std::convert::From) and [`Into`](std::convert::Into) Vecs.
Note that the latter may need to allocate if there are other shards also using the shards allocation.
```rust
let vec = vec![1, 2, 3];
let shard = VecShard::from(vec);
let vec2 : Vec<_> = shard.into();
```
## Iteration
To iterate over a [`VecShard`], you have several choices.
[`VecShard<T>`](crate::VecShard) itself is a draining [`Iterator`] and returns owned `T` instances,
removing them from its own storage.
If you only need `&T` or `&mut T`, you can deref it to a slice and iterate over that.
Finally, if you need an owning [`Iterator`] but do not want to drain the shard,
you can [`clone`][std::clone::Clone::clone] the shard and iterate over that.
```rust
let mut shard = VecShard::from(vec!['y', 'e', 'e', 't']);
assert_eq!(Some('y'), shard.next());
assert_eq!(Some('e'), shard.next());
assert_eq!(*shard, ['e', 't']);
```
[`VecShard`]: crate::VecShard
License: CC0-1.0