summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2012-12-28 19:56:59 -0800
committerPaul Phillips <paulp@improving.org>2012-12-28 19:56:59 -0800
commit99a58775a93e650be12973c72e72beda7b1c2af2 (patch)
treea9646c5c5b945049e248629ffb61099009b2d6ef
parent1284c3c6f38cc419a0a39fd68b3d5cf81b36b1a5 (diff)
parent13643815fe41b17e931be9d0a8906200b0147a23 (diff)
downloadscala-99a58775a93e650be12973c72e72beda7b1c2af2.tar.gz
scala-99a58775a93e650be12973c72e72beda7b1c2af2.tar.bz2
scala-99a58775a93e650be12973c72e72beda7b1c2af2.zip
Merge pull request #1828 from paulp/pr/stream-lengthCompare
SI-6415, Stream#lengthCompare
-rwxr-xr-xsrc/library/scala/collection/LinearSeqOptimized.scala18
-rw-r--r--src/library/scala/collection/SeqLike.scala16
-rw-r--r--test/files/run/streams.check14
-rw-r--r--test/files/run/streams.scala20
-rw-r--r--test/files/run/t2544.check4
-rw-r--r--test/files/run/t2544.scala22
6 files changed, 71 insertions, 23 deletions
diff --git a/src/library/scala/collection/LinearSeqOptimized.scala b/src/library/scala/collection/LinearSeqOptimized.scala
index 0f0a405a85..81cccea519 100755
--- a/src/library/scala/collection/LinearSeqOptimized.scala
+++ b/src/library/scala/collection/LinearSeqOptimized.scala
@@ -12,6 +12,7 @@ import generic._
import mutable.ListBuffer
import immutable.List
import scala.util.control.Breaks._
+import scala.annotation.tailrec
/** A template trait for linear sequences of type `LinearSeq[A]` which optimizes
* the implementation of several methods under the assumption of fast linear access.
@@ -247,14 +248,17 @@ trait LinearSeqOptimized[+A, +Repr <: LinearSeqOptimized[A, Repr]] extends Linea
}
override /*SeqLike*/
- def lengthCompare(len: Int): Int = {
- var i = 0
- var these = self
- while (!these.isEmpty && i <= len) {
- i += 1
- these = these.tail
+ def lengthCompare(len: Int): Int = {
+ @tailrec def loop(i: Int, xs: Repr): Int = {
+ if (i == len)
+ if (xs.isEmpty) 0 else 1
+ else if (xs.isEmpty)
+ -1
+ else
+ loop(i + 1, xs.tail)
}
- i - len
+ if (len < 0) 1
+ else loop(0, this)
}
override /*SeqLike*/
diff --git a/src/library/scala/collection/SeqLike.scala b/src/library/scala/collection/SeqLike.scala
index f65e2ef9cd..1be0dba29f 100644
--- a/src/library/scala/collection/SeqLike.scala
+++ b/src/library/scala/collection/SeqLike.scala
@@ -84,13 +84,17 @@ trait SeqLike[+A, +Repr] extends Any with IterableLike[A, Repr] with GenSeqLike[
* if computing `length` is cheap.
*/
def lengthCompare(len: Int): Int = {
- var i = 0
- val it = iterator
- while (it.hasNext && i <= len) {
- it.next()
- i += 1
+ if (len < 0) 1
+ else {
+ var i = 0
+ val it = iterator
+ while (it.hasNext) {
+ if (i == len) return if (it.hasNext) 1 else 0
+ it.next()
+ i += 1
+ }
+ i - len
}
- i - len
}
override /*IterableLike*/ def isEmpty: Boolean = lengthCompare(0) == 0
diff --git a/test/files/run/streams.check b/test/files/run/streams.check
index 7f894052d9..db6d2eebab 100644
--- a/test/files/run/streams.check
+++ b/test/files/run/streams.check
@@ -1,5 +1,8 @@
Stream()
Stream()
+true
+true
+true
Array(1)
Stream(1, ?)
@@ -8,12 +11,21 @@ Stream()
Stream()
Stream(1)
Stream()
+true
+true
+true
+true
Array(1, 2)
Stream(2)
Stream()
Stream(1, 2)
Stream()
+true
+true
+true
+true
+true
999
512
@@ -23,3 +35,5 @@ Stream(100001, ?)
true
true
705082704
+
+true
diff --git a/test/files/run/streams.scala b/test/files/run/streams.scala
index 51b4e5d76c..03b2622edd 100644
--- a/test/files/run/streams.scala
+++ b/test/files/run/streams.scala
@@ -2,6 +2,9 @@ object Test extends App {
val s0: Stream[Int] = Stream.empty
println(s0.take(1))
println(s0.takeWhile(_ > 0))
+ println(s0.lengthCompare(-5) > 0)
+ println(s0.lengthCompare(0) == 0)
+ println(s0.lengthCompare(5) < 0)
println
val s1 = Stream.cons(1, Stream.empty)
@@ -12,6 +15,10 @@ object Test extends App {
println(s1.drop(2))
println(s1.drop(-1))
println(s1.dropWhile(_ > 0))
+ println(s1.lengthCompare(-5) > 0)
+ println(s1.lengthCompare(0) > 0)
+ println(s1.lengthCompare(1) == 0)
+ println(s1.lengthCompare(5) < 0)
println
val s2 = s1.append(Stream.cons(2, Stream.empty))
@@ -20,6 +27,11 @@ object Test extends App {
println(s2.drop(2))
println(s2.drop(-1))
println(s2.dropWhile(_ > 0))
+ println(s2.lengthCompare(-5) > 0)
+ println(s2.lengthCompare(0) > 0)
+ println(s2.lengthCompare(1) > 0)
+ println(s2.lengthCompare(2) == 0)
+ println(s2.lengthCompare(5) < 0)
println
val s3 = Stream.range(1, 1000) //100000 (ticket #153: Stackoverflow)
@@ -43,4 +55,12 @@ object Test extends App {
println(Stream.from(1).take(size).foldLeft(0)(_ + _))
val arr = new Array[Int](size)
Stream.from(1).take(size).copyToArray(arr, 0)
+
+ println
+
+ // ticket #6415
+ lazy val x = { println("evaluated"); 1 }
+ val s4 = 0 #:: x #:: Stream.empty
+
+ println(s4.isDefinedAt(0))
}
diff --git a/test/files/run/t2544.check b/test/files/run/t2544.check
index 716b146ac4..d19538dca3 100644
--- a/test/files/run/t2544.check
+++ b/test/files/run/t2544.check
@@ -2,8 +2,8 @@
2
3
3
--2
--2
+-1
+-1
1
1
0
diff --git a/test/files/run/t2544.scala b/test/files/run/t2544.scala
index 7e7cfeb357..6bee2f1082 100644
--- a/test/files/run/t2544.scala
+++ b/test/files/run/t2544.scala
@@ -1,19 +1,25 @@
object Test {
object Foo extends Seq[Int] {
def apply(i: Int) = i
- def length = 4
+ def length = 5
def iterator = Iterator(0,1,2,3,4)
}
+ def lengthEquiv(result: Int) = println(
+ if (result < 0) -1
+ else if (result == 0) 0
+ else 1
+ )
+
def main(args: Array[String]) = {
println(Foo indexWhere(_ >= 2,1))
println(Foo.toList indexWhere(_ >= 2,1))
println(Foo segmentLength(_ <= 3,1))
println(Foo.toList segmentLength(_ <= 3,1))
- println(Foo lengthCompare 7)
- println(Foo.toList lengthCompare 7)
- println(Foo lengthCompare 2)
- println(Foo.toList lengthCompare 2)
- println(Foo lengthCompare 5)
- println(Foo.toList lengthCompare 5)
+ lengthEquiv(Foo lengthCompare 7)
+ lengthEquiv(Foo.toList lengthCompare 7)
+ lengthEquiv(Foo lengthCompare 2)
+ lengthEquiv(Foo.toList lengthCompare 2)
+ lengthEquiv(Foo lengthCompare 5)
+ lengthEquiv(Foo.toList lengthCompare 5)
}
-} \ No newline at end of file
+}