Skip to main content

mdarray/
array.rs

1#[cfg(feature = "nightly")]
2use alloc::alloc::{Allocator, Global};
3use alloc::collections::TryReserveError;
4#[cfg(not(feature = "std"))]
5use alloc::vec::Vec;
6
7use core::borrow::{Borrow, BorrowMut};
8use core::fmt::{self, Debug, Formatter};
9use core::hash::{Hash, Hasher};
10use core::mem::{self, ManuallyDrop, MaybeUninit};
11use core::ops::{Deref, DerefMut, Index, IndexMut, RangeBounds};
12use core::{ptr, slice};
13
14#[cfg(not(feature = "nightly"))]
15use crate::allocator::{Allocator, Global};
16use crate::buffer::{Buffer, Drain, DynBuffer, Owned};
17use crate::dim::{Const, Dim, Dyn};
18use crate::expr::{self, IntoExpr, Iter, Map, Zip};
19use crate::expr::{Apply, Expand, Expression, FromExpression, IntoExpression};
20use crate::index::SliceIndex;
21use crate::layout::{Dense, Layout};
22use crate::mapping::{DenseMapping, Mapping};
23use crate::shape::{ConstShape, DynRank, IntoShape, Rank, Shape};
24use crate::slice::Slice;
25use crate::traits::IntoCloned;
26use crate::view::{View, ViewMut};
27
28#[cfg(not(feature = "nightly"))]
29macro_rules! vec_t {
30    ($type:ty, $alloc:ty) => {
31        Vec<$type>
32    };
33}
34
35#[cfg(feature = "nightly")]
36macro_rules! vec_t {
37    ($type:ty, $alloc:ty) => {
38        Vec<$type, $alloc>
39    };
40}
41
42/// Dense multidimensional array.
43#[repr(transparent)]
44pub struct Array<T, S: Shape = DynRank, A: Allocator = Global> {
45    buffer: S::Buffer<T, A>,
46}
47
48/// Multidimensional array with dynamically-sized dimensions and dense layout.
49pub type DArray<T, const N: usize, A = Global> = Array<T, Rank<N>, A>;
50
51/// Dense multidimensional array.
52///
53/// This type alias is for backward compatibility, use `Array` instead.
54pub type Tensor<T, S = DynRank, A = Global> = Array<T, S, A>;
55
56/// Multidimensional array with dynamically-sized dimensions and dense layout.
57///
58/// This type alias is for backward compatibility, use `DArray` instead.
59pub type DTensor<T, const N: usize, A = Global> = Array<T, Rank<N>, A>;
60
61impl<T, S: Shape, A: Allocator> Array<T, S, A> {
62    /// Returns a reference to the underlying allocator.
63    #[cfg(feature = "nightly")]
64    #[inline]
65    pub fn allocator(&self) -> &A {
66        self.buffer.allocator()
67    }
68
69    /// Creates an array from the given element with the specified allocator.
70    #[cfg(feature = "nightly")]
71    #[inline]
72    pub fn from_elem_in<I: IntoShape<IntoShape = S>>(shape: I, elem: T, alloc: A) -> Self
73    where
74        T: Clone,
75    {
76        Self::from_expr_in(expr::from_elem(shape, elem), alloc)
77    }
78
79    /// Creates an array from an expression with the specified allocator.
80    #[cfg(feature = "nightly")]
81    #[inline]
82    pub fn from_expr_in<I: IntoExpression<Item = T, Shape = S>>(expr: I, alloc: A) -> Self {
83        Self::with_expr_in(expr.into_expr(), alloc)
84    }
85
86    /// Creates an array with the results from the given function and the specified allocator.
87    #[cfg(feature = "nightly")]
88    #[inline]
89    pub fn from_fn_in<I: IntoShape<IntoShape = S>, F>(shape: I, f: F, alloc: A) -> Self
90    where
91        F: FnMut(&[usize]) -> T,
92    {
93        Self::from_expr_in(expr::from_fn(shape, f), alloc)
94    }
95
96    /// Converts the array into a new array with the given shape type.
97    ///
98    /// # Panics
99    ///
100    /// Panics if the shape is not matching static rank or constant-sized dimensions.
101    #[inline]
102    pub fn into_buffer<R: Shape>(self) -> Array<T, R, A> {
103        Array { buffer: self.buffer.into_buffer() }
104    }
105
106    /// Converts the array into an array with dynamic rank.
107    #[inline]
108    pub fn into_dyn(self) -> Array<T, DynRank, A> {
109        self.into_buffer()
110    }
111
112    /// Converts the array into a one-dimensional array.
113    #[cfg(not(feature = "nightly"))]
114    #[inline]
115    pub fn into_flat(self) -> Array<T, (Dyn,), A> {
116        let vec = self.into_vec();
117        let shape = (vec.len(),);
118
119        Array { buffer: unsafe { DynBuffer::from_parts(vec, shape) } }
120    }
121
122    /// Converts the array into a one-dimensional array.
123    #[cfg(feature = "nightly")]
124    #[inline]
125    pub fn into_flat(self) -> Array<T, (Dyn,), A> {
126        self.into_vec().into()
127    }
128
129    /// Converts the array into a new array with the given shape type.
130    ///
131    /// This method is deprecated, use `into_buffer` instead.
132    #[deprecated]
133    #[inline]
134    pub fn into_mapping<R: Shape>(self) -> Array<T, R, A> {
135        self.into_buffer()
136    }
137
138    /// Converts an array with a single element into the contained value.
139    ///
140    /// # Panics
141    ///
142    /// Panics if the array length is not equal to one.
143    #[inline]
144    pub fn into_scalar(self) -> T {
145        assert!(self.len() == 1, "invalid length");
146
147        self.into_iter().next().unwrap()
148    }
149
150    /// Converts the array into a reshaped array, which must have the same length.
151    ///
152    /// At most one dimension can have dynamic size `usize::MAX`, and is then inferred
153    /// from the other dimensions and the array length.
154    ///
155    /// # Examples
156    ///
157    /// ```
158    /// use mdarray::{darray, view};
159    ///
160    /// let a = darray![[1, 2, 3], [4, 5, 6]];
161    ///
162    /// assert_eq!(a.into_shape([!0, 2]), view![[1, 2], [3, 4], [5, 6]]);
163    /// ```
164    ///
165    /// # Panics
166    ///
167    /// Panics if the array length is changed.
168    #[inline]
169    pub fn into_shape<I: IntoShape>(self, shape: I) -> Array<T, I::IntoShape, A> {
170        Array { buffer: self.buffer.into_shape::<I::IntoShape>(shape.into_shape()) }
171    }
172
173    /// Converts the array into a vector.
174    #[inline]
175    pub fn into_vec(self) -> vec_t!(T, A) {
176        let len = self.len();
177        let (vec, _) = self.into_shape(len).buffer.into_parts();
178
179        vec
180    }
181
182    /// Returns an array with the same shape, and the given closure applied to each element.
183    ///
184    /// The input array is reused if the memory layout for the input and output elements
185    /// are the same, or otherwise a new array is allocated for the result.
186    #[inline]
187    pub fn map<U, F: FnMut(T) -> U>(self, mut f: F) -> Array<U, S, A> {
188        self.zip_with(expr::fill(()), |(x, ())| f(x))
189    }
190
191    /// Creates an array with uninitialized elements and the specified allocator.
192    #[cfg(feature = "nightly")]
193    #[inline]
194    pub fn uninit_in<I: IntoShape<IntoShape = S>>(
195        shape: I,
196        alloc: A,
197    ) -> Array<MaybeUninit<T>, S, A> {
198        Array { buffer: <S::Buffer<T, A>>::uninit_in(shape.into_shape(), alloc) }
199    }
200
201    /// Creates an array with elements set to zero and the specified allocator.
202    ///
203    /// Zero elements are created using `Default::default()`.
204    #[cfg(feature = "nightly")]
205    #[inline]
206    pub fn zeros_in<I: IntoShape<IntoShape = S>>(shape: I, alloc: A) -> Self
207    where
208        T: Default,
209    {
210        Self::from_expr_in(expr::from_elem(shape, ()).map(|_| T::default()), alloc)
211    }
212
213    #[inline]
214    pub(crate) fn into_inner(self) -> S::Buffer<T, A> {
215        self.buffer
216    }
217
218    #[inline]
219    pub(crate) fn with_expr_in<E: Expression<Item = T>>(expr: E, alloc: A) -> Self {
220        struct DropGuard<'a, T, S: Shape, A: Allocator> {
221            array: &'a mut Array<MaybeUninit<T>, S, A>,
222            index: usize,
223        }
224
225        impl<T, S: Shape, A: Allocator> Drop for DropGuard<'_, T, S, A> {
226            #[inline]
227            fn drop(&mut self) {
228                let ptr = self.array.as_mut_ptr() as *mut T;
229
230                unsafe {
231                    ptr::slice_from_raw_parts_mut(ptr, self.index).drop_in_place();
232                }
233            }
234        }
235
236        let shape = expr.shape().with_dims(S::from_dims);
237
238        #[cfg(not(feature = "nightly"))]
239        let mut array = Array { buffer: <S::Buffer<T, A>>::uninit_in(shape, alloc) };
240        #[cfg(feature = "nightly")]
241        let mut array = Array::uninit_in(shape, alloc);
242        let mut guard = DropGuard { array: &mut array, index: 0 };
243
244        let expr = guard.array.expr_mut().zip(expr);
245
246        expr.for_each(|(x, y)| {
247            _ = x.write(y);
248            guard.index += 1;
249        });
250
251        mem::forget(guard);
252
253        unsafe { array.assume_init() }
254    }
255}
256
257impl<T, S: Shape<Buffer<T, A> = DynBuffer<T, S, A>>, A: Allocator> Array<T, S, A> {
258    /// Moves all elements from another array into the array along the first dimension.
259    ///
260    /// If the array is empty, it is reshaped to match the shape of the other array.
261    ///
262    /// # Panics
263    ///
264    /// Panics if the inner dimensions do not match, if the rank is not the same and
265    /// at least 1, or if the first dimension is not dynamically-sized.
266    #[inline]
267    pub fn append(&mut self, other: &mut Self) {
268        self.expand(other.drain(..));
269    }
270
271    /// Returns the number of elements the array can hold without reallocating.
272    #[inline]
273    pub fn capacity(&self) -> usize {
274        self.buffer.capacity()
275    }
276
277    /// Clears the array, removing all values.
278    ///
279    /// If the array type has dynamic rank, the rank is set to 1.
280    ///
281    /// Note that this method has no effect on the allocated capacity of the array.
282    #[inline]
283    pub fn clear(&mut self) {
284        unsafe {
285            self.buffer.with_mut_parts(|vec, shape| {
286                vec.clear();
287                *shape = S::default();
288            });
289        }
290    }
291
292    /// Removes the specified range from the array along the first dimension,
293    /// and returns the removed range as an expression.
294    ///
295    /// # Panics
296    ///
297    /// Panics if the rank is not at least 1, or if the first dimension
298    /// is not dynamically-sized.
299    #[inline]
300    pub fn drain<R: RangeBounds<usize>>(&mut self, range: R) -> IntoExpr<T, Drain<'_, T, S, A>> {
301        assert!(self.rank() > 0, "invalid rank");
302        assert!(S::Head::SIZE.is_none(), "first dimension not dynamically-sized");
303
304        #[cfg(not(feature = "nightly"))]
305        let range = crate::index::range(range, ..self.dim(0));
306        #[cfg(feature = "nightly")]
307        let range = slice::range(range, ..self.dim(0));
308
309        IntoExpr::new(Drain::new(self, range.start, range.end))
310    }
311
312    /// Appends an expression to the array along the first dimension with broadcasting,
313    /// cloning elements if needed.
314    ///
315    /// If the array is empty, it is reshaped to match the shape of the expression.
316    ///
317    /// # Panics
318    ///
319    /// Panics if the inner dimensions do not match, if the rank is not the same and
320    /// at least 1, or if the first dimension is not dynamically-sized.
321    #[inline]
322    pub fn expand<I: IntoExpression<Item: IntoCloned<T>>>(&mut self, expr: I) {
323        assert!(self.rank() > 0, "invalid rank");
324        assert!(S::Head::SIZE.is_none(), "first dimension not dynamically-sized");
325
326        let expr = expr.into_expr();
327        let len = expr.len();
328
329        if len > 0 {
330            unsafe {
331                self.buffer.with_mut_parts(|vec, shape| {
332                    vec.reserve(len);
333
334                    expr.shape().with_dims(|src| {
335                        if shape.is_empty() {
336                            if src.len() == shape.rank() {
337                                shape.with_mut_dims(|dims| dims.copy_from_slice(src));
338                            } else {
339                                *shape = Shape::from_dims(src);
340                            }
341                        } else {
342                            shape.with_mut_dims(|dims| {
343                                assert!(src.len() == dims.len(), "invalid rank");
344                                assert!(src[1..] == dims[1..], "inner dimensions mismatch");
345
346                                dims[0] += src[0];
347                            });
348                        }
349                    });
350
351                    expr.clone_into_vec(vec);
352                });
353            }
354        }
355    }
356
357    /// Creates an array from raw components of another array with the specified allocator.
358    ///
359    /// # Safety
360    ///
361    /// The pointer must be a valid allocation given the shape, capacity and allocator.
362    #[cfg(feature = "nightly")]
363    #[inline]
364    pub unsafe fn from_raw_parts_in(ptr: *mut T, shape: S, capacity: usize, alloc: A) -> Self {
365        unsafe {
366            let vec = Vec::from_raw_parts_in(ptr, shape.len(), capacity, alloc);
367
368            Self { buffer: DynBuffer::from_parts(vec, shape) }
369        }
370    }
371
372    /// Decomposes an array into its raw components including the allocator.
373    #[cfg(feature = "nightly")]
374    #[inline]
375    pub fn into_raw_parts_with_alloc(self) -> (*mut T, S, usize, A) {
376        let (vec, shape) = self.buffer.into_parts();
377        let (ptr, _, capacity, alloc) = vec.into_raw_parts_with_alloc();
378
379        (ptr, shape, capacity, alloc)
380    }
381
382    /// Creates a new, empty array with the specified allocator.
383    #[cfg(feature = "nightly")]
384    #[inline]
385    pub fn new_in(alloc: A) -> Self {
386        assert!(S::default().checked_len().is_some(), "invalid length");
387
388        Self { buffer: unsafe { DynBuffer::from_parts(Vec::new_in(alloc), S::default()) } }
389    }
390
391    /// Reserves capacity for at least the additional number of elements in the array.
392    #[inline]
393    pub fn reserve(&mut self, additional: usize) {
394        unsafe {
395            self.buffer.with_mut_parts(|vec, _| vec.reserve(additional));
396        }
397    }
398
399    /// Reserves the minimum capacity for the additional number of elements in the array.
400    #[inline]
401    pub fn reserve_exact(&mut self, additional: usize) {
402        unsafe {
403            self.buffer.with_mut_parts(|vec, _| vec.reserve_exact(additional));
404        }
405    }
406
407    /// Resizes the array to the new shape, creating new elements with the given value.
408    #[inline]
409    pub fn resize<I: IntoShape<IntoShape = S>>(&mut self, new_shape: I, value: T)
410    where
411        T: Clone,
412    {
413        new_shape.into_dims(|new_dims| self.buffer.resize_with(new_dims, || value.clone()));
414    }
415
416    /// Resizes the array to the new shape, creating new elements from the given closure.
417    #[inline]
418    pub fn resize_with<I: IntoShape<IntoShape = S>, F>(&mut self, new_shape: I, f: F)
419    where
420        F: FnMut() -> T,
421    {
422        new_shape.into_dims(|new_dims| self.buffer.resize_with(new_dims, f));
423    }
424
425    /// Forces the array layout mapping to the new mapping.
426    ///
427    /// This method is deprecated, use `set_shape` instead.
428    #[allow(clippy::missing_safety_doc)]
429    #[deprecated]
430    #[inline]
431    pub unsafe fn set_mapping(&mut self, new_mapping: DenseMapping<S>) {
432        unsafe {
433            self.set_shape(new_mapping.shape().clone());
434        }
435    }
436
437    /// Forces the array layout mapping to the new shape.
438    ///
439    /// # Safety
440    ///
441    /// All elements within the array length must be initialized.
442    #[inline]
443    pub unsafe fn set_shape(&mut self, new_shape: S) {
444        unsafe {
445            self.buffer.set_shape(new_shape);
446        }
447    }
448
449    /// Shrinks the capacity of the array with a lower bound.
450    #[inline]
451    pub fn shrink_to(&mut self, min_capacity: usize) {
452        unsafe {
453            self.buffer.with_mut_parts(|vec, _| vec.shrink_to(min_capacity));
454        }
455    }
456
457    /// Shrinks the capacity of the array as much as possible.
458    #[inline]
459    pub fn shrink_to_fit(&mut self) {
460        unsafe {
461            self.buffer.with_mut_parts(|vec, _| vec.shrink_to_fit());
462        }
463    }
464
465    /// Returns the remaining spare capacity of the array as a slice of `MaybeUninit<T>`.
466    ///
467    /// The returned slice can be used to fill the array with data, before marking
468    /// the data as initialized using the `set_shape` method.
469    #[inline]
470    pub fn spare_capacity_mut(&mut self) -> &mut [MaybeUninit<T>] {
471        let ptr = self.as_mut_ptr();
472        let len = self.capacity() - self.len();
473
474        unsafe { slice::from_raw_parts_mut(ptr.add(self.len()).cast(), len) }
475    }
476
477    /// Shortens the array along the first dimension, keeping the first `size` indices.
478    ///
479    /// If `size` is greater or equal to the current dimension size, this has no effect.
480    ///
481    /// Note that this method has no effect on the allocated capacity of the array.
482    ///
483    /// # Panics
484    ///
485    /// Panics if the rank is not at least 1, or if the first dimension
486    /// is not dynamically-sized.
487    #[inline]
488    pub fn truncate(&mut self, size: usize) {
489        assert!(self.rank() > 0, "invalid rank");
490        assert!(S::Head::SIZE.is_none(), "first dimension not dynamically-sized");
491
492        if size < self.dim(0) {
493            unsafe {
494                self.buffer.with_mut_parts(|vec, shape| {
495                    shape.with_mut_dims(|dims| dims[0] = size);
496                    vec.truncate(shape.len());
497                });
498            }
499        }
500    }
501
502    /// Tries to reserve capacity for at least the additional number of elements in the array.
503    ///
504    /// # Errors
505    ///
506    /// If the capacity overflows, or the allocator reports a failure, then an error is returned.
507    #[inline]
508    pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
509        unsafe { self.buffer.with_mut_parts(|vec, _| vec.try_reserve(additional)) }
510    }
511
512    /// Tries to reserve the minimum capacity for the additional number of elements in the array.
513    ///
514    /// # Errors
515    ///
516    /// If the capacity overflows, or the allocator reports a failure, then an error is returned.
517    #[inline]
518    pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), TryReserveError> {
519        unsafe { self.buffer.with_mut_parts(|vec, _| vec.try_reserve_exact(additional)) }
520    }
521
522    /// Creates a new, empty array with the specified capacity and allocator.
523    #[cfg(feature = "nightly")]
524    #[inline]
525    pub fn with_capacity_in(capacity: usize, alloc: A) -> Self {
526        assert!(S::default().checked_len().is_some(), "invalid length");
527
528        let vec = Vec::with_capacity_in(capacity, alloc);
529
530        Self { buffer: unsafe { DynBuffer::from_parts(vec, S::default()) } }
531    }
532}
533
534#[cfg(not(feature = "nightly"))]
535impl<T, S: Shape> Array<T, S> {
536    /// Creates an array from the given element.
537    #[inline]
538    pub fn from_elem<I: IntoShape<IntoShape = S>>(shape: I, elem: T) -> Self
539    where
540        T: Clone,
541    {
542        Self::from_expr(expr::from_elem(shape, elem))
543    }
544
545    /// Creates an array from an expression.
546    #[inline]
547    pub fn from_expr<I: IntoExpression<Item = T, Shape = S>>(expr: I) -> Self {
548        Self::with_expr_in(expr.into_expr(), Global)
549    }
550
551    /// Creates an array with the results from the given function.
552    #[inline]
553    pub fn from_fn<I: IntoShape<IntoShape = S>, F>(shape: I, f: F) -> Self
554    where
555        F: FnMut(&[usize]) -> T,
556    {
557        Self::from_expr(expr::from_fn(shape, f))
558    }
559
560    /// Creates an array with uninitialized elements.
561    #[inline]
562    pub fn uninit<I: IntoShape<IntoShape = S>>(shape: I) -> Array<MaybeUninit<T>, S> {
563        Array { buffer: <S::Buffer<T, Global>>::uninit_in(shape.into_shape(), Global) }
564    }
565
566    /// Creates an array with elements set to zero.
567    ///
568    /// Zero elements are created using `Default::default()`.
569    #[inline]
570    pub fn zeros<I: IntoShape<IntoShape = S>>(shape: I) -> Self
571    where
572        T: Default,
573    {
574        Self::from_expr(expr::from_elem(shape, ()).map(|_| T::default()))
575    }
576
577    #[inline]
578    pub(crate) fn clone_from_slice(&mut self, slice: &Slice<T, S>)
579    where
580        T: Clone,
581    {
582        self.buffer.clone_from_slice(slice);
583    }
584}
585
586#[cfg(not(feature = "nightly"))]
587impl<T, S: Shape<Buffer<T, Global> = DynBuffer<T, S>>> Array<T, S> {
588    /// Creates an array from raw components of another array.
589    ///
590    /// # Safety
591    ///
592    /// The pointer must be a valid allocation given the shape and capacity.
593    #[inline]
594    pub unsafe fn from_raw_parts(ptr: *mut T, shape: S, capacity: usize) -> Self {
595        unsafe {
596            let vec = Vec::from_raw_parts(ptr, shape.len(), capacity);
597
598            Self { buffer: DynBuffer::from_parts(vec, shape) }
599        }
600    }
601
602    /// Decomposes an array into its raw components.
603    #[inline]
604    pub fn into_raw_parts(self) -> (*mut T, S, usize) {
605        let (vec, shape) = self.buffer.into_parts();
606        let mut vec = mem::ManuallyDrop::new(vec);
607
608        (vec.as_mut_ptr(), shape, vec.capacity())
609    }
610
611    /// Creates a new, empty array.
612    #[inline]
613    pub fn new() -> Self {
614        assert!(S::default().checked_len().is_some(), "invalid length");
615
616        Self { buffer: unsafe { DynBuffer::from_parts(Vec::new(), S::default()) } }
617    }
618
619    /// Creates a new, empty array with the specified capacity.
620    #[inline]
621    pub fn with_capacity(capacity: usize) -> Self {
622        assert!(S::default().checked_len().is_some(), "invalid length");
623
624        let vec = Vec::with_capacity(capacity);
625
626        Self { buffer: unsafe { DynBuffer::from_parts(vec, S::default()) } }
627    }
628}
629
630#[cfg(feature = "nightly")]
631impl<T, S: Shape> Array<T, S> {
632    /// Creates an array from the given element.
633    #[inline]
634    pub fn from_elem<I: IntoShape<IntoShape = S>>(shape: I, elem: T) -> Self
635    where
636        T: Clone,
637    {
638        Self::from_elem_in(shape, elem, Global)
639    }
640
641    /// Creates an array from an expression.
642    #[inline]
643    pub fn from_expr<I: IntoExpression<Item = T, Shape = S>>(expr: I) -> Self {
644        Self::from_expr_in(expr, Global)
645    }
646
647    /// Creates an array with the results from the given function.
648    #[inline]
649    pub fn from_fn<I: IntoShape<IntoShape = S>, F>(shape: I, f: F) -> Self
650    where
651        F: FnMut(&[usize]) -> T,
652    {
653        Self::from_fn_in(shape, f, Global)
654    }
655
656    /// Creates an array with uninitialized elements.
657    #[inline]
658    pub fn uninit<I: IntoShape<IntoShape = S>>(shape: I) -> Array<MaybeUninit<T>, S> {
659        Self::uninit_in(shape, Global)
660    }
661
662    /// Creates an array with elements set to zero.
663    ///
664    /// Zero elements are created using `Default::default()`.
665    #[inline]
666    pub fn zeros<I: IntoShape<IntoShape = S>>(shape: I) -> Self
667    where
668        T: Default,
669    {
670        Self::zeros_in(shape, Global)
671    }
672
673    #[inline]
674    pub(crate) fn clone_from_slice(&mut self, slice: &Slice<T, S>)
675    where
676        T: Clone,
677    {
678        self.buffer.clone_from_slice(slice);
679    }
680}
681
682#[cfg(feature = "nightly")]
683impl<T, S: Shape<Buffer<T, Global> = DynBuffer<T, S>>> Array<T, S> {
684    /// Creates an array from raw components of another array.
685    ///
686    /// # Safety
687    ///
688    /// The pointer must be a valid allocation given the shape and capacity.
689    #[inline]
690    pub unsafe fn from_raw_parts(ptr: *mut T, shape: S, capacity: usize) -> Self {
691        unsafe { Self::from_raw_parts_in(ptr, shape, capacity, Global) }
692    }
693
694    /// Decomposes an array into its raw components.
695    #[inline]
696    pub fn into_raw_parts(self) -> (*mut T, S, usize) {
697        let (ptr, shape, capacity, _) = self.into_raw_parts_with_alloc();
698
699        (ptr, shape, capacity)
700    }
701
702    /// Creates a new, empty array.
703    #[inline]
704    pub fn new() -> Self {
705        Self::new_in(Global)
706    }
707
708    /// Creates a new, empty array with the specified capacity.
709    #[inline]
710    pub fn with_capacity(capacity: usize) -> Self {
711        Self::with_capacity_in(capacity, Global)
712    }
713}
714
715impl<T, S: ConstShape> Array<T, S> {
716    /// Creates an array from the given value with constant-sized dimensions.
717    #[inline]
718    pub fn fill(value: T) -> Self
719    where
720        T: Clone,
721    {
722        Self::with_expr_in(expr::from_elem(S::default(), value), Global)
723    }
724
725    /// Creates an array with the results from the given function and constant-sized dimensions.
726    #[inline]
727    pub fn fill_with<F: FnMut() -> T>(mut f: F) -> Self {
728        Self::with_expr_in(expr::from_elem(S::default(), ()).map(|_| f()), Global)
729    }
730}
731
732impl<T, S: Shape, A: Allocator> Array<MaybeUninit<T>, S, A> {
733    /// Converts the array element type from `MaybeUninit<T>` to `T`.
734    ///
735    /// # Safety
736    ///
737    /// All elements in the array must be initialized, or the behavior is undefined.
738    #[inline]
739    pub unsafe fn assume_init(self) -> Array<T, S, A> {
740        Array { buffer: unsafe { self.buffer.cast() } }
741    }
742}
743
744impl<'a, T, U, S: Shape, A: Allocator> Apply<U> for &'a Array<T, S, A> {
745    type Output<F: FnMut(&'a T) -> U> = Map<Self::IntoExpr, F>;
746    type ZippedWith<I: IntoExpression, F: FnMut((&'a T, I::Item)) -> U> =
747        Map<Zip<Self::IntoExpr, I::IntoExpr>, F>;
748
749    #[inline]
750    fn apply<F: FnMut(&'a T) -> U>(self, f: F) -> Self::Output<F> {
751        self.expr().map(f)
752    }
753
754    #[inline]
755    fn zip_with<I: IntoExpression, F>(self, expr: I, f: F) -> Self::ZippedWith<I, F>
756    where
757        F: FnMut((&'a T, I::Item)) -> U,
758    {
759        self.expr().zip(expr).map(f)
760    }
761}
762
763impl<'a, T, U, S: Shape, A: Allocator> Apply<U> for &'a mut Array<T, S, A> {
764    type Output<F: FnMut(&'a mut T) -> U> = Map<Self::IntoExpr, F>;
765    type ZippedWith<I: IntoExpression, F: FnMut((&'a mut T, I::Item)) -> U> =
766        Map<Zip<Self::IntoExpr, I::IntoExpr>, F>;
767
768    #[inline]
769    fn apply<F: FnMut(&'a mut T) -> U>(self, f: F) -> Self::Output<F> {
770        self.expr_mut().map(f)
771    }
772
773    #[inline]
774    fn zip_with<I: IntoExpression, F>(self, expr: I, f: F) -> Self::ZippedWith<I, F>
775    where
776        F: FnMut((&'a mut T, I::Item)) -> U,
777    {
778        self.expr_mut().zip(expr).map(f)
779    }
780}
781
782impl<T, U, S: Shape, A: Allocator> Apply<U> for Array<T, S, A> {
783    type Output<F: FnMut(T) -> U> = Array<U, S, A>;
784    type ZippedWith<I: IntoExpression, F: FnMut((T, I::Item)) -> U> = Array<U, S, A>;
785
786    #[inline]
787    fn apply<F: FnMut(T) -> U>(self, f: F) -> Array<U, S, A> {
788        self.map(f)
789    }
790
791    #[inline]
792    fn zip_with<I: IntoExpression, F>(self, expr: I, f: F) -> Array<U, S, A>
793    where
794        F: FnMut((T, I::Item)) -> U,
795    {
796        Array { buffer: self.buffer.zip_with(expr.into_expr(), f) }
797    }
798}
799
800impl<T, U: ?Sized, S: Shape, A: Allocator> AsMut<U> for Array<T, S, A>
801where
802    Slice<T, S>: AsMut<U>,
803{
804    #[inline]
805    fn as_mut(&mut self) -> &mut U {
806        (**self).as_mut()
807    }
808}
809
810impl<T, U: ?Sized, S: Shape, A: Allocator> AsRef<U> for Array<T, S, A>
811where
812    Slice<T, S>: AsRef<U>,
813{
814    #[inline]
815    fn as_ref(&self) -> &U {
816        (**self).as_ref()
817    }
818}
819
820//
821// The below implementations assume that casting a pointer from a primitive array to an
822// Array is possible. This is ensured by the representations of Array and StaticBuffer.
823//
824
825macro_rules! impl_as_mut_ref {
826    (($($xyz:tt),+), $array:tt) => {
827        impl<T, $(const $xyz: usize),+> AsMut<Array<T, ($(Const<$xyz>,)+)>> for $array {
828            #[inline]
829            fn as_mut(&mut self) -> &mut Array<T, ($(Const<$xyz>,)+)> {
830                unsafe { &mut *(self as *mut Self as *mut Array<T, ($(Const<$xyz>,)+)>) }
831            }
832        }
833
834        impl<T, $(const $xyz: usize),+> AsRef<Array<T, ($(Const<$xyz>,)+)>> for $array {
835            #[inline]
836            fn as_ref(&self) -> &Array<T, ($(Const<$xyz>,)+)> {
837                unsafe { &*(self as *const Self as *const Array<T, ($(Const<$xyz>,)+)>) }
838            }
839        }
840    };
841}
842
843impl_as_mut_ref!((X), [T; X]);
844impl_as_mut_ref!((X, Y), [[T; Y]; X]);
845impl_as_mut_ref!((X, Y, Z), [[[T; Z]; Y]; X]);
846impl_as_mut_ref!((X, Y, Z, W), [[[[T; W]; Z]; Y]; X]);
847impl_as_mut_ref!((X, Y, Z, W, U), [[[[[T; U]; W]; Z]; Y]; X]);
848impl_as_mut_ref!((X, Y, Z, W, U, V), [[[[[[T; V]; U]; W]; Z]; Y]; X]);
849
850impl<T, S: Shape, A: Allocator> Borrow<Slice<T, S>> for Array<T, S, A> {
851    #[inline]
852    fn borrow(&self) -> &Slice<T, S> {
853        self
854    }
855}
856
857impl<T, S: Shape, A: Allocator> BorrowMut<Slice<T, S>> for Array<T, S, A> {
858    #[inline]
859    fn borrow_mut(&mut self) -> &mut Slice<T, S> {
860        self
861    }
862}
863
864impl<T: Clone, S: Shape, A: Allocator + Clone> Clone for Array<T, S, A> {
865    #[inline]
866    fn clone(&self) -> Self {
867        Array { buffer: self.buffer.clone() }
868    }
869
870    #[inline]
871    fn clone_from(&mut self, source: &Self) {
872        self.buffer.clone_from(&source.buffer);
873    }
874}
875
876impl<T: Copy, S: Shape<Buffer<T, A>: Copy>, A: Allocator + Copy> Copy for Array<T, S, A> {}
877
878impl<T: Debug, S: Shape, A: Allocator> Debug for Array<T, S, A> {
879    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
880        (**self).fmt(f)
881    }
882}
883
884impl<T: Default, S: Shape> Default for Array<T, S> {
885    #[inline]
886    fn default() -> Self {
887        Self::zeros(S::default())
888    }
889}
890
891impl<T, S: Shape, A: Allocator> Deref for Array<T, S, A> {
892    type Target = Slice<T, S>;
893
894    #[inline]
895    fn deref(&self) -> &Self::Target {
896        self.buffer.as_slice()
897    }
898}
899
900impl<T, S: Shape, A: Allocator> DerefMut for Array<T, S, A> {
901    #[inline]
902    fn deref_mut(&mut self) -> &mut Self::Target {
903        self.buffer.as_mut_slice()
904    }
905}
906
907impl<T, U: IntoCloned<T>, S: Shape<Buffer<T, A> = DynBuffer<T, S, A>>, A: Allocator> Expand<U>
908    for Array<T, S, A>
909{
910    #[inline]
911    fn expand<I: IntoExpression<Item = U>>(&mut self, expr: I) {
912        self.expand(expr);
913    }
914}
915
916impl<'a, T: Clone, A: Allocator> Extend<&'a T> for Array<T, (Dyn,), A> {
917    #[inline]
918    fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
919        self.extend(iter.into_iter().cloned());
920    }
921}
922
923impl<T, A: Allocator> Extend<T> for Array<T, (Dyn,), A> {
924    #[inline]
925    fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
926        unsafe {
927            self.buffer.with_mut_parts(|vec, shape| {
928                vec.extend(iter);
929                *shape = (vec.len(),);
930            });
931        }
932    }
933}
934
935impl<T: Clone> From<&[T]> for Array<T, (Dyn,)> {
936    #[inline]
937    fn from(value: &[T]) -> Self {
938        Self::from(value.to_vec())
939    }
940}
941
942impl<'a, T: 'a + Clone, S: Shape, L: Layout, I: IntoExpression<IntoExpr = View<'a, T, S, L>>>
943    From<I> for Array<T, S>
944{
945    #[inline]
946    fn from(value: I) -> Self {
947        Self::from_expr(value.into_expr().cloned())
948    }
949}
950
951impl<T, D: Dim, A: Allocator> From<Array<T, (D,), A>> for vec_t!(T, A) {
952    #[inline]
953    fn from(value: Array<T, (D,), A>) -> Self {
954        value.into_vec()
955    }
956}
957
958#[cfg(not(feature = "nightly"))]
959impl<T> From<Vec<T>> for Array<T, (Dyn,)> {
960    #[inline]
961    fn from(value: Vec<T>) -> Self {
962        let shape = (value.len(),);
963
964        Self { buffer: unsafe { DynBuffer::from_parts(value, shape) } }
965    }
966}
967
968#[cfg(feature = "nightly")]
969impl<T, A: Allocator> From<Vec<T, A>> for Array<T, (Dyn,), A> {
970    #[inline]
971    fn from(value: Vec<T, A>) -> Self {
972        let shape = (value.len(),);
973
974        Self { buffer: unsafe { DynBuffer::from_parts(value, shape) } }
975    }
976}
977
978macro_rules! impl_from_array {
979    (($($xyz:tt),+), ($($abc:tt),+), $array:tt) => {
980        impl<T: Clone $(,$xyz: Dim + From<Const<$abc>>)+ $(,const $abc: usize)+> From<&$array>
981            for Array<T, ($($xyz,)+)>
982        {
983            #[inline]
984            fn from(value: &$array) -> Self {
985                Self::from_expr(View::from(value).cloned())
986            }
987        }
988
989        impl<T $(,const $abc: usize)+> From<Array<T, ($(Const<$abc>,)+)>> for $array {
990            #[inline]
991            fn from(value: Array<T, ($(Const<$abc>,)+)>) -> Self {
992                unsafe { mem::transmute_copy(&ManuallyDrop::new(value)) }
993            }
994        }
995
996        impl<T $(,$xyz: Dim + From<Const<$abc>>)+ $(,const $abc: usize)+> From<$array>
997            for Array<T, ($($xyz,)+)>
998        {
999            #[inline]
1000            fn from(value: $array) -> Self {
1001                let array: Array<T, ($(Const<$abc>,)+)> =
1002                    unsafe { mem::transmute_copy(&ManuallyDrop::new(value)) };
1003
1004                array.into_buffer()
1005            }
1006        }
1007    };
1008}
1009
1010impl_from_array!((X), (A), [T; A]);
1011impl_from_array!((X, Y), (A, B), [[T; B]; A]);
1012impl_from_array!((X, Y, Z), (A, B, C), [[[T; C]; B]; A]);
1013impl_from_array!((X, Y, Z, W), (A, B, C, D), [[[[T; D]; C]; B]; A]);
1014impl_from_array!((X, Y, Z, W, U), (A, B, C, D, E), [[[[[T; E]; D]; C]; B]; A]);
1015impl_from_array!((X, Y, Z, W, U, V), (A, B, C, D, E, F), [[[[[[T; F]; E]; D]; C]; B]; A]);
1016
1017impl<T, S: Shape> FromExpression<T, S> for Array<T, S> {
1018    #[cfg(not(feature = "nightly"))]
1019    #[inline]
1020    fn from_expr<I: IntoExpression<Item = T, Shape = S>>(expr: I) -> Self {
1021        Self::from_expr(expr.into_expr())
1022    }
1023
1024    #[cfg(feature = "nightly")]
1025    #[inline]
1026    fn from_expr<I: IntoExpression<Item = T, Shape = S>>(expr: I) -> Self {
1027        Self::from_expr_in(expr.into_expr(), Global)
1028    }
1029}
1030
1031impl<T> FromIterator<T> for Array<T, (Dyn,)> {
1032    #[inline]
1033    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
1034        Self::from(Vec::from_iter(iter))
1035    }
1036}
1037
1038impl<T: Hash, S: Shape, A: Allocator> Hash for Array<T, S, A> {
1039    #[inline]
1040    fn hash<H: Hasher>(&self, state: &mut H) {
1041        (**self).hash(state)
1042    }
1043}
1044
1045impl<T, S: Shape, A: Allocator, I: SliceIndex<T, S, Dense>> Index<I> for Array<T, S, A> {
1046    type Output = I::Output;
1047
1048    #[inline]
1049    fn index(&self, index: I) -> &I::Output {
1050        index.index(self)
1051    }
1052}
1053
1054impl<T, S: Shape, A: Allocator, I: SliceIndex<T, S, Dense>> IndexMut<I> for Array<T, S, A> {
1055    #[inline]
1056    fn index_mut(&mut self, index: I) -> &mut I::Output {
1057        index.index_mut(self)
1058    }
1059}
1060
1061impl<'a, T, S: Shape, A: Allocator> IntoExpression for &'a Array<T, S, A> {
1062    type Shape = S;
1063    type IntoExpr = View<'a, T, S>;
1064
1065    #[inline]
1066    fn into_expr(self) -> Self::IntoExpr {
1067        self.expr()
1068    }
1069}
1070
1071impl<'a, T, S: Shape, A: Allocator> IntoExpression for &'a mut Array<T, S, A> {
1072    type Shape = S;
1073    type IntoExpr = ViewMut<'a, T, S>;
1074
1075    #[inline]
1076    fn into_expr(self) -> Self::IntoExpr {
1077        self.expr_mut()
1078    }
1079}
1080
1081impl<T, S: Shape, A: Allocator> IntoExpression for Array<T, S, A> {
1082    type Shape = S;
1083    type IntoExpr = IntoExpr<T, S::Buffer<ManuallyDrop<T>, A>>;
1084
1085    #[inline]
1086    fn into_expr(self) -> Self::IntoExpr {
1087        unsafe { IntoExpr::new(self.buffer.cast()) }
1088    }
1089}
1090
1091impl<'a, T, S: Shape, A: Allocator> IntoIterator for &'a Array<T, S, A> {
1092    type Item = &'a T;
1093    type IntoIter = Iter<View<'a, T, S>>;
1094
1095    #[inline]
1096    fn into_iter(self) -> Self::IntoIter {
1097        self.iter()
1098    }
1099}
1100
1101impl<'a, T, S: Shape, A: Allocator> IntoIterator for &'a mut Array<T, S, A> {
1102    type Item = &'a mut T;
1103    type IntoIter = Iter<ViewMut<'a, T, S>>;
1104
1105    #[inline]
1106    fn into_iter(self) -> Self::IntoIter {
1107        self.iter_mut()
1108    }
1109}
1110
1111impl<T, S: Shape, A: Allocator> IntoIterator for Array<T, S, A> {
1112    type Item = T;
1113    type IntoIter = Iter<IntoExpr<T, S::Buffer<ManuallyDrop<T>, A>>>;
1114
1115    #[inline]
1116    fn into_iter(self) -> Self::IntoIter {
1117        self.into_expr().into_iter()
1118    }
1119}