
java.util.EnumSet Maven / Gradle / Ivy
/*
* Copyright 2016 Carlos Ballesteros Velasco
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package java.util;
public abstract class EnumSet> extends AbstractSet implements Cloneable, java.io.Serializable {
final Class elementType;
final Enum>[] universe;
private static Enum>[] ZERO_LENGTH_ENUM_ARRAY = new Enum>[0];
EnumSet(Class elementType, Enum>[] universe) {
this.elementType = elementType;
this.universe = universe;
}
public static > EnumSet noneOf(Class elementType) {
Enum>[] universe = getUniverse(elementType);
if (universe == null) throw new ClassCastException(elementType + " not an enum");
return new RegularEnumSet(elementType, universe);
}
public static > EnumSet allOf(Class elementType) {
EnumSet result = noneOf(elementType);
result.addAll();
return result;
}
abstract void addAll();
public static > EnumSet copyOf(EnumSet s) {
return s.clone();
}
public static > EnumSet copyOf(Collection c) {
if (c instanceof EnumSet) return ((EnumSet) c).clone();
if (c.isEmpty()) throw new IllegalArgumentException("Collection is empty");
Iterator i = c.iterator();
E first = i.next();
EnumSet result = EnumSet.of(first);
while (i.hasNext()) result.add(i.next());
return result;
}
public static > EnumSet complementOf(EnumSet s) {
EnumSet result = copyOf(s);
result.complement();
return result;
}
public static > EnumSet of(E e) {
EnumSet result = noneOf(e.getDeclaringClass());
result.add(e);
return result;
}
public static > EnumSet of(E e1, E e2) {
EnumSet result = noneOf(e1.getDeclaringClass());
result.add(e1);
result.add(e2);
return result;
}
public static > EnumSet of(E e1, E e2, E e3) {
EnumSet result = noneOf(e1.getDeclaringClass());
result.add(e1);
result.add(e2);
result.add(e3);
return result;
}
public static > EnumSet of(E e1, E e2, E e3, E e4) {
EnumSet result = noneOf(e1.getDeclaringClass());
result.add(e1);
result.add(e2);
result.add(e3);
result.add(e4);
return result;
}
public static > EnumSet of(E e1, E e2, E e3, E e4, E e5) {
EnumSet result = noneOf(e1.getDeclaringClass());
result.add(e1);
result.add(e2);
result.add(e3);
result.add(e4);
result.add(e5);
return result;
}
public static > EnumSet of(E first, E... rest) {
EnumSet result = noneOf(first.getDeclaringClass());
result.add(first);
for (E e : rest)
result.add(e);
return result;
}
public static > EnumSet range(E from, E to) {
if (from.compareTo(to) > 0) throw new IllegalArgumentException(from + " > " + to);
EnumSet result = noneOf(from.getDeclaringClass());
result.addRange(from, to);
return result;
}
abstract void addRange(E from, E to);
@SuppressWarnings("unchecked")
public EnumSet clone() {
try {
return (EnumSet) super.clone();
} catch (CloneNotSupportedException e) {
throw new AssertionError(e);
}
}
abstract void complement();
final void typeCheck(E e) {
Class> eClass = e.getClass();
if (eClass != elementType && eClass.getSuperclass() != elementType) {
throw new ClassCastException(eClass + " != " + elementType);
}
}
private static > E[] getUniverse(Class elementType) {
return elementType.getEnumConstants();
}
}
class RegularEnumSet> extends EnumSet {
private long elements = 0L;
RegularEnumSet(Class elementType, Enum>[] universe) {
super(elementType, universe);
}
void addRange(E from, E to) {
elements = (-1L >>> (from.ordinal() - to.ordinal() - 1)) << from.ordinal();
}
void addAll() {
if (universe.length != 0) elements = -1L >>> -universe.length;
}
void complement() {
if (universe.length == 0) return;
elements = ~elements;
elements &= -1L >>> -universe.length;
}
public Iterator iterator() {
return new EnumSetIterator();
}
private class EnumSetIterator> implements Iterator {
long unseen;
long lastReturned = 0;
EnumSetIterator() {
unseen = elements;
}
public boolean hasNext() {
return unseen != 0;
}
@SuppressWarnings("unchecked")
public E next() {
if (unseen == 0) throw new NoSuchElementException();
lastReturned = unseen & -unseen;
unseen -= lastReturned;
return (E) universe[Long.numberOfTrailingZeros(lastReturned)];
}
public void remove() {
if (lastReturned == 0) throw new IllegalStateException();
elements &= ~lastReturned;
lastReturned = 0;
}
}
public int size() {
return Long.bitCount(elements);
}
public boolean isEmpty() {
return elements == 0;
}
public boolean contains(Object e) {
if (e == null) return false;
Class> eClass = e.getClass();
if (eClass != elementType && eClass.getSuperclass() != elementType) return false;
return (elements & (1L << ((Enum>) e).ordinal())) != 0;
}
public boolean add(E e) {
typeCheck(e);
long oldElements = elements;
elements |= (1L << ((Enum>) e).ordinal());
return elements != oldElements;
}
public boolean remove(Object e) {
if (e == null) return false;
Class> eClass = e.getClass();
if (eClass != elementType && eClass.getSuperclass() != elementType) return false;
long oldElements = elements;
elements &= ~(1L << ((Enum>) e).ordinal());
return elements != oldElements;
}
public boolean containsAll(Collection> c) {
if (!(c instanceof RegularEnumSet)) return super.containsAll(c);
RegularEnumSet> es = (RegularEnumSet>) c;
if (es.elementType != elementType) return es.isEmpty();
return (es.elements & ~elements) == 0;
}
public boolean addAll(Collection extends E> c) {
if (!(c instanceof RegularEnumSet)) return super.addAll(c);
RegularEnumSet> es = (RegularEnumSet>) c;
if (es.elementType != elementType) {
if (es.isEmpty()) {
return false;
} else {
throw new ClassCastException(es.elementType + " != " + elementType);
}
}
long oldElements = elements;
elements |= es.elements;
return elements != oldElements;
}
public boolean removeAll(Collection> c) {
if (!(c instanceof RegularEnumSet)) return super.removeAll(c);
RegularEnumSet> es = (RegularEnumSet>) c;
if (es.elementType != elementType) return false;
long oldElements = elements;
elements &= ~es.elements;
return elements != oldElements;
}
public boolean retainAll(Collection> c) {
if (!(c instanceof RegularEnumSet)) return super.retainAll(c);
RegularEnumSet> es = (RegularEnumSet>) c;
if (es.elementType != elementType) {
boolean changed = (elements != 0);
elements = 0;
return changed;
}
long oldElements = elements;
elements &= es.elements;
return elements != oldElements;
}
public void clear() {
elements = 0;
}
public boolean equals(Object o) {
if (!(o instanceof RegularEnumSet)) return super.equals(o);
RegularEnumSet> es = (RegularEnumSet>) o;
if (es.elementType != elementType) return elements == 0 && es.elements == 0;
return es.elements == elements;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy