rt/emul/compact/src/main/java/java/util/EnumSet.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Sun, 22 Sep 2013 21:56:49 +0200
changeset 1294 70532b5324e2
parent 1293 b7da86101183
child 1360 49fb4574259b
permissions -rw-r--r--
Need EnumSet for Javac
jtulach@1292
     1
/*
jtulach@1292
     2
 * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
jtulach@1292
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
jtulach@1292
     4
 *
jtulach@1292
     5
 * This code is free software; you can redistribute it and/or modify it
jtulach@1292
     6
 * under the terms of the GNU General Public License version 2 only, as
jtulach@1292
     7
 * published by the Free Software Foundation.  Oracle designates this
jtulach@1292
     8
 * particular file as subject to the "Classpath" exception as provided
jtulach@1292
     9
 * by Oracle in the LICENSE file that accompanied this code.
jtulach@1292
    10
 *
jtulach@1292
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
jtulach@1292
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
jtulach@1292
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
jtulach@1292
    14
 * version 2 for more details (a copy is included in the LICENSE file that
jtulach@1292
    15
 * accompanied this code).
jtulach@1292
    16
 *
jtulach@1292
    17
 * You should have received a copy of the GNU General Public License version
jtulach@1292
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
jtulach@1292
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
jtulach@1292
    20
 *
jtulach@1292
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
jtulach@1292
    22
 * or visit www.oracle.com if you need additional information or have any
jtulach@1292
    23
 * questions.
jtulach@1292
    24
 */
jtulach@1292
    25
jtulach@1292
    26
package java.util;
jtulach@1292
    27
jaroslav@1294
    28
import org.apidesign.bck2brwsr.core.JavaScriptBody;
jtulach@1292
    29
jtulach@1292
    30
/**
jtulach@1292
    31
 * A specialized {@link Set} implementation for use with enum types.  All of
jtulach@1292
    32
 * the elements in an enum set must come from a single enum type that is
jtulach@1292
    33
 * specified, explicitly or implicitly, when the set is created.  Enum sets
jtulach@1292
    34
 * are represented internally as bit vectors.  This representation is
jtulach@1292
    35
 * extremely compact and efficient. The space and time performance of this
jtulach@1292
    36
 * class should be good enough to allow its use as a high-quality, typesafe
jtulach@1292
    37
 * alternative to traditional <tt>int</tt>-based "bit flags."  Even bulk
jtulach@1292
    38
 * operations (such as <tt>containsAll</tt> and <tt>retainAll</tt>) should
jtulach@1292
    39
 * run very quickly if their argument is also an enum set.
jtulach@1292
    40
 *
jtulach@1292
    41
 * <p>The iterator returned by the <tt>iterator</tt> method traverses the
jtulach@1292
    42
 * elements in their <i>natural order</i> (the order in which the enum
jtulach@1292
    43
 * constants are declared).  The returned iterator is <i>weakly
jtulach@1292
    44
 * consistent</i>: it will never throw {@link ConcurrentModificationException}
jtulach@1292
    45
 * and it may or may not show the effects of any modifications to the set that
jtulach@1292
    46
 * occur while the iteration is in progress.
jtulach@1292
    47
 *
jtulach@1292
    48
 * <p>Null elements are not permitted.  Attempts to insert a null element
jtulach@1292
    49
 * will throw {@link NullPointerException}.  Attempts to test for the
jtulach@1292
    50
 * presence of a null element or to remove one will, however, function
jtulach@1292
    51
 * properly.
jtulach@1292
    52
 *
jtulach@1292
    53
 * <P>Like most collection implementations, <tt>EnumSet</tt> is not
jtulach@1292
    54
 * synchronized.  If multiple threads access an enum set concurrently, and at
jtulach@1292
    55
 * least one of the threads modifies the set, it should be synchronized
jtulach@1292
    56
 * externally.  This is typically accomplished by synchronizing on some
jtulach@1292
    57
 * object that naturally encapsulates the enum set.  If no such object exists,
jtulach@1292
    58
 * the set should be "wrapped" using the {@link Collections#synchronizedSet}
jtulach@1292
    59
 * method.  This is best done at creation time, to prevent accidental
jtulach@1292
    60
 * unsynchronized access:
jtulach@1292
    61
 *
jtulach@1292
    62
 * <pre>
jtulach@1292
    63
 * Set&lt;MyEnum&gt; s = Collections.synchronizedSet(EnumSet.noneOf(MyEnum.class));
jtulach@1292
    64
 * </pre>
jtulach@1292
    65
 *
jtulach@1292
    66
 * <p>Implementation note: All basic operations execute in constant time.
jtulach@1292
    67
 * They are likely (though not guaranteed) to be much faster than their
jtulach@1292
    68
 * {@link HashSet} counterparts.  Even bulk operations execute in
jtulach@1292
    69
 * constant time if their argument is also an enum set.
jtulach@1292
    70
 *
jtulach@1292
    71
 * <p>This class is a member of the
jtulach@1292
    72
 * <a href="{@docRoot}/../technotes/guides/collections/index.html">
jtulach@1292
    73
 * Java Collections Framework</a>.
jtulach@1292
    74
 *
jtulach@1292
    75
 * @author Josh Bloch
jtulach@1292
    76
 * @since 1.5
jtulach@1292
    77
 * @see EnumMap
jtulach@1292
    78
 * @serial exclude
jtulach@1292
    79
 */
