Mercurial > hg > truffle
view graal/com.oracle.max.base/src/com/sun/max/util/Enumerator.java @ 3733:e233f5660da4
Added Java files from Maxine project.
author | Thomas Wuerthinger <thomas.wuerthinger@oracle.com> |
---|---|
date | Sat, 17 Dec 2011 19:59:18 +0100 |
parents | |
children |
line wrap: on
line source
/* * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.sun.max.util; import java.util.*; import com.sun.max.*; /** * @see Enumerable */ public class Enumerator<E extends Enum<E> & Enumerable<E>> implements Symbolizer<E> { private final Class<E> type; private final E[] ordinalMap; private final E[] valueMap; private final int lowestValue; public Enumerator(Class<E> type) { this.type = type; ordinalMap = type.getEnumConstants(); int lowValue = 0; int highestValue = ordinalMap.length - 1; boolean valuesAreSameAsOrdinals = true; for (E e : ordinalMap) { final int value = e.value(); if (value != e.ordinal()) { valuesAreSameAsOrdinals = false; } if (value < lowValue) { lowValue = value; } else if (value > highestValue) { highestValue = value; } } if (valuesAreSameAsOrdinals) { this.lowestValue = 0; valueMap = ordinalMap; } else { final int valueMapLength = (highestValue - lowValue) + 1; final Class<E[]> arrayType = null; this.lowestValue = lowValue; valueMap = Utils.cast(arrayType, new Enum[valueMapLength]); for (E e : ordinalMap) { final int value = e.value(); // The enumerable with the lowest ordinal is stored in the value map: if (valueMap[value] == null) { valueMap[value] = e; } } } } public Class<E> type() { return type; } public int numberOfValues() { return ordinalMap.length; } /** * Adds all the enumerable constants in this enumerator to a given set. * * @param set * the set to which the enumerable constants are to be added */ public void addAll(Set<E> set) { for (E e : this) { set.add(e); } } public int size() { return ordinalMap.length; } public Iterator<E> iterator() { return Arrays.asList(ordinalMap).iterator(); } /** * Gets the enumerable constant denoted by a given ordinal. Note that this differs from {@link #fromValue(int)} in * that the latter retrieves an enumerable constant matching a given {@linkplain Enumerable#value() value}. An * enumerable's value is not necessarily the same as its ordinal. * * @throws IndexOutOfBoundsException * if {@code 0 < ordinal || ordinal >= length()} */ public E get(int ordinal) throws IndexOutOfBoundsException { return ordinalMap[ordinal]; } /** * Gets the enumerable constant matching a given value. That is, this method gets an enumerable from this enumerator * whose {@linkplain Enumerable#value() value} is equal to {@code value}. Note that the given value may not match * any enumerable in this enumerator in which case null is returned. Additionally, there may be more than one * enumerable with a matching value in which case the matching enumerable with the lowest * {@linkplain Enum#ordinal() ordinal} is returned. */ public E fromValue(int value) { final int index = value - lowestValue; if (index >= 0 && index < valueMap.length) { return valueMap[index]; } return null; } }