Skip to content

Commit 0651816

Browse files
committed
ArrayBuilder, ArrayOps, WrappedArray are added/updated for arrays of value classes
1 parent e37edd2 commit 0651816

File tree

6 files changed

+142
-27
lines changed

6 files changed

+142
-27
lines changed

src/dotty/DottyPredef.scala

Lines changed: 5 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@ package dotty
22

33
import scala.reflect.runtime.universe.TypeTag
44
import scala.reflect.ClassTag
5-
import scala.collection.mutable.ArrayOps
6-
import scala.runtime.ScalaRunTime.arrayElementClass
7-
import scala.collection.mutable.WrappedArray
5+
import scala.collection.mutable.{ArrayOps, WrappedArray}
86
import dotty.runtime.vc._
97
import scala.Predef.???
108

@@ -15,17 +13,8 @@ object DottyPredef {
1513
implicit def arrayTag[T](implicit ctag: ClassTag[T]): ClassTag[Array[T]] =
1614
ctag.wrap
1715

18-
def wrapVCArray[T](xs: Array[T]): WrappedArray[T] = {
19-
new WrappedArray[T] {
20-
val array = xs
21-
lazy val elemTag = ClassTag[T](arrayElementClass(array.getClass))
22-
def length: Int = array.length
23-
def apply(index: Int): T = array(index)
24-
def update(index: Int, elem: T) = {
25-
array(index) = elem
26-
}
27-
}
28-
}
16+
def wrapVCArray[T](xs: Array[T]): WrappedArray[T] =
17+
new VCWrappedArray[T](xs)
2918

3019
//def to substitute scala.Predef.genericWrapArray
3120
def genericWrapArray2[T](xs: Array[T]): WrappedArray[T] = {
@@ -39,19 +28,8 @@ object DottyPredef {
3928
}
4029
}
4130

42-
def refVCArray[T /*<: AnyVal*/](xs: Array[T]): ArrayOps[T] = {
43-
new ArrayOps[T] {
44-
val array = xs
45-
lazy val elemTag = ClassTag[T](arrayElementClass(array.getClass))
46-
def length: Int = array.length
47-
def apply(index: Int): T = array(index)
48-
def update(index: Int, elem: T) = {
49-
array(index) = elem
50-
}
51-
//TODO - add the implementation for newBuilder
52-
def newBuilder = ???
53-
}
54-
}
31+
def refVCArray[T /*<: AnyVal*/](xs: Array[T]): ArrayOps[T] =
32+
new VCArrayOps[T](xs)
5533

5634
//def to substitute scala.Predef.genericArrayOps
5735
def genericArrayOps2[T](xs: Array[T]): ArrayOps[T] = (xs match {
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package dotty.runtime.vc
2+
3+
import scala.collection.TraversableOnce
4+
import scala.collection.mutable.ArrayBuilder
5+
import scala.reflect.ClassTag
6+
7+
class VCArrayBuilder[T](implicit ct: ClassTag[T]) extends ArrayBuilder[T] {
8+
9+
private var elems: Array[T] = _
10+
private var capacity: Int = 0
11+
private var size: Int = 0
12+
13+
private def mkArray(size: Int): Array[T] = {
14+
val newelems = new Array[T](size)
15+
if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size)
16+
newelems
17+
}
18+
19+
private def resize(size: Int) = {
20+
elems = mkArray(size)
21+
capacity = size
22+
}
23+
24+
override def sizeHint(size: Int) = {
25+
if (capacity < size) resize(size)
26+
}
27+
28+
private def ensureSize(size: Int) = {
29+
if (capacity < size || capacity == 0) {
30+
var newsize = if (capacity == 0) 16 else capacity * 2
31+
while (newsize < size) newsize *= 2
32+
resize(newsize)
33+
}
34+
}
35+
36+
def +=(elem: T): this.type = {
37+
ensureSize(size + 1)
38+
elems(size) = elem
39+
size += 1
40+
this
41+
}
42+
43+
override def ++=(xs: TraversableOnce[T]): this.type = (xs.asInstanceOf[AnyRef]) match {
44+
case xs: VCWrappedArray[_] =>
45+
ensureSize(this.size + xs.length)
46+
//TODO: check correctness
47+
Array.copy(xs.array, 0, elems, this.size, xs.length)
48+
size += xs.length
49+
this
50+
case _ =>
51+
super.++=(xs)
52+
}
53+
54+
def clear() = {
55+
size = 0
56+
}
57+
58+
def result() = {
59+
if (capacity != 0 && capacity == size) elems
60+
else mkArray(size)
61+
}
62+
63+
override def equals(other: Any): Boolean = other match {
64+
case x: VCArrayBuilder[_] => (size == x.size) && (elems == x.elems)
65+
case _ => false
66+
}
67+
68+
override def toString = "ArrayBuilder.ofVC"
69+
}

src/dotty/runtime/vc/VCArrayOps.scala

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package dotty.runtime.vc
2+
3+
import scala.collection.mutable.{WrappedArray, ArrayBuilder, ArrayOps}
4+
import scala.reflect.ClassTag
5+
import dotty.DottyPredef._
6+
7+
class VCArrayOps[T](xs: Array[T]) extends ArrayOps[T] {
8+
val array = xs
9+
def length: Int = array.length
10+
def apply(index: Int): T = array(index)
11+
def update(index: Int, elem: T) = {
12+
array(index) = elem
13+
}
14+
15+
lazy val elemTag = (xs.asInstanceOf[Object]: @unchecked) match {
16+
case vc: VCIntArray[_] => vc.ct.asInstanceOf[ClassTag[T]]
17+
case vc: VCShortArray[_] => vc.ct.asInstanceOf[ClassTag[T]]
18+
case vc: VCLongArray[_] => vc.ct.asInstanceOf[ClassTag[T]]
19+
case vc: VCFloatArray[_] => vc.ct.asInstanceOf[ClassTag[T]]
20+
case vc: VCDoubleArray[_] => vc.ct.asInstanceOf[ClassTag[T]]
21+
case vc: VCByteArray[_] => vc.ct.asInstanceOf[ClassTag[T]]
22+
case vc: VCBooleanArray[_] => vc.ct.asInstanceOf[ClassTag[T]]
23+
case vc: VCCharArray[_] => vc.ct.asInstanceOf[ClassTag[T]]
24+
case vc: VCObjectArray[_] => vc.ct.asInstanceOf[ClassTag[T]]
25+
}
26+
27+
override protected[this] def newBuilder = new VCArrayBuilder[T]()(elemTag).asInstanceOf[ArrayBuilder[T]]
28+
//override protected[this] def newBuilder = new ArrayBuilder.ofRef[T]()(ClassTag[T](arrayElementClass(repr.getClass)))
29+
30+
override protected[this] def thisCollection: WrappedArray[T] = wrapVCArray(xs)
31+
override protected[this] def toCollection(repr: Array[T]): WrappedArray[T] = wrapVCArray(xs)
32+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package dotty.runtime.vc
2+
3+
import scala.collection.mutable.WrappedArray
4+
import scala.reflect.ClassTag
5+
6+
class VCWrappedArray[T](xs: Array[T]) extends WrappedArray[T] {
7+
val array = xs
8+
lazy val elemTag = (xs.asInstanceOf[Object]: @unchecked) match {
9+
case vc: VCIntArray[_] => vc.ct.asInstanceOf[ClassTag[T]]
10+
case vc: VCShortArray[_] => vc.ct.asInstanceOf[ClassTag[T]]
11+
case vc: VCLongArray[_] => vc.ct.asInstanceOf[ClassTag[T]]
12+
case vc: VCFloatArray[_] => vc.ct.asInstanceOf[ClassTag[T]]
13+
case vc: VCDoubleArray[_] => vc.ct.asInstanceOf[ClassTag[T]]
14+
case vc: VCByteArray[_] => vc.ct.asInstanceOf[ClassTag[T]]
15+
case vc: VCBooleanArray[_] => vc.ct.asInstanceOf[ClassTag[T]]
16+
case vc: VCCharArray[_] => vc.ct.asInstanceOf[ClassTag[T]]
17+
case vc: VCObjectArray[_] => vc.ct.asInstanceOf[ClassTag[T]]
18+
}
19+
//lazy val elemTag = ClassTag[T](arrayElementClass(array.getClass))
20+
21+
def length: Int = array.length
22+
def apply(index: Int): T = array(index)
23+
def update(index: Int, elem: T) = {
24+
array(index) = elem
25+
}
26+
}

tests/run/valueclasses-array-functions.check

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,6 @@ X-7
55
X-9
66
X-11
77
X-32
8+
List(X-11)
9+
r6: Set(X-7, X-9, X-11)
10+
r7: List(X-7, X-9, X-11)

tests/run/valueclasses-array-functions.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,14 @@ object Test {
1010
val r1 = for (y <- test) { println(y) }
1111
val r2 = test foreach ( x => println(x.toString) )
1212
val r3 = test.foldLeft(new X(5))((x, y) => new X(x.a + y.a))
13+
val r4 = test filter ( x => x.toString.contains("1") )
14+
val r5 = r4.toList
1315
println(r3)
16+
println(r5)
17+
val r6 = test.toSet
18+
println(s"r6: $r6")
19+
val r7 = test.toList
20+
println(s"r7: $r7")
1421

1522
val t1: ArrayOps[X] = Array(new X(7))
1623
}

0 commit comments

Comments
 (0)