[][src]Crate vec_option

vec-option

A space optimized version of Vec<Option<T>> that stores the discriminant seperately.

Feature flags

nightly - This turns on a few optimizations (makes Cloneing Copy elements much cheaper) and extends try_fold and try_for_each to work with all Try types. Finally, this also allows the iterator.nth_back(n) methods to be used.

Pros

  • Can have a smaller memory footprint compared to Vec<Option<T>> if Option<T>'s space optimizations don't take effect
  • More cache-friendly if Option<T>'s space optimizations don't take effect
  • Quickly set the entire collection to contain None
  • Fast extend with None

Cons

  • 2 allocations, instead of a single allocation
  • Cannot remove elements from the middle of the vector
  • Cannot work on the option's directly

Example

Just like a normal vector, you can push and pop elements from the end of the vector

let mut vec = VecOption::new();

vec.push(10);

assert_eq!(vec, [Some(10)]);

vec.push(20);
vec.push(None);
vec.push(Some(30));

assert_eq!(vec, [Some(10), Some(20), None, Some(30)]);

assert_eq!(vec.pop(), Some(Some(30)));
assert_eq!(vec.pop(), Some(None));
assert_eq!(vec.pop(), Some(Some(20)));
assert_eq!(vec.pop(), Some(Some(10)));
assert_eq!(vec.pop(), None);
assert_eq!(vec, []);

You can get elements from the vector

let mut vec = VecOption::from(vec![0, 1, 2, 3, 4]);
assert_eq!(vec.len(), 5);
assert_eq!(vec, [Some(0), Some(1), Some(2), Some(3), Some(4)]);
// assert_eq!(vec.get(2), Some(Some(&2)));
// assert_eq!(vec.get_mut(4), Some(Some(&mut 4)));
assert_eq!(vec.get(5), None);

You can swap and replace elements

This example is not tested
vec.swap(2, 1);

assert_eq!(vec, [Some(0), Some(2), Some(1), Some(3), Some(4)]);

assert_eq!(vec.replace(3, None), Some(Some(3)));
assert_eq!(vec.replace(1, Some(10)), Some(Some(1)));

assert_eq!(vec, [Some(0), Some(10), Some(1), None, Some(4)]);

or if vec.replace(index, None) is too much, you can do

This example is not tested
assert_eq!(vec.take(1), Some(Some(10)));

assert_eq!(vec, [Some(0), None, Some(1), None, Some(4)]);

Of course, you can also truncate or clear the vector

let mut vec = VecOption::from(vec![0, 1, 3, 4]);

assert_eq!(vec.len(), 4);

vec.truncate(2);

assert_eq!(vec, [Some(0), Some(1)]);

vec.clear();

assert!(vec.is_empty());

But due to the limitations imposed by spliting the representation of the vector, you can't really get a &Option<T>/&mut Option<T> outside of a closure. In fact, you can't get an &Option<T> at all, it would be fairly useless, as the only thing you can really do with it is convert it to a Option<&T>. But &mut Option<T> is usefull, so there are a handful of functions that allow you to operate with them.

These functions below are like the corrosponding functions in Iterator, they iterate over the vector and allow you to do stuff based on which one you call. The only difference is that you get to operate on &mut Option<T> directly. Again, if the closure panics, it will be as if you took the value out of the vector.

This example is not tested
vec.try_fold(...);

vec.fold(...);

vec.try_for_each(...);

vec.for_each(...);

But because of these limitations, you can very quickly fill up your vector with None and set all of the elements in your vector to None! This can compile down to just a memset if your types don't have drop glue!

let mut vec = VecOption::from(vec![0, 1, 2, 3, 4]);

assert_eq!(vec, [Some(0), Some(1), Some(2), Some(3), Some(4)]);

vec.extend_none(5);

assert_eq!(vec, [Some(0), Some(1), Some(2), Some(3), Some(4), None, None, None, None, None]);

vec.set_all_none();

assert_eq!(vec, [None, None, None, None, None, None, None, None, None, None]);

Structs

CapacityInfo

The capacity information of the given VecOption<T>

IntoIter

This struct is created by the into_iter method on VecOption (provided by the IntoIterator trait).

Iter

This struct is created by the iter method on VecOption

IterMut

This struct is created by the iter_mut method on VecOption

OptionProxy

A proxy to a mutable reference to an option in a VecOption<T>

VecOption

A space optimized version of Vec<Option<T>> that stores the discriminant seperately