Free cookie consent management tool by TermsFeed Policy Generator

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

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

Operator architecture refactoring (#95)

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