Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 3109 was 3017, checked in by epitzer, 15 years ago

Merge StorableClassType.Empty into StorableClassType.MarkedOnly and make it the default if not specified (#548)

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