jtulach@1292
    80
public abstract class EnumSet<E extends Enum<E>> extends AbstractSet<E>
jtulach@1292
    81
    implements Cloneable, java.io.Serializable
jtulach@1292
    82
{
jtulach@1292
    83
    /**
jtulach@1292
    84
     * The class of all the elements of this set.
jtulach@1292
    85
     */
jtulach@1292
    86
    final Class<E> elementType;
jtulach@1292
    87
jtulach@1292
    88
    /**
jtulach@1292
    89
     * All of the values comprising T.  (Cached for performance.)
jtulach@1292
    90
     */
jtulach@1292
    91
    final Enum[] universe;
jtulach@1292
    92
jtulach@1292
    93
    private static Enum[] ZERO_LENGTH_ENUM_ARRAY = new Enum[0];
jtulach@1292
    94
jtulach@1292
    95
    EnumSet(Class<E>elementType, Enum[] universe) {
jtulach@1292
    96
        this.elementType = elementType;
jtulach@1292
    97
        this.universe    = universe;
jtulach@1292
    98
    }
jtulach@1292
    99
jtulach@1292
   100
    /**
jtulach@1292
   101
     * Creates an empty enum set with the specified element type.
jtulach@1292
   102
     *
jtulach@1292
   103
     * @param elementType the class object of the element type for this enum
jtulach@1292
   104
     *     set
jtulach@1292
   105
     * @throws NullPointerException if <tt>elementType</tt> is null
jtulach@1292
   106
     */
jtulach@1292
   107
    public static <E extends Enum<E>> EnumSet<E> noneOf(Class<E> elementType) {
jtulach@1292
   108
        Enum[] universe = getUniverse(elementType);
jtulach@1292
   109
        if (universe == null)
jtulach@1292
   110
            throw new ClassCastException(elementType + " not an enum");
jtulach@1292
   111
jtulach@1292
   112
        if (universe.length <= 64)
jtulach@1292
   113
            return new RegularEnumSet<>(elementType, universe);
jtulach@1292
   114
        else
jtulach@1292
   115
            return new JumboEnumSet<>(elementType, universe);
jtulach@1292
   116
    }
jtulach@1292
   117
jtulach@1292
   118
    /**
jtulach@1292
   119
     * Creates an enum set containing all of the elements in the specified
jtulach@1292
   120
     * element type.
jtulach@1292
   121
     *
jtulach@1292
   122
     * @param elementType the class object of the element type for this enum
jtulach@1292
   123
     *     set
jtulach@1292
   124
     * @throws NullPointerException if <tt>elementType</tt> is null
jtulach@1292
   125
     */
jtulach@1292
   126
    public static <E extends Enum<E>> EnumSet<E> allOf(Class<E> elementType) {
jtulach@1292
   127
        EnumSet<E> result = noneOf(elementType);
jtulach@1292
   128
        result.addAll();
jtulach@1292
   129
        return result;
jtulach@1292
   130
    }
jtulach@1292
   131
jtulach@1292
   132
    /**
jtulach@1292
   133
     * Adds all of the elements from the appropriate enum type to this enum
jtulach@1292
   134
     * set, which is empty prior to the call.
jtulach@1292
   135
     */
jtulach@1292
   136
    abstract void addAll();
jtulach@1292
   137
jtulach@1292
   138
    /**
jtulach@1292
   139
     * Creates an enum set with the same element type as the specified enum
jtulach@1292
   140
     * set, initially containing the same elements (if any).
jtulach@1292
   141
     *
jtulach@1292
   142
     * @param s the enum set from which to initialize this enum set
jtulach@1292
   143
     * @throws NullPointerException if <tt>s</tt> is null
jtulach@1292
   144
     */
jtulach@1292
   145
    public static <E extends Enum<E>> EnumSet<E> copyOf(EnumSet<E> s) {
jtulach@1292
   146
        return s.clone();
jtulach@1292
   147
    }
jtulach@1292
   148
jtulach@1292
   149
    /**
jtulach@1292
   150
     * Creates an enum set initialized from the specified collection.  If
jtulach@1292
   151
     * the specified collection is an <tt>EnumSet</tt> instance, this static
jtulach@1292
   152
     * factory method behaves identically to {@link #copyOf(EnumSet)}.
jtulach@1292
   153
     * Otherwise, the specified collection must contain at least one element
jtulach@1292
   154
     * (in order to determine the new enum set's element type).
jtulach@1292
   155
     *
jtulach@1292
   156
     * @param c the collection from which to initialize this enum set
jtulach@1292
   157
     * @throws IllegalArgumentException if <tt>c</tt> is not an
jtulach@1292
   158
     *     <tt>EnumSet</tt> instance and contains no elements
jtulach@1292
   159
     * @throws NullPointerException if <tt>c</tt> is null
jtulach@1292
   160
     */
jtulach@1292
   161
    public static <E extends Enum<E>> EnumSet<E> copyOf(Collection<E> c) {
jtulach@1292
   162
        if (c instanceof EnumSet) {
jtulach@1292
   163
            return ((EnumSet<E>)c).clone();
jtulach@1292
   164
        } else {
jtulach@1292
   165
            if (c.isEmpty())
jtulach@1292
   166
                throw new IllegalArgumentException("Collection is empty");
jtulach@1292
   167
            Iterator<E> i = c.iterator();
jtulach@1292
   168
            E first = i.next();
jtulach@1292
   169
            EnumSet<E> result = EnumSet.of(first);
jtulach@1292
   170
            while (i.hasNext())
jtulach@1292
   171
                result.add(i.next());
jtulach@1292
   172
            return result;
jtulach@1292
   173
        }
jtulach@1292
   174
    }
jtulach@1292
   175
jtulach@1292
   176
    /**
jtulach@1292
   177
     * Creates an enum set with the same element type as the specified enum
jtulach@1292
   178
     * set, initially containing all the elements of this type that are
jtulach@1292
   179
     * <i>not</i> contained in the specified set.
jtulach@1292
   180
     *
jtulach@1292
   181
     * @param s the enum set from whose complement to initialize this enum set
jtulach@1292
   182
     * @throws NullPointerException if <tt>s</tt> is null
jtulach@1292
   183
     */
jtulach@1292
   184
    public static <E extends Enum<E>> EnumSet<E> complementOf(EnumSet<E> s) {
jtulach@1292
   185
        EnumSet<E> result = copyOf(s);
jtulach@1292
   186
        result.complement();
jtulach@1292
   187
        return result;
jtulach@1292
   188
    }
jtulach@1292
   189
jtulach@1292
   190
    /**
jtulach@1292
   191
     * Creates an enum set initially containing the specified element.
jtulach@1292
   192
     *
jtulach@1292
   193
     * Overloadings of this method exist to initialize an enum set with
jtulach@1292
   194
     * one through five elements.  A sixth overloading is provided that
jtulach@1292
   195
     * uses the varargs feature.  This overloading may be used to create
jtulach@1292
   196
     * an enum set initially containing an arbitrary number of elements, but
jtulach@1292
   197
     * is likely to run slower than the overloadings that do not use varargs.
jtulach@1292
   198
     *
jtulach@1292
   199
     * @param e the element that this set is to contain initially
jtulach@1292
   200
     * @throws NullPointerException if <tt>e</tt> is null
jtulach@1292
   201
     * @return an enum set initially containing the specified element
jtulach@1292
   202
     */
jtulach@1292
   203
    public static <E extends Enum<E>> EnumSet<E> of(E e) {
jtulach@1292
   204
        EnumSet<E> result = noneOf(e.getDeclaringClass());
jtulach@1292
   205
        result.add(e);
jtulach@1292
   206
        return result;
jtulach@1292
   207
    }
jtulach@1292
   208
jtulach@1292
   209
    /**
jtulach@1292
   210
     * Creates an enum set initially containing the specified elements.
jtulach@1292
   211
     *
jtulach@1292
   212
     * Overloadings of this method exist to initialize an enum set with
jtulach@1292
   213
     * one through five elements.  A sixth overloading is provided that
jtulach@1292
   214
     * uses the varargs feature.  This overloading may be used to create
jtulach@1292
   215
     * an enum set initially containing an arbitrary number of elements, but
jtulach@1292
   216
     * is likely to run slower than the overloadings that do not use varargs.
jtulach@1292
   217
     *
jtulach@1292
   218
     * @param e1 an element that this set is to contain initially
jtulach@1292
   219
     * @param e2 another element that this set is to contain initially
jtulach@1292
   220
     * @throws NullPointerException if any parameters are null
jtulach@1292
   221
     * @return an enum set initially containing the specified elements
jtulach@1292
   222
     */
jtulach@1292
   223
    public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2) {
jtulach@1292
   224
        EnumSet<E> result = noneOf(e1.getDeclaringClass());
jtulach@1292
   225
        result.add(e1);
jtulach@1292
   226
        result.add(e2);
jtulach@1292
   227
        return result;
jtulach@1292
   228
    }
