001: /*
002: * Primitive Collections for Java.
003: * Copyright (C) 2002 Søren Bak
004: *
005: * This library is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU Lesser General Public
007: * License as published by the Free Software Foundation; either
008: * version 2.1 of the License, or (at your option) any later version.
009: *
010: * This library is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * Lesser General Public License for more details.
014: *
015: * You should have received a copy of the GNU Lesser General Public
016: * License along with this library; if not, write to the Free Software
017: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
018: */
019: package bak.pcj.set;
020:
021: import bak.pcj.BooleanIterator;
022: import bak.pcj.BooleanCollection;
023: import bak.pcj.util.Exceptions;
024: import java.util.NoSuchElementException;
025:
026: /**
027: * This class represents sets of boolean values. The elements of the
028: * set are represented by a single state variable:
029: * 0 -> {}, 1 -> {F}, 2 -> {T}, and 3 -> {F, T}.
030: *
031: * @author Søren Bak
032: * @version 1.3 21-08-2003 20:22
033: * @since 1.0
034: */
035: public class BooleanDirectSet extends AbstractBooleanSet {
036:
037: private int values;
038:
039: private static final int EMPTY = 0;
040: private static final int FALSE = 1;
041: private static final int TRUE = 2;
042: private static final int FALSETRUE = 3;
043:
044: /**
045: * Creates a new empty set.
046: */
047: public BooleanDirectSet() {
048: values = EMPTY;
049: }
050:
051: /**
052: * Creates a new set with the same values as a specified
053: * collection.
054: *
055: * @param c
056: * the collection whose elements to add to the
057: * new set.
058: *
059: * @throws NullPointerException
060: * if <tt>c</tt> is <tt>null</tt>.
061: */
062: public BooleanDirectSet(BooleanCollection c) {
063: this ();
064: addAll(c);
065: }
066:
067: private void removeError() {
068: Exceptions.noElementToRemove();
069: }
070:
071: private void nextError() {
072: Exceptions.endOfIterator();
073: }
074:
075: public boolean contains(boolean v) {
076: switch (values) {
077: case EMPTY:
078: return false;
079: case FALSE:
080: return !v;
081: case TRUE:
082: return v;
083: case FALSETRUE:
084: return true;
085: default:
086: throw new RuntimeException("Internal error");
087: }
088: }
089:
090: public boolean add(boolean v) {
091: switch (values) {
092: case EMPTY:
093: if (v)
094: values = TRUE;
095: else
096: values = FALSE;
097: return true;
098: case FALSE:
099: if (v) {
100: values = FALSETRUE;
101: return true;
102: }
103: return false;
104: case TRUE:
105: if (!v) {
106: values = FALSETRUE;
107: return true;
108: }
109: return false;
110: case FALSETRUE:
111: return false;
112: default:
113: throw new RuntimeException("Internal error");
114: }
115: }
116:
117: public boolean remove(boolean v) {
118: switch (values) {
119: case EMPTY:
120: return false;
121: case FALSE:
122: if (!v) {
123: values = EMPTY;
124: return true;
125: }
126: return false;
127: case TRUE:
128: if (v) {
129: values = EMPTY;
130: return true;
131: }
132: return false;
133: case FALSETRUE:
134: if (v)
135: values = FALSE;
136: else
137: values = TRUE;
138: return true;
139: default:
140: throw new RuntimeException("Internal error");
141: }
142: }
143:
144: public int size() {
145: switch (values) {
146: case EMPTY:
147: return 0;
148: case FALSE:
149: return 1;
150: case TRUE:
151: return 1;
152: case FALSETRUE:
153: return 2;
154: default:
155: throw new RuntimeException("Internal error");
156: }
157: }
158:
159: public boolean isEmpty() {
160: return values == EMPTY;
161: }
162:
163: public void clear() {
164: values = EMPTY;
165: }
166:
167: public BooleanIterator iterator() {
168: return new BIterator();
169: }
170:
171: private class BIterator implements BooleanIterator {
172: private static final int I_EMPTY = 0;
173: private static final int I_F_0 = 1; // before F
174: private static final int I_F_1 = 2; // after F
175: private static final int I_F_2 = 3; // F removed
176: private static final int I_T_0 = 4; // before T
177: private static final int I_T_1 = 5; // after T
178: private static final int I_T_2 = 6; // T removed
179: private static final int I_FT_0 = 7; // before FT
180: private static final int I_FT_1 = 8; // between FT
181: private static final int I_FT_2 = 9; // between FT, F removed
182: private static final int I_FT_3 = 10; // after FT
183: private static final int I_FT_4 = 11; // after FT, T removed
184: private static final int I_FT_5 = 12; // after FT, F removed
185: private static final int I_FT_6 = 13; // after FT, FT removed
186:
187: private int state;
188:
189: BIterator() {
190: switch (values) {
191: case EMPTY:
192: state = I_EMPTY;
193: break;
194: case FALSE:
195: state = I_F_0;
196: break;
197: case TRUE:
198: state = I_T_0;
199: break;
200: case FALSETRUE:
201: state = I_FT_0;
202: break;
203: default:
204: throw new RuntimeException("Internal error");
205: }
206: }
207:
208: public boolean hasNext() {
209: switch (state) {
210: case I_EMPTY:
211: return false;
212: case I_F_0:
213: return true;
214: case I_F_1:
215: return false;
216: case I_F_2:
217: return false;
218: case I_T_0:
219: return true;
220: case I_T_1:
221: return false;
222: case I_T_2:
223: return false;
224: case I_FT_0:
225: return true;
226: case I_FT_1:
227: return true;
228: case I_FT_2:
229: return true;
230: case I_FT_3:
231: return false;
232: case I_FT_4:
233: return false;
234: case I_FT_5:
235: return false;
236: case I_FT_6:
237: return false;
238: default:
239: throw new RuntimeException("Internal error");
240: }
241: }
242:
243: public boolean next() {
244: switch (state) {
245: case I_EMPTY:
246: nextError();
247: case I_F_0:
248: state = I_F_1;
249: return false;
250: case I_F_1:
251: nextError();
252: case I_F_2:
253: nextError();
254: case I_T_0:
255: state = I_T_1;
256: return true;
257: case I_T_1:
258: nextError();
259: case I_T_2:
260: nextError();
261: case I_FT_0:
262: state = I_FT_1;
263: return false;
264: case I_FT_1:
265: state = I_FT_3;
266: return true;
267: case I_FT_2:
268: state = I_FT_5;
269: return true;
270: case I_FT_3:
271: nextError();
272: case I_FT_4:
273: nextError();
274: case I_FT_5:
275: nextError();
276: case I_FT_6:
277: nextError();
278: default:
279: throw new RuntimeException("Internal error");
280: }
281: }
282:
283: public void remove() {
284: switch (state) {
285: case I_EMPTY:
286: removeError();
287: case I_F_0:
288: removeError();
289: case I_F_1:
290: values = EMPTY;
291: state = I_F_2;
292: break;
293: case I_F_2:
294: removeError();
295: case I_T_0:
296: removeError();
297: case I_T_1:
298: values = EMPTY;
299: state = I_T_2;
300: break;
301: case I_T_2:
302: removeError();
303: case I_FT_0:
304: removeError();
305: case I_FT_1:
306: values = TRUE;
307: state = I_FT_2;
308: break;
309: case I_FT_2:
310: removeError();
311: case I_FT_3:
312: values = FALSE;
313: state = I_FT_4;
314: break;
315: case I_FT_4:
316: removeError();
317: case I_FT_5:
318: values = EMPTY;
319: state = I_FT_6;
320: break;
321: case I_FT_6:
322: removeError();
323: default:
324: throw new RuntimeException("Internal error");
325: }
326: }
327: }
328:
329: }
|