9
9
use alloc:: vec;
10
10
#[ cfg( not( feature = "std" ) ) ]
11
11
use alloc:: vec:: Vec ;
12
+ #[ allow( unused_imports) ]
13
+ use std:: compile_error;
12
14
use std:: mem:: { forget, size_of} ;
13
15
use std:: ptr:: NonNull ;
14
16
15
17
use crate :: imp_prelude:: * ;
16
18
use crate :: { dimension, ArcArray1 , ArcArray2 } ;
17
19
18
- /// Create an **[`Array`]** with one, two or
19
- /// three dimensions.
20
+ /// Create an **[`Array`]** with one, two, three, four, five, or six dimensions.
20
21
///
21
22
/// ```
22
23
/// use ndarray::array;
@@ -28,17 +29,49 @@ use crate::{dimension, ArcArray1, ArcArray2};
28
29
/// let a3 = array![[[1, 2], [3, 4]],
29
30
/// [[5, 6], [7, 8]]];
30
31
///
32
+ /// let a4 = array![[[[1, 2, 3, 4]]]];
33
+ ///
34
+ /// let a5 = array![[[[[1, 2, 3, 4, 5]]]]];
35
+ ///
36
+ /// let a6 = array![[[[[[1, 2, 3, 4, 5, 6]]]]]];
37
+ ///
31
38
/// assert_eq!(a1.shape(), &[4]);
32
39
/// assert_eq!(a2.shape(), &[2, 2]);
33
40
/// assert_eq!(a3.shape(), &[2, 2, 2]);
41
+ /// assert_eq!(a4.shape(), &[1, 1, 1, 4]);
42
+ /// assert_eq!(a5.shape(), &[1, 1, 1, 1, 5]);
43
+ /// assert_eq!(a6.shape(), &[1, 1, 1, 1, 1, 6]);
34
44
/// ```
35
45
///
36
46
/// This macro uses `vec![]`, and has the same ownership semantics;
37
47
/// elements are moved into the resulting `Array`.
38
48
///
39
49
/// Use `array![...].into_shared()` to create an `ArcArray`.
50
+ ///
51
+ /// Attempts to crate 7D+ arrays with this macro will lead to
52
+ /// a compiler error, since the difference between a 7D array
53
+ /// of i32 and a 6D array of `[i32; 3]` is ambiguous. Higher-dim
54
+ /// arrays can be created with [`ArrayD`].
55
+ ///
56
+ /// ```compile_fail
57
+ /// use ndarray::array;
58
+ /// let a7 = array![[[[[[[1, 2, 3]]]]]]];
59
+ /// // error: Arrays of 7 dimensions or more (or ndarrays of Rust arrays) cannot be constructed with the array! macro.
60
+ /// ```
40
61
#[ macro_export]
41
62
macro_rules! array {
63
+ ( $( [ $( [ $( [ $( [ $( [ $( [ $( $x: expr) ,* $( , ) * ] ) ,+ $( , ) * ] ) ,+ $( , ) * ] ) ,+ $( , ) * ] ) ,+ $( , ) * ] ) ,+ $( , ) * ] ) ,+ $( , ) * ) => { {
64
+ compile_error!( "Arrays of 7 dimensions or more (or ndarrays of Rust arrays) cannot be constructed with the array! macro." ) ;
65
+ } } ;
66
+ ( $( [ $( [ $( [ $( [ $( [ $( $x: expr) ,* $( , ) * ] ) ,+ $( , ) * ] ) ,+ $( , ) * ] ) ,+ $( , ) * ] ) ,+ $( , ) * ] ) ,+ $( , ) * ) => { {
67
+ $crate:: Array6 :: from( vec![ $( [ $( [ $( [ $( [ $( [ $( $x, ) * ] , ) * ] , ) * ] , ) * ] , ) * ] , ) * ] )
68
+ } } ;
69
+ ( $( [ $( [ $( [ $( [ $( $x: expr) ,* $( , ) * ] ) ,+ $( , ) * ] ) ,+ $( , ) * ] ) ,+ $( , ) * ] ) ,+ $( , ) * ) => { {
70
+ $crate:: Array5 :: from( vec![ $( [ $( [ $( [ $( [ $( $x, ) * ] , ) * ] , ) * ] , ) * ] , ) * ] )
71
+ } } ;
72
+ ( $( [ $( [ $( [ $( $x: expr) ,* $( , ) * ] ) ,+ $( , ) * ] ) ,+ $( , ) * ] ) ,+ $( , ) * ) => { {
73
+ $crate:: Array4 :: from( vec![ $( [ $( [ $( [ $( $x, ) * ] , ) * ] , ) * ] , ) * ] )
74
+ } } ;
42
75
( $( [ $( [ $( $x: expr) ,* $( , ) * ] ) ,+ $( , ) * ] ) ,+ $( , ) * ) => { {
43
76
$crate:: Array3 :: from( vec![ $( [ $( [ $( $x, ) * ] , ) * ] , ) * ] )
44
77
} } ;
@@ -233,63 +266,39 @@ pub fn arr2<A: Clone, const N: usize>(xs: &[[A; N]]) -> Array2<A>
233
266
Array2 :: from ( xs. to_vec ( ) )
234
267
}
235
268
236
- impl < A , const N : usize > From < Vec < [ A ; N ] > > for Array2 < A >
237
- {
238
- /// Converts the `Vec` of arrays to an owned 2-D array.
239
- ///
240
- /// **Panics** if the product of non-zero axis lengths overflows `isize`.
241
- fn from ( mut xs : Vec < [ A ; N ] > ) -> Self
242
- {
243
- let dim = Ix2 ( xs. len ( ) , N ) ;
244
- let ptr = xs. as_mut_ptr ( ) ;
245
- let cap = xs. capacity ( ) ;
246
- let expand_len =
247
- dimension:: size_of_shape_checked ( & dim) . expect ( "Product of non-zero axis lengths must not overflow isize." ) ;
248
- forget ( xs) ;
249
- unsafe {
250
- let v = if size_of :: < A > ( ) == 0 {
251
- Vec :: from_raw_parts ( ptr as * mut A , expand_len, expand_len)
252
- } else if N == 0 {
253
- Vec :: new ( )
254
- } else {
255
- // Guaranteed not to overflow in this case since A is non-ZST
256
- // and Vec never allocates more than isize bytes.
257
- let expand_cap = cap * N ;
258
- Vec :: from_raw_parts ( ptr as * mut A , expand_len, expand_cap)
259
- } ;
260
- ArrayBase :: from_shape_vec_unchecked ( dim, v)
269
+ macro_rules! impl_from_nested_vec {
270
+ ( $arr_type: ty, $ix_type: tt, $( $n: ident) ,+) => {
271
+ impl <A , $( const $n: usize ) ,+> From <Vec <$arr_type>> for Array <A , $ix_type>
272
+ {
273
+ fn from( mut xs: Vec <$arr_type>) -> Self
274
+ {
275
+ let dim = $ix_type( xs. len( ) , $( $n) ,+) ;
276
+ let ptr = xs. as_mut_ptr( ) ;
277
+ let cap = xs. capacity( ) ;
278
+ let expand_len = dimension:: size_of_shape_checked( & dim)
279
+ . expect( "Product of non-zero axis lengths must not overflow isize." ) ;
280
+ forget( xs) ;
281
+ unsafe {
282
+ let v = if size_of:: <A >( ) == 0 {
283
+ Vec :: from_raw_parts( ptr as * mut A , expand_len, expand_len)
284
+ } else if $( $n == 0 ||) + false {
285
+ Vec :: new( )
286
+ } else {
287
+ let expand_cap = cap $( * $n) +;
288
+ Vec :: from_raw_parts( ptr as * mut A , expand_len, expand_cap)
289
+ } ;
290
+ ArrayBase :: from_shape_vec_unchecked( dim, v)
291
+ }
292
+ }
261
293
}
262
- }
294
+ } ;
263
295
}
264
296
265
- impl < A , const N : usize , const M : usize > From < Vec < [ [ A ; M ] ; N ] > > for Array3 < A >
266
- {
267
- /// Converts the `Vec` of arrays to an owned 3-D array.
268
- ///
269
- /// **Panics** if the product of non-zero axis lengths overflows `isize`.
270
- fn from ( mut xs : Vec < [ [ A ; M ] ; N ] > ) -> Self
271
- {
272
- let dim = Ix3 ( xs. len ( ) , N , M ) ;
273
- let ptr = xs. as_mut_ptr ( ) ;
274
- let cap = xs. capacity ( ) ;
275
- let expand_len =
276
- dimension:: size_of_shape_checked ( & dim) . expect ( "Product of non-zero axis lengths must not overflow isize." ) ;
277
- forget ( xs) ;
278
- unsafe {
279
- let v = if size_of :: < A > ( ) == 0 {
280
- Vec :: from_raw_parts ( ptr as * mut A , expand_len, expand_len)
281
- } else if N == 0 || M == 0 {
282
- Vec :: new ( )
283
- } else {
284
- // Guaranteed not to overflow in this case since A is non-ZST
285
- // and Vec never allocates more than isize bytes.
286
- let expand_cap = cap * N * M ;
287
- Vec :: from_raw_parts ( ptr as * mut A , expand_len, expand_cap)
288
- } ;
289
- ArrayBase :: from_shape_vec_unchecked ( dim, v)
290
- }
291
- }
292
- }
297
+ impl_from_nested_vec ! ( [ A ; N ] , Ix2 , N ) ;
298
+ impl_from_nested_vec ! ( [ [ A ; M ] ; N ] , Ix3 , N , M ) ;
299
+ impl_from_nested_vec ! ( [ [ [ A ; L ] ; M ] ; N ] , Ix4 , N , M , L ) ;
300
+ impl_from_nested_vec ! ( [ [ [ [ A ; K ] ; L ] ; M ] ; N ] , Ix5 , N , M , L , K ) ;
301
+ impl_from_nested_vec ! ( [ [ [ [ [ A ; J ] ; K ] ; L ] ; M ] ; N ] , Ix6 , N , M , L , K , J ) ;
293
302
294
303
/// Create a two-dimensional array with elements from `xs`.
295
304
///
0 commit comments