Skip to content

Commit b4213ef

Browse files
committed
IterableOnce#copyToArray uses helper for count
1 parent 27440d4 commit b4213ef

File tree

2 files changed

+44
-23
lines changed

2 files changed

+44
-23
lines changed

src/library/scala/collection/IterableOnce.scala

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,9 @@ object IterableOnce {
272272
* @return the number of elements that will be copied to the destination array
273273
*/
274274
@inline private[collection] def elemsToCopyToArray(srcLen: Int, destLen: Int, start: Int, len: Int): Int =
275-
math.max(math.min(math.min(len, srcLen), destLen - start), 0)
275+
math.max(0,
276+
math.min(if (start < 0) destLen else destLen - start,
277+
math.min(len, srcLen)))
276278

277279
/** Calls `copyToArray` on the given collection, regardless of whether or not it is an `Iterable`. */
278280
@inline private[collection] def copyElemsToArray[A, B >: A](elems: IterableOnce[A],
@@ -1035,7 +1037,11 @@ trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A] =>
10351037
def copyToArray[B >: A](xs: Array[B], start: Int, len: Int): Int = {
10361038
val it = iterator
10371039
var i = start
1038-
val end = start + math.min(len, xs.length - start)
1040+
val srclen = knownSize match {
1041+
case -1 => xs.length
1042+
case k => k
1043+
}
1044+
val end = start + IterableOnce.elemsToCopyToArray(srclen, xs.length, start, len)
10391045
while (i < end && it.hasNext) {
10401046
xs(i) = it.next()
10411047
i += 1

test/junit/scala/collection/IterableTest.scala

Lines changed: 36 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -114,27 +114,42 @@ class IterableTest {
114114
}
115115
}
116116

117-
val far = 100000
118-
val l = Iterable.from(Range(0, 100))
119-
check(new Array(100), l.copyToArray(_), 100, 0, far)
120-
check(new Array(10), l.copyToArray(_), 10, 0, far)
121-
check(new Array(100), l.copyToArray(_), 100, 0, 100)
122-
123-
check(new Array(100), l.copyToArray(_, 5), 95, 5, 105)
124-
check(new Array(10), l.copyToArray(_, 5), 5, 5, 10)
125-
check(new Array(1000), l.copyToArray(_, 5), 100, 5, 105)
126-
127-
check(new Array(100), l.copyToArray(_, 5, 50), 50, 5, 55)
128-
check(new Array(10), l.copyToArray(_, 5, 50), 5, 5, 10)
129-
check(new Array(1000), l.copyToArray(_, 5, 50), 50, 5, 55)
130-
131-
assertThrows[ArrayIndexOutOfBoundsException](l.copyToArray(new Array(10), -1))
132-
assertThrows[ArrayIndexOutOfBoundsException](l.copyToArray(new Array(10), -1, 10))
133-
assertEquals(0, l.copyToArray(new Array(10), 1, -1))
134-
135-
check(new Array(10), l.copyToArray(_, 10), 0, 0, 0)
136-
check(new Array(10), l.copyToArray(_, 10, 10), 0, 0, 0)
137-
check(new Array(10), l.copyToArray(_, 0, -1), 0, 0, 0)
117+
def checkUp(basis: IterableOnce[Int]): Unit = {
118+
val it = Iterable.from(basis)
119+
val far = 100000
120+
121+
check(new Array(100), it.copyToArray(_), 100, 0, far)
122+
check(new Array(10), it.copyToArray(_), 10, 0, far)
123+
check(new Array(100), it.copyToArray(_), 100, 0, 100)
124+
125+
check(new Array(100), it.copyToArray(_, 5), 95, 5, 105)
126+
check(new Array(10), it.copyToArray(_, 5), 5, 5, 10)
127+
check(new Array(1000), it.copyToArray(_, 5), 100, 5, 105)
128+
129+
check(new Array(100), it.copyToArray(_, 5, 50), 50, 5, 55)
130+
check(new Array(10), it.copyToArray(_, 5, 50), 5, 5, 10)
131+
check(new Array(1000), it.copyToArray(_, 5, 50), 50, 5, 55)
132+
133+
// bad start index throws if n >= 0
134+
assertThrows[ArrayIndexOutOfBoundsException](it.copyToArray(new Array(10), -1))
135+
assertThrows[ArrayIndexOutOfBoundsException](it.copyToArray(new Array(10), -1, 10))
136+
assertEquals(0, it.copyToArray(new Array(10), 1, -1))
137+
138+
check(new Array(10), it.copyToArray(_, 10), 0, 0, 0)
139+
check(new Array(10), it.copyToArray(_, 10, 10), 0, 0, 0)
140+
check(new Array(10), it.copyToArray(_, 0, -1), 0, 0, 0)
141+
142+
// bad start index is ignored if n < 0
143+
check(new Array(10), it.copyToArray(_, -1, -1), 0, 0, 0)
144+
check(new Array(10), it.copyToArray(_, Int.MinValue, -1), 0, 0, 0)
145+
146+
// also if destination is empty
147+
check(new Array(0), it.copyToArray(_, 10, 10), 0, 0, 0)
148+
check(new Array(0), it.copyToArray(_, Int.MinValue, -1), 0, 0, 0)
149+
}
150+
checkUp(Range(0, 100))
151+
checkUp(List.range(0, 100))
152+
checkUp(Vector.range(0, 100))
138153
}
139154

140155
@Test @nowarn("cat=deprecation")

0 commit comments

Comments
 (0)