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

Subversion Repositories openrisc

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

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

Line No. Rev Author Line
1 771 jeremybenn
/* EnumMap.java - Map where keys are enum constants
2
   Copyright (C) 2004, 2005, 2007 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
 * @author Tom Tromey (tromey@redhat.com)
45
 * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
46
 * @since 1.5
47
 */
48
 
49
public class EnumMap<K extends Enum<K>, V>
50
  extends AbstractMap<K, V>
51
  implements Cloneable, Serializable
52
{
53
  private static final long serialVersionUID = 458661240069192865L;
54
 
55
  V[] store;
56
  int cardinality;
57
  Class<K> enumClass;
58
 
59
  /**
60
   * The cache for {@link #entrySet()}.
61
   */
62
  transient Set<Map.Entry<K, V>> entries;
63
 
64
  static final Object emptySlot = new Object();
65
 
66
  public EnumMap(Class<K> keyType)
67
  {
68
    store = (V[]) new Object[keyType.getEnumConstants().length];
69
    Arrays.fill(store, emptySlot);
70
    cardinality = 0;
71
    enumClass = keyType;
72
  }
73
 
74
  public EnumMap(EnumMap<K, ? extends V> map)
75
  {
76
    store = (V[]) map.store.clone();
77
    cardinality = map.cardinality;
78
    enumClass = map.enumClass;
79
  }
80
 
81
  public EnumMap(Map<K, ? extends V> map)
82
  {
83
    if (map instanceof EnumMap)
84
      {
85
        EnumMap<K, ? extends V> other = (EnumMap<K, ? extends V>) map;
86
        store = (V[]) other.store.clone();
87
        cardinality = other.cardinality;
88
        enumClass = other.enumClass;
89
      }
90
    else
91
      {
92
        for (K key : map.keySet())
93
          {
94
            V value = map.get(key);
95
            if (store == null)
96
              {
97
                enumClass = key.getDeclaringClass();
98
                store = (V[]) new Object[enumClass.getEnumConstants().length];
99
              }
100
            int o = key.ordinal();
101
            if (store[o] == emptySlot)
102
              ++cardinality;
103
            store[o] = value;
104
          }
105
        // There must be a single element.
106
        if (store == null)
107
          throw new IllegalArgumentException("no elements in map");
108
      }
109
  }
110
 
111
  public int size()
112
  {
113
    return cardinality;
114
  }
115
 
116
  public boolean containsValue(Object value)
117
  {
118
    for (V i : store)
119
      {
120
        if (i != emptySlot && AbstractCollection.equals(i , value))
121
          return true;
122
      }
123
    return false;
124
  }
125
 
126
  public boolean containsKey(Object key)
127
  {
128
    if (! (key instanceof Enum))
129
      return false;
130
    Enum<K> e = (Enum<K>) key;
131
    if (e.getDeclaringClass() != enumClass)
132
      return false;
133
    return store[e.ordinal()] != emptySlot;
134
  }
135
 
136
  public V get(Object key)
137
  {
138
    if (! (key instanceof Enum))
139
      return null;
140
    Enum<K> e = (Enum<K>) key;
141
    if (e.getDeclaringClass() != enumClass)
142
      return null;
143
    V o = store[e.ordinal()];
144
    return o == emptySlot ? null : o;
145
  }
146
 
147
  public V put(K key, V value)
148
  {
149
    int o = key.ordinal();
150
    V result;
151
    if (store[o] == emptySlot)
152
      {
153
        result = null;
154
        ++cardinality;
155
      }
156
    else
157
      result = store[o];
158
    store[o] = value;
159
    return result;
160
  }
161
 
162
  public V remove(Object key)
163
  {
164
    if (! (key instanceof Enum))
165
      return null;
166
    Enum<K> e = (Enum<K>) key;
167
    if (e.getDeclaringClass() != enumClass)
168
      return null;
169
    V result = store[e.ordinal()];
170
    if (result == emptySlot)
171
      result = null;
172
    else
173
      --cardinality;
174
    store[e.ordinal()] = (V) emptySlot;
175
    return result;
176
  }
177
 
178
  public void putAll(Map<? extends K, ? extends V> map)
179
  {
180
    for (K key : map.keySet())
181
      {
182
        V value = map.get(key);
183
 
184
        int o = key.ordinal();
185
        if (store[o] == emptySlot)
186
          ++cardinality;
187
        store[o] = value;
188
      }
189
  }
190
 
191
  public void clear()
192
  {
193
    Arrays.fill(store, emptySlot);
194
    cardinality = 0;
195
  }
196
 
197
  public Set<K> keySet()
198
  {
199
    if (keys == null)
200
      {
201
        keys = new AbstractSet<K>()
202
        {
203
          public int size()
204
          {
205
            return cardinality;
206
          }
207
 
208
          public Iterator<K> iterator()
209
          {
210
            return new Iterator<K>()
211
            {
212
              int count = 0;
213
              int index = -1;
214
 
215
              public boolean hasNext()
216
              {
217
                return count < cardinality;
218
              }
219
 
220
              public K next()
221
              {
222
                ++count;
223
                for (++index; store[index] == emptySlot; ++index)
224
                  ;
225
                return enumClass.getEnumConstants()[index];
226
              }
227
 
228
              public void remove()
229
              {
230
                --cardinality;
231
                store[index] = (V) emptySlot;
232
              }
233
            };
234
          }
235
 
236
          public void clear()
237
          {
238
            EnumMap.this.clear();
239
          }
240
 
241
          public boolean contains(Object o)
242
          {
243
            return contains(o);
244
          }
245
 
246
          public boolean remove(Object o)
247
          {
248
            return EnumMap.this.remove(o) != null;
249
          }
250
        };
251
      }
252
    return keys;
253
  }
254
 
255
  public Collection<V> values()
256
  {
257
    if (values == null)
258
      {
259
        values = new AbstractCollection<V>()
260
        {
261
          public int size()
262
          {
263
            return cardinality;
264
          }
265
 
266
          public Iterator<V> iterator()
267
          {
268
            return new Iterator<V>()
269
            {
270
              int count = 0;
271
              int index = -1;
272
 
273
              public boolean hasNext()
274
              {
275
                return count < cardinality;
276
              }
277
 
278
              public V next()
279
              {
280
                ++count;
281
                for (++index; store[index] == emptySlot; ++index)
282
                  ;
283
                return store[index];
284
              }
285
 
286
              public void remove()
287
              {
288
                --cardinality;
289
                store[index] = (V) emptySlot;
290
              }
291
            };
292
          }
293
 
294
          public void clear()
295
          {
296
            EnumMap.this.clear();
297
          }
298
        };
299
      }
300
    return values;
301
  }
302
 
303
  public Set<Map.Entry<K, V>> entrySet()
304
  {
305
    if (entries == null)
306
      {
307
        entries = new AbstractSet<Map.Entry<K, V>>()
308
        {
309
          public int size()
310
          {
311
            return cardinality;
312
          }
313
 
314
          public Iterator<Map.Entry<K, V>> iterator()
315
          {
316
            return new Iterator<Map.Entry<K, V>>()
317
            {
318
              int count = 0;
319
              int index = -1;
320
 
321
              public boolean hasNext()
322
              {
323
                return count < cardinality;
324
              }
325
 
326
              public Map.Entry<K,V> next()
327
              {
328
                ++count;
329
                for (++index; store[index] == emptySlot; ++index)
330
                  ;
331
                // FIXME: we could just return something that
332
                // only knows the index.  That would be cleaner.
333
                return new AbstractMap.SimpleEntry<K, V>(enumClass.getEnumConstants()[index],
334
                                                           store[index])
335
                {
336
                  public V setValue(V newVal)
337
                  {
338
                    value = newVal;
339
                    return put(key, newVal);
340
                  }
341
                };
342
              }
343
 
344
              public void remove()
345
              {
346
                --cardinality;
347
                store[index] = (V) emptySlot;
348
              }
349
            };
350
          }
351
 
352
          public void clear()
353
          {
354
            EnumMap.this.clear();
355
          }
356
 
357
          public boolean contains(Object o)
358
          {
359
            if (! (o instanceof Map.Entry))
360
              return false;
361
            Map.Entry<K, V> other = (Map.Entry<K, V>) o;
362
            return (containsKey(other.getKey())
363
                    && AbstractCollection.equals(get(other.getKey()),
364
                                                 other.getValue()));
365
          }
366
 
367
          public boolean remove(Object o)
368
          {
369
            if (! (o instanceof Map.Entry))
370
              return false;
371
            Map.Entry<K, V> other = (Map.Entry<K, V>) o;
372
            return EnumMap.this.remove(other.getKey()) != null;
373
          }
374
        };
375
      }
376
    return entries;
377
  }
378
 
379
  public boolean equals(Object o)
380
  {
381
    if (! (o instanceof EnumMap))
382
      return false;
383
    EnumMap<K, V> other = (EnumMap<K, V>) o;
384
    if (other.enumClass != enumClass || other.cardinality != cardinality)
385
      return false;
386
    return Arrays.equals(store, other.store);
387
  }
388
 
389
  public EnumMap<K, V> clone()
390
  {
391
    EnumMap<K, V> result;
392
    try
393
      {
394
        result = (EnumMap<K, V>) super.clone();
395
      }
396
    catch (CloneNotSupportedException ignore)
397
      {
398
        // Can't happen.
399
        result = null;
400
      }
401
    result.store = (V[]) store.clone();
402
    return result;
403
  }
404
 
405
}

powered by: WebSVN 2.1.0

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