use super::options::OneDimensionalMode;
pub const STORAGE_DIMS_BUF_LEN: usize = 8;
#[inline]
pub fn vector_dims(len: usize, mode: OneDimensionalMode) -> [usize; 2] {
match mode {
OneDimensionalMode::ColumnVector => [len, 1],
OneDimensionalMode::RowVector => [1, len],
}
}
#[inline]
pub fn matrix_dims(extents: &[usize], mode: OneDimensionalMode) -> Vec<usize> {
match extents {
[] => vec![1, 1],
[len] => vector_dims(*len, mode).to_vec(),
_ => extents.to_vec(),
}
}
#[inline]
pub fn storage_dims_u64_into<'a>(matlab_dims: &[usize], buf: &'a mut [u64]) -> &'a [u64] {
let n = matlab_dims.len().max(2);
assert!(
n <= buf.len(),
"storage_dims_u64_into: need {n} slots, buf has {}",
buf.len()
);
if matlab_dims.is_empty() {
buf[0] = 1;
buf[1] = 1;
} else if matlab_dims.len() == 1 {
buf[0] = 1;
buf[1] = matlab_dims[0] as u64;
} else {
for (i, &d) in matlab_dims.iter().enumerate() {
buf[n - 1 - i] = d as u64;
}
}
&buf[..n]
}
#[inline]
pub fn storage_dims_u64(matlab_dims: &[usize]) -> Vec<u64> {
let mut buf = [0u64; STORAGE_DIMS_BUF_LEN];
if matlab_dims.len() > STORAGE_DIMS_BUF_LEN {
return storage_dims_u64_heap(matlab_dims);
}
storage_dims_u64_into(matlab_dims, &mut buf).to_vec()
}
#[cold]
fn storage_dims_u64_heap(matlab_dims: &[usize]) -> Vec<u64> {
let n = matlab_dims.len().max(2);
let mut out = vec![0u64; n];
storage_dims_u64_into(matlab_dims, &mut out);
out
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn vector_dims_modes() {
assert_eq!(vector_dims(5, OneDimensionalMode::ColumnVector), [5, 1]);
assert_eq!(vector_dims(5, OneDimensionalMode::RowVector), [1, 5]);
}
#[test]
fn matrix_dims_handles_special_cases() {
assert_eq!(
matrix_dims(&[], OneDimensionalMode::ColumnVector),
vec![1, 1]
);
assert_eq!(
matrix_dims(&[7], OneDimensionalMode::ColumnVector),
vec![7, 1]
);
assert_eq!(
matrix_dims(&[3, 4], OneDimensionalMode::ColumnVector),
vec![3, 4]
);
}
#[test]
fn storage_dims_u64_pads_and_reverses() {
let mut buf = [0u64; STORAGE_DIMS_BUF_LEN];
assert_eq!(storage_dims_u64_into(&[], &mut buf), &[1u64, 1]);
assert_eq!(storage_dims_u64_into(&[5], &mut buf), &[1u64, 5]);
assert_eq!(storage_dims_u64_into(&[3, 4], &mut buf), &[4u64, 3]);
assert_eq!(storage_dims_u64_into(&[2, 3, 4], &mut buf), &[4u64, 3, 2]);
}
#[test]
fn storage_dims_u64_alloc_path_matches() {
assert_eq!(storage_dims_u64(&[5]), vec![1u64, 5]);
assert_eq!(storage_dims_u64(&[3, 4]), vec![4u64, 3]);
assert_eq!(storage_dims_u64(&[2, 3, 4]), vec![4u64, 3, 2]);
}
}