001    /*
002    Copyright (c) 1996-2012, 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             * With pairwise elements considered equal if both null or equals() is true.
076             */
077            @Override
078            public boolean equals(final Object obj)
079                {
080                if(this == obj) { return(true); }
081                if(!(obj instanceof Pair)) { return(false); }
082    
083                final Pair other = (Pair) obj;
084                if(first == null)
085                    { if(other.first != null) { return(false); } }
086                else if(!first.equals(other.first)) { return(false); }
087                if(second == null)
088                    { if(other.second != null) { return(false); } }
089                else if(!second.equals(other.second)) { return(false); }
090    
091                return(true); // Equal!
092                }
093    
094            /**Unique Serialisation class ID generated by http://random&#46;hd&#46;org/. */
095            private static final long serialVersionUID = -5550500104003361224L;
096            }
097    
098    
099        /**A simple immutable Comparable pair (though the referenced items may be mutable).
100         * Either or both fields can be null.
101         * <p />
102         * Equality and hash are based on that of the two members.
103         * <p />
104         * The natural ordering given by compareTo() is determined by "first", with "second" breaking ties.
105         */
106        public static final class ComparablePair<T1 extends Comparable<T1>, T2 extends Comparable<T2>> implements
107                                                 Serializable, Comparable<ComparablePair<T1,T2>>
108            {
109            public ComparablePair(final T1 first, final T2 second)
110                {
111                this.first = first;
112                this.second = second;
113                }
114    
115            /**The first member of the pair. */
116            public final T1 first;
117    
118            /**The second member of the pair. */
119            public final T2 second;
120    
121            /**Human-readable form. */
122            @Override
123            public String toString()
124                { return("<" + first + "," + second + ">"); }
125    
126            /**Hash is based on that of the two members. */
127            @Override
128            public int hashCode()
129                {
130                return(
131                   ((first == null) ? 101 : first.hashCode()) ^
132                   ((second == null) ? 2002 : second.hashCode())
133                          );
134                }
135    
136            /**Indicates whether some other object is "equal to" this one.
137             */
138            @Override
139            public boolean equals(final Object obj)
140                {
141                if(this == obj) { return(true); }
142                if(!(obj instanceof ComparablePair)) { return(false); }
143    
144                final ComparablePair other = (ComparablePair) obj;
145                if(first == null)
146                    { if(other.first != null) { return(false); } }
147                else if(!first.equals(other.first)) { return(false); }
148                if(second == null)
149                    { if(other.second != null) { return(false); } }
150                else if(!second.equals(other.second)) { return(false); }
151    
152                return(true); // Equal!
153                }
154    
155            /**The ordering is determined by "first", with "second" breaking ties.
156             * Instances with nulls may not be comparable.
157             */
158            public int compareTo(final ComparablePair<T1,T2> other)
159                {
160                final int cf = first.compareTo(other.first);
161                if(cf != 0) { return(cf); }
162                return(second.compareTo(other.second));
163                }
164    
165            /**Unique Serialisation class ID generated by http://random&#46;hd&#46;org/. */
166            private static final long serialVersionUID = -5550500104003361225L;
167            }
168    
169    
170        /**A simple immutable 3-tuple/triple (though the referenced items may be mutable).
171         * Any or all fields can be null.
172         * <p />
173         * Equality and hash are based on that of the three members.
174         */
175        public static final class Triple<T1,T2,T3> implements Serializable
176            {
177            public Triple(final T1 first, final T2 second, final T3 third)
178                {
179                this.first = first;
180                this.second = second;
181                this.third = third;
182                }
183    
184            /**The first member of the triple. */
185            public final T1 first;
186    
187            /**The second member of the triple. */
188            public final T2 second;
189    
190            /**The third member of the triple. */
191            public final T3 third;
192    
193            /**Human-readable form. */
194            @Override
195            public String toString()
196                { return("<" + first + "," + second + "," + third + ">"); }
197    
198            /**Hash is based on that of the members. */
199            @Override
200            public int hashCode()
201                {
202                return(
203                   ((first == null) ? -101 : first.hashCode()) ^
204                   ((second == null) ? -10102 : Integer.rotateRight(second.hashCode(), 11)) ^
205                   ((third == null) ? -1010103 : Integer.rotateLeft(third.hashCode(), 11))
206                          );
207                }
208    
209            /**Indicates whether some other object is "equal to" this one. */
210            @Override
211            public boolean equals(final Object obj)
212                {
213                if(this == obj) { return(true); }
214                if(!(obj instanceof Triple)) { return(false); }
215    
216                final Triple other = (Triple) obj;
217                if(first == null)
218                    { if(other.first != null) { return(false); } }
219                else if(!first.equals(other.first)) { return(false); }
220                if(second == null)
221                    { if(other.second != null) { return(false); } }
222                else if(!second.equals(other.second)) { return(false); }
223                if(third == null)
224                    { if(other.third != null) { return(false); } }
225                else if(!third.equals(other.third)) { return(false); }
226    
227                return(true); // Equal!
228                }
229    
230            private static final long serialVersionUID = -4570980722385392466L;
231            }
232    
233        /**A simple immutable Comparable pair (though the referenced items may be mutable).
234         * Either or both fields can be null.
235         * <p />
236         * Equality and hash are based on that of the two members.
237         * <p />
238         * The natural ordering given by compareTo() is determined by "first", with "second" breaking ties.
239         */
240        public static final class ComparableTriple<T1 extends Comparable<T1>, T2 extends Comparable<T2>, T3 extends Comparable<T3>> implements
241                                                 Serializable, Comparable<ComparableTriple<T1,T2,T3>>
242            {
243            public ComparableTriple(final T1 first, final T2 second, final T3 third)
244                {
245                this.first = first;
246                this.second = second;
247                this.third = third;
248                }
249    
250            /**The first member of the triple. */
251            public final T1 first;
252    
253            /**The second member of the triple. */
254            public final T2 second;
255    
256            /**The third member of the triple. */
257            public final T3 third;
258    
259            /**Human-readable form. */
260            @Override
261            public String toString()
262                { return("<" + first + "," + second + "," + third + ">"); }
263    
264            /**Hash is based on that of the members. */
265            @Override
266            public int hashCode()
267                {
268                return(
269                   ((first == null) ? -101 : first.hashCode()) ^
270                   ((second == null) ? -10102 : second.hashCode()) ^
271                   ((third == null) ? -1010103 : third.hashCode())
272                          );
273                }
274    
275            /**Indicates whether some other object is "equal to" this one. */
276            @Override
277            public boolean equals(final Object obj)
278                {
279                if(this == obj) { return(true); }
280                if(!(obj instanceof ComparableTriple)) { return(false); }
281    
282                final ComparableTriple other = (ComparableTriple) obj;
283                if(first == null)
284                    { if(other.first != null) { return(false); } }
285                else if(!first.equals(other.first)) { return(false); }
286                if(second == null)
287                    { if(other.second != null) { return(false); } }
288                else if(!second.equals(other.second)) { return(false); }
289                if(third == null)
290                    { if(other.third != null) { return(false); } }
291                else if(!third.equals(other.third)) { return(false); }
292    
293                return(true); // Equal!
294                }
295    
296    
297            /**The ordering is determined by "first", with "second" and then "third" breaking ties.
298             * Instances with nulls may not be comparable.
299             */
300            public int compareTo(final ComparableTriple<T1,T2,T3> other)
301                {
302                final int cf1 = first.compareTo(other.first);
303                if(cf1 != 0) { return(cf1); }
304                final int cf2 = second.compareTo(other.second);
305                if(cf2 != 0) { return(cf2); }
306                return(third.compareTo(other.third));
307                }
308    
309            private static final long serialVersionUID = -4570980722385392467L;
310            }
311        }