Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Collections/3.3/ObservableArray.cs @ 3226

Last change on this file since 3226 was 3017, checked in by epitzer, 15 years ago

Merge StorableClassType.Empty into StorableClassType.MarkedOnly and make it the default if not specified (#548)

File size: 10.9 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections;
24using System.Collections.Generic;
25using System.ComponentModel;
26using System.Linq;
27using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
28
29namespace HeuristicLab.Collections {
30  [Serializable]
31  [StorableClass]
32  public class ObservableArray<T> : IObservableArray<T> {
33    [Storable]
34    private T[] array;
35
36    #region Properties
37    public int Length {
38      get { return array.Length; }
39    }
40    int ICollection<T>.Count {
41      get { return array.Length; }
42    }
43    bool ICollection<T>.IsReadOnly {
44      get { return array.IsReadOnly; }
45    }
46
47    public T this[int index] {
48      get {
49        return array[index];
50      }
51      set {
52        T item = array[index];
53        if (!((item == null) && (value == null)) && ((item == null) || (!item.Equals(value)))) {
54          array[index] = value;
55          OnItemsReplaced(new IndexedItem<T>[] { new IndexedItem<T>(index, value) }, new IndexedItem<T>[] { new IndexedItem<T>(index, item) });
56          OnPropertyChanged("Item[]");
57        }
58      }
59    }
60    #endregion
61
62    #region Constructors
63    public ObservableArray() {
64      array = new T[0];
65    }
66    public ObservableArray(int length) {
67      array = new T[length];
68    }
69    public ObservableArray(T[] array) {
70      this.array = (T[])array.Clone();
71    }
72    public ObservableArray(IEnumerable<T> collection) {
73      array = collection.ToArray();
74    }
75    #endregion
76
77    #region Access
78    public bool Contains(T item) {
79      return IndexOf(item) != -1;
80    }
81    public int IndexOf(T item) {
82      return Array.IndexOf<T>(array, item);
83    }
84    public int IndexOf(T item, int startIndex) {
85      return Array.IndexOf<T>(array, item, startIndex);
86    }
87    public int IndexOf(T item, int startIndex, int count) {
88      return Array.IndexOf<T>(array, item, startIndex, count);
89    }
90
91    public int LastIndexOf(T item) {
92      return Array.LastIndexOf<T>(array, item);
93    }
94    public int LastIndexOf(T item, int startIndex) {
95      return Array.LastIndexOf<T>(array, item, startIndex);
96    }
97    public int LastIndexOf(T item, int startIndex, int count) {
98      return Array.LastIndexOf<T>(array, item, startIndex, count);
99    }
100
101    public int BinarySearch(T item) {
102      return Array.BinarySearch<T>(array, item);
103    }
104    public int BinarySearch(T item, IComparer<T> comparer) {
105      return Array.BinarySearch<T>(array, item, comparer);
106    }
107    public int BinarySearch(int index, int count, T item) {
108      return Array.BinarySearch<T>(array, index, count, item);
109    }
110    public int BinarySearch(int index, int count, T item, IComparer<T> comparer) {
111      return Array.BinarySearch<T>(array, index, count, item, comparer);
112    }
113
114    public bool Exists(Predicate<T> match) {
115      return Array.Exists<T>(array, match);
116    }
117
118    public T Find(Predicate<T> match) {
119      return Array.Find<T>(array, match);
120    }
121    public T[] FindAll(Predicate<T> match) {
122      return Array.FindAll<T>(array, match);
123    }
124    public T FindLast(Predicate<T> match) {
125      return Array.FindLast<T>(array, match);
126    }
127
128    public int FindIndex(Predicate<T> match) {
129      return Array.FindIndex<T>(array, match);
130    }
131    public int FindIndex(int startIndex, Predicate<T> match) {
132      return Array.FindIndex<T>(array, startIndex, match);
133    }
134    public int FindIndex(int startIndex, int count, Predicate<T> match) {
135      return Array.FindIndex<T>(array, startIndex, count, match);
136    }
137
138    public int FindLastIndex(Predicate<T> match) {
139      return Array.FindLastIndex<T>(array, match);
140    }
141    public int FindLastIndex(int startIndex, Predicate<T> match) {
142      return Array.FindLastIndex<T>(array, startIndex, match);
143    }
144    public int FindLastIndex(int startIndex, int count, Predicate<T> match) {
145      return Array.FindLastIndex<T>(array, startIndex, count, match);
146    }
147    #endregion
148
149    #region Manipulation
150    void ICollection<T>.Add(T item) {
151      throw new NotSupportedException();
152    }
153    void IList<T>.Insert(int index, T item) {
154      throw new NotSupportedException();
155    }
156    bool ICollection<T>.Remove(T item) {
157      throw new NotSupportedException();
158    }
159    void IList<T>.RemoveAt(int index) {
160      throw new NotSupportedException();
161    }
162
163    public void Clear(int index, int length) {
164      if (length > 0) {
165        IndexedItem<T>[] oldItems = GetIndexedItems(index, length);
166        Array.Clear(array, index, length);
167        OnPropertyChanged("Item[]");
168        OnItemsReplaced(GetIndexedItems(index, length), oldItems);
169      }
170    }
171    void ICollection<T>.Clear() {
172      Clear(0, array.Length);
173    }
174
175    public void Resize(int newSize) {
176      if (newSize != array.Length) {
177        IndexedItem<T>[] oldItems = GetIndexedItems();
178        Array.Resize<T>(ref array, newSize);
179        OnPropertyChanged("Length");
180        OnPropertyChanged("Item[]");
181        OnCollectionReset(GetIndexedItems(), oldItems);
182      }
183    }
184
185    public void Reverse() {
186      if (array.Length > 1) {
187        IndexedItem<T>[] oldItems = GetIndexedItems();
188        Array.Reverse(array);
189        OnPropertyChanged("Item[]");
190        OnItemsMoved(GetIndexedItems(), oldItems);
191      }
192    }
193    public void Reverse(int index, int length) {
194      if (length > 1) {
195        IndexedItem<T>[] oldItems = GetIndexedItems(index, length);
196        Array.Reverse(array, index, length);
197        OnPropertyChanged("Item[]");
198        OnItemsMoved(GetIndexedItems(index, length), oldItems);
199      }
200    }
201
202    public void Sort() {
203      if (array.Length > 1) {
204        IndexedItem<T>[] oldItems = GetIndexedItems();
205        Array.Sort<T>(array);
206        OnPropertyChanged("Item[]");
207        OnItemsMoved(GetIndexedItems(), oldItems);
208      }
209    }
210    public void Sort(Comparison<T> comparison) {
211      if (array.Length > 1) {
212        IndexedItem<T>[] oldItems = GetIndexedItems();
213        Array.Sort<T>(array, comparison);
214        OnPropertyChanged("Item[]");
215        OnItemsMoved(GetIndexedItems(), oldItems);
216      }
217    }
218    public void Sort(IComparer<T> comparer) {
219      if (array.Length > 1) {
220        IndexedItem<T>[] oldItems = GetIndexedItems();
221        Array.Sort<T>(array, comparer);
222        OnPropertyChanged("Item[]");
223        OnItemsMoved(GetIndexedItems(), oldItems);
224      }
225    }
226    public void Sort(int index, int length) {
227      if (length > 1) {
228        IndexedItem<T>[] oldItems = GetIndexedItems(index, length);
229        Array.Sort<T>(array, index, length);
230        OnPropertyChanged("Item[]");
231        OnItemsMoved(GetIndexedItems(index, length), oldItems);
232      }
233    }
234    public void Sort(int index, int length, IComparer<T> comparer) {
235      if (length > 1) {
236        IndexedItem<T>[] oldItems = GetIndexedItems(index, length);
237        Array.Sort<T>(array, index, length, comparer);
238        OnPropertyChanged("Item[]");
239        OnItemsMoved(GetIndexedItems(index, length), oldItems);
240      }
241    }
242    #endregion
243
244    #region Conversion
245    public ReadOnlyObservableArray<T> AsReadOnly() {
246      return new ReadOnlyObservableArray<T>(this);
247    }
248    public void CopyTo(T[] array) {
249      Array.Copy(this.array, array, this.array.Length);
250    }
251    public void CopyTo(T[] array, int arrayIndex) {
252      Array.Copy(this.array, 0, array, arrayIndex, this.array.Length);
253    }
254    public void CopyTo(int index, T[] array, int arrayIndex, int count) {
255      Array.Copy(this.array, index, array, arrayIndex, count);
256    }
257    public TOutput[] ConvertAll<TOutput>(Converter<T, TOutput> converter) {
258      return Array.ConvertAll<T, TOutput>(array, converter);
259    }
260    #endregion
261
262    #region Processing
263    public void ForEach(Action<T> action) {
264      Array.ForEach<T>(array, action);
265    }
266    public bool TrueForAll(Predicate<T> match) {
267      return Array.TrueForAll<T>(array, match);
268    }
269    #endregion
270
271    #region Enumeration
272    public IEnumerator<T> GetEnumerator() {
273      foreach (object o in ((IEnumerable)this))
274        yield return (T)o;
275    }
276    IEnumerator IEnumerable.GetEnumerator() {
277      return array.GetEnumerator();
278    }
279    #endregion
280
281    #region Events
282    [field: NonSerialized]
283    public event CollectionItemsChangedEventHandler<IndexedItem<T>> ItemsReplaced;
284    protected virtual void OnItemsReplaced(IEnumerable<IndexedItem<T>> items, IEnumerable<IndexedItem<T>> oldItems) {
285      if (ItemsReplaced != null)
286        ItemsReplaced(this, new CollectionItemsChangedEventArgs<IndexedItem<T>>(items, oldItems));
287    }
288
289    [field: NonSerialized]
290    public event CollectionItemsChangedEventHandler<IndexedItem<T>> ItemsMoved;
291    protected virtual void OnItemsMoved(IEnumerable<IndexedItem<T>> items, IEnumerable<IndexedItem<T>> oldItems) {
292      if (ItemsMoved != null)
293        ItemsMoved(this, new CollectionItemsChangedEventArgs<IndexedItem<T>>(items, oldItems));
294    }
295
296    [field: NonSerialized]
297    public event CollectionItemsChangedEventHandler<IndexedItem<T>> CollectionReset;
298    protected virtual void OnCollectionReset(IEnumerable<IndexedItem<T>> items, IEnumerable<IndexedItem<T>> oldItems) {
299      if (CollectionReset != null)
300        CollectionReset(this, new CollectionItemsChangedEventArgs<IndexedItem<T>>(items, oldItems));
301    }
302
303    [field: NonSerialized]
304    public event PropertyChangedEventHandler PropertyChanged;
305    protected virtual void OnPropertyChanged(string propertyName) {
306      if (PropertyChanged != null)
307        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
308    }
309    #endregion
310
311    #region Private helpers
312    private IndexedItem<T>[] GetIndexedItems() {
313      IndexedItem<T>[] items = new IndexedItem<T>[array.Length];
314      for (int i = 0; i < array.Length; i++)
315        items[i] = new IndexedItem<T>(i, array[i]);
316      return items;
317    }
318    private IndexedItem<T>[] GetIndexedItems(int index, int count) {
319      IndexedItem<T>[] items = new IndexedItem<T>[count];
320      for (int i = 0; i < count; i++)
321        items[i] = new IndexedItem<T>(index + i, array[index + i]);
322      return items;
323    }
324    #endregion
325  }
326}
Note: See TracBrowser for help on using the repository browser.