Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Collections/3.3/ObservableSet.cs @ 2867

Last change on this file since 2867 was 2830, checked in by swagner, 14 years ago

Operator architecture refactoring (#95)

  • worked on operators and SGA
  • improved performance
File size: 7.5 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  public class ObservableSet<T> : IObservableSet<T> {
32    [Storable]
33    private HashSet<T> set;
34
35    #region Properties
36    public IEqualityComparer<T> Comparer {
37      get { return set.Comparer; }
38    }
39    public int Count {
40      get { return set.Count; }
41    }
42    bool ICollection<T>.IsReadOnly {
43      get { return ((ICollection<T>)set).IsReadOnly; }
44    }
45    #endregion
46
47    #region Constructors
48    public ObservableSet() {
49      set = new HashSet<T>();
50    }
51    public ObservableSet(IEnumerable<T> collection) {
52      set = new HashSet<T>(collection);
53    }
54    public ObservableSet(IEqualityComparer<T> comparer) {
55      set = new HashSet<T>(comparer);
56    }
57    public ObservableSet(IEnumerable<T> collection, IEqualityComparer<T> comparer) {
58      set = new HashSet<T>(collection, comparer);
59    }
60    #endregion
61
62    #region Access
63    public bool Contains(T item) {
64      return set.Contains(item);
65    }
66
67    public bool IsProperSubsetOf(IEnumerable<T> other) {
68      return set.IsProperSubsetOf(other);
69    }
70    public bool IsProperSupersetOf(IEnumerable<T> other) {
71      return set.IsProperSupersetOf(other);
72    }
73
74    public bool IsSubsetOf(IEnumerable<T> other) {
75      return set.IsSubsetOf(other);
76    }
77    public bool IsSupersetOf(IEnumerable<T> other) {
78      return set.IsSupersetOf(other);
79    }
80
81    public bool Overlaps(IEnumerable<T> other) {
82      return set.Overlaps(other);
83    }
84
85    public bool SetEquals(IEnumerable<T> other) {
86      return set.SetEquals(other);
87    }
88    #endregion
89
90    #region Manipulation
91    public bool Add(T item) {
92      if (set.Add(item)) {
93        OnPropertyChanged("Count");
94        OnItemsAdded(new T[] { item });
95        return true;
96      }
97      return false;
98    }
99    void ICollection<T>.Add(T item) {
100      Add(item);
101    }
102
103    public void ExceptWith(IEnumerable<T> other) {
104      if (other == null) throw new ArgumentNullException();
105      List<T> items = new List<T>();
106      foreach (T item in other) {
107        if (set.Remove(item))
108          items.Add(item);
109      }
110      if (items.Count > 0) {
111        OnPropertyChanged("Count");
112        OnItemsRemoved(items);
113      }
114    }
115
116    public void IntersectWith(IEnumerable<T> other) {
117      if (other == null) throw new ArgumentNullException();
118      HashSet<T> items = new HashSet<T>();
119      foreach (T item in set) {
120        if (!other.Contains(item)) items.Add(item);
121      }
122      if (items.Count > 0) {
123        set.ExceptWith(items);
124        OnPropertyChanged("Count");
125        OnItemsRemoved(items);
126      }
127    }
128
129    public bool Remove(T item) {
130      if (set.Remove(item)) {
131        OnPropertyChanged("Count");
132        OnItemsRemoved(new T[] { item });
133        return true;
134      }
135      return false;
136    }
137    public int RemoveWhere(Predicate<T> match) {
138      if (match == null) throw new ArgumentNullException();
139      HashSet<T> items = new HashSet<T>();
140      foreach (T item in set) {
141        if (match(item)) items.Add(item);
142      }
143      if (items.Count > 0) {
144        set.ExceptWith(items);
145        OnPropertyChanged("Count");
146        OnItemsRemoved(items);
147      }
148      return items.Count;
149    }
150
151    public void SymmetricExceptWith(IEnumerable<T> other) {
152      if (other == null) throw new ArgumentNullException();
153      List<T> addedItems = new List<T>();
154      List<T> removedItems = new List<T>();
155      foreach (T item in other) {
156        if (set.Contains(item)) {
157          set.Remove(item);
158          removedItems.Add(item);
159        } else {
160          set.Add(item);
161          addedItems.Add(item);
162        }
163      }
164      if ((addedItems.Count > 0) || (removedItems.Count > 0)) {
165        OnPropertyChanged("Count");
166        if (addedItems.Count > 0) OnItemsAdded(addedItems);
167        if (removedItems.Count > 0) OnItemsRemoved(removedItems);
168      }
169    }
170
171    public void UnionWith(IEnumerable<T> other) {
172      if (other == null) throw new ArgumentNullException();
173      List<T> items = new List<T>();
174      foreach (T item in other) {
175        if (set.Add(item)) {
176          items.Add(item);
177        }
178      }
179      if (items.Count > 0) {
180        OnPropertyChanged("Count");
181        OnItemsAdded(items);
182      }
183    }
184
185    public void Clear() {
186      if (set.Count > 0) {
187        T[] items = new T[set.Count];
188        set.CopyTo(items);
189        set.Clear();
190        OnPropertyChanged("Count");
191        OnCollectionReset(new T[0], items);
192      }
193    }
194    #endregion
195
196    #region Conversion
197    public ReadOnlyObservableSet<T> AsReadOnly() {
198      return new ReadOnlyObservableSet<T>(this);
199    }
200    public void CopyTo(T[] array) {
201      set.CopyTo(array);
202    }
203    public void CopyTo(T[] array, int arrayIndex) {
204      set.CopyTo(array, arrayIndex);
205    }
206    public void CopyTo(T[] array, int arrayIndex, int count) {
207      set.CopyTo(array, arrayIndex, count);
208    }
209    #endregion
210
211    #region Enumeration
212    public IEnumerator<T> GetEnumerator() {
213      return set.GetEnumerator();
214    }
215    IEnumerator IEnumerable.GetEnumerator() {
216      return set.GetEnumerator();
217    }
218    #endregion
219
220    #region Helpers
221    public void TrimExcess() {
222      set.TrimExcess();
223    }
224    #endregion
225
226    #region Events
227    [field: NonSerialized]
228    public event CollectionItemsChangedEventHandler<T> ItemsAdded;
229    protected virtual void OnItemsAdded(IEnumerable<T> items) {
230      if (ItemsAdded != null)
231        ItemsAdded(this, new CollectionItemsChangedEventArgs<T>(items));
232    }
233
234    [field: NonSerialized]
235    public event CollectionItemsChangedEventHandler<T> ItemsRemoved;
236    protected virtual void OnItemsRemoved(IEnumerable<T> items) {
237      if (ItemsRemoved != null)
238        ItemsRemoved(this, new CollectionItemsChangedEventArgs<T>(items));
239    }
240
241    [field: NonSerialized]
242    public event CollectionItemsChangedEventHandler<T> CollectionReset;
243    protected virtual void OnCollectionReset(IEnumerable<T> items, IEnumerable<T> oldItems) {
244      if (CollectionReset != null)
245        CollectionReset(this, new CollectionItemsChangedEventArgs<T>(items, oldItems));
246    }
247
248    [field: NonSerialized]
249    public event PropertyChangedEventHandler PropertyChanged;
250    protected virtual void OnPropertyChanged(string propertyName) {
251      if (PropertyChanged != null)
252        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
253    }
254    #endregion
255  }
256}
Note: See TracBrowser for help on using the repository browser.