diff --git a/libjava/classpath/ChangeLog b/libjava/classpath/ChangeLog index 33455acf899..cb34d1daaa1 100644 --- a/libjava/classpath/ChangeLog +++ b/libjava/classpath/ChangeLog @@ -1,3 +1,16 @@ +2007-07-31 Dalibor Topic + + PR 32844 + * java/util/EnumSet.java: + Made class abstract per API spec. + (size, iterator, add, addAll, clear, contains, + containsAll, remove, removeAll, retainAll) Moved + into an anonymous inner class in of(T). + (allOf, noneOf, copyOf, of, range) Made more + implementation independent. + (of(T)) return an instance of an anonymous class + implementing EmptySet. + 2007-07-28 Matthias Klose * include/jvmti.h(jniNativeInterface): Rename type. diff --git a/libjava/classpath/java/util/EnumSet.java b/libjava/classpath/java/util/EnumSet.java index 44ae370ba0b..543df0c0279 100644 --- a/libjava/classpath/java/util/EnumSet.java +++ b/libjava/classpath/java/util/EnumSet.java @@ -43,16 +43,20 @@ import java.io.Serializable; /** * @author Tom Tromey (tromey@redhat.com) * @author Andrew John Hughes (gnu_andrew@member.fsf.org) + * @author Dalibor Topic (robilad@kaffe.org) * @since 1.5 */ -// FIXME: serialization is special. -public class EnumSet> +// FIXME: serialization is special, uses SerializationProxy. +// of(E e) is the 'bottom' method that creates a real EnumSet. +public abstract class EnumSet> extends AbstractSet implements Cloneable, Serializable { private static final long serialVersionUID = 4782406773684236311L; + // These fields could go into the anonymous inner class in of(E), + // complementOf would need to be refactored then, though. BitSet store; int cardinality; Class enumClass; @@ -78,276 +82,246 @@ public class EnumSet> return r; } - public int size() - { - return cardinality; - } - - public Iterator iterator() - { - return new Iterator() - { - int next = -1; - int count = 0; - - public boolean hasNext() - { - return count < cardinality; - } - - public T next() - { - next = store.nextSetBit(next + 1); - ++count; - return enumClass.getEnumConstants()[next]; - } - - public void remove() - { - if (! store.get(next)) - { - store.clear(next); - --cardinality; - } - } - }; - } - - public boolean add(T val) - { - if (store.get(val.ordinal())) - return false; - store.set(val.ordinal()); - ++cardinality; - return true; - } - - public boolean addAll(Collection c) - { - boolean result = false; - if (c instanceof EnumSet) - { - EnumSet other = (EnumSet) c; - if (enumClass == other.enumClass) - { - store.or(other.store); - int save = cardinality; - cardinality = store.cardinality(); - result = save != cardinality; - } - } - else - { - for (T val : c) - { - if (add (val)) - result = true; - } - } - return result; - } - - public void clear() - { - store.clear(); - cardinality = 0; - } - - public boolean contains(Object o) - { - if (! (o instanceof Enum)) - return false; - Enum e = (Enum) o; - if (e.getDeclaringClass() != enumClass) - return false; - return store.get(e.ordinal()); - } - - public boolean containsAll(Collection c) - { - if (c instanceof EnumSet) - { - EnumSet other = (EnumSet) c; - if (enumClass == other.enumClass) - return store.containsAll(other.store); - return false; - } - return super.containsAll(c); - } - - public boolean remove(Object o) - { - if (! (o instanceof Enum)) - return false; - Enum e = (Enum) o; - if (e.getDeclaringClass() != enumClass) - return false; - store.clear(e.ordinal()); - --cardinality; - return true; - } - - public boolean removeAll(Collection c) - { - if (c instanceof EnumSet) - { - EnumSet other = (EnumSet) c; - if (enumClass != other.enumClass) - return false; - store.andNot(other.store); - int save = cardinality; - cardinality = store.cardinality(); - return save != cardinality; - } - return super.removeAll(c); - } - - public boolean retainAll(Collection c) - { - if (c instanceof EnumSet) - { - EnumSet other = (EnumSet) c; - if (enumClass != other.enumClass) - return false; - store.and(other.store); - int save = cardinality; - cardinality = store.cardinality(); - return save != cardinality; - } - return super.retainAll(c); - } - public static > EnumSet allOf(Class eltType) { - EnumSet r = new EnumSet(); - r.store = new BitSet(eltType.getEnumConstants().length); - r.store.set(0, r.store.size()); - r.cardinality = r.store.size(); - r.enumClass = eltType; - return r; + // create an EnumSet from the list of values of the type + return copyOf(Arrays.asList(eltType.getEnumConstants())); } public static > EnumSet noneOf(Class eltType) { - EnumSet r = new EnumSet(); - r.store = new BitSet(eltType.getEnumConstants().length); - r.enumClass = eltType; - return r; + return complementOf(allOf(eltType)); } public static > EnumSet copyOf(EnumSet other) { - // We can't just use `other.clone' since we don't want to make a - // subclass. - EnumSet r = new EnumSet(); - r.store = (BitSet) other.store.clone(); - r.cardinality = other.cardinality; - r.enumClass = other.enumClass; - return r; + return other.clone(); } public static > EnumSet copyOf(Collection other) { if (other instanceof EnumSet) return copyOf((EnumSet) other); - EnumSet r = new EnumSet(); + if (other.isEmpty()) + throw new IllegalArgumentException("Collection is empty"); + + EnumSet r = null; + for (T val : other) { - if (r.store == null) - { - r.enumClass = val.getDeclaringClass(); - r.store = new BitSet(r.enumClass.getEnumConstants().length); - } - r.store.set(val.ordinal()); + if (r == null) + r = of(val); + else + r.add(val); } - // The collection must contain at least one element. - if (r.store == null) - throw new IllegalArgumentException(); - r.cardinality = r.store.cardinality(); + return r; } public static > EnumSet complementOf(EnumSet other) { - EnumSet r = new EnumSet(); - r.store = (BitSet) other.store.clone(); + EnumSet r = other.clone(); r.store.flip(0, r.store.size()); r.cardinality = r.store.size() - other.cardinality; - r.enumClass = other.enumClass; return r; } public static > EnumSet of(T first) { - EnumSet r = new EnumSet(); + EnumSet r = new EnumSet() + { + public boolean add(T val) + { + if (store.get(val.ordinal())) + return false; + + store.set(val.ordinal()); + ++cardinality; + return true; + } + + public boolean addAll(Collection c) + { + boolean result = false; + if (c instanceof EnumSet) + { + EnumSet other = (EnumSet) c; + if (enumClass == other.enumClass) + { + store.or(other.store); + int save = cardinality; + cardinality = store.cardinality(); + result = save != cardinality; + } + } + else + { + for (T val : c) + { + if (add (val)) + result = true; + } + } + return result; + } + + public void clear() + { + store.clear(); + cardinality = 0; + } + + public boolean contains(Object o) + { + if (! (o instanceof Enum)) + return false; + + Enum e = (Enum) o; + if (e.getDeclaringClass() != enumClass) + return false; + + return store.get(e.ordinal()); + } + + public boolean containsAll(Collection c) + { + if (c instanceof EnumSet) + { + EnumSet other = (EnumSet) c; + if (enumClass == other.enumClass) + return store.containsAll(other.store); + + return false; + } + return super.containsAll(c); + } + + public Iterator iterator() + { + return new Iterator() + { + int next = -1; + int count = 0; + + public boolean hasNext() + { + return count < cardinality; + } + + public T next() + { + next = store.nextSetBit(next + 1); + ++count; + return enumClass.getEnumConstants()[next]; + } + + public void remove() + { + if (! store.get(next)) + { + store.clear(next); + --cardinality; + } + } + }; + } + + public boolean remove(Object o) + { + if (! (o instanceof Enum)) + return false; + + Enum e = (Enum) o; + if (e.getDeclaringClass() != enumClass) + return false; + + store.clear(e.ordinal()); + --cardinality; + return true; + } + + public boolean removeAll(Collection c) + { + if (c instanceof EnumSet) + { + EnumSet other = (EnumSet) c; + if (enumClass != other.enumClass) + return false; + + store.andNot(other.store); + int save = cardinality; + cardinality = store.cardinality(); + return save != cardinality; + } + return super.removeAll(c); + } + + public boolean retainAll(Collection c) + { + if (c instanceof EnumSet) + { + EnumSet other = (EnumSet) c; + if (enumClass != other.enumClass) + return false; + + store.and(other.store); + int save = cardinality; + cardinality = store.cardinality(); + return save != cardinality; + } + return super.retainAll(c); + } + + public int size() + { + return cardinality; + } + }; + + // initialize the class r.enumClass = first.getDeclaringClass(); r.store = new BitSet(r.enumClass.getEnumConstants().length); - r.store.set(first.ordinal()); - r.cardinality = 1; + + r.add(first); return r; } public static > EnumSet of(T first, T second) { - EnumSet r = new EnumSet(); - r.enumClass = first.getDeclaringClass(); - r.store = new BitSet(r.enumClass.getEnumConstants().length); - r.store.set(first.ordinal()); - r.store.set(second.ordinal()); - r.cardinality = r.store.cardinality(); + EnumSet r = of(first); + r.add(second); return r; } public static > EnumSet of(T first, T second, T third) { - EnumSet r = new EnumSet(); - r.enumClass = first.getDeclaringClass(); - r.store = new BitSet(r.enumClass.getEnumConstants().length); - r.store.set(first.ordinal()); - r.store.set(second.ordinal()); - r.store.set(third.ordinal()); - r.cardinality = r.store.cardinality(); + EnumSet r = of(first, second); + r.add(third); return r; } public static > EnumSet of(T first, T second, T third, T fourth) { - EnumSet r = new EnumSet(); - r.enumClass = first.getDeclaringClass(); - r.store = new BitSet(r.enumClass.getEnumConstants().length); - r.store.set(first.ordinal()); - r.store.set(second.ordinal()); - r.store.set(third.ordinal()); - r.store.set(fourth.ordinal()); - r.cardinality = r.store.cardinality(); + EnumSet r = of(first, second, third); + r.add(fourth); return r; } public static > EnumSet of(T first, T second, T third, T fourth, T fifth) { - EnumSet r = new EnumSet(); - r.enumClass = first.getDeclaringClass(); - r.store = new BitSet(r.enumClass.getEnumConstants().length); - r.store.set(first.ordinal()); - r.store.set(second.ordinal()); - r.store.set(third.ordinal()); - r.store.set(fourth.ordinal()); - r.store.set(fifth.ordinal()); - r.cardinality = r.store.cardinality(); + EnumSet r = of(first, second, third, fourth); + r.add(fifth); return r; } public static > EnumSet of(T first, T... rest) { - EnumSet r = new EnumSet(); - r.enumClass = first.getDeclaringClass(); - r.store = new BitSet(r.enumClass.getEnumConstants().length); - r.store.set(first.ordinal()); + EnumSet r = noneOf(first.getDeclaringClass()); + r.add(first); for (T val : rest) - r.store.set(val.ordinal()); - r.cardinality = r.store.cardinality(); + r.add(val); return r; } @@ -355,11 +329,24 @@ public class EnumSet> { if (from.compareTo(to) > 0) throw new IllegalArgumentException(); - EnumSet r = new EnumSet(); - r.store = new BitSet(from.getDeclaringClass().getEnumConstants().length); - r.store.set(from.ordinal(), to.ordinal() + 1); - r.enumClass = from.getDeclaringClass(); - r.cardinality = to.ordinal() - from.ordinal() + 1; + Class type = from.getDeclaringClass(); + EnumSet r = noneOf(type); + + T[] values = type.getEnumConstants(); + // skip over values until start of range is found + int i = 0; + while (from != values[i]) + i++; + + // add values until end of range is found + while (to != values[i]) { + r.add(values[i]); + i++; + } + + // add end of range + r.add(to); + return r; } } diff --git a/libjava/classpath/lib/java/util/EnumSet$1.class b/libjava/classpath/lib/java/util/EnumSet$1.class index fcf636207d5..c390f5bdf69 100644 Binary files a/libjava/classpath/lib/java/util/EnumSet$1.class and b/libjava/classpath/lib/java/util/EnumSet$1.class differ diff --git a/libjava/classpath/lib/java/util/EnumSet$2.class b/libjava/classpath/lib/java/util/EnumSet$2.class new file mode 100644 index 00000000000..59eec59f2b0 Binary files /dev/null and b/libjava/classpath/lib/java/util/EnumSet$2.class differ diff --git a/libjava/classpath/lib/java/util/EnumSet.class b/libjava/classpath/lib/java/util/EnumSet.class index 75d30d93014..68aa8a803c1 100644 Binary files a/libjava/classpath/lib/java/util/EnumSet.class and b/libjava/classpath/lib/java/util/EnumSet.class differ diff --git a/libjava/java/util/EnumSet$1.h b/libjava/java/util/EnumSet$1.h index 55e1c91d248..3e247ec9bd5 100644 --- a/libjava/java/util/EnumSet$1.h +++ b/libjava/java/util/EnumSet$1.h @@ -6,23 +6,25 @@ #pragma interface -#include +#include -class java::util::EnumSet$1 : public ::java::lang::Object +class java::util::EnumSet$1 : public ::java::util::EnumSet { public: // actually package-private - EnumSet$1(::java::util::EnumSet *); -public: - jboolean hasNext(); - ::java::lang::Enum * EnumSet$1$next(); - void remove(); - ::java::lang::Object * next(); -public: // actually package-private - jint __attribute__((aligned(__alignof__( ::java::lang::Object)))) next__; - jint count; - ::java::util::EnumSet * this$0; + EnumSet$1(); public: + jboolean EnumSet$1$add(::java::lang::Enum *); + jboolean addAll(::java::util::Collection *); + void clear(); + jboolean contains(::java::lang::Object *); + jboolean containsAll(::java::util::Collection *); + ::java::util::Iterator * iterator(); + jboolean remove(::java::lang::Object *); + jboolean removeAll(::java::util::Collection *); + jboolean retainAll(::java::util::Collection *); + jint size(); + jboolean add(::java::lang::Object *); static ::java::lang::Class class$; }; diff --git a/libjava/java/util/EnumSet$2.h b/libjava/java/util/EnumSet$2.h new file mode 100644 index 00000000000..e80b9789bed --- /dev/null +++ b/libjava/java/util/EnumSet$2.h @@ -0,0 +1,29 @@ + +// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*- + +#ifndef __java_util_EnumSet$2__ +#define __java_util_EnumSet$2__ + +#pragma interface + +#include + +class java::util::EnumSet$2 : public ::java::lang::Object +{ + +public: // actually package-private + EnumSet$2(::java::util::EnumSet$1 *); +public: + jboolean hasNext(); + ::java::lang::Enum * EnumSet$2$next(); + void remove(); + ::java::lang::Object * next(); +public: // actually package-private + jint __attribute__((aligned(__alignof__( ::java::lang::Object)))) next__; + jint count; + ::java::util::EnumSet$1 * this$1; +public: + static ::java::lang::Class class$; +}; + +#endif // __java_util_EnumSet$2__ diff --git a/libjava/java/util/EnumSet.h b/libjava/java/util/EnumSet.h index 200868ae876..5497e306d8c 100644 --- a/libjava/java/util/EnumSet.h +++ b/libjava/java/util/EnumSet.h @@ -17,16 +17,6 @@ public: // actually package-private EnumSet(); public: virtual ::java::util::EnumSet * EnumSet$clone(); - virtual jint size(); - virtual ::java::util::Iterator * iterator(); - virtual jboolean EnumSet$add(::java::lang::Enum *); - virtual jboolean addAll(::java::util::Collection *); - virtual void clear(); - virtual jboolean contains(::java::lang::Object *); - virtual jboolean containsAll(::java::util::Collection *); - virtual jboolean remove(::java::lang::Object *); - virtual jboolean removeAll(::java::util::Collection *); - virtual jboolean retainAll(::java::util::Collection *); static ::java::util::EnumSet * allOf(::java::lang::Class *); static ::java::util::EnumSet * noneOf(::java::lang::Class *); static ::java::util::EnumSet * copyOf(::java::util::EnumSet *); @@ -40,7 +30,6 @@ public: static ::java::util::EnumSet * of(::java::lang::Enum *, JArray< ::java::lang::Enum * > *); static ::java::util::EnumSet * range(::java::lang::Enum *, ::java::lang::Enum *); virtual ::java::lang::Object * clone(); - virtual jboolean add(::java::lang::Object *); private: static const jlong serialVersionUID = 4782406773684236311LL; public: // actually package-private