Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Collections/3.3/ObservableList.cs @ 2574

Last change on this file since 2574 was 2574, checked in by swagner, 15 years ago

Restructured interfaces and base classes (#819)

File size: 12.0 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2008 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.Collections.ObjectModel;
26using System.Linq;
27using System.Text;
28using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
29
30namespace HeuristicLab.Collections {
31  [Serializable]
32  public class ObservableList<T> : IObservableList<T> {
33    [Storable]
34    private List<T> list;
35
36    #region Properties
37    public int Capacity {
38      get { return list.Capacity; }
39      set { list.Capacity = value; }
40    }
41    public int Count {
42      get { return list.Count; }
43    }
44    bool ICollection<T>.IsReadOnly {
45      get { return ((ICollection<T>)list).IsReadOnly; }
46    }
47    bool ICollection<IndexedItem<T>>.IsReadOnly {
48      get { return ((ICollection<T>)list).IsReadOnly; }
49    }
50
51    public T this[int index] {
52      get {
53        return list[index];
54      }
55      set {
56        T item = list[index];
57        list[index] = value;
58        OnItemsReplaced(new IndexedItem<T>[] { new IndexedItem<T>(index, value) }, new IndexedItem<T>[] { new IndexedItem<T>(index, item) });
59      }
60    }
61    #endregion
62
63    #region Constructors
64    public ObservableList() {
65      list = new List<T>();
66    }
67    public ObservableList(int capacity) {
68      list = new List<T>(capacity);
69    }
70    public ObservableList(IEnumerable<T> collection) {
71      list = new List<T>(collection);
72    }
73    #endregion
74
75    #region Access
76    public List<T> GetRange(int index, int count) {
77      return list.GetRange(index, count);
78    }
79
80    public bool Contains(T item) {
81      return list.Contains(item);
82    }
83    public bool Contains(IndexedItem<T> item) {
84      return list[item.Index].Equals(item.Value);
85    }
86
87    public int IndexOf(T item) {
88      return list.IndexOf(item);
89    }
90    public int IndexOf(T item, int index) {
91      return list.IndexOf(item, index);
92    }
93    public int IndexOf(T item, int index, int count) {
94      return list.IndexOf(item, index, count);
95    }
96
97    public int LastIndexOf(T item) {
98      return list.LastIndexOf(item);
99    }
100    public int LastIndexOf(T item, int index) {
101      return list.LastIndexOf(item, index);
102    }
103    public int LastIndexOf(T item, int index, int count) {
104      return list.LastIndexOf(item, index, count);
105    }
106
107    public int BinarySearch(T item) {
108      return list.BinarySearch(item);
109    }
110    public int BinarySearch(T item, IComparer<T> comparer) {
111      return list.BinarySearch(item, comparer);
112    }
113    public int BinarySearch(int index, int count, T item, IComparer<T> comparer) {
114      return list.BinarySearch(index, count, item, comparer);
115    }
116
117    public bool Exists(Predicate<T> match) {
118      return list.Exists(match);
119    }
120
121    public T Find(Predicate<T> match) {
122      return list.Find(match);
123    }
124    public List<T> FindAll(Predicate<T> match) {
125      return list.FindAll(match);
126    }
127    public T FindLast(Predicate<T> match) {
128      return list.FindLast(match);
129    }
130
131    public int FindIndex(Predicate<T> match) {
132      return list.FindIndex(match);
133    }
134    public int FindIndex(int startIndex, Predicate<T> match) {
135      return list.FindIndex(startIndex, match);
136    }
137    public int FindIndex(int startIndex, int count, Predicate<T> match) {
138      return list.FindIndex(startIndex, count, match);
139    }
140
141    public int FindLastIndex(Predicate<T> match) {
142      return list.FindLastIndex(match);
143    }
144    public int FindLastIndex(int startIndex, Predicate<T> match) {
145      return list.FindLastIndex(startIndex, match);
146    }
147    public int FindLastIndex(int startIndex, int count, Predicate<T> match) {
148      return list.FindLastIndex(startIndex, count, match);
149    }
150    #endregion
151
152    #region Manipulation
153    public void Add(T item) {
154      list.Add(item);
155      OnItemsAdded(new IndexedItem<T>[] { new IndexedItem<T>(list.Count - 1, item) });
156    }
157    public void Add(IndexedItem<T> item) {
158      list.Insert(item.Index, item.Value);
159      OnItemsAdded(new IndexedItem<T>[] { item });
160    }
161    public void AddRange(IEnumerable<T> collection) {
162      int index = list.Count;
163      list.AddRange(collection);
164      List<IndexedItem<T>> items = new List<IndexedItem<T>>();
165      foreach (T item in collection) {
166        items.Add(new IndexedItem<T>(index, item));
167        index++;
168      }
169      OnItemsAdded(items);
170    }
171
172    public void Insert(int index, T item) {
173      list.Insert(index, item);
174      OnItemsAdded(new IndexedItem<T>[] { new IndexedItem<T>(index, item) });
175    }
176    public void InsertRange(int index, IEnumerable<T> collection) {
177      list.InsertRange(index, collection);
178      List<IndexedItem<T>> items = new List<IndexedItem<T>>();
179      foreach (T item in collection) {
180        items.Add(new IndexedItem<T>(index, item));
181        index++;
182      }
183      OnItemsAdded(items);
184    }
185
186    public bool Remove(T item) {
187      int index = list.IndexOf(item);
188      if (index != -1) {
189        list.RemoveAt(index);
190        OnItemsRemoved(new IndexedItem<T>[] { new IndexedItem<T>(index, item) });
191        return true;
192      }
193      return false;
194    }
195    public bool Remove(IndexedItem<T> item) {
196      if (list[item.Index].Equals(item.Value)) {
197        list.RemoveAt(item.Index);
198        OnItemsRemoved(new IndexedItem<T>[] { item });
199        return true;
200      }
201      return false;
202    }
203    public int RemoveAll(Predicate<T> match) {
204      if (match == null) throw new ArgumentNullException();
205      List<IndexedItem<T>> items = new List<IndexedItem<T>>();
206      for (int i = 0; i < list.Count; i++) {
207        if (match(list[i]))
208          items.Add(new IndexedItem<T>(i, list[i]));
209      }
210      int result = list.RemoveAll(match);
211      OnItemsRemoved(items);
212      return result;
213    }
214    public void RemoveAt(int index) {
215      T item = list[index];
216      list.RemoveAt(index);
217      OnItemsRemoved(new IndexedItem<T>[] { new IndexedItem<T>(index, item) });
218    }
219    public void RemoveRange(int index, int count) {
220      IndexedItem<T>[] items = GetIndexedItems(index, count);
221      list.RemoveRange(index, count);
222      OnItemsRemoved(items);
223    }
224
225    public void Clear() {
226      IndexedItem<T>[] items = GetIndexedItems();
227      list.Clear();
228      OnCollectionReset(new IndexedItem<T>[0], items);
229    }
230
231    public void Reverse() {
232      IndexedItem<T>[] oldItems = GetIndexedItems();
233      list.Reverse();
234      OnItemsMoved(GetIndexedItems(), oldItems);
235    }
236    public void Reverse(int index, int count) {
237      IndexedItem<T>[] oldItems = GetIndexedItems(index, count);
238      list.Reverse(index, count);
239      OnItemsMoved(GetIndexedItems(index, count), oldItems);
240    }
241
242    public void Sort() {
243      IndexedItem<T>[] oldItems = GetIndexedItems();
244      list.Sort();
245      OnItemsMoved(GetIndexedItems(), oldItems);
246    }
247    public void Sort(Comparison<T> comparison) {
248      IndexedItem<T>[] oldItems = GetIndexedItems();
249      list.Sort(comparison);
250      OnItemsMoved(GetIndexedItems(), oldItems);
251    }
252    public void Sort(IComparer<T> comparer) {
253      IndexedItem<T>[] oldItems = GetIndexedItems();
254      list.Sort(comparer);
255      OnItemsMoved(GetIndexedItems(), oldItems);
256    }
257    public void Sort(int index, int count, IComparer<T> comparer) {
258      IndexedItem<T>[] oldItems = GetIndexedItems(index, count);
259      list.Sort(index, count, comparer);
260      OnItemsMoved(GetIndexedItems(index, count), oldItems);
261    }
262    #endregion
263
264    #region Conversion
265    public ReadOnlyCollection<T> AsReadOnly() {
266      return list.AsReadOnly();
267    }
268    public T[] ToArray() {
269      return list.ToArray();
270    }
271    void ICollection<T>.CopyTo(T[] array, int arrayIndex) {
272      list.CopyTo(array, arrayIndex);
273    }
274    void ICollection<IndexedItem<T>>.CopyTo(IndexedItem<T>[] array, int arrayIndex) {
275      IndexedItem<T>[] items = GetIndexedItems();
276      items.CopyTo(array, arrayIndex);
277    }
278    public List<TOutput> ConvertAll<TOutput>(Converter<T, TOutput> converter) {
279      return list.ConvertAll<TOutput>(converter);
280    }
281    #endregion
282
283    #region Processing
284    public void ForEach(Action<T> action) {
285      list.ForEach(action);
286    }
287    public bool TrueForAll(Predicate<T> match) {
288      return list.TrueForAll(match);
289    }
290    #endregion
291
292    #region Enumeration
293    public List<T>.Enumerator GetEnumerator() {
294      return list.GetEnumerator();
295    }
296    IEnumerator<T> IEnumerable<T>.GetEnumerator() {
297      return ((IEnumerable<T>)list).GetEnumerator();
298    }
299    IEnumerator<IndexedItem<T>> IEnumerable<IndexedItem<T>>.GetEnumerator() {
300      int index = -1;
301      foreach (T item in list) {
302        index++;
303        yield return new IndexedItem<T>(index, item);
304      }
305    }
306    IEnumerator IEnumerable.GetEnumerator() {
307      return ((IEnumerable)list).GetEnumerator();
308    }
309    #endregion
310
311    #region Helpers
312    public void TrimExcess() {
313      list.TrimExcess();
314    }
315    #endregion
316
317    #region Events
318    [field: NonSerialized]
319    public event CollectionItemsChangedEventHandler<IndexedItem<T>> ItemsAdded;
320    protected virtual void OnItemsAdded(IEnumerable<IndexedItem<T>> items) {
321      if (ItemsAdded != null)
322        ItemsAdded(this, new CollectionItemsChangedEventArgs<IndexedItem<T>>(items));
323    }
324
325    [field: NonSerialized]
326    public event CollectionItemsChangedEventHandler<IndexedItem<T>> ItemsRemoved;
327    protected virtual void OnItemsRemoved(IEnumerable<IndexedItem<T>> items) {
328      if (ItemsRemoved != null)
329        ItemsRemoved(this, new CollectionItemsChangedEventArgs<IndexedItem<T>>(items));
330    }
331
332    [field: NonSerialized]
333    public event CollectionItemsChangedEventHandler<IndexedItem<T>> ItemsReplaced;
334    protected virtual void OnItemsReplaced(IEnumerable<IndexedItem<T>> items, IEnumerable<IndexedItem<T>> oldItems) {
335      if (ItemsReplaced != null)
336        ItemsReplaced(this, new CollectionItemsChangedEventArgs<IndexedItem<T>>(items, oldItems));
337    }
338
339    [field: NonSerialized]
340    public event CollectionItemsChangedEventHandler<IndexedItem<T>> ItemsMoved;
341    protected virtual void OnItemsMoved(IEnumerable<IndexedItem<T>> items, IEnumerable<IndexedItem<T>> oldItems) {
342      if (ItemsMoved != null)
343        ItemsMoved(this, new CollectionItemsChangedEventArgs<IndexedItem<T>>(items, oldItems));
344    }
345
346    [field: NonSerialized]
347    public event CollectionItemsChangedEventHandler<IndexedItem<T>> CollectionReset;
348    protected virtual void OnCollectionReset(IEnumerable<IndexedItem<T>> items, IEnumerable<IndexedItem<T>> oldItems) {
349      if (CollectionReset != null)
350        CollectionReset(this, new CollectionItemsChangedEventArgs<IndexedItem<T>>(items, oldItems));
351    }
352    #endregion
353
354    #region Private helpers
355    private IndexedItem<T>[] GetIndexedItems() {
356      IndexedItem<T>[] items = new IndexedItem<T>[list.Count];
357      for (int i = 0; i < list.Count; i++)
358        items[i] = new IndexedItem<T>(i, list[i]);
359      return items;
360    }
361    private IndexedItem<T>[] GetIndexedItems(int index, int count) {
362      IndexedItem<T>[] items = new IndexedItem<T>[count];
363      for (int i = 0; i < count; i++)
364        items[i] = new IndexedItem<T>(index + i, list[index + i]);
365      return items;
366    }
367    #endregion
368  }
369}
Note: See TracBrowser for help on using the repository browser.