Skip to content

Commit

Permalink
Add initial zeroslice! and zerovec! macros (#3453)
Browse files Browse the repository at this point in the history
  • Loading branch information
skius authored May 26, 2023
1 parent 51da740 commit 1baf9e9
Showing 1 changed file with 81 additions and 0 deletions.
81 changes: 81 additions & 0 deletions utils/zerovec/src/zerovec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -919,6 +919,87 @@ impl<T: AsULE> FromIterator<T> for ZeroVec<'_, T> {
}
}

/// Convenience wrapper for [`ZeroSlice::from_ule_slice`]. The value will be created at compile-time.
///
/// # Arguments
///
/// * `$aligned` - The type of an element in its canonical, aligned form, e.g., `char`.
/// * `$array_fn` - A const function that converts an array of `$aligned` elements into an array
/// of their unaligned equivalents, e.g.,
/// `const fn from_array<const N: usize>(arr: [char; N]) -> [<char as AsULE>::ULE; N]`.
/// * `$x` - The elements that the `ZeroSlice` will hold.
///
/// # Examples
///
/// Using array-conversion functions provided by this crate:
///
/// ```
/// use zerovec::{ZeroSlice, zeroslice, ule::AsULE};
///
/// const SIGNATURE: &ZeroSlice<char> = zeroslice![char; <char as AsULE>::ULE::from_array; 'b', 'y', 'e', '✌'];
/// const EMPTY: &ZeroSlice<u32> = zeroslice![];
/// let empty: &ZeroSlice<u32> = zeroslice![];
/// let nums = zeroslice![u32; <u32 as AsULE>::ULE::from_array; 1, 2, 3, 4, 5];
/// assert_eq!(nums.last().unwrap(), 5);
/// ```
///
/// Using a custom array-conversion function:
///
/// ```
/// use zerovec::{ZeroSlice, zeroslice};
///
/// mod conversion {
/// use zerovec::ule::RawBytesULE;
/// pub(super) const fn i16_array_to_be_array<const N: usize>(arr: [i16; N]) -> [RawBytesULE<2>; N] {
/// let mut result = [RawBytesULE([0; 2]); N];
/// let mut i = 0;
/// while i < N {
/// result[i] = RawBytesULE(arr[i].to_be_bytes());
/// i += 1;
/// }
/// result
/// }
/// }
///
/// const NUMBERS: &ZeroSlice<i16> = zeroslice![i16; conversion::i16_array_to_be_array; 1, -2, 3, -4, 5];
/// ```
#[macro_export]
macro_rules! zeroslice {
() => (
$crate::ZeroSlice::new_empty()
);
($aligned:ty; $array_fn:expr; $($x:expr),+ $(,)?) => (
$crate::ZeroSlice::<$aligned>::from_ule_slice(
{const X: &[<$aligned as $crate::ule::AsULE>::ULE] = &$array_fn([$($x),+]); X}
)
);
}

/// Creates a borrowed `ZeroVec`. Convenience wrapper for `zeroslice![...].as_zerovec()`.
///
/// See [`zeroslice!`](crate::zeroslice) for more information.
///
/// # Examples
///
/// ```
/// use zerovec::{ZeroVec, zerovec, ule::AsULE};
///
/// const SIGNATURE: ZeroVec<char> = zerovec![char; <char as AsULE>::ULE::from_array; 'a', 'y', 'e', '✌'];
/// assert!(!SIGNATURE.is_owned());
///
/// const EMPTY: ZeroVec<u32> = zerovec![];
/// assert!(!EMPTY.is_owned());
/// ```
#[macro_export]
macro_rules! zerovec {
() => (
$crate::ZeroVec::new()
);
($aligned:ty; $array_fn:expr; $($x:expr),+ $(,)?) => (
$crate::zeroslice![$aligned; $array_fn; $($x),+].as_zerovec()
);
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down

0 comments on commit 1baf9e9

Please sign in to comment.