33use std:: cast;
44use std:: vec:: VecIterator ;
55
6+ /// Information about a dimension of an array
67#[ deriving( Eq , Clone ) ]
78pub struct DimensionInfo {
9+ /// The size of the dimension
810 len : uint ,
11+ /// The index of the first element of the dimension
912 lower_bound : int ,
1013}
1114
15+ /// Specifies methods that can be performed on multi-dimensional arrays
1216pub trait Array < T > {
17+ /// Returns information about the dimensions of this array
1318 fn get_dimension_info < ' a > ( & ' a self ) -> & ' a [ DimensionInfo ] ;
19+
20+ /// Slices into this array, returning an immutable view of a subarray.
21+ ///
22+ /// # Failure
23+ ///
24+ /// Fails if the array is one-dimensional or the index is out of bounds.
1425 fn slice < ' a > ( & ' a self , idx : int ) -> ArraySlice < ' a , T > ;
26+
27+ /// Retrieves an immutable reference to a value in this array.
28+ ///
29+ ///
30+ /// # Failure
31+ ///
32+ /// Fails if the array is multi-dimensional or the index is out of bounds.
1533 fn get < ' a > ( & ' a self , idx : int ) -> & ' a T ;
1634}
1735
36+ /// Specifies methods that can be performed on mutable multi-dimensional arrays
1837pub trait MutableArray < T > : Array < T > {
38+ /// Slices into this array, returning a mutable view of a subarray.
39+ ///
40+ /// # Failure
41+ ///
42+ /// Fails if the array is one-dimensional or the index is out of bounds.
1943 fn slice_mut < ' a > ( & ' a mut self , idx : int ) -> MutArraySlice < ' a , T > {
2044 MutArraySlice { slice : self . slice ( idx) }
2145 }
2246
47+ /// Retrieves a mutable reference to a value in this array.
48+ ///
49+ ///
50+ /// # Failure
51+ ///
52+ /// Fails if the array is multi-dimensional or the index is out of bounds.
2353 fn get_mut < ' a > ( & ' a mut self , idx : int ) -> & ' a mut T {
2454 unsafe { cast:: transmute_mut ( self . get ( idx) ) }
2555 }
@@ -28,20 +58,32 @@ pub trait MutableArray<T> : Array<T> {
2858trait InternalArray < T > : Array < T > {
2959 fn shift_idx ( & self , idx : int ) -> uint {
3060 let shifted_idx = idx - self . get_dimension_info ( ) [ 0 ] . lower_bound ;
31- assert ! ( shifted_idx >= 0 , "Out of bounds array access" ) ;
61+ assert ! ( shifted_idx >= 0 &&
62+ shifted_idx < self . get_dimension_info( ) [ 0 ] . len as int,
63+ "Out of bounds array access" ) ;
3264 shifted_idx as uint
3365 }
3466
3567 fn raw_get < ' a > ( & ' a self , idx : uint , size : uint ) -> & ' a T ;
3668}
3769
70+ /// A multi-dimensional array
3871#[ deriving( Eq , Clone ) ]
3972pub struct ArrayBase < T > {
4073 priv info : ~[ DimensionInfo ] ,
4174 priv data : ~[ T ] ,
4275}
4376
4477impl < T > ArrayBase < T > {
78+ /// Creates a new multi-dimensional array from its underlying components.
79+ ///
80+ /// The data array should be provided in the higher-dimensional equivalent
81+ /// of row-major order.
82+ ///
83+ /// # Failure
84+ ///
85+ /// Fails if there are 0 dimensions or the number of elements provided does
86+ /// not match the number of elements specified.
4587 pub fn from_raw ( data : ~[ T ] , info : ~[ DimensionInfo ] )
4688 -> ArrayBase < T > {
4789 assert ! ( !info. is_empty( ) , "Cannot create a 0x0 array" ) ;
@@ -53,6 +95,7 @@ impl<T> ArrayBase<T> {
5395 }
5496 }
5597
98+ /// Creates a new one-dimensional array from a vector.
5699 pub fn from_vec ( data : ~[ T ] , lower_bound : int ) -> ArrayBase < T > {
57100 ArrayBase {
58101 info : ~[ DimensionInfo {
@@ -63,13 +106,31 @@ impl<T> ArrayBase<T> {
63106 }
64107 }
65108
109+ /// Wraps this array in a new dimension of size 1.
110+ ///
111+ /// For example the one-dimensional array `[1,2]` would turn into
112+ /// the two-dimensional array `[[1,2]]`.
66113 pub fn wrap ( & mut self , lower_bound : int ) {
67114 self . info . unshift ( DimensionInfo {
68115 len : 1 ,
69116 lower_bound : lower_bound
70117 } )
71118 }
72119
120+ /// Takes ownership of another array, appending it to the top-level
121+ /// dimension of this array.
122+ ///
123+ /// The dimensions of the other array must have an identical shape to the
124+ /// dimensions of a slice of this array. This includes both the sizes of
125+ /// the dimensions as well as their lower bounds.
126+ ///
127+ /// For example, if `[3,4]` is pushed onto `[[1,2]]`, the result is
128+ /// `[[1,2],[3,4]]`.
129+ ///
130+ /// # Failure
131+ ///
132+ /// Fails if the other array does not have dimensions identical to the
133+ /// dimensions of a slice of this array.
73134 pub fn push_move ( & mut self , other : ArrayBase < T > ) {
74135 assert ! ( self . info. len( ) - 1 == other. info. len( ) ,
75136 "Cannot append differently shaped arrays" ) ;
@@ -80,6 +141,8 @@ impl<T> ArrayBase<T> {
80141 self . data . push_all_move ( other. data ) ;
81142 }
82143
144+ /// Returns an iterator over the values in this array, in the
145+ /// higher-dimensional equivalent of row-major order.
83146 pub fn values < ' a > ( & ' a self ) -> VecIterator < ' a , T > {
84147 self . data . iter ( )
85148 }
@@ -119,6 +182,7 @@ enum ArrayParent<'parent, T> {
119182 BaseParent ( & ' parent ArrayBase < T > ) ,
120183}
121184
185+ /// An immutable slice of a multi-dimensional array
122186pub struct ArraySlice < ' parent , T > {
123187 priv parent : ArrayParent < ' parent , T > ,
124188 priv idx: uint ,
@@ -160,6 +224,7 @@ impl<'parent, T> InternalArray<T> for ArraySlice<'parent, T> {
160224 }
161225}
162226
227+ /// A mutable slice of a multi-dimensional array
163228pub struct MutArraySlice < ' parent , T > {
164229 priv slice : ArraySlice < ' parent , T >
165230}
@@ -204,12 +269,20 @@ mod tests {
204269
205270 #[ test]
206271 #[ should_fail]
207- fn test_2d_slice_range_fail ( ) {
272+ fn test_2d_slice_range_fail_low ( ) {
208273 let mut a = ArrayBase :: from_vec ( ~[ 0 , 1 , 2 ] , -1 ) ;
209274 a. wrap ( 1 ) ;
210275 a. slice ( 0 ) ;
211276 }
212277
278+ #[ test]
279+ #[ should_fail]
280+ fn test_2d_slice_range_fail_high ( ) {
281+ let mut a = ArrayBase :: from_vec ( ~[ 0 , 1 , 2 ] , -1 ) ;
282+ a. wrap ( 1 ) ;
283+ a. slice ( 2 ) ;
284+ }
285+
213286 #[ test]
214287 fn test_2d_slice_get ( ) {
215288 let mut a = ArrayBase :: from_vec ( ~[ 0 , 1 , 2 ] , -1 ) ;
0 commit comments