jtulach@1292
   229
jtulach@1292
   230
    /**
jtulach@1292
   231
     * Creates an enum set initially containing the specified elements.
jtulach@1292
   232
     *
jtulach@1292
   233
     * Overloadings of this method exist to initialize an enum set with
jtulach@1292
   234
     * one through five elements.  A sixth overloading is provided that
jtulach@1292
   235
     * uses the varargs feature.  This overloading may be used to create
jtulach@1292
   236
     * an enum set initially containing an arbitrary number of elements, but
jtulach@1292
   237
     * is likely to run slower than the overloadings that do not use varargs.
jtulach@1292
   238
     *
jtulach@1292
   239
     * @param e1 an element that this set is to contain initially
jtulach@1292
   240
     * @param e2 another element that this set is to contain initially
jtulach@1292
   241
     * @param e3 another element that this set is to contain initially
jtulach@1292
   242
     * @throws NullPointerException if any parameters are null
jtulach@1292
   243
     * @return an enum set initially containing the specified elements
jtulach@1292
   244
     */
jtulach@1292
   245
    public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3) {
jtulach@1292
   246
        EnumSet<E> result = noneOf(e1.getDeclaringClass());
jtulach@1292
   247
        result.add(e1);
jtulach@1292
   248
        result.add(e2);
jtulach@1292
   249
        result.add(e3);
jtulach@1292
   250
        return result;
jtulach@1292
   251
    }
