HarrenVec

Struct HarrenVec 

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

Implementations§

Source§

impl HarrenVec

Source

pub fn new() -> Self

Constructs a new empty HarrenVec.

§Examples
let mut list = HarrenVec::new();
Source

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

pub fn reserve(&mut self, items: usize, bytes: usize)

Reserve capacity for at least items more items and bytes more bytes.

Source

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.)

Source

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.

Source

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.

Source

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

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.)

Source

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.)

Source

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

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

pub fn len(&self) -> usize

Returns the number of items in the HarrenVec.

Source

pub fn bytes_len(&self) -> usize

Returns the total number of bytes occupied by the contents of the HarrenVec.

Source

pub fn is_empty(&self) -> bool

Returns true if there are no contents.

Source

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

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.

Source

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.

Source

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

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

pub unsafe fn pop_unchecked<T: 'static>(&mut self) -> Option<T>

See Self::pop. 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.

Source

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

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

pub unsafe fn get_unchecked<T: 'static>(&self, index: usize) -> Option<&T>

See Self::get. 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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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

Trait Implementations§

Source§

impl Clone for HarrenVec

Source§

fn clone(&self) -> HarrenVec

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for HarrenVec

Source§

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

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

impl Default for HarrenVec

Source§

fn default() -> Self

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

impl Drop for HarrenVec

Available on non-crate feature no_drop only.
Source§

fn drop(&mut self)

Executes the destructor for this type. Read more

Auto Trait Implementations§

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> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. 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> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
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.