| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408 |
- //
- // System.Collections.Generic.Collection
- //
- // Author:
- // Carlos Alberto Cortez ([email protected])
- //
- // (C) 2004 Carlos Alberto Cortez
- //
- //
- // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
- //
- // Permission is hereby granted, free of charge, to any person obtaining
- // a copy of this software and associated documentation files (the
- // "Software"), to deal in the Software without restriction, including
- // without limitation the rights to use, copy, modify, merge, publish,
- // distribute, sublicense, and/or sell copies of the Software, and to
- // permit persons to whom the Software is furnished to do so, subject to
- // the following conditions:
- //
- // The above copyright notice and this permission notice shall be
- // included in all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- //
- #if NET_2_0
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Runtime.InteropServices;
- namespace System.Collections.Generic
- {
- [CLSCompliant(false)]
- [ComVisible(false)]
- public class Collection <T> : ICollection <T>, IEnumerable <T>, IList <T>,
- ICollection, IEnumerable, IList
- {
- const int defaultLength = 16;
- T [] contents;
- int count;
- int modcount;
- public Collection ()
- {
- contents = new T [defaultLength];
- }
- public Collection (List <T> list) : this (list, list.Count * 2)
- {
- }
- internal Collection (IList <T> list, int length)
- {
- if (list == null)
- throw new ArgumentNullException ("list");
- contents = new T [length];
- list.CopyTo (contents, 0);
- count = list.Count;
- }
-
- public void Add (T item)
- {
- if (count >= contents.Length)
- Array.Resize<T> (ref contents, contents.Length * 2);
-
- InsertItem (count, item);
- }
- public void Clear ()
- {
- ClearItems ();
- }
- protected virtual void ClearItems ()
- {
- modcount++;
- if (count <= 0)
- return;
- Array.Clear (contents, 0, count);
- count = 0;
- }
- public bool Contains (T item)
- {
- return IndexOf (item) >= 0;
- }
- public void CopyTo (T [] array, int index)
- {
- if (array == null)
- throw new ArgumentNullException ("array");
- if (index < 0)
- throw new ArgumentOutOfRangeException ("index");
- if (count < 0)
- return;
- Array.Copy (contents, 0, array, index, count);
- }
- public IEnumerator<T> GetEnumerator ()
- {
- return new Enumerator (this);
- }
- void ICollection.CopyTo (Array array, int index)
- {
- if (array == null)
- throw new ArgumentNullException ("array");
- if (array.Rank > 1)
- throw new ArgumentException ("Only single dimension arrays are supported.","array");
- CopyTo ((T []) array, index);
- }
- IEnumerator IEnumerable.GetEnumerator ()
- {
- return new Enumerator (this);
- }
- int IList.Add (object value)
- {
- int pos = count;
- CheckType (value);
- Add ((T) value);
- return pos;
- }
- bool IList.Contains (object value)
- {
- CheckType (value);
- return Contains ((T) value);
- }
- int IList.IndexOf (object value)
- {
- CheckType (value);
- return IndexOf ((T) value);
- }
- void IList.Insert (int index, object value)
- {
- CheckType (value);
- Insert (index, (T) value);
- }
- void IList.Remove (object value)
- {
- CheckType (value);
- Remove ((T) value);
- }
- public int IndexOf (T item)
- {
- if (item == null)
- for (int i = 0; i < count; i++) {
- if (contents [i] == null)
- return i;
- }
- else
- for (int i = 0; i < count; i++) {
- if (item.Equals (contents [i]))
- return i;
- }
- return -1;
- }
- public void Insert (int index, T item)
- {
- if (index < 0 || index > count)
- throw new ArgumentOutOfRangeException ("index");
- if (count >= contents.Length)
- Array.Resize<T> (ref contents, contents.Length * 2);
- InsertItem (index, item);
- }
- protected virtual void InsertItem (int index, T item)
- {
- modcount++;
- //
- // Shift them by 1
- //
- int rest = count - index;
- if (rest > 0)
- Array.Copy (contents, index, contents, index + 1, rest);
- contents [index] = item;
- count++;
- }
- public bool Remove (T item)
- {
- int index = IndexOf (item);
- if (index > -1) {
- RemoveItem (index);
- return true;
- }
-
- return false;
- }
- public void RemoveAt (int index)
- {
- if (index < 0 || index >= count)
- throw new ArgumentOutOfRangeException ("index");
- RemoveItem (index);
-
- }
- protected virtual void RemoveItem (int index)
- {
- modcount++;
-
- int rest = count - index - 1;
- if (rest > 0)
- Array.Copy (contents, index + 1, contents, index, rest);
- //
- // Clear the last element
- //
- Array.Clear (contents, --count, 1);
- }
- protected virtual void SetItem (int index, T item)
- {
- modcount++;
- contents [index] = item;
- }
- public int Count {
- get {
- return count;
- }
-
- }
- public T this [int index] {
- get {
- if (index < 0 || index >= count)
- throw new ArgumentOutOfRangeException ("index");
- return contents [index];
- }
- set {
- if (index < 0 || index >= count)
- throw new ArgumentOutOfRangeException ("index");
- SetItem (index, value);
- }
-
- }
- object IList.this [int index] {
- get {
- return this [index];
- }
- set {
- CheckType(value);
- this [index] = (T) value;
- }
- }
- //
- // We could try to make List.contents internal,
- // avoiding the box and unbox when copying
- //
- protected internal List <T> Items {
- get {
- return new List <T> (this);
- }
-
- }
- public bool IsFixedSize {
- get {
- return false;
- }
- }
- public bool IsReadOnly {
-
- get {
- return false;
- }
-
- }
- public bool IsSynchronized {
-
- get {
- return false;
- }
-
- }
- public object SyncRoot {
-
- get {
- return this;
- }
-
- }
- private void CheckType (object value)
- {
- if (!(value is T)) {
- string valtype = value.GetType ().ToString ();
- throw new ArgumentException (
- String.Format ("A value of type {0} can't be used in this generic collection.", valtype),
- "value");
- }
- }
- //
- // Will we use this iterator until iterators support is done?
- //
- private struct Enumerator : IEnumerator <T>, IEnumerator
- {
- private Collection <T> collection;
- private int current;
- private int modcount;
- public Enumerator (Collection <T> collection)
- {
- this.collection = collection;
- modcount = collection.modcount;
- current = -1;
- }
- public void Dispose()
- {
- modcount = -1;
- }
- object IEnumerator.Current {
- get {
- return Current;
- }
-
- }
- void IEnumerator.Reset ()
- {
- if (modcount != collection.modcount)
- throw new InvalidOperationException
- ("Collection was modified while enumerating.");
- current = -1;
- }
- public bool MoveNext ()
- {
- if (modcount != collection.modcount)
- throw new InvalidOperationException
- ("Collection was modified while enumerating.");
-
- current++;
- return current < collection.count;
- }
- public T Current {
- get {
- if (current < 0 || current >= collection.count)
- throw new InvalidOperationException
- ("Collection was modified while enumerating.");
- return collection.contents [current];
- }
- }
- }
-
- }
- }
- #endif
|