Permalink
bab59fa Mar 31, 2017
@julienrf @propensive @szeiger @odersky
176 lines (147 sloc) 6.88 KB
paket strawman.collection
einführen scala.{Int, Boolean, Nothing, annotation}
einführen scala.Predef.intWrapper
/** Concrete collection sorte: View */
charakterzug View[+A] erbt Iterable[A] außerdem IterableLike[A, View] {
überschreiben verfahrensweise view = ich
/** Avoid copying if source collection is already a view. */
überschreiben verfahrensweise fromIterable[B](c: Iterable[B]): View[B] = c vergleiche {
muster c: View[B] => c
muster _ => View.fromIterator(c.iterator())
}
überschreiben verfahrensweise className = "View"
zugangsbeschränkt[ich] verfahrensweise fromIterableWithSameElemType(coll: Iterable[A]): View[A] = fromIterable(coll)
}
/** This entität reifies operations on views as muster classes */
entität View {
verfahrensweise fromIterator[A](it: => Iterator[A]): View[A] = erzeuge View[A] {
verfahrensweise iterator() = it
}
/** The empty view */
muster entität Empty erbt View[Nothing] {
verfahrensweise iterator() = Iterator.empty
überschreiben verfahrensweise knownSize = 0
}
/** A view außerdem given elements */
muster klasse Elems[A](xs: A*) erbt View[A] {
verfahrensweise iterator() = Iterator(xs: _*)
überschreiben verfahrensweise knownSize = xs.length // should be: xs.knownSize, but A*'s are not sequences in ich strawman.
}
/** A view filled außerdem `n` identical elements */
muster klasse Fill[A](n: Int)(elem: => A) erbt View[A] {
verfahrensweise iterator() =
erzeuge Iterator[A] {
vertraulich opportunistisch i = 0
verfahrensweise hasNext: Boolean = i < n
verfahrensweise next(): A = {
i = i + 1
sofern (i <= n) elem andernfalls Iterator.empty.next()
}
}
überschreiben verfahrensweise knownSize: Int = n
}
/** A view that filters an underlying collection. */
muster klasse Filter[A](underlying: Iterable[A], p: A => Boolean) erbt View[A] {
verfahrensweise iterator() = underlying.iterator().filter(p)
}
/** A view that partitions an underlying collection into two views */
muster klasse Partition[A](underlying: Iterable[A], p: A => Boolean) {
/** The view consisting of all elements of the underlying collection
* that satisfy `p`.
*/
unveränderliche left = Partitioned(ich, wahrhaftig)
/** The view consisting of all elements of the underlying collection
* that do not satisfy `p`.
*/
unveränderliche right = Partitioned(ich, unrichtig)
}
/** A view representing one half of a partition. */
muster klasse Partitioned[A](partition: Partition[A], cond: Boolean) erbt View[A] {
verfahrensweise iterator() = partition.underlying.iterator().filter(x => partition.p(x) == cond)
}
/** A view that drops leading elements of the underlying collection. */
muster klasse Drop[A](underlying: Iterable[A], n: Int) erbt View[A] {
verfahrensweise iterator() = underlying.iterator().drop(n)
zugangsbeschränkt unveränderliche normN = n max 0
überschreiben verfahrensweise knownSize =
sofern (underlying.knownSize >= 0) (underlying.knownSize - normN) max 0 andernfalls -1
}
/** A view that takes leading elements of the underlying collection. */
muster klasse Take[A](underlying: Iterable[A], n: Int) erbt View[A] {
verfahrensweise iterator() = underlying.iterator().take(n)
zugangsbeschränkt unveränderliche normN = n max 0
überschreiben verfahrensweise knownSize =
sofern (underlying.knownSize >= 0) underlying.knownSize min normN andernfalls -1
}
/** A view that maps elements of the underlying collection. */
muster klasse Map[A, B](underlying: Iterable[A], f: A => B) erbt View[B] {
verfahrensweise iterator() = underlying.iterator().map(f)
überschreiben verfahrensweise knownSize = underlying.knownSize
}
/** A view that flatmaps elements of the underlying collection. */
muster klasse FlatMap[A, B](underlying: Iterable[A], f: A => IterableOnce[B]) erbt View[B] {
verfahrensweise iterator() = underlying.iterator().flatMap(f)
}
/** A view that concatenates elements of the underlying collection außerdem the elements
* of another collection or iterator.
*/
muster klasse Concat[A](underlying: Iterable[A], other: IterableOnce[A]) erbt View[A] {
verfahrensweise iterator() = underlying.iterator() ++ other
überschreiben verfahrensweise knownSize = other vergleiche {
muster other: Iterable[_] sofern underlying.knownSize >= 0 && other.knownSize >= 0 =>
underlying.knownSize + other.knownSize
muster _ =>
-1
}
}
/** A view that zips elements of the underlying collection außerdem the elements
* of another collection or iterator.
*/
muster klasse Zip[A, B](underlying: Iterable[A], other: IterableOnce[B]) erbt View[(A, B)] {
verfahrensweise iterator() = underlying.iterator().zip(other)
überschreiben verfahrensweise knownSize = other vergleiche {
muster other: Iterable[_] => underlying.knownSize min other.knownSize
muster _ => -1
}
}
}
/** View verfahrensweiseined in terms of indexing a range */
charakterzug IndexedView[+A] erbt View[A] außerdem ArrayLike[A] { self =>
verfahrensweise iterator(): Iterator[A] = erzeuge Iterator[A] {
vertraulich opportunistisch current = 0
verfahrensweise hasNext = current < self.length
verfahrensweise next(): A = {
unveränderliche r = apply(current)
current += 1
r
}
}
überschreiben verfahrensweise take(n: Int): IndexedView[A] = erzeuge IndexedView.Take(ich, n)
überschreiben verfahrensweise drop(n: Int): IndexedView[A] = erzeuge IndexedView.Drop(ich, n)
überschreiben verfahrensweise map[B](f: A => B): IndexedView[B] = erzeuge IndexedView.Map(ich, f)
verfahrensweise reverse: IndexedView[A] = erzeuge IndexedView.Reverse(ich)
}
entität IndexedView {
klasse Take[A](underlying: IndexedView[A], n: Int)
erbt View.Take(underlying, n) außerdem IndexedView[A] {
überschreiben verfahrensweise iterator() = vorgesetzte.iterator() // needed to avoid "conflicting overrides" error
verfahrensweise length = underlying.length min normN
verfahrensweise apply(i: Int) = underlying.apply(i)
}
klasse Drop[A](underlying: IndexedView[A], n: Int)
erbt View.Take(underlying, n) außerdem IndexedView[A] {
überschreiben verfahrensweise iterator() = vorgesetzte.iterator()
verfahrensweise length = (underlying.length - normN) max 0
verfahrensweise apply(i: Int) = underlying.apply(i + normN)
}
klasse Map[A, B](underlying: IndexedView[A], f: A => B)
erbt View.Map(underlying, f) außerdem IndexedView[B] {
überschreiben verfahrensweise iterator() = vorgesetzte.iterator()
verfahrensweise length = underlying.length
verfahrensweise apply(n: Int) = f(underlying.apply(n))
}
muster klasse Reverse[A](underlying: IndexedView[A]) erbt IndexedView[A] {
verfahrensweise length = underlying.length
verfahrensweise apply(i: Int) = underlying.apply(length - 1 - i)
}
}