use crate::imp_prelude::*;
use crate::Layout;
use crate::NdIndex;
#[cfg(not(features = "std"))]
use alloc::vec::Vec;
pub trait IntoNdProducer {
type Item;
type Dim: Dimension;
type Output: NdProducer<Dim = Self::Dim, Item = Self::Item>;
fn into_producer(self) -> Self::Output;
}
impl<P> IntoNdProducer for P
where
P: NdProducer,
{
type Item = P::Item;
type Dim = P::Dim;
type Output = Self;
fn into_producer(self) -> Self::Output {
self
}
}
pub trait NdProducer {
type Item;
type Dim: Dimension;
#[doc(hidden)]
type Ptr: Offset<Stride = Self::Stride>;
#[doc(hidden)]
type Stride: Copy;
#[doc(hidden)]
fn layout(&self) -> Layout;
fn raw_dim(&self) -> Self::Dim;
#[doc(hidden)]
fn equal_dim(&self, dim: &Self::Dim) -> bool {
self.raw_dim() == *dim
}
#[doc(hidden)]
fn as_ptr(&self) -> Self::Ptr;
#[doc(hidden)]
unsafe fn as_ref(&self, ptr: Self::Ptr) -> Self::Item;
#[doc(hidden)]
unsafe fn uget_ptr(&self, i: &Self::Dim) -> Self::Ptr;
#[doc(hidden)]
fn stride_of(&self, axis: Axis) -> <Self::Ptr as Offset>::Stride;
#[doc(hidden)]
fn contiguous_stride(&self) -> Self::Stride;
#[doc(hidden)]
fn split_at(self, axis: Axis, index: usize) -> (Self, Self)
where
Self: Sized;
private_decl! {}
}
pub trait Offset: Copy {
type Stride: Copy;
unsafe fn stride_offset(self, s: Self::Stride, index: usize) -> Self;
private_decl! {}
}
impl<T> Offset for *const T {
type Stride = isize;
unsafe fn stride_offset(self, s: Self::Stride, index: usize) -> Self {
self.offset(s * (index as isize))
}
private_impl! {}
}
impl<T> Offset for *mut T {
type Stride = isize;
unsafe fn stride_offset(self, s: Self::Stride, index: usize) -> Self {
self.offset(s * (index as isize))
}
private_impl! {}
}
impl<'a, A: 'a, S, D> IntoNdProducer for &'a ArrayBase<S, D>
where
D: Dimension,
S: Data<Elem = A>,
{
type Item = &'a A;
type Dim = D;
type Output = ArrayView<'a, A, D>;
fn into_producer(self) -> Self::Output {
self.view()
}
}
impl<'a, A: 'a, S, D> IntoNdProducer for &'a mut ArrayBase<S, D>
where
D: Dimension,
S: DataMut<Elem = A>,
{
type Item = &'a mut A;
type Dim = D;
type Output = ArrayViewMut<'a, A, D>;
fn into_producer(self) -> Self::Output {
self.view_mut()
}
}
impl<'a, A: 'a> IntoNdProducer for &'a [A] {
type Item = <Self::Output as NdProducer>::Item;
type Dim = Ix1;
type Output = ArrayView1<'a, A>;
fn into_producer(self) -> Self::Output {
<_>::from(self)
}
}
impl<'a, A: 'a> IntoNdProducer for &'a mut [A] {
type Item = <Self::Output as NdProducer>::Item;
type Dim = Ix1;
type Output = ArrayViewMut1<'a, A>;
fn into_producer(self) -> Self::Output {
<_>::from(self)
}
}
impl<'a, A: 'a> IntoNdProducer for &'a Vec<A> {
type Item = <Self::Output as NdProducer>::Item;
type Dim = Ix1;
type Output = ArrayView1<'a, A>;
fn into_producer(self) -> Self::Output {
<_>::from(self)
}
}
impl<'a, A: 'a> IntoNdProducer for &'a mut Vec<A> {
type Item = <Self::Output as NdProducer>::Item;
type Dim = Ix1;
type Output = ArrayViewMut1<'a, A>;
fn into_producer(self) -> Self::Output {
<_>::from(self)
}
}
impl<'a, A, D: Dimension> NdProducer for ArrayView<'a, A, D> {
type Item = &'a A;
type Dim = D;
type Ptr = *mut A;
type Stride = isize;
private_impl! {}
fn raw_dim(&self) -> Self::Dim {
self.raw_dim()
}
fn equal_dim(&self, dim: &Self::Dim) -> bool {
self.dim.equal(dim)
}
fn as_ptr(&self) -> *mut A {
self.as_ptr() as _
}
fn layout(&self) -> Layout {
self.layout_impl()
}
unsafe fn as_ref(&self, ptr: *mut A) -> Self::Item {
&*ptr
}
unsafe fn uget_ptr(&self, i: &Self::Dim) -> *mut A {
self.ptr.as_ptr().offset(i.index_unchecked(&self.strides))
}
fn stride_of(&self, axis: Axis) -> isize {
self.stride_of(axis)
}
#[inline(always)]
fn contiguous_stride(&self) -> Self::Stride {
1
}
fn split_at(self, axis: Axis, index: usize) -> (Self, Self) {
self.split_at(axis, index)
}
}
impl<'a, A, D: Dimension> NdProducer for ArrayViewMut<'a, A, D> {
type Item = &'a mut A;
type Dim = D;
type Ptr = *mut A;
type Stride = isize;
private_impl! {}
fn raw_dim(&self) -> Self::Dim {
self.raw_dim()
}
fn equal_dim(&self, dim: &Self::Dim) -> bool {
self.dim.equal(dim)
}
fn as_ptr(&self) -> *mut A {
self.as_ptr() as _
}
fn layout(&self) -> Layout {
self.layout_impl()
}
unsafe fn as_ref(&self, ptr: *mut A) -> Self::Item {
&mut *ptr
}
unsafe fn uget_ptr(&self, i: &Self::Dim) -> *mut A {
self.ptr.as_ptr().offset(i.index_unchecked(&self.strides))
}
fn stride_of(&self, axis: Axis) -> isize {
self.stride_of(axis)
}
#[inline(always)]
fn contiguous_stride(&self) -> Self::Stride {
1
}
fn split_at(self, axis: Axis, index: usize) -> (Self, Self) {
self.split_at(axis, index)
}
}
impl<A, D: Dimension> NdProducer for RawArrayView<A, D> {
type Item = *const A;
type Dim = D;
type Ptr = *const A;
type Stride = isize;
private_impl! {}
fn raw_dim(&self) -> Self::Dim {
self.raw_dim()
}
fn equal_dim(&self, dim: &Self::Dim) -> bool {
self.dim.equal(dim)
}
fn as_ptr(&self) -> *const A {
self.as_ptr()
}
fn layout(&self) -> Layout {
self.layout_impl()
}
unsafe fn as_ref(&self, ptr: *const A) -> *const A {
ptr
}
unsafe fn uget_ptr(&self, i: &Self::Dim) -> *const A {
self.ptr.as_ptr().offset(i.index_unchecked(&self.strides))
}
fn stride_of(&self, axis: Axis) -> isize {
self.stride_of(axis)
}
#[inline(always)]
fn contiguous_stride(&self) -> Self::Stride {
1
}
fn split_at(self, axis: Axis, index: usize) -> (Self, Self) {
self.split_at(axis, index)
}
}
impl<A, D: Dimension> NdProducer for RawArrayViewMut<A, D> {
type Item = *mut A;
type Dim = D;
type Ptr = *mut A;
type Stride = isize;
private_impl! {}
fn raw_dim(&self) -> Self::Dim {
self.raw_dim()
}
fn equal_dim(&self, dim: &Self::Dim) -> bool {
self.dim.equal(dim)
}
fn as_ptr(&self) -> *mut A {
self.as_ptr() as _
}
fn layout(&self) -> Layout {
self.layout_impl()
}
unsafe fn as_ref(&self, ptr: *mut A) -> *mut A {
ptr
}
unsafe fn uget_ptr(&self, i: &Self::Dim) -> *mut A {
self.ptr.as_ptr().offset(i.index_unchecked(&self.strides))
}
fn stride_of(&self, axis: Axis) -> isize {
self.stride_of(axis)
}
#[inline(always)]
fn contiguous_stride(&self) -> Self::Stride {
1
}
fn split_at(self, axis: Axis, index: usize) -> (Self, Self) {
self.split_at(axis, index)
}
}