#[non_exhaustive]pub enum FlexZeroVec<'a> {
Owned(FlexZeroVecOwned),
Borrowed(&'a FlexZeroSlice),
}
Expand description
A zero-copy data structure that efficiently stores integer values.
FlexZeroVec
automatically increases or decreases its storage capacity based on the largest
integer stored in the vector. It therefore results in lower memory usage when smaller numbers
are usually stored, but larger values must sometimes also be stored.
The maximum value that can be stored in FlexZeroVec
is usize::MAX
on the current platform.
FlexZeroVec
is the data structure for storing usize
in a ZeroMap
.
FlexZeroVec
derefs to FlexZeroSlice
, which contains most of the methods.
§Examples
Storing a vec of usize
s in a zero-copy way:
use zerovec::vecs::FlexZeroVec;
// Create a FlexZeroVec and add a few numbers to it
let mut zv1 = FlexZeroVec::new();
zv1.to_mut().push(55);
zv1.to_mut().push(33);
zv1.to_mut().push(999);
assert_eq!(zv1.to_vec(), vec![55, 33, 999]);
// Convert it to bytes and back
let bytes = zv1.as_bytes();
let zv2 =
FlexZeroVec::parse_byte_slice(bytes).expect("bytes should round-trip");
assert_eq!(zv2.to_vec(), vec![55, 33, 999]);
// Verify the compact storage
assert_eq!(7, bytes.len());
assert!(matches!(zv2, FlexZeroVec::Borrowed(_)));
Storing a map of usize
to usize
in a zero-copy way:
use zerovec::ZeroMap;
// Append some values to the ZeroMap
let mut zm = ZeroMap::<usize, usize>::new();
assert!(zm.try_append(&29, &92).is_none());
assert!(zm.try_append(&38, &83).is_none());
assert!(zm.try_append(&56, &65).is_none());
assert_eq!(zm.len(), 3);
// Insert another value into the middle
assert!(zm.try_append(&47, &74).is_some());
assert!(zm.insert(&47, &74).is_none());
assert_eq!(zm.len(), 4);
// Verify that the values are correct
assert_eq!(zm.get_copied(&0), None);
assert_eq!(zm.get_copied(&29), Some(92));
assert_eq!(zm.get_copied(&38), Some(83));
assert_eq!(zm.get_copied(&47), Some(74));
assert_eq!(zm.get_copied(&56), Some(65));
assert_eq!(zm.get_copied(&usize::MAX), None);
Variants (Non-exhaustive)§
This enum is marked as non-exhaustive
Owned(FlexZeroVecOwned)
Borrowed(&'a FlexZeroSlice)
Implementations§
Source§impl<'a> FlexZeroVec<'a>
impl<'a> FlexZeroVec<'a>
Sourcepub const fn new() -> Self
pub const fn new() -> Self
Creates a new, borrowed, empty FlexZeroVec
.
§Examples
use zerovec::vecs::FlexZeroVec;
let zv: FlexZeroVec = FlexZeroVec::new();
assert!(zv.is_empty());
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 FlexZeroVec
.
The bytes within the byte buffer must remain constant for the life of the FlexZeroVec.
§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.
§Max Value
The bytes will fail to parse if the high value is greater than the capacity of usize
on this platform. For example, a FlexZeroVec
created on a 64-bit platform might fail
to deserialize on a 32-bit platform.
§Example
use zerovec::vecs::FlexZeroVec;
let bytes: &[u8] = &[2, 0xD3, 0x00, 0x19, 0x01, 0xA5, 0x01, 0xCD, 0x01];
let zv = FlexZeroVec::parse_byte_slice(bytes).expect("valid slice");
assert!(matches!(zv, FlexZeroVec::Borrowed(_)));
assert_eq!(zv.get(2), Some(421));
Sourcepub fn into_owned(self) -> FlexZeroVec<'static>
pub fn into_owned(self) -> FlexZeroVec<'static>
Converts a borrowed FlexZeroVec to an owned FlexZeroVec. No-op if already owned.
§Example
use zerovec::vecs::FlexZeroVec;
let bytes: &[u8] = &[2, 0xD3, 0x00, 0x19, 0x01, 0xA5, 0x01, 0xCD, 0x01];
let zv = FlexZeroVec::parse_byte_slice(bytes).expect("valid bytes");
assert!(matches!(zv, FlexZeroVec::Borrowed(_)));
let owned = zv.into_owned();
assert!(matches!(owned, FlexZeroVec::Owned(_)));
Sourcepub fn to_mut(&mut self) -> &mut FlexZeroVecOwned
pub fn to_mut(&mut self) -> &mut FlexZeroVecOwned
Allows the FlexZeroVec to be mutated by converting it to an owned variant, and producing
a mutable FlexZeroVecOwned
.
§Example
use zerovec::vecs::FlexZeroVec;
let bytes: &[u8] = &[2, 0xD3, 0x00, 0x19, 0x01, 0xA5, 0x01, 0xCD, 0x01];
let mut zv = FlexZeroVec::parse_byte_slice(bytes).expect("valid bytes");
assert!(matches!(zv, FlexZeroVec::Borrowed(_)));
zv.to_mut().push(12);
assert!(matches!(zv, FlexZeroVec::Owned(_)));
assert_eq!(zv.get(4), Some(12));
Methods from Deref<Target = FlexZeroSlice>§
Sourcepub fn as_bytes(&self) -> &[u8]
pub fn as_bytes(&self) -> &[u8]
Returns this slice as its underlying &[u8]
byte buffer representation.
Useful for serialization.
§Example
use zerovec::vecs::FlexZeroSlice;
let bytes: &[u8] = &[2, 0xD3, 0x00, 0x19, 0x01, 0xA5, 0x01, 0xCD, 0x80];
let fzv = FlexZeroSlice::parse_byte_slice(bytes).expect("valid bytes");
assert_eq!(bytes, fzv.as_bytes());
Sourcepub fn as_flexzerovec(&self) -> FlexZeroVec<'_>
pub fn as_flexzerovec(&self) -> FlexZeroVec<'_>
Borrows this FlexZeroSlice
as a FlexZeroVec::Borrowed
.
Sourcepub fn get(&self, index: usize) -> Option<usize>
pub fn get(&self, index: usize) -> Option<usize>
Gets the element at index
, or None
if index >= self.len()
.
§Examples
use zerovec::vecs::FlexZeroVec;
let fzv: FlexZeroVec = [22, 33].iter().copied().collect();
assert_eq!(fzv.get(0), Some(22));
assert_eq!(fzv.get(1), Some(33));
assert_eq!(fzv.get(2), None);
Sourcepub unsafe fn get_unchecked(&self, index: usize) -> usize
pub unsafe fn get_unchecked(&self, index: usize) -> usize
Sourcepub fn first(&self) -> Option<usize>
pub fn first(&self) -> Option<usize>
Gets the first element of the slice, or None
if the slice is empty.
Sourcepub fn last(&self) -> Option<usize>
pub fn last(&self) -> Option<usize>
Gets the last element of the slice, or None
if the slice is empty.
Sourcepub fn iter(
&self,
) -> impl DoubleEndedIterator<Item = usize> + '_ + ExactSizeIterator<Item = usize>
pub fn iter( &self, ) -> impl DoubleEndedIterator<Item = usize> + '_ + ExactSizeIterator<Item = usize>
Gets an iterator over the elements of the slice as usize
.
Sourcepub fn iter_pairs(&self) -> impl Iterator<Item = (usize, Option<usize>)> + '_
pub fn iter_pairs(&self) -> impl Iterator<Item = (usize, Option<usize>)> + '_
Gets an iterator over pairs of elements.
The second element of the final pair is None
.
§Examples
use zerovec::vecs::FlexZeroVec;
let nums: &[usize] = &[211, 281, 421, 461];
let fzv: FlexZeroVec = nums.iter().copied().collect();
let mut pairs_it = fzv.iter_pairs();
assert_eq!(pairs_it.next(), Some((211, Some(281))));
assert_eq!(pairs_it.next(), Some((281, Some(421))));
assert_eq!(pairs_it.next(), Some((421, Some(461))));
assert_eq!(pairs_it.next(), Some((461, None)));
assert_eq!(pairs_it.next(), None);
Sourcepub fn to_vec(&self) -> Vec<usize>
pub fn to_vec(&self) -> Vec<usize>
Creates a Vec<usize>
from a FlexZeroSlice
(or FlexZeroVec
).
§Examples
use zerovec::vecs::FlexZeroVec;
let nums: &[usize] = &[211, 281, 421, 461];
let fzv: FlexZeroVec = nums.iter().copied().collect();
let vec: Vec<usize> = fzv.to_vec();
assert_eq!(nums, vec.as_slice());
Sourcepub fn binary_search(&self, needle: usize) -> Result<usize, usize>
pub fn binary_search(&self, needle: usize) -> Result<usize, usize>
Binary searches a sorted FlexZeroSlice
for the given usize
value.
§Examples
use zerovec::vecs::FlexZeroVec;
let nums: &[usize] = &[211, 281, 421, 461];
let fzv: FlexZeroVec = nums.iter().copied().collect();
assert_eq!(fzv.binary_search(0), Err(0));
assert_eq!(fzv.binary_search(211), Ok(0));
assert_eq!(fzv.binary_search(250), Err(1));
assert_eq!(fzv.binary_search(281), Ok(1));
assert_eq!(fzv.binary_search(300), Err(2));
assert_eq!(fzv.binary_search(421), Ok(2));
assert_eq!(fzv.binary_search(450), Err(3));
assert_eq!(fzv.binary_search(461), Ok(3));
assert_eq!(fzv.binary_search(462), Err(4));
Sourcepub fn binary_search_in_range(
&self,
needle: usize,
range: Range<usize>,
) -> Option<Result<usize, usize>>
pub fn binary_search_in_range( &self, needle: usize, range: Range<usize>, ) -> Option<Result<usize, usize>>
Binary searches a sorted range of a FlexZeroSlice
for the given usize
value.
The indices in the return value are relative to the start of the range.
§Examples
use zerovec::vecs::FlexZeroVec;
// Make a FlexZeroVec with two sorted ranges: 0..3 and 3..5
let nums: &[usize] = &[111, 222, 444, 333, 555];
let fzv: FlexZeroVec = nums.iter().copied().collect();
// Search in the first range:
assert_eq!(fzv.binary_search_in_range(0, 0..3), Some(Err(0)));
assert_eq!(fzv.binary_search_in_range(111, 0..3), Some(Ok(0)));
assert_eq!(fzv.binary_search_in_range(199, 0..3), Some(Err(1)));
assert_eq!(fzv.binary_search_in_range(222, 0..3), Some(Ok(1)));
assert_eq!(fzv.binary_search_in_range(399, 0..3), Some(Err(2)));
assert_eq!(fzv.binary_search_in_range(444, 0..3), Some(Ok(2)));
assert_eq!(fzv.binary_search_in_range(999, 0..3), Some(Err(3)));
// Search in the second range:
assert_eq!(fzv.binary_search_in_range(0, 3..5), Some(Err(0)));
assert_eq!(fzv.binary_search_in_range(333, 3..5), Some(Ok(0)));
assert_eq!(fzv.binary_search_in_range(399, 3..5), Some(Err(1)));
assert_eq!(fzv.binary_search_in_range(555, 3..5), Some(Ok(1)));
assert_eq!(fzv.binary_search_in_range(999, 3..5), Some(Err(2)));
// Out-of-bounds range:
assert_eq!(fzv.binary_search_in_range(0, 4..6), None);
Sourcepub fn binary_search_by(
&self,
predicate: impl FnMut(usize) -> Ordering,
) -> Result<usize, usize>
pub fn binary_search_by( &self, predicate: impl FnMut(usize) -> Ordering, ) -> Result<usize, usize>
Binary searches a sorted FlexZeroSlice
according to a predicate function.
Sourcepub fn binary_search_in_range_by(
&self,
predicate: impl FnMut(usize) -> Ordering,
range: Range<usize>,
) -> Option<Result<usize, usize>>
pub fn binary_search_in_range_by( &self, predicate: impl FnMut(usize) -> Ordering, range: Range<usize>, ) -> Option<Result<usize, usize>>
Binary searches a sorted range of a FlexZeroSlice
according to a predicate function.
The indices in the return value are relative to the start of the range.
Sourcepub fn binary_search_with_index(
&self,
predicate: impl FnMut(usize) -> Ordering,
) -> Result<usize, usize>
pub fn binary_search_with_index( &self, predicate: impl FnMut(usize) -> Ordering, ) -> Result<usize, usize>
Binary searches a FlexZeroSlice
by its indices.
The predicate
function is passed in-bounds indices into the FlexZeroSlice
.
Sourcepub fn binary_search_in_range_with_index(
&self,
predicate: impl FnMut(usize) -> Ordering,
range: Range<usize>,
) -> Option<Result<usize, usize>>
pub fn binary_search_in_range_with_index( &self, predicate: impl FnMut(usize) -> Ordering, range: Range<usize>, ) -> Option<Result<usize, usize>>
Binary searches a range of a FlexZeroSlice
by its indices.
The predicate
function is passed in-bounds indices into the FlexZeroSlice
, which are
relative to the start of the entire slice.
The indices in the return value are relative to the start of the range.
Trait Implementations§
Source§impl<'a> AsRef<FlexZeroSlice> for FlexZeroVec<'a>
impl<'a> AsRef<FlexZeroSlice> for FlexZeroVec<'a>
Source§fn as_ref(&self) -> &FlexZeroSlice
fn as_ref(&self) -> &FlexZeroSlice
Source§impl<'a> Debug for FlexZeroVec<'a>
impl<'a> Debug for FlexZeroVec<'a>
Source§impl<'a> Default for FlexZeroVec<'a>
impl<'a> Default for FlexZeroVec<'a>
Source§impl<'a> Deref for FlexZeroVec<'a>
impl<'a> Deref for FlexZeroVec<'a>
Source§impl FromIterator<usize> for FlexZeroVec<'_>
impl FromIterator<usize> for FlexZeroVec<'_>
Source§fn from_iter<I>(iter: I) -> Selfwhere
I: IntoIterator<Item = usize>,
fn from_iter<I>(iter: I) -> Selfwhere
I: IntoIterator<Item = usize>,
Creates a FlexZeroVec::Owned
from an iterator of usize
.
Source§impl<'a> MutableZeroVecLike<'a, usize> for FlexZeroVec<'a>
impl<'a> MutableZeroVecLike<'a, usize> for FlexZeroVec<'a>
Source§fn zvl_insert(&mut self, index: usize, value: &usize)
fn zvl_insert(&mut self, index: usize, value: &usize)
index
Source§fn zvl_remove(&mut self, index: usize) -> usize
fn zvl_remove(&mut self, index: usize) -> usize
index
(panicking if nonexistant)Source§fn zvl_replace(&mut self, index: usize, value: &usize) -> usize
fn zvl_replace(&mut self, index: usize, value: &usize) -> usize
index
with another one, returning the old elementSource§fn zvl_with_capacity(_cap: usize) -> Self
fn zvl_with_capacity(_cap: usize) -> Self
Source§fn zvl_reserve(&mut self, _addl: usize)
fn zvl_reserve(&mut self, _addl: usize)
addl
additional elementsSource§fn owned_as_t(o: &Self::OwnedType) -> &usize
fn owned_as_t(o: &Self::OwnedType) -> &usize
Source§fn zvl_from_borrowed(b: &'a FlexZeroSlice) -> Self
fn zvl_from_borrowed(b: &'a FlexZeroSlice) -> Self
Source§fn zvl_as_borrowed_inner(&self) -> Option<&'a FlexZeroSlice>
fn zvl_as_borrowed_inner(&self) -> Option<&'a FlexZeroSlice>
None
if the data is owned. Read moreSource§fn zvl_permute(&mut self, permutation: &mut [usize])
fn zvl_permute(&mut self, permutation: &mut [usize])
before.zvl_get(permutation[i]) == after.zvl_get(i)
. Read moreSource§impl<'a> Ord for FlexZeroVec<'a>
impl<'a> Ord for FlexZeroVec<'a>
Source§impl<'a, 'b> PartialEq<FlexZeroVec<'b>> for FlexZeroVec<'a>
impl<'a, 'b> PartialEq<FlexZeroVec<'b>> for FlexZeroVec<'a>
Source§impl<'a> PartialOrd for FlexZeroVec<'a>
impl<'a> PartialOrd for FlexZeroVec<'a>
Source§impl<'a> Yokeable<'a> for FlexZeroVec<'static>
impl<'a> Yokeable<'a> for FlexZeroVec<'static>
This impl requires enabling the optional yoke
Cargo feature of the zerovec
crate
Source§type Output = FlexZeroVec<'a>
type Output = FlexZeroVec<'a>
Self
with the 'static
replaced with 'a
, i.e. Self<'a>
Source§fn transform_owned(self) -> Self::Output
fn transform_owned(self) -> Self::Output
Source§impl<'zf> ZeroFrom<'zf, FlexZeroSlice> for FlexZeroVec<'zf>
impl<'zf> ZeroFrom<'zf, FlexZeroSlice> for FlexZeroVec<'zf>
Source§fn zero_from(other: &'zf FlexZeroSlice) -> Self
fn zero_from(other: &'zf FlexZeroSlice) -> Self
C
into a struct that may retain references into C
.Source§impl<'zf> ZeroFrom<'zf, FlexZeroVec<'_>> for FlexZeroVec<'zf>
impl<'zf> ZeroFrom<'zf, FlexZeroVec<'_>> for FlexZeroVec<'zf>
Source§fn zero_from(other: &'zf FlexZeroVec<'_>) -> Self
fn zero_from(other: &'zf FlexZeroVec<'_>) -> Self
C
into a struct that may retain references into C
.Source§impl<'a> ZeroVecLike<usize> for FlexZeroVec<'a>
impl<'a> ZeroVecLike<usize> for FlexZeroVec<'a>
Source§type SliceVariant = FlexZeroSlice
type SliceVariant = FlexZeroSlice
Source§fn zvl_new_borrowed() -> &'static Self::SliceVariant
fn zvl_new_borrowed() -> &'static Self::SliceVariant
Source§fn zvl_binary_search(&self, k: &usize) -> Result<usize, usize>
fn zvl_binary_search(&self, k: &usize) -> Result<usize, usize>
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.Source§fn zvl_binary_search_in_range(
&self,
k: &usize,
range: Range<usize>,
) -> Option<Result<usize, usize>>
fn zvl_binary_search_in_range( &self, k: &usize, range: Range<usize>, ) -> Option<Result<usize, usize>>
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.Source§fn zvl_binary_search_by(
&self,
predicate: impl FnMut(&usize) -> Ordering,
) -> Result<usize, usize>
fn zvl_binary_search_by( &self, predicate: impl FnMut(&usize) -> Ordering, ) -> Result<usize, usize>
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.Source§fn zvl_binary_search_in_range_by(
&self,
predicate: impl FnMut(&usize) -> Ordering,
range: Range<usize>,
) -> Option<Result<usize, usize>>
fn zvl_binary_search_in_range_by( &self, predicate: impl FnMut(&usize) -> Ordering, range: Range<usize>, ) -> Option<Result<usize, usize>>
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.Source§fn zvl_as_borrowed(&self) -> &FlexZeroSlice
fn zvl_as_borrowed(&self) -> &FlexZeroSlice
&self
. Read moreSource§fn zvl_get_as_t<R>(g: &[u8], f: impl FnOnce(&usize) -> R) -> R
fn zvl_get_as_t<R>(g: &[u8], f: impl FnOnce(&usize) -> R) -> R
Source§fn zvl_is_ascending(&self) -> boolwhere
T: Ord,
fn zvl_is_ascending(&self) -> boolwhere
T: Ord,
T
s Ord
impl