Free cookie consent management tool by TermsFeed Policy Generator

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

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

Refactored HeuristicLab.Collections (#977)

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