001    /*
002    Copyright (c) 1996-2011, Damon Hart-Davis
003    All rights reserved.
004    
005    Redistribution and use in source and binary forms, with or without
006    modification, are permitted provided that the following conditions are
007    met:
008    
009      * Redistributions of source code must retain the above copyright
010        notice, this list of conditions and the following disclaimer.
011    
012      * Redistributions in binary form must reproduce the above copyright
013        notice, this list of conditions and the following disclaimer in the
014        documentation and/or other materials provided with the
015        distribution.
016    
017    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
018    IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
019    TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
020    PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
021    OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
022    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
023    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
024    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
025    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
026    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
027    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
028    */
029    package org.hd.d.pg2k.svrCore;
030    
031    import java.io.Serializable;
032    
033    /**Support for anonymous tuples such as pairs.
034     */
035    public final class Tuple
036        {
037        /**Prevent construction of an instance. */
038        private Tuple() { }
039    
040        /**A simple immutable pair (though the referenced items may be mutable).
041         * Either or both fields can be null.
042         * <p />
043         * Equality and hash are based on that of the two members.
044         */
045        public static final class Pair<T1,T2> implements Serializable
046            {
047            public Pair(final T1 first, final T2 second)
048                {
049                this.first = first;
050                this.second = second;
051                }
052    
053            /**The first member of the pair. */
054            public final T1 first;
055    
056            /**The second member of the pair. */
057            public final T2 second;
058    
059            /**Human-readable form. */
060            @Override
061            public String toString()
062                { return("<" + first + "," + second + ">"); }
063    
064            /**Hash is based on that of the two members. */
065            @Override
066            public int hashCode()
067                {
068                return(
069                   ((first == null) ? 1 : first.hashCode()) ^
070                   ((second == null) ? 2 : second.hashCode())
071                          );
072                }
073    
074            /**Indicates whether some other object is "equal to" this one.
075             */
076            @Override
077            public boolean equals(final Object obj)
078                {
079                if(this == obj) { return(true); }
080                if(!(obj instanceof Pair)) { return(false); }
081    
082                final Pair other = (Pair) obj;
083                if(first == null)
084                    { if(other.first != null) { return(false); } }
085                else if(!first.equals(other.first)) { return(false); }
086                if(second == null)
087                    { if(other.second != null) { return(false); } }
088                else if(!second.equals(other.second)) { return(false); }
089    
090                return(true); // Equal!
091                }
092    
093            /**Unique Serialisation class ID generated by http://random&#46;hd&#46;org/. */
094            private static final long serialVersionUID = -5550500104003361224L;
095            }
096    
097    
098        /**A simple immutable Comparable pair (though the referenced items may be mutable).
099         * Either or both fields can be null.
100         * <p />
101         * Equality and hash are based on that of the two members.
102         * <p />
103         * The natural ordering given by compareTo() is determined by "first", with "second" breaking ties.
104         */
105        public static final class ComparablePair<T1 extends Comparable<T1>, T2 extends Comparable<T2>> implements
106                                                 Serializable, Comparable<ComparablePair<T1,T2>>
107            {
108            public ComparablePair(final T1 first, final T2 second)
109                {
110                this.first = first;
111                this.second = second;
112                }
113    
114            /**The first member of the pair. */
115            public final T1 first;
116    
117            /**The second member of the pair. */
118            public final T2 second;
119    
120            /**Human-readable form. */
121            @Override
122            public String toString()
123                { return("<" + first + "," + second + ">"); }
124    
125            /**Hash is based on that of the two members. */
126            @Override
127            public int hashCode()
128                {
129                return(
130                   ((first == null) ? 101 : first.hashCode()) ^
131                   ((second == null) ? 2002 : second.hashCode())
132                          );
133                }
134    
135            /**Indicates whether some other object is "equal to" this one.
136             */
137            @Override
138            public boolean equals(final Object obj)
139                {
140                if(this == obj) { return(true); }
141                if(!(obj instanceof ComparablePair)) { return(false); }
142    
143                final ComparablePair other = (ComparablePair) obj;
144                if(first == null)
145                    { if(other.first != null) { return(false); } }
146                else if(!first.equals(other.first)) { return(false); }
147                if(second == null)
148                    { if(other.second != null) { return(false); } }
149                else if(!second.equals(other.second)) { return(false); }
150    
151                return(true); // Equal!
152                }
153    
154            /**The ordering is determined by "first", with "second" breaking ties.
155             * Instances with nulls may not be comparable.
156             */
157            public int compareTo(final ComparablePair<T1,T2> other)
158                {
159                final int cf = first.compareTo(other.first);
160                if(cf != 0) { return(cf); }
161                return(second.compareTo(other.second));
162                }
163    
164            /**Unique Serialisation class ID generated by http://random&#46;hd&#46;org/. */
165            private static final long serialVersionUID = -5550500104003361225L;
166            }
167    
168    
169        /**A simple immutable 3-tuple/triple (though the referenced items may be mutable).
170         * Any or all fields can be null.
171         * <p />
172         * Equality and hash are based on that of the three members.
173         */
174        public static final class Triple<T1,T2,T3> implements Serializable
175            {
176            public Triple(final T1 first, final T2 second, final T3 third)
177                {
178                this.first = first;
179                this.second = second;
180                this.third = third;
181                }
182    
183            /**The first member of the triple. */
184            public final T1 first;
185    
186            /**The second member of the triple. */
187            public final T2 second;
188    
189            /**The third member of the triple. */
190            public final T3 third;
191    
192            /**Human-readable form. */
193            @Override
194            public String toString()
195                { return("<" + first + "," + second + "," + third + ">"); }
196    
197            /**Hash is based on that of the members. */
198            @Override
199            public int hashCode()
200                {
201                return(
202                   ((first == null) ? -101 : first.hashCode()) ^
203                   ((second == null) ? -10102 : Integer.rotateRight(second.hashCode(), 11)) ^
204                   ((third == null) ? -1010103 : Integer.rotateLeft(third.hashCode(), 11))
205                          );
206                }
207    
208            /**Indicates whether some other object is "equal to" this one. */
209            @Override
210            public boolean equals(final Object obj)
211                {
212                if(this == obj) { return(true); }
213                if(!(obj instanceof Triple)) { return(false); }
214    
215                final Triple other = (Triple) obj;
216                if(first == null)
217                    { if(other.first != null) { return(false); } }
218                else if(!first.equals(other.first)) { return(false); }
219                if(second == null)
220                    { if(other.second != null) { return(false); } }
221                else if(!second.equals(other.second)) { return(false); }
222                if(third == null)
223                    { if(other.third != null) { return(false); } }
224                else if(!third.equals(other.third)) { return(false); }
225    
226                return(true); // Equal!
227                }
228    
229            private static final long serialVersionUID = -4570980722385392466L;
230            }
231    
232        /**A simple immutable Comparable pair (though the referenced items may be mutable).
233         * Either or both fields can be null.
234         * <p />
235         * Equality and hash are based on that of the two members.
236         * <p />
237         * The natural ordering given by compareTo() is determined by "first", with "second" breaking ties.
238         */
239        public static final class ComparableTriple<T1 extends Comparable<T1>, T2 extends Comparable<T2>, T3 extends Comparable<T3>> implements
240                                                 Serializable, Comparable<ComparableTriple<T1,T2,T3>>
241            {
242            public ComparableTriple(final T1 first, final T2 second, final T3 third)
243                {
244                this.first = first;
245                this.second = second;
246                this.third = third;
247                }
248    
249            /**The first member of the triple. */
250            public final T1 first;
251    
252            /**The second member of the triple. */
253            public final T2 second;
254    
255            /**The third member of the triple. */
256            public final T3 third;
257    
258            /**Human-readable form. */
259            @Override
260            public String toString()
261                { return("<" + first + "," + second + "," + third + ">"); }
262    
263            /**Hash is based on that of the members. */
264            @Override
265            public int hashCode()
266                {
267                return(
268                   ((first == null) ? -101 : first.hashCode()) ^
269                   ((second == null) ? -10102 : second.hashCode()) ^
270                   ((third == null) ? -1010103 : third.hashCode())
271                          );
272                }
273    
274            /**Indicates whether some other object is "equal to" this one. */
275            @Override
276            public boolean equals(final Object obj)
277                {
278                if(this == obj) { return(true); }
279                if(!(obj instanceof ComparableTriple)) { return(false); }
280    
281                final ComparableTriple other = (ComparableTriple) obj;
282                if(first == null)
283                    { if(other.first != null) { return(false); } }
284                else if(!first.equals(other.first)) { return(false); }
285                if(second == null)
286                    { if(other.second != null) { return(false); } }
287                else if(!second.equals(other.second)) { return(false); }
288                if(third == null)
289                    { if(other.third != null) { return(false); } }
290                else if(!third.equals(other.third)) { return(false); }
291    
292                return(true); // Equal!
293                }
294    
295    
296            /**The ordering is determined by "first", with "second" and then "third" breaking ties.
297             * Instances with nulls may not be comparable.
298             */
299            public int compareTo(final ComparableTriple<T1,T2,T3> other)
300                {
301                final int cf1 = first.compareTo(other.first);
302                if(cf1 != 0) { return(cf1); }
303                final int cf2 = second.compareTo(other.second);
304                if(cf2 != 0) { return(cf2); }
305                return(third.compareTo(other.third));
306                }
307    
308            private static final long serialVersionUID = -4570980722385392467L;
309            }
310        }