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. For variable-width types like str
,
see VarZeroVec
. zerovec::make_ule
may
be used to automatically implement AsULE
for a type and generate the underlying ULE
type.
Typically, the zero-copy equivalent of a Vec<T>
will simply be ZeroVec<'a, T>
.
Most of the methods on ZeroVec<'a, T>
come from its Deref
implementation to ZeroSlice<T>
.
For creating zero-copy vectors of fixed-size types, see VarZeroVec
.
ZeroVec<T>
behaves much like Cow
, where it can be constructed from
owned data (and then mutated!) but can also borrow from some buffer.
Example
use zerovec::ZeroVec;
// The little-endian bytes correspond to the numbers on the following line.
let nums: &[u16] = &[211, 281, 421, 461];
#[derive(serde::Serialize, serde::Deserialize)]
struct Data<'a> {
#[serde(borrow)]
nums: ZeroVec<'a, u16>,
}
// The owned version will allocate
let data = Data {
nums: ZeroVec::alloc_from_slice(nums),
};
let bincode_bytes = bincode::serialize(&data).expect("Serialization should be successful");
// Will deserialize without allocations
let deserialized: Data =
bincode::deserialize(&bincode_bytes).expect("Deserialization should be successful");
// This deserializes without allocation!
assert!(matches!(deserialized.nums, ZeroVec::Borrowed(_)));
assert_eq!(deserialized.nums.get(2), Some(421));
assert_eq!(deserialized.nums, nums);
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, with some results found in the crate-level documentation.
See the design doc for more details.
Variants
Owned(Vec<T::ULE>)
An owned ZeroVec<T>
. This will typically be constructed by ZeroVec::alloc_from_slice()
or by calling ZeroVec::to_mut()
/ZeroVec::for_each_mut()
/etc on ZeroVec::Borrowed
.
Borrowed(&'a [T::ULE])
A borrowed ZeroVec<T>
. This will typically be constructed by ZeroVec::parse_byte_slice()
,
ZeroVec::from_slice_or_alloc()
, or deserializers capable of doing zero-copy deserialization.
If you already have a slice of [T::ULE]
s, you can directly construct one of these.
Example
use zerovec::ule::*;
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: &[RawBytesULE<2>] = &[
211_u16.to_unaligned(),
281_u16.to_unaligned(),
421_u16.to_unaligned(),
461_u16.to_unaligned(),
];
let zerovec = ZeroVec::<u16>::Borrowed(nums);
assert!(matches!(zerovec, ZeroVec::Borrowed(_)));
assert_eq!(bytes, zerovec.as_bytes());
Implementations
sourceimpl<'a, T> ZeroVec<'a, T> where
T: AsULE + ?Sized,
impl<'a, T> ZeroVec<'a, T> where
T: AsULE + ?Sized,
sourcepub const fn new() -> Self
pub const fn new() -> Self
Creates a new, borrowed, empty ZeroVec<T>
.
Examples
use zerovec::ZeroVec;
let zv: ZeroVec<u16> = ZeroVec::new();
assert!(zv.is_empty());
sourcepub fn with_capacity(capacity: usize) -> Self
pub fn with_capacity(capacity: usize) -> Self
Creates a new, owned, empty ZeroVec<T>
, with a certain capacity pre-allocated.
sourcepub fn parse_byte_slice(bytes: &'a [u8]) -> Result<Self, ZeroVecError>
pub fn parse_byte_slice(bytes: &'a [u8]) -> Result<Self, ZeroVecError>
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::parse_byte_slice(bytes).expect("infallible");
assert!(matches!(zerovec, ZeroVec::Borrowed(_)));
assert_eq!(zerovec.get(2), Some(421));
sourcepub const unsafe fn from_bytes_unchecked(bytes: &'a [u8]) -> Self
pub const unsafe fn from_bytes_unchecked(bytes: &'a [u8]) -> Self
Uses a &[u8]
buffer as a ZeroVec<T>
without any verification.
Safety
bytes
need to be an output from ZeroSlice::as_bytes()
.
sourcepub fn into_bytes(self) -> ZeroVec<'a, u8>
pub fn into_bytes(self) -> ZeroVec<'a, u8>
Converts a ZeroVec<T>
into a ZeroVec<u8>
, retaining the current ownership model.
Note that the length of the ZeroVec may change.
Examples
Convert a borrowed ZeroVec
:
use zerovec::ZeroVec;
let bytes: &[u8] = &[0xD3, 0x00, 0x19, 0x01, 0xA5, 0x01, 0xCD, 0x01];
let zerovec: ZeroVec<u16> = ZeroVec::parse_byte_slice(bytes).expect("infallible");
let zv_bytes = zerovec.into_bytes();
assert!(matches!(zv_bytes, ZeroVec::Borrowed(_)));
assert_eq!(zv_bytes.get(0), Some(0xD3));
Convert an owned ZeroVec
:
use zerovec::ZeroVec;
let nums: &[u16] = &[211, 281, 421, 461];
let zerovec = ZeroVec::alloc_from_slice(nums);
let zv_bytes = zerovec.into_bytes();
assert!(matches!(zv_bytes, ZeroVec::Owned(_)));
assert_eq!(zv_bytes.get(0), Some(0xD3));
sourcepub fn cast<P>(self) -> ZeroVec<'a, P> where
P: AsULE<ULE = T::ULE>,
pub fn cast<P>(self) -> ZeroVec<'a, P> where
P: AsULE<ULE = T::ULE>,
Casts a ZeroVec<T>
to a compatible ZeroVec<P>
.
T
and P
are compatible if they have the same ULE
representation.
If the ULE
s of T
and P
are different types but have the same size,
use Self::try_into_converted()
.
Examples
use zerovec::ZeroVec;
let bytes: &[u8] = &[0xD3, 0x00, 0x19, 0x01, 0xA5, 0x01, 0xCD, 0x80];
let zerovec_u16: ZeroVec<u16> = ZeroVec::parse_byte_slice(bytes).expect("infallible");
assert_eq!(zerovec_u16.get(3), Some(32973));
let zerovec_i16: ZeroVec<i16> = zerovec_u16.cast();
assert_eq!(zerovec_i16.get(3), Some(-32563));
sourcepub fn try_into_converted<P: AsULE>(
self
) -> Result<ZeroVec<'a, P>, ZeroVecError>
pub fn try_into_converted<P: AsULE>(
self
) -> Result<ZeroVec<'a, P>, ZeroVecError>
Converts a ZeroVec<T>
into a ZeroVec<P>
, retaining the current ownership model.
If T
and P
have the exact same ULE
, use Self::cast()
.
Panics
Panics if T::ULE
and P::ULE
are not the same size.
Examples
Convert a borrowed ZeroVec
:
use zerovec::ZeroVec;
let bytes: &[u8] = &[0x7F, 0xF3, 0x01, 0x49, 0xF6, 0x01];
let zv_char: ZeroVec<char> = ZeroVec::parse_byte_slice(bytes).expect("valid code points");
let zv_u8_3: ZeroVec<[u8; 3]> = zv_char.try_into_converted().expect("infallible conversion");
assert!(matches!(zv_u8_3, ZeroVec::Borrowed(_)));
assert_eq!(zv_u8_3.get(0), Some([0x7F, 0xF3, 0x01]));
Convert an owned ZeroVec
:
use zerovec::ZeroVec;
let chars: &[char] = &['🍿', '🙉'];
let zv_char = ZeroVec::alloc_from_slice(chars);
let zv_u8_3: ZeroVec<[u8; 3]> = zv_char.try_into_converted().expect("length is divisible");
assert!(matches!(zv_u8_3, ZeroVec::Owned(_)));
assert_eq!(zv_u8_3.get(0), Some([0x7F, 0xF3, 0x01]));
If the types are not the same size, we refuse to convert:
use zerovec::ZeroVec;
let bytes: &[u8] = &[0x7F, 0xF3, 0x01, 0x49, 0xF6, 0x01];
let zv_char: ZeroVec<char> = ZeroVec::parse_byte_slice(bytes).expect("valid code points");
// Panics! mem::size_of::<char::ULE> != mem::size_of::<u16::ULE>
zv_char.try_into_converted::<u16>();
Instead, convert to bytes and then parse:
use zerovec::ZeroVec;
let bytes: &[u8] = &[0x7F, 0xF3, 0x01, 0x49, 0xF6, 0x01];
let zv_char: ZeroVec<char> = ZeroVec::parse_byte_slice(bytes).expect("valid code points");
let zv_u16: ZeroVec<u16> = zv_char.into_bytes().try_into_parsed().expect("infallible");
assert!(matches!(zv_u16, ZeroVec::Borrowed(_)));
assert_eq!(zv_u16.get(0), Some(0xF37F));
sourceimpl<'a> ZeroVec<'a, u8>
impl<'a> ZeroVec<'a, u8>
sourcepub fn try_into_parsed<T: AsULE>(self) -> Result<ZeroVec<'a, T>, ZeroVecError>
pub fn try_into_parsed<T: AsULE>(self) -> Result<ZeroVec<'a, T>, ZeroVecError>
Converts a ZeroVec<u8>
into a ZeroVec<T>
, retaining the current ownership model.
Note that the length of the ZeroVec may change.
Examples
Convert a borrowed ZeroVec
:
use zerovec::ZeroVec;
let bytes: &[u8] = &[0xD3, 0x00, 0x19, 0x01, 0xA5, 0x01, 0xCD, 0x01];
let zv_bytes = ZeroVec::Borrowed(bytes);
let zerovec: ZeroVec<u16> = zv_bytes.try_into_parsed().expect("infallible");
assert!(matches!(zerovec, ZeroVec::Borrowed(_)));
assert_eq!(zerovec.get(0), Some(211));
Convert an owned ZeroVec
:
use zerovec::ZeroVec;
let bytes: Vec<u8> = vec![0xD3, 0x00, 0x19, 0x01, 0xA5, 0x01, 0xCD, 0x01];
let zv_bytes = ZeroVec::Owned(bytes);
let zerovec: ZeroVec<u16> = zv_bytes.try_into_parsed().expect("infallible");
assert!(matches!(zerovec, ZeroVec::Owned(_)));
assert_eq!(zerovec.get(0), Some(211));
sourceimpl<T> ZeroVec<'_, T> where
T: AsULE,
impl<T> ZeroVec<'_, T> where
T: AsULE,
sourcepub fn alloc_from_slice(other: &[T]) -> Self
pub fn alloc_from_slice(other: &[T]) -> Self
Creates a ZeroVec<T>
from a &[T]
by allocating memory.
This function 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::alloc_from_slice(nums);
assert!(matches!(zerovec, ZeroVec::Owned(_)));
assert_eq!(bytes, zerovec.as_bytes());
sourceimpl<'a, T> ZeroVec<'a, T> where
T: EqULE,
impl<'a, T> ZeroVec<'a, T> where
T: EqULE,
sourcepub fn try_from_slice(slice: &'a [T]) -> Option<Self>
pub fn try_from_slice(slice: &'a [T]) -> Option<Self>
Attempts to create a ZeroVec<'a, T>
from a &'a [T]
by borrowing the argument.
If this is not possible, such as on a big-endian platform, None
is returned.
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];
if let Some(zerovec) = ZeroVec::try_from_slice(nums) {
assert!(matches!(zerovec, ZeroVec::Borrowed(_)));
assert_eq!(bytes, zerovec.as_bytes());
}
sourcepub fn from_slice_or_alloc(slice: &'a [T]) -> Self
pub fn from_slice_or_alloc(slice: &'a [T]) -> Self
Creates a ZeroVec<'a, T>
from a &'a [T]
, either by borrowing the argument or by
allocating a new vector.
This is a cheap operation on little-endian platforms, falling back to a more expensive operation on big-endian platforms.
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_slice_or_alloc(nums);
// Note: zerovec could be either borrowed or owned.
assert_eq!(bytes, zerovec.as_bytes());
sourceimpl<T> ZeroVec<'_, T> where
T: AsULE,
impl<T> ZeroVec<'_, T> where
T: AsULE,
sourcepub fn for_each_mut(&mut self, f: impl FnMut(&mut T))
pub fn for_each_mut(&mut self, f: impl FnMut(&mut T))
Mutates each element according to a given function, meant to be
a more convenient version of calling .iter_mut()
on
ZeroVec::to_mut()
which serves fewer use cases.
This will convert the ZeroVec into an owned ZeroVec if not already the case.
Example
use zerovec::ule::AsULE;
use zerovec::ZeroVec;
let bytes: &[u8] = &[0xD3, 0x00, 0x19, 0x01, 0xA5, 0x01, 0xCD, 0x01];
let mut zerovec: ZeroVec<u16> = ZeroVec::parse_byte_slice(bytes).expect("infallible");
zerovec.for_each_mut(|item| *item += 1);
assert_eq!(zerovec.to_vec(), &[212, 282, 422, 462]);
assert!(matches!(zerovec, ZeroVec::Owned(_)));
sourcepub fn try_for_each_mut<E>(
&mut self,
f: impl FnMut(&mut T) -> Result<(), E>
) -> Result<(), E>
pub fn try_for_each_mut<E>(
&mut self,
f: impl FnMut(&mut T) -> Result<(), E>
) -> Result<(), E>
Same as ZeroVec::for_each_mut()
, but bubbles up errors.
Example
use zerovec::ule::AsULE;
use zerovec::ZeroVec;
let bytes: &[u8] = &[0xD3, 0x00, 0x19, 0x01, 0xA5, 0x01, 0xCD, 0x01];
let mut zerovec: ZeroVec<u16> = ZeroVec::parse_byte_slice(bytes).expect("infallible");
zerovec.try_for_each_mut(|item| {
*item = item.checked_add(1).ok_or(())?;
Ok(())
})?;
assert_eq!(zerovec.to_vec(), &[212, 282, 422, 462]);
assert!(matches!(zerovec, ZeroVec::Owned(_)));
sourcepub fn into_owned(self) -> ZeroVec<'static, T>
pub fn into_owned(self) -> ZeroVec<'static, T>
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::parse_byte_slice(bytes).expect("infallible");
assert!(matches!(zerovec, ZeroVec::Borrowed(_)));
let owned = zerovec.into_owned();
assert!(matches!(owned, ZeroVec::Owned(_)));
sourcepub fn to_mut(&mut self) -> &mut Vec<T::ULE>
pub fn to_mut(&mut self) -> &mut Vec<T::ULE>
Allows the ZeroVec to be mutated by converting it to an owned variant, and producing a mutable vector of ULEs.
Example
use zerovec::ZeroVec;
let bytes: &[u8] = &[0xD3, 0x00, 0x19, 0x01, 0xA5, 0x01, 0xCD, 0x01];
let mut zerovec: ZeroVec<u16> = ZeroVec::parse_byte_slice(bytes).expect("infallible");
assert!(matches!(zerovec, ZeroVec::Borrowed(_)));
zerovec.to_mut().push(12_u16.to_unaligned());
assert!(matches!(zerovec, ZeroVec::Owned(_)));
Methods from Deref<Target = ZeroSlice<T>>
sourcepub fn as_zerovec(&self) -> ZeroVec<'_, T>
pub fn as_zerovec(&self) -> ZeroVec<'_, T>
sourcepub fn as_bytes(&self) -> &[u8]ⓘNotable traits for &[u8]impl Read for &[u8]impl Write for &mut [u8]
pub fn as_bytes(&self) -> &[u8]ⓘNotable traits for &[u8]impl Read for &[u8]impl Write for &mut [u8]
Returns this slice 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, 0x80];
let nums: &[u16] = &[211, 281, 421, 32973];
let zerovec = ZeroVec::alloc_from_slice(nums);
assert_eq!(bytes, zerovec.as_bytes());
sourcepub fn as_ule_slice(&self) -> &[T::ULE]
pub fn as_ule_slice(&self) -> &[T::ULE]
Dereferences this slice as &[T::ULE]
.
sourcepub fn len(&self) -> usize
pub fn len(&self) -> usize
Returns the number of elements in this slice.
Example
use zerovec::ule::AsULE;
use zerovec::ZeroVec;
let bytes: &[u8] = &[0xD3, 0x00, 0x19, 0x01, 0xA5, 0x01, 0xCD, 0x80];
let zerovec: ZeroVec<u16> = ZeroVec::parse_byte_slice(bytes).expect("infallible");
assert_eq!(4, zerovec.len());
assert_eq!(
bytes.len(),
zerovec.len() * std::mem::size_of::<<u16 as AsULE>::ULE>()
);
sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
Returns whether this slice is empty.
Example
use zerovec::ZeroVec;
let bytes: &[u8] = &[0xD3, 0x00, 0x19, 0x01, 0xA5, 0x01, 0xCD, 0x80];
let zerovec: ZeroVec<u16> = ZeroVec::parse_byte_slice(bytes).expect("infallible");
assert!(!zerovec.is_empty());
let emptyvec: ZeroVec<u16> = ZeroVec::parse_byte_slice(&[]).expect("infallible");
assert!(emptyvec.is_empty());
sourcepub fn get(&self, index: usize) -> Option<T>
pub fn get(&self, index: usize) -> Option<T>
Gets the element at the specified index. Returns None if out of range.
Example
use zerovec::ZeroVec;
let bytes: &[u8] = &[0xD3, 0x00, 0x19, 0x01, 0xA5, 0x01, 0xCD, 0x80];
let zerovec: ZeroVec<u16> = ZeroVec::parse_byte_slice(bytes).expect("infallible");
assert_eq!(zerovec.get(2), Some(421));
assert_eq!(zerovec.get(4), None);
sourcepub fn get_subslice(&self, range: Range<usize>) -> Option<&ZeroSlice<T>>
pub fn get_subslice(&self, range: Range<usize>) -> Option<&ZeroSlice<T>>
Gets a subslice of elements within a certain range. Returns None if the range
is out of bounds of this ZeroSlice
.
Example
use zerovec::ZeroVec;
let bytes: &[u8] = &[0xD3, 0x00, 0x19, 0x01, 0xA5, 0x01, 0xCD, 0x80];
let zerovec: ZeroVec<u16> = ZeroVec::parse_byte_slice(bytes).expect("infallible");
assert_eq!(
zerovec.get_subslice(1..3),
Some(&*ZeroVec::from_slice_or_alloc(&[0x0119, 0x01A5]))
);
assert_eq!(zerovec.get_subslice(3..5), None);
sourcepub fn get_ule_ref(&self, index: usize) -> Option<&T::ULE>
pub fn get_ule_ref(&self, index: usize) -> Option<&T::ULE>
Get a borrowed reference to the underlying ULE type at a specified index.
Prefer Self::get()
over this method where possible since working
directly with ULE
types is less ergonomic
sourcepub fn cast<P>(&self) -> &ZeroSlice<P> where
P: AsULE<ULE = T::ULE>,
pub fn cast<P>(&self) -> &ZeroSlice<P> where
P: AsULE<ULE = T::ULE>,
Casts a ZeroSlice<T>
to a compatible ZeroSlice<P>
.
T
and P
are compatible if they have the same ULE
representation.
If the ULE
s of T
and P
are different, use Self::try_as_converted()
.
Examples
use zerovec::ZeroSlice;
const bytes: &[u8] = &[0xD3, 0x00, 0x19, 0x01, 0xA5, 0x01, 0xCD, 0x80];
const zs_u16: &ZeroSlice<u16> = {
match ZeroSlice::<u16>::try_from_bytes(bytes) {
Ok(s) => s,
Err(_) => unreachable!(),
}
};
let zs_i16: &ZeroSlice<i16> = zs_u16.cast();
assert_eq!(zs_u16.get(3), Some(32973));
assert_eq!(zs_i16.get(3), Some(-32563));
sourcepub fn try_as_converted<P: AsULE>(&self) -> Result<&ZeroSlice<P>, ZeroVecError>
pub fn try_as_converted<P: AsULE>(&self) -> Result<&ZeroSlice<P>, ZeroVecError>
Converts a &ZeroSlice<T>
into a &ZeroSlice<P>
.
The resulting slice will have the same length as the original slice
if and only if T::ULE
and P::ULE
are the same size.
If T
and P
have the exact same ULE
, use Self::cast()
.
Examples
use zerovec::ZeroSlice;
const bytes: &[u8] = &[0x7F, 0xF3, 0x01, 0x00, 0x49, 0xF6, 0x01, 0x00];
const zs_u32: &ZeroSlice<u32> = {
match ZeroSlice::<u32>::try_from_bytes(bytes) {
Ok(s) => s,
Err(_) => unreachable!(),
}
};
let zs_u8_4: &ZeroSlice<[u8; 4]> = zs_u32.try_as_converted().expect("valid code points");
assert_eq!(zs_u32.get(0), Some(127871));
assert_eq!(zs_u8_4.get(0), Some([0x7F, 0xF3, 0x01, 0x00]));
sourcepub fn first(&self) -> Option<T>
pub fn first(&self) -> Option<T>
Gets the first element. Returns None if empty.
Example
use zerovec::ZeroVec;
let bytes: &[u8] = &[0xD3, 0x00, 0x19, 0x01, 0xA5, 0x01, 0xCD, 0x80];
let zerovec: ZeroVec<u16> = ZeroVec::parse_byte_slice(bytes).expect("infallible");
assert_eq!(zerovec.first(), Some(211));
sourcepub fn last(&self) -> Option<T>
pub fn last(&self) -> Option<T>
Gets the last element. Returns None if empty.
Example
use zerovec::ZeroVec;
let bytes: &[u8] = &[0xD3, 0x00, 0x19, 0x01, 0xA5, 0x01, 0xCD, 0x80];
let zerovec: ZeroVec<u16> = ZeroVec::parse_byte_slice(bytes).expect("infallible");
assert_eq!(zerovec.last(), Some(32973));
sourcepub fn iter(
&self
) -> impl DoubleEndedIterator<Item = T> + ExactSizeIterator<Item = T> + '_
pub fn iter(
&self
) -> impl DoubleEndedIterator<Item = T> + ExactSizeIterator<Item = T> + '_
Gets an iterator over the elements.
Example
use zerovec::ZeroVec;
let bytes: &[u8] = &[0xD3, 0x00, 0x19, 0x01, 0xA5, 0x01, 0xCD, 0x80];
let zerovec: ZeroVec<u16> = ZeroVec::parse_byte_slice(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(32973));
assert_eq!(it.next(), None);
sourcepub fn binary_search(&self, x: &T) -> Result<usize, usize>
pub fn binary_search(&self, x: &T) -> Result<usize, usize>
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, 0x80];
let zerovec: ZeroVec<u16> = ZeroVec::parse_byte_slice(bytes).expect("infallible");
assert_eq!(zerovec.binary_search(&281), Ok(1));
assert_eq!(zerovec.binary_search(&282), Err(2));
sourcepub fn binary_search_by(
&self,
predicate: impl FnMut(T) -> Ordering
) -> Result<usize, usize>
pub fn binary_search_by(
&self,
predicate: impl FnMut(T) -> Ordering
) -> Result<usize, usize>
Binary searches a sorted ZeroVec<T>
based on a given predicate. For more information, see
the primitive function binary_search_by
.
Example
use zerovec::ZeroVec;
let bytes: &[u8] = &[0xD3, 0x00, 0x19, 0x01, 0xA5, 0x01, 0xCD, 0x80];
let zerovec: ZeroVec<u16> = ZeroVec::parse_byte_slice(bytes).expect("infallible");
assert_eq!(zerovec.binary_search_by(|x| x.cmp(&281)), Ok(1));
assert_eq!(zerovec.binary_search_by(|x| x.cmp(&282)), Err(2));
Trait Implementations
sourceimpl<T> Bake for ZeroVec<'_, T> where
T: AsULE + ?Sized,
impl<T> Bake for ZeroVec<'_, T> where
T: AsULE + ?Sized,
sourcefn bake(&self, env: &CrateEnv) -> TokenStream
fn bake(&self, env: &CrateEnv) -> TokenStream
Returns a TokenStream
that would evalutate to self
. Read more
sourceimpl<'a, T: Clone> Clone for ZeroVec<'a, T> where
T: AsULE + ?Sized,
T::ULE: Clone,
T::ULE: Clone,
impl<'a, T: Clone> Clone for ZeroVec<'a, T> where
T: AsULE + ?Sized,
T::ULE: Clone,
T::ULE: Clone,
sourceimpl<'de, 'a, T> Deserialize<'de> for ZeroVec<'a, T> where
T: 'de + Deserialize<'de> + AsULE,
'de: 'a,
impl<'de, 'a, T> Deserialize<'de> for ZeroVec<'a, T> where
T: 'de + Deserialize<'de> + AsULE,
'de: 'a,
This impl can be made available by enabling the optional serde
feature of the zerovec
crate
sourcefn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where
D: Deserializer<'de>,
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where
D: Deserializer<'de>,
Deserialize this value from the given Serde deserializer. Read more
sourceimpl<T> EncodeAsVarULE<ZeroSlice<T>> for ZeroVec<'_, T> where
T: AsULE + 'static,
impl<T> EncodeAsVarULE<ZeroSlice<T>> for ZeroVec<'_, T> where
T: AsULE + 'static,
sourcefn encode_var_ule_as_slices<R>(&self, _: impl FnOnce(&[&[u8]]) -> R) -> R
fn encode_var_ule_as_slices<R>(&self, _: impl FnOnce(&[&[u8]]) -> R) -> R
Calls cb
with a piecewise list of byte slices that when concatenated
produce the memory pattern of the corresponding instance of T
. Read more
sourcefn encode_var_ule_len(&self) -> usize
fn encode_var_ule_len(&self) -> usize
Return the length, in bytes, of the corresponding VarULE
type
sourcefn encode_var_ule_write(&self, dst: &mut [u8])
fn encode_var_ule_write(&self, dst: &mut [u8])
Write the corresponding VarULE
type to the dst
buffer. dst
should
be the size of Self::encode_var_ule_len()
Read more
sourceimpl<T: AsULE> FromIterator<T> for ZeroVec<'_, T>
impl<T: AsULE> FromIterator<T> for ZeroVec<'_, T>
sourcefn from_iter<I>(iter: I) -> Self where
I: IntoIterator<Item = T>,
fn from_iter<I>(iter: I) -> Self where
I: IntoIterator<Item = T>,
Creates a ZeroVec::Owned
from an iterator of values.
sourceimpl<'a, T> MutableZeroVecLike<'a, T> for ZeroVec<'a, T> where
T: AsULE + Copy + 'static,
impl<'a, T> MutableZeroVecLike<'a, T> for ZeroVec<'a, T> where
T: AsULE + Copy + 'static,
type OwnedType = T
type OwnedType = T
The type returned by Self::remove()
and Self::replace()
sourcefn zvl_insert(&mut self, index: usize, value: &T)
fn zvl_insert(&mut self, index: usize, value: &T)
Insert an element at index
sourcefn zvl_remove(&mut self, index: usize) -> T
fn zvl_remove(&mut self, index: usize) -> T
Remove the element at index
(panicking if nonexistant)
sourcefn zvl_replace(&mut self, index: usize, value: &T) -> T
fn zvl_replace(&mut self, index: usize, value: &T) -> T
Replace the element at index
with another one, returning the old element
sourcefn zvl_with_capacity(cap: usize) -> Self
fn zvl_with_capacity(cap: usize) -> Self
Create a new, empty vector, with given capacity
sourcefn zvl_reserve(&mut self, addl: usize)
fn zvl_reserve(&mut self, addl: usize)
Reserve space for addl
additional elements
sourcefn owned_as_t(o: &Self::OwnedType) -> &T
fn owned_as_t(o: &Self::OwnedType) -> &T
Convert an owned value to a borrowed T
sourcefn zvl_from_borrowed(b: &'a ZeroSlice<T>) -> Self
fn zvl_from_borrowed(b: &'a ZeroSlice<T>) -> Self
Construct from the borrowed version of the type Read more
sourcefn zvl_as_borrowed_inner(&self) -> Option<&'a ZeroSlice<T>>
fn zvl_as_borrowed_inner(&self) -> Option<&'a ZeroSlice<T>>
Extract the inner borrowed variant if possible. Returns None
if the data is owned. Read more
sourceimpl<'a, T: AsULE + Ord> Ord for ZeroVec<'a, T>
impl<'a, T: AsULE + Ord> Ord for ZeroVec<'a, T>
1.21.0 · sourcefn max(self, other: Self) -> Self
fn max(self, other: Self) -> Self
Compares and returns the maximum of two values. Read more
1.21.0 · sourcefn min(self, other: Self) -> Self
fn min(self, other: Self) -> Self
Compares and returns the minimum of two values. Read more
1.50.0 · sourcefn clamp(self, min: Self, max: Self) -> Self where
Self: PartialOrd<Self>,
fn clamp(self, min: Self, max: Self) -> Self where
Self: PartialOrd<Self>,
Restrict a value to a certain interval. Read more
sourceimpl<T, const N: usize> PartialEq<[T; N]> for ZeroVec<'_, T> where
T: AsULE + PartialEq + ?Sized,
impl<T, const N: usize> PartialEq<[T; N]> for ZeroVec<'_, T> where
T: AsULE + PartialEq + ?Sized,
sourceimpl<'a, 'b, T> PartialEq<ZeroVec<'b, T>> for ZeroVec<'a, T> where
T: AsULE + PartialEq + ?Sized,
impl<'a, 'b, T> PartialEq<ZeroVec<'b, T>> for ZeroVec<'a, T> where
T: AsULE + PartialEq + ?Sized,
sourceimpl<'a, T: AsULE + PartialOrd> PartialOrd<ZeroVec<'a, T>> for ZeroVec<'a, T>
impl<'a, T: AsULE + PartialOrd> PartialOrd<ZeroVec<'a, T>> for ZeroVec<'a, T>
sourcefn partial_cmp(&self, other: &Self) -> Option<Ordering>
fn partial_cmp(&self, other: &Self) -> Option<Ordering>
This method returns an ordering between self
and other
values if one exists. Read more
1.0.0 · sourcefn lt(&self, other: &Rhs) -> bool
fn lt(&self, other: &Rhs) -> bool
This method tests less than (for self
and other
) and is used by the <
operator. Read more
1.0.0 · sourcefn le(&self, other: &Rhs) -> bool
fn le(&self, other: &Rhs) -> bool
This method tests less than or equal to (for self
and other
) and is used by the <=
operator. Read more
sourceimpl<T> Serialize for ZeroVec<'_, T> where
T: Serialize + AsULE,
impl<T> Serialize for ZeroVec<'_, T> where
T: Serialize + AsULE,
This impl can be made available by enabling the optional serde
feature of the zerovec
crate
sourceimpl<'a, T: 'static + AsULE + ?Sized> Yokeable<'a> for ZeroVec<'static, T>
impl<'a, T: 'static + AsULE + ?Sized> Yokeable<'a> for ZeroVec<'static, T>
This impl can be made available by enabling the optional yoke
feature of the zerovec
crate
sourcefn transform(&'a self) -> &'a Self::Output
fn transform(&'a self) -> &'a Self::Output
This method must cast self
between &'a Self<'static>
and &'a Self<'a>
. Read more
sourcefn transform_owned(self) -> Self::Output
fn transform_owned(self) -> Self::Output
This method must cast self
between Self<'static>
and Self<'a>
. Read more
sourceunsafe fn make(from: Self::Output) -> Self
unsafe fn make(from: Self::Output) -> Self
This method can be used to cast away Self<'a>
’s lifetime. Read more
sourcefn transform_mut<F>(&'a mut self, f: F) where
F: 'static + for<'b> FnOnce(&'b mut Self::Output),
fn transform_mut<F>(&'a mut self, f: F) where
F: 'static + for<'b> FnOnce(&'b mut Self::Output),
This method must cast self
between &'a mut Self<'static>
and &'a mut Self<'a>
,
and pass it to f
. Read more
sourceimpl<'zf, T> ZeroFrom<'zf, ZeroSlice<T>> for ZeroVec<'zf, T> where
T: 'static + AsULE + ?Sized,
impl<'zf, T> ZeroFrom<'zf, ZeroSlice<T>> for ZeroVec<'zf, T> where
T: 'static + AsULE + ?Sized,
sourceimpl<'zf, T> ZeroFrom<'zf, ZeroVec<'_, T>> for ZeroVec<'zf, T> where
T: 'static + AsULE + ?Sized,
impl<'zf, T> ZeroFrom<'zf, ZeroVec<'_, T>> for ZeroVec<'zf, T> where
T: 'static + AsULE + ?Sized,
sourceimpl<'a, T> ZeroVecLike<T> for ZeroVec<'a, T> where
T: 'a + AsULE + Copy,
impl<'a, T> ZeroVecLike<T> for ZeroVec<'a, T> where
T: 'a + AsULE + Copy,
type SliceVariant = ZeroSlice<T>
type SliceVariant = ZeroSlice<T>
A fully borrowed version of this
sourcefn zvl_new_borrowed() -> &'static Self::SliceVariant
fn zvl_new_borrowed() -> &'static Self::SliceVariant
Create a new, empty borrowed variant
sourcefn zvl_binary_search(&self, k: &T) -> Result<usize, usize> where
T: Ord,
fn zvl_binary_search(&self, k: &T) -> Result<usize, usize> where
T: Ord,
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
sourcefn zvl_binary_search_in_range(
&self,
k: &T,
range: Range<usize>
) -> Option<Result<usize, usize>> where
T: Ord,
fn zvl_binary_search_in_range(
&self,
k: &T,
range: Range<usize>
) -> Option<Result<usize, usize>> where
T: Ord,
Search for a key within a certain range in a sorted vector.
Returns None
if the range is out of bounds, and
Ok
or Err
in the same way as zvl_binary_search
.
Indices are returned relative to the start of the range. Read more
sourcefn zvl_binary_search_by(
&self,
predicate: impl FnMut(&T) -> Ordering
) -> Result<usize, usize>
fn zvl_binary_search_by(
&self,
predicate: impl FnMut(&T) -> Ordering
) -> Result<usize, usize>
Search for a key in a sorted vector by a predicate, 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
sourcefn zvl_binary_search_in_range_by(
&self,
predicate: impl FnMut(&T) -> Ordering,
range: Range<usize>
) -> Option<Result<usize, usize>>
fn zvl_binary_search_in_range_by(
&self,
predicate: impl FnMut(&T) -> Ordering,
range: Range<usize>
) -> Option<Result<usize, usize>>
Search for a key within a certain range in a sorted vector by a predicate.
Returns None
if the range is out of bounds, and
Ok
or Err
in the same way as zvl_binary_search
.
Indices are returned relative to the start of the range. Read more
sourcefn zvl_as_borrowed(&self) -> &ZeroSlice<T>
fn zvl_as_borrowed(&self) -> &ZeroSlice<T>
Construct a borrowed variant by borrowing from &self
. Read more
sourcefn zvl_get_as_t<R>(g: &Self::GetType, f: impl FnOnce(&T) -> R) -> R
fn zvl_get_as_t<R>(g: &Self::GetType, f: impl FnOnce(&T) -> R) -> R
Obtain a reference to T, passed to a closure Read more
sourcefn zvl_is_ascending(&self) -> bool where
T: Ord,
fn zvl_is_ascending(&self) -> bool where
T: Ord,
Check if this vector is in ascending order according to T
s Ord
impl
sourcefn zvl_is_empty(&self) -> bool
fn zvl_is_empty(&self) -> bool
Check if this vector is empty
impl<T> Eq for ZeroVec<'_, T> where
T: AsULE + Eq + ?Sized,
Auto Trait Implementations
impl<'a, T> RefUnwindSafe for ZeroVec<'a, T> where
<T as AsULE>::ULE: RefUnwindSafe,
impl<'a, T> Send for ZeroVec<'a, T> where
<T as AsULE>::ULE: Send + Sync,
impl<'a, T> Sync for ZeroVec<'a, T> where
<T as AsULE>::ULE: Sync,
impl<'a, T> Unpin for ZeroVec<'a, T> where
<T as AsULE>::ULE: Unpin,
impl<'a, T> UnwindSafe for ZeroVec<'a, T> where
<T as AsULE>::ULE: UnwindSafe + RefUnwindSafe,
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more