Enum zerovec::ZeroVec [−][src]
#[non_exhaustive] pub enum ZeroVec<'a, T: ?Sized> where
T: AsULE, { Owned(Vec<T::ULE>), Borrowed(&'a [T::ULE]), }
Expand description
A zero-copy vector for fixed-width types.
ZeroVec<T>
is designed as a drop-in replacement for Vec<T>
in situations where it is
desirable to borrow data from an unaligned byte slice, such as zero-copy deserialization.
T
must implement AsULE
, which is auto-implemented for a number of built-in types,
including all fixed-width multibyte integers.
How it Works
ZeroVec<T>
represents a slice of T
as a slice of T::ULE
. The difference between T
and
T::ULE
is that T::ULE
must be encoded in little-endian with 1-byte alignment. When accessing
items from ZeroVec<T>
, we fetch the T::ULE
, convert it on the fly to T
, and return T
by
value.
Benchmarks can be found in the project repository. We found that for common operations on small
and large vectors, ZeroVec<T>
performs from slightly faster to 15% slower than Vec<T>
.
However, the main performance improvement on ZeroVec<T>
is when deserializing from a byte
array; ZeroVec<T>
deserializes 80% faster than Vec<T>
in Serde Bincode, and it does not
require any heap allocations.
Safety
ZeroVec<T>
contains no unsafe code. However, the conversion from &[u8]
to &[T::ULE]
may
be unsafe. For more information, see the ule
module.
Example
use zerovec::ZeroVec; // The little-endian bytes correspond to the numbers on the following line. let bytes: &[u8] = &[0xD3, 0x00, 0x19, 0x01, 0xA5, 0x01, 0xCD, 0x01]; let nums: &[u16] = &[211, 281, 421, 461]; // Conversion from &[u8] to &[u16::ULE] is infallible. let zerovec: ZeroVec<u16> = ZeroVec::try_from_bytes(bytes).expect("infallible"); assert!(matches!(zerovec, ZeroVec::Borrowed(_))); assert_eq!(zerovec.get(2), Some(421)); assert_eq!(zerovec, nums);
Variants (Non-exhaustive)
This enum is marked as non-exhaustive
Implementations
impl<'a, T: ?Sized> ZeroVec<'a, T> where
T: AsULE,
[src]
impl<'a, T: ?Sized> ZeroVec<'a, T> where
T: AsULE,
[src]pub fn try_from_bytes(
bytes: &'a [u8]
) -> Result<Self, <<T as AsULE>::ULE as ULE>::Error>
[src]
pub fn try_from_bytes(
bytes: &'a [u8]
) -> Result<Self, <<T as AsULE>::ULE as ULE>::Error>
[src]Parses a &[u8]
buffer into a ZeroVec<T>
.
This function is infallible for built-in integer types, but fallible for other types,
such as char
. For more information, see ULE::parse_byte_slice
.
The bytes within the byte buffer must remain constant for the life of the ZeroVec.
Endianness
The byte buffer must be encoded in little-endian, even if running in a big-endian environment. This ensures a consistent representation of data across platforms.
Example
use zerovec::ZeroVec; let bytes: &[u8] = &[0xD3, 0x00, 0x19, 0x01, 0xA5, 0x01, 0xCD, 0x01]; let zerovec: ZeroVec<u16> = ZeroVec::try_from_bytes(bytes).expect("infallible"); assert!(matches!(zerovec, ZeroVec::Borrowed(_))); assert_eq!(zerovec.get(2), Some(421));
pub fn as_bytes(&self) -> &[u8]
[src]
pub fn as_bytes(&self) -> &[u8]
[src]Returns a ZeroVec<T>
as its underlying &[u8]
byte buffer representation.
Useful for serialization.
Example
use zerovec::ZeroVec; // The little-endian bytes correspond to the numbers on the following line. let bytes: &[u8] = &[0xD3, 0x00, 0x19, 0x01, 0xA5, 0x01, 0xCD, 0x01]; let nums: &[u16] = &[211, 281, 421, 461]; let zerovec = ZeroVec::from_aligned(nums); assert_eq!(bytes, zerovec.as_bytes());
pub fn as_slice(&self) -> &[T::ULE]
[src]
pub fn as_slice(&self) -> &[T::ULE]
[src]Dereferences this ZeroVec<T>
as &[T::ULE]
. Most other functions on ZeroVec<T>
use
this function as a building block.
pub fn len(&self) -> usize
[src]
pub fn len(&self) -> usize
[src]Returns the number of elements in this ZeroVec<T>
.
Example
use zerovec::ZeroVec; use zerovec::ule::AsULE; let bytes: &[u8] = &[0xD3, 0x00, 0x19, 0x01, 0xA5, 0x01, 0xCD, 0x01]; let zerovec: ZeroVec<u16> = ZeroVec::try_from_bytes(bytes).expect("infallible"); assert_eq!(4, zerovec.len()); assert_eq!( bytes.len(), zerovec.len() * std::mem::size_of::<<u16 as AsULE>::ULE>() );
pub fn is_empty(&self) -> bool
[src]
pub fn is_empty(&self) -> bool
[src]Returns whether the vec is empty.
Example
use zerovec::ZeroVec; let bytes: &[u8] = &[0xD3, 0x00, 0x19, 0x01, 0xA5, 0x01, 0xCD, 0x01]; let zerovec: ZeroVec<u16> = ZeroVec::try_from_bytes(bytes).expect("infallible"); assert!(!zerovec.is_empty()); let emptyvec: ZeroVec<u16> = ZeroVec::try_from_bytes(&[]).expect("infallible"); assert!(emptyvec.is_empty());
impl<T> ZeroVec<'_, T> where
T: AsULE,
[src]
impl<T> ZeroVec<'_, T> where
T: AsULE,
[src]pub fn from_aligned(other: &[T]) -> Self
[src]
pub fn from_aligned(other: &[T]) -> Self
[src]Creates a ZeroVec<T>
from a &[T]
.
This function allocates memory and results in an Owned
instance of ZeroVec<T>
.
Example
use zerovec::ZeroVec; // The little-endian bytes correspond to the numbers on the following line. let bytes: &[u8] = &[0xD3, 0x00, 0x19, 0x01, 0xA5, 0x01, 0xCD, 0x01]; let nums: &[u16] = &[211, 281, 421, 461]; let zerovec = ZeroVec::from_aligned(nums); assert!(matches!(zerovec, ZeroVec::Owned(_))); assert_eq!(bytes, zerovec.as_bytes());
impl<T: ?Sized> ZeroVec<'_, T> where
T: AsULE + Copy,
[src]
impl<T: ?Sized> ZeroVec<'_, T> where
T: AsULE + Copy,
[src]pub fn get(&self, index: usize) -> Option<T>
[src]
pub fn get(&self, index: usize) -> Option<T>
[src]Gets the element at the specified index. Returns None if out of range.
The element is returned by value, so T
must implement Copy
.
Example
use zerovec::ZeroVec; let bytes: &[u8] = &[0xD3, 0x00, 0x19, 0x01, 0xA5, 0x01, 0xCD, 0x01]; let zerovec: ZeroVec<u16> = ZeroVec::try_from_bytes(bytes).expect("infallible"); assert_eq!(zerovec.get(2), Some(421)); assert_eq!(zerovec.get(4), None);
pub fn first(&self) -> Option<T>
[src]
pub fn first(&self) -> Option<T>
[src]Gets the first element. Returns None if empty.
The element is returned by value, so T
must implement Copy
.
Example
use zerovec::ZeroVec; let bytes: &[u8] = &[0xD3, 0x00, 0x19, 0x01, 0xA5, 0x01, 0xCD, 0x01]; let zerovec: ZeroVec<u16> = ZeroVec::try_from_bytes(bytes).expect("infallible"); assert_eq!(zerovec.first(), Some(211));
pub fn last(&self) -> Option<T>
[src]
pub fn last(&self) -> Option<T>
[src]Gets the last element. Returns None if empty.
The element is returned by value, so T
must implement Copy
.
Example
use zerovec::ZeroVec; let bytes: &[u8] = &[0xD3, 0x00, 0x19, 0x01, 0xA5, 0x01, 0xCD, 0x01]; let zerovec: ZeroVec<u16> = ZeroVec::try_from_bytes(bytes).expect("infallible"); assert_eq!(zerovec.last(), Some(461));
pub fn iter(&self) -> impl Iterator<Item = T> + '_
[src]
pub fn iter(&self) -> impl Iterator<Item = T> + '_
[src]Gets an iterator over the elements.
The elements are returned by value, so T
must implement Copy
.
Example
use zerovec::ZeroVec; let bytes: &[u8] = &[0xD3, 0x00, 0x19, 0x01, 0xA5, 0x01, 0xCD, 0x01]; let zerovec: ZeroVec<u16> = ZeroVec::try_from_bytes(bytes).expect("infallible"); let mut it = zerovec.iter(); assert_eq!(it.next(), Some(211)); assert_eq!(it.next(), Some(281)); assert_eq!(it.next(), Some(421)); assert_eq!(it.next(), Some(461)); assert_eq!(it.next(), None);
pub fn into_owned(self) -> ZeroVec<'static, T>
[src]
pub fn into_owned(self) -> ZeroVec<'static, T>
[src]Converts a borrowed ZeroVec to an owned ZeroVec. No-op if already owned.
Example
use zerovec::ZeroVec; let bytes: &[u8] = &[0xD3, 0x00, 0x19, 0x01, 0xA5, 0x01, 0xCD, 0x01]; let zerovec: ZeroVec<u16> = ZeroVec::try_from_bytes(bytes).expect("infallible"); assert!(matches!(zerovec, ZeroVec::Borrowed(_))); let owned = zerovec.into_owned(); assert!(matches!(owned, ZeroVec::Owned(_)));
impl<T> ZeroVec<'_, T> where
T: AsULE + Ord,
[src]
impl<T> ZeroVec<'_, T> where
T: AsULE + Ord,
[src]pub fn binary_search(&self, x: &T) -> Result<usize, usize>
[src]
pub fn binary_search(&self, x: &T) -> Result<usize, usize>
[src]Binary searches a sorted ZeroVec<T>
for the given element. For more information, see
the primitive function binary_search
.
Example
use zerovec::ZeroVec; let bytes: &[u8] = &[0xD3, 0x00, 0x19, 0x01, 0xA5, 0x01, 0xCD, 0x01]; let zerovec: ZeroVec<u16> = ZeroVec::try_from_bytes(bytes).expect("infallible"); assert_eq!(zerovec.binary_search(&281), Ok(1)); assert_eq!(zerovec.binary_search(&282), Err(2));
Trait Implementations
impl<'a, T: Clone + ?Sized> Clone for ZeroVec<'a, T> where
T: AsULE,
T::ULE: Clone,
T::ULE: Clone,
[src]
impl<'a, T: Clone + ?Sized> Clone for ZeroVec<'a, T> where
T: AsULE,
T::ULE: Clone,
T::ULE: Clone,
[src]impl<'a, 'b, T> PartialEq<ZeroVec<'b, T>> for ZeroVec<'a, T> where
T: AsULE + Copy + PartialEq,
[src]
impl<'a, 'b, T> PartialEq<ZeroVec<'b, T>> for ZeroVec<'a, T> where
T: AsULE + Copy + PartialEq,
[src]impl<'a, T> ZeroVecLike<'a, T> for ZeroVec<'a, T> where
T: AsULE + Ord + Copy,
[src]
impl<'a, T> ZeroVecLike<'a, T> for ZeroVec<'a, T> where
T: AsULE + Ord + Copy,
[src]type NeedleType = T
type NeedleType = T
The type received by Self::binary_search()
fn binary_search(&self, k: &T) -> Result<usize, usize>
[src]
fn binary_search(&self, k: &T) -> Result<usize, usize>
[src]Search for a key in a sorted vector, returns Ok(index)
if found,
returns Err(insert_index)
if not found, where insert_index
is the
index where it should be inserted to maintain sort order. Read more
fn replace(&mut self, index: usize, value: T) -> T
[src]
fn replace(&mut self, index: usize, value: T) -> T
[src]Replace the element at index
with another one, returning the old element
fn with_capacity(cap: usize) -> Self
[src]
fn with_capacity(cap: usize) -> Self
[src]Create a new, empty vector, with given capacity
fn is_ascending(&self) -> bool
[src]
fn is_ascending(&self) -> bool
[src]Check if this vector is in ascending order according to T
s Ord
impl
Auto Trait Implementations
impl<'a, T: ?Sized> RefUnwindSafe for ZeroVec<'a, T> where
<T as AsULE>::ULE: RefUnwindSafe,
<T as AsULE>::ULE: RefUnwindSafe,
impl<'a, T: ?Sized> Send for ZeroVec<'a, T> where
<T as AsULE>::ULE: Send + Sync,
<T as AsULE>::ULE: Send + Sync,
impl<'a, T: ?Sized> Sync for ZeroVec<'a, T> where
<T as AsULE>::ULE: Sync,
<T as AsULE>::ULE: Sync,
impl<'a, T: ?Sized> Unpin for ZeroVec<'a, T> where
<T as AsULE>::ULE: Unpin,
<T as AsULE>::ULE: Unpin,
impl<'a, T: ?Sized> UnwindSafe for ZeroVec<'a, T> where
<T as AsULE>::ULE: RefUnwindSafe + UnwindSafe,
<T as AsULE>::ULE: RefUnwindSafe + UnwindSafe,
Blanket Implementations
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]pub fn borrow_mut(&mut self) -> &mut T
[src]
pub fn borrow_mut(&mut self) -> &mut T
[src]Mutably borrows from an owned value. Read more
impl<T> ToOwned for T where
T: Clone,
[src]
impl<T> ToOwned for T where
T: Clone,
[src]type Owned = T
type Owned = T
The resulting type after obtaining ownership.
pub fn to_owned(&self) -> T
[src]
pub fn to_owned(&self) -> T
[src]Creates owned data from borrowed data, usually by cloning. Read more
pub fn clone_into(&self, target: &mut T)
[src]
pub fn clone_into(&self, target: &mut T)
[src]🔬 This is a nightly-only experimental API. (toowned_clone_into
)
recently added
Uses borrowed data to replace owned data, usually by cloning. Read more