1 /***
2  * ASM: a very small and fast Java bytecode manipulation framework
3  * Copyright (c) 2000-2007 INRIA, France Telecom
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. Neither the name of the copyright holders nor the names of its
15  *    contributors may be used to endorse or promote products derived from
16  *    this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28  * THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 package org.mockito.asm.tree.analysis;
31 
32 import java.util.AbstractSet;
33 import java.util.HashSet;
34 import java.util.Iterator;
35 import java.util.Set;
36 
37 /**
38  * A set of at most two elements.
39  *
40  * @author Eric Bruneton
41  */
42 class SmallSet extends AbstractSet implements Iterator {
43 
44     // if e1 is null, e2 must be null; otherwise e2 must be different from e1
45 
46     Object e1, e2;
47 
48     static final Set EMPTY_SET = new SmallSet(null, null);
49 
SmallSet(final Object e1, final Object e2)50     SmallSet(final Object e1, final Object e2) {
51         this.e1 = e1;
52         this.e2 = e2;
53     }
54 
55     // -------------------------------------------------------------------------
56     // Implementation of inherited abstract methods
57     // -------------------------------------------------------------------------
58 
iterator()59     public Iterator iterator() {
60         return new SmallSet(e1, e2);
61     }
62 
size()63     public int size() {
64         return e1 == null ? 0 : (e2 == null ? 1 : 2);
65     }
66 
67     // -------------------------------------------------------------------------
68     // Implementation of the Iterator interface
69     // -------------------------------------------------------------------------
70 
hasNext()71     public boolean hasNext() {
72         return e1 != null;
73     }
74 
next()75     public Object next() {
76         Object e = e1;
77         e1 = e2;
78         e2 = null;
79         return e;
80     }
81 
remove()82     public void remove() {
83     }
84 
85     // -------------------------------------------------------------------------
86     // Utility methods
87     // -------------------------------------------------------------------------
88 
union(final SmallSet s)89     Set union(final SmallSet s) {
90         if ((s.e1 == e1 && s.e2 == e2) || (s.e1 == e2 && s.e2 == e1)) {
91             return this; // if the two sets are equal, return this
92         }
93         if (s.e1 == null) {
94             return this; // if s is empty, return this
95         }
96         if (e1 == null) {
97             return s; // if this is empty, return s
98         }
99         if (s.e2 == null) { // s contains exactly one element
100             if (e2 == null) {
101                 return new SmallSet(e1, s.e1); // necessarily e1 != s.e1
102             } else if (s.e1 == e1 || s.e1 == e2) { // s is included in this
103                 return this;
104             }
105         }
106         if (e2 == null) { // this contains exactly one element
107             // if (s.e2 == null) { // cannot happen
108             // return new SmallSet(e1, s.e1); // necessarily e1 != s.e1
109             // } else
110             if (e1 == s.e1 || e1 == s.e2) { // this in included in s
111                 return s;
112             }
113         }
114         // here we know that there are at least 3 distinct elements
115         HashSet r = new HashSet(4);
116         r.add(e1);
117         if (e2 != null) {
118             r.add(e2);
119         }
120         r.add(s.e1);
121         if (s.e2 != null) {
122             r.add(s.e2);
123         }
124         return r;
125     }
126 }
127