jtulach@1292
   252
jtulach@1292
   253
    /**
jtulach@1292
   254
     * Creates an enum set initially containing the specified elements.
jtulach@1292
   255
     *
jtulach@1292
   256
     * Overloadings of this method exist to initialize an enum set with
jtulach@1292
   257
     * one through five elements.  A sixth overloading is provided that
jtulach@1292
   258
     * uses the varargs feature.  This overloading may be used to create
jtulach@1292
   259
     * an enum set initially containing an arbitrary number of elements, but
jtulach@1292
   260
     * is likely to run slower than the overloadings that do not use varargs.
jtulach@1292
   261
     *
jtulach@1292
   262
     * @param e1 an element that this set is to contain initially
jtulach@1292
   263
     * @param e2 another element that this set is to contain initially
jtulach@1292
   264
     * @param e3 another element that this set is to contain initially
jtulach@1292
   265
     * @param e4 another element that this set is to contain initially
jtulach@1292
   266
     * @throws NullPointerException if any parameters are null
jtulach@1292
   267
     * @return an enum set initially containing the specified elements
jtulach@1292
   268
     */
jtulach@1292
   269
    public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3, E e4) {
jtulach@1292
   270
        EnumSet<E> result = noneOf(e1.getDeclaringClass());
jtulach@1292
   271
        result.add(e1);
jtulach@1292
   272
        result.add(e2);
jtulach@1292
   273
        result.add(e3);
jtulach@1292
   274
        result.add(e4);
jtulach@1292
   275
        return result;
jtulach@1292
   276
    }
jtulach@1292
   277
