pub struct HarrenVec { /* private fields */ }Expand description
A Vec-like data structure that can store items
of different types and sizes from each other.
Values of any type can be stored, and they are
stored contiguous in memory like a normal Vec would.
The intended use case for this data structure is
efficiently packing structs with large optional fields,
while avoiding Box-ing those values.
It supports values with a Drop implementation by default.
However, if you include the no_drop feature, then
dropping the HarrenVec will not call the destructors of
the contents. Instead you should use the
HarrenVec::into_iter method to ensure you are consuming
and dropping values correctly. If the values do not have
destructors, this is not necessary.
§Examples
use hvec::HarrenVec;
struct SmallMessage {
id: usize,
has_extra: bool,
}
struct LargeExtraField {
data: [[f64; 4]; 4],
}
let mut messages = HarrenVec::new();
messages.push(SmallMessage { id: 0, has_extra: false });
messages.push(SmallMessage { id: 1, has_extra: true });
messages.push(LargeExtraField { data: [[0.; 4]; 4] });
messages.push(SmallMessage { id: 2, has_extra: false });
let mut iter = messages.into_iter();
while let Some(message) = iter.next::<SmallMessage>() {
println!("id = {}", message.id);
if message.has_extra {
let extra = iter.next::<LargeExtraField>().unwrap();
println!("extra data = {:?}", extra.data);
}
}
// Output:
// id = 0
// id = 1
// extra data = [[0., 0., 0., 0.], [0., 0., 0., 0.], [0., 0., 0., 0.], [0., 0., 0., 0.]]
// id = 2Implementations§
Source§impl HarrenVec
impl HarrenVec
Sourcepub fn with_capacity(items: usize, bytes: usize) -> Self
pub fn with_capacity(items: usize, bytes: usize) -> Self
Constructs a new empty HarrenVec with at least the
specified capacity in items and bytes.
The HarrenVec stores the types of the data separately
from the data. In practice, it will re-allocate if
either of these capacities are exceeded.
§Examples
let mut list = HarrenVec::with_capacity(4, 64);
assert!(list.item_capacity() >= 4);
assert!(list.byte_capacity() >= 64);Sourcepub fn reserve(&mut self, items: usize, bytes: usize)
pub fn reserve(&mut self, items: usize, bytes: usize)
Reserve capacity for at least items more items and
bytes more bytes.
Sourcepub fn reserve_exact(&mut self, items: usize, bytes: usize)
pub fn reserve_exact(&mut self, items: usize, bytes: usize)
Reserve capacity for at least items more items and
bytes more bytes. (Attempts to reserve the minimum
possible, but this is not guaranteed.)
Sourcepub fn try_reserve(
&mut self,
items: usize,
bytes: usize,
) -> Result<(), TryReserveError>
pub fn try_reserve( &mut self, items: usize, bytes: usize, ) -> Result<(), TryReserveError>
Reserve capacity for at least items more items and
bytes more bytes.
§Errors
Returns an error if allocation fails.
Sourcepub fn try_reserve_exact(
&mut self,
items: usize,
bytes: usize,
) -> Result<(), TryReserveError>
pub fn try_reserve_exact( &mut self, items: usize, bytes: usize, ) -> Result<(), TryReserveError>
Reserve capacity for at least items more items and
bytes more bytes. (Attempts to reserve the minimum
possible, but this is not guaranteed.)
§Errors
Returns an error if allocation fails.
Sourcepub fn append(&mut self, other: &mut HarrenVec)
pub fn append(&mut self, other: &mut HarrenVec)
Move all elements from another HarrenVec into
this one, leaving the other empty.
§Examples
let mut a = hvec![1, 2, 3];
let mut b = hvec![4, 5, 6];
a.append(&mut b);
assert_eq!(a.len(), 6);
assert_eq!(b.len(), 0);Sourcepub fn clear(&mut self)
pub fn clear(&mut self)
Clears the contents of the HarrenVec.
(Note that if the no_drop feature is enabled, then
this method will not call the destructors of any of its contents.
If the contents do not have a Drop implementation, this is not a
concern.)
Sourcepub fn truncate(&mut self, items: usize)
pub fn truncate(&mut self, items: usize)
Truncates the contents of the HarrenVec to a set
number of items, clearing the rest.
(Note that if the no_drop feature is enabled, then
this method will not call the destructors of any of its contents.
If the contents do not have a Drop implementation, this is not a
concern.)
Sourcepub fn peek_type(&self) -> Option<TypeId>
pub fn peek_type(&self) -> Option<TypeId>
Returns the type of the last item in the HarrenVec.
§Examples
use std::any::TypeId;
let list = hvec![1_u8, 2_i32, 3_u64];
assert_eq!(list.peek_type(), Some(TypeId::of::<u64>()));Sourcepub fn peek_ptr(&self) -> Option<(TypeId, *const u8)>
pub fn peek_ptr(&self) -> Option<(TypeId, *const u8)>
Returns the type of the last item in the HarrenVec,
as well as a pointer to the first byte of it.
§Safety
The pointer returned points to memory owned by the
HarrenVec, and so it is only valid as long as it that
data is unchanged.
§Examples
use std::any::TypeId;
let list = hvec![1_u8, 2_i32, 3_u64];
let (type_id, ptr) = list.peek_ptr().unwrap();
assert_eq!(type_id, TypeId::of::<u64>());
unsafe {
let ptr = ptr as *const u64;
assert_eq!(*ptr, 3_u64);
}Sourcepub fn bytes_len(&self) -> usize
pub fn bytes_len(&self) -> usize
Returns the total number of bytes occupied by the
contents of the HarrenVec.
Sourcepub fn into_iter(self) -> HarrenIter
pub fn into_iter(self) -> HarrenIter
Returns an Iterator-like structure for stepping through
the contents of the HarrenVec.
Note that because the type of each item can be
different, and may not be known, this “iterator” cannot
be used in for loops.
§Examples
The recommended way to use this method depends on how
much you know about the contents. If there is a main
type and you know in advance when that type will
deviate, you can use a while-let loop:
let list = hvec![1_usize, 2_usize, 999_usize, "Wow, big number!".to_string(), 3_usize];
let mut iter = list.into_iter();
let mut total = 0;
while let Some(number) = iter.next::<usize>() {
if number > 100 {
let comment = iter.next::<String>().unwrap();
assert_eq!(comment, "Wow, big number!");
}
total += number;
}
assert_eq!(total, 1005);If you don’t have a structure that allows you to know what type the next element is in advance, you can check the type of each item as you read it:
use std::any::TypeId;
let list = hvec![1_u8, 500_u16, 99999_u32];
let mut iter = list.into_iter();
let mut total: usize = 0;
while let Some(type_id) = iter.peek_type() {
if type_id == TypeId::of::<u8>() {
total += iter.next::<u8>().unwrap() as usize;
} else if type_id == TypeId::of::<u16>() {
total += iter.next::<u16>().unwrap() as usize;
} else if type_id == TypeId::of::<u32>() {
total += iter.next::<u32>().unwrap() as usize;
}
}
assert_eq!(total, 100500);Sourcepub fn iter(&self) -> HarrenRefIter<'_>
pub fn iter(&self) -> HarrenRefIter<'_>
Returns an Iterator-like structure for stepping through immutable references to
the contents of the HarrenVec.
See HarrenVec::into_iter for examples.
Sourcepub fn iter_mut(&mut self) -> HarrenMutIter<'_>
pub fn iter_mut(&mut self) -> HarrenMutIter<'_>
Returns an Iterator-like structure for stepping through mutable references to
the contents of the HarrenVec.
See HarrenVec::into_iter for examples.
Sourcepub fn push<T: 'static>(&mut self, t: T)
pub fn push<T: 'static>(&mut self, t: T)
Add an element of any type to the HarrenVec.
§Examples
let mut list = HarrenVec::new();
list.push(1_u8);
list.push("Hello, world!".to_string());
assert_eq!(list.len(), 2);Sourcepub fn pop<T: 'static>(&mut self) -> Option<T>
pub fn pop<T: 'static>(&mut self) -> Option<T>
Pop the last element from the HarrenVec.
§Panics
(This method can only panic if the type_assertions feature flag is enabled.)
This method panics if the actual element is not an
element of the specified type T.
§Examples
let mut list = hvec!["Hello".to_string()];
assert_eq!(list.pop::<String>().unwrap(), "Hello".to_string());Sourcepub unsafe fn pop_unchecked<T: 'static>(&mut self) -> Option<T>
pub unsafe fn pop_unchecked<T: 'static>(&mut self) -> Option<T>
Sourcepub fn contains<T: PartialEq<T> + 'static>(&self, x: &T) -> bool
pub fn contains<T: PartialEq<T> + 'static>(&self, x: &T) -> bool
Returns true if this HarrenVec contains the element.
§Examples
let list = hvec![1_usize, "Hello".to_string()];
assert!(list.contains::<usize>(&1));
assert!(list.contains::<String>(&"Hello".to_string()));
assert!(!list.contains::<isize>(&1));
assert!(!list.contains::<String>(&"???".to_string()));Sourcepub fn first<T: 'static>(&self) -> Option<&T>
pub fn first<T: 'static>(&self) -> Option<&T>
Return a reference to the first item of the HarrenVec.
§Panics
(This method can only panic if the type_assertions feature flag is enabled.)
This method panics if the item is not of the specified
type T.
Sourcepub unsafe fn first_unchecked<T: 'static>(&self) -> Option<&T>
pub unsafe fn first_unchecked<T: 'static>(&self) -> Option<&T>
See Self::first. Does not panic if the type doesn’t match.
§Safety
This method is only safe if the bytes can be safely interpreted as a struct of type T.
Sourcepub fn first_mut<T: 'static>(&mut self) -> Option<&mut T>
pub fn first_mut<T: 'static>(&mut self) -> Option<&mut T>
Return a mutable reference to the first item of
the HarrenVec.
§Panics
(This method can only panic if the type_assertions feature flag is enabled.)
This method panics if the item is not of the specified
type T.
Sourcepub unsafe fn first_mut_unchecked<T: 'static>(&mut self) -> Option<&mut T>
pub unsafe fn first_mut_unchecked<T: 'static>(&mut self) -> Option<&mut T>
See Self::first_mut. Does not panic if the type doesn’t match.
§Safety
This method is only safe if the bytes can be safely interpreted as a struct of type T.
Sourcepub fn last<T: 'static>(&self) -> Option<&T>
pub fn last<T: 'static>(&self) -> Option<&T>
Return a reference to the last item of the HarrenVec.
§Panics
(This method can only panic if the type_assertions feature flag is enabled.)
This method panics if the item is not of the specified
type T.
Sourcepub unsafe fn last_unchecked<T: 'static>(&self) -> Option<&T>
pub unsafe fn last_unchecked<T: 'static>(&self) -> Option<&T>
See Self::last. Does not panic if the type doesn’t match.
§Safety
This method is only safe if the bytes can be safely interpreted as a struct of type T.
Sourcepub fn last_mut<T: 'static>(&mut self) -> Option<&mut T>
pub fn last_mut<T: 'static>(&mut self) -> Option<&mut T>
Return a mutable reference to the last item of
the HarrenVec.
§Panics
(This method can only panic if the type_assertions feature flag is enabled.)
This method panics if the item is not of the specified
type T.
Sourcepub unsafe fn last_mut_unchecked<T: 'static>(&mut self) -> Option<&mut T>
pub unsafe fn last_mut_unchecked<T: 'static>(&mut self) -> Option<&mut T>
See Self::last_mut. Does not panic if the type doesn’t match.
§Safety
This method is only safe if the bytes can be safely interpreted as a struct of type T.
Sourcepub fn peek<T: 'static>(&self) -> Option<&T>
pub fn peek<T: 'static>(&self) -> Option<&T>
Alias of the Self::last method.
§Safety
This method is only safe if the bytes can be safely interpreted as a struct of type T.
Sourcepub unsafe fn peek_unchecked<T: 'static>(&self) -> Option<&T>
pub unsafe fn peek_unchecked<T: 'static>(&self) -> Option<&T>
Alias of the Self::last_unchecked method.
§Safety
This method is only safe if the bytes can be safely interpreted as a struct of type T.
Sourcepub fn peek_mut<T: 'static>(&mut self) -> Option<&mut T>
pub fn peek_mut<T: 'static>(&mut self) -> Option<&mut T>
Alias of the Self::last_mut method.
§Safety
This method is only safe if the bytes can be safely interpreted as a struct of type T.
Sourcepub unsafe fn peek_mut_unchecked<T: 'static>(&mut self) -> Option<&mut T>
pub unsafe fn peek_mut_unchecked<T: 'static>(&mut self) -> Option<&mut T>
Alias of the Self::last_mut_unchecked method.
§Safety
This method is only safe if the bytes can be safely interpreted as a struct of type T.
Sourcepub fn get<T: 'static>(&self, index: usize) -> Option<&T>
pub fn get<T: 'static>(&self, index: usize) -> Option<&T>
Return a reference to the item of the HarrenVec at
the given index.
§Panics
(This method can only panic if the type_assertions feature flag is enabled.)
This method panics if the item is not of the specified
type T.
Sourcepub unsafe fn get_unchecked<T: 'static>(&self, index: usize) -> Option<&T>
pub unsafe fn get_unchecked<T: 'static>(&self, index: usize) -> Option<&T>
Sourcepub fn get_mut<T: 'static>(&mut self, index: usize) -> Option<&mut T>
pub fn get_mut<T: 'static>(&mut self, index: usize) -> Option<&mut T>
Return a mutable reference to the item of
the HarrenVec at the given index.
§Panics
(This method can only panic if the type_assertions feature flag is enabled.)
This method panics if the item is not of the specified
type T.
Sourcepub unsafe fn get_mut_unchecked<T: 'static>(
&mut self,
index: usize,
) -> Option<&mut T>
pub unsafe fn get_mut_unchecked<T: 'static>( &mut self, index: usize, ) -> Option<&mut T>
See Self::get_mut. Does not panic if the type doesn’t match.
§Safety
This method is only safe if the bytes can be safely interpreted as a struct of type T.
Sourcepub fn item_capacity(&self) -> usize
pub fn item_capacity(&self) -> usize
Returns the total number of elements this HarrenVec
can store without reallocating.
Note that this is separate from its capacity in bytes. Allocation will occur if either capacity is exceeded.
Sourcepub fn byte_capacity(&self) -> usize
pub fn byte_capacity(&self) -> usize
Returns the total number of bytes this HarrenVec
can store without reallocating.
Note that this is separate from its capacity in items. Allocation will occur if either capacity is exceeded.
Sourcepub fn bytes_eq(&self, other: &HarrenVec) -> bool
pub fn bytes_eq(&self, other: &HarrenVec) -> bool
Returns true if other contains the exact same types
and bytes as this HarrenVec. Not that this does not
call the actual PartialEq implementation for the
stored values, so the result may not be intuitive for
more complex or heap-allocated types.
§Examples
let list_a = hvec![1_u8, 2_isize];
let list_b = hvec![1_u8, 2_isize];
let list_c = hvec![1_u8, "Hello".to_string()];
let list_d = hvec![1_u8, "Hello".to_string()];
// Numbers can be correctly compared as bytes
assert!(list_a.bytes_eq(&list_b));
// Strings contain pointers so identical strings may differ in bytes
assert!(!list_c.bytes_eq(&list_d));