2001-07-10 Joe Shaw <joe@ximian.com>
[mono.git] / mcs / class / corlib / System / Array.cs
1 //
2 // System.Array.cs
3 //
4 // Author:
5 //   Joe Shaw (joe@ximian.com)
6 //
7 // (C) 2001 Ximian, Inc.  http://www.ximian.com
8 //
9
10 namespace System {
11
12         public abstract class Array : ICloneable {
13                 public int lower_bound = 0;
14                 private int length;
15                 private int rank;
16
17                 // Properties
18                 public int Length {
19                         get {
20                                 return length;
21                         }
22                 }
23
24                 public int Rank {
25                         get {
26                                 return rank;
27                         }
28                 }
29
30                 // Methods
31                 public static int BinarySearch (Array array, object value)
32                 {
33                         return BinarySearch (array, this.lower_bound, this.length, value, null);
34                 }
35
36                 public static int BinarySearch (Array array, object value, IComparer comparer)
37                 {
38                         return BinarySearch (array, this.lower_bound, this.length, value, comparer);
39                 }
40
41                 public static int BinarySearch (Array array, int index, int length, object value)
42                 {
43                         return BinarySearch (array, index, length, value, null);
44                 }
45
46                 public static int BinarySearch (Array array, int index, int length, object value, IComparer comparer)
47                 {
48                         if (array == null)
49                                 throw new ArgumentNullException ();
50
51                         if (array.Rank > 1)
52                                 throw new RankException ();
53
54                         if (index < array.lower_bound || length < 0)
55                                 throw new ArgumentOutOfRangeException ();
56
57                         if (index + length > array.lower_bound + array.Length)
58                                 throw new ArgumentException ();
59
60                         if (comparer == null && !(value is IComparable))
61                                 throw new ArgumentException ();
62
63                         // FIXME: Throw an ArgumentException if comparer
64                         // is null and value is not of the same type as the
65                         // elements of array.
66
67                         for (int i = 0; i < length; i++) {
68                                 int result;
69
70                                 if (comparer == null && !(array[index + i] is IComparable))
71                                         throw new ArgumentException ();
72
73                                 if (comparer == null)
74                                         result = comparer.Compare(value, array[index + i]);
75                                 else
76                                         result = value.CompareTo(array[index + i]);
77
78                                 if (result == 0)
79                                         return index + i;
80                                 else if (result < 0)
81                                         return ~(index + i);
82                         }
83
84                         return ~(index + length);
85                 }
86
87                 public static void Clear (Array array, int index, int length)
88                 {
89                         if (array == null)
90                                 throw new ArgumentNullException ();
91
92                         if (index < this.lower_bound || length < 0 ||
93                             index + length > this.lower_bound + this.length)
94                                 throw new ArgumentOutOfRangeException ();
95
96                         for (int i = 0; i < length; i++) {
97                                 if (array[index + i] is bool)
98                                         array[index + i] = false;
99                                 else if (array[index + i] is ValueType)
100                                         array[index + i] = 0;
101                                 else
102                                         array[index + i] = null;
103                         }
104                 }
105
106                 public virtual object Clone ()
107                 {
108                         Array a = new Array;
109
110                         for (int i = 0; i < this.length; i++) {
111                                 int index = this.lower_bound + i;
112
113                                 a[index] = this[index];
114                         }
115
116                         return a;
117                 }
118
119                 public static void Copy (Array source, Array dest, int length)
120                 {
121                         Copy (source, source.lower_bound, dest, dest.lower_bound, length);
122                 }
123
124                 public static void Copy (Array source, int source_idx, Array dest, int dest_idx, int length)
125                 {
126                         if (length < 0)
127                                 throw new ArgumentOutOfRangeException ();
128
129                         if (source == null || dest == null)
130                                 throw new ArgumentNullException ();
131
132                         if (source_idx < source.lower_bound || source_idx + length > source.lower_bound + source.Length || dest_idx < dest.lower_bound || dest_idx + length > dest.lower_bound + dest.Length)
133                                 throw new ArgumentException ();
134
135                         if (source.Rank != dest.Rank)
136                                 throw new RankException ();
137
138                         for (int i = 0; i < length; i++) {
139                                 int index = source.lower_bound + i;
140
141                                 dest[index] = source[index];
142                         }
143                 }
144
145                 public object GetValue (int index)
146                 {
147                         if (this.rank > 1)
148                                 throw new ArgumentException ();
149
150                         if (index < this.lower_bound ||
151                             index > this.lower_bound + this.length)
152                                 throw new ArgumentOutOfRangeException ();
153
154                         return this[index];
155                 }
156
157                 public static int IndexOf (Array array, object value)
158                 {
159                         return IndexOf (array, value, 0, array.Length);
160                 }
161
162                 public static int IndexOf (Array array, object value, int index)
163                 {
164                         return IndexOf (array, value, index, array.Length - index);
165                 }
166
167                 public static int IndexOf (Array array, object value, int index, int length)
168                 {
169                         if (array == null)
170                                 throw new ArgumentNullException ();
171         
172                         if (length < 0 || index < array.lower_bound || index > array.lower_bound + length)
173                                 throw new ArgumentOutOfRangeException ();
174
175                         for (int i = 0; i < length; i++) {
176                                 if (array[index + i] == value)
177                                         return index + i;
178                         }
179
180                         return array.lower_bound - 1;
181                 }
182
183                 public static int LastIndexOf (Array array, object value)
184                 {
185                         return LastIndexOf (array, value, 0, array.Length);
186                 }
187
188                 public static int LastIndexOf (Array array, object value, int index)
189                 {
190                         return LastIndexOf (array, value, index, array.Length - index);
191                 }
192
193                 public static int LastIndexOf (Array array, object value, int index, int length)
194                 {
195                         int occurrance = array.lower_bound - 1;
196
197                         if (array == null)
198                                 throw new ArgumentNullException ();
199         
200                         if (length < 0 || index < array.lower_bound || index > array.lower_bound + length)
201                                 throw new ArgumentOutOfRangeException ();
202
203                         for (int i = 0; i < length; i++) {
204                                 if (array[index + i] == value)
205                                         occurrance = index + i;
206                         }
207
208                         return occurrance;
209                 }
210         
211                 public static void Reverse (Array array)
212                 {
213                         Reverse (array, array.lower_bound, array.Length);
214                 }
215
216                 public static void Reverse (Array array, int index, int length)
217                 {
218                         if (array == null)
219                                 throw new ArgumentNullException ();
220
221                         if (array.Rank > 1)
222                                 throw new RankException ();
223
224                         if (index < array.lower_bound || length < 0)
225                                 throw new ArgumentOutOfRangeException ();
226
227                         if (index + length > array.lower_bound + array.Length)
228                                 throw new ArgumentException ();
229
230                         for (int i = 0; i < length/2; i++) {
231                                 object tmp;
232
233                                 tmp = array[index + i];
234                                 array[index + i] = array[index + length - i - 1];
235                                 array[index + length - i - 1] = tmp;
236                         }
237                 }
238
239                 public static void Sort (Array array)
240                 {
241                         Sort (array, null, array.lower_bound, array.Length, null);
242                 }
243
244                 public static void Sort (Array keys, Array items)
245                 {
246                         Sort (keys, items, keys.lower_bound, keys.Length, null);
247                 }
248
249                 public static void Sort (Array array, IComparer comparer)
250                 {
251                         Sort (array, null, array.lower_bound, array.Length, comparer);
252                 }
253
254                 public static void Sort (Array array, int index, int length)
255                 {
256                         Sort (array, null, index, length, null);
257                 }
258
259                 public static void Sort (Array keys, Array items, IComparer comparer)
260                 {
261                         Sort (keys, items, keys.lower_bound, keys.Length, comparer);
262                 }
263
264                 public static void Sort (Array keys, Array items, int index, int length)
265                 {
266                         Sort (keys, items, index, length, null);
267                 }
268
269                 public static void Sort (Array array, int index, int length, IComparer comparer)
270                 {
271                         Sort (array, null, index, length, comparer);
272                 }
273
274                 public static void Sort (Array keys, Array items, int index, int length, IComparer comparer)
275                 {
276                         // TODO
277                 }