PageRenderTime 25ms CodeModel.GetById 10ms app.highlight 12ms RepoModel.GetById 1ms app.codeStats 0ms

/Mono.Cecil/Mono.Collections.Generic/Collection.cs

http://github.com/icsharpcode/ILSpy
C# | 420 lines | 304 code | 89 blank | 27 comment | 28 complexity | c02b2ecacd394f8ef989d3185336f29a MD5 | raw file
  1//
  2// Collection.cs
  3//
  4// Author:
  5//   Jb Evain (jbevain@gmail.com)
  6//
  7// Copyright (c) 2008 - 2011 Jb Evain
  8//
  9// Permission is hereby granted, free of charge, to any person obtaining
 10// a copy of this software and associated documentation files (the
 11// "Software"), to deal in the Software without restriction, including
 12// without limitation the rights to use, copy, modify, merge, publish,
 13// distribute, sublicense, and/or sell copies of the Software, and to
 14// permit persons to whom the Software is furnished to do so, subject to
 15// the following conditions:
 16//
 17// The above copyright notice and this permission notice shall be
 18// included in all copies or substantial portions of the Software.
 19//
 20// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 21// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 22// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 23// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 24// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 25// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 26// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 27//
 28
 29using System;
 30using System.Collections;
 31using System.Collections.Generic;
 32
 33namespace Mono.Collections.Generic {
 34
 35	public class Collection<T> : IList<T>, IList {
 36
 37		internal T [] items;
 38		internal int size;
 39		int version;
 40
 41		public int Count {
 42			get { return size; }
 43		}
 44
 45		public T this [int index] {
 46			get {
 47				if (index >= size)
 48					throw new ArgumentOutOfRangeException ();
 49
 50				return items [index];
 51			}
 52			set {
 53				CheckIndex (index);
 54				if (index == size)
 55					throw new ArgumentOutOfRangeException ();
 56
 57				OnSet (value, index);
 58
 59				items [index] = value;
 60			}
 61		}
 62
 63		bool ICollection<T>.IsReadOnly {
 64			get { return false; }
 65		}
 66
 67		bool IList.IsFixedSize {
 68			get { return false; }
 69		}
 70
 71		bool IList.IsReadOnly {
 72			get { return false; }
 73		}
 74
 75		object IList.this [int index] {
 76			get { return this [index]; }
 77			set {
 78				CheckIndex (index);
 79
 80				try {
 81					this [index] = (T) value;
 82					return;
 83				} catch (InvalidCastException) {
 84				} catch (NullReferenceException) {
 85				}
 86
 87				throw new ArgumentException ();
 88			}
 89		}
 90
 91		int ICollection.Count {
 92			get { return Count; }
 93		}
 94
 95		bool ICollection.IsSynchronized {
 96			get { return false; }
 97		}
 98
 99		object ICollection.SyncRoot {
100			get { return this; }
101		}
102
103		public Collection ()
104		{
105			items = Empty<T>.Array;
106		}
107
108		public Collection (int capacity)
109		{
110			if (capacity < 0)
111				throw new ArgumentOutOfRangeException ();
112
113			items = new T [capacity];
114		}
115
116		public Collection (ICollection<T> items)
117		{
118			if (items == null)
119				throw new ArgumentNullException ("items");
120
121			this.items = new T [items.Count];
122			items.CopyTo (this.items, 0);
123			this.size = this.items.Length;
124		}
125
126		public void Add (T item)
127		{
128			if (size == items.Length)
129				Grow (1);
130
131			OnAdd (item, size);
132
133			items [size++] = item;
134			version++;
135		}
136
137		public bool Contains (T item)
138		{
139			return IndexOf (item) != -1;
140		}
141
142		public int IndexOf (T item)
143		{
144			return Array.IndexOf (items, item, 0, size);
145		}
146
147		public void Insert (int index, T item)
148		{
149			CheckIndex (index);
150			if (size == items.Length)
151				Grow (1);
152
153			OnInsert (item, index);
154
155			Shift (index, 1);
156			items [index] = item;
157			version++;
158		}
159
160		public void RemoveAt (int index)
161		{
162			if (index < 0 || index >= size)
163				throw new ArgumentOutOfRangeException ();
164
165			var item = items [index];
166
167			OnRemove (item, index);
168
169			Shift (index, -1);
170			Array.Clear (items, size, 1);
171			version++;
172		}
173
174		public bool Remove (T item)
175		{
176			var index = IndexOf (item);
177			if (index == -1)
178				return false;
179
180			OnRemove (item, index);
181
182			Shift (index, -1);
183			Array.Clear (items, size, 1);
184			version++;
185
186			return true;
187		}
188
189		public void Clear ()
190		{
191			OnClear ();
192
193			Array.Clear (items, 0, size);
194			size = 0;
195			version++;
196		}
197
198		public void CopyTo (T [] array, int arrayIndex)
199		{
200			Array.Copy (items, 0, array, arrayIndex, size);
201		}
202
203		public T [] ToArray ()
204		{
205			var array = new T [size];
206			Array.Copy (items, 0, array, 0, size);
207			return array;
208		}
209
210		void CheckIndex (int index)
211		{
212			if (index < 0 || index > size)
213				throw new ArgumentOutOfRangeException ();
214		}
215
216		void Shift (int start, int delta)
217		{
218			if (delta < 0)
219				start -= delta;
220
221			if (start < size)
222				Array.Copy (items, start, items, start + delta, size - start);
223
224			size += delta;
225
226			if (delta < 0)
227				Array.Clear (items, size, -delta);
228		}
229
230		protected virtual void OnAdd (T item, int index)
231		{
232		}
233
234		protected virtual void OnInsert (T item, int index)
235		{
236		}
237
238		protected virtual void OnSet (T item, int index)
239		{
240		}
241
242		protected virtual void OnRemove (T item, int index)
243		{
244		}
245
246		protected virtual void OnClear ()
247		{
248		}
249
250		internal virtual void Grow (int desired)
251		{
252			int new_size = size + desired;
253			if (new_size <= items.Length)
254				return;
255
256			const int default_capacity = 4;
257
258			new_size = System.Math.Max (
259				System.Math.Max (items.Length * 2, default_capacity),
260				new_size);
261
262#if !CF
263			Array.Resize (ref items, new_size);
264#else
265			var array = new T [new_size];
266			Array.Copy (items, array, size);
267			items = array;
268#endif
269		}
270
271		int IList.Add (object value)
272		{
273			try {
274				Add ((T) value);
275				return size - 1;
276			} catch (InvalidCastException) {
277			} catch (NullReferenceException) {
278			}
279
280			throw new ArgumentException ();
281		}
282
283		void IList.Clear ()
284		{
285			Clear ();
286		}
287
288		bool IList.Contains (object value)
289		{
290			return ((IList) this).IndexOf (value) > -1;
291		}
292
293		int IList.IndexOf (object value)
294		{
295			try {
296				return IndexOf ((T) value);
297			} catch (InvalidCastException) {
298			} catch (NullReferenceException) {
299			}
300
301			return -1;
302		}
303
304		void IList.Insert (int index, object value)
305		{
306			CheckIndex (index);
307
308			try {
309				Insert (index, (T) value);
310				return;
311			} catch (InvalidCastException) {
312			} catch (NullReferenceException) {
313			}
314
315			throw new ArgumentException ();
316		}
317
318		void IList.Remove (object value)
319		{
320			try {
321				Remove ((T) value);
322			} catch (InvalidCastException) {
323			} catch (NullReferenceException) {
324			}
325		}
326
327		void IList.RemoveAt (int index)
328		{
329			RemoveAt (index);
330		}
331
332		void ICollection.CopyTo (Array array, int index)
333		{
334			Array.Copy (items, 0, array, index, size);
335		}
336
337		public Enumerator GetEnumerator ()
338		{
339			return new Enumerator (this);
340		}
341
342		IEnumerator IEnumerable.GetEnumerator ()
343		{
344			return new Enumerator (this);
345		}
346
347		IEnumerator<T> IEnumerable<T>.GetEnumerator ()
348		{
349			return new Enumerator (this);
350		}
351
352		public struct Enumerator : IEnumerator<T>, IDisposable {
353
354			Collection<T> collection;
355			T current;
356
357			int next;
358			readonly int version;
359
360			public T Current {
361				get { return current; }
362			}
363
364			object IEnumerator.Current {
365				get {
366					CheckState ();
367
368					if (next <= 0)
369						throw new InvalidOperationException ();
370
371					return current;
372				}
373			}
374
375			internal Enumerator (Collection<T> collection)
376				: this ()
377			{
378				this.collection = collection;
379				this.version = collection.version;
380			}
381
382			public bool MoveNext ()
383			{
384				CheckState ();
385
386				if (next < 0)
387					return false;
388
389				if (next < collection.size) {
390					current = collection.items [next++];
391					return true;
392				}
393
394				next = -1;
395				return false;
396			}
397
398			public void Reset ()
399			{
400				CheckState ();
401
402				next = 0;
403			}
404
405			void CheckState ()
406			{
407				if (collection == null)
408					throw new ObjectDisposedException (GetType ().FullName);
409
410				if (version != collection.version)
411					throw new InvalidOperationException ();
412			}
413
414			public void Dispose ()
415			{
416				collection = null;
417			}
418		}
419	}
420}