source: trunk/CrypPlugins/WorkspaceManager/View/VisualComponents/CryptoLineView/PowerCollections/Pair.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.0 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    /// Stores a pair of objects within a single struct. This struct is useful to use as the
16    /// T of a collection, or as the TKey or TValue of a dictionary.
17    /// </summary>
18    [Serializable]
19    public struct Pair<TFirst, TSecond> : IComparable, IComparable<Pair<TFirst, TSecond>>
20    {
21        /// <summary>
22        /// Comparers for the first and second type that are used to compare
23        /// values.
24        /// </summary>
25
26        private static readonly IComparer<TFirst> firstComparer = Comparer<TFirst>.Default;
27        private static readonly IComparer<TSecond> secondComparer = Comparer<TSecond>.Default;
28
29        private static readonly IEqualityComparer<TFirst> firstEqualityComparer = EqualityComparer<TFirst>.Default;
30        private static readonly IEqualityComparer<TSecond> secondEqualityComparer = EqualityComparer<TSecond>.Default;
31
32        /// <summary>
33        /// The first element of the pair.
34        /// </summary>
35        public TFirst First;
36
37        /// <summary>
38        /// The second element of the pair.
39        /// </summary>
40        public TSecond Second;
41
42        /// <summary>
43        /// Creates a new pair with given first and second elements.
44        /// </summary>
45        /// <param name="first">The first element of the pair.</param>
46        /// <param name="second">The second element of the pair.</param>
47        public Pair(TFirst first, TSecond second)
48        {
49            this.First = first;
50            this.Second = second;
51        }
52
53        /// <summary>
54        /// Creates a new pair using elements from a KeyValuePair structure. The
55        /// First element gets the Key, and the Second elements gets the Value.
56        /// </summary>
57        /// <param name="keyAndValue">The KeyValuePair to initialize the Pair with .</param>
58        public Pair(KeyValuePair<TFirst,TSecond> keyAndValue)
59        {
60            this.First = keyAndValue.Key;
61            this.Second = keyAndValue.Value;
62        }
63
64        /// <summary>
65        /// Determines if this pair is equal to another object. The pair is equal to another object
66        /// if that object is a Pair, both element types are the same, and the first and second elements
67        /// both compare equal using object.Equals.
68        /// </summary>
69        /// <param name="obj">Object to compare for equality.</param>
70        /// <returns>True if the objects are equal. False if the objects are not equal.</returns>
71        public override bool Equals(object obj)
72        {
73            if (obj != null && obj is Pair<TFirst, TSecond>) {
74                Pair<TFirst, TSecond> other = (Pair<TFirst, TSecond>)obj;
75
76                return Equals(other);
77            }
78            else {
79                return false;
80            }
81        }
82
83        /// <summary>
84        /// Determines if this pair is equal to another pair. The pair is equal if  the first and second elements
85        /// both compare equal using IComparable&lt;T&gt;.Equals or object.Equals.
86        /// </summary>
87        /// <param name="other">Pair to compare with for equality.</param>
88        /// <returns>True if the pairs are equal. False if the pairs are not equal.</returns>
89        public bool Equals(Pair<TFirst, TSecond> other)
90        {
91            return firstEqualityComparer.Equals(First, other.First) && secondEqualityComparer.Equals(Second, other.Second);
92        }
93
94        /// <summary>
95        /// Returns a hash code for the pair, suitable for use in a hash-table or other hashed collection.
96        /// Two pairs that compare equal (using Equals) will have the same hash code. The hash code for
97        /// the pair is derived by combining the hash codes for each of the two elements of the pair.
98        /// </summary>
99        /// <returns>The hash code.</returns>
100        public override int GetHashCode()
101        {
102            // Build the hash code from the hash codes of First and Second.
103            int hashFirst = (First == null) ? 0x61E04917 : First.GetHashCode();
104            int hashSecond = (Second == null) ? 0x198ED6A3 : Second.GetHashCode();
105            return hashFirst ^ hashSecond;
106        }
107
108        /// <summary>
109        /// <para> Compares this pair to another pair of the some type. The pairs are compared by using
110        /// the IComparable&lt;T&gt; or IComparable interface on TFirst and TSecond. The pairs
111        /// are compared by their first elements first, if their first elements are equal, then they
112        /// are compared by their second elements.</para>
113        /// <para>If either TFirst or TSecond does not implement IComparable&lt;T&gt; or IComparable, then
114        /// an NotSupportedException is thrown, because the pairs cannot be compared.</para>
115        /// </summary>
116        /// <param name="other">The pair to compare to.</param>
117        /// <returns>An integer indicating how this pair compares to <paramref name="other"/>. Less
118        /// than zero indicates this pair is less than <paramref name="other"/>. Zero indicate this pair is
119        /// equals to <paramref name="other"/>. Greater than zero indicates this pair is greater than
120        /// <paramref name="other"/>.</returns>
121        /// <exception cref="NotSupportedException">Either FirstSecond or TSecond is not comparable
122        /// via the IComparable&lt;T&gt; or IComparable interfaces.</exception>
123        public int CompareTo(Pair<TFirst, TSecond> other)
124        {
125            try {
126                int firstCompare = firstComparer.Compare(First, other.First);
127                if (firstCompare != 0)
128                    return firstCompare;
129                else
130                    return secondComparer.Compare(Second, other.Second);
131            }
132            catch (ArgumentException) {
133                // Determine which type caused the problem for a better error message.
134                if (!typeof(IComparable<TFirst>).IsAssignableFrom(typeof(TFirst)) &&
135                    !typeof(System.IComparable).IsAssignableFrom(typeof(TFirst))) {
136                    throw new NotSupportedException(string.Format(Strings.UncomparableType, typeof(TFirst).FullName));
137                }
138                else if (!typeof(IComparable<TSecond>).IsAssignableFrom(typeof(TSecond)) &&
139                    !typeof(System.IComparable).IsAssignableFrom(typeof(TSecond))) {
140                    throw new NotSupportedException(string.Format(Strings.UncomparableType, typeof(TSecond).FullName));
141                }
142                else
143                    throw;              // Hmmm. Unclear why we got the ArgumentException.
144            }
145        }
146
147        /// <summary>
148        /// <para> Compares this pair to another pair of the some type. The pairs are compared by using
149        /// the IComparable&lt;T&gt; or IComparable interface on TFirst and TSecond. The pairs
150        /// are compared by their first elements first, if their first elements are equal, then they
151        /// are compared by their second elements.</para>
152        /// <para>If either TFirst or TSecond does not implement IComparable&lt;T&gt; or IComparable, then
153        /// an NotSupportedException is thrown, because the pairs cannot be compared.</para>
154        /// </summary>
155        /// <param name="obj">The pair to compare to.</param>
156        /// <returns>An integer indicating how this pair compares to <paramref name="obj"/>. Less
157        /// than zero indicates this pair is less than <paramref name="obj"/>. Zero indicate this pair is
158        /// equals to <paramref name="obj"/>. Greater than zero indicates this pair is greater than
159        /// <paramref name="obj"/>.</returns>
160        /// <exception cref="ArgumentException"><paramref name="obj"/> is not of the correct type.</exception>
161        /// <exception cref="NotSupportedException">Either FirstSecond or TSecond is not comparable
162        /// via the IComparable&lt;T&gt; or IComparable interfaces.</exception>
163        int IComparable.CompareTo(object obj)
164        {
165            if (obj is Pair<TFirst, TSecond>)
166                return CompareTo((Pair<TFirst, TSecond>)obj);
167            else
168                throw new ArgumentException(Strings.BadComparandType, "obj");
169        }
170
171        /// <summary>
172        /// Returns a string representation of the pair. The string representation of the pair is
173        /// of the form:
174        /// <c>First: {0}, Second: {1}</c>
175        /// where {0} is the result of First.ToString(), and {1} is the result of Second.ToString() (or
176        /// "null" if they are null.)
177        /// </summary>
178        /// <returns> The string representation of the pair.</returns>
179        public override string ToString()
180        {
181            return string.Format("First: {0}, Second: {1}", (First == null) ? "null" : First.ToString(), (Second == null) ? "null" : Second.ToString());
182        }
183
184        /// <summary>
185        /// Determines if two pairs are equal. Two pairs are equal if  the first and second elements
186        /// both compare equal using IComparable&lt;T&gt;.Equals or object.Equals.
187        /// </summary>
188        /// <param name="pair1">First pair to compare.</param>
189        /// <param name="pair2">Second pair to compare.</param>
190        /// <returns>True if the pairs are equal. False if the pairs are not equal.</returns>
191        public static bool operator ==(Pair<TFirst, TSecond> pair1, Pair<TFirst, TSecond> pair2)
192        {
193            return firstEqualityComparer.Equals(pair1.First, pair2.First) && secondEqualityComparer.Equals(pair1.Second, pair2.Second);
194        }
195
196        /// <summary>
197        /// Determines if two pairs are not equal. Two pairs are equal if  the first and second elements
198        /// both compare equal using IComparable&lt;T&gt;.Equals or object.Equals.
199        /// </summary>
200        /// <param name="pair1">First pair to compare.</param>
201        /// <param name="pair2">Second pair to compare.</param>
202        /// <returns>True if the pairs are not equal. False if the pairs are equal.</returns>
203        public static bool operator !=(Pair<TFirst, TSecond> pair1, Pair<TFirst, TSecond> pair2)
204        {
205            return !(pair1 == pair2);
206        }
207
208        /// <summary>
209        /// Converts a Pair to a KeyValuePair. The Key part of the KeyValuePair gets
210        /// the First element, and the Value part of the KeyValuePair gets the Second
211        /// elements.
212        /// </summary>
213        /// <param name="pair">Pair to convert.</param>
214        /// <returns>The KeyValuePair created from <paramref name="pair"/>.</returns>
215        public static explicit operator KeyValuePair<TFirst,TSecond>(Pair<TFirst, TSecond> pair)
216        {
217            return new KeyValuePair<TFirst, TSecond>(pair.First, pair.Second);
218        }
219
220        /// <summary>
221        /// Converts this Pair to a KeyValuePair. The Key part of the KeyValuePair gets
222        /// the First element, and the Value part of the KeyValuePair gets the Second
223        /// elements.
224        /// </summary>
225        /// <returns>The KeyValuePair created from this Pair.</returns>
226        public KeyValuePair<TFirst, TSecond> ToKeyValuePair()
227        {
228            return new KeyValuePair<TFirst, TSecond>(this.First, this.Second);
229        }
230
231        /// <summary>
232        /// Converts a KeyValuePair structure into a Pair. The
233        /// First element gets the Key, and the Second element gets the Value.
234        /// </summary>
235        /// <param name="keyAndValue">The KeyValuePair to convert.</param>
236        /// <returns>The Pair created by converted the KeyValuePair into a Pair.</returns>
237        public static explicit operator Pair<TFirst, TSecond>(KeyValuePair<TFirst, TSecond> keyAndValue)
238        {
239            return new Pair<TFirst, TSecond>(keyAndValue);
240        }
241    }
242}
Note: See TracBrowser for help on using the repository browser.