use crate::ndarray::flags::NdArrayFlags;
use crate::ndarray::NdArray;
use crate::common::constructors::Constructors;
use crate::RawDataType;
use std::mem::ManuallyDrop;
use std::ptr::NonNull;
pub(crate) fn stride_from_shape(shape: &[usize]) -> Vec<usize> {
let ndims = shape.len();
let mut stride = vec![0; ndims];
let mut p = 1;
for i in (0..ndims).rev() {
stride[i] = p;
p *= shape[i];
}
stride
}
impl<'a, T: RawDataType> Constructors<T> for NdArray<'a, T> {
unsafe fn from_contiguous_owned_buffer(shape: Vec<usize>, data: Vec<T>) -> Self {
let flags = NdArrayFlags::Owned | NdArrayFlags::Contiguous | NdArrayFlags::UniformStride | NdArrayFlags::Writeable;
let mut data = ManuallyDrop::new(data);
let stride = stride_from_shape(&shape);
Self {
ptr: NonNull::new_unchecked(data.as_mut_ptr()),
len: data.len(),
capacity: data.capacity(),
shape,
stride,
flags,
_marker: Default::default(),
}
}
}
impl<T: RawDataType> Drop for NdArray<'_, T> {
fn drop(&mut self) {
if self.flags.contains(NdArrayFlags::Owned) {
unsafe { Vec::from_raw_parts(self.mut_ptr(), self.len, self.capacity) };
}
self.len = 0;
self.capacity = 0;
}
}