Skip to content

Commit

Permalink
Add partial implementation of EnumSet (#3397)
Browse files Browse the repository at this point in the history
  • Loading branch information
WojciechMazur committed Jul 19, 2023
1 parent 16ddcdc commit ce94cf5
Show file tree
Hide file tree
Showing 2 changed files with 230 additions and 17 deletions.
120 changes: 103 additions & 17 deletions javalib/src/main/scala/java/util/EnumSet.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,113 @@ package java.util

import java.lang.Enum

final class EnumSet[E <: Enum[E]] private (values: Array[E])
final class EnumSet[E <: Enum[E]] private (values: Set[E])
extends AbstractSet[E]
with Cloneable
with Serializable {
def iterator(): Iterator[E] =
new Iterator[E] {
private var i = 0
override def hasNext(): Boolean = i < values.length
override def next(): E = {
val r = values(i)
i += 1
r
}
override def remove(): Unit = throw new UnsupportedOperationException()
}
def size(): Int = values.length
// Unsupported requires reflection
// def this(elementType: Class[E], universe: Array[Enum[E]]) = ???

override def iterator(): Iterator[E] = values.iterator()
override def size(): Int = values.size()
override def isEmpty(): Boolean = values.isEmpty()
override def contains(o: Any): Boolean = values.contains(o)
override def toArray(): Array[AnyRef] = values.toArray()
override def toArray[T <: AnyRef](a: Array[T]): Array[T] = values.toArray(a)
override def add(e: E): Boolean = values.add(e)
override def remove(o: Any): Boolean = values.remove(o)
override def containsAll(c: Collection[_]): Boolean = values.containsAll(c)
override def addAll(c: Collection[_ <: E]): Boolean = values.addAll(c)
override def removeAll(c: Collection[_]): Boolean = values.removeAll(c)
override def retainAll(c: Collection[_]): Boolean = values.retainAll(c)
override def clear(): Unit = values.clear()
override def equals(o: Any): Boolean = values.equals(o)
override def hashCode(): Int = values.hashCode()

override protected[util] def clone(): EnumSet[E] =
super.clone().asInstanceOf[EnumSet[E]]
}

object EnumSet {
def noneOf[E <: Enum[E]: scala.reflect.ClassTag](
elementType: Class[E]
): EnumSet[E] =
new EnumSet[E](Array.empty[E])
def noneOf[E <: Enum[E]](elementType: Class[E]): EnumSet[E] =
new EnumSet[E](new HashSet[E]())

// Unsupported, requires reflection
// def allOf[E <: Enum[E]](elementType: Class[E]): EnumSet[E] = ???

def copyOf[E <: Enum[E]](s: EnumSet[E]): EnumSet[E] =
s.clone().asInstanceOf[EnumSet[E]]

def copyOf[E <: Enum[E]](c: Collection[E]): EnumSet[E] = c match {
case c: EnumSet[E] => copyOf(c)
case c =>
if (c.isEmpty()) throw new IllegalArgumentException("Collection is empty")
val i = c.iterator()
val set = EnumSet.of(i.next())
while (i.hasNext()) {
set.add(i.next())
}
set
}

// Unsupported, requires reflection
// def complementOf[E <: Enum[E]](s: EnumSet[E]): EnumSet[E] = {
// val result = copyOf(s)
// result.complement()
// result
// }

def of[E <: Enum[E]](e: E): EnumSet[E] = {
val s = emptySetOf(e)
s.add(e)
s
}

def of[E <: Enum[E]](e1: E, e2: E): EnumSet[E] = {
val s = emptySetOf(e1)
s.add(e1)
s.add(e2)
s
}

def of[E <: Enum[E]](e1: E, e2: E, e3: E): EnumSet[E] = {
val s = emptySetOf(e1)
s.add(e1)
s.add(e2)
s.add(e3)
s
}

def of[E <: Enum[E]](e1: E, e2: E, e3: E, e4: E): EnumSet[E] = {
val s = emptySetOf(e1)
s.add(e1)
s.add(e2)
s.add(e3)
s.add(e4)
s
}

def of[E <: Enum[E]](e1: E, e2: E, e3: E, e4: E, e5: E): EnumSet[E] = {
val s = emptySetOf(e1)
s.add(e1)
s.add(e2)
s.add(e3)
s.add(e4)
s.add(e5)
s
}

def of[E <: Enum[E]](first: E, rest: Array[E]): EnumSet[E] = {
val s = emptySetOf(first)
s.add(first)
rest.foreach(s.add)
s
}

// Unsupported, requires reflection
// def range[E <: Enum[E]](from: E, to: E): EnumSet[E] = ???

@inline
private def emptySetOf[E <: Enum[E]](e: E): EnumSet[E] =
new EnumSet[E](new HashSet[E]())
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
package org.scalanative.testsuite.javalib.util

import java.lang._
import java.util.EnumSet

import org.junit.Test
import org.junit.Assert._

// Tested only in Scala 3 becouse we cannot create Java enums in Scala 2

object EnumSetTest {
enum Value extends java.lang.Enum[Value]:
case A, B, C, D, E, F
}

class EnumSetTest {
import EnumSetTest.Value

@Test def noneOf(): Unit = {
val s = EnumSet.noneOf(classOf[Value])
assertTrue(s.isEmpty())
assertEquals(0, s.size())
assertFalse(s.iterator().hasNext())
}

@Test def of1(): Unit = {
val s = EnumSet.of(Value.A)
assertFalse(s.isEmpty())
assertEquals(1, s.size())
val it = s.iterator()
assertTrue(it.hasNext())
assertEquals(Value.A, it.next())
}

@Test def of2(): Unit = {
val s = EnumSet.of(Value.A, Value.B)
assertFalse(s.isEmpty())
assertEquals(2, s.size())
assertTrue(s.contains(Value.A))
assertTrue(s.contains(Value.B))
}

@Test def of3(): Unit = {
val s = EnumSet.of(Value.A, Value.B, Value.C)
assertFalse(s.isEmpty())
assertEquals(3, s.size())
assertTrue(s.contains(Value.A))
assertTrue(s.contains(Value.B))
assertTrue(s.contains(Value.C))
}

@Test def of4(): Unit = {
val s = EnumSet.of(Value.A, Value.B, Value.C, Value.D)
assertFalse(s.isEmpty())
assertEquals(4, s.size())
assertTrue(s.contains(Value.A))
assertTrue(s.contains(Value.B))
assertTrue(s.contains(Value.C))
assertTrue(s.contains(Value.D))
}

@Test def of5(): Unit = {
val s = EnumSet.of(Value.A, Value.B, Value.C, Value.D, Value.E)
assertFalse(s.isEmpty())
assertEquals(5, s.size())
assertTrue(s.contains(Value.A))
assertTrue(s.contains(Value.B))
assertTrue(s.contains(Value.C))
assertTrue(s.contains(Value.D))
assertTrue(s.contains(Value.E))
}

@Test def ofVarArg(): Unit = {
val s = EnumSet.of(Value.A, Value.B, Value.C, Value.D, Value.E, Value.F)
assertFalse(s.isEmpty())
assertEquals(6, s.size())
assertTrue(s.contains(Value.A))
assertTrue(s.contains(Value.B))
assertTrue(s.contains(Value.C))
assertTrue(s.contains(Value.D))
assertTrue(s.contains(Value.E))
assertTrue(s.contains(Value.F))
}

@Test def ofVarArg2(): Unit = {
val s =
EnumSet.of(Value.A, Seq(Value.B, Value.C, Value.D, Value.E, Value.F): _*)
assertFalse(s.isEmpty())
assertEquals(6, s.size())
assertTrue(s.contains(Value.A))
assertTrue(s.contains(Value.B))
assertTrue(s.contains(Value.C))
assertTrue(s.contains(Value.D))
assertTrue(s.contains(Value.E))
assertTrue(s.contains(Value.F))
}

@Test def copyOf(): Unit = {
val s = EnumSet.of(Value.A, Value.B, Value.C)
val c = EnumSet.copyOf(s)
assertNotSame(s, c)
assertEquals(s, c)
}

@Test def copyOfCollection(): Unit = {
val c: java.util.Collection[Value] = new java.util.LinkedList[Value]()
c.add(Value.A)
c.add(Value.B)
c.add(Value.C)
val s = EnumSet.copyOf(c)

assertNotSame(s, c)
assertEquals(3, s.size())
assertTrue(s.contains(Value.A))
assertTrue(s.contains(Value.B))
assertTrue(s.contains(Value.C))
}

@Test def uniqness(): Unit = {
val s = EnumSet.of(Value.A, Value.A, Value.B, Value.C, Value.B)
assertEquals(3, s.size())
assertTrue(s.contains(Value.A))
assertTrue(s.contains(Value.B))
assertTrue(s.contains(Value.C))
}

}

0 comments on commit ce94cf5

Please sign in to comment.