1use crate::imp_prelude::*;
2use crate::ArrayRef;
3use crate::Layout;
4use crate::NdIndex;
5#[cfg(not(feature = "std"))]
6use alloc::vec::Vec;
7
8pub trait IntoNdProducer
14{
15 type Item;
17 type Dim: Dimension;
19 type Output: NdProducer<Dim = Self::Dim, Item = Self::Item>;
21 fn into_producer(self) -> Self::Output;
23}
24
25impl<P> IntoNdProducer for P
26where P: NdProducer
27{
28 type Item = P::Item;
29 type Dim = P::Dim;
30 type Output = Self;
31 fn into_producer(self) -> Self::Output
32 {
33 self
34 }
35}
36
37pub trait NdProducer
58{
59 type Item;
61 type Dim: Dimension;
64
65 #[doc(hidden)]
70 type Ptr: Offset<Stride = Self::Stride>;
72 #[doc(hidden)]
73 type Stride: Copy;
75
76 #[doc(hidden)]
77 fn layout(&self) -> Layout;
78 fn raw_dim(&self) -> Self::Dim;
80 #[doc(hidden)]
81 fn equal_dim(&self, dim: &Self::Dim) -> bool
82 {
83 self.raw_dim() == *dim
84 }
85 #[doc(hidden)]
86 fn as_ptr(&self) -> Self::Ptr;
87 #[doc(hidden)]
88 unsafe fn as_ref(&self, ptr: Self::Ptr) -> Self::Item;
89 #[doc(hidden)]
90 unsafe fn uget_ptr(&self, i: &Self::Dim) -> Self::Ptr;
91 #[doc(hidden)]
92 fn stride_of(&self, axis: Axis) -> <Self::Ptr as Offset>::Stride;
93 #[doc(hidden)]
94 fn contiguous_stride(&self) -> Self::Stride;
95 #[doc(hidden)]
96 fn split_at(self, axis: Axis, index: usize) -> (Self, Self)
97 where Self: Sized;
98
99 private_decl! {}
100}
101
102pub trait Offset: Copy
103{
104 type Stride: Copy;
105 unsafe fn stride_offset(self, s: Self::Stride, index: usize) -> Self;
106 private_decl! {}
107}
108
109impl<T> Offset for *const T
110{
111 type Stride = isize;
112 unsafe fn stride_offset(self, s: Self::Stride, index: usize) -> Self
113 {
114 self.offset(s * (index as isize))
115 }
116 private_impl! {}
117}
118
119impl<T> Offset for *mut T
120{
121 type Stride = isize;
122 unsafe fn stride_offset(self, s: Self::Stride, index: usize) -> Self
123 {
124 self.offset(s * (index as isize))
125 }
126 private_impl! {}
127}
128
129impl<'a, A: 'a, S, D> IntoNdProducer for &'a ArrayBase<S, D>
132where
133 D: Dimension,
134 S: Data<Elem = A>,
135{
136 type Item = &'a A;
137 type Dim = D;
138 type Output = ArrayView<'a, A, D>;
139 fn into_producer(self) -> Self::Output
140 {
141 self.view()
142 }
143}
144
145impl<'a, A: 'a, S, D> IntoNdProducer for &'a mut ArrayBase<S, D>
148where
149 D: Dimension,
150 S: DataMut<Elem = A>,
151{
152 type Item = &'a mut A;
153 type Dim = D;
154 type Output = ArrayViewMut<'a, A, D>;
155 fn into_producer(self) -> Self::Output
156 {
157 self.view_mut()
158 }
159}
160
161impl<'a, A: 'a, D> IntoNdProducer for &'a ArrayRef<A, D>
164where D: Dimension
165{
166 type Item = &'a A;
167 type Dim = D;
168 type Output = ArrayView<'a, A, D>;
169 fn into_producer(self) -> Self::Output
170 {
171 self.view()
172 }
173}
174
175impl<'a, A: 'a, D> IntoNdProducer for &'a mut ArrayRef<A, D>
178where D: Dimension
179{
180 type Item = &'a mut A;
181 type Dim = D;
182 type Output = ArrayViewMut<'a, A, D>;
183 fn into_producer(self) -> Self::Output
184 {
185 self.view_mut()
186 }
187}
188
189impl<'a, A: 'a> IntoNdProducer for &'a [A]
191{
192 type Item = <Self::Output as NdProducer>::Item;
193 type Dim = Ix1;
194 type Output = ArrayView1<'a, A>;
195 fn into_producer(self) -> Self::Output
196 {
197 <_>::from(self)
198 }
199}
200
201impl<'a, A: 'a> IntoNdProducer for &'a mut [A]
203{
204 type Item = <Self::Output as NdProducer>::Item;
205 type Dim = Ix1;
206 type Output = ArrayViewMut1<'a, A>;
207 fn into_producer(self) -> Self::Output
208 {
209 <_>::from(self)
210 }
211}
212
213impl<'a, A: 'a, const N: usize> IntoNdProducer for &'a [A; N]
215{
216 type Item = <Self::Output as NdProducer>::Item;
217 type Dim = Ix1;
218 type Output = ArrayView1<'a, A>;
219 fn into_producer(self) -> Self::Output
220 {
221 <_>::from(self)
222 }
223}
224
225impl<'a, A: 'a, const N: usize> IntoNdProducer for &'a mut [A; N]
227{
228 type Item = <Self::Output as NdProducer>::Item;
229 type Dim = Ix1;
230 type Output = ArrayViewMut1<'a, A>;
231 fn into_producer(self) -> Self::Output
232 {
233 <_>::from(self)
234 }
235}
236
237impl<'a, A: 'a> IntoNdProducer for &'a Vec<A>
239{
240 type Item = <Self::Output as NdProducer>::Item;
241 type Dim = Ix1;
242 type Output = ArrayView1<'a, A>;
243 fn into_producer(self) -> Self::Output
244 {
245 <_>::from(self)
246 }
247}
248
249impl<'a, A: 'a> IntoNdProducer for &'a mut Vec<A>
251{
252 type Item = <Self::Output as NdProducer>::Item;
253 type Dim = Ix1;
254 type Output = ArrayViewMut1<'a, A>;
255 fn into_producer(self) -> Self::Output
256 {
257 <_>::from(self)
258 }
259}
260
261impl<'a, A, D: Dimension> NdProducer for ArrayView<'a, A, D>
262{
263 type Item = &'a A;
264 type Dim = D;
265 type Ptr = *mut A;
266 type Stride = isize;
267
268 private_impl! {}
269
270 fn raw_dim(&self) -> Self::Dim
271 {
272 (***self).raw_dim()
273 }
274
275 fn equal_dim(&self, dim: &Self::Dim) -> bool
276 {
277 self._dim().equal(dim)
278 }
279
280 fn as_ptr(&self) -> *mut A
281 {
282 (**self).as_ptr() as _
283 }
284
285 fn layout(&self) -> Layout
286 {
287 self.layout_impl()
288 }
289
290 unsafe fn as_ref(&self, ptr: *mut A) -> Self::Item
291 {
292 &*ptr
293 }
294
295 unsafe fn uget_ptr(&self, i: &Self::Dim) -> *mut A
296 {
297 self._ptr()
298 .as_ptr()
299 .offset(i.index_unchecked(self._strides()))
300 }
301
302 fn stride_of(&self, axis: Axis) -> isize
303 {
304 (**self).stride_of(axis)
305 }
306
307 #[inline(always)]
308 fn contiguous_stride(&self) -> Self::Stride
309 {
310 1
311 }
312
313 fn split_at(self, axis: Axis, index: usize) -> (Self, Self)
314 {
315 self.split_at(axis, index)
316 }
317}
318
319impl<'a, A, D: Dimension> NdProducer for ArrayViewMut<'a, A, D>
320{
321 type Item = &'a mut A;
322 type Dim = D;
323 type Ptr = *mut A;
324 type Stride = isize;
325
326 private_impl! {}
327
328 fn raw_dim(&self) -> Self::Dim
329 {
330 (***self).raw_dim()
331 }
332
333 fn equal_dim(&self, dim: &Self::Dim) -> bool
334 {
335 self._dim().equal(dim)
336 }
337
338 fn as_ptr(&self) -> *mut A
339 {
340 (**self).as_ptr() as _
341 }
342
343 fn layout(&self) -> Layout
344 {
345 self.layout_impl()
346 }
347
348 unsafe fn as_ref(&self, ptr: *mut A) -> Self::Item
349 {
350 &mut *ptr
351 }
352
353 unsafe fn uget_ptr(&self, i: &Self::Dim) -> *mut A
354 {
355 self._ptr()
356 .as_ptr()
357 .offset(i.index_unchecked(self._strides()))
358 }
359
360 fn stride_of(&self, axis: Axis) -> isize
361 {
362 (**self).stride_of(axis)
363 }
364
365 #[inline(always)]
366 fn contiguous_stride(&self) -> Self::Stride
367 {
368 1
369 }
370
371 fn split_at(self, axis: Axis, index: usize) -> (Self, Self)
372 {
373 self.split_at(axis, index)
374 }
375}
376
377impl<A, D: Dimension> NdProducer for RawArrayView<A, D>
378{
379 type Item = *const A;
380 type Dim = D;
381 type Ptr = *const A;
382 type Stride = isize;
383
384 private_impl! {}
385
386 fn raw_dim(&self) -> Self::Dim
387 {
388 self.raw_dim()
389 }
390
391 fn equal_dim(&self, dim: &Self::Dim) -> bool
392 {
393 self.parts.dim.equal(dim)
394 }
395
396 fn as_ptr(&self) -> *const A
397 {
398 self.as_ptr() as _
399 }
400
401 fn layout(&self) -> Layout
402 {
403 AsRef::<LayoutRef<_, _>>::as_ref(self).layout_impl()
404 }
405
406 unsafe fn as_ref(&self, ptr: *const A) -> *const A
407 {
408 ptr
409 }
410
411 unsafe fn uget_ptr(&self, i: &Self::Dim) -> *const A
412 {
413 self.parts
414 .ptr
415 .as_ptr()
416 .offset(i.index_unchecked(&self.parts.strides))
417 }
418
419 fn stride_of(&self, axis: Axis) -> isize
420 {
421 self.stride_of(axis)
422 }
423
424 #[inline(always)]
425 fn contiguous_stride(&self) -> Self::Stride
426 {
427 1
428 }
429
430 fn split_at(self, axis: Axis, index: usize) -> (Self, Self)
431 {
432 self.split_at(axis, index)
433 }
434}
435
436impl<A, D: Dimension> NdProducer for RawArrayViewMut<A, D>
437{
438 type Item = *mut A;
439 type Dim = D;
440 type Ptr = *mut A;
441 type Stride = isize;
442
443 private_impl! {}
444
445 fn raw_dim(&self) -> Self::Dim
446 {
447 self.raw_dim()
448 }
449
450 fn equal_dim(&self, dim: &Self::Dim) -> bool
451 {
452 self.parts.dim.equal(dim)
453 }
454
455 fn as_ptr(&self) -> *mut A
456 {
457 self.as_ptr() as _
458 }
459
460 fn layout(&self) -> Layout
461 {
462 AsRef::<LayoutRef<_, _>>::as_ref(self).layout_impl()
463 }
464
465 unsafe fn as_ref(&self, ptr: *mut A) -> *mut A
466 {
467 ptr
468 }
469
470 unsafe fn uget_ptr(&self, i: &Self::Dim) -> *mut A
471 {
472 self.parts
473 .ptr
474 .as_ptr()
475 .offset(i.index_unchecked(&self.parts.strides))
476 }
477
478 fn stride_of(&self, axis: Axis) -> isize
479 {
480 self.stride_of(axis)
481 }
482
483 #[inline(always)]
484 fn contiguous_stride(&self) -> Self::Stride
485 {
486 1
487 }
488
489 fn split_at(self, axis: Axis, index: usize) -> (Self, Self)
490 {
491 self.split_at(axis, index)
492 }
493}