use crate::dimension;
use crate::error::ShapeError;
use crate::extension::nonnull::nonnull_debug_checked_from_ptr;
use crate::imp_prelude::*;
use crate::{is_aligned, StrideShape};
impl<'a, A, D> ArrayView<'a, A, D>
where
D: Dimension,
{
pub fn from_shape<Sh>(shape: Sh, xs: &'a [A]) -> Result<Self, ShapeError>
where
Sh: Into<StrideShape<D>>,
{
Self::from_shape_impl(shape.into(), xs)
}
fn from_shape_impl(shape: StrideShape<D>, xs: &'a [A]) -> Result<Self, ShapeError> {
let dim = shape.dim;
let strides = shape.strides;
if shape.custom {
dimension::can_index_slice(xs, &dim, &strides)?;
} else {
dimension::can_index_slice_not_custom::<A, _>(xs, &dim)?;
}
unsafe { Ok(Self::new_(xs.as_ptr(), dim, strides)) }
}
pub unsafe fn from_shape_ptr<Sh>(shape: Sh, ptr: *const A) -> Self
where
Sh: Into<StrideShape<D>>,
{
RawArrayView::from_shape_ptr(shape, ptr).deref_into_view()
}
}
impl<'a, A, D> ArrayViewMut<'a, A, D>
where
D: Dimension,
{
pub fn from_shape<Sh>(shape: Sh, xs: &'a mut [A]) -> Result<Self, ShapeError>
where
Sh: Into<StrideShape<D>>,
{
Self::from_shape_impl(shape.into(), xs)
}
fn from_shape_impl(shape: StrideShape<D>, xs: &'a mut [A]) -> Result<Self, ShapeError> {
let dim = shape.dim;
let strides = shape.strides;
if shape.custom {
dimension::can_index_slice(xs, &dim, &strides)?;
} else {
dimension::can_index_slice_not_custom::<A, _>(xs, &dim)?;
}
unsafe { Ok(Self::new_(xs.as_mut_ptr(), dim, strides)) }
}
pub unsafe fn from_shape_ptr<Sh>(shape: Sh, ptr: *mut A) -> Self
where
Sh: Into<StrideShape<D>>,
{
RawArrayViewMut::from_shape_ptr(shape, ptr).deref_into_view_mut()
}
pub fn reborrow<'b>(mut self) -> ArrayViewMut<'b, A, D>
where
'a: 'b,
{
unsafe { ArrayViewMut::new_(self.as_mut_ptr(), self.dim, self.strides) }
}
}
impl<'a, A, D> ArrayView<'a, A, D>
where
D: Dimension,
{
#[inline(always)]
pub(crate) unsafe fn new_(ptr: *const A, dim: D, strides: D) -> Self {
ArrayView {
data: ViewRepr::new(),
ptr: nonnull_debug_checked_from_ptr(ptr as *mut A),
dim,
strides,
}
}
}
impl<'a, A, D> ArrayViewMut<'a, A, D>
where
D: Dimension,
{
#[inline(always)]
pub(crate) unsafe fn new_(ptr: *mut A, dim: D, strides: D) -> Self {
if cfg!(debug_assertions) {
assert!(!ptr.is_null(), "The pointer must be non-null.");
assert!(is_aligned(ptr), "The pointer must be aligned.");
dimension::max_abs_offset_check_overflow::<A, _>(&dim, &strides).unwrap();
}
ArrayViewMut {
data: ViewRepr::new(),
ptr: nonnull_debug_checked_from_ptr(ptr),
dim,
strides,
}
}
}