Struct unsized_vec::UnsizedVec
source · [−]pub struct UnsizedVec<T: ?Sized> { /* private fields */ }Expand description
Like Vec, but can store unsized values.
Memory layout
When T is a Sized type, the memory layout is more or less the same as Vec<T>;
pointer to a heap allocation, as well as a usize each for length and capacity.
Elements are laid out in order, one after the other.
When T is a slice, there are two heap allocations.
The first is to the slices themsleves; they are laid out end-to-end, one after the other,
with no padding in between. The second heap allocation is to a list of offsets, to store
where each element begins and ends.
When T is neither of the above, there are still two allocations.
The first allocation still contains the elements of the vector laid out end-to-end,
but now every element is padded to at least the alignment of the most-aligned element
in the UnsizedVec. For this reason, adding a new element to the Vec with a larger alignment
than any of the elements already in it will add new padding to all the existing elements,
which will involve a lot of copying and probably a reallocation.
If you want to avoid excessive copies, use the UnsizedVec::with_byte_capacity_align
function to set the padding up front.
In the third case, the second allocation, in addition to storing offsets, also stores the pointer metadata of each element.
Example
#![feature(unsized_fn_params)]
use core::fmt::Debug;
use unsized_vec::{*, emplace::box_new_with};
// `Box::new()` necessary only to coerce the values to trait objects.
let obj: Box<dyn Debug> = Box::new(1);
let obj_2: Box<dyn Debug> = Box::new((97_u128, "oh noes"));
let mut vec: UnsizedVec<dyn Debug> = unsized_vec![*obj, *obj_2];
for traitobj in &vec {
dbg!(traitobj);
};
assert_eq!(vec.len(), 2);
let popped = box_new_with(|e| vec.pop_unwrap(e));
dbg!(&*popped);
assert_eq!(vec.len(), 1);Implementations
sourceimpl<T: ?Sized> UnsizedVec<T>
impl<T: ?Sized> UnsizedVec<T>
sourcepub fn with_byte_capacity_align(byte_capacity: usize, align: usize) -> Self
pub fn with_byte_capacity_align(byte_capacity: usize, align: usize) -> Self
sourcepub fn insert(&mut self, index: usize, elem: T)
pub fn insert(&mut self, index: usize, elem: T)
Insert element into vec at given index, shifting following elements to the right.
sourcepub fn pop_unwrap(&mut self, emplacer: &mut Emplacer<T>)
pub fn pop_unwrap(&mut self, emplacer: &mut Emplacer<T>)
Remove an element from the end of the vec.
This returns the element, which is unsized, through the “emplacer” mechanism.
Call box_new_with(|e| your_unsized_vec.pop_unwrap(e)) to get the element boxed.
Panics
Panics if len is 0.
sourcepub fn remove(&mut self, index: usize, emplacer: &mut Emplacer<T>)
pub fn remove(&mut self, index: usize, emplacer: &mut Emplacer<T>)
Remove the element at the given index, shifting those after it to the left.
This returns the element, which is unsized, through the “emplacer” mechanism.
Call box_new_with(|e| your_unsized_vec.remove(index, e)) to get the element boxed.
Doesn’t shink the allocation, and doesn’t reduce alignment.
Panics
Panics if index is out of bounds.
pub fn len(&self) -> usize
pub fn byte_capacity(&self) -> usize
pub fn align(&self) -> usize
pub fn is_empty(&self) -> bool
pub fn iter(&self) -> UnsizedVecIter<'_, T>ⓘNotable traits for UnsizedVecIter<'a, T>impl<'a, T: ?Sized> Iterator for UnsizedVecIter<'a, T> type Item = &'a T;
pub fn iter_mut(&mut self) -> UnsizedVecIterMut<'_, T>ⓘNotable traits for UnsizedVecIterMut<'a, T>impl<'a, T: ?Sized + 'a> Iterator for UnsizedVecIterMut<'a, T> type Item = &'a mut T;
Trait Implementations
sourceimpl<T: ?Sized + Clone> Clone for UnsizedVec<T>
impl<T: ?Sized + Clone> Clone for UnsizedVec<T>
sourceimpl<T: ?Sized + Debug> Debug for UnsizedVec<T>
impl<T: ?Sized + Debug> Debug for UnsizedVec<T>
sourceimpl<T: ?Sized> Default for UnsizedVec<T>
impl<T: ?Sized> Default for UnsizedVec<T>
sourceimpl<T: ?Sized> Drop for UnsizedVec<T>
impl<T: ?Sized> Drop for UnsizedVec<T>
sourceimpl<T: ?Sized + Hash> Hash for UnsizedVec<T>
impl<T: ?Sized + Hash> Hash for UnsizedVec<T>
sourceimpl<T: ?Sized> Index<usize> for UnsizedVec<T>
impl<T: ?Sized> Index<usize> for UnsizedVec<T>
sourceimpl<T: ?Sized> IndexMut<usize> for UnsizedVec<T>
impl<T: ?Sized> IndexMut<usize> for UnsizedVec<T>
sourceimpl<'a, T: ?Sized + 'a> IntoIterator for &'a UnsizedVec<T>
impl<'a, T: ?Sized + 'a> IntoIterator for &'a UnsizedVec<T>
sourceimpl<'a, T: ?Sized + 'a> IntoIterator for &'a mut UnsizedVec<T>
impl<'a, T: ?Sized + 'a> IntoIterator for &'a mut UnsizedVec<T>
sourceimpl<T: ?Sized + Ord> Ord for UnsizedVec<T>
impl<T: ?Sized + Ord> Ord for UnsizedVec<T>
1.21.0 · sourcefn max(self, other: Self) -> Self
fn max(self, other: Self) -> Self
1.21.0 · sourcefn min(self, other: Self) -> Self
fn min(self, other: Self) -> Self
1.50.0 · sourcefn clamp(self, min: Self, max: Self) -> Selfwhere
Self: PartialOrd<Self>,
fn clamp(self, min: Self, max: Self) -> Selfwhere
Self: PartialOrd<Self>,
sourceimpl<T: ?Sized + PartialEq<U>, U: ?Sized> PartialEq<UnsizedVec<U>> for UnsizedVec<T>
impl<T: ?Sized + PartialEq<U>, U: ?Sized> PartialEq<UnsizedVec<U>> for UnsizedVec<T>
sourcefn eq(&self, other: &UnsizedVec<U>) -> bool
fn eq(&self, other: &UnsizedVec<U>) -> bool
sourceimpl<T: ?Sized + PartialOrd<U>, U: ?Sized> PartialOrd<UnsizedVec<U>> for UnsizedVec<T>
impl<T: ?Sized + PartialOrd<U>, U: ?Sized> PartialOrd<UnsizedVec<U>> for UnsizedVec<T>
sourcefn partial_cmp(&self, other: &UnsizedVec<U>) -> Option<Ordering>
fn partial_cmp(&self, other: &UnsizedVec<U>) -> Option<Ordering>
1.0.0 · sourcefn le(&self, other: &Rhs) -> bool
fn le(&self, other: &Rhs) -> bool
self and other) and is used by the <=
operator. Read more