5 // Joe Shaw (joe@ximian.com)
7 // (C) 2001 Ximian, Inc. http://www.ximian.com
13 public abstract class Array : ICloneable
\r
15 public int lower_bound = 0;
37 public static int BinarySearch (Array array, object value)
39 return BinarySearch (array, this.lower_bound, this.length, value, null);
42 public static int BinarySearch (Array array, object value, IComparer comparer)
44 return BinarySearch (array, this.lower_bound, this.length, value, comparer);
47 public static int BinarySearch (Array array, int index, int length, object value)
49 return BinarySearch (array, index, length, value, null);
52 public static int BinarySearch (Array array, int index, int length, object value, IComparer comparer)
55 throw new ArgumentNullException ();
58 throw new RankException ();
60 if (index < array.lower_bound || length < 0)
61 throw new ArgumentOutOfRangeException ();
63 if (index + length > array.lower_bound + array.Length)
64 throw new ArgumentException ();
66 if (comparer == null && !(value is IComparable))
67 throw new ArgumentException ();
69 // FIXME: Throw an ArgumentException if comparer
70 // is null and value is not of the same type as the
73 for (int i = 0; i < length; i++)
\r
77 if (comparer == null && !(array.GetValue(index + i) is IComparable))
78 throw new ArgumentException ();
81 result = value.CompareTo(array.GetValue(index + i));
83 result = comparer.Compare(value, array.GetValue(index + i));
91 return ~(index + length);
94 public static void Clear (Array array, int index, int length)
97 throw new ArgumentNullException ();
99 if (index < this.lower_bound || length < 0 ||
100 index + length > this.lower_bound + this.length)
101 throw new ArgumentOutOfRangeException ();
103 for (int i = 0; i < length; i++)
\r
105 if (array.GetValue(index + i) is bool)
106 array.SetValue(false, index + i);
107 else if (array.GetValue(index + i) is ValueType)
108 array.SetValue(0, index + i);
110 array.SetValue(null, index + i);
114 public virtual object Clone ()
116 Array a = new Array();
118 for (int i = 0; i < this.length; i++)
\r
120 int index = this.lower_bound + i;
122 a.SetValue(this.GetValue(index), index);
128 public static void Copy (Array source, Array dest, int length)
130 Copy (source, source.lower_bound, dest, dest.lower_bound, length);
133 public static void Copy (Array source, int source_idx, Array dest, int dest_idx, int length)
136 throw new ArgumentOutOfRangeException ();
138 if (source == null || dest == null)
139 throw new ArgumentNullException ();
141 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)
142 throw new ArgumentException ();
144 if (source.Rank != dest.Rank)
145 throw new RankException ();
147 for (int i = 0; i < length; i++)
\r
149 int index = source.lower_bound + i;
151 dest.SetValue(source.GetValue(index), index);
155 [MethodImplAttribute(InternalCall)]
156 private object InternalGetValue (int index);
158 public object GetValue (int index)
161 throw new ArgumentException ();
163 if (index < this.lower_bound ||
164 index > this.lower_bound + this.length)
165 throw new ArgumentOutOfRangeException ();
167 return InternalGetValue (index);
170 [MethodImplAttribute(InternalCall)]
171 private void InternalSetValue (object value, int index);
173 public void SetValue (object value, int index)
176 throw new ArgumentException ();
178 if (index < this.lower_bound ||
179 index > this.lower_bound + this.length)
180 throw new ArgumentOutOfRangeException ();
182 InternalSetValue (value);
185 public static int IndexOf (Array array, object value)
187 return IndexOf (array, value, 0, array.Length);
190 public static int IndexOf (Array array, object value, int index)
192 return IndexOf (array, value, index, array.Length - index);
195 public static int IndexOf (Array array, object value, int index, int length)
198 throw new ArgumentNullException ();
200 if (length < 0 || index < array.lower_bound || index > array.lower_bound + length)
201 throw new ArgumentOutOfRangeException ();
203 for (int i = 0; i < length; i++)
\r
205 if (array.GetValue(index + i) == value)
209 return array.lower_bound - 1;
212 public static int LastIndexOf (Array array, object value)
214 return LastIndexOf (array, value, 0, array.Length);
217 public static int LastIndexOf (Array array, object value, int index)
219 return LastIndexOf (array, value, index, array.Length - index);
222 public static int LastIndexOf (Array array, object value, int index, int length)
225 throw new ArgumentNullException ();
227 if (length < 0 || index < array.lower_bound || index > array.lower_bound + length)
228 throw new ArgumentOutOfRangeException ();
230 for (int i = length - 1; i >= 0; i--)
\r
232 if (array.GetValue(index + i) == value)
236 return array.lower_bound - 1;
239 public static void Reverse (Array array)
241 Reverse (array, array.lower_bound, array.Length);
244 public static void Reverse (Array array, int index, int length)
247 throw new ArgumentNullException ();
250 throw new RankException ();
252 if (index < array.lower_bound || length < 0)
253 throw new ArgumentOutOfRangeException ();
255 if (index + length > array.lower_bound + array.Length)
256 throw new ArgumentException ();
258 for (int i = 0; i < length/2; i++)
\r
262 tmp = array.GetValue(index + i);
263 array.SetValue(array.GetValue(index + length - i - 1), index + i);
264 array.SetValue(tmp, index + length - i - 1);
268 public static void Sort (Array array)
270 Sort (array, null, array.lower_bound, array.Length, null);
273 public static void Sort (Array keys, Array items)
275 Sort (keys, items, keys.lower_bound, keys.Length, null);
278 public static void Sort (Array array, IComparer comparer)
280 Sort (array, null, array.lower_bound, array.Length, comparer);
283 public static void Sort (Array array, int index, int length)
285 Sort (array, null, index, length, null);
288 public static void Sort (Array keys, Array items, IComparer comparer)
290 Sort (keys, items, keys.lower_bound, keys.Length, comparer);
293 public static void Sort (Array keys, Array items, int index, int length)
295 Sort (keys, items, index, length, null);
298 public static void Sort (Array array, int index, int length, IComparer comparer)
300 Sort (array, null, index, length, comparer);
303 public static void Sort (Array keys, Array items, int index, int length, IComparer comparer)
306 int high0 = index + length - 1;
308 qsort (keys, items, index, index + length - 1, comparer);
311 private static void qsort (Array keys, Array items, int low0, int high0, IComparer comparer)
320 pivot = (low + high) / 2;
322 if (compare(keys.GetValue(low), keys.GetValue(pivot), comparer) > 0)
323 swap(keys, items, low, pivot);
325 if (compare(keys.GetValue(pivot), keys.GetValue(high), comparer) > 0)
326 swap(keys, items, pivot, high);
328 while (low < high)
\r
331 while (low < high && compare(keys.GetValue(low), keys.GetValue(pivot), comparer) < 0)
333 while (low < high && compare(keys.GetValue(pivot), keys.GetValue(high), comparer) < 0)
338 swap(keys, items, low, high);
344 qsort (keys, items, low0, low - 1);
345 qsort (keys, items, high + 1, high0);
348 private static void swap (Array keys, Array items, int i, int j)
352 tmp = keys.GetValue(i);
353 keys.SetValue(keys.GetValue(j), i);
354 keys.SetValue(tmp, j);
356 if (items != null)
\r
358 tmp = items.GetValue(i);
359 items.SetValue(items.GetValue(j), i);
360 items.SetValue(tmp, j);
364 private static int compare (object value1, object value2, IComparer comparer)
366 if (comparer == null)
367 return ((IComparable) value1).CompareTo(value2);
369 return comparer.Compare(value1, value2);