OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [java/] [util/] [EnumSet.java] - Blame information for rev 791

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 771 jeremybenn
/* EnumSet.java - Set of enum objects
2
   Copyright (C) 2004, 2005 Free Software Foundation, Inc.
3
 
4
This file is part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
9
any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
02110-1301 USA.
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version. */
37
 
38
 
39
package java.util;
40
 
41
import java.io.Serializable;
42
 
43
/**
44
 * <p>
45
 * Provides an efficient mechanism for recording a set of enumeration
46
 * constants.  As enumerations have a known set of possible values, certain
47
 * assumptions can be made when creating a set of constants.  The maximum
48
 * size of the set will always be equal to the number of constants, and each
49
 * value will always be one of these constants.  As a result, the set only needs
50
 * to store whether a particular constant is present or not rather than the
51
 * values themselves.  Each constant can thus be represented by a single bit.
52
 * </p>
53
 * <p>
54
 * This class is designed to provide an alternative to using integer bit flags
55
 * by providing a typesafe {@link Collection} interface with an underlying
56
 * implementation that utilises the assumptions above to give an equivalent level
57
 * of efficiency.  The values in a {@link EnumSet} must all be from the same
58
 * {@link Enum} type, which allows the contents to be packed into a bit vector.
59
 * A containment test is then simply a matter of inspecting the appropriate bit, while
60
 * addition involves setting the same.  Such basic operations take place in constant
61
 * time.
62
 * </p>
63
 * <p>
64
 * The {@link Iterator} implementation traverses the values in the natural order
65
 * of the enumeration provided by each constant's {@link Enum#ordinal()}.  It is
66
 * <emph>weakly consistent</emph> and will not throw a {@link ConcurrentModificationException}.
67
 * This means that concurrent changes to the set may or may not be noticeable during
68
 * traversal.
69
 * </p>
70
 * <p>
71
 * As is usual with most collections, the set is not synchronized by default.  This
72
 * can be remedied by using the {@link Collections#synchronizedSet(Set)} method.  Null
73
 * elements are not supported and attempts to add one will throw a {@link NullPointerException}.
74
 * </p>
75
 *
76
 * @author Tom Tromey (tromey@redhat.com)
77
 * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
78
 * @author Dalibor Topic (robilad@kaffe.org)
79
 * @since 1.5
80
 */
81
 
82
// FIXME: serialization is special, uses SerializationProxy.
83
// of(E e) is the 'bottom' method that creates a real EnumSet.
84
public abstract class EnumSet<T extends Enum<T>>
85
  extends AbstractSet<T>
86
  implements Cloneable, Serializable
