use std::ptr::NonNull;
use crate::dimension::offset_from_low_addr_ptr_to_logical_ptr;
use crate::dimension::{self, CanIndexCheckMode};
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;
dimension::can_index_slice_with_strides(xs, &dim, &shape.strides, CanIndexCheckMode::ReadOnly)?;
let strides = shape.strides.strides_for_dim(&dim);
unsafe {
Ok(Self::new_(
xs.as_ptr()
.add(offset_from_low_addr_ptr_to_logical_ptr(&dim, &strides)),
dim,
strides,
))
}
}
#[inline]
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;
dimension::can_index_slice_with_strides(xs, &dim, &shape.strides, CanIndexCheckMode::OwnedMutable)?;
let strides = shape.strides.strides_for_dim(&dim);
unsafe {
Ok(Self::new_(
xs.as_mut_ptr()
.add(offset_from_low_addr_ptr_to_logical_ptr(&dim, &strides)),
dim,
strides,
))
}
}
#[inline]
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>(self) -> ArrayViewMut<'b, A, D>
where 'a: 'b
{
unsafe { ArrayViewMut::new(self.parts.ptr, self.parts.dim, self.parts.strides) }
}
}
impl<A, D> ArrayView<'_, A, D>
where D: Dimension
{
#[inline(always)]
pub(crate) unsafe fn new(ptr: NonNull<A>, dim: D, strides: D) -> Self
{
if cfg!(debug_assertions) {
assert!(is_aligned(ptr.as_ptr()), "The pointer must be aligned.");
dimension::max_abs_offset_check_overflow::<A, _>(&dim, &strides).unwrap();
}
ArrayView::from_data_ptr(ViewRepr::new(), ptr).with_strides_dim(strides, dim)
}
#[inline]
pub(crate) unsafe fn new_(ptr: *const A, dim: D, strides: D) -> Self
{
Self::new(nonnull_debug_checked_from_ptr(ptr as *mut A), dim, strides)
}
}
impl<A, D> ArrayViewMut<'_, A, D>
where D: Dimension
{
#[inline(always)]
pub(crate) unsafe fn new(ptr: NonNull<A>, dim: D, strides: D) -> Self
{
if cfg!(debug_assertions) {
assert!(is_aligned(ptr.as_ptr()), "The pointer must be aligned.");
dimension::max_abs_offset_check_overflow::<A, _>(&dim, &strides).unwrap();
}
ArrayViewMut::from_data_ptr(ViewRepr::new(), ptr).with_strides_dim(strides, dim)
}
#[inline(always)]
pub(crate) unsafe fn new_(ptr: *mut A, dim: D, strides: D) -> Self
{
Self::new(nonnull_debug_checked_from_ptr(ptr), dim, strides)
}
}