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

Last change on this file since 9456 was 9456, checked in by swagner, 7 years ago

Updated copyright year and added some missing license headers (#1889)

File size: 11.2 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2013 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  [StorableClass]
31  [Serializable]
32  public class ObservableArray<T> : IObservableArray<T> {
33    [Storable]
34    protected 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    [StorableConstructor]
76    protected ObservableArray(bool deserializing) { }
77    #endregion
78
79    #region Access
80    public bool Contains(T item) {
81      return IndexOf(item) != -1;
82    }
83    public int IndexOf(T item) {
84      return Array.IndexOf<T>(array, item);
85    }
86    public int IndexOf(T item, int startIndex) {
87      return Array.IndexOf<T>(array, item, startIndex);
88    }
89    public int IndexOf(T item, int startIndex, int count) {
90      return Array.IndexOf<T>(array, item, startIndex, count);
91    }
92
93    public int LastIndexOf(T item) {
94      return Array.LastIndexOf<T>(array, item);
95    }
96    public int LastIndexOf(T item, int startIndex) {
97      return Array.LastIndexOf<T>(array, item, startIndex);
98    }
99    public int LastIndexOf(T item, int startIndex, int count) {
100      return Array.LastIndexOf<T>(array, item, startIndex, count);
101    }
102
103    public int BinarySearch(T item) {
104      return Array.BinarySearch<T>(array, item);
105    }
106    public int BinarySearch(T item, IComparer<T> comparer) {
107      return Array.BinarySearch<T>(array, item, comparer);
108    }
109    public int BinarySearch(int index, int count, T item) {
110      return Array.BinarySearch<T>(array, index, count, item);
111    }
112    public int BinarySearch(int index, int count, T item, IComparer<T> comparer) {
113      return Array.BinarySearch<T>(array, index, count, item, comparer);
114    }
115
116    public bool Exists(Predicate<T> match) {
117      return Array.Exists<T>(array, match);
118    }
119
120    public T Find(Predicate<T> match) {
121      return Array.Find<T>(array, match);
122    }
123    public T[] FindAll(Predicate<T> match) {
124      return Array.FindAll<T>(array, match);
125    }
126    public T FindLast(Predicate<T> match) {
127      return Array.FindLast<T>(array, match);
128    }
129
130    public int FindIndex(Predicate<T> match) {
131      return Array.FindIndex<T>(array, match);
132    }
133    public int FindIndex(int startIndex, Predicate<T> match) {
134      return Array.FindIndex<T>(array, startIndex, match);
135    }
136    public int FindIndex(int startIndex, int count, Predicate<T> match) {
137      return Array.FindIndex<T>(array, startIndex, count, match);
138    }
139
140    public int FindLastIndex(Predicate<T> match) {
141      return Array.FindLastIndex<T>(array, match);
142    }
143    public int FindLastIndex(int startIndex, Predicate<T> match) {
144      return Array.FindLastIndex<T>(array, startIndex, match);
145    }
146    public int FindLastIndex(int startIndex, int count, Predicate<T> match) {
147      return Array.FindLastIndex<T>(array, startIndex, count, match);
148    }
149    #endregion
150
151    #region Manipulation
152    void ICollection<T>.Add(T item) {
153      throw new NotSupportedException();
154    }
155    void IList<T>.Insert(int index, T item) {
156      throw new NotSupportedException();
157    }
158    bool ICollection<T>.Remove(T item) {
159      throw new NotSupportedException();
160    }
161    void IList<T>.RemoveAt(int index) {
162      throw new NotSupportedException();
163    }
164
165    public void Clear(int index, int length) {
166      if (length > 0) {
167        IndexedItem<T>[] oldItems = GetIndexedItems(index, length);
168        Array.Clear(array, index, length);
169        OnPropertyChanged("Item[]");
170        OnItemsReplaced(GetIndexedItems(index, length), oldItems);
171      }
172    }
173    void ICollection<T>.Clear() {
174      Clear(0, array.Length);
175    }
176
177    public void Resize(int newSize) {
178      if (newSize != array.Length) {
179        IndexedItem<T>[] oldItems = GetIndexedItems();
180        Array.Resize<T>(ref array, newSize);
181        OnPropertyChanged("Length");
182        OnPropertyChanged("Item[]");
183        OnCollectionReset(GetIndexedItems(), oldItems);
184      }
185    }
186
187    public void Reverse() {
188      if (array.Length > 1) {
189        IndexedItem<T>[] oldItems = GetIndexedItems();
190        Array.Reverse(array);
191        OnPropertyChanged("Item[]");
192        OnItemsMoved(GetIndexedItems(), oldItems);
193      }
194    }
195    public void Reverse(int index, int length) {
196      if (length > 1) {
197        IndexedItem<T>[] oldItems = GetIndexedItems(index, length);
198        Array.Reverse(array, index, length);
199        OnPropertyChanged("Item[]");
200        OnItemsMoved(GetIndexedItems(index, length), oldItems);
201      }
202    }
203
204    public void Sort() {
205      if (array.Length > 1) {
206        IndexedItem<T>[] oldItems = GetIndexedItems();
207        Array.Sort<T>(array);
208        OnPropertyChanged("Item[]");
209        OnItemsMoved(GetIndexedItems(), oldItems);
210      }
211    }
212    public void Sort(Comparison<T> comparison) {
213      if (array.Length > 1) {
214        IndexedItem<T>[] oldItems = GetIndexedItems();
215        Array.Sort<T>(array, comparison);
216        OnPropertyChanged("Item[]");
217        OnItemsMoved(GetIndexedItems(), oldItems);
218      }
219    }
220    public void Sort(IComparer<T> comparer) {
221      if (array.Length > 1) {
222        IndexedItem<T>[] oldItems = GetIndexedItems();
223        Array.Sort<T>(array, comparer);
224        OnPropertyChanged("Item[]");
225        OnItemsMoved(GetIndexedItems(), oldItems);
226      }
227    }
228    public void Sort(int index, int length) {
229      if (length > 1) {
230        IndexedItem<T>[] oldItems = GetIndexedItems(index, length);
231        Array.Sort<T>(array, index, length);
232        OnPropertyChanged("Item[]");
233        OnItemsMoved(GetIndexedItems(index, length), oldItems);
234      }
235    }
236    public void Sort(int index, int length, IComparer<T> comparer) {
237      if (length > 1) {
238        IndexedItem<T>[] oldItems = GetIndexedItems(index, length);
239        Array.Sort<T>(array, index, length, comparer);
240        OnPropertyChanged("Item[]");
241        OnItemsMoved(GetIndexedItems(index, length), oldItems);
242      }
243    }
244    #endregion
245
246    #region Conversion
247    public ReadOnlyObservableArray<T> AsReadOnly() {
248      return new ReadOnlyObservableArray<T>(this);
249    }
250    public void CopyTo(T[] array) {
251      Array.Copy(this.array, array, this.array.Length);
252    }
253    public void CopyTo(T[] array, int arrayIndex) {
254      Array.Copy(this.array, 0, array, arrayIndex, this.array.Length);
255    }
256    public void CopyTo(int index, T[] array, int arrayIndex, int count) {
257      Array.Copy(this.array, index, array, arrayIndex, count);
258    }
259    public TOutput[] ConvertAll<TOutput>(Converter<T, TOutput> converter) {
260      return Array.ConvertAll<T, TOutput>(array, converter);
261    }
262    #endregion
263
264    #region Processing
265    public void ForEach(Action<T> action) {
266      Array.ForEach<T>(array, action);
267    }
268    public bool TrueForAll(Predicate<T> match) {
269      return Array.TrueForAll<T>(array, match);
270    }
271    #endregion
272
273    #region Enumeration
274    public IEnumerator<T> GetEnumerator() {
275      foreach (object o in ((IEnumerable)this))
276        yield return (T)o;
277    }
278    IEnumerator IEnumerable.GetEnumerator() {
279      return array.GetEnumerator();
280    }
281    #endregion
282
283    #region Events
284    [field: NonSerialized]
285    public event CollectionItemsChangedEventHandler<IndexedItem<T>> ItemsReplaced;
286    protected virtual void OnItemsReplaced(IEnumerable<IndexedItem<T>> items, IEnumerable<IndexedItem<T>> oldItems) {
287      CollectionItemsChangedEventHandler<IndexedItem<T>> handler = ItemsReplaced;
288      if (handler != null) handler(this, new CollectionItemsChangedEventArgs<IndexedItem<T>>(items, oldItems));
289    }
290
291    [field: NonSerialized]
292    public event CollectionItemsChangedEventHandler<IndexedItem<T>> ItemsMoved;
293    protected virtual void OnItemsMoved(IEnumerable<IndexedItem<T>> items, IEnumerable<IndexedItem<T>> oldItems) {
294      CollectionItemsChangedEventHandler<IndexedItem<T>> handler = ItemsMoved;
295      if (handler != null) handler(this, new CollectionItemsChangedEventArgs<IndexedItem<T>>(items, oldItems));
296    }
297
298    [field: NonSerialized]
299    public event CollectionItemsChangedEventHandler<IndexedItem<T>> CollectionReset;
300    protected virtual void OnCollectionReset(IEnumerable<IndexedItem<T>> items, IEnumerable<IndexedItem<T>> oldItems) {
301      CollectionItemsChangedEventHandler<IndexedItem<T>> handler = CollectionReset;
302      if (handler != null) handler(this, new CollectionItemsChangedEventArgs<IndexedItem<T>>(items, oldItems));
303    }
304
305    [field: NonSerialized]
306    public event PropertyChangedEventHandler PropertyChanged;
307    protected virtual void OnPropertyChanged(string propertyName) {
308      PropertyChangedEventHandler handler = PropertyChanged;
309      if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
310    }
311    #endregion
312
313    #region Private helpers
314    private IndexedItem<T>[] GetIndexedItems() {
315      IndexedItem<T>[] items = new IndexedItem<T>[array.Length];
316      for (int i = 0; i < array.Length; i++)
317        items[i] = new IndexedItem<T>(i, array[i]);
318      return items;
319    }
320    private IndexedItem<T>[] GetIndexedItems(int index, int count) {
321      IndexedItem<T>[] items = new IndexedItem<T>[count];
322      for (int i = 0; i < count; i++)
323        items[i] = new IndexedItem<T>(index + i, array[index + i]);
324      return items;
325    }
326    #endregion
327  }
328}
Note: See TracBrowser for help on using the repository browser.