87
{
88
  private static final long serialVersionUID = 4782406773684236311L;
89
 
90
  // These fields could go into the anonymous inner class in of(E),
91
  // complementOf would need to be refactored then, though.
92
  /**
93
   * The store which maintains the bits used to represent
94
   * the enumeration constants.
95
   */
96
  BitSet store;
97
 
98
  /**
99
   * The cardinality of the set (the current number
100
   * of bits set).
101
   */
102
  int cardinality;
103
 
104
  /**
105
   * The enumeration used by this set.
106
   */
107
  Class<T> enumClass;
108
 
109
  /**
110
   * Empty package-private constructor
111
   */
112
  EnumSet()
113
  {
114
  }
115
 
116
  /**
117
   * Returns a clone of the set.
118
   *
119
   * @return a clone of the set.
120
   */
121
  public EnumSet<T> clone()
122
  {
123
    EnumSet<T> r;
124
 
125
    try
126
      {
127
        r = (EnumSet<T>) super.clone();
128
      }
129
    catch (CloneNotSupportedException _)
130
      {
131
        /* Can't happen */
132
        return null;
133
      }
134
    r.store = (BitSet) store.clone();
135
    return r;
136
  }
137
 
138
  /**
139
   * Returns a set for the given enumeration type where
140
   * all the constants are present.
141
   *
142
   * @param eltType the type of enumeration to use for the set.
143
   * @return an {@link EnumSet} with all the bits set.
144
   * @throws NullPointerException if the element type is <code>null</code>.
145
   */
146
  public static <T extends Enum<T>> EnumSet<T> allOf(Class<T> eltType)
147
  {
148
    // create an EnumSet from the list of values of the type
149
    return copyOf(Arrays.asList(eltType.getEnumConstants()));
150
  }
151
 
152
  /**
153
   * Returns a set for the given enumeration type where
154
   * none of the constants are present.
155
   *
156
   * @param eltType the type of enumeration to use for the set.
157
   * @return an {@link EnumSet} with none of the bits set.
158
   * @throws NullPointerException if the element type is <code>null</code>.
159
   */
160
  public static <T extends Enum<T>> EnumSet<T> noneOf(Class<T> eltType)
161
  {
162
    return complementOf(allOf(eltType));
163
  }
164
 
165
  /**
166
   * Returns a clone of the given set.
167
   *
168
   * @param other the set to clone.
169
   * @return an {@link EnumSet} that is a clone of the given set.
170
   * @throws NullPointerException if <code>other</code> is <code>null</code>.
171
   */
172
  public static <T extends Enum<T>> EnumSet<T> copyOf(EnumSet<T> other)
173
  {
174
    return other.clone();
175
  }
176
 
177
  /**
178
   * Creates an {@link EnumSet} using the contents of the given collection.
179
   * If the collection is also an {@link EnumSet}, this method works the
180
   * same as {@link #copyOf(EnumSet)}.  Otherwise, the elements of the collection
181
   * are inspected and used to populate the new set.
182
   *
183
   * @param other the collection to use to populate the new set.
184
   * @return an {@link EnumSet} containing elements from the given collection.
185
   * @throws NullPointerException if <code>other</code> is <code>null</code>.
186
   * @throws IllegalArgumentException if the collection is empty.
187
   */
188
  public static <T extends Enum<T>> EnumSet<T> copyOf(Collection<T> other)
189
  {
190
    if (other instanceof EnumSet)
191
      return copyOf((EnumSet<T>) other);
192
    if (other.isEmpty())
193
        throw new IllegalArgumentException("Collection is empty");
194
 
195
    EnumSet<T> r = null;
196
 
197
    for (T val : other)
198
      {
199
        if (r == null)
200
          r = of(val);
201
        else
202
          r.add(val);
203
      }
204
 
205
    return r;
206
  }
207
 
208
  /**
209
   * Returns a set which is the inverse of the supplied set.
210
   * If a constant is present in the current set, it will not be
211
   * present in the new set and vice versa.
212
   *
213
   * @param other the set to provide the complement of.
214
   * @return an {@link EnumSet} which is the inverse of the current one.
215
   * @throws NullPointerException if <code>other</code> is <code>null</code>.
216
   */
217
  public static <T extends Enum<T>> EnumSet<T> complementOf(EnumSet<T> other)
218
  {
219
    EnumSet<T> r = other.clone();
220
    int numConstants = r.enumClass.getEnumConstants().length;
221
    r.store.flip(0, numConstants);
222
    r.cardinality = numConstants - other.cardinality;
223
    return r;
224
  }
225
 
226
  /**
227
   * Creates a new {@link EnumSet} populated with the given element.
228
   *
229
   * @param first the element to use to populate the new set.
230
   * @return an {@link EnumSet} containing the element.
231
   * @throws NullPointerException if <code>first</code> is <code>null</code>.
232
   */
233
  public static <T extends Enum<T>> EnumSet<T> of(T first)
234
  {
235
    EnumSet<T> r = new EnumSet<T>()
236
    {
237
      public boolean add(T val)
238
      {
239
        if (store.get(val.ordinal()))
240
          return false;
241
 
242
        store.set(val.ordinal());
243
        ++cardinality;
244
        return true;
245
      }
246
 
247
      public boolean addAll(Collection<? extends T> c)
248
      {
249
        boolean result = false;
250
        if (c instanceof EnumSet)
251
        {
252
          EnumSet<T> other = (EnumSet<T>) c;
253
          if (enumClass == other.enumClass)
254
          {
255
            store.or(other.store);
256
            int save = cardinality;
257
            cardinality = store.cardinality();
258
            result = save != cardinality;
259
          }
260
        }
261
        else
262
        {
263
          for (T val : c)
264
          {
265
            if (add (val))
266
            result = true;
267
          }
268
        }
269
        return result;
270
      }
271
 
272
      public void clear()
273
      {
274
        store.clear();
275
        cardinality = 0;
276
      }
277
 
278
      public boolean contains(Object o)
279
      {
280
        if (! (o instanceof Enum))
281
          return false;
282
 
283
        Enum<T> e = (Enum<T>) o;
284
        if (e.getDeclaringClass() != enumClass)
285
          return false;
286
 
287
        return store.get(e.ordinal());
288
      }
289
 
290
      public boolean containsAll(Collection<?> c)
291
      {
292
        if (c instanceof EnumSet)
293
        {
294
          EnumSet<T> other = (EnumSet<T>) c;
295
          if (enumClass == other.enumClass)
296
            return store.containsAll(other.store);
297
 
298
          return false;
299
        }
300
        return super.containsAll(c);
301
      }
302
 
303
      public Iterator<T> iterator()
304
      {
305
        return new Iterator<T>()
306
        {
307
          int next = -1;
308
          int count = 0;
309
 
310
          public boolean hasNext()
311
          {
312
            return count < cardinality;
313
          }
314
 
315
          public T next()
316
          {
317
            next = store.nextSetBit(next + 1);
318
            ++count;
319
            return enumClass.getEnumConstants()[next];
320
          }
321
 
322
          public void remove()
323
          {
324
            if (! store.get(next))
325
            {
326
                store.clear(next);
327
                --cardinality;
328
            }
329
          }
330
        };
331
      }
332
 
333
      public boolean remove(Object o)
334
      {
335
        if (! (o instanceof Enum))
336
          return false;
337
 
338
        Enum<T> e = (Enum<T>) o;
339
        if (e.getDeclaringClass() != enumClass)
340
          return false;
341
 
342
        store.clear(e.ordinal());
343
        --cardinality;
344
        return true;
345
      }
346
 
347
      public boolean removeAll(Collection<?> c)
348
      {
349
        if (c instanceof EnumSet)
350
        {
351
          EnumSet<T> other = (EnumSet<T>) c;
352
          if (enumClass != other.enumClass)
353
            return false;
354
 
355
          store.andNot(other.store);
356
          int save = cardinality;
357
          cardinality = store.cardinality();
358
          return save != cardinality;
359
        }
360
        return super.removeAll(c);
361
      }
362
 
363
      public boolean retainAll(Collection<?> c)
364
      {
365
        if (c instanceof EnumSet)
366
        {
367
          EnumSet<T> other = (EnumSet<T>) c;
368
          if (enumClass != other.enumClass)
369
            return false;
370
 
371
          store.and(other.store);
372
          int save = cardinality;
373
          cardinality = store.cardinality();
374
          return save != cardinality;
375
        }
376
        return super.retainAll(c);
377
      }
378
 
379
      public int size()
380
      {
381
        return cardinality;
382
      }
383
    };
384
 
385
    // initialize the class
386
    r.enumClass = first.getDeclaringClass();
387
    r.store = new BitSet(r.enumClass.getEnumConstants().length);
388
 
389
    r.add(first);
390
    return r;
391
  }
392
 
393
  /**
394
   * Creates a new {@link EnumSet} populated with the given two elements.
395
   *
396
   * @param first the first element to use to populate the new set.
397
   * @param second the second element to use.
398
   * @return an {@link EnumSet} containing the elements.
399
   * @throws NullPointerException if any of the parameters are <code>null</code>.
400
   */
401
  public static <T extends Enum<T>> EnumSet<T> of(T first, T second)
402
  {
403
    EnumSet<T> r = of(first);
404
    r.add(second);
405
    return r;
406
  }
407
 
408
  /**
409
   * Creates a new {@link EnumSet} populated with the given three elements.
410
   *
411
   * @param first the first element to use to populate the new set.
412
   * @param second the second element to use.
413
   * @param third the third element to use.
414
   * @return an {@link EnumSet} containing the elements.
415
   * @throws NullPointerException if any of the parameters are <code>null</code>.
416
   */
417
  public static <T extends Enum<T>> EnumSet<T> of(T first, T second, T third)
418
  {
419
    EnumSet<T> r = of(first, second);
420
    r.add(third);
421
    return r;
422
  }
423
 
424
  /**
425
   * Creates a new {@link EnumSet} populated with the given four elements.
426
   *
427
   * @param first the first element to use to populate the new set.
428
   * @param second the second element to use.
429
   * @param third the third element to use.
430
   * @param fourth the fourth element to use.
431
   * @return an {@link EnumSet} containing the elements.
432
   * @throws NullPointerException if any of the parameters are <code>null</code>.
433
   */
434
  public static <T extends Enum<T>> EnumSet<T> of(T first, T second, T third,
435
                                                  T fourth)
436
  {
437
    EnumSet<T> r = of(first, second, third);
438
    r.add(fourth);
439
    return r;
440
  }
441
 
442
  /**
443
   * Creates a new {@link EnumSet} populated with the given five elements.
444
   *
445
   * @param first the first element to use to populate the new set.
446
   * @param second the second element to use.
447
   * @param third the third element to use.
448
   * @param fourth the fourth element to use.
449
   * @param fifth the fifth element to use.
450
   * @return an {@link EnumSet} containing the elements.
451
   * @throws NullPointerException if any of the parameters are <code>null</code>.
452
   */
453
  public static <T extends Enum<T>> EnumSet<T> of(T first, T second, T third,
454
                                                  T fourth, T fifth)
455
  {
456
    EnumSet<T> r = of(first, second, third, fourth);
457
    r.add(fifth);
458
    return r;
459
  }
460
 
461
  /**
462
   * Creates a new {@link EnumSet} populated with the given elements.
463
   *
464
   * @param first the first element to use to populate the new set.
465
   * @param rest the other elements to use.
466
   * @return an {@link EnumSet} containing the elements.
467
   * @throws NullPointerException if any of the parameters are <code>null</code>.
468
   */
469
  public static <T extends Enum<T>> EnumSet<T> of(T first, T... rest)
470
  {
471
    EnumSet<T> r = noneOf(first.getDeclaringClass());
472
    r.add(first);
473
    for (T val : rest)
474
      r.add(val);
475
    return r;
476
  }
477
 
478
  /**
479
   * Creates a new {@link EnumSet} using the enumeration constants
480
   * starting from {@code from} and ending at {@code to} inclusive.
481
   * The two may be the same, but they must be in the correct order.
482
   * So giving the first constant twice would give a set with just that
483
   * constant set, while supplying the first and second constant will give
484
   * a set with those two elements.  However, specifying the second as
485
   * the {@code from} element followed by an earlier element as the
486
   * {@code to} element will result in an error.
487
   *
488
   * @param from the element to start from.
489
   * @param to the element to end at (may be the same as {@code from}.
490
   * @return an {@link EnumSet} containing the specified range of elements.
491
   * @throws NullPointerException if any of the parameters are <code>null</code>.
492
   * @throws IllegalArgumentException if {@code first.compareTo(last) > 0}.
493
   */
494
  public static <T extends Enum<T>> EnumSet<T> range(T from, T to)
495
  {
496
    if (from.compareTo(to) > 0)
497
      throw new IllegalArgumentException();
498
    Class<T> type = from.getDeclaringClass();
499
    EnumSet<T> r = noneOf(type);
500
 
501
    T[] values = type.getEnumConstants();
502
    // skip over values until start of range is found
503
    int i = 0;
504
    while (from != values[i])
505
      i++;
506
 
507
    // add values until end of range is found
508
    while (to != values[i]) {
509
      r.add(values[i]);
510
      i++;
511
    }
512
 
513
    // add end of range
514
    r.add(to);
515
 
516
    return r;
517
  }
518
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.