pub mod rowmajor;
pub unsafe trait DenseData {
type Elem;
fn as_slice(&self) -> &[Self::Elem];
}
pub unsafe trait MutDenseData: DenseData {
fn as_mut_slice(&mut self) -> &mut [Self::Elem];
}
unsafe impl<T> DenseData for &[T] {
type Elem = T;
fn as_slice(&self) -> &[Self::Elem] {
self
}
}
unsafe impl<T> DenseData for &mut [T] {
type Elem = T;
fn as_slice(&self) -> &[Self::Elem] {
self
}
}
unsafe impl<T> MutDenseData for &mut [T] {
fn as_mut_slice(&mut self) -> &mut [Self::Elem] {
self
}
}
unsafe impl<T> DenseData for Box<[T]> {
type Elem = T;
fn as_slice(&self) -> &[Self::Elem] {
self
}
}
unsafe impl<T> MutDenseData for Box<[T]> {
fn as_mut_slice(&mut self) -> &mut [Self::Elem] {
self
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::lazy_format;
fn test_dense_data_repr<T, Repr>(
ptr: *const T,
len: usize,
repr: Repr,
context: &dyn std::fmt::Display,
) where
T: Copy,
Repr: DenseData<Elem = T>,
{
let retrieved = repr.as_slice();
assert_eq!(retrieved.len(), len, "{}", context);
assert_eq!(retrieved.as_ptr(), ptr, "{}", context);
}
fn set_mut_dense_data_repr<T, Repr>(repr: &mut Repr, base: T, increment: T)
where
T: Copy + std::ops::Add<Output = T>,
Repr: DenseData<Elem = T> + MutDenseData,
{
let slice = repr.as_mut_slice();
for i in 0..slice.len() {
if i == 0 {
slice[i] = base;
} else {
slice[i] = slice[i - 1] + increment;
}
}
}
#[test]
fn slice_implements_dense_data_repr() {
for len in 0..10 {
let context = lazy_format!("len = {}", len);
let data: Vec<f32> = vec![0.0; len];
let slice = data.as_slice();
test_dense_data_repr(slice.as_ptr(), slice.len(), slice, &context);
}
}
#[test]
fn mut_slice_implements_dense_data_repr() {
for len in 0..10 {
let context = lazy_format!("len = {}", len);
let mut data: Vec<f32> = vec![0.0; len];
let slice = data.as_mut_slice();
let ptr = slice.as_ptr();
let len = slice.len();
test_dense_data_repr(ptr, len, slice, &context);
}
}
#[test]
fn mut_slice_implements_mut_dense_data_repr() {
for len in 0..10 {
let context = lazy_format!("len = {}", len);
let mut data: Vec<f32> = vec![0.0; len];
let mut slice = data.as_mut_slice();
let base = 2.0;
let increment = 1.0;
set_mut_dense_data_repr(&mut slice, base, increment);
for (i, &v) in slice.iter().enumerate() {
let context = lazy_format!("entry {}, {}", i, context);
assert_eq!(v, base + increment * (i as f32), "{}", context);
}
}
}
#[test]
fn test_box_slice_dense_data_impls() {
let data: Box<[f32]> = vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0].into();
let ptr = data.as_ptr();
let len = data.len();
test_dense_data_repr(ptr, len, data, &lazy_format!("Box<[T]> DenseData"));
let mut data: Box<[f32]> = vec![0.0; 6].into();
set_mut_dense_data_repr(&mut data, 1.0, 2.0);
for (i, &v) in data.iter().enumerate() {
assert_eq!(
v,
1.0 + 2.0 * (i as f32),
"Box<[T]> MutDenseData at index {}",
i
);
}
}
}