PageRenderTime 41ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/DotSpatial.Topology/Utilities/Iesi.Collections/Generic/DictionarySet.cs

#
C# | 238 lines | 98 code | 21 blank | 119 comment | 5 complexity | f22630927da3847446a7fb0a2d1fde07 MD5 | raw file
Possible License(s): CC-BY-SA-3.0, BSD-3-Clause
  1. // ********************************************************************************************************
  2. // Product Name: DotSpatial.Topology.dll
  3. // Description: The basic topology module for the new dotSpatial libraries
  4. // ********************************************************************************************************
  5. // The contents of this file are subject to the Lesser GNU Public License (LGPL)
  6. // you may not use this file except in compliance with the License. You may obtain a copy of the License at
  7. // http://dotspatial.codeplex.com/license Alternately, you can access an earlier version of this content from
  8. // the Net Topology Suite, which is also protected by the GNU Lesser Public License and the sourcecode
  9. // for the Net Topology Suite can be obtained here: http://sourceforge.net/projects/nts.
  10. //
  11. // Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
  12. // ANY KIND, either expressed or implied. See the License for the specific language governing rights and
  13. // limitations under the License.
  14. //
  15. // The Original Code is from the Net Topology Suite, which is a C# port of the Java Topology Suite.
  16. //
  17. // The Initial Developer to integrate this code into MapWindow 6.0 is Ted Dunsford.
  18. //
  19. // Contributor(s): (Open source contributors should list themselves and their modifications here).
  20. // | Name | Date | Comment
  21. // |----------------------|------------|------------------------------------------------------------
  22. // | | |
  23. // ********************************************************************************************************
  24. /* Copyright Š 2002-2004 by Aidant Systems, Inc., and by Jason Smith. */
  25. using System;
  26. using System.Collections.Generic;
  27. using System.Linq;
  28. namespace Iesi.Collections.Generic
  29. {
  30. /// <summary>
  31. /// <p><c>DictionarySet</c> is an abstract class that supports the creation of new <c>Set</c>
  32. /// types where the underlying data store is an <c>IDictionary</c> instance.</p>
  33. ///
  34. /// <p>You can use any object that implements the <c>IDictionary</c> interface to hold set data.
  35. /// You can define your own, or you can use one of the objects provided in the Framework.
  36. /// The type of <c>IDictionary</c> you choose will affect both the performance and the behavior
  37. /// of the <c>Set</c> using it. </p>
  38. ///
  39. /// <p>To make a <c>Set</c> typed based on your own <c>IDictionary</c>, simply derive a
  40. /// new class with a constructor that takes no parameters. Some <c>Set</c> implmentations
  41. /// cannot be defined with a default constructor. If this is the case for your class,
  42. /// you will need to override <c>Clone()</c> as well.</p>
  43. ///
  44. /// <p>It is also standard practice that at least one of your constructors takes an <c>ICollection</c> or
  45. /// an <c>ISet</c> as an argument.</p>
  46. /// </summary>
  47. [Serializable]
  48. public abstract class DictionarySet<T> : Set<T>
  49. {
  50. /// <summary>
  51. /// Provides the storage for elements in the <c>Set</c>, stored as the key-set
  52. /// of the <c>IDictionary</c> object. Set this object in the constructor
  53. /// if you create your own <c>Set</c> class.
  54. /// </summary>
  55. protected IDictionary<T, object> InternalDictionary { get; set; }
  56. private static readonly object _placeholderObject = new object();
  57. /// <summary>
  58. /// The placeholder object used as the value for the <c>IDictionary</c> instance.
  59. /// </summary>
  60. /// <remarks>
  61. /// There is a single instance of this object globally, used for all <c>Sets</c>.
  62. /// </remarks>
  63. protected object Placeholder
  64. {
  65. get { return _placeholderObject; }
  66. }
  67. /// <summary>
  68. /// Adds the specified element to this set if it is not already present.
  69. /// </summary>
  70. /// <param name="o">The object to add to the set.</param>
  71. /// <returns><c>true</c> is the object was added, <c>false</c> if it was already present.</returns>
  72. public override bool Add(T o)
  73. {
  74. //The object we are adding is just a placeholder. The thing we are
  75. //really concerned with is 'o', the key.
  76. if (!InternalDictionary.ContainsKey(o))
  77. {
  78. InternalDictionary.Add(o, _placeholderObject);
  79. return true;
  80. }
  81. return false;
  82. }
  83. /// <summary>
  84. /// Adds all the elements in the specified collection to the set if they are not already present.
  85. /// </summary>
  86. /// <param name="c">A collection of objects to add to the set.</param>
  87. /// <returns><c>true</c> is the set changed as a result of this operation, <c>false</c> if not.</returns>
  88. public override bool AddAll(ICollection<T> c)
  89. {
  90. bool changed = false;
  91. foreach (T o in c)
  92. {
  93. if (!Contains(o))
  94. {
  95. Add(o);
  96. changed = true;
  97. }
  98. }
  99. return changed;
  100. }
  101. /// <summary>
  102. /// Removes all objects from the set.
  103. /// </summary>
  104. public override void Clear()
  105. {
  106. InternalDictionary.Clear();
  107. }
  108. /// <summary>
  109. /// Returns <c>true</c> if this set contains the specified element.
  110. /// </summary>
  111. /// <param name="o">The element to look for.</param>
  112. /// <returns><c>true</c> if this set contains the specified element, <c>false</c> otherwise.</returns>
  113. public override bool Contains(T o)
  114. {
  115. return InternalDictionary.ContainsKey(o);
  116. }
  117. /// <summary>
  118. /// Returns <c>true</c> if the set contains all the elements in the specified collection.
  119. /// </summary>
  120. /// <param name="c">A collection of objects.</param>
  121. /// <returns><c>true</c> if the set contains all the elements in the specified collection, <c>false</c> otherwise.</returns>
  122. public override bool ContainsAll(ICollection<T> c)
  123. {
  124. return c.All(Contains);
  125. }
  126. /// <summary>
  127. /// Returns <c>true</c> if this set contains no elements.
  128. /// </summary>
  129. public override bool IsEmpty
  130. {
  131. get { return InternalDictionary.Count == 0; }
  132. }
  133. /// <summary>
  134. /// Removes the specified element from the set.
  135. /// </summary>
  136. /// <param name="o">The element to be removed.</param>
  137. /// <returns><c>true</c> if the set contained the specified element, <c>false</c> otherwise.</returns>
  138. public override bool Remove(T o)
  139. {
  140. bool contained = Contains(o);
  141. if (contained)
  142. {
  143. InternalDictionary.Remove(o);
  144. }
  145. return contained;
  146. }
  147. /// <summary>
  148. /// Remove all the specified elements from this set, if they exist in this set.
  149. /// </summary>
  150. /// <param name="c">A collection of elements to remove.</param>
  151. /// <returns><c>true</c> if the set was modified as a result of this operation.</returns>
  152. public override bool RemoveAll(ICollection<T> c)
  153. {
  154. return c.Aggregate(false, (current, o) => current | Remove(o));
  155. }
  156. /// <summary>
  157. /// Retains only the elements in this set that are contained in the specified collection.
  158. /// </summary>
  159. /// <param name="c">Collection that defines the set of elements to be retained.</param>
  160. /// <returns><c>true</c> if this set changed as a result of this operation.</returns>
  161. public override bool RetainAll(ICollection<T> c)
  162. {
  163. //Put data from C into a set so we can use the Contains() method.
  164. Set<T> cSet = new HybridSet<T>(c);
  165. //We are going to build a set of elements to remove.
  166. Set<T> removeSet = new HybridSet<T>();
  167. foreach (T o in this)
  168. {
  169. //If C does not contain O, then we need to remove O from our
  170. //set. We can't do this while iterating through our set, so
  171. //we put it into RemoveSet for later.
  172. if (!cSet.Contains(o))
  173. removeSet.Add(o);
  174. }
  175. return RemoveAll(removeSet);
  176. }
  177. /// <summary>
  178. /// Copies the elements in the <c>Set</c> to an array. The type of array needs
  179. /// to be compatible with the objects in the <c>Set</c>, obviously.
  180. /// </summary>
  181. /// <param name="array">An array that will be the target of the copy operation.</param>
  182. /// <param name="index">The zero-based index where copying will start.</param>
  183. public override void CopyTo(T[] array, int index)
  184. {
  185. InternalDictionary.Keys.CopyTo(array, index);
  186. }
  187. /// <summary>
  188. /// The number of elements contained in this collection.
  189. /// </summary>
  190. public override int Count
  191. {
  192. get { return InternalDictionary.Count; }
  193. }
  194. /// <summary>
  195. /// Gets an enumerator for the elements in the <c>Set</c>.
  196. /// </summary>
  197. /// <returns>An <c>IEnumerator</c> over the elements in the <c>Set</c>.</returns>
  198. public override IEnumerator<T> GetEnumerator()
  199. {
  200. return InternalDictionary.Keys.GetEnumerator();
  201. }
  202. /// <summary>
  203. /// Gets a boolean that indicates whether the dictionary is synchronized
  204. /// </summary>
  205. public override bool IsSynchronized
  206. {
  207. get { return false; }
  208. }
  209. /// <summary>
  210. /// Not Implemented
  211. /// </summary>
  212. public override object SyncRoot
  213. {
  214. get { throw new NotImplementedException("Implement me!"); }
  215. }
  216. }
  217. }