jtulach@1292
   278
    /**
jtulach@1292
   279
     * Creates an enum set initially containing the specified elements.
jtulach@1292
   280
     *
jtulach@1292
   281
     * Overloadings of this method exist to initialize an enum set with
jtulach@1292
   282
     * one through five elements.  A sixth overloading is provided that
jtulach@1292
   283
     * uses the varargs feature.  This overloading may be used to create
jtulach@1292
   284
     * an enum set initially containing an arbitrary number of elements, but
jtulach@1292
   285
     * is likely to run slower than the overloadings that do not use varargs.
jtulach@1292
   286
     *
jtulach@1292
   287
     * @param e1 an element that this set is to contain initially
jtulach@1292
   288
     * @param e2 another element that this set is to contain initially
jtulach@1292
   289
     * @param e3 another element that this set is to contain initially
jtulach@1292
   290
     * @param e4 another element that this set is to contain initially
jtulach@1292
   291
     * @param e5 another element that this set is to contain initially
jtulach@1292
   292
     * @throws NullPointerException if any parameters are null
jtulach@1292
   293
     * @return an enum set initially containing the specified elements
jtulach@1292
   294
     */
jtulach@1292
   295
    public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2, E e3, E e4,
jtulach@1292
   296
                                                    E e5)
jtulach@1292
   297
    {
jtulach@1292
   298
        EnumSet<E> result = noneOf(e1.getDeclaringClass());
jtulach@1292
   299
        result.add(e1);
jtulach@1292
   300
        result.add(e2);
jtulach@1292
   301
        result.add(e3);
jtulach@1292
   302
        result.add(e4);
jtulach@1292
   303
        result.add(e5);
jtulach@1292
   304
        return result;
jtulach@1292
   305
    }
jtulach@1292
   306
jtulach@1292
   307
    /**
jtulach@1292
   308
     * Creates an enum set initially containing the specified elements.
jtulach@1292
   309
     * This factory, whose parameter list uses the varargs feature, may
jtulach@1292
   310
     * be used to create an enum set initially containing an arbitrary
jtulach@1292
   311
     * number of elements, but it is likely to run slower than the overloadings
jtulach@1292
   312
     * that do not use varargs.
jtulach@1292
   313
     *
jtulach@1292
   314
     * @param first an element that the set is to contain initially
jtulach@1292
   315
     * @param rest the remaining elements the set is to contain initially
jtulach@1292
   316
     * @throws NullPointerException if any of the specified elements are null,
jtulach@1292
   317
     *     or if <tt>rest</tt> is null
jtulach@1292
   318
     * @return an enum set initially containing the specified elements
jtulach@1292
   319
     */
jtulach@1292
   320
    @SafeVarargs
jtulach@1292
   321
    public static <E extends Enum<E>> EnumSet<E> of(E first, E... rest) {
jtulach@1292
   322
        EnumSet<E> result = noneOf(first.getDeclaringClass());
jtulach@1292
   323
        result.add(first);
jtulach@1292
   324
        for (E e : rest)
jtulach@1292
   325
            result.add(e);
jtulach@1292
   326
        return result;
jtulach@1292
   327
    }
jtulach@1292
   328
jtulach@1292
   329
    /**
jtulach@1292
   330
     * Creates an enum set initially containing all of the elements in the
jtulach@1292
   331
     * range defined by the two specified endpoints.  The returned set will
jtulach@1292
   332
     * contain the endpoints themselves, which may be identical but must not
jtulach@1292
   333
     * be out of order.
jtulach@1292
   334
     *
jtulach@1292
   335
     * @param from the first element in the range
jtulach@1292
   336
     * @param to the last element in the range
jtulach@1292
   337
     * @throws NullPointerException if {@code from} or {@code to} are null
jtulach@1292
   338
     * @throws IllegalArgumentException if {@code from.compareTo(to) > 0}
jtulach@1292
   339
     * @return an enum set initially containing all of the elements in the
jtulach@1292
   340
     *         range defined by the two specified endpoints
jtulach@1292
   341
     */
jtulach@1292
   342
    public static <E extends Enum<E>> EnumSet<E> range(E from, E to) {
jtulach@1292
   343
        if (from.compareTo(to) > 0)
jtulach@1292
   344
            throw new IllegalArgumentException(from + " > " + to);
jtulach@1292
   345
        EnumSet<E> result = noneOf(from.getDeclaringClass());
jtulach@1292
   346
        result.addRange(from, to);
jtulach@1292
   347
        return result;
jtulach@1292
   348
    }
jtulach@1292
   349
jtulach@1292
   350
    /**
jtulach@1292
   351
     * Adds the specified range to this enum set, which is empty prior
jtulach@1292
   352
     * to the call.
jtulach@1292
   353
     */
jtulach@1292
   354
    abstract void addRange(E from, E to);
jtulach@1292
   355
jtulach@1292
   356
    /**
jtulach@1292
   357
     * Returns a copy of this set.
jtulach@1292
   358
     *
jtulach@1292
   359
     * @return a copy of this set
jtulach@1292
   360
     */
