Skip to content

Commit fa71a56

Browse files
committed
Add subclasses IndexedSeq, LinearSeq, {mutable,immutable}.Seq to stdlib tests
1 parent 64e95b2 commit fa71a56

File tree

8 files changed

+674
-0
lines changed

8 files changed

+674
-0
lines changed

tests/pos/stdlib/IndexedSeq.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
collection/IndexedSeq.scala

tests/pos/stdlib/LinearSeq.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
collection/LinearSeq.scala
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
/*
2+
* Scala (https://www.scala-lang.org)
3+
*
4+
* Copyright EPFL and Lightbend, Inc.
5+
*
6+
* Licensed under Apache License 2.0
7+
* (http://www.apache.org/licenses/LICENSE-2.0).
8+
*
9+
* See the NOTICE file distributed with this work for
10+
* additional information regarding copyright ownership.
11+
*/
12+
13+
package scala
14+
package collection
15+
16+
import scala.annotation.{nowarn, tailrec}
17+
import scala.collection.Searching.{Found, InsertionPoint, SearchResult}
18+
import scala.collection.Stepper.EfficientSplit
19+
import scala.math.Ordering
20+
import language.experimental.captureChecking
21+
22+
/** Base trait for indexed sequences that have efficient `apply` and `length` */
23+
trait IndexedSeq[+A] extends Seq[A]
24+
with IndexedSeqOps[A, IndexedSeq, IndexedSeq[A]]
25+
with IterableFactoryDefaults[A, IndexedSeq] {
26+
@nowarn("""cat=deprecation&origin=scala\.collection\.Iterable\.stringPrefix""")
27+
override protected[this] def stringPrefix: String = "IndexedSeq"
28+
29+
override def iterableFactory: SeqFactory[IndexedSeq] = IndexedSeq
30+
}
31+
32+
@SerialVersionUID(3L)
33+
object IndexedSeq extends SeqFactory.Delegate[IndexedSeq](immutable.IndexedSeq)
34+
35+
/** Base trait for indexed Seq operations */
36+
trait IndexedSeqOps[+A, +CC[_], +C] extends AnyRef with SeqOps[A, CC, C] { self =>
37+
38+
def iterator: Iterator[A] = view.iterator
39+
40+
override def stepper[S <: Stepper[_]](implicit shape: StepperShape[A, S]): S with EfficientSplit = {
41+
import convert.impl._
42+
val s = shape.shape match {
43+
case StepperShape.IntShape => new IntIndexedSeqStepper (this.asInstanceOf[IndexedSeqOps[Int, AnyConstr, _]], 0, length)
44+
case StepperShape.LongShape => new LongIndexedSeqStepper (this.asInstanceOf[IndexedSeqOps[Long, AnyConstr, _]], 0, length)
45+
case StepperShape.DoubleShape => new DoubleIndexedSeqStepper(this.asInstanceOf[IndexedSeqOps[Double, AnyConstr, _]], 0, length)
46+
case _ => shape.parUnbox(new AnyIndexedSeqStepper[A](this, 0, length))
47+
}
48+
s.asInstanceOf[S with EfficientSplit]
49+
}
50+
51+
override def reverseIterator: Iterator[A] = view.reverseIterator
52+
53+
/* TODO 2.14+ uncomment and delete related code in IterableOnce
54+
@tailrec private def foldl[B](start: Int, end: Int, z: B, op: (B, A) => B): B =
55+
if (start == end) z
56+
else foldl(start + 1, end, op(z, apply(start)), op)
57+
*/
58+
59+
@tailrec private def foldr[B](start: Int, end: Int, z: B, op: (A, B) => B): B =
60+
if (start == end) z
61+
else foldr(start, end - 1, op(apply(end - 1), z), op)
62+
63+
//override def foldLeft[B](z: B)(op: (B, A) => B): B = foldl(0, length, z, op)
64+
65+
override def foldRight[B](z: B)(op: (A, B) => B): B = foldr(0, length, z, op)
66+
67+
//override def reduceLeft[B >: A](op: (B, A) => B): B = if (length > 0) foldl(1, length, apply(0), op) else super.reduceLeft(op)
68+
69+
//override def reduceRight[B >: A](op: (A, B) => B): B = if (length > 0) foldr(0, length - 1, apply(length - 1), op) else super.reduceRight(op)
70+
71+
override def view: IndexedSeqView[A] = new IndexedSeqView.Id[A](this)
72+
73+
@deprecated("Use .view.slice(from, until) instead of .view(from, until)", "2.13.0")
74+
override def view(from: Int, until: Int): IndexedSeqView[A] = view.slice(from, until)
75+
76+
override protected def reversed: Iterable[A] = new IndexedSeqView.Reverse(this)
77+
78+
// Override transformation operations to use more efficient views than the default ones
79+
override def prepended[B >: A](elem: B): CC[B] = iterableFactory.from(new IndexedSeqView.Prepended(elem, this))
80+
81+
override def take(n: Int): C = fromSpecific(new IndexedSeqView.Take(this, n))
82+
83+
override def takeRight(n: Int): C = fromSpecific(new IndexedSeqView.TakeRight(this, n))
84+
85+
override def drop(n: Int): C = fromSpecific(new IndexedSeqView.Drop(this, n))
86+
87+
override def dropRight(n: Int): C = fromSpecific(new IndexedSeqView.DropRight(this, n))
88+
89+
override def map[B](f: A => B): CC[B] = iterableFactory.from(new IndexedSeqView.Map(this, f))
90+
91+
override def reverse: C = fromSpecific(new IndexedSeqView.Reverse(this))
92+
93+
override def slice(from: Int, until: Int): C = fromSpecific(new IndexedSeqView.Slice(this, from, until))
94+
95+
override def head: A = apply(0)
96+
97+
override def headOption: Option[A] = if (isEmpty) None else Some(head)
98+
99+
override def last: A = apply(length - 1)
100+
101+
// We already inherit an efficient `lastOption = if (isEmpty) None else Some(last)`
102+
103+
override final def lengthCompare(len: Int): Int = Integer.compare(length, len)
104+
105+
override def knownSize: Int = length
106+
107+
override final def lengthCompare(that: Iterable[_]^): Int = {
108+
val res = that.sizeCompare(length)
109+
// can't just invert the result, because `-Int.MinValue == Int.MinValue`
110+
if (res == Int.MinValue) 1 else -res
111+
}
112+
113+
override def search[B >: A](elem: B)(implicit ord: Ordering[B]): SearchResult =
114+
binarySearch(elem, 0, length)(ord)
115+
116+
override def search[B >: A](elem: B, from: Int, to: Int)(implicit ord: Ordering[B]): SearchResult =
117+
binarySearch(elem, from, to)(ord)
118+
119+
@tailrec
120+
private[this] def binarySearch[B >: A](elem: B, from: Int, to: Int)
121+
(implicit ord: Ordering[B]): SearchResult = {
122+
if (from < 0) binarySearch(elem, 0, to)
123+
else if (to > length) binarySearch(elem, from, length)
124+
else if (to <= from) InsertionPoint(from)
125+
else {
126+
val idx = from + (to - from - 1) / 2
127+
math.signum(ord.compare(elem, apply(idx))) match {
128+
case -1 => binarySearch(elem, from, idx)(ord)
129+
case 1 => binarySearch(elem, idx + 1, to)(ord)
130+
case _ => Found(idx)
131+
}
132+
}
133+
}
134+
}

0 commit comments

Comments
 (0)