source: trunk/CrypPlugins/WorkspaceManager/View/VisualComponents/CryptoLineView/PowerCollections/Comparers.cs @ 1927

Last change on this file since 1927 was 1927, checked in by matkovic, 11 years ago

-added PowerCollection library
-added QuadTree
-improved path finding performance

File size: 12.1 KB
Line 
1//******************************
2// Written by Peter Golde
3// Copyright (c) 2004-2007, Wintellect
4//
5// Use and restribution of this code is subject to the license agreement
6// contained in the file "License.txt" accompanying this file.
7//******************************
8
9using System;
10using System.Collections.Generic;
11
12namespace Wintellect.PowerCollections
13{
14    /// <summary>
15    /// A collection of methods to create IComparer and IEqualityComparer instances in various ways.
16    /// </summary>
17    internal static class Comparers
18    {
19        /// <summary>
20        /// Class to change an IEqualityComparer&lt;TKey&gt; to an IEqualityComparer&lt;KeyValuePair&lt;TKey, TValue&gt;&gt;
21        /// Only the keys are compared.
22        /// </summary>
23        [Serializable]
24        class KeyValueEqualityComparer<TKey, TValue> : IEqualityComparer<KeyValuePair<TKey, TValue>>
25        {
26            private readonly IEqualityComparer<TKey> keyEqualityComparer;
27
28            public KeyValueEqualityComparer(IEqualityComparer<TKey> keyEqualityComparer)
29            { this.keyEqualityComparer = keyEqualityComparer; }
30
31            public bool Equals(KeyValuePair<TKey, TValue> x, KeyValuePair<TKey, TValue> y)
32            { return keyEqualityComparer.Equals(x.Key, y.Key); }
33
34            public int GetHashCode(KeyValuePair<TKey, TValue> obj)
35            {
36                return Util.GetHashCode(obj.Key, keyEqualityComparer);
37            }
38
39            public override bool Equals(object obj)
40            {
41                if (obj is KeyValueEqualityComparer<TKey, TValue>)
42                    return object.Equals(keyEqualityComparer, ((KeyValueEqualityComparer<TKey, TValue>)obj).keyEqualityComparer);
43                else
44                    return false;
45            }
46
47            public override int GetHashCode()
48            {
49                return keyEqualityComparer.GetHashCode();
50            }
51        }
52
53        /// <summary>
54        /// Class to change an IComparer&lt;TKey&gt; to an IComparer&lt;KeyValuePair&lt;TKey, TValue&gt;&gt;
55        /// Only the keys are compared.
56        /// </summary>
57        [Serializable]
58        class KeyValueComparer<TKey, TValue> : IComparer<KeyValuePair<TKey, TValue>>
59        {
60            private readonly IComparer<TKey> keyComparer;
61
62            public KeyValueComparer(IComparer<TKey> keyComparer)
63            { this.keyComparer = keyComparer; }
64
65            public int Compare(KeyValuePair<TKey, TValue> x, KeyValuePair<TKey, TValue> y)
66            { return keyComparer.Compare(x.Key, y.Key); }
67
68            public override bool Equals(object obj)
69            {
70                if (obj is KeyValueComparer<TKey, TValue>)
71                    return object.Equals(keyComparer, ((KeyValueComparer<TKey, TValue>)obj).keyComparer);
72                else
73                    return false;
74            }
75
76            public override int GetHashCode()
77            {
78                return keyComparer.GetHashCode();
79            }
80        }
81
82        /// <summary>
83        /// Class to change an IComparer&lt;TKey&gt; and IComparer&lt;TValue&gt; to an IComparer&lt;KeyValuePair&lt;TKey, TValue&gt;&gt;
84        /// Keys are compared, followed by values.
85        /// </summary>
86        [Serializable]
87        class PairComparer<TKey, TValue> : IComparer<KeyValuePair<TKey, TValue>>
88        {
89            private readonly IComparer<TKey> keyComparer;
90            private readonly IComparer<TValue> valueComparer;
91
92            public PairComparer(IComparer<TKey> keyComparer, IComparer<TValue> valueComparer)
93            { 
94                this.keyComparer = keyComparer; 
95                this.valueComparer = valueComparer; 
96            }
97
98            public int Compare(KeyValuePair<TKey, TValue> x, KeyValuePair<TKey, TValue> y)
99            {
100                int keyCompare = keyComparer.Compare(x.Key, y.Key);
101
102                if (keyCompare == 0)
103                    return valueComparer.Compare(x.Value, y.Value);
104                else
105                    return keyCompare;
106            }
107
108            public override bool Equals(object obj)
109            {
110                if (obj is PairComparer<TKey, TValue>)
111                    return object.Equals(keyComparer, ((PairComparer<TKey, TValue>)obj).keyComparer) &&
112                        object.Equals(valueComparer, ((PairComparer<TKey, TValue>)obj).valueComparer);
113                else
114                    return false;
115            }
116
117            public override int GetHashCode()
118            {
119                return keyComparer.GetHashCode() ^ valueComparer.GetHashCode();
120            }
121        }
122
123        /// <summary>
124        /// Class to change an Comparison&lt;T&gt; to an IComparer&lt;T&gt;.
125        /// </summary>
126        [Serializable]
127        class ComparisonComparer<T> : IComparer<T>
128        {
129            private readonly Comparison<T> comparison;
130
131            public ComparisonComparer(Comparison<T> comparison)
132            { this.comparison = comparison; }
133
134            public int Compare(T x, T y)
135            { return comparison(x, y); }
136
137            public override bool Equals(object obj)
138            {
139                if (obj is ComparisonComparer<T>)
140                    return comparison.Equals(((ComparisonComparer<T>)obj).comparison);
141                else
142                    return false;
143            }
144
145            public override int GetHashCode()
146            {
147                return comparison.GetHashCode();
148            }
149        }
150
151        /// <summary>
152        /// Class to change an Comparison&lt;TKey&gt; to an IComparer&lt;KeyValuePair&lt;TKey, TValue&gt;&gt;.
153        /// GetHashCode cannot be used on this class.
154        /// </summary>
155        [Serializable]
156        class ComparisonKeyValueComparer<TKey, TValue> : IComparer<KeyValuePair<TKey, TValue>>
157        {
158            private readonly Comparison<TKey> comparison;
159
160            public ComparisonKeyValueComparer(Comparison<TKey> comparison)
161            { this.comparison = comparison; }
162
163            public int Compare(KeyValuePair<TKey, TValue> x, KeyValuePair<TKey, TValue> y)
164            { return comparison(x.Key, y.Key); }
165
166            public override bool Equals(object obj)
167            {
168                if (obj is ComparisonKeyValueComparer<TKey, TValue>)
169                    return comparison.Equals(((ComparisonKeyValueComparer<TKey, TValue>)obj).comparison);
170                else
171                    return false;
172            }
173
174            public override int GetHashCode()
175            {
176                return comparison.GetHashCode();
177            }
178        }
179
180
181        /// <summary>
182        /// Given an Comparison on a type, returns an IComparer on that type.
183        /// </summary>
184        /// <typeparam name="T">T to compare.</typeparam>
185        /// <param name="comparison">Comparison delegate on T</param>
186        /// <returns>IComparer that uses the comparison.</returns>
187        public static IComparer<T> ComparerFromComparison<T>(Comparison<T> comparison)
188        {
189            if (comparison == null)
190                throw new ArgumentNullException("comparison");
191
192            return new ComparisonComparer<T>(comparison);
193        }
194
195        /// <summary>
196        /// Given an IComparer on TKey, returns an IComparer on
197        /// key-value Pairs.
198        /// </summary>
199        /// <typeparam name="TKey">TKey of the pairs</typeparam>
200        /// <typeparam name="TValue">TValue of the apris</typeparam>
201        /// <param name="keyComparer">IComparer on TKey</param>
202        /// <returns>IComparer for comparing key-value pairs.</returns>
203        public static IComparer<KeyValuePair<TKey, TValue>> ComparerKeyValueFromComparerKey<TKey, TValue>(IComparer<TKey> keyComparer)
204        {
205            if (keyComparer == null)
206                throw new ArgumentNullException("keyComparer");
207
208            return new KeyValueComparer<TKey, TValue>(keyComparer);
209        }
210
211        /// <summary>
212        /// Given an IEqualityComparer on TKey, returns an IEqualityComparer on
213        /// key-value Pairs.
214        /// </summary>
215        /// <typeparam name="TKey">TKey of the pairs</typeparam>
216        /// <typeparam name="TValue">TValue of the apris</typeparam>
217        /// <param name="keyEqualityComparer">IComparer on TKey</param>
218        /// <returns>IEqualityComparer for comparing key-value pairs.</returns>
219        public static IEqualityComparer<KeyValuePair<TKey, TValue>> EqualityComparerKeyValueFromComparerKey<TKey, TValue>(IEqualityComparer<TKey> keyEqualityComparer)
220        {
221            if (keyEqualityComparer == null)
222                throw new ArgumentNullException("keyEqualityComparer");
223
224            return new KeyValueEqualityComparer<TKey, TValue>(keyEqualityComparer);
225        }
226
227        /// <summary>
228        /// Given an IComparer on TKey and TValue, returns an IComparer on
229        /// key-value Pairs of TKey and TValue, comparing first keys, then values.
230        /// </summary>
231        /// <typeparam name="TKey">TKey of the pairs</typeparam>
232        /// <typeparam name="TValue">TValue of the apris</typeparam>
233        /// <param name="keyComparer">IComparer on TKey</param>
234        /// <param name="valueComparer">IComparer on TValue</param>
235        /// <returns>IComparer for comparing key-value pairs.</returns>
236        public static IComparer<KeyValuePair<TKey, TValue>> ComparerPairFromKeyValueComparers<TKey, TValue>(IComparer<TKey> keyComparer, IComparer<TValue> valueComparer)
237        {
238            if (keyComparer == null)
239                throw new ArgumentNullException("keyComparer");
240            if (valueComparer == null)
241                throw new ArgumentNullException("valueComparer");
242
243            return new PairComparer<TKey, TValue>(keyComparer, valueComparer);
244        }
245
246        /// <summary>
247        /// Given an Comparison on TKey, returns an IComparer on
248        /// key-value Pairs.
249        /// </summary>
250        /// <typeparam name="TKey">TKey of the pairs</typeparam>
251        /// <typeparam name="TValue">TValue of the apris</typeparam>
252        /// <param name="keyComparison">Comparison delegate on TKey</param>
253        /// <returns>IComparer for comparing key-value pairs.</returns>
254        public static IComparer<KeyValuePair<TKey, TValue>> ComparerKeyValueFromComparisonKey<TKey, TValue>(Comparison<TKey> keyComparison)
255        {
256            if (keyComparison == null)
257                throw new ArgumentNullException("keyComparison");
258
259            return new ComparisonKeyValueComparer<TKey, TValue>(keyComparison);
260        }
261
262        /// <summary>
263        /// Given an element type, check that it implements IComparable&lt;T&gt; or IComparable, then returns
264        /// a IComparer that can be used to compare elements of that type.
265        /// </summary>
266        /// <returns>The IComparer&lt;T&gt; instance.</returns>
267        /// <exception cref="InvalidOperationException">T does not implement IComparable&lt;T&gt;.</exception>
268        public static IComparer<T> DefaultComparer<T>()
269        {
270            if (typeof(IComparable<T>).IsAssignableFrom(typeof(T)) ||
271                typeof(System.IComparable).IsAssignableFrom(typeof(T))) 
272            {
273                return Comparer<T>.Default;
274            }
275            else {
276                throw new InvalidOperationException(string.Format(Strings.UncomparableType, typeof(T).FullName));
277            }
278        }
279
280        /// <summary>
281        /// Given an key and value type, check that TKey implements IComparable&lt;T&gt; or IComparable, then returns
282        /// a IComparer that can be used to compare KeyValuePairs of those types.
283        /// </summary>
284        /// <returns>The IComparer&lt;KeyValuePair&lt;TKey, TValue&gt;&gt; instance.</returns>
285        /// <exception cref="InvalidOperationException">TKey does not implement IComparable&lt;T&gt;.</exception>
286        public static IComparer<KeyValuePair<TKey, TValue>> DefaultKeyValueComparer<TKey, TValue>()
287        {
288            IComparer<TKey> keyComparer = DefaultComparer<TKey>();
289            return ComparerKeyValueFromComparerKey<TKey,TValue>(keyComparer);
290        }
291    }
292}
Note: See TracBrowser for help on using the repository browser.