Struct XsoVec

Source
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>

Source

pub const fn new() -> Self

Construct a new, empty XsoVec.

let mut vec = XsoVec::<dyn Trait>::new();
Source

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);
Source

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)));
Source

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));
Source

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);
Source

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);
Source

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)]);
Source

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)]);
Source

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)]);
Source

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));
Source

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>

Source

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);
Source

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());
Source

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.

Source

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);
Source

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);
}
Source

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: ?Sized> Debug for XsoVec<T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<T: ?Sized> Default for XsoVec<T>

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl<T: DynXso + ?Sized + 'static> Extend<Xso<T>> for XsoVec<T>

Source§

fn extend<I: IntoIterator<Item = Xso<T>>>(&mut self, iter: I)

Extends a collection with the contents of an iterator. Read more
Source§

fn extend_one(&mut self, item: A)

🔬This is a nightly-only experimental API. (extend_one)
Extends a collection with exactly one element.
Source§

fn extend_reserve(&mut self, additional: usize)

🔬This is a nightly-only experimental API. (extend_one)
Reserves capacity in a collection for the given number of additional elements. Read more
Source§

impl<'x, T: ?Sized> IntoIterator for &'x XsoVec<T>

Source§

type Item = &'x Xso<T>

The type of the elements being iterated over.
Source§

type IntoIter = XsoVecIter<'x, T>

Which kind of iterator are we turning this into?
Source§

fn into_iter(self) -> Self::IntoIter

Creates an iterator from a value. Read more
Source§

impl<'x, T: ?Sized> IntoIterator for &'x mut XsoVec<T>

Source§

type Item = &'x mut Xso<T>

The type of the elements being iterated over.
Source§

type IntoIter = XsoVecIterMut<'x, T>

Which kind of iterator are we turning this into?
Source§

fn into_iter(self) -> Self::IntoIter

Creates an iterator from a value. Read more
Source§

impl<T: ?Sized> IntoIterator for XsoVec<T>

Source§

type Item = Xso<T>

The type of the elements being iterated over.
Source§

type IntoIter = XsoVecIntoIter<T>

Which kind of iterator are we turning this into?
Source§

fn into_iter(self) -> Self::IntoIter

Creates an iterator from a value. Read more

Auto Trait Implementations§

§

impl<T> Freeze for XsoVec<T>
where T: ?Sized,

§

impl<T> RefUnwindSafe for XsoVec<T>
where T: RefUnwindSafe + ?Sized,

§

impl<T> Send for XsoVec<T>
where T: Send + ?Sized,

§

impl<T> Sync for XsoVec<T>
where T: Sync + ?Sized,

§

impl<T> Unpin for XsoVec<T>
where T: ?Sized,

§

impl<T> UnwindSafe for XsoVec<T>
where T: RefUnwindSafe + ?Sized,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> ErasedDestructor for T
where T: 'static,