Free cookie consent management tool by TermsFeed Policy Generator

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

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

Worked on HeuristicLab.Collections (#819)

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