1+ use std:: ops:: { Index , IndexMut } ;
12use std:: slice;
23use std:: vec;
34
45use Dimension ;
56
7+ /// A multi-dimensional array.
68#[ derive( Debug , PartialEq , Eq , Clone ) ]
79pub struct Array < T > {
810 dims : Vec < Dimension > ,
911 data : Vec < T > ,
1012}
1113
1214impl < T > Array < T > {
15+ /// Creates a new `Array` from its underlying components.
16+ ///
17+ /// The data array should be provided in the higher-dimensional equivalent
18+ /// of row-major order.
19+ ///
20+ /// # Panics
21+ ///
22+ /// Panics if the number of elements provided does not match the number of
23+ /// elements specified by the dimensions.
1324 pub fn from_parts ( data : Vec < T > , dimensions : Vec < Dimension > ) -> Array < T > {
1425 assert ! ( ( data. is_empty( ) && dimensions. is_empty( ) ) ||
1526 data. len( ) == dimensions. iter( ) . fold( 1 , |acc, i| acc * i. len) ,
@@ -20,6 +31,7 @@ impl<T> Array<T> {
2031 }
2132 }
2233
34+ /// Creates a new one-dimensional array.
2335 pub fn from_vec ( data : Vec < T > , lower_bound : isize ) -> Array < T > {
2436 Array {
2537 dims : vec ! [ Dimension {
@@ -30,13 +42,30 @@ impl<T> Array<T> {
3042 }
3143 }
3244
45+ /// Wraps this array in a new dimension of size 1.
46+ ///
47+ /// For example, the one dimensional array `[1, 2]` would turn into the
48+ /// two-dimensional array `[[1, 2]]`.
3349 pub fn wrap ( & mut self , lower_bound : isize ) {
3450 self . dims . insert ( 0 , Dimension {
3551 len : 1 ,
3652 lower_bound : lower_bound,
3753 } ) ;
3854 }
3955
56+ /// Consumes another array, appending it to the top level dimension of this
57+ /// array.
58+ ///
59+ /// The dimensions of the other array must be the same as the dimensions
60+ /// of this array with the first dimension removed. This includes lower
61+ /// bounds as well as lengths.
62+ ///
63+ /// For example, if `[3, 4]` is pushed onto `[[1, 2]]`, the result is
64+ /// `[[1, 2], [3, 4]]`.
65+ ///
66+ /// # Panics
67+ ///
68+ /// Panics if the dimensions of the two arrays do not match.
4069 pub fn push ( & mut self , other : Array < T > ) {
4170 assert ! ( self . dims. len( ) - 1 == other. dims. len( ) ,
4271 "cannot append differently shaped arrays" ) ;
@@ -47,20 +76,11 @@ impl<T> Array<T> {
4776 self . data . extend ( other. data ) ;
4877 }
4978
79+ /// Returns the dimensions of this array.
5080 pub fn dimensions ( & self ) -> & [ Dimension ] {
5181 & self . dims
5282 }
5383
54- pub fn get ( & self , indices : & [ isize ] ) -> & T {
55- let idx = self . shift_idx ( indices) ;
56- & self . data [ idx]
57- }
58-
59- pub fn get_mut ( & mut self , indices : & [ isize ] ) -> & mut T {
60- let idx = self . shift_idx ( indices) ;
61- & mut self . data [ idx]
62- }
63-
6484 fn shift_idx ( & self , indices : & [ isize ] ) -> usize {
6585 assert_eq ! ( self . dims. len( ) , indices. len( ) ) ;
6686 self . dims
@@ -86,6 +106,61 @@ impl<T> Array<T> {
86106 }
87107}
88108
109+ pub trait ArrayIndex {
110+ fn index < T > ( & self , array : & Array < T > ) -> usize ;
111+ }
112+
113+ impl < ' a > ArrayIndex for & ' a [ isize ] {
114+ fn index < T > ( & self , array : & Array < T > ) -> usize {
115+ array. shift_idx ( * self )
116+ }
117+ }
118+
119+ impl ArrayIndex for isize {
120+ fn index < T > ( & self , array : & Array < T > ) -> usize {
121+ let slice: & [ isize ] = & [ * self ] ;
122+ ArrayIndex :: index ( & slice, array)
123+ }
124+ }
125+
126+ macro_rules! tuple_impl {
127+ ( $( $name: ident : $t: ty) ,+) => {
128+ impl ArrayIndex for ( $( $t, ) +) {
129+ fn index<T >( & self , array: & Array <T >) -> usize {
130+ let ( $( $name, ) +) = * self ;
131+ let slice: & [ isize ] = & [ $( $name) ,+] ;
132+ ArrayIndex :: index( & slice, array)
133+ }
134+ }
135+ }
136+ }
137+
138+ tuple_impl ! ( a: isize ) ;
139+ tuple_impl ! ( a: isize , b: isize ) ;
140+ tuple_impl ! ( a: isize , b: isize , c: isize ) ;
141+ tuple_impl ! ( a: isize , b: isize , c: isize , d: isize ) ;
142+ tuple_impl ! ( a: isize , b: isize , c: isize , d: isize , e: isize ) ;
143+ tuple_impl ! ( a: isize , b: isize , c: isize , d: isize , e: isize , f: isize ) ;
144+ tuple_impl ! ( a: isize , b: isize , c: isize , d: isize , e: isize , f: isize , g: isize ) ;
145+ tuple_impl ! ( a: isize , b: isize , c: isize , d: isize , e: isize , f: isize , g: isize , h: isize ) ;
146+ tuple_impl ! ( a: isize , b: isize , c: isize , d: isize , e: isize , f: isize , g: isize , h: isize , i: isize ) ;
147+
148+ impl < T , I : ArrayIndex > Index < I > for Array < T > {
149+ type Output = T ;
150+
151+ fn index ( & self , idx : I ) -> & T {
152+ let idx = idx. index ( self ) ;
153+ & self . data [ idx]
154+ }
155+ }
156+
157+ impl < T , I : ArrayIndex > IndexMut < I > for Array < T > {
158+ fn index_mut ( & mut self , idx : I ) -> & mut T {
159+ let idx = idx. index ( self ) ;
160+ & mut self . data [ idx]
161+ }
162+ }
163+
89164impl < ' a , T : ' a > IntoIterator for & ' a Array < T > {
90165 type Item = & ' a T ;
91166 type IntoIter = Iter < ' a , T > ;
0 commit comments