Free cookie consent management tool by TermsFeed Policy Generator

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

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

Worked on ReadOnlyView property (#969).

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