diff --git a/src/java/com/threerings/util/StreamableEnumSet.java b/src/java/com/threerings/util/StreamableEnumSet.java index d6397aa04..7f67c853f 100644 --- a/src/java/com/threerings/util/StreamableEnumSet.java +++ b/src/java/com/threerings/util/StreamableEnumSet.java @@ -24,6 +24,7 @@ package com.threerings.util; import java.io.IOException; import java.util.AbstractSet; import java.util.Arrays; +import java.util.Collection; import java.util.ConcurrentModificationException; import java.util.EnumSet; import java.util.Iterator; @@ -41,6 +42,97 @@ import com.threerings.io.Streamable; public class StreamableEnumSet> extends AbstractSet implements Cloneable, Streamable { + /** + * Creates an empty set of the specified type. + */ + public static > StreamableEnumSet noneOf (Class elementType) + { + return new StreamableEnumSet(elementType); + } + + /** + * Creates a set containing all elements of the specified type. + */ + public static > StreamableEnumSet allOf (Class elementType) + { + StreamableEnumSet set = new StreamableEnumSet(elementType); + for (E constant : elementType.getEnumConstants()) { + set.add(constant); + } + return set; + } + + /** + * Creates a set containing all elements in the collection provided (which must have at least + * one element, unless it is a StreamableEnumSet). + */ + public static > StreamableEnumSet copyOf (Collection s) + { + if (s instanceof StreamableEnumSet) { + @SuppressWarnings("unchecked") StreamableEnumSet set = (StreamableEnumSet)s; + return copyOf(set); + } + if (s.isEmpty()) { + throw new IllegalArgumentException("Collection must have at least one element."); + } + StreamableEnumSet set = new StreamableEnumSet( + s.iterator().next().getDeclaringClass()); + set.addAll(s); + return set; + } + + /** + * Creates a set containing all elements in the set provided. + */ + public static > StreamableEnumSet copyOf (StreamableEnumSet s) + { + @SuppressWarnings("unchecked") StreamableEnumSet set = + (StreamableEnumSet)s.clone(); + return set; + } + + /** + * Creates a set containing all elements not in the set provided. + */ + public static > StreamableEnumSet complementOf (StreamableEnumSet s) + { + Class elementType = s._elementType; + StreamableEnumSet set = new StreamableEnumSet(elementType); + for (E constant : elementType.getEnumConstants()) { + if (!s.contains(constant)) { + set.add(constant); + } + } + return set; + } + + /** + * Creates a set consisting of the specified elements. + */ + public static > StreamableEnumSet of (E first, E... rest) + { + StreamableEnumSet set = new StreamableEnumSet(first.getDeclaringClass()); + set.add(first); + for (E e : rest) { + set.add(e); + } + return set; + } + + /** + * Creates a set that includes all enum constants in the specified (inclusive) range. + */ + public static > StreamableEnumSet range (E from, E to) + { + Class elementType = from.getDeclaringClass(); + StreamableEnumSet set = new StreamableEnumSet(elementType); + E[] constants = elementType.getEnumConstants(); + for (int ii = from.ordinal(), last = to.ordinal(); ii <= last; ii++) { + set.add(constants[ii]); + } + return set; + } + /** * Creates a new, empty enum set for storing elements of the specified class. */ @@ -190,7 +282,11 @@ public class StreamableEnumSet> extends AbstractSet } initContents(); in.read(_contents); - updateSize(); + + // count set bits to initialize size + for (byte b : _contents) { + _size += Integer.bitCount(b & 0xFF); + } } /** @@ -212,17 +308,6 @@ public class StreamableEnumSet> extends AbstractSet _contents = new byte[(constants >> 3) + ((constants & 0x07) == 0 ? 0 : 1)]; } - /** - * Computes the size from the contents. - */ - protected void updateSize () - { - _size = 0; - for (byte b : _contents) { - _size += Integer.bitCount(b & 0xFF); - } - } - /** The element type. */ protected Class _elementType;