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