1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/emul/compact/src/main/java/java/util/EnumSet.java Sun Sep 22 21:49:42 2013 +0200
1.3 @@ -0,0 +1,443 @@
1.4 +/*
1.5 + * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
1.7 + *
1.8 + * This code is free software; you can redistribute it and/or modify it
1.9 + * under the terms of the GNU General Public License version 2 only, as
1.10 + * published by the Free Software Foundation. Oracle designates this
1.11 + * particular file as subject to the "Classpath" exception as provided
1.12 + * by Oracle in the LICENSE file that accompanied this code.
1.13 + *
1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
1.17 + * version 2 for more details (a copy is included in the LICENSE file that
1.18 + * accompanied this code).
1.19 + *
1.20 + * You should have received a copy of the GNU General Public License version
1.21 + * 2 along with this work; if not, write to the Free Software Foundation,
1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1.23 + *
1.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
1.25 + * or visit www.oracle.com if you need additional information or have any
1.26 + * questions.
1.27 + */
1.28 +
1.29 +package java.util;
1.30 +
1.31 +import sun.misc.SharedSecrets;
1.32 +
1.33 +/**
1.34 + * A specialized {@link Set} implementation for use with enum types. All of
1.35 + * the elements in an enum set must come from a single enum type that is
1.36 + * specified, explicitly or implicitly, when the set is created. Enum sets
1.37 + * are represented internally as bit vectors. This representation is
1.38 + * extremely compact and efficient. The space and time performance of this
1.39 + * class should be good enough to allow its use as a high-quality, typesafe
1.40 + * alternative to traditional <tt>int</tt>-based "bit flags." Even bulk
1.41 + * operations (such as <tt>containsAll</tt> and <tt>retainAll</tt>) should
1.42 + * run very quickly if their argument is also an enum set.
1.43 + *
1.44 + * <p>The iterator returned by the <tt>iterator</tt> method traverses the
1.45 + * elements in their <i>natural order</i> (the order in which the enum
1.46 + * constants are declared). The returned iterator is <i>weakly
1.47 + * consistent</i>: it will never throw {@link ConcurrentModificationException}
1.48 + * and it may or may not show the effects of any modifications to the set that
1.49 + * occur while the iteration is in progress.
1.50 + *
1.51 + * <p>Null elements are not permitted. Attempts to insert a null element
1.52 + * will throw {@link NullPointerException}. Attempts to test for the
1.53 + * presence of a null element or to remove one will, however, function
1.54 + * properly.
1.55 + *
1.56 + * <P>Like most collection implementations, <tt>EnumSet</tt> is not
1.57 + * synchronized. If multiple threads access an enum set concurrently, and at
1.58 + * least one of the threads modifies the set, it should be synchronized
1.59 + * externally. This is typically accomplished by synchronizing on some
1.60 + * object that naturally encapsulates the enum set. If no such object exists,
1.61 + * the set should be "wrapped" using the {@link Collections#synchronizedSet}
1.62 + * method. This is best done at creation time, to prevent accidental
1.63 + * unsynchronized access:
1.64 + *
1.65 + * <pre>
1.66 + * Set<MyEnum> s = Collections.synchronizedSet(EnumSet.noneOf(MyEnum.class));
1.67 + * </pre>
1.68 + *
1.69 + * <p>Implementation note: All basic operations execute in constant time.
1.70 + * They are likely (though not guaranteed) to be much faster than their
1.71 + * {@link HashSet} counterparts. Even bulk operations execute in
1.72 + * constant time if their argument is also an enum set.
1.73 + *
1.74 + * <p>This class is a member of the
1.75 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
1.76 + * Java Collections Framework</a>.
1.77 + *
1.78 + * @author Josh Bloch
1.79 + * @since 1.5
1.80 + * @see EnumMap
1.81 + * @serial exclude
1.82 + */
1.83 +public abstract class EnumSet<E extends Enum<E>> extends AbstractSet<E>
1.84 + implements Cloneable, java.io.Serializable
1.85 +{
1.86 + /**
1.87 + * The class of all the elements of this set.
1.88 + */
1.89 + final Class<E> elementType;
1.90 +
1.91 + /**
1.92 + * All of the values comprising T. (Cached for performance.)
1.93 + */
1.94 + final Enum[] universe;
1.95 +
1.96 + private static Enum[] ZERO_LENGTH_ENUM_ARRAY = new Enum[0];
1.97 +
1.98 + EnumSet(Class<E>elementType, Enum[] universe) {
1.99 + this.elementType = elementType;
1.100 + this.universe = universe;
1.101 + }
1.102 +
1.103 + /**
1.104 + * Creates an empty enum set with the specified element type.
1.105 + *
1.106 + * @param elementType the class object of the element type for this enum
1.107 + * set
1.108 + * @throws NullPointerException if <tt>elementType</tt> is null
1.109 + */
1.110 + public static <E extends Enum<E>> EnumSet<E> noneOf(Class<E> elementType) {
1.111 + Enum[] universe = getUniverse(elementType);
1.112 + if (universe == null)
1.113 + throw new ClassCastException(elementType + " not an enum");
1.114 +
1.115 + if (universe.length <= 64)
1.116 + return new RegularEnumSet<>(elementType, universe);
1.117 + else
1.118 + return new JumboEnumSet<>(elementType, universe);
1.119 + }
1.120 +
1.121 + /**
1.122 + * Creates an enum set containing all of the elements in the specified
1.123 + * element type.
1.124 + *
1.125 + * @param elementType the class object of the element type for this enum
1.126 + * set
1.127 + * @throws NullPointerException if <tt>elementType</tt> is null
1.128 + */
1.129 + public static <E extends Enum<E>> EnumSet<E> allOf(Class<E> elementType) {
1.130 + EnumSet<E> result = noneOf(elementType);
1.131 + result.addAll();
1.132 + return result;
1.133 + }
1.134 +
1.135 + /**
1.136 + * Adds all of the elements from the appropriate enum type to this enum
1.137 + * set, which is empty prior to the call.
1.138 + */
1.139 + abstract void addAll();
1.140 +
1.141 + /**
1.142 + * Creates an enum set with the same element type as the specified enum
1.143 + * set, initially containing the same elements (if any).
1.144 + *
1.145 + * @param s the enum set from which to initialize this enum set
1.146 + * @throws NullPointerException if <tt>s</tt> is null
1.147 + */
1.148 + public static <E extends Enum<E>> EnumSet<E> copyOf(EnumSet<E> s) {
1.149 + return s.clone();
1.150 + }
1.151 +
1.152 + /**
1.153 + * Creates an enum set initialized from the specified collection. If
1.154 + * the specified collection is an <tt>EnumSet</tt> instance, this static
1.155 + * factory method behaves identically to {@link #copyOf(EnumSet)}.
1.156 + * Otherwise, the specified collection must contain at least one element
1.157 + * (in order to determine the new enum set's element type).
1.158 + *
1.159 + * @param c the collection from which to initialize this enum set
1.160 + * @throws IllegalArgumentException if <tt>c</tt> is not an
1.161 + * <tt>EnumSet</tt> instance and contains no elements
1.162 + * @throws NullPointerException if <tt>c</tt> is null
1.163 + */
1.164 + public static <E extends Enum<E>> EnumSet<E> copyOf(Collection<E> c) {
1.165 + if (c instanceof EnumSet) {
1.166 + return ((EnumSet<E>)c).clone();
1.167 + } else {
1.168 + if (c.isEmpty())
1.169 + throw new IllegalArgumentException("Collection is empty");
1.170 + Iterator<E> i = c.iterator();
1.171 + E first = i.next();
1.172 + EnumSet<E> result = EnumSet.of(first);
1.173 + while (i.hasNext())
1.174 + result.add(i.next());
1.175 + return result;
1.176 + }
1.177 + }
1.178 +
1.179 + /**
1.180 + * Creates an enum set with the same element type as the specified enum
1.181 + * set, initially containing all the elements of this type that are
1.182 + * <i>not</i> contained in the specified set.
1.183 + *
1.184 + * @param s the enum set from whose complement to initialize this enum set
1.185 + * @throws NullPointerException if <tt>s</tt> is null
1.186 + */
1.187 + public static <E extends Enum<E>> EnumSet<E> complementOf(EnumSet<E> s) {
1.188 + EnumSet<E> result = copyOf(s);
1.189 + result.complement();
1.190 + return result;
1.191 + }
1.192 +
1.193 + /**
1.194 + * Creates an enum set initially containing the specified element.
1.195 + *
1.196 + * Overloadings of this method exist to initialize an enum set with
1.197 + * one through five elements. A sixth overloading is provided that
1.198 + * uses the varargs feature. This overloading may be used to create
1.199 + * an enum set initially containing an arbitrary number of elements, but
1.200 + * is likely to run slower than the overloadings that do not use varargs.
1.201 + *
1.202 + * @param e the element that this set is to contain initially
1.203 + * @throws NullPointerException if <tt>e</tt> is null
1.204 + * @return an enum set initially containing the specified element
1.205 + */
1.206 + public static <E extends Enum<E>> EnumSet<E> of(E e) {
1.207 + EnumSet<E> result = noneOf(e.getDeclaringClass());
1.208 + result.add(e);
1.209 + return result;
1.210 + }
1.211 +
1.212 + /**
1.213 + * Creates an enum set initially containing the specified elements.
1.214 + *
1.215 + * Overloadings of this method exist to initialize an enum set with
1.216 + * one through five elements. A sixth overloading is provided that
1.217 + * uses the varargs feature. This overloading may be used to create
1.218 + * an enum set initially containing an arbitrary number of elements, but
1.219 + * is likely to run slower than the overloadings that do not use varargs.
1.220 + *
1.221 + * @param e1 an element that this set is to contain initially
1.222 + * @param e2 another element that this set is to contain initially
1.223 + * @throws NullPointerException if any parameters are null
1.224 + * @return an enum set initially containing the specified elements
1.225 + */
1.226 + public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2) {
1.227 + EnumSet<E> result = noneOf(e1.getDeclaringClass());
1.228 + result.add(e1);
1.229 + result.add(e2);
1.230 + return result;
1.231 + }
1.232 +
1.233 + /**
1.234 + * Creates an enum set initially containing the specified elements.
1.235 + *
1.236 + * Overloadings of this method exist to initialize an enum set with
1.237 + * one through five elements. A sixth overloading is provided that
1.238 + * uses the varargs feature. This overloading may be used to create
1.239 + * an enum set initially containing an arbitrary number of elements, but
1.240 + * is likely to run slower than the overloadings that do not use varargs.
1.241 + *
1.242 + * @param e1 an element that this set is to contain initially
1.243 + * @param e2 another element that this set is to contain initially
1.244 + * @param e3 another element that this set is to contain initially
1.245 + * @throws NullPointerException if any parameters are null
1.246 + * @return an enum set initially containing the specified elements
1.247 + */
1.248 + public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3) {
1.249 + EnumSet<E> result = noneOf(e1.getDeclaringClass());
1.250 + result.add(e1);
1.251 + result.add(e2);
1.252 + result.add(e3);
1.253 + return result;
1.254 + }
1.255 +
1.256 + /**
1.257 + * Creates an enum set initially containing the specified elements.
1.258 + *
1.259 + * Overloadings of this method exist to initialize an enum set with
1.260 + * one through five elements. A sixth overloading is provided that
1.261 + * uses the varargs feature. This overloading may be used to create
1.262 + * an enum set initially containing an arbitrary number of elements, but
1.263 + * is likely to run slower than the overloadings that do not use varargs.
1.264 + *
1.265 + * @param e1 an element that this set is to contain initially
1.266 + * @param e2 another element that this set is to contain initially
1.267 + * @param e3 another element that this set is to contain initially
1.268 + * @param e4 another element that this set is to contain initially
1.269 + * @throws NullPointerException if any parameters are null
1.270 + * @return an enum set initially containing the specified elements
1.271 + */
1.272 + public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3, E e4) {
1.273 + EnumSet<E> result = noneOf(e1.getDeclaringClass());
1.274 + result.add(e1);
1.275 + result.add(e2);
1.276 + result.add(e3);
1.277 + result.add(e4);
1.278 + return result;
1.279 + }
1.280 +
1.281 + /**
1.282 + * Creates an enum set initially containing the specified elements.
1.283 + *
1.284 + * Overloadings of this method exist to initialize an enum set with
1.285 + * one through five elements. A sixth overloading is provided that
1.286 + * uses the varargs feature. This overloading may be used to create
1.287 + * an enum set initially containing an arbitrary number of elements, but
1.288 + * is likely to run slower than the overloadings that do not use varargs.
1.289 + *
1.290 + * @param e1 an element that this set is to contain initially
1.291 + * @param e2 another element that this set is to contain initially
1.292 + * @param e3 another element that this set is to contain initially
1.293 + * @param e4 another element that this set is to contain initially
1.294 + * @param e5 another element that this set is to contain initially
1.295 + * @throws NullPointerException if any parameters are null
1.296 + * @return an enum set initially containing the specified elements
1.297 + */
1.298 + public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3, E e4,
1.299 + E e5)
1.300 + {
1.301 + EnumSet<E> result = noneOf(e1.getDeclaringClass());
1.302 + result.add(e1);
1.303 + result.add(e2);
1.304 + result.add(e3);
1.305 + result.add(e4);
1.306 + result.add(e5);
1.307 + return result;
1.308 + }
1.309 +
1.310 + /**
1.311 + * Creates an enum set initially containing the specified elements.
1.312 + * This factory, whose parameter list uses the varargs feature, may
1.313 + * be used to create an enum set initially containing an arbitrary
1.314 + * number of elements, but it is likely to run slower than the overloadings
1.315 + * that do not use varargs.
1.316 + *
1.317 + * @param first an element that the set is to contain initially
1.318 + * @param rest the remaining elements the set is to contain initially
1.319 + * @throws NullPointerException if any of the specified elements are null,
1.320 + * or if <tt>rest</tt> is null
1.321 + * @return an enum set initially containing the specified elements
1.322 + */
1.323 + @SafeVarargs
1.324 + public static <E extends Enum<E>> EnumSet<E> of(E first, E... rest) {
1.325 + EnumSet<E> result = noneOf(first.getDeclaringClass());
1.326 + result.add(first);
1.327 + for (E e : rest)
1.328 + result.add(e);
1.329 + return result;
1.330 + }
1.331 +
1.332 + /**
1.333 + * Creates an enum set initially containing all of the elements in the
1.334 + * range defined by the two specified endpoints. The returned set will
1.335 + * contain the endpoints themselves, which may be identical but must not
1.336 + * be out of order.
1.337 + *
1.338 + * @param from the first element in the range
1.339 + * @param to the last element in the range
1.340 + * @throws NullPointerException if {@code from} or {@code to} are null
1.341 + * @throws IllegalArgumentException if {@code from.compareTo(to) > 0}
1.342 + * @return an enum set initially containing all of the elements in the
1.343 + * range defined by the two specified endpoints
1.344 + */
1.345 + public static <E extends Enum<E>> EnumSet<E> range(E from, E to) {
1.346 + if (from.compareTo(to) > 0)
1.347 + throw new IllegalArgumentException(from + " > " + to);
1.348 + EnumSet<E> result = noneOf(from.getDeclaringClass());
1.349 + result.addRange(from, to);
1.350 + return result;
1.351 + }
1.352 +
1.353 + /**
1.354 + * Adds the specified range to this enum set, which is empty prior
1.355 + * to the call.
1.356 + */
1.357 + abstract void addRange(E from, E to);
1.358 +
1.359 + /**
1.360 + * Returns a copy of this set.
1.361 + *
1.362 + * @return a copy of this set
1.363 + */
1.364 + public EnumSet<E> clone() {
1.365 + try {
1.366 + return (EnumSet<E>) super.clone();
1.367 + } catch(CloneNotSupportedException e) {
1.368 + throw new AssertionError(e);
1.369 + }
1.370 + }
1.371 +
1.372 + /**
1.373 + * Complements the contents of this enum set.
1.374 + */
1.375 + abstract void complement();
1.376 +
1.377 + /**
1.378 + * Throws an exception if e is not of the correct type for this enum set.
1.379 + */
1.380 + final void typeCheck(E e) {
1.381 + Class eClass = e.getClass();
1.382 + if (eClass != elementType && eClass.getSuperclass() != elementType)
1.383 + throw new ClassCastException(eClass + " != " + elementType);
1.384 + }
1.385 +
1.386 + /**
1.387 + * Returns all of the values comprising E.
1.388 + * The result is uncloned, cached, and shared by all callers.
1.389 + */
1.390 + private static <E extends Enum<E>> E[] getUniverse(Class<E> elementType) {
1.391 + return SharedSecrets.getJavaLangAccess()
1.392 + .getEnumConstantsShared(elementType);
1.393 + }
1.394 +
1.395 + /**
1.396 + * This class is used to serialize all EnumSet instances, regardless of
1.397 + * implementation type. It captures their "logical contents" and they
1.398 + * are reconstructed using public static factories. This is necessary
1.399 + * to ensure that the existence of a particular implementation type is
1.400 + * an implementation detail.
1.401 + *
1.402 + * @serial include
1.403 + */
1.404 + private static class SerializationProxy <E extends Enum<E>>
1.405 + implements java.io.Serializable
1.406 + {
1.407 + /**
1.408 + * The element type of this enum set.
1.409 + *
1.410 + * @serial
1.411 + */
1.412 + private final Class<E> elementType;
1.413 +
1.414 + /**
1.415 + * The elements contained in this enum set.
1.416 + *
1.417 + * @serial
1.418 + */
1.419 + private final Enum[] elements;
1.420 +
1.421 + SerializationProxy(EnumSet<E> set) {
1.422 + elementType = set.elementType;
1.423 + elements = set.toArray(ZERO_LENGTH_ENUM_ARRAY);
1.424 + }
1.425 +
1.426 + private Object readResolve() {
1.427 + EnumSet<E> result = EnumSet.noneOf(elementType);
1.428 + for (Enum e : elements)
1.429 + result.add((E)e);
1.430 + return result;
1.431 + }
1.432 +
1.433 + private static final long serialVersionUID = 362491234563181265L;
1.434 + }
1.435 +
1.436 + Object writeReplace() {
1.437 + return new SerializationProxy<>(this);
1.438 + }
1.439 +
1.440 + // readObject method for the serialization proxy pattern
1.441 + // See Effective Java, Second Ed., Item 78.
1.442 + private void readObject(java.io.ObjectInputStream stream)
1.443 + throws java.io.InvalidObjectException {
1.444 + throw new java.io.InvalidObjectException("Proxy required");
1.445 + }
1.446 +}