Expand description
Type erased vector AnyVec
. Allow to store elements of the same type.
Have same performance and operations as std::vec::Vec
.
You can downcast type erased AnyVec
to concrete AnyVecTyped
with downcast
-family.
Or use AnyVec
type erased operations, which works with any_value
.
use any_vec::AnyVec;
let mut vec: AnyVec = AnyVec::new::<String>();
{
// Typed operations.
let mut vec = vec.downcast_mut::<String>().unwrap();
vec.push(String::from("0"));
vec.push(String::from("1"));
vec.push(String::from("2"));
}
let mut other_vec: AnyVec = AnyVec::new::<String>();
// Fully type erased element move from one vec to another
// without intermediate mem-copies.
let element = vec.swap_remove(0);
other_vec.push(element);
// Output 2 1
for s in vec.downcast_ref::<String>().unwrap(){
println!("{}", s);
}
N.B. AnyVecTyped
operations may be somewhat faster, due to the fact that
compiler able to do better optimisation with full type knowledge.
§Send, Sync, Clone
You can make AnyVec
Send
able, Sync
able, Cloneable
:
use any_vec::AnyVec;
use any_vec::traits::*;
let v1: AnyVec<dyn Cloneable + Sync + Send> = AnyVec::new::<String>();
let v2 = v1.clone();
This constraints will be applied compiletime to element type:
let v1: AnyVec<dyn Sync + Send> = AnyVec::new::<Rc<usize>>();
§LazyClone
Whenever possible, any_vec
types implement AnyValueCloneable
, which
can work with LazyClone
:
let mut v1: AnyVec<dyn Cloneable> = AnyVec::new::<String>();
v1.push(AnyValueWrapper::new(String::from("0")));
let mut v2: AnyVec<dyn Cloneable> = AnyVec::new::<String>();
let e = v1.swap_remove(0);
v2.push(e.lazy_clone());
v2.push(e.lazy_clone());
§MemBuilder
MemBuilder
+ Mem
works like Allocator
for AnyVec
. But unlike allocator,
Mem
container-specialized design allows to perform more optimizations. For example,
it is possible to make stack-allocated FixedAnyVec
and small-buffer-optimized(SBO) SmallAnyVec
from AnyVec
by just changing MemBuilder
:
type FixedAnyVec<Traits = dyn None> = AnyVec<Traits, Stack<512>>;
let mut any_vec: FixedAnyVec = AnyVec::new::<String>();
// This will be on stack, without any allocations.
any_vec.push(AnyValueWrapper::new(String::from("0")))
With help of clone_empty_in
you can use stack allocated, or SBO AnyVec
as fast intermediate storage for values of unknown type:
fn self_push_first_element<T: Trait + Cloneable>(any_vec: &mut AnyVec<T>){
let mut tmp = any_vec.clone_empty_in(StackN::<1, 256>);
tmp.push(any_vec.at(0).lazy_clone());
any_vec.push(tmp.pop().unwrap());
}
MemBuilder
interface, being stateful, allow to make Mem
,
which can work with complex custom allocators.
§AnyValue
Being type erased, AnyVec needs a way to operate on untyped values safely.
Instead of working with plain *mut u8
, AnyVec operates with any_value.
AnyValue is a trait, that provide operations to work with type erased values. Any type that implements AnyValue can be used with AnyVec. AnyValue interface allows to perform postponed operations on consumption. This trick used heavily by AnyVec destructive operations, which instead of concrete type return AnyValue, which perform actual operation on value drop.
Implementing AnyValueMut and AnyValueCloneable makes type mutable and cloneable respectively.
§No alloc
This library is no_std
and can work without alloc
.
For this - disable default alloc
feature. mem::Heap will become unavailable
after that, and you’ll have to specify MemBuilder for AnyVec. You can use
mem::Stack, or specify your own Mem.
Modules§
- AnyValue is concept of type-erased object, that can be moved around without type knowledge.
- AnyVec operations.
Structs§
- Type erased vec-like container. All elements have the same type.
- Typed view to &mut
AnyVec
. - Typed view to &
AnyVec
. - Concrete type
AnyVec
representation. AnyVec
iterator.AnyVec
raw parts.
Traits§
- Trait for compile time check - does
T
satisfyTraits
constraints.
Type Aliases§
- Mutable reference
AnyVec
iterator. ReturnElementMut
items. - Reference
AnyVec
iterator. ReturnElementRef
items.