pub struct XsoVec<T: ?Sized> { /* private fields */ }
Expand description
§Container for dynamically-typed XSOs optimized for type-keyed access
This container holds dynamically typed XSOs (see
Xso<dyn Trait>
). It allows efficient access to its contents
based on the actual type.
Like Xso<dyn Trait>
itself, XsoVec<dyn Trait>
requires that
MayContain
is implemented by dyn Trait
for all items which are added
to the container. This is automatically the case for all T: Trait
if derive_dyn_traits
has been used on
Trait
.
Note that XsoVec
has a non-obvious iteration order, which is described
in XsoVec::iter()
.
Implementations§
Source§impl<T: DynXso + ?Sized + 'static> XsoVec<T>
impl<T: DynXso + ?Sized + 'static> XsoVec<T>
Sourcepub const fn new() -> Self
pub const fn new() -> Self
Construct a new, empty XsoVec
.
let mut vec = XsoVec::<dyn Trait>::new();
Sourcepub fn get_first<U: 'static>(&self) -> Option<&U>where
T: MayContain<U>,
pub fn get_first<U: 'static>(&self) -> Option<&U>where
T: MayContain<U>,
Return a reference to the first item of type U
.
If the container does not hold any item of type U
, return None
.
#[derive(PartialEq, Debug)]
struct Foo(u8);
impl Trait for Foo {}
#[derive(PartialEq, Debug)]
struct Bar(u16);
impl Trait for Bar {}
#[derive(PartialEq, Debug)]
struct Baz(u32);
impl Trait for Baz {}
let mut vec = XsoVec::<dyn Trait>::new();
vec.push(Bar(1));
vec.push(Foo(2));
vec.push(Foo(1));
assert_eq!(vec.get_first::<Foo>(), Some(&Foo(2)));
assert_eq!(vec.get_first::<Bar>(), Some(&Bar(1)));
assert_eq!(vec.get_first::<Baz>(), None);
Sourcepub fn get_first_mut<U: 'static>(&mut self) -> Option<&mut U>where
T: MayContain<U>,
pub fn get_first_mut<U: 'static>(&mut self) -> Option<&mut U>where
T: MayContain<U>,
Return a mutable reference to the first item of type U
.
If the container does not hold any item of type U
, return None
.
#[derive(PartialEq, Debug)]
struct Foo(u8);
impl Trait for Foo {}
let mut vec = XsoVec::<dyn Trait>::new();
vec.push(Foo(1));
vec.get_first_mut::<Foo>().unwrap().0 = 2;
assert_eq!(vec.get_first::<Foo>(), Some(&Foo(2)));
Sourcepub fn take_one<U: 'static>(&mut self) -> Result<Option<Box<U>>, TakeOneError>where
T: MayContain<U>,
pub fn take_one<U: 'static>(&mut self) -> Result<Option<Box<U>>, TakeOneError>where
T: MayContain<U>,
Take and return exactly one item of type U
.
If no item of type U
is present in the container, return Ok(None).
If more than one item of type U
is present in the container,
return an error.
#[derive(PartialEq, Debug)]
struct Foo(u8);
impl Trait for Foo {}
#[derive(PartialEq, Debug)]
struct Bar(u16);
impl Trait for Bar {}
#[derive(PartialEq, Debug)]
struct Baz(u32);
impl Trait for Baz {}
let mut vec = XsoVec::<dyn Trait>::new();
vec.push(Bar(1));
vec.push(Foo(2));
vec.push(Foo(1));
assert_eq!(vec.take_one::<Foo>(), Err(TakeOneError::MultipleEntries));
assert_eq!(*vec.take_one::<Bar>().unwrap().unwrap(), Bar(1));
assert_eq!(vec.take_one::<Bar>(), Ok(None));
assert_eq!(vec.take_one::<Baz>(), Ok(None));
Sourcepub fn take_first<U: 'static>(&mut self) -> Option<Box<U>>where
T: MayContain<U>,
pub fn take_first<U: 'static>(&mut self) -> Option<Box<U>>where
T: MayContain<U>,
Take and return the first item of type U
.
If no item of type U
is present in the container, return None.
#[derive(PartialEq, Debug)]
struct Foo(u8);
impl Trait for Foo {}
#[derive(PartialEq, Debug)]
struct Bar(u16);
impl Trait for Bar {}
#[derive(PartialEq, Debug)]
struct Baz(u32);
impl Trait for Baz {}
let mut vec = XsoVec::<dyn Trait>::new();
vec.push(Bar(1));
vec.push(Foo(2));
vec.push(Foo(1));
assert_eq!(*vec.take_first::<Foo>().unwrap(), Foo(2));
assert_eq!(*vec.take_first::<Foo>().unwrap(), Foo(1));
assert_eq!(*vec.take_first::<Bar>().unwrap(), Bar(1));
assert_eq!(vec.take_first::<Bar>(), None);
assert_eq!(vec.take_first::<Baz>(), None);
Sourcepub fn take_last<U: 'static>(&mut self) -> Option<Box<U>>where
T: MayContain<U>,
pub fn take_last<U: 'static>(&mut self) -> Option<Box<U>>where
T: MayContain<U>,
Take and return the last item of type U
.
If no item of type U
is present in the container, return None.
#[derive(PartialEq, Debug)]
struct Foo(u8);
impl Trait for Foo {}
#[derive(PartialEq, Debug)]
struct Bar(u16);
impl Trait for Bar {}
#[derive(PartialEq, Debug)]
struct Baz(u32);
impl Trait for Baz {}
let mut vec = XsoVec::<dyn Trait>::new();
vec.push(Bar(1));
vec.push(Foo(2));
vec.push(Foo(1));
assert_eq!(*vec.take_last::<Foo>().unwrap(), Foo(1));
assert_eq!(*vec.take_last::<Foo>().unwrap(), Foo(2));
assert_eq!(*vec.take_last::<Bar>().unwrap(), Bar(1));
assert_eq!(vec.take_last::<Bar>(), None);
assert_eq!(vec.take_last::<Baz>(), None);
Sourcepub fn iter_typed<U: 'static>(&self) -> impl Iterator<Item = &U>where
T: MayContain<U>,
pub fn iter_typed<U: 'static>(&self) -> impl Iterator<Item = &U>where
T: MayContain<U>,
Iterate all items of type U
as references.
#[derive(PartialEq, Debug)]
struct Foo(u8);
impl Trait for Foo {}
#[derive(PartialEq, Debug)]
struct Bar(u16);
impl Trait for Bar {}
#[derive(PartialEq, Debug)]
struct Baz(u32);
impl Trait for Baz {}
let mut vec = XsoVec::<dyn Trait>::new();
vec.push(Bar(1));
vec.push(Foo(2));
vec.push(Foo(1));
let foos: Vec<_> = vec.iter_typed::<Foo>().collect();
assert_eq!(&foos[..], &[&Foo(2), &Foo(1)]);
Sourcepub fn iter_typed_mut<U: 'static>(&mut self) -> impl Iterator<Item = &mut U>where
T: MayContain<U>,
pub fn iter_typed_mut<U: 'static>(&mut self) -> impl Iterator<Item = &mut U>where
T: MayContain<U>,
Iterate all items of type U
as mutable references.
#[derive(PartialEq, Debug)]
struct Foo(u8);
impl Trait for Foo {}
#[derive(PartialEq, Debug)]
struct Bar(u16);
impl Trait for Bar {}
#[derive(PartialEq, Debug)]
struct Baz(u32);
impl Trait for Baz {}
let mut vec = XsoVec::<dyn Trait>::new();
vec.push(Bar(1));
vec.push(Foo(2));
vec.push(Foo(1));
let foos: Vec<_> = vec.iter_typed_mut::<Foo>().collect();
assert_eq!(&foos[..], &[&mut Foo(2), &mut Foo(1)]);
Sourcepub fn drain_typed<U: 'static>(&mut self) -> impl Iterator<Item = Box<U>>where
T: MayContain<U>,
pub fn drain_typed<U: 'static>(&mut self) -> impl Iterator<Item = Box<U>>where
T: MayContain<U>,
Drain all items of type U
out of the container.
If the result is dropped before the end of the iterator has been reached, the remaining items are still dropped out of the container.
#[derive(PartialEq, Debug)]
struct Foo(u8);
impl Trait for Foo {}
#[derive(PartialEq, Debug)]
struct Bar(u16);
impl Trait for Bar {}
#[derive(PartialEq, Debug)]
struct Baz(u32);
impl Trait for Baz {}
let mut vec = XsoVec::<dyn Trait>::new();
vec.push(Bar(1));
vec.push(Foo(2));
vec.push(Foo(1));
let foos: Vec<_> = vec.drain_typed::<Foo>().map(|x| *x).collect();
// converts Box<T> to T ↑
assert_eq!(&foos[..], &[Foo(2), Foo(1)]);
Sourcepub fn push<U: 'static>(&mut self, value: U)where
T: MayContain<U>,
pub fn push<U: 'static>(&mut self, value: U)where
T: MayContain<U>,
Push a new item of type U
to the end of the section of U
inside
the container.
Please note the information about iteration order of the XsoVec
at XsoVec::iter
.
#[derive(PartialEq, Debug)]
struct Foo(u8);
impl Trait for Foo {}
let mut vec = XsoVec::<dyn Trait>::new();
vec.push(Foo(1));
Sourcepub fn push_dyn(&mut self, value: Xso<T>)
pub fn push_dyn(&mut self, value: Xso<T>)
Push a new dynamically typed item to the end of the section of values with the same type inside the container.
Please note the information about iteration order of the XsoVec
at XsoVec::iter
.
#[derive(PartialEq, Debug)]
struct Foo(u8);
impl Trait for Foo {}
#[derive(PartialEq, Debug)]
struct Bar(u8);
impl Trait for Bar {}
let mut vec = XsoVec::<dyn Trait>::new();
vec.push(Foo(1));
vec.push_dyn(Xso::wrap(Foo(2)));
vec.push_dyn(Xso::wrap(Bar(1)));
vec.push(Bar(2));
let foos: Vec<_> = vec.iter_typed::<Foo>().collect();
assert_eq!(&foos[..], &[&Foo(1), &Foo(2)]);
let bars: Vec<_> = vec.iter_typed::<Bar>().collect();
assert_eq!(&bars[..], &[&Bar(1), &Bar(2)]);
Source§impl<T: ?Sized> XsoVec<T>
impl<T: ?Sized> XsoVec<T>
Sourcepub fn clear(&mut self)
pub fn clear(&mut self)
Clear all contents, without deallocating memory.
#[derive(PartialEq, Debug)]
struct Foo(u8);
impl Trait for Foo {}
let mut vec = XsoVec::<dyn Trait>::new();
vec.push(Foo(1));
vec.push(Foo(2));
vec.clear();
assert_eq!(vec.len(), 0);
Sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
Return true if there are no items in the container.
#[derive(PartialEq, Debug)]
struct Foo(u8);
impl Trait for Foo {}
let mut vec = XsoVec::<dyn Trait>::new();
assert!(vec.is_empty());
vec.push(Foo(1));
assert!(!vec.is_empty());
Sourcepub fn shrink_to_fit(&mut self)
pub fn shrink_to_fit(&mut self)
Reduce memory use of the container to the minimum required to hold the current data.
This may be expensive if lots of data needs to be shuffled.
Sourcepub fn len(&self) -> usize
pub fn len(&self) -> usize
Return the total amount of items in the container.
#[derive(PartialEq, Debug)]
struct Foo(u8);
impl Trait for Foo {}
let mut vec = XsoVec::<dyn Trait>::new();
assert_eq!(vec.len(), 0);
vec.push(Foo(1));
assert_eq!(vec.len(), 1);
Sourcepub fn iter(&self) -> XsoVecIter<'_, T> ⓘ
pub fn iter(&self) -> XsoVecIter<'_, T> ⓘ
Iterate the items inside the container.
This iterator (unlike the iterator returned by
iter_typed()
) yields references to untyped
Xso<dyn Trait>
.
§Iteration order
Items which have the same concrete type are grouped and their ordering with respect to one another is preserved. However, the ordering of items with different concrete types is unspecified.
§Example
#[derive(PartialEq, Debug)]
struct Foo(u8);
impl Trait for Foo {}
#[derive(PartialEq, Debug)]
struct Bar(u16);
impl Trait for Bar {}
let mut vec = XsoVec::<dyn Trait>::new();
vec.push(Foo(1));
vec.push(Bar(1));
vec.push(Foo(2));
for item in vec.iter() {
println!("{:?}", item);
}
Sourcepub fn iter_mut(&mut self) -> XsoVecIterMut<'_, T> ⓘ
pub fn iter_mut(&mut self) -> XsoVecIterMut<'_, T> ⓘ
Iterate the items inside the container, mutably.
This iterator (unlike the iterator returned by
iter_typed_mut()
) yields mutable
references to untyped Xso<dyn Trait>
.
Please note the information about iteration order of the XsoVec
at XsoVec::iter
.
Trait Implementations§
Source§impl<T: DynXso + ?Sized + 'static> Extend<Xso<T>> for XsoVec<T>
impl<T: DynXso + ?Sized + 'static> Extend<Xso<T>> for XsoVec<T>
Source§fn extend<I: IntoIterator<Item = Xso<T>>>(&mut self, iter: I)
fn extend<I: IntoIterator<Item = Xso<T>>>(&mut self, iter: I)
Source§fn extend_one(&mut self, item: A)
fn extend_one(&mut self, item: A)
extend_one
)Source§fn extend_reserve(&mut self, additional: usize)
fn extend_reserve(&mut self, additional: usize)
extend_one
)