use aligned_vec::{AVec, ConstAlign};
use std::collections::TryReserveError;
#[allow(dead_code)] pub const SIMD_ALIGN: usize = 64;
#[allow(dead_code)] pub type AlignedVec<T> = AVec<T, ConstAlign<SIMD_ALIGN>>;
#[allow(dead_code)] pub fn aligned_vec_with_capacity<T>(capacity: usize) -> Result<AlignedVec<T>, TryReserveError> {
let mut vec = AVec::new(SIMD_ALIGN);
let size_bytes = capacity.checked_mul(std::mem::size_of::<T>());
if size_bytes.is_none() || size_bytes.unwrap() > isize::MAX as usize {
let mut dummy: Vec<T> = Vec::new();
dummy.try_reserve(capacity)?;
}
vec.reserve(capacity);
Ok(vec)
}
#[allow(dead_code)] pub fn aligned_vec_zeroed<T: Default + Clone>(
len: usize,
) -> Result<AlignedVec<T>, TryReserveError> {
let mut vec = aligned_vec_with_capacity(len)?;
vec.resize(len, T::default());
Ok(vec)
}
pub trait NewWithCapacity {
type Output;
type Error;
fn new_with_capacity(capacity: usize) -> Result<Self::Output, Self::Error>;
}
impl<T> NewWithCapacity for Vec<T> {
type Output = Vec<T>;
type Error = TryReserveError;
fn new_with_capacity(capacity: usize) -> Result<Self::Output, Self::Error> {
let mut vec = Vec::new();
vec.try_reserve(capacity)?;
Ok(vec)
}
}
impl NewWithCapacity for String {
type Output = String;
type Error = TryReserveError;
fn new_with_capacity(capacity: usize) -> Result<Self::Output, Self::Error> {
let mut s = String::new();
s.try_reserve(capacity)?;
Ok(s)
}
}
pub trait TryVecExt<T> {
fn try_from_elem(value: T, count: usize) -> Result<Vec<T>, TryReserveError>
where
T: Clone;
#[allow(dead_code)]
fn try_extend_from_slice(&mut self, slice: &[T]) -> Result<(), TryReserveError>
where
T: Clone;
}
impl<T> TryVecExt<T> for Vec<T> {
fn try_from_elem(value: T, count: usize) -> Result<Vec<T>, TryReserveError>
where
T: Clone,
{
let mut vec = Vec::new();
vec.try_reserve(count)?;
vec.resize(count, value);
Ok(vec)
}
fn try_extend_from_slice(&mut self, slice: &[T]) -> Result<(), TryReserveError>
where
T: Clone,
{
self.try_reserve(slice.len())?;
self.extend_from_slice(slice);
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_aligned_vec_with_capacity() {
let vec: AlignedVec<f32> = aligned_vec_with_capacity(1024).unwrap();
assert!((vec.as_ptr() as usize).is_multiple_of(SIMD_ALIGN));
}
#[test]
fn test_aligned_vec_zeroed() {
let vec: AlignedVec<f32> = aligned_vec_zeroed(1024).unwrap();
assert_eq!(vec.len(), 1024);
assert!(vec.iter().all(|&x| x == 0.0));
assert!((vec.as_ptr() as usize).is_multiple_of(SIMD_ALIGN));
}
#[test]
fn test_try_from_elem() {
let vec = Vec::<u8>::try_from_elem(42, 100).unwrap();
assert_eq!(vec.len(), 100);
assert!(vec.iter().all(|&x| x == 42));
}
}