Free cookie consent management tool by TermsFeed Policy Generator

source: stable/HeuristicLab.ExtLibs/HeuristicLab.Cecil/0.9.5/Mono.Cecil-0.9.5/Mono.Cecil/Mono.Collections.Generic/Collection.cs @ 15049

Last change on this file since 15049 was 11700, checked in by jkarder, 10 years ago

#2077: created branch and added first version

File size: 7.5 KB
Line 
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}
Note: See TracBrowser for help on using the repository browser.