jtulach@1292
   361
    public EnumSet<E> clone() {
jtulach@1292
   362
        try {
jtulach@1292
   363
            return (EnumSet<E>) super.clone();
jtulach@1292
   364
        } catch(CloneNotSupportedException e) {
jtulach@1292
   365
            throw new AssertionError(e);
jtulach@1292
   366
        }
jtulach@1292
   367
    }
jtulach@1292
   368
jtulach@1292
   369
    /**
jtulach@1292
   370
     * Complements the contents of this enum set.
jtulach@1292
   371
     */
jtulach@1292
   372
    abstract void complement();
jtulach@1292
   373
jtulach@1292
   374
    /**
jtulach@1292
   375
     * Throws an exception if e is not of the correct type for this enum set.
jtulach@1292
   376
     */
jtulach@1292
   377
    final void typeCheck(E e) {
jtulach@1292
   378
        Class eClass = e.getClass();
jtulach@1292
   379
        if (eClass != elementType && eClass.getSuperclass() != elementType)
jtulach@1292
   380
            throw new ClassCastException(eClass + " != " + elementType);
jtulach@1292
   381
    }
jtulach@1292
   382
jtulach@1292
   383
    /**
jtulach@1292
   384
     * Returns all of the values comprising E.
jtulach@1292
   385
     * The result is uncloned, cached, and shared by all callers.
jtulach@1292
   386
     */
jaroslav@1294
   387
    @JavaScriptBody(args = { "enumType" }, body = "return enumType.cnstr.$VALUES;")
jaroslav@1294
   388
    private static native <E extends Enum<E>> E[] getUniverse(Class<E> elementType);
jtulach@1292
   389
jtulach@1292
   390
    /**
jtulach@1292
   391
     * This class is used to serialize all EnumSet instances, regardless of
jtulach@1292
   392
     * implementation type.  It captures their "logical contents" and they
jtulach@1292
   393
     * are reconstructed using public static factories.  This is necessary
jtulach@1292
   394
     * to ensure that the existence of a particular implementation type is
jtulach@1292
   395
     * an implementation detail.
jtulach@1292
   396
     *
jtulach@1292
   397
     * @serial include
jtulach@1292
   398
     */
jtulach@1292
   399
    private static class SerializationProxy <E extends Enum<E>>
jtulach@1292
   400
        implements java.io.Serializable
jtulach@1292
   401
    {
jtulach@1292
   402
        /**
jtulach@1292
   403
         * The element type of this enum set.
jtulach@1292
   404
         *
jtulach@1292
   405
         * @serial
jtulach@1292
   406
         */
jtulach@1292
   407
        private final Class<E> elementType;
jtulach@1292
   408
jtulach@1292
   409
        /**
jtulach@1292
   410
         * The elements contained in this enum set.
jtulach@1292
   411
         *
jtulach@1292
   412
         * @serial
jtulach@1292
   413
         */
jtulach@1292
   414
        private final Enum[] elements;
jtulach@1292
   415
jtulach@1292
   416
        SerializationProxy(EnumSet<E> set) {
jtulach@1292
   417
            elementType = set.elementType;
jtulach@1292
   418
            elements = set.toArray(ZERO_LENGTH_ENUM_ARRAY);
jtulach@1292
   419
        }
jtulach@1292
   420
jtulach@1292
   421
        private Object readResolve() {
jtulach@1292
   422
            EnumSet<E> result = EnumSet.noneOf(elementType);
jtulach@1292
   423
            for (Enum e : elements)
jtulach@1292
   424
                result.add((E)e);
jtulach@1292
   425
            return result;
jtulach@1292
   426
        }
jtulach@1292
   427
jtulach@1292
   428
        private static final long serialVersionUID = 362491234563181265L;
jtulach@1292
   429
    }
jtulach@1292
   430
jtulach@1292
   431
    Object writeReplace() {
jtulach@1292
   432
        return new SerializationProxy<>(this);
jtulach@1292
   433
    }
jtulach@1292
   434
jtulach@1292
   435
    // readObject method for the serialization proxy pattern
jtulach@1292
   436
    // See Effective Java, Second Ed., Item 78.
jtulach@1292
   437
    private void readObject(java.io.ObjectInputStream stream)
jtulach@1292
   438
        throws java.io.InvalidObjectException {
jtulach@1292
   439
        throw new java.io.InvalidObjectException("Proxy required");
jtulach@1292
   440
    }
jtulach@1292
   441
}