boB Rudis
3 years ago
38 changed files with 10315 additions and 25 deletions
Binary file not shown.
@ -0,0 +1,627 @@ |
|||||
|
/* |
||||
|
* Scala (https://www.scala-lang.org) |
||||
|
* |
||||
|
* Copyright EPFL and Lightbend, Inc. |
||||
|
* |
||||
|
* Licensed under Apache License 2.0 |
||||
|
* (http://www.apache.org/licenses/LICENSE-2.0). |
||||
|
* |
||||
|
* See the NOTICE file distributed with this work for |
||||
|
* additional information regarding copyright ownership. |
||||
|
*/ |
||||
|
|
||||
|
package scala |
||||
|
|
||||
|
import scala.collection.generic._ |
||||
|
import scala.collection.{ mutable, immutable } |
||||
|
import mutable.{ ArrayBuilder, ArraySeq } |
||||
|
import scala.reflect.ClassTag |
||||
|
import scala.runtime.ScalaRunTime.{ array_apply, array_update } |
||||
|
|
||||
|
/** Contains a fallback builder for arrays when the element type |
||||
|
* does not have a class tag. In that case a generic array is built. |
||||
|
*/ |
||||
|
class FallbackArrayBuilding { |
||||
|
|
||||
|
/** A builder factory that generates a generic array. |
||||
|
* Called instead of `Array.newBuilder` if the element type of an array |
||||
|
* does not have a class tag. Note that fallbackBuilder factory |
||||
|
* needs an implicit parameter (otherwise it would not be dominated in |
||||
|
* implicit search by `Array.canBuildFrom`). We make sure that |
||||
|
* implicit search is always successful. |
||||
|
*/ |
||||
|
implicit def fallbackCanBuildFrom[T](implicit m: DummyImplicit): CanBuildFrom[Array[_], T, ArraySeq[T]] = |
||||
|
new CanBuildFrom[Array[_], T, ArraySeq[T]] { |
||||
|
def apply(from: Array[_]) = ArraySeq.newBuilder[T] |
||||
|
def apply() = ArraySeq.newBuilder[T] |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** Utility methods for operating on arrays. |
||||
|
* For example: |
||||
|
* {{{ |
||||
|
* val a = Array(1, 2) |
||||
|
* val b = Array.ofDim[Int](2) |
||||
|
* val c = Array.concat(a, b) |
||||
|
* }}} |
||||
|
* where the array objects `a`, `b` and `c` have respectively the values |
||||
|
* `Array(1, 2)`, `Array(0, 0)` and `Array(1, 2, 0, 0)`. |
||||
|
* |
||||
|
* @author Martin Odersky |
||||
|
* @since 1.0 |
||||
|
*/ |
||||
|
object Array extends FallbackArrayBuilding { |
||||
|
val emptyBooleanArray = new Array[Boolean](0) |
||||
|
val emptyByteArray = new Array[Byte](0) |
||||
|
val emptyCharArray = new Array[Char](0) |
||||
|
val emptyDoubleArray = new Array[Double](0) |
||||
|
val emptyFloatArray = new Array[Float](0) |
||||
|
val emptyIntArray = new Array[Int](0) |
||||
|
val emptyLongArray = new Array[Long](0) |
||||
|
val emptyShortArray = new Array[Short](0) |
||||
|
val emptyObjectArray = new Array[Object](0) |
||||
|
|
||||
|
implicit def canBuildFrom[T](implicit tag: ClassTag[T]): CanBuildFrom[Array[_], T, Array[T]] = { |
||||
|
val cls = tag.runtimeClass |
||||
|
(if (cls.isPrimitive) { |
||||
|
cls match { |
||||
|
case java.lang.Integer.TYPE => cbfIntArray |
||||
|
case java.lang.Double.TYPE => cbfDoubleArray |
||||
|
case java.lang.Long.TYPE => cbfLongArray |
||||
|
case java.lang.Float.TYPE => cbfFloatArray |
||||
|
case java.lang.Character.TYPE => cbfCharArray |
||||
|
case java.lang.Byte.TYPE => cbfByteArray |
||||
|
case java.lang.Short.TYPE => cbfShortArray |
||||
|
case java.lang.Boolean.TYPE => cbfBooleanArray |
||||
|
case java.lang.Void.TYPE => cbfUnitArray |
||||
|
} |
||||
|
} else if (cls == ObjectClass) { |
||||
|
cbfObjectArray |
||||
|
} else { |
||||
|
refCBF[T with AnyRef](tag.asInstanceOf[ClassTag[T with AnyRef]]) |
||||
|
}).asInstanceOf[CanBuildFrom[Array[_], T, Array[T]]] |
||||
|
} |
||||
|
private[this] val ObjectClass = classOf[Object] |
||||
|
|
||||
|
private[this] val cbfBooleanArray = new CanBuildFrom[Array[_], Boolean, Array[Boolean]] { |
||||
|
def apply(from: Array[_]) = new ArrayBuilder.ofBoolean() |
||||
|
def apply() = new ArrayBuilder.ofBoolean() |
||||
|
} |
||||
|
|
||||
|
private[this] val cbfByteArray = new CanBuildFrom[Array[_], Byte, Array[Byte]] { |
||||
|
def apply(from: Array[_]) = new ArrayBuilder.ofByte() |
||||
|
def apply() = new ArrayBuilder.ofByte() |
||||
|
} |
||||
|
|
||||
|
private[this] val cbfCharArray = new CanBuildFrom[Array[_], Char, Array[Char]] { |
||||
|
def apply(from: Array[_]) = new ArrayBuilder.ofChar() |
||||
|
def apply() = new ArrayBuilder.ofChar() |
||||
|
} |
||||
|
|
||||
|
private[this] val cbfDoubleArray = new CanBuildFrom[Array[_], Double, Array[Double]] { |
||||
|
def apply(from: Array[_]) = new ArrayBuilder.ofDouble() |
||||
|
def apply() = new ArrayBuilder.ofDouble() |
||||
|
} |
||||
|
|
||||
|
private[this] val cbfFloatArray = new CanBuildFrom[Array[_], Float, Array[Float]] { |
||||
|
def apply(from: Array[_]) = new ArrayBuilder.ofFloat() |
||||
|
def apply() = new ArrayBuilder.ofFloat() |
||||
|
} |
||||
|
|
||||
|
private[this] val cbfIntArray = new CanBuildFrom[Array[_], Int, Array[Int]] { |
||||
|
def apply(from: Array[_]) = new ArrayBuilder.ofInt() |
||||
|
def apply() = new ArrayBuilder.ofInt() |
||||
|
} |
||||
|
|
||||
|
private[this] val cbfLongArray = new CanBuildFrom[Array[_], Long, Array[Long]] { |
||||
|
def apply(from: Array[_]) = new ArrayBuilder.ofLong() |
||||
|
def apply() = new ArrayBuilder.ofLong() |
||||
|
} |
||||
|
|
||||
|
private[this] val cbfShortArray = new CanBuildFrom[Array[_], Short, Array[Short]] { |
||||
|
def apply(from: Array[_]) = new ArrayBuilder.ofShort() |
||||
|
def apply() = new ArrayBuilder.ofShort() |
||||
|
} |
||||
|
|
||||
|
private[this] val cbfUnitArray = new CanBuildFrom[Array[_], Unit, Array[Unit]] { |
||||
|
def apply(from: Array[_]) = new ArrayBuilder.ofUnit() |
||||
|
def apply() = new ArrayBuilder.ofUnit() |
||||
|
} |
||||
|
|
||||
|
private[this] val cbfObjectArray = refCBF[Object] |
||||
|
private[this] def refCBF[T <: AnyRef](implicit t: ClassTag[T]): CanBuildFrom[Array[_], T, Array[T]] = |
||||
|
new CanBuildFrom[Array[_], T, Array[T]] { |
||||
|
def apply(from: Array[_]) = new ArrayBuilder.ofRef[T]()(t) |
||||
|
def apply() = new ArrayBuilder.ofRef[T]()(t) |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Returns a new [[scala.collection.mutable.ArrayBuilder]]. |
||||
|
*/ |
||||
|
def newBuilder[T](implicit t: ClassTag[T]): ArrayBuilder[T] = ArrayBuilder.make[T]()(t) |
||||
|
|
||||
|
private def slowcopy(src : AnyRef, |
||||
|
srcPos : Int, |
||||
|
dest : AnyRef, |
||||
|
destPos : Int, |
||||
|
length : Int) { |
||||
|
var i = srcPos |
||||
|
var j = destPos |
||||
|
val srcUntil = srcPos + length |
||||
|
while (i < srcUntil) { |
||||
|
array_update(dest, j, array_apply(src, i)) |
||||
|
i += 1 |
||||
|
j += 1 |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** Copy one array to another. |
||||
|
* Equivalent to Java's |
||||
|
* `System.arraycopy(src, srcPos, dest, destPos, length)`, |
||||
|
* except that this also works for polymorphic and boxed arrays. |
||||
|
* |
||||
|
* Note that the passed-in `dest` array will be modified by this call. |
||||
|
* |
||||
|
* @param src the source array. |
||||
|
* @param srcPos starting position in the source array. |
||||
|
* @param dest destination array. |
||||
|
* @param destPos starting position in the destination array. |
||||
|
* @param length the number of array elements to be copied. |
||||
|
* |
||||
|
* @see `java.lang.System#arraycopy` |
||||
|
*/ |
||||
|
def copy(src: AnyRef, srcPos: Int, dest: AnyRef, destPos: Int, length: Int) { |
||||
|
val srcClass = src.getClass |
||||
|
if (srcClass.isArray && dest.getClass.isAssignableFrom(srcClass)) |
||||
|
java.lang.System.arraycopy(src, srcPos, dest, destPos, length) |
||||
|
else |
||||
|
slowcopy(src, srcPos, dest, destPos, length) |
||||
|
} |
||||
|
|
||||
|
/** Returns an array of length 0 */ |
||||
|
def empty[T: ClassTag]: Array[T] = new Array[T](0) |
||||
|
|
||||
|
/** Creates an array with given elements. |
||||
|
* |
||||
|
* @param xs the elements to put in the array |
||||
|
* @return an array containing all elements from xs. |
||||
|
*/ |
||||
|
// Subject to a compiler optimization in Cleanup. |
||||
|
// Array(e0, ..., en) is translated to { val a = new Array(3); a(i) = ei; a } |
||||
|
def apply[T: ClassTag](xs: T*): Array[T] = { |
||||
|
val array = new Array[T](xs.length) |
||||
|
var i = 0 |
||||
|
for (x <- xs.iterator) { array(i) = x; i += 1 } |
||||
|
array |
||||
|
} |
||||
|
|
||||
|
/** Creates an array of `Boolean` objects */ |
||||
|
// Subject to a compiler optimization in Cleanup, see above. |
||||
|
def apply(x: Boolean, xs: Boolean*): Array[Boolean] = { |
||||
|
val array = new Array[Boolean](xs.length + 1) |
||||
|
array(0) = x |
||||
|
var i = 1 |
||||
|
for (x <- xs.iterator) { array(i) = x; i += 1 } |
||||
|
array |
||||
|
} |
||||
|
|
||||
|
/** Creates an array of `Byte` objects */ |
||||
|
// Subject to a compiler optimization in Cleanup, see above. |
||||
|
def apply(x: Byte, xs: Byte*): Array[Byte] = { |
||||
|
val array = new Array[Byte](xs.length + 1) |
||||
|
array(0) = x |
||||
|
var i = 1 |
||||
|
for (x <- xs.iterator) { array(i) = x; i += 1 } |
||||
|
array |
||||
|
} |
||||
|
|
||||
|
/** Creates an array of `Short` objects */ |
||||
|
// Subject to a compiler optimization in Cleanup, see above. |
||||
|
def apply(x: Short, xs: Short*): Array[Short] = { |
||||
|
val array = new Array[Short](xs.length + 1) |
||||
|
array(0) = x |
||||
|
var i = 1 |
||||
|
for (x <- xs.iterator) { array(i) = x; i += 1 } |
||||
|
array |
||||
|
} |
||||
|
|
||||
|
/** Creates an array of `Char` objects */ |
||||
|
// Subject to a compiler optimization in Cleanup, see above. |
||||
|
def apply(x: Char, xs: Char*): Array[Char] = { |
||||
|
val array = new Array[Char](xs.length + 1) |
||||
|
array(0) = x |
||||
|
var i = 1 |
||||
|
for (x <- xs.iterator) { array(i) = x; i += 1 } |
||||
|
array |
||||
|
} |
||||
|
|
||||
|
/** Creates an array of `Int` objects */ |
||||
|
// Subject to a compiler optimization in Cleanup, see above. |
||||
|
def apply(x: Int, xs: Int*): Array[Int] = { |
||||
|
val array = new Array[Int](xs.length + 1) |
||||
|
array(0) = x |
||||
|
var i = 1 |
||||
|
for (x <- xs.iterator) { array(i) = x; i += 1 } |
||||
|
array |
||||
|
} |
||||
|
|
||||
|
/** Creates an array of `Long` objects */ |
||||
|
// Subject to a compiler optimization in Cleanup, see above. |
||||
|
def apply(x: Long, xs: Long*): Array[Long] = { |
||||
|
val array = new Array[Long](xs.length + 1) |
||||
|
array(0) = x |
||||
|
var i = 1 |
||||
|
for (x <- xs.iterator) { array(i) = x; i += 1 } |
||||
|
array |
||||
|
} |
||||
|
|
||||
|
/** Creates an array of `Float` objects */ |
||||
|
// Subject to a compiler optimization in Cleanup, see above. |
||||
|
def apply(x: Float, xs: Float*): Array[Float] = { |
||||
|
val array = new Array[Float](xs.length + 1) |
||||
|
array(0) = x |
||||
|
var i = 1 |
||||
|
for (x <- xs.iterator) { array(i) = x; i += 1 } |
||||
|
array |
||||
|
} |
||||
|
|
||||
|
/** Creates an array of `Double` objects */ |
||||
|
// Subject to a compiler optimization in Cleanup, see above. |
||||
|
def apply(x: Double, xs: Double*): Array[Double] = { |
||||
|
val array = new Array[Double](xs.length + 1) |
||||
|
array(0) = x |
||||
|
var i = 1 |
||||
|
for (x <- xs.iterator) { array(i) = x; i += 1 } |
||||
|
array |
||||
|
} |
||||
|
|
||||
|
/** Creates an array of `Unit` objects */ |
||||
|
def apply(x: Unit, xs: Unit*): Array[Unit] = { |
||||
|
val array = new Array[Unit](xs.length + 1) |
||||
|
array(0) = x |
||||
|
var i = 1 |
||||
|
for (x <- xs.iterator) { array(i) = x; i += 1 } |
||||
|
array |
||||
|
} |
||||
|
|
||||
|
/** Creates array with given dimensions */ |
||||
|
def ofDim[T: ClassTag](n1: Int): Array[T] = |
||||
|
new Array[T](n1) |
||||
|
/** Creates a 2-dimensional array */ |
||||
|
def ofDim[T: ClassTag](n1: Int, n2: Int): Array[Array[T]] = { |
||||
|
val arr: Array[Array[T]] = (new Array[Array[T]](n1): Array[Array[T]]) |
||||
|
for (i <- 0 until n1) arr(i) = new Array[T](n2) |
||||
|
arr |
||||
|
// tabulate(n1)(_ => ofDim[T](n2)) |
||||
|
} |
||||
|
/** Creates a 3-dimensional array */ |
||||
|
def ofDim[T: ClassTag](n1: Int, n2: Int, n3: Int): Array[Array[Array[T]]] = |
||||
|
tabulate(n1)(_ => ofDim[T](n2, n3)) |
||||
|
/** Creates a 4-dimensional array */ |
||||
|
def ofDim[T: ClassTag](n1: Int, n2: Int, n3: Int, n4: Int): Array[Array[Array[Array[T]]]] = |
||||
|
tabulate(n1)(_ => ofDim[T](n2, n3, n4)) |
||||
|
/** Creates a 5-dimensional array */ |
||||
|
def ofDim[T: ClassTag](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int): Array[Array[Array[Array[Array[T]]]]] = |
||||
|
tabulate(n1)(_ => ofDim[T](n2, n3, n4, n5)) |
||||
|
|
||||
|
/** Concatenates all arrays into a single array. |
||||
|
* |
||||
|
* @param xss the given arrays |
||||
|
* @return the array created from concatenating `xss` |
||||
|
*/ |
||||
|
def concat[T: ClassTag](xss: Array[T]*): Array[T] = { |
||||
|
val b = newBuilder[T] |
||||
|
b.sizeHint(xss.map(_.length).sum) |
||||
|
for (xs <- xss) b ++= xs |
||||
|
b.result() |
||||
|
} |
||||
|
|
||||
|
/** Returns an array that contains the results of some element computation a number |
||||
|
* of times. |
||||
|
* |
||||
|
* Note that this means that `elem` is computed a total of n times: |
||||
|
* {{{ |
||||
|
* scala> Array.fill(3){ math.random } |
||||
|
* res3: Array[Double] = Array(0.365461167592537, 1.550395944913685E-4, 0.7907242137333306) |
||||
|
* }}} |
||||
|
* |
||||
|
* @param n the number of elements desired |
||||
|
* @param elem the element computation |
||||
|
* @return an Array of size n, where each element contains the result of computing |
||||
|
* `elem`. |
||||
|
*/ |
||||
|
def fill[T: ClassTag](n: Int)(elem: => T): Array[T] = { |
||||
|
val b = newBuilder[T] |
||||
|
b.sizeHint(n) |
||||
|
var i = 0 |
||||
|
while (i < n) { |
||||
|
b += elem |
||||
|
i += 1 |
||||
|
} |
||||
|
b.result() |
||||
|
} |
||||
|
|
||||
|
/** Returns a two-dimensional array that contains the results of some element |
||||
|
* computation a number of times. |
||||
|
* |
||||
|
* @param n1 the number of elements in the 1st dimension |
||||
|
* @param n2 the number of elements in the 2nd dimension |
||||
|
* @param elem the element computation |
||||
|
*/ |
||||
|
def fill[T: ClassTag](n1: Int, n2: Int)(elem: => T): Array[Array[T]] = |
||||
|
tabulate(n1)(_ => fill(n2)(elem)) |
||||
|
|
||||
|
/** Returns a three-dimensional array that contains the results of some element |
||||
|
* computation a number of times. |
||||
|
* |
||||
|
* @param n1 the number of elements in the 1st dimension |
||||
|
* @param n2 the number of elements in the 2nd dimension |
||||
|
* @param n3 the number of elements in the 3nd dimension |
||||
|
* @param elem the element computation |
||||
|
*/ |
||||
|
def fill[T: ClassTag](n1: Int, n2: Int, n3: Int)(elem: => T): Array[Array[Array[T]]] = |
||||
|
tabulate(n1)(_ => fill(n2, n3)(elem)) |
||||
|
|
||||
|
/** Returns a four-dimensional array that contains the results of some element |
||||
|
* computation a number of times. |
||||
|
* |
||||
|
* @param n1 the number of elements in the 1st dimension |
||||
|
* @param n2 the number of elements in the 2nd dimension |
||||
|
* @param n3 the number of elements in the 3nd dimension |
||||
|
* @param n4 the number of elements in the 4th dimension |
||||
|
* @param elem the element computation |
||||
|
*/ |
||||
|
def fill[T: ClassTag](n1: Int, n2: Int, n3: Int, n4: Int)(elem: => T): Array[Array[Array[Array[T]]]] = |
||||
|
tabulate(n1)(_ => fill(n2, n3, n4)(elem)) |
||||
|
|
||||
|
/** Returns a five-dimensional array that contains the results of some element |
||||
|
* computation a number of times. |
||||
|
* |
||||
|
* @param n1 the number of elements in the 1st dimension |
||||
|
* @param n2 the number of elements in the 2nd dimension |
||||
|
* @param n3 the number of elements in the 3nd dimension |
||||
|
* @param n4 the number of elements in the 4th dimension |
||||
|
* @param n5 the number of elements in the 5th dimension |
||||
|
* @param elem the element computation |
||||
|
*/ |
||||
|
def fill[T: ClassTag](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int)(elem: => T): Array[Array[Array[Array[Array[T]]]]] = |
||||
|
tabulate(n1)(_ => fill(n2, n3, n4, n5)(elem)) |
||||
|
|
||||
|
/** Returns an array containing values of a given function over a range of integer |
||||
|
* values starting from 0. |
||||
|
* |
||||
|
* @param n The number of elements in the array |
||||
|
* @param f The function computing element values |
||||
|
* @return A traversable consisting of elements `f(0),f(1), ..., f(n - 1)` |
||||
|
*/ |
||||
|
def tabulate[T: ClassTag](n: Int)(f: Int => T): Array[T] = { |
||||
|
val b = newBuilder[T] |
||||
|
b.sizeHint(n) |
||||
|
var i = 0 |
||||
|
while (i < n) { |
||||
|
b += f(i) |
||||
|
i += 1 |
||||
|
} |
||||
|
b.result() |
||||
|
} |
||||
|
|
||||
|
/** Returns a two-dimensional array containing values of a given function |
||||
|
* over ranges of integer values starting from `0`. |
||||
|
* |
||||
|
* @param n1 the number of elements in the 1st dimension |
||||
|
* @param n2 the number of elements in the 2nd dimension |
||||
|
* @param f The function computing element values |
||||
|
*/ |
||||
|
def tabulate[T: ClassTag](n1: Int, n2: Int)(f: (Int, Int) => T): Array[Array[T]] = |
||||
|
tabulate(n1)(i1 => tabulate(n2)(f(i1, _))) |
||||
|
|
||||
|
/** Returns a three-dimensional array containing values of a given function |
||||
|
* over ranges of integer values starting from `0`. |
||||
|
* |
||||
|
* @param n1 the number of elements in the 1st dimension |
||||
|
* @param n2 the number of elements in the 2nd dimension |
||||
|
* @param n3 the number of elements in the 3rd dimension |
||||
|
* @param f The function computing element values |
||||
|
*/ |
||||
|
def tabulate[T: ClassTag](n1: Int, n2: Int, n3: Int)(f: (Int, Int, Int) => T): Array[Array[Array[T]]] = |
||||
|
tabulate(n1)(i1 => tabulate(n2, n3)(f(i1, _, _))) |
||||
|
|
||||
|
/** Returns a four-dimensional array containing values of a given function |
||||
|
* over ranges of integer values starting from `0`. |
||||
|
* |
||||
|
* @param n1 the number of elements in the 1st dimension |
||||
|
* @param n2 the number of elements in the 2nd dimension |
||||
|
* @param n3 the number of elements in the 3rd dimension |
||||
|
* @param n4 the number of elements in the 4th dimension |
||||
|
* @param f The function computing element values |
||||
|
*/ |
||||
|
def tabulate[T: ClassTag](n1: Int, n2: Int, n3: Int, n4: Int)(f: (Int, Int, Int, Int) => T): Array[Array[Array[Array[T]]]] = |
||||
|
tabulate(n1)(i1 => tabulate(n2, n3, n4)(f(i1, _, _, _))) |
||||
|
|
||||
|
/** Returns a five-dimensional array containing values of a given function |
||||
|
* over ranges of integer values starting from `0`. |
||||
|
* |
||||
|
* @param n1 the number of elements in the 1st dimension |
||||
|
* @param n2 the number of elements in the 2nd dimension |
||||
|
* @param n3 the number of elements in the 3rd dimension |
||||
|
* @param n4 the number of elements in the 4th dimension |
||||
|
* @param n5 the number of elements in the 5th dimension |
||||
|
* @param f The function computing element values |
||||
|
*/ |
||||
|
def tabulate[T: ClassTag](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int)(f: (Int, Int, Int, Int, Int) => T): Array[Array[Array[Array[Array[T]]]]] = |
||||
|
tabulate(n1)(i1 => tabulate(n2, n3, n4, n5)(f(i1, _, _, _, _))) |
||||
|
|
||||
|
/** Returns an array containing a sequence of increasing integers in a range. |
||||
|
* |
||||
|
* @param start the start value of the array |
||||
|
* @param end the end value of the array, exclusive (in other words, this is the first value '''not''' returned) |
||||
|
* @return the array with values in range `start, start + 1, ..., end - 1` |
||||
|
* up to, but excluding, `end`. |
||||
|
*/ |
||||
|
def range(start: Int, end: Int): Array[Int] = range(start, end, 1) |
||||
|
|
||||
|
/** Returns an array containing equally spaced values in some integer interval. |
||||
|
* |
||||
|
* @param start the start value of the array |
||||
|
* @param end the end value of the array, exclusive (in other words, this is the first value '''not''' returned) |
||||
|
* @param step the increment value of the array (may not be zero) |
||||
|
* @return the array with values in `start, start + step, ...` up to, but excluding `end` |
||||
|
*/ |
||||
|
def range(start: Int, end: Int, step: Int): Array[Int] = { |
||||
|
if (step == 0) throw new IllegalArgumentException("zero step") |
||||
|
val b = newBuilder[Int] |
||||
|
b.sizeHint(immutable.Range.count(start, end, step, isInclusive = false)) |
||||
|
|
||||
|
var i = start |
||||
|
while (if (step < 0) end < i else i < end) { |
||||
|
b += i |
||||
|
i += step |
||||
|
} |
||||
|
b.result() |
||||
|
} |
||||
|
|
||||
|
/** Returns an array containing repeated applications of a function to a start value. |
||||
|
* |
||||
|
* @param start the start value of the array |
||||
|
* @param len the number of elements returned by the array |
||||
|
* @param f the function that is repeatedly applied |
||||
|
* @return the array returning `len` values in the sequence `start, f(start), f(f(start)), ...` |
||||
|
*/ |
||||
|
def iterate[T: ClassTag](start: T, len: Int)(f: T => T): Array[T] = { |
||||
|
val b = newBuilder[T] |
||||
|
|
||||
|
if (len > 0) { |
||||
|
b.sizeHint(len) |
||||
|
var acc = start |
||||
|
var i = 1 |
||||
|
b += acc |
||||
|
|
||||
|
while (i < len) { |
||||
|
acc = f(acc) |
||||
|
i += 1 |
||||
|
b += acc |
||||
|
} |
||||
|
} |
||||
|
b.result() |
||||
|
} |
||||
|
|
||||
|
/** Called in a pattern match like `{ case Array(x,y,z) => println('3 elements')}`. |
||||
|
* |
||||
|
* @param x the selector value |
||||
|
* @return sequence wrapped in a [[scala.Some]], if `x` is a Seq, otherwise `None` |
||||
|
*/ |
||||
|
def unapplySeq[T](x: Array[T]): Option[IndexedSeq[T]] = |
||||
|
if (x == null) None else Some(x.toIndexedSeq) |
||||
|
// !!! the null check should to be necessary, but without it 2241 fails. Seems to be a bug |
||||
|
// in pattern matcher. @PP: I noted in #4364 I think the behavior is correct. |
||||
|
} |
||||
|
|
||||
|
/** Arrays are mutable, indexed collections of values. `Array[T]` is Scala's representation |
||||
|
* for Java's `T[]`. |
||||
|
* |
||||
|
* {{{ |
||||
|
* val numbers = Array(1, 2, 3, 4) |
||||
|
* val first = numbers(0) // read the first element |
||||
|
* numbers(3) = 100 // replace the 4th array element with 100 |
||||
|
* val biggerNumbers = numbers.map(_ * 2) // multiply all numbers by two |
||||
|
* }}} |
||||
|
* |
||||
|
* Arrays make use of two common pieces of Scala syntactic sugar, shown on lines 2 and 3 of the above |
||||
|
* example code. |
||||
|
* Line 2 is translated into a call to `apply(Int)`, while line 3 is translated into a call to |
||||
|
* `update(Int, T)`. |
||||
|
* |
||||
|
* Two implicit conversions exist in [[scala.Predef]] that are frequently applied to arrays: a conversion |
||||
|
* to [[scala.collection.mutable.ArrayOps]] (shown on line 4 of the example above) and a conversion |
||||
|
* to [[scala.collection.mutable.WrappedArray]] (a subtype of [[scala.collection.Seq]]). |
||||
|
* Both types make available many of the standard operations found in the Scala collections API. |
||||
|
* The conversion to `ArrayOps` is temporary, as all operations defined on `ArrayOps` return an `Array`, |
||||
|
* while the conversion to `WrappedArray` is permanent as all operations return a `WrappedArray`. |
||||
|
* |
||||
|
* The conversion to `ArrayOps` takes priority over the conversion to `WrappedArray`. For instance, |
||||
|
* consider the following code: |
||||
|
* |
||||
|
* {{{ |
||||
|
* val arr = Array(1, 2, 3) |
||||
|
* val arrReversed = arr.reverse |
||||
|
* val seqReversed : Seq[Int] = arr.reverse |
||||
|
* }}} |
||||
|
* |
||||
|
* Value `arrReversed` will be of type `Array[Int]`, with an implicit conversion to `ArrayOps` occurring |
||||
|
* to perform the `reverse` operation. The value of `seqReversed`, on the other hand, will be computed |
||||
|
* by converting to `WrappedArray` first and invoking the variant of `reverse` that returns another |
||||
|
* `WrappedArray`. |
||||
|
* |
||||
|
* @author Martin Odersky |
||||
|
* @since 1.0 |
||||
|
* @see [[http://www.scala-lang.org/files/archive/spec/2.12/ Scala Language Specification]], for in-depth information on the transformations the Scala compiler makes on Arrays (Sections 6.6 and 6.15 respectively.) |
||||
|
* @see [[http://docs.scala-lang.org/sips/completed/scala-2-8-arrays.html "Scala 2.8 Arrays"]] the Scala Improvement Document detailing arrays since Scala 2.8. |
||||
|
* @see [[http://docs.scala-lang.org/overviews/collections/arrays.html "The Scala 2.8 Collections' API"]] section on `Array` by Martin Odersky for more information. |
||||
|
* @hideImplicitConversion scala.Predef.booleanArrayOps |
||||
|
* @hideImplicitConversion scala.Predef.byteArrayOps |
||||
|
* @hideImplicitConversion scala.Predef.charArrayOps |
||||
|
* @hideImplicitConversion scala.Predef.doubleArrayOps |
||||
|
* @hideImplicitConversion scala.Predef.floatArrayOps |
||||
|
* @hideImplicitConversion scala.Predef.intArrayOps |
||||
|
* @hideImplicitConversion scala.Predef.longArrayOps |
||||
|
* @hideImplicitConversion scala.Predef.refArrayOps |
||||
|
* @hideImplicitConversion scala.Predef.shortArrayOps |
||||
|
* @hideImplicitConversion scala.Predef.unitArrayOps |
||||
|
* @hideImplicitConversion scala.LowPriorityImplicits.wrapRefArray |
||||
|
* @hideImplicitConversion scala.LowPriorityImplicits.wrapIntArray |
||||
|
* @hideImplicitConversion scala.LowPriorityImplicits.wrapDoubleArray |
||||
|
* @hideImplicitConversion scala.LowPriorityImplicits.wrapLongArray |
||||
|
* @hideImplicitConversion scala.LowPriorityImplicits.wrapFloatArray |
||||
|
* @hideImplicitConversion scala.LowPriorityImplicits.wrapCharArray |
||||
|
* @hideImplicitConversion scala.LowPriorityImplicits.wrapByteArray |
||||
|
* @hideImplicitConversion scala.LowPriorityImplicits.wrapShortArray |
||||
|
* @hideImplicitConversion scala.LowPriorityImplicits.wrapBooleanArray |
||||
|
* @hideImplicitConversion scala.LowPriorityImplicits.wrapUnitArray |
||||
|
* @hideImplicitConversion scala.LowPriorityImplicits.genericWrapArray |
||||
|
* @define coll array |
||||
|
* @define Coll `Array` |
||||
|
* @define orderDependent |
||||
|
* @define orderDependentFold |
||||
|
* @define mayNotTerminateInf |
||||
|
* @define willNotTerminateInf |
||||
|
* @define collectExample |
||||
|
* @define undefinedorder |
||||
|
* @define thatinfo the class of the returned collection. In the standard library configuration, |
||||
|
* `That` is either `Array[B]` if an ClassTag is available for B or `ArraySeq[B]` otherwise. |
||||
|
* @define zipthatinfo $thatinfo |
||||
|
* @define bfinfo an implicit value of class `CanBuildFrom` which determines the result class `That` from the current |
||||
|
* representation type `Repr` and the new element type `B`. |
||||
|
*/ |
||||
|
final class Array[T](_length: Int) extends java.io.Serializable with java.lang.Cloneable { |
||||
|
|
||||
|
/** The length of the array */ |
||||
|
def length: Int = throw new Error() |
||||
|
|
||||
|
/** The element at given index. |
||||
|
* |
||||
|
* Indices start at `0`; `xs.apply(0)` is the first element of array `xs`. |
||||
|
* Note the indexing syntax `xs(i)` is a shorthand for `xs.apply(i)`. |
||||
|
* |
||||
|
* @param i the index |
||||
|
* @return the element at the given index |
||||
|
* @throws ArrayIndexOutOfBoundsException if `i < 0` or `length <= i` |
||||
|
*/ |
||||
|
def apply(i: Int): T = throw new Error() |
||||
|
|
||||
|
/** Update the element at given index. |
||||
|
* |
||||
|
* Indices start at `0`; `xs.update(i, x)` replaces the i^th^ element in the array. |
||||
|
* Note the syntax `xs(i) = x` is a shorthand for `xs.update(i, x)`. |
||||
|
* |
||||
|
* @param i the index |
||||
|
* @param x the value to be written at index `i` |
||||
|
* @throws ArrayIndexOutOfBoundsException if `i < 0` or `length <= i` |
||||
|
*/ |
||||
|
def update(i: Int, x: T) { throw new Error() } |
||||
|
|
||||
|
/** Clone the Array. |
||||
|
* |
||||
|
* @return A clone of the Array. |
||||
|
*/ |
||||
|
override def clone(): Array[T] = throw new Error() |
||||
|
} |
@ -0,0 +1,325 @@ |
|||||
|
/* |
||||
|
* Scala (https://www.scala-lang.org) |
||||
|
* |
||||
|
* Copyright EPFL and Lightbend, Inc. |
||||
|
* |
||||
|
* Licensed under Apache License 2.0 |
||||
|
* (http://www.apache.org/licenses/LICENSE-2.0). |
||||
|
* |
||||
|
* See the NOTICE file distributed with this work for |
||||
|
* additional information regarding copyright ownership. |
||||
|
*/ |
||||
|
|
||||
|
package scala |
||||
|
package collection |
||||
|
|
||||
|
import scala.annotation.tailrec |
||||
|
|
||||
|
/** A template trait for linear sequences of type `LinearSeq[A]` which optimizes |
||||
|
* the implementation of various methods under the assumption of fast linear access. |
||||
|
* |
||||
|
* $linearSeqOptim |
||||
|
* |
||||
|
* @define linearSeqOptim |
||||
|
* Linear-optimized sequences implement most operations in in terms of three methods, |
||||
|
* which are assumed to have efficient implementations. These are: |
||||
|
* {{{ |
||||
|
* def isEmpty: Boolean |
||||
|
* def head: A |
||||
|
* def tail: Repr |
||||
|
* }}} |
||||
|
* Here, `A` is the type of the sequence elements and `Repr` is the type of the sequence itself. |
||||
|
* Note that default implementations are provided via inheritance, but these |
||||
|
* should be overridden for performance. |
||||
|
* |
||||
|
* |
||||
|
*/ |
||||
|
trait LinearSeqOptimized[+A, +Repr <: LinearSeqOptimized[A, Repr]] extends LinearSeqLike[A, Repr] { self: Repr => |
||||
|
|
||||
|
def isEmpty: Boolean |
||||
|
|
||||
|
def head: A |
||||
|
|
||||
|
def tail: Repr |
||||
|
|
||||
|
/** The length of the $coll. |
||||
|
* |
||||
|
* $willNotTerminateInf |
||||
|
* |
||||
|
* Note: the execution of `length` may take time proportional to the length of the sequence. |
||||
|
*/ |
||||
|
def length: Int = { |
||||
|
var these = self |
||||
|
var len = 0 |
||||
|
while (!these.isEmpty) { |
||||
|
len += 1 |
||||
|
these = these.tail |
||||
|
} |
||||
|
len |
||||
|
} |
||||
|
|
||||
|
/** Selects an element by its index in the $coll. |
||||
|
* Note: the execution of `apply` may take time proportional to the index value. |
||||
|
* @throws IndexOutOfBoundsException if `idx` does not satisfy `0 <= idx < length`. |
||||
|
*/ |
||||
|
def apply(n: Int): A = { |
||||
|
val rest = drop(n) |
||||
|
if (n < 0 || rest.isEmpty) throw new IndexOutOfBoundsException("" + n) |
||||
|
rest.head |
||||
|
} |
||||
|
|
||||
|
override /*IterableLike*/ |
||||
|
def foreach[U](f: A => U) { |
||||
|
var these = this |
||||
|
while (!these.isEmpty) { |
||||
|
f(these.head) |
||||
|
these = these.tail |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
override /*IterableLike*/ |
||||
|
def forall(p: A => Boolean): Boolean = { |
||||
|
var these = this |
||||
|
while (!these.isEmpty) { |
||||
|
if (!p(these.head)) return false |
||||
|
these = these.tail |
||||
|
} |
||||
|
true |
||||
|
} |
||||
|
|
||||
|
override /*IterableLike*/ |
||||
|
def exists(p: A => Boolean): Boolean = { |
||||
|
var these = this |
||||
|
while (!these.isEmpty) { |
||||
|
if (p(these.head)) return true |
||||
|
these = these.tail |
||||
|
} |
||||
|
false |
||||
|
} |
||||
|
|
||||
|
override /*SeqLike*/ |
||||
|
def contains[A1 >: A](elem: A1): Boolean = { |
||||
|
var these = this |
||||
|
while (!these.isEmpty) { |
||||
|
if (these.head == elem) return true |
||||
|
these = these.tail |
||||
|
} |
||||
|
false |
||||
|
} |
||||
|
|
||||
|
override /*IterableLike*/ |
||||
|
def find(p: A => Boolean): Option[A] = { |
||||
|
var these = this |
||||
|
while (!these.isEmpty) { |
||||
|
if (p(these.head)) return Some(these.head) |
||||
|
these = these.tail |
||||
|
} |
||||
|
None |
||||
|
} |
||||
|
|
||||
|
override /*TraversableLike*/ |
||||
|
def foldLeft[B](z: B)(@deprecatedName('f) op: (B, A) => B): B = { |
||||
|
var acc = z |
||||
|
var these = this |
||||
|
while (!these.isEmpty) { |
||||
|
acc = op(acc, these.head) |
||||
|
these = these.tail |
||||
|
} |
||||
|
acc |
||||
|
} |
||||
|
|
||||
|
override /*IterableLike*/ |
||||
|
def foldRight[B](z: B)(@deprecatedName('f) op: (A, B) => B): B = |
||||
|
if (this.isEmpty) z |
||||
|
else op(head, tail.foldRight(z)(op)) |
||||
|
|
||||
|
override /*TraversableLike*/ |
||||
|
def reduceLeft[B >: A](@deprecatedName('f) op: (B, A) => B): B = |
||||
|
if (isEmpty) throw new UnsupportedOperationException("empty.reduceLeft") |
||||
|
else tail.foldLeft[B](head)(op) |
||||
|
|
||||
|
override /*IterableLike*/ |
||||
|
def reduceRight[B >: A](op: (A, B) => B): B = |
||||
|
if (isEmpty) throw new UnsupportedOperationException("Nil.reduceRight") |
||||
|
else if (tail.isEmpty) head |
||||
|
else op(head, tail.reduceRight(op)) |
||||
|
|
||||
|
override /*TraversableLike*/ |
||||
|
def last: A = { |
||||
|
if (isEmpty) throw new NoSuchElementException |
||||
|
var these = this |
||||
|
var nx = these.tail |
||||
|
while (!nx.isEmpty) { |
||||
|
these = nx |
||||
|
nx = nx.tail |
||||
|
} |
||||
|
these.head |
||||
|
} |
||||
|
|
||||
|
override /*IterableLike*/ |
||||
|
def take(n: Int): Repr = { |
||||
|
val b = newBuilder |
||||
|
var i = 0 |
||||
|
var these = repr |
||||
|
while (!these.isEmpty && i < n) { |
||||
|
i += 1 |
||||
|
b += these.head |
||||
|
these = these.tail |
||||
|
} |
||||
|
b.result() |
||||
|
} |
||||
|
|
||||
|
override /*TraversableLike*/ |
||||
|
def drop(n: Int): Repr = { |
||||
|
var these: Repr = repr |
||||
|
var count = n |
||||
|
while (!these.isEmpty && count > 0) { |
||||
|
these = these.tail |
||||
|
count -= 1 |
||||
|
} |
||||
|
// !!! This line should actually be something like: |
||||
|
// newBuilder ++= these result |
||||
|
// since we are in collection.*, not immutable.*. |
||||
|
// However making that change will pessimize all the |
||||
|
// immutable linear seqs (like list) which surely expect |
||||
|
// drop to share. (Or at least it would penalize List if |
||||
|
// it didn't override drop. It would be a lot better if |
||||
|
// the leaf collections didn't override so many methods.) |
||||
|
// |
||||
|
// Upshot: MutableList is broken and passes part of the |
||||
|
// original list as the result of drop. |
||||
|
these |
||||
|
} |
||||
|
|
||||
|
override /*IterableLike*/ |
||||
|
def dropRight(n: Int): Repr = { |
||||
|
val b = newBuilder |
||||
|
var these = this |
||||
|
var lead = this drop n |
||||
|
while (!lead.isEmpty) { |
||||
|
b += these.head |
||||
|
these = these.tail |
||||
|
lead = lead.tail |
||||
|
} |
||||
|
b.result() |
||||
|
} |
||||
|
|
||||
|
override /*IterableLike*/ |
||||
|
def slice(from: Int, until: Int): Repr = { |
||||
|
var these: Repr = repr |
||||
|
var count = from max 0 |
||||
|
if (until <= count) |
||||
|
return newBuilder.result() |
||||
|
|
||||
|
val b = newBuilder |
||||
|
var sliceElems = until - count |
||||
|
while (these.nonEmpty && count > 0) { |
||||
|
these = these.tail |
||||
|
count -= 1 |
||||
|
} |
||||
|
while (these.nonEmpty && sliceElems > 0) { |
||||
|
sliceElems -= 1 |
||||
|
b += these.head |
||||
|
these = these.tail |
||||
|
} |
||||
|
b.result() |
||||
|
} |
||||
|
|
||||
|
override /*IterableLike*/ |
||||
|
def takeWhile(p: A => Boolean): Repr = { |
||||
|
val b = newBuilder |
||||
|
var these = this |
||||
|
while (!these.isEmpty && p(these.head)) { |
||||
|
b += these.head |
||||
|
these = these.tail |
||||
|
} |
||||
|
b.result() |
||||
|
} |
||||
|
|
||||
|
override /*TraversableLike*/ |
||||
|
def span(p: A => Boolean): (Repr, Repr) = { |
||||
|
var these: Repr = repr |
||||
|
val b = newBuilder |
||||
|
while (!these.isEmpty && p(these.head)) { |
||||
|
b += these.head |
||||
|
these = these.tail |
||||
|
} |
||||
|
(b.result(), these) |
||||
|
} |
||||
|
|
||||
|
override /*IterableLike*/ |
||||
|
def sameElements[B >: A](that: GenIterable[B]): Boolean = that match { |
||||
|
case that1: LinearSeq[_] => |
||||
|
// Probably immutable, so check reference identity first (it's quick anyway) |
||||
|
(this eq that1) || { |
||||
|
var these = this |
||||
|
var those = that1 |
||||
|
while (!these.isEmpty && !those.isEmpty && these.head == those.head) { |
||||
|
these = these.tail |
||||
|
those = those.tail |
||||
|
} |
||||
|
these.isEmpty && those.isEmpty |
||||
|
} |
||||
|
case _ => |
||||
|
super.sameElements(that) |
||||
|
} |
||||
|
|
||||
|
override /*SeqLike*/ |
||||
|
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) |
||||
|
} |
||||
|
if (len < 0) 1 |
||||
|
else loop(0, this) |
||||
|
} |
||||
|
|
||||
|
override /*SeqLike*/ |
||||
|
def isDefinedAt(x: Int): Boolean = x >= 0 && lengthCompare(x) > 0 |
||||
|
|
||||
|
override /*SeqLike*/ |
||||
|
def segmentLength(p: A => Boolean, from: Int): Int = { |
||||
|
var i = 0 |
||||
|
var these = this drop from |
||||
|
while (!these.isEmpty && p(these.head)) { |
||||
|
i += 1 |
||||
|
these = these.tail |
||||
|
} |
||||
|
i |
||||
|
} |
||||
|
|
||||
|
override /*SeqLike*/ |
||||
|
def indexWhere(p: A => Boolean, from: Int): Int = { |
||||
|
var i = math.max(from, 0) |
||||
|
var these = this drop from |
||||
|
while (these.nonEmpty) { |
||||
|
if (p(these.head)) |
||||
|
return i |
||||
|
|
||||
|
i += 1 |
||||
|
these = these.tail |
||||
|
} |
||||
|
-1 |
||||
|
} |
||||
|
|
||||
|
override /*SeqLike*/ |
||||
|
def lastIndexWhere(p: A => Boolean, end: Int): Int = { |
||||
|
var i = 0 |
||||
|
var these = this |
||||
|
var last = -1 |
||||
|
while (!these.isEmpty && i <= end) { |
||||
|
if (p(these.head)) last = i |
||||
|
these = these.tail |
||||
|
i += 1 |
||||
|
} |
||||
|
last |
||||
|
} |
||||
|
|
||||
|
override /*TraversableLike*/ |
||||
|
def tails: Iterator[Repr] = Iterator.iterate(repr)(_.tail).takeWhile(_.nonEmpty) ++ Iterator(newBuilder.result) |
||||
|
} |
@ -0,0 +1,375 @@ |
|||||
|
/* |
||||
|
* Scala (https://www.scala-lang.org) |
||||
|
* |
||||
|
* Copyright EPFL and Lightbend, Inc. |
||||
|
* |
||||
|
* Licensed under Apache License 2.0 |
||||
|
* (http://www.apache.org/licenses/LICENSE-2.0). |
||||
|
* |
||||
|
* See the NOTICE file distributed with this work for |
||||
|
* additional information regarding copyright ownership. |
||||
|
*/ |
||||
|
|
||||
|
package scala |
||||
|
package io |
||||
|
|
||||
|
import scala.collection.AbstractIterator |
||||
|
import java.io.{ FileInputStream, InputStream, PrintStream, File => JFile, Closeable } |
||||
|
import java.net.{ URI, URL } |
||||
|
|
||||
|
/** This object provides convenience methods to create an iterable |
||||
|
* representation of a source file. |
||||
|
* |
||||
|
* @author Burak Emir, Paul Phillips |
||||
|
*/ |
||||
|
object Source { |
||||
|
val DefaultBufSize = 2048 |
||||
|
|
||||
|
/** Creates a `Source` from System.in. |
||||
|
*/ |
||||
|
def stdin = fromInputStream(System.in) |
||||
|
|
||||
|
/** Creates a Source from an Iterable. |
||||
|
* |
||||
|
* @param iterable the Iterable |
||||
|
* @return the Source |
||||
|
*/ |
||||
|
def fromIterable(iterable: Iterable[Char]): Source = new Source { |
||||
|
val iter = iterable.iterator |
||||
|
} withReset(() => fromIterable(iterable)) |
||||
|
|
||||
|
/** Creates a Source instance from a single character. |
||||
|
*/ |
||||
|
def fromChar(c: Char): Source = fromIterable(Array(c)) |
||||
|
|
||||
|
/** creates Source from array of characters, with empty description. |
||||
|
*/ |
||||
|
def fromChars(chars: Array[Char]): Source = fromIterable(chars) |
||||
|
|
||||
|
/** creates Source from a String, with no description. |
||||
|
*/ |
||||
|
def fromString(s: String): Source = fromIterable(s) |
||||
|
|
||||
|
/** creates Source from file with given name, setting its description to |
||||
|
* filename. |
||||
|
*/ |
||||
|
def fromFile(name: String)(implicit codec: Codec): BufferedSource = |
||||
|
fromFile(new JFile(name))(codec) |
||||
|
|
||||
|
/** creates Source from file with given name, using given encoding, setting |
||||
|
* its description to filename. |
||||
|
*/ |
||||
|
def fromFile(name: String, enc: String): BufferedSource = |
||||
|
fromFile(name)(Codec(enc)) |
||||
|
|
||||
|
/** creates `source` from file with given file `URI`. |
||||
|
*/ |
||||
|
def fromFile(uri: URI)(implicit codec: Codec): BufferedSource = |
||||
|
fromFile(new JFile(uri))(codec) |
||||
|
|
||||
|
/** creates Source from file with given file: URI |
||||
|
*/ |
||||
|
def fromFile(uri: URI, enc: String): BufferedSource = |
||||
|
fromFile(uri)(Codec(enc)) |
||||
|
|
||||
|
/** creates Source from file, using default character encoding, setting its |
||||
|
* description to filename. |
||||
|
*/ |
||||
|
def fromFile(file: JFile)(implicit codec: Codec): BufferedSource = |
||||
|
fromFile(file, Source.DefaultBufSize)(codec) |
||||
|
|
||||
|
/** same as fromFile(file, enc, Source.DefaultBufSize) |
||||
|
*/ |
||||
|
def fromFile(file: JFile, enc: String): BufferedSource = |
||||
|
fromFile(file)(Codec(enc)) |
||||
|
|
||||
|
def fromFile(file: JFile, enc: String, bufferSize: Int): BufferedSource = |
||||
|
fromFile(file, bufferSize)(Codec(enc)) |
||||
|
|
||||
|
/** Creates Source from `file`, using given character encoding, setting |
||||
|
* its description to filename. Input is buffered in a buffer of size |
||||
|
* `bufferSize`. |
||||
|
*/ |
||||
|
def fromFile(file: JFile, bufferSize: Int)(implicit codec: Codec): BufferedSource = { |
||||
|
val inputStream = new FileInputStream(file) |
||||
|
|
||||
|
createBufferedSource( |
||||
|
inputStream, |
||||
|
bufferSize, |
||||
|
() => fromFile(file, bufferSize)(codec), |
||||
|
() => inputStream.close() |
||||
|
)(codec) withDescription ("file:" + file.getAbsolutePath) |
||||
|
} |
||||
|
|
||||
|
/** Create a `Source` from array of bytes, decoding |
||||
|
* the bytes according to codec. |
||||
|
* |
||||
|
* @return the created `Source` instance. |
||||
|
*/ |
||||
|
def fromBytes(bytes: Array[Byte])(implicit codec: Codec): Source = |
||||
|
fromString(new String(bytes, codec.name)) |
||||
|
|
||||
|
def fromBytes(bytes: Array[Byte], enc: String): Source = |
||||
|
fromBytes(bytes)(Codec(enc)) |
||||
|
|
||||
|
/** Create a `Source` from array of bytes, assuming |
||||
|
* one byte per character (ISO-8859-1 encoding.) |
||||
|
*/ |
||||
|
def fromRawBytes(bytes: Array[Byte]): Source = |
||||
|
fromString(new String(bytes, Codec.ISO8859.name)) |
||||
|
|
||||
|
/** creates `Source` from file with given file: URI |
||||
|
*/ |
||||
|
def fromURI(uri: URI)(implicit codec: Codec): BufferedSource = |
||||
|
fromFile(new JFile(uri))(codec) |
||||
|
|
||||
|
/** same as fromURL(new URL(s))(Codec(enc)) |
||||
|
*/ |
||||
|
def fromURL(s: String, enc: String): BufferedSource = |
||||
|
fromURL(s)(Codec(enc)) |
||||
|
|
||||
|
/** same as fromURL(new URL(s)) |
||||
|
*/ |
||||
|
def fromURL(s: String)(implicit codec: Codec): BufferedSource = |
||||
|
fromURL(new URL(s))(codec) |
||||
|
|
||||
|
/** same as fromInputStream(url.openStream())(Codec(enc)) |
||||
|
*/ |
||||
|
def fromURL(url: URL, enc: String): BufferedSource = |
||||
|
fromURL(url)(Codec(enc)) |
||||
|
|
||||
|
/** same as fromInputStream(url.openStream())(codec) |
||||
|
*/ |
||||
|
def fromURL(url: URL)(implicit codec: Codec): BufferedSource = |
||||
|
fromInputStream(url.openStream())(codec) |
||||
|
|
||||
|
/** Reads data from inputStream with a buffered reader, using the encoding |
||||
|
* in implicit parameter codec. |
||||
|
* |
||||
|
* @param inputStream the input stream from which to read |
||||
|
* @param bufferSize buffer size (defaults to Source.DefaultBufSize) |
||||
|
* @param reset a () => Source which resets the stream (if unset, reset() will throw an Exception) |
||||
|
* @param close a () => Unit method which closes the stream (if unset, close() will do nothing) |
||||
|
* @param codec (implicit) a scala.io.Codec specifying behavior (defaults to Codec.default) |
||||
|
* @return the buffered source |
||||
|
*/ |
||||
|
def createBufferedSource( |
||||
|
inputStream: InputStream, |
||||
|
bufferSize: Int = DefaultBufSize, |
||||
|
reset: () => Source = null, |
||||
|
close: () => Unit = null |
||||
|
)(implicit codec: Codec): BufferedSource = { |
||||
|
// workaround for default arguments being unable to refer to other parameters |
||||
|
val resetFn = if (reset == null) () => createBufferedSource(inputStream, bufferSize, reset, close)(codec) else reset |
||||
|
|
||||
|
new BufferedSource(inputStream, bufferSize)(codec) withReset resetFn withClose close |
||||
|
} |
||||
|
|
||||
|
def fromInputStream(is: InputStream, enc: String): BufferedSource = |
||||
|
fromInputStream(is)(Codec(enc)) |
||||
|
|
||||
|
def fromInputStream(is: InputStream)(implicit codec: Codec): BufferedSource = |
||||
|
createBufferedSource(is, reset = () => fromInputStream(is)(codec), close = () => is.close())(codec) |
||||
|
|
||||
|
/** Reads data from a classpath resource, using either a context classloader (default) or a passed one. |
||||
|
* |
||||
|
* @param resource name of the resource to load from the classpath |
||||
|
* @param classLoader classloader to be used, or context classloader if not specified |
||||
|
* @return the buffered source |
||||
|
*/ |
||||
|
def fromResource(resource: String, classLoader: ClassLoader = Thread.currentThread().getContextClassLoader())(implicit codec: Codec): BufferedSource = |
||||
|
fromInputStream(classLoader.getResourceAsStream(resource)) |
||||
|
|
||||
|
} |
||||
|
|
||||
|
/** An iterable representation of source data. |
||||
|
* It may be reset with the optional [[reset]] method. |
||||
|
* |
||||
|
* Subclasses must supply [[scala.io.Source.iter the underlying iterator]]. |
||||
|
* |
||||
|
* Error handling may be customized by overriding the [[scala.io.Source.report report]] method. |
||||
|
* |
||||
|
* The [[scala.io.Source.ch current input]] and [[scala.io.Source.pos position]], |
||||
|
* as well as the [[scala.io.Source.next next character]] methods delegate to |
||||
|
* [[scala.io.Source#Positioner the positioner]]. |
||||
|
* |
||||
|
* The default positioner encodes line and column numbers in the position passed to [[report]]. |
||||
|
* This behavior can be changed by supplying a |
||||
|
* [[scala.io.Source.withPositioning(pos:* custom positioner]]. |
||||
|
* |
||||
|
*/ |
||||
|
abstract class Source extends Iterator[Char] with Closeable { |
||||
|
/** the actual iterator */ |
||||
|
protected val iter: Iterator[Char] |
||||
|
|
||||
|
// ------ public values |
||||
|
|
||||
|
/** description of this source, default empty */ |
||||
|
var descr: String = "" |
||||
|
var nerrors = 0 |
||||
|
var nwarnings = 0 |
||||
|
|
||||
|
private def lineNum(line: Int): String = (getLines() drop (line - 1) take 1).mkString |
||||
|
|
||||
|
class LineIterator extends AbstractIterator[String] with Iterator[String] { |
||||
|
private[this] val sb = new StringBuilder |
||||
|
|
||||
|
lazy val iter: BufferedIterator[Char] = Source.this.iter.buffered |
||||
|
def isNewline(ch: Char) = ch == '\r' || ch == '\n' |
||||
|
def getc() = iter.hasNext && { |
||||
|
val ch = iter.next() |
||||
|
if (ch == '\n') false |
||||
|
else if (ch == '\r') { |
||||
|
if (iter.hasNext && iter.head == '\n') |
||||
|
iter.next() |
||||
|
|
||||
|
false |
||||
|
} |
||||
|
else { |
||||
|
sb append ch |
||||
|
true |
||||
|
} |
||||
|
} |
||||
|
def hasNext = iter.hasNext |
||||
|
def next = { |
||||
|
sb.clear() |
||||
|
while (getc()) { } |
||||
|
sb.toString |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** Returns an iterator who returns lines (NOT including newline character(s)). |
||||
|
* It will treat any of \r\n, \r, or \n as a line separator (longest match) - if |
||||
|
* you need more refined behavior you can subclass Source#LineIterator directly. |
||||
|
*/ |
||||
|
def getLines(): Iterator[String] = new LineIterator() |
||||
|
|
||||
|
/** Returns `'''true'''` if this source has more characters. |
||||
|
*/ |
||||
|
def hasNext = iter.hasNext |
||||
|
|
||||
|
/** Returns next character. |
||||
|
*/ |
||||
|
def next(): Char = positioner.next() |
||||
|
|
||||
|
class Positioner(encoder: Position) { |
||||
|
def this() = this(RelaxedPosition) |
||||
|
/** the last character returned by next. */ |
||||
|
var ch: Char = _ |
||||
|
|
||||
|
/** position of last character returned by next */ |
||||
|
var pos = 0 |
||||
|
|
||||
|
/** current line and column */ |
||||
|
var cline = 1 |
||||
|
var ccol = 1 |
||||
|
|
||||
|
/** default col increment for tabs '\t', set to 4 initially */ |
||||
|
var tabinc = 4 |
||||
|
|
||||
|
def next(): Char = { |
||||
|
ch = iter.next() |
||||
|
pos = encoder.encode(cline, ccol) |
||||
|
ch match { |
||||
|
case '\n' => |
||||
|
ccol = 1 |
||||
|
cline += 1 |
||||
|
case '\t' => |
||||
|
ccol += tabinc |
||||
|
case _ => |
||||
|
ccol += 1 |
||||
|
} |
||||
|
ch |
||||
|
} |
||||
|
} |
||||
|
/** A Position implementation which ignores errors in |
||||
|
* the positions. |
||||
|
*/ |
||||
|
object RelaxedPosition extends Position { |
||||
|
def checkInput(line: Int, column: Int): Unit = () |
||||
|
} |
||||
|
object RelaxedPositioner extends Positioner(RelaxedPosition) { } |
||||
|
object NoPositioner extends Positioner(Position) { |
||||
|
override def next(): Char = iter.next() |
||||
|
} |
||||
|
def ch = positioner.ch |
||||
|
def pos = positioner.pos |
||||
|
|
||||
|
/** Reports an error message to the output stream `out`. |
||||
|
* |
||||
|
* @param pos the source position (line/column) |
||||
|
* @param msg the error message to report |
||||
|
* @param out PrintStream to use (optional: defaults to `Console.err`) |
||||
|
*/ |
||||
|
def reportError( |
||||
|
pos: Int, |
||||
|
msg: String, |
||||
|
out: PrintStream = Console.err) |
||||
|
{ |
||||
|
nerrors += 1 |
||||
|
report(pos, msg, out) |
||||
|
} |
||||
|
|
||||
|
private def spaces(n: Int) = List.fill(n)(' ').mkString |
||||
|
/** |
||||
|
* @param pos the source position (line/column) |
||||
|
* @param msg the error message to report |
||||
|
* @param out PrintStream to use |
||||
|
*/ |
||||
|
def report(pos: Int, msg: String, out: PrintStream) { |
||||
|
val line = Position line pos |
||||
|
val col = Position column pos |
||||
|
|
||||
|
out println "%s:%d:%d: %s%s%s^".format(descr, line, col, msg, lineNum(line), spaces(col - 1)) |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @param pos the source position (line/column) |
||||
|
* @param msg the warning message to report |
||||
|
* @param out PrintStream to use (optional: defaults to `Console.out`) |
||||
|
*/ |
||||
|
def reportWarning( |
||||
|
pos: Int, |
||||
|
msg: String, |
||||
|
out: PrintStream = Console.out) |
||||
|
{ |
||||
|
nwarnings += 1 |
||||
|
report(pos, "warning! " + msg, out) |
||||
|
} |
||||
|
|
||||
|
private[this] var resetFunction: () => Source = null |
||||
|
private[this] var closeFunction: () => Unit = null |
||||
|
private[this] var positioner: Positioner = RelaxedPositioner |
||||
|
|
||||
|
def withReset(f: () => Source): this.type = { |
||||
|
resetFunction = f |
||||
|
this |
||||
|
} |
||||
|
def withClose(f: () => Unit): this.type = { |
||||
|
closeFunction = f |
||||
|
this |
||||
|
} |
||||
|
def withDescription(text: String): this.type = { |
||||
|
descr = text |
||||
|
this |
||||
|
} |
||||
|
/** Change or disable the positioner. */ |
||||
|
def withPositioning(on: Boolean): this.type = { |
||||
|
positioner = if (on) RelaxedPositioner else NoPositioner |
||||
|
this |
||||
|
} |
||||
|
def withPositioning(pos: Positioner): this.type = { |
||||
|
positioner = pos |
||||
|
this |
||||
|
} |
||||
|
|
||||
|
/** The close() method closes the underlying resource. */ |
||||
|
def close() { |
||||
|
if (closeFunction != null) closeFunction() |
||||
|
} |
||||
|
|
||||
|
/** The reset() method creates a fresh copy of this Source. */ |
||||
|
def reset(): Source = |
||||
|
if (resetFunction != null) resetFunction() |
||||
|
else throw new UnsupportedOperationException("Source's reset() method was not set.") |
||||
|
} |
@ -0,0 +1,98 @@ |
|||||
|
/* |
||||
|
* Scala (https://www.scala-lang.org) |
||||
|
* |
||||
|
* Copyright EPFL and Lightbend, Inc. |
||||
|
* |
||||
|
* Licensed under Apache License 2.0 |
||||
|
* (http://www.apache.org/licenses/LICENSE-2.0). |
||||
|
* |
||||
|
* See the NOTICE file distributed with this work for |
||||
|
* additional information regarding copyright ownership. |
||||
|
*/ |
||||
|
|
||||
|
package scala |
||||
|
package util.control |
||||
|
|
||||
|
/** A class that can be instantiated for the break control abstraction. |
||||
|
* Example usage: |
||||
|
* {{{ |
||||
|
* val mybreaks = new Breaks |
||||
|
* import mybreaks.{break, breakable} |
||||
|
* |
||||
|
* breakable { |
||||
|
* for (...) { |
||||
|
* if (...) break() |
||||
|
* } |
||||
|
* } |
||||
|
* }}} |
||||
|
* Calls to break from one instantiation of `Breaks` will never |
||||
|
* target breakable objects of some other instantiation. |
||||
|
*/ |
||||
|
class Breaks { |
||||
|
|
||||
|
private val breakException = new BreakControl |
||||
|
|
||||
|
/** |
||||
|
* A block from which one can exit with a `break`. The `break` may be |
||||
|
* executed further down in the call stack provided that it is called on the |
||||
|
* exact same instance of `Breaks`. |
||||
|
*/ |
||||
|
def breakable(op: => Unit) { |
||||
|
try { |
||||
|
op |
||||
|
} catch { |
||||
|
case ex: BreakControl => |
||||
|
if (ex ne breakException) throw ex |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
sealed trait TryBlock[T] { |
||||
|
def catchBreak(onBreak: =>T): T |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* This variant enables the execution of a code block in case of a `break()`: |
||||
|
* {{{ |
||||
|
* tryBreakable { |
||||
|
* for (...) { |
||||
|
* if (...) break() |
||||
|
* } |
||||
|
* } catchBreak { |
||||
|
* doCleanup() |
||||
|
* } |
||||
|
* }}} |
||||
|
*/ |
||||
|
def tryBreakable[T](op: =>T) = new TryBlock[T] { |
||||
|
def catchBreak(onBreak: =>T) = try { |
||||
|
op |
||||
|
} catch { |
||||
|
case ex: BreakControl => |
||||
|
if (ex ne breakException) throw ex |
||||
|
onBreak |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Break from dynamically closest enclosing breakable block using this exact |
||||
|
* `Breaks` instance. |
||||
|
* |
||||
|
* @note This might be different than the statically closest enclosing block! |
||||
|
*/ |
||||
|
def break(): Nothing = { throw breakException } |
||||
|
} |
||||
|
|
||||
|
/** An object that can be used for the break control abstraction. |
||||
|
* Example usage: |
||||
|
* {{{ |
||||
|
* import Breaks.{break, breakable} |
||||
|
* |
||||
|
* breakable { |
||||
|
* for (...) { |
||||
|
* if (...) break |
||||
|
* } |
||||
|
* } |
||||
|
* }}} |
||||
|
*/ |
||||
|
object Breaks extends Breaks |
||||
|
|
||||
|
private class BreakControl extends ControlThrowable |
@ -0,0 +1,7 @@ |
|||||
|
{ |
||||
|
// Use IntelliSense to learn about possible attributes. |
||||
|
// Hover to view descriptions of existing attributes. |
||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 |
||||
|
"version": "0.2.0", |
||||
|
"configurations": [] |
||||
|
} |
@ -0,0 +1,5 @@ |
|||||
|
{ |
||||
|
"files.watcherExclude": { |
||||
|
"**/target": true |
||||
|
} |
||||
|
} |
@ -0,0 +1,16 @@ |
|||||
|
{ |
||||
|
"semanticDBVersion": "4.4.0", |
||||
|
"supportedScalaVersions": [ |
||||
|
"2.13.4", |
||||
|
"2.12.12", |
||||
|
"2.12.11", |
||||
|
"2.12.10", |
||||
|
"2.13.2", |
||||
|
"2.13.3", |
||||
|
"2.11.12", |
||||
|
"2.12.8", |
||||
|
"2.12.9", |
||||
|
"2.13.0", |
||||
|
"2.13.1" |
||||
|
] |
||||
|
} |
Binary file not shown.
Binary file not shown.
@ -0,0 +1,167 @@ |
|||||
|
{ |
||||
|
"version": "1.4.0", |
||||
|
"project": { |
||||
|
"name": "root-09-test", |
||||
|
"directory": "/Users/hrbrmstr/Development/2020-code-advent/scala/09/09", |
||||
|
"workspaceDir": "/Users/hrbrmstr/Development/2020-code-advent/scala/09/09", |
||||
|
"sources": [ |
||||
|
"/Users/hrbrmstr/Development/2020-code-advent/scala/09/09/src/test/scala", |
||||
|
"/Users/hrbrmstr/Development/2020-code-advent/scala/09/09/src/test/scala-2.13", |
||||
|
"/Users/hrbrmstr/Development/2020-code-advent/scala/09/09/src/test/scala-2", |
||||
|
"/Users/hrbrmstr/Development/2020-code-advent/scala/09/09/src/test/java", |
||||
|
"/Users/hrbrmstr/Development/2020-code-advent/scala/09/09/target/scala-2.13/src_managed/test" |
||||
|
], |
||||
|
"dependencies": [ |
||||
|
"root-09" |
||||
|
], |
||||
|
"classpath": [ |
||||
|
"/Users/hrbrmstr/Development/2020-code-advent/scala/09/09/.bloop/root-09/scala-2.13/classes", |
||||
|
"/Users/hrbrmstr/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala-library/2.13.3/scala-library-2.13.3.jar", |
||||
|
"/Users/hrbrmstr/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/modules/scala-parser-combinators_2.13/1.1.2/scala-parser-combinators_2.13-1.1.2.jar" |
||||
|
], |
||||
|
"out": "/Users/hrbrmstr/Development/2020-code-advent/scala/09/09/.bloop/root-09", |
||||
|
"classesDir": "/Users/hrbrmstr/Development/2020-code-advent/scala/09/09/.bloop/root-09/scala-2.13/test-classes", |
||||
|
"resources": [ |
||||
|
"/Users/hrbrmstr/Development/2020-code-advent/scala/09/09/src/test/resources", |
||||
|
"/Users/hrbrmstr/Development/2020-code-advent/scala/09/09/target/scala-2.13/resource_managed/test" |
||||
|
], |
||||
|
"scala": { |
||||
|
"organization": "org.scala-lang", |
||||
|
"name": "scala-compiler", |
||||
|
"version": "2.13.3", |
||||
|
"options": [ |
||||
|
|
||||
|
], |
||||
|
"jars": [ |
||||
|
"/Users/hrbrmstr/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala-compiler/2.13.3/scala-compiler-2.13.3.jar", |
||||
|
"/Users/hrbrmstr/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala-library/2.13.3/scala-library-2.13.3.jar", |
||||
|
"/Users/hrbrmstr/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala-reflect/2.13.3/scala-reflect-2.13.3.jar", |
||||
|
"/Users/hrbrmstr/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/org/jline/jline/3.15.0/jline-3.15.0.jar", |
||||
|
"/Users/hrbrmstr/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/net/java/dev/jna/jna/5.3.1/jna-5.3.1.jar" |
||||
|
], |
||||
|
"analysis": "/Users/hrbrmstr/Development/2020-code-advent/scala/09/09/target/streams/test/bloopAnalysisOut/_global/streams/inc_compile_2.13.zip", |
||||
|
"setup": { |
||||
|
"order": "mixed", |
||||
|
"addLibraryToBootClasspath": true, |
||||
|
"addCompilerToClasspath": false, |
||||
|
"addExtraJarsToClasspath": false, |
||||
|
"manageBootClasspath": true, |
||||
|
"filterLibraryFromClasspath": true |
||||
|
} |
||||
|
}, |
||||
|
"java": { |
||||
|
"options": [ |
||||
|
|
||||
|
] |
||||
|
}, |
||||
|
"test": { |
||||
|
"frameworks": [ |
||||
|
{ |
||||
|
"names": [ |
||||
|
"org.scalacheck.ScalaCheckFramework" |
||||
|
] |
||||
|
}, |
||||
|
{ |
||||
|
"names": [ |
||||
|
"org.specs2.runner.Specs2Framework", |
||||
|
"org.specs2.runner.SpecsFramework" |
||||
|
] |
||||
|
}, |
||||
|
{ |
||||
|
"names": [ |
||||
|
"org.specs.runner.SpecsFramework" |
||||
|
] |
||||
|
}, |
||||
|
{ |
||||
|
"names": [ |
||||
|
"org.scalatest.tools.Framework", |
||||
|
"org.scalatest.tools.ScalaTestFramework" |
||||
|
] |
||||
|
}, |
||||
|
{ |
||||
|
"names": [ |
||||
|
"com.novocode.junit.JUnitFramework" |
||||
|
] |
||||
|
} |
||||
|
], |
||||
|
"options": { |
||||
|
"excludes": [ |
||||
|
|
||||
|
], |
||||
|
"arguments": [ |
||||
|
|
||||
|
] |
||||
|
} |
||||
|
}, |
||||
|
"platform": { |
||||
|
"name": "jvm", |
||||
|
"config": { |
||||
|
"home": "/Library/Java/JavaVirtualMachines/openjdk-11.0.2.jdk/Contents/Home", |
||||
|
"options": [ |
||||
|
"-Duser.dir=/Users/hrbrmstr/Development/2020-code-advent/scala/09/09" |
||||
|
] |
||||
|
}, |
||||
|
"mainClass": [ |
||||
|
|
||||
|
] |
||||
|
}, |
||||
|
"resolution": { |
||||
|
"modules": [ |
||||
|
{ |
||||
|
"organization": "org.scala-lang", |
||||
|
"name": "scala-library", |
||||
|
"version": "2.13.3", |
||||
|
"configurations": "default", |
||||
|
"artifacts": [ |
||||
|
{ |
||||
|
"name": "scala-library", |
||||
|
"path": "/Users/hrbrmstr/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala-library/2.13.3/scala-library-2.13.3.jar" |
||||
|
}, |
||||
|
{ |
||||
|
"name": "scala-library", |
||||
|
"classifier": "sources", |
||||
|
"path": "/Users/hrbrmstr/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala-library/2.13.3/scala-library-2.13.3-sources.jar" |
||||
|
} |
||||
|
] |
||||
|
}, |
||||
|
{ |
||||
|
"organization": "org.scala-lang.modules", |
||||
|
"name": "scala-parser-combinators_2.13", |
||||
|
"version": "1.1.2", |
||||
|
"configurations": "default", |
||||
|
"artifacts": [ |
||||
|
{ |
||||
|
"name": "scala-parser-combinators_2.13", |
||||
|
"path": "/Users/hrbrmstr/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/modules/scala-parser-combinators_2.13/1.1.2/scala-parser-combinators_2.13-1.1.2.jar" |
||||
|
}, |
||||
|
{ |
||||
|
"name": "scala-parser-combinators_2.13", |
||||
|
"classifier": "sources", |
||||
|
"path": "/Users/hrbrmstr/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/modules/scala-parser-combinators_2.13/1.1.2/scala-parser-combinators_2.13-1.1.2-sources.jar" |
||||
|
} |
||||
|
] |
||||
|
}, |
||||
|
{ |
||||
|
"organization": "org.scala-lang", |
||||
|
"name": "scala-library", |
||||
|
"version": "2.13.3", |
||||
|
"configurations": "optional", |
||||
|
"artifacts": [ |
||||
|
{ |
||||
|
"name": "scala-library", |
||||
|
"path": "/Users/hrbrmstr/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala-library/2.13.3/scala-library-2.13.3.jar" |
||||
|
}, |
||||
|
{ |
||||
|
"name": "scala-library", |
||||
|
"classifier": "sources", |
||||
|
"path": "/Users/hrbrmstr/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala-library/2.13.3/scala-library-2.13.3-sources.jar" |
||||
|
} |
||||
|
] |
||||
|
} |
||||
|
] |
||||
|
}, |
||||
|
"tags": [ |
||||
|
"test" |
||||
|
] |
||||
|
} |
||||
|
} |
@ -0,0 +1,166 @@ |
|||||
|
{ |
||||
|
"version": "1.4.0", |
||||
|
"project": { |
||||
|
"name": "root-09", |
||||
|
"directory": "/Users/hrbrmstr/Development/2020-code-advent/scala/09/09", |
||||
|
"workspaceDir": "/Users/hrbrmstr/Development/2020-code-advent/scala/09/09", |
||||
|
"sources": [ |
||||
|
"/Users/hrbrmstr/Development/2020-code-advent/scala/09/09/src/main/scala", |
||||
|
"/Users/hrbrmstr/Development/2020-code-advent/scala/09/09/src/main/scala-2.13", |
||||
|
"/Users/hrbrmstr/Development/2020-code-advent/scala/09/09/src/main/scala-2", |
||||
|
"/Users/hrbrmstr/Development/2020-code-advent/scala/09/09/src/main/java", |
||||
|
"/Users/hrbrmstr/Development/2020-code-advent/scala/09/09/target/scala-2.13/src_managed/main" |
||||
|
], |
||||
|
"dependencies": [ |
||||
|
|
||||
|
], |
||||
|
"classpath": [ |
||||
|
"/Users/hrbrmstr/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala-library/2.13.3/scala-library-2.13.3.jar", |
||||
|
"/Users/hrbrmstr/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/modules/scala-parser-combinators_2.13/1.1.2/scala-parser-combinators_2.13-1.1.2.jar" |
||||
|
], |
||||
|
"out": "/Users/hrbrmstr/Development/2020-code-advent/scala/09/09/.bloop/root-09", |
||||
|
"classesDir": "/Users/hrbrmstr/Development/2020-code-advent/scala/09/09/.bloop/root-09/scala-2.13/classes", |
||||
|
"resources": [ |
||||
|
"/Users/hrbrmstr/Development/2020-code-advent/scala/09/09/src/main/resources", |
||||
|
"/Users/hrbrmstr/Development/2020-code-advent/scala/09/09/target/scala-2.13/resource_managed/main" |
||||
|
], |
||||
|
"scala": { |
||||
|
"organization": "org.scala-lang", |
||||
|
"name": "scala-compiler", |
||||
|
"version": "2.13.3", |
||||
|
"options": [ |
||||
|
|
||||
|
], |
||||
|
"jars": [ |
||||
|
"/Users/hrbrmstr/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala-compiler/2.13.3/scala-compiler-2.13.3.jar", |
||||
|
"/Users/hrbrmstr/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala-library/2.13.3/scala-library-2.13.3.jar", |
||||
|
"/Users/hrbrmstr/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala-reflect/2.13.3/scala-reflect-2.13.3.jar", |
||||
|
"/Users/hrbrmstr/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/org/jline/jline/3.15.0/jline-3.15.0.jar", |
||||
|
"/Users/hrbrmstr/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/net/java/dev/jna/jna/5.3.1/jna-5.3.1.jar" |
||||
|
], |
||||
|
"analysis": "/Users/hrbrmstr/Development/2020-code-advent/scala/09/09/target/streams/compile/bloopAnalysisOut/_global/streams/inc_compile_2.13.zip", |
||||
|
"setup": { |
||||
|
"order": "mixed", |
||||
|
"addLibraryToBootClasspath": true, |
||||
|
"addCompilerToClasspath": false, |
||||
|
"addExtraJarsToClasspath": false, |
||||
|
"manageBootClasspath": true, |
||||
|
"filterLibraryFromClasspath": true |
||||
|
} |
||||
|
}, |
||||
|
"java": { |
||||
|
"options": [ |
||||
|
|
||||
|
] |
||||
|
}, |
||||
|
"test": { |
||||
|
"frameworks": [ |
||||
|
{ |
||||
|
"names": [ |
||||
|
"org.scalacheck.ScalaCheckFramework" |
||||
|
] |
||||
|
}, |
||||
|
{ |
||||
|
"names": [ |
||||
|
"org.specs2.runner.Specs2Framework", |
||||
|
"org.specs2.runner.SpecsFramework" |
||||
|
] |
||||
|
}, |
||||
|
{ |
||||
|
"names": [ |
||||
|
"org.specs.runner.SpecsFramework" |
||||
|
] |
||||
|
}, |
||||
|
{ |
||||
|
"names": [ |
||||
|
"org.scalatest.tools.Framework", |
||||
|
"org.scalatest.tools.ScalaTestFramework" |
||||
|
] |
||||
|
}, |
||||
|
{ |
||||
|
"names": [ |
||||
|
"com.novocode.junit.JUnitFramework" |
||||
|
] |
||||
|
} |
||||
|
], |
||||
|
"options": { |
||||
|
"excludes": [ |
||||
|
|
||||
|
], |
||||
|
"arguments": [ |
||||
|
|
||||
|
] |
||||
|
} |
||||
|
}, |
||||
|
"platform": { |
||||
|
"name": "jvm", |
||||
|
"config": { |
||||
|
"home": "/Library/Java/JavaVirtualMachines/openjdk-11.0.2.jdk/Contents/Home", |
||||
|
"options": [ |
||||
|
"-Duser.dir=/Users/hrbrmstr/Development/2020-code-advent/scala/09/09" |
||||
|
] |
||||
|
}, |
||||
|
"mainClass": [ |
||||
|
|
||||
|
] |
||||
|
}, |
||||
|
"resolution": { |
||||
|
"modules": [ |
||||
|
{ |
||||
|
"organization": "org.scala-lang", |
||||
|
"name": "scala-library", |
||||
|
"version": "2.13.3", |
||||
|
"configurations": "default", |
||||
|
"artifacts": [ |
||||
|
{ |
||||
|
"name": "scala-library", |
||||
|
"path": "/Users/hrbrmstr/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala-library/2.13.3/scala-library-2.13.3.jar" |
||||
|
}, |
||||
|
{ |
||||
|
"name": "scala-library", |
||||
|
"classifier": "sources", |
||||
|
"path": "/Users/hrbrmstr/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala-library/2.13.3/scala-library-2.13.3-sources.jar" |
||||
|
} |
||||
|
] |
||||
|
}, |
||||
|
{ |
||||
|
"organization": "org.scala-lang.modules", |
||||
|
"name": "scala-parser-combinators_2.13", |
||||
|
"version": "1.1.2", |
||||
|
"configurations": "default", |
||||
|
"artifacts": [ |
||||
|
{ |
||||
|
"name": "scala-parser-combinators_2.13", |
||||
|
"path": "/Users/hrbrmstr/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/modules/scala-parser-combinators_2.13/1.1.2/scala-parser-combinators_2.13-1.1.2.jar" |
||||
|
}, |
||||
|
{ |
||||
|
"name": "scala-parser-combinators_2.13", |
||||
|
"classifier": "sources", |
||||
|
"path": "/Users/hrbrmstr/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/modules/scala-parser-combinators_2.13/1.1.2/scala-parser-combinators_2.13-1.1.2-sources.jar" |
||||
|
} |
||||
|
] |
||||
|
}, |
||||
|
{ |
||||
|
"organization": "org.scala-lang", |
||||
|
"name": "scala-library", |
||||
|
"version": "2.13.3", |
||||
|
"configurations": "optional", |
||||
|
"artifacts": [ |
||||
|
{ |
||||
|
"name": "scala-library", |
||||
|
"path": "/Users/hrbrmstr/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala-library/2.13.3/scala-library-2.13.3.jar" |
||||
|
}, |
||||
|
{ |
||||
|
"name": "scala-library", |
||||
|
"classifier": "sources", |
||||
|
"path": "/Users/hrbrmstr/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala-library/2.13.3/scala-library-2.13.3-sources.jar" |
||||
|
} |
||||
|
] |
||||
|
} |
||||
|
] |
||||
|
}, |
||||
|
"tags": [ |
||||
|
"library" |
||||
|
] |
||||
|
} |
||||
|
} |
Binary file not shown.
Binary file not shown.
@ -0,0 +1 @@ |
|||||
|
{"name":"sbt","version":"1.4.3","bspVersion":"2.0.0-M5","languages":["scala"],"argv":["/Library/Java/JavaVirtualMachines/openjdk-11.0.2.jdk/Contents/Home/bin/java","-Xms100m","-Xmx100m","-classpath","/Users/hrbrmstr/Library/Application Support/Coursier/bin/sbt:/Users/hrbrmstr/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/io/get-coursier/sbt/sbt-runner/0.2.0/sbt-runner-0.2.0.jar:/Users/hrbrmstr/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/org/scala-sbt/sbt-launch/1.4.0-M1/sbt-launch-1.4.0-M1.jar","xsbt.boot.Boot","-bsp"]} |
Binary file not shown.
@ -0,0 +1,6 @@ |
|||||
|
#FileLock |
||||
|
#Wed Dec 09 20:03:31 EST 2020 |
||||
|
server=localhost\:54387 |
||||
|
hostName=localhost |
||||
|
method=file |
||||
|
id=1764a2caf2598470263a82b27841a578d29b6951659 |
@ -0,0 +1,79 @@ |
|||||
|
/* |
||||
|
* Scala (https://www.scala-lang.org) |
||||
|
* |
||||
|
* Copyright EPFL and Lightbend, Inc. |
||||
|
* |
||||
|
* Licensed under Apache License 2.0 |
||||
|
* (http://www.apache.org/licenses/LICENSE-2.0). |
||||
|
* |
||||
|
* See the NOTICE file distributed with this work for |
||||
|
* additional information regarding copyright ownership. |
||||
|
*/ |
||||
|
|
||||
|
package scala |
||||
|
|
||||
|
import java.lang.System.{currentTimeMillis => currentTime} |
||||
|
import scala.collection.mutable.ListBuffer |
||||
|
|
||||
|
/** The `App` trait can be used to quickly turn objects |
||||
|
* into executable programs. Here is an example: |
||||
|
* {{{ |
||||
|
* object Main extends App { |
||||
|
* Console.println("Hello World: " + (args mkString ", ")) |
||||
|
* } |
||||
|
* }}} |
||||
|
* |
||||
|
* No explicit `main` method is needed. Instead, |
||||
|
* the whole class body becomes the “main method”. |
||||
|
* |
||||
|
* `args` returns the current command line arguments as an array. |
||||
|
* |
||||
|
* ==Caveats== |
||||
|
* |
||||
|
* '''''It should be noted that this trait is implemented using the [[DelayedInit]] |
||||
|
* functionality, which means that fields of the object will not have been initialized |
||||
|
* before the main method has been executed.''''' |
||||
|
* |
||||
|
* Future versions of this trait will no longer extend `DelayedInit`. |
||||
|
*/ |
||||
|
trait App extends DelayedInit { |
||||
|
|
||||
|
/** The time when the execution of this program started, in milliseconds since 1 |
||||
|
* January 1970 UTC. */ |
||||
|
final val executionStart: Long = currentTime |
||||
|
|
||||
|
/** The command line arguments passed to the application's `main` method. |
||||
|
*/ |
||||
|
protected final def args: Array[String] = _args |
||||
|
|
||||
|
private[this] var _args: Array[String] = _ |
||||
|
|
||||
|
private[this] val initCode = new ListBuffer[() => Unit] |
||||
|
|
||||
|
/** The init hook. This saves all initialization code for execution within `main`. |
||||
|
* This method is normally never called directly from user code. |
||||
|
* Instead it is called as compiler-generated code for those classes and objects |
||||
|
* (but not traits) that inherit from the `DelayedInit` trait and that do not |
||||
|
* themselves define a `delayedInit` method. |
||||
|
* @param body the initialization code to be stored for later execution |
||||
|
*/ |
||||
|
@deprecated("the delayedInit mechanism will disappear", "2.11.0") |
||||
|
override def delayedInit(body: => Unit): Unit = { |
||||
|
initCode += (() => body) |
||||
|
} |
||||
|
|
||||
|
/** The main method. |
||||
|
* This stores all arguments so that they can be retrieved with `args` |
||||
|
* and then executes all initialization code segments in the order in which |
||||
|
* they were passed to `delayedInit`. |
||||
|
* @param args the arguments passed to the main method |
||||
|
*/ |
||||
|
final def main(args: Array[String]) = { |
||||
|
this._args = args |
||||
|
for (proc <- initCode) proc() |
||||
|
if (util.Properties.propIsSet("scala.time")) { |
||||
|
val total = currentTime - executionStart |
||||
|
Console.println("[total " + total + "ms]") |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,659 @@ |
|||||
|
/* |
||||
|
* Scala (https://www.scala-lang.org) |
||||
|
* |
||||
|
* Copyright EPFL and Lightbend, Inc. |
||||
|
* |
||||
|
* Licensed under Apache License 2.0 |
||||
|
* (http://www.apache.org/licenses/LICENSE-2.0). |
||||
|
* |
||||
|
* See the NOTICE file distributed with this work for |
||||
|
* additional information regarding copyright ownership. |
||||
|
*/ |
||||
|
|
||||
|
package scala |
||||
|
|
||||
|
//import scala.collection.generic._ |
||||
|
import scala.collection.{Factory, immutable, mutable} |
||||
|
import mutable.ArrayBuilder |
||||
|
import immutable.ArraySeq |
||||
|
import scala.language.implicitConversions |
||||
|
import scala.reflect.ClassTag |
||||
|
import scala.runtime.BoxedUnit |
||||
|
import scala.runtime.ScalaRunTime.{array_apply, array_update} |
||||
|
|
||||
|
/** Utility methods for operating on arrays. |
||||
|
* For example: |
||||
|
* {{{ |
||||
|
* val a = Array(1, 2) |
||||
|
* val b = Array.ofDim[Int](2) |
||||
|
* val c = Array.concat(a, b) |
||||
|
* }}} |
||||
|
* where the array objects `a`, `b` and `c` have respectively the values |
||||
|
* `Array(1, 2)`, `Array(0, 0)` and `Array(1, 2, 0, 0)`. |
||||
|
*/ |
||||
|
object Array { |
||||
|
val emptyBooleanArray = new Array[Boolean](0) |
||||
|
val emptyByteArray = new Array[Byte](0) |
||||
|
val emptyCharArray = new Array[Char](0) |
||||
|
val emptyDoubleArray = new Array[Double](0) |
||||
|
val emptyFloatArray = new Array[Float](0) |
||||
|
val emptyIntArray = new Array[Int](0) |
||||
|
val emptyLongArray = new Array[Long](0) |
||||
|
val emptyShortArray = new Array[Short](0) |
||||
|
val emptyObjectArray = new Array[Object](0) |
||||
|
|
||||
|
/** Provides an implicit conversion from the Array object to a collection Factory */ |
||||
|
implicit def toFactory[A : ClassTag](dummy: Array.type): Factory[A, Array[A]] = new ArrayFactory(dummy) |
||||
|
@SerialVersionUID(3L) |
||||
|
private class ArrayFactory[A : ClassTag](dummy: Array.type) extends Factory[A, Array[A]] with Serializable { |
||||
|
def fromSpecific(it: IterableOnce[A]): Array[A] = Array.from[A](it) |
||||
|
def newBuilder: mutable.Builder[A, Array[A]] = Array.newBuilder[A] |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Returns a new [[scala.collection.mutable.ArrayBuilder]]. |
||||
|
*/ |
||||
|
def newBuilder[T](implicit t: ClassTag[T]): ArrayBuilder[T] = ArrayBuilder.make[T](t) |
||||
|
|
||||
|
def from[A : ClassTag](it: IterableOnce[A]): Array[A] = it match { |
||||
|
case it: Iterable[A] => it.toArray[A] |
||||
|
case _ => it.iterator.toArray[A] |
||||
|
} |
||||
|
|
||||
|
private def slowcopy(src : AnyRef, |
||||
|
srcPos : Int, |
||||
|
dest : AnyRef, |
||||
|
destPos : Int, |
||||
|
length : Int): Unit = { |
||||
|
var i = srcPos |
||||
|
var j = destPos |
||||
|
val srcUntil = srcPos + length |
||||
|
while (i < srcUntil) { |
||||
|
array_update(dest, j, array_apply(src, i)) |
||||
|
i += 1 |
||||
|
j += 1 |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** Copy one array to another. |
||||
|
* Equivalent to Java's |
||||
|
* `System.arraycopy(src, srcPos, dest, destPos, length)`, |
||||
|
* except that this also works for polymorphic and boxed arrays. |
||||
|
* |
||||
|
* Note that the passed-in `dest` array will be modified by this call. |
||||
|
* |
||||
|
* @param src the source array. |
||||
|
* @param srcPos starting position in the source array. |
||||
|
* @param dest destination array. |
||||
|
* @param destPos starting position in the destination array. |
||||
|
* @param length the number of array elements to be copied. |
||||
|
* |
||||
|
* @see `java.lang.System#arraycopy` |
||||
|
*/ |
||||
|
def copy(src: AnyRef, srcPos: Int, dest: AnyRef, destPos: Int, length: Int): Unit = { |
||||
|
val srcClass = src.getClass |
||||
|
if (srcClass.isArray && dest.getClass.isAssignableFrom(srcClass)) |
||||
|
java.lang.System.arraycopy(src, srcPos, dest, destPos, length) |
||||
|
else |
||||
|
slowcopy(src, srcPos, dest, destPos, length) |
||||
|
} |
||||
|
|
||||
|
/** Copy one array to another, truncating or padding with default values (if |
||||
|
* necessary) so the copy has the specified length. |
||||
|
* |
||||
|
* Equivalent to Java's |
||||
|
* `java.util.Arrays.copyOf(original, newLength)`, |
||||
|
* except that this works for primitive and object arrays in a single method. |
||||
|
* |
||||
|
* @see `java.util.Arrays#copyOf` |
||||
|
*/ |
||||
|
def copyOf[A](original: Array[A], newLength: Int): Array[A] = (original match { |
||||
|
case x: Array[BoxedUnit] => newUnitArray(newLength).asInstanceOf[Array[A]] |
||||
|
case x: Array[AnyRef] => java.util.Arrays.copyOf(x, newLength) |
||||
|
case x: Array[Int] => java.util.Arrays.copyOf(x, newLength) |
||||
|
case x: Array[Double] => java.util.Arrays.copyOf(x, newLength) |
||||
|
case x: Array[Long] => java.util.Arrays.copyOf(x, newLength) |
||||
|
case x: Array[Float] => java.util.Arrays.copyOf(x, newLength) |
||||
|
case x: Array[Char] => java.util.Arrays.copyOf(x, newLength) |
||||
|
case x: Array[Byte] => java.util.Arrays.copyOf(x, newLength) |
||||
|
case x: Array[Short] => java.util.Arrays.copyOf(x, newLength) |
||||
|
case x: Array[Boolean] => java.util.Arrays.copyOf(x, newLength) |
||||
|
}).asInstanceOf[Array[A]] |
||||
|
|
||||
|
/** Copy one array to another, truncating or padding with default values (if |
||||
|
* necessary) so the copy has the specified length. The new array can have |
||||
|
* a different type than the original one as long as the values are |
||||
|
* assignment-compatible. When copying between primitive and object arrays, |
||||
|
* boxing and unboxing are supported. |
||||
|
* |
||||
|
* Equivalent to Java's |
||||
|
* `java.util.Arrays.copyOf(original, newLength, newType)`, |
||||
|
* except that this works for all combinations of primitive and object arrays |
||||
|
* in a single method. |
||||
|
* |
||||
|
* @see `java.util.Arrays#copyOf` |
||||
|
*/ |
||||
|
def copyAs[A](original: Array[_], newLength: Int)(implicit ct: ClassTag[A]): Array[A] = { |
||||
|
val runtimeClass = ct.runtimeClass |
||||
|
if (runtimeClass == Void.TYPE) newUnitArray(newLength).asInstanceOf[Array[A]] |
||||
|
else { |
||||
|
val destClass = runtimeClass.asInstanceOf[Class[A]] |
||||
|
if (destClass.isAssignableFrom(original.getClass.getComponentType)) { |
||||
|
if (destClass.isPrimitive) copyOf[A](original.asInstanceOf[Array[A]], newLength) |
||||
|
else { |
||||
|
val destArrayClass = java.lang.reflect.Array.newInstance(destClass, 0).getClass.asInstanceOf[Class[Array[AnyRef]]] |
||||
|
java.util.Arrays.copyOf(original.asInstanceOf[Array[AnyRef]], newLength, destArrayClass).asInstanceOf[Array[A]] |
||||
|
} |
||||
|
} else { |
||||
|
val dest = new Array[A](newLength) |
||||
|
Array.copy(original, 0, dest, 0, original.length) |
||||
|
dest |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private def newUnitArray(len: Int): Array[Unit] = { |
||||
|
val result = new Array[Unit](len) |
||||
|
java.util.Arrays.fill(result.asInstanceOf[Array[AnyRef]], ()) |
||||
|
result |
||||
|
} |
||||
|
|
||||
|
/** Returns an array of length 0 */ |
||||
|
def empty[T: ClassTag]: Array[T] = new Array[T](0) |
||||
|
|
||||
|
/** Creates an array with given elements. |
||||
|
* |
||||
|
* @param xs the elements to put in the array |
||||
|
* @return an array containing all elements from xs. |
||||
|
*/ |
||||
|
// Subject to a compiler optimization in Cleanup. |
||||
|
// Array(e0, ..., en) is translated to { val a = new Array(3); a(i) = ei; a } |
||||
|
def apply[T: ClassTag](xs: T*): Array[T] = { |
||||
|
val array = new Array[T](xs.length) |
||||
|
val iterator = xs.iterator |
||||
|
var i = 0 |
||||
|
while (iterator.hasNext) { |
||||
|
array(i) = iterator.next(); i += 1 |
||||
|
} |
||||
|
array |
||||
|
} |
||||
|
|
||||
|
/** Creates an array of `Boolean` objects */ |
||||
|
// Subject to a compiler optimization in Cleanup, see above. |
||||
|
def apply(x: Boolean, xs: Boolean*): Array[Boolean] = { |
||||
|
val array = new Array[Boolean](xs.length + 1) |
||||
|
array(0) = x |
||||
|
val iterator = xs.iterator |
||||
|
var i = 1 |
||||
|
while (iterator.hasNext) { |
||||
|
array(i) = iterator.next(); i += 1 |
||||
|
} |
||||
|
array |
||||
|
} |
||||
|
|
||||
|
/** Creates an array of `Byte` objects */ |
||||
|
// Subject to a compiler optimization in Cleanup, see above. |
||||
|
def apply(x: Byte, xs: Byte*): Array[Byte] = { |
||||
|
val array = new Array[Byte](xs.length + 1) |
||||
|
array(0) = x |
||||
|
val iterator = xs.iterator |
||||
|
var i = 1 |
||||
|
while (iterator.hasNext) { |
||||
|
array(i) = iterator.next(); i += 1 |
||||
|
} |
||||
|
array |
||||
|
} |
||||
|
|
||||
|
/** Creates an array of `Short` objects */ |
||||
|
// Subject to a compiler optimization in Cleanup, see above. |
||||
|
def apply(x: Short, xs: Short*): Array[Short] = { |
||||
|
val array = new Array[Short](xs.length + 1) |
||||
|
array(0) = x |
||||
|
val iterator = xs.iterator |
||||
|
var i = 1 |
||||
|
while (iterator.hasNext) { |
||||
|
array(i) = iterator.next(); i += 1 |
||||
|
} |
||||
|
array |
||||
|
} |
||||
|
|
||||
|
/** Creates an array of `Char` objects */ |
||||
|
// Subject to a compiler optimization in Cleanup, see above. |
||||
|
def apply(x: Char, xs: Char*): Array[Char] = { |
||||
|
val array = new Array[Char](xs.length + 1) |
||||
|
array(0) = x |
||||
|
val iterator = xs.iterator |
||||
|
var i = 1 |
||||
|
while (iterator.hasNext) { |
||||
|
array(i) = iterator.next(); i += 1 |
||||
|
} |
||||
|
array |
||||
|
} |
||||
|
|
||||
|
/** Creates an array of `Int` objects */ |
||||
|
// Subject to a compiler optimization in Cleanup, see above. |
||||
|
def apply(x: Int, xs: Int*): Array[Int] = { |
||||
|
val array = new Array[Int](xs.length + 1) |
||||
|
array(0) = x |
||||
|
val iterator = xs.iterator |
||||
|
var i = 1 |
||||
|
while (iterator.hasNext) { |
||||
|
array(i) = iterator.next(); i += 1 |
||||
|
} |
||||
|
array |
||||
|
} |
||||
|
|
||||
|
/** Creates an array of `Long` objects */ |
||||
|
// Subject to a compiler optimization in Cleanup, see above. |
||||
|
def apply(x: Long, xs: Long*): Array[Long] = { |
||||
|
val array = new Array[Long](xs.length + 1) |
||||
|
array(0) = x |
||||
|
val iterator = xs.iterator |
||||
|
var i = 1 |
||||
|
while (iterator.hasNext) { |
||||
|
array(i) = iterator.next(); i += 1 |
||||
|
} |
||||
|
array |
||||
|
} |
||||
|
|
||||
|
/** Creates an array of `Float` objects */ |
||||
|
// Subject to a compiler optimization in Cleanup, see above. |
||||
|
def apply(x: Float, xs: Float*): Array[Float] = { |
||||
|
val array = new Array[Float](xs.length + 1) |
||||
|
array(0) = x |
||||
|
val iterator = xs.iterator |
||||
|
var i = 1 |
||||
|
while (iterator.hasNext) { |
||||
|
array(i) = iterator.next(); i += 1 |
||||
|
} |
||||
|
array |
||||
|
} |
||||
|
|
||||
|
/** Creates an array of `Double` objects */ |
||||
|
// Subject to a compiler optimization in Cleanup, see above. |
||||
|
def apply(x: Double, xs: Double*): Array[Double] = { |
||||
|
val array = new Array[Double](xs.length + 1) |
||||
|
array(0) = x |
||||
|
val iterator = xs.iterator |
||||
|
var i = 1 |
||||
|
while (iterator.hasNext) { |
||||
|
array(i) = iterator.next(); i += 1 |
||||
|
} |
||||
|
array |
||||
|
} |
||||
|
|
||||
|
/** Creates an array of `Unit` objects */ |
||||
|
def apply(x: Unit, xs: Unit*): Array[Unit] = { |
||||
|
val array = new Array[Unit](xs.length + 1) |
||||
|
array(0) = x |
||||
|
val iterator = xs.iterator |
||||
|
var i = 1 |
||||
|
while (iterator.hasNext) { |
||||
|
array(i) = iterator.next(); i += 1 |
||||
|
} |
||||
|
array |
||||
|
} |
||||
|
|
||||
|
/** Creates array with given dimensions */ |
||||
|
def ofDim[T: ClassTag](n1: Int): Array[T] = |
||||
|
new Array[T](n1) |
||||
|
/** Creates a 2-dimensional array */ |
||||
|
def ofDim[T: ClassTag](n1: Int, n2: Int): Array[Array[T]] = { |
||||
|
val arr: Array[Array[T]] = (new Array[Array[T]](n1): Array[Array[T]]) |
||||
|
for (i <- 0 until n1) arr(i) = new Array[T](n2) |
||||
|
arr |
||||
|
// tabulate(n1)(_ => ofDim[T](n2)) |
||||
|
} |
||||
|
/** Creates a 3-dimensional array */ |
||||
|
def ofDim[T: ClassTag](n1: Int, n2: Int, n3: Int): Array[Array[Array[T]]] = |
||||
|
tabulate(n1)(_ => ofDim[T](n2, n3)) |
||||
|
/** Creates a 4-dimensional array */ |
||||
|
def ofDim[T: ClassTag](n1: Int, n2: Int, n3: Int, n4: Int): Array[Array[Array[Array[T]]]] = |
||||
|
tabulate(n1)(_ => ofDim[T](n2, n3, n4)) |
||||
|
/** Creates a 5-dimensional array */ |
||||
|
def ofDim[T: ClassTag](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int): Array[Array[Array[Array[Array[T]]]]] = |
||||
|
tabulate(n1)(_ => ofDim[T](n2, n3, n4, n5)) |
||||
|
|
||||
|
/** Concatenates all arrays into a single array. |
||||
|
* |
||||
|
* @param xss the given arrays |
||||
|
* @return the array created from concatenating `xss` |
||||
|
*/ |
||||
|
def concat[T: ClassTag](xss: Array[T]*): Array[T] = { |
||||
|
val b = newBuilder[T] |
||||
|
b.sizeHint(xss.map(_.length).sum) |
||||
|
for (xs <- xss) b ++= xs |
||||
|
b.result() |
||||
|
} |
||||
|
|
||||
|
/** Returns an array that contains the results of some element computation a number |
||||
|
* of times. |
||||
|
* |
||||
|
* Note that this means that `elem` is computed a total of n times: |
||||
|
* {{{ |
||||
|
* scala> Array.fill(3){ math.random } |
||||
|
* res3: Array[Double] = Array(0.365461167592537, 1.550395944913685E-4, 0.7907242137333306) |
||||
|
* }}} |
||||
|
* |
||||
|
* @param n the number of elements desired |
||||
|
* @param elem the element computation |
||||
|
* @return an Array of size n, where each element contains the result of computing |
||||
|
* `elem`. |
||||
|
*/ |
||||
|
def fill[T: ClassTag](n: Int)(elem: => T): Array[T] = { |
||||
|
if (n <= 0) { |
||||
|
empty[T] |
||||
|
} else { |
||||
|
val array = new Array[T](n) |
||||
|
var i = 0 |
||||
|
while (i < n) { |
||||
|
array(i) = elem |
||||
|
i += 1 |
||||
|
} |
||||
|
array |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** Returns a two-dimensional array that contains the results of some element |
||||
|
* computation a number of times. |
||||
|
* |
||||
|
* @param n1 the number of elements in the 1st dimension |
||||
|
* @param n2 the number of elements in the 2nd dimension |
||||
|
* @param elem the element computation |
||||
|
*/ |
||||
|
def fill[T: ClassTag](n1: Int, n2: Int)(elem: => T): Array[Array[T]] = |
||||
|
tabulate(n1)(_ => fill(n2)(elem)) |
||||
|
|
||||
|
/** Returns a three-dimensional array that contains the results of some element |
||||
|
* computation a number of times. |
||||
|
* |
||||
|
* @param n1 the number of elements in the 1st dimension |
||||
|
* @param n2 the number of elements in the 2nd dimension |
||||
|
* @param n3 the number of elements in the 3rd dimension |
||||
|
* @param elem the element computation |
||||
|
*/ |
||||
|
def fill[T: ClassTag](n1: Int, n2: Int, n3: Int)(elem: => T): Array[Array[Array[T]]] = |
||||
|
tabulate(n1)(_ => fill(n2, n3)(elem)) |
||||
|
|
||||
|
/** Returns a four-dimensional array that contains the results of some element |
||||
|
* computation a number of times. |
||||
|
* |
||||
|
* @param n1 the number of elements in the 1st dimension |
||||
|
* @param n2 the number of elements in the 2nd dimension |
||||
|
* @param n3 the number of elements in the 3rd dimension |
||||
|
* @param n4 the number of elements in the 4th dimension |
||||
|
* @param elem the element computation |
||||
|
*/ |
||||
|
def fill[T: ClassTag](n1: Int, n2: Int, n3: Int, n4: Int)(elem: => T): Array[Array[Array[Array[T]]]] = |
||||
|
tabulate(n1)(_ => fill(n2, n3, n4)(elem)) |
||||
|
|
||||
|
/** Returns a five-dimensional array that contains the results of some element |
||||
|
* computation a number of times. |
||||
|
* |
||||
|
* @param n1 the number of elements in the 1st dimension |
||||
|
* @param n2 the number of elements in the 2nd dimension |
||||
|
* @param n3 the number of elements in the 3rd dimension |
||||
|
* @param n4 the number of elements in the 4th dimension |
||||
|
* @param n5 the number of elements in the 5th dimension |
||||
|
* @param elem the element computation |
||||
|
*/ |
||||
|
def fill[T: ClassTag](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int)(elem: => T): Array[Array[Array[Array[Array[T]]]]] = |
||||
|
tabulate(n1)(_ => fill(n2, n3, n4, n5)(elem)) |
||||
|
|
||||
|
/** Returns an array containing values of a given function over a range of integer |
||||
|
* values starting from 0. |
||||
|
* |
||||
|
* @param n The number of elements in the array |
||||
|
* @param f The function computing element values |
||||
|
* @return A traversable consisting of elements `f(0),f(1), ..., f(n - 1)` |
||||
|
*/ |
||||
|
def tabulate[T: ClassTag](n: Int)(f: Int => T): Array[T] = { |
||||
|
if (n <= 0) { |
||||
|
empty[T] |
||||
|
} else { |
||||
|
val array = new Array[T](n) |
||||
|
var i = 0 |
||||
|
while (i < n) { |
||||
|
array(i) = f(i) |
||||
|
i += 1 |
||||
|
} |
||||
|
array |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** Returns a two-dimensional array containing values of a given function |
||||
|
* over ranges of integer values starting from `0`. |
||||
|
* |
||||
|
* @param n1 the number of elements in the 1st dimension |
||||
|
* @param n2 the number of elements in the 2nd dimension |
||||
|
* @param f The function computing element values |
||||
|
*/ |
||||
|
def tabulate[T: ClassTag](n1: Int, n2: Int)(f: (Int, Int) => T): Array[Array[T]] = |
||||
|
tabulate(n1)(i1 => tabulate(n2)(f(i1, _))) |
||||
|
|
||||
|
/** Returns a three-dimensional array containing values of a given function |
||||
|
* over ranges of integer values starting from `0`. |
||||
|
* |
||||
|
* @param n1 the number of elements in the 1st dimension |
||||
|
* @param n2 the number of elements in the 2nd dimension |
||||
|
* @param n3 the number of elements in the 3rd dimension |
||||
|
* @param f The function computing element values |
||||
|
*/ |
||||
|
def tabulate[T: ClassTag](n1: Int, n2: Int, n3: Int)(f: (Int, Int, Int) => T): Array[Array[Array[T]]] = |
||||
|
tabulate(n1)(i1 => tabulate(n2, n3)(f(i1, _, _))) |
||||
|
|
||||
|
/** Returns a four-dimensional array containing values of a given function |
||||
|
* over ranges of integer values starting from `0`. |
||||
|
* |
||||
|
* @param n1 the number of elements in the 1st dimension |
||||
|
* @param n2 the number of elements in the 2nd dimension |
||||
|
* @param n3 the number of elements in the 3rd dimension |
||||
|
* @param n4 the number of elements in the 4th dimension |
||||
|
* @param f The function computing element values |
||||
|
*/ |
||||
|
def tabulate[T: ClassTag](n1: Int, n2: Int, n3: Int, n4: Int)(f: (Int, Int, Int, Int) => T): Array[Array[Array[Array[T]]]] = |
||||
|
tabulate(n1)(i1 => tabulate(n2, n3, n4)(f(i1, _, _, _))) |
||||
|
|
||||
|
/** Returns a five-dimensional array containing values of a given function |
||||
|
* over ranges of integer values starting from `0`. |
||||
|
* |
||||
|
* @param n1 the number of elements in the 1st dimension |
||||
|
* @param n2 the number of elements in the 2nd dimension |
||||
|
* @param n3 the number of elements in the 3rd dimension |
||||
|
* @param n4 the number of elements in the 4th dimension |
||||
|
* @param n5 the number of elements in the 5th dimension |
||||
|
* @param f The function computing element values |
||||
|
*/ |
||||
|
def tabulate[T: ClassTag](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int)(f: (Int, Int, Int, Int, Int) => T): Array[Array[Array[Array[Array[T]]]]] = |
||||
|
tabulate(n1)(i1 => tabulate(n2, n3, n4, n5)(f(i1, _, _, _, _))) |
||||
|
|
||||
|
/** Returns an array containing a sequence of increasing integers in a range. |
||||
|
* |
||||
|
* @param start the start value of the array |
||||
|
* @param end the end value of the array, exclusive (in other words, this is the first value '''not''' returned) |
||||
|
* @return the array with values in range `start, start + 1, ..., end - 1` |
||||
|
* up to, but excluding, `end`. |
||||
|
*/ |
||||
|
def range(start: Int, end: Int): Array[Int] = range(start, end, 1) |
||||
|
|
||||
|
/** Returns an array containing equally spaced values in some integer interval. |
||||
|
* |
||||
|
* @param start the start value of the array |
||||
|
* @param end the end value of the array, exclusive (in other words, this is the first value '''not''' returned) |
||||
|
* @param step the increment value of the array (may not be zero) |
||||
|
* @return the array with values in `start, start + step, ...` up to, but excluding `end` |
||||
|
*/ |
||||
|
def range(start: Int, end: Int, step: Int): Array[Int] = { |
||||
|
if (step == 0) throw new IllegalArgumentException("zero step") |
||||
|
val array = new Array[Int](immutable.Range.count(start, end, step, isInclusive = false)) |
||||
|
|
||||
|
var n = 0 |
||||
|
var i = start |
||||
|
while (if (step < 0) end < i else i < end) { |
||||
|
array(n) = i |
||||
|
i += step |
||||
|
n += 1 |
||||
|
} |
||||
|
array |
||||
|
} |
||||
|
|
||||
|
/** Returns an array containing repeated applications of a function to a start value. |
||||
|
* |
||||
|
* @param start the start value of the array |
||||
|
* @param len the number of elements returned by the array |
||||
|
* @param f the function that is repeatedly applied |
||||
|
* @return the array returning `len` values in the sequence `start, f(start), f(f(start)), ...` |
||||
|
*/ |
||||
|
def iterate[T: ClassTag](start: T, len: Int)(f: T => T): Array[T] = { |
||||
|
if (len > 0) { |
||||
|
val array = new Array[T](len) |
||||
|
var acc = start |
||||
|
var i = 1 |
||||
|
array(0) = acc |
||||
|
|
||||
|
while (i < len) { |
||||
|
acc = f(acc) |
||||
|
array(i) = acc |
||||
|
i += 1 |
||||
|
} |
||||
|
array |
||||
|
} else { |
||||
|
empty[T] |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
def equals(xs: Array[AnyRef], ys: Array[AnyRef]): Boolean = { |
||||
|
if (xs eq ys) |
||||
|
return true |
||||
|
if (xs.length != ys.length) |
||||
|
return false |
||||
|
|
||||
|
val len = xs.length |
||||
|
var i = 0 |
||||
|
while (i < len) { |
||||
|
if (xs(i) != ys(i)) |
||||
|
return false |
||||
|
i += 1 |
||||
|
} |
||||
|
true |
||||
|
} |
||||
|
|
||||
|
/** Called in a pattern match like `{ case Array(x,y,z) => println('3 elements')}`. |
||||
|
* |
||||
|
* @param x the selector value |
||||
|
* @return sequence wrapped in a [[scala.Some]], if `x` is an Array, otherwise `None` |
||||
|
*/ |
||||
|
def unapplySeq[T](x: Array[T]): UnapplySeqWrapper[T] = new UnapplySeqWrapper(x) |
||||
|
|
||||
|
final class UnapplySeqWrapper[T](private val a: Array[T]) extends AnyVal { |
||||
|
def isEmpty: Boolean = false |
||||
|
def get: UnapplySeqWrapper[T] = this |
||||
|
def lengthCompare(len: Int): Int = a.lengthCompare(len) |
||||
|
def apply(i: Int): T = a(i) |
||||
|
def drop(n: Int): scala.Seq[T] = ArraySeq.unsafeWrapArray(a.drop(n)) // clones the array, also if n == 0 |
||||
|
def toSeq: scala.Seq[T] = a.toSeq // clones the array |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** Arrays are mutable, indexed collections of values. `Array[T]` is Scala's representation |
||||
|
* for Java's `T[]`. |
||||
|
* |
||||
|
* {{{ |
||||
|
* val numbers = Array(1, 2, 3, 4) |
||||
|
* val first = numbers(0) // read the first element |
||||
|
* numbers(3) = 100 // replace the 4th array element with 100 |
||||
|
* val biggerNumbers = numbers.map(_ * 2) // multiply all numbers by two |
||||
|
* }}} |
||||
|
* |
||||
|
* Arrays make use of two common pieces of Scala syntactic sugar, shown on lines 2 and 3 of the above |
||||
|
* example code. |
||||
|
* Line 2 is translated into a call to `apply(Int)`, while line 3 is translated into a call to |
||||
|
* `update(Int, T)`. |
||||
|
* |
||||
|
* Two implicit conversions exist in [[scala.Predef]] that are frequently applied to arrays: a conversion |
||||
|
* to [[scala.collection.ArrayOps]] (shown on line 4 of the example above) and a conversion |
||||
|
* to [[scala.collection.mutable.ArraySeq]] (a subtype of [[scala.collection.Seq]]). |
||||
|
* Both types make available many of the standard operations found in the Scala collections API. |
||||
|
* The conversion to `ArrayOps` is temporary, as all operations defined on `ArrayOps` return an `Array`, |
||||
|
* while the conversion to `ArraySeq` is permanent as all operations return a `ArraySeq`. |
||||
|
* |
||||
|
* The conversion to `ArrayOps` takes priority over the conversion to `ArraySeq`. For instance, |
||||
|
* consider the following code: |
||||
|
* |
||||
|
* {{{ |
||||
|
* val arr = Array(1, 2, 3) |
||||
|
* val arrReversed = arr.reverse |
||||
|
* val seqReversed : collection.Seq[Int] = arr.reverse |
||||
|
* }}} |
||||
|
* |
||||
|
* Value `arrReversed` will be of type `Array[Int]`, with an implicit conversion to `ArrayOps` occurring |
||||
|
* to perform the `reverse` operation. The value of `seqReversed`, on the other hand, will be computed |
||||
|
* by converting to `ArraySeq` first and invoking the variant of `reverse` that returns another |
||||
|
* `ArraySeq`. |
||||
|
* |
||||
|
* @see [[http://www.scala-lang.org/files/archive/spec/2.13/ Scala Language Specification]], for in-depth information on the transformations the Scala compiler makes on Arrays (Sections 6.6 and 6.15 respectively.) |
||||
|
* @see [[http://docs.scala-lang.org/sips/completed/scala-2-8-arrays.html "Scala 2.8 Arrays"]] the Scala Improvement Document detailing arrays since Scala 2.8. |
||||
|
* @see [[http://docs.scala-lang.org/overviews/collections/arrays.html "The Scala 2.8 Collections' API"]] section on `Array` by Martin Odersky for more information. |
||||
|
* @hideImplicitConversion scala.Predef.booleanArrayOps |
||||
|
* @hideImplicitConversion scala.Predef.byteArrayOps |
||||
|
* @hideImplicitConversion scala.Predef.charArrayOps |
||||
|
* @hideImplicitConversion scala.Predef.doubleArrayOps |
||||
|
* @hideImplicitConversion scala.Predef.floatArrayOps |
||||
|
* @hideImplicitConversion scala.Predef.intArrayOps |
||||
|
* @hideImplicitConversion scala.Predef.longArrayOps |
||||
|
* @hideImplicitConversion scala.Predef.refArrayOps |
||||
|
* @hideImplicitConversion scala.Predef.shortArrayOps |
||||
|
* @hideImplicitConversion scala.Predef.unitArrayOps |
||||
|
* @hideImplicitConversion scala.LowPriorityImplicits.wrapRefArray |
||||
|
* @hideImplicitConversion scala.LowPriorityImplicits.wrapIntArray |
||||
|
* @hideImplicitConversion scala.LowPriorityImplicits.wrapDoubleArray |
||||
|
* @hideImplicitConversion scala.LowPriorityImplicits.wrapLongArray |
||||
|
* @hideImplicitConversion scala.LowPriorityImplicits.wrapFloatArray |
||||
|
* @hideImplicitConversion scala.LowPriorityImplicits.wrapCharArray |
||||
|
* @hideImplicitConversion scala.LowPriorityImplicits.wrapByteArray |
||||
|
* @hideImplicitConversion scala.LowPriorityImplicits.wrapShortArray |
||||
|
* @hideImplicitConversion scala.LowPriorityImplicits.wrapBooleanArray |
||||
|
* @hideImplicitConversion scala.LowPriorityImplicits.wrapUnitArray |
||||
|
* @hideImplicitConversion scala.LowPriorityImplicits.genericWrapArray |
||||
|
* @define coll array |
||||
|
* @define Coll `Array` |
||||
|
* @define orderDependent |
||||
|
* @define orderDependentFold |
||||
|
* @define mayNotTerminateInf |
||||
|
* @define willNotTerminateInf |
||||
|
* @define collectExample |
||||
|
* @define undefinedorder |
||||
|
*/ |
||||
|
final class Array[T](_length: Int) extends java.io.Serializable with java.lang.Cloneable { |
||||
|
|
||||
|
/** The length of the array */ |
||||
|
def length: Int = throw new Error() |
||||
|
|
||||
|
/** The element at given index. |
||||
|
* |
||||
|
* Indices start at `0`; `xs.apply(0)` is the first element of array `xs`. |
||||
|
* Note the indexing syntax `xs(i)` is a shorthand for `xs.apply(i)`. |
||||
|
* |
||||
|
* @param i the index |
||||
|
* @return the element at the given index |
||||
|
* @throws ArrayIndexOutOfBoundsException if `i < 0` or `length <= i` |
||||
|
*/ |
||||
|
def apply(i: Int): T = throw new Error() |
||||
|
|
||||
|
/** Update the element at given index. |
||||
|
* |
||||
|
* Indices start at `0`; `xs.update(i, x)` replaces the i^th^ element in the array. |
||||
|
* Note the syntax `xs(i) = x` is a shorthand for `xs.update(i, x)`. |
||||
|
* |
||||
|
* @param i the index |
||||
|
* @param x the value to be written at index `i` |
||||
|
* @throws ArrayIndexOutOfBoundsException if `i < 0` or `length <= i` |
||||
|
*/ |
||||
|
def update(i: Int, x: T): Unit = { throw new Error() } |
||||
|
|
||||
|
/** Clone the Array. |
||||
|
* |
||||
|
* @return A clone of the Array. |
||||
|
*/ |
||||
|
override def clone(): Array[T] = throw new Error() |
||||
|
} |
@ -0,0 +1,140 @@ |
|||||
|
/* |
||||
|
* Scala (https://www.scala-lang.org) |
||||
|
* |
||||
|
* Copyright EPFL and Lightbend, Inc. |
||||
|
* |
||||
|
* Licensed under Apache License 2.0 |
||||
|
* (http://www.apache.org/licenses/LICENSE-2.0). |
||||
|
* |
||||
|
* See the NOTICE file distributed with this work for |
||||
|
* additional information regarding copyright ownership. |
||||
|
*/ |
||||
|
|
||||
|
// DO NOT EDIT, CHANGES WILL BE LOST |
||||
|
// This auto-generated code can be modified in "project/GenerateAnyVals.scala". |
||||
|
// Afterwards, running "sbt generateSources" regenerates this source file. |
||||
|
|
||||
|
package scala |
||||
|
|
||||
|
/** `Boolean` (equivalent to Java's `boolean` primitive type) is a |
||||
|
* subtype of [[scala.AnyVal]]. Instances of `Boolean` are not |
||||
|
* represented by an object in the underlying runtime system. |
||||
|
* |
||||
|
* There is an implicit conversion from [[scala.Boolean]] => [[scala.runtime.RichBoolean]] |
||||
|
* which provides useful non-primitive operations. |
||||
|
*/ |
||||
|
final abstract class Boolean private extends AnyVal { |
||||
|
/** Negates a Boolean expression. |
||||
|
* |
||||
|
* - `!a` results in `false` if and only if `a` evaluates to `true` and |
||||
|
* - `!a` results in `true` if and only if `a` evaluates to `false`. |
||||
|
* |
||||
|
* @return the negated expression |
||||
|
*/ |
||||
|
def unary_! : Boolean |
||||
|
|
||||
|
/** Compares two Boolean expressions and returns `true` if they evaluate to the same value. |
||||
|
* |
||||
|
* `a == b` returns `true` if and only if |
||||
|
* - `a` and `b` are `true` or |
||||
|
* - `a` and `b` are `false`. |
||||
|
*/ |
||||
|
def ==(x: Boolean): Boolean |
||||
|
|
||||
|
/** |
||||
|
* Compares two Boolean expressions and returns `true` if they evaluate to a different value. |
||||
|
* |
||||
|
* `a != b` returns `true` if and only if |
||||
|
* - `a` is `true` and `b` is `false` or |
||||
|
* - `a` is `false` and `b` is `true`. |
||||
|
*/ |
||||
|
def !=(x: Boolean): Boolean |
||||
|
|
||||
|
/** Compares two Boolean expressions and returns `true` if one or both of them evaluate to true. |
||||
|
* |
||||
|
* `a || b` returns `true` if and only if |
||||
|
* - `a` is `true` or |
||||
|
* - `b` is `true` or |
||||
|
* - `a` and `b` are `true`. |
||||
|
* |
||||
|
* @note This method uses 'short-circuit' evaluation and |
||||
|
* behaves as if it was declared as `def ||(x: => Boolean): Boolean`. |
||||
|
* If `a` evaluates to `true`, `true` is returned without evaluating `b`. |
||||
|
*/ |
||||
|
def ||(x: Boolean): Boolean |
||||
|
|
||||
|
/** Compares two Boolean expressions and returns `true` if both of them evaluate to true. |
||||
|
* |
||||
|
* `a && b` returns `true` if and only if |
||||
|
* - `a` and `b` are `true`. |
||||
|
* |
||||
|
* @note This method uses 'short-circuit' evaluation and |
||||
|
* behaves as if it was declared as `def &&(x: => Boolean): Boolean`. |
||||
|
* If `a` evaluates to `false`, `false` is returned without evaluating `b`. |
||||
|
*/ |
||||
|
def &&(x: Boolean): Boolean |
||||
|
|
||||
|
// Compiler won't build with these seemingly more accurate signatures |
||||
|
// def ||(x: => Boolean): Boolean |
||||
|
// def &&(x: => Boolean): Boolean |
||||
|
|
||||
|
/** Compares two Boolean expressions and returns `true` if one or both of them evaluate to true. |
||||
|
* |
||||
|
* `a | b` returns `true` if and only if |
||||
|
* - `a` is `true` or |
||||
|
* - `b` is `true` or |
||||
|
* - `a` and `b` are `true`. |
||||
|
* |
||||
|
* @note This method evaluates both `a` and `b`, even if the result is already determined after evaluating `a`. |
||||
|
*/ |
||||
|
def |(x: Boolean): Boolean |
||||
|
|
||||
|
/** Compares two Boolean expressions and returns `true` if both of them evaluate to true. |
||||
|
* |
||||
|
* `a & b` returns `true` if and only if |
||||
|
* - `a` and `b` are `true`. |
||||
|
* |
||||
|
* @note This method evaluates both `a` and `b`, even if the result is already determined after evaluating `a`. |
||||
|
*/ |
||||
|
def &(x: Boolean): Boolean |
||||
|
|
||||
|
/** Compares two Boolean expressions and returns `true` if they evaluate to a different value. |
||||
|
* |
||||
|
* `a ^ b` returns `true` if and only if |
||||
|
* - `a` is `true` and `b` is `false` or |
||||
|
* - `a` is `false` and `b` is `true`. |
||||
|
*/ |
||||
|
def ^(x: Boolean): Boolean |
||||
|
|
||||
|
// Provide a more specific return type for Scaladoc |
||||
|
override def getClass(): Class[Boolean] = ??? |
||||
|
} |
||||
|
|
||||
|
object Boolean extends AnyValCompanion { |
||||
|
|
||||
|
/** Transform a value type into a boxed reference type. |
||||
|
* |
||||
|
* Runtime implementation determined by `scala.runtime.BoxesRunTime.boxToBoolean`. See [[https://github.com/scala/scala src/library/scala/runtime/BoxesRunTime.java]]. |
||||
|
* |
||||
|
* @param x the Boolean to be boxed |
||||
|
* @return a java.lang.Boolean offering `x` as its underlying value. |
||||
|
*/ |
||||
|
def box(x: Boolean): java.lang.Boolean = ??? |
||||
|
|
||||
|
/** Transform a boxed type into a value type. Note that this |
||||
|
* method is not typesafe: it accepts any Object, but will throw |
||||
|
* an exception if the argument is not a java.lang.Boolean. |
||||
|
* |
||||
|
* Runtime implementation determined by `scala.runtime.BoxesRunTime.unboxToBoolean`. See [[https://github.com/scala/scala src/library/scala/runtime/BoxesRunTime.java]]. |
||||
|
* |
||||
|
* @param x the java.lang.Boolean to be unboxed. |
||||
|
* @throws ClassCastException if the argument is not a java.lang.Boolean |
||||
|
* @return the Boolean resulting from calling booleanValue() on `x` |
||||
|
*/ |
||||
|
def unbox(x: java.lang.Object): Boolean = ??? |
||||
|
|
||||
|
/** The String representation of the scala.Boolean companion object. */ |
||||
|
override def toString = "object scala.Boolean" |
||||
|
|
||||
|
} |
||||
|
|
@ -0,0 +1,42 @@ |
|||||
|
/* |
||||
|
* Scala (https://www.scala-lang.org) |
||||
|
* |
||||
|
* Copyright EPFL and Lightbend, Inc. |
||||
|
* |
||||
|
* Licensed under Apache License 2.0 |
||||
|
* (http://www.apache.org/licenses/LICENSE-2.0). |
||||
|
* |
||||
|
* See the NOTICE file distributed with this work for |
||||
|
* additional information regarding copyright ownership. |
||||
|
*/ |
||||
|
|
||||
|
// GENERATED CODE: DO NOT EDIT. |
||||
|
// genprod generated these sources at: 2020-02-01T04:13:22.795Z |
||||
|
|
||||
|
package scala |
||||
|
|
||||
|
|
||||
|
/** A function of 0 parameters. |
||||
|
* |
||||
|
* In the following example, the definition of javaVersion is a |
||||
|
* shorthand for the anonymous class definition anonfun0: |
||||
|
* |
||||
|
* {{{ |
||||
|
* object Main extends App { |
||||
|
* val javaVersion = () => sys.props("java.version") |
||||
|
* |
||||
|
* val anonfun0 = new Function0[String] { |
||||
|
* def apply(): String = sys.props("java.version") |
||||
|
* } |
||||
|
* assert(javaVersion() == anonfun0()) |
||||
|
* } |
||||
|
* }}} |
||||
|
*/ |
||||
|
trait Function0[@specialized(Specializable.Primitives) +R] extends AnyRef { self => |
||||
|
/** Apply the body of this function to the arguments. |
||||
|
* @return the result of function application. |
||||
|
*/ |
||||
|
def apply(): R |
||||
|
|
||||
|
override def toString(): String = "<function0>" |
||||
|
} |
@ -0,0 +1,486 @@ |
|||||
|
/* |
||||
|
* Scala (https://www.scala-lang.org) |
||||
|
* |
||||
|
* Copyright EPFL and Lightbend, Inc. |
||||
|
* |
||||
|
* Licensed under Apache License 2.0 |
||||
|
* (http://www.apache.org/licenses/LICENSE-2.0). |
||||
|
* |
||||
|
* See the NOTICE file distributed with this work for |
||||
|
* additional information regarding copyright ownership. |
||||
|
*/ |
||||
|
|
||||
|
// DO NOT EDIT, CHANGES WILL BE LOST |
||||
|
// This auto-generated code can be modified in "project/GenerateAnyVals.scala". |
||||
|
// Afterwards, running "sbt generateSources" regenerates this source file. |
||||
|
|
||||
|
package scala |
||||
|
|
||||
|
/** `Int`, a 32-bit signed integer (equivalent to Java's `int` primitive type) is a |
||||
|
* subtype of [[scala.AnyVal]]. Instances of `Int` are not |
||||
|
* represented by an object in the underlying runtime system. |
||||
|
* |
||||
|
* There is an implicit conversion from [[scala.Int]] => [[scala.runtime.RichInt]] |
||||
|
* which provides useful non-primitive operations. |
||||
|
*/ |
||||
|
final abstract class Int private extends AnyVal { |
||||
|
def toByte: Byte |
||||
|
def toShort: Short |
||||
|
def toChar: Char |
||||
|
def toInt: Int |
||||
|
def toLong: Long |
||||
|
def toFloat: Float |
||||
|
def toDouble: Double |
||||
|
|
||||
|
/** |
||||
|
* Returns the bitwise negation of this value. |
||||
|
* @example {{{ |
||||
|
* ~5 == -6 |
||||
|
* // in binary: ~00000101 == |
||||
|
* // 11111010 |
||||
|
* }}} |
||||
|
*/ |
||||
|
def unary_~ : Int |
||||
|
/** Returns this value, unmodified. */ |
||||
|
def unary_+ : Int |
||||
|
/** Returns the negation of this value. */ |
||||
|
def unary_- : Int |
||||
|
|
||||
|
@deprecated("Adding a number and a String is deprecated. Use the string interpolation `s\"$num$str\"`", "2.13.0") |
||||
|
def +(x: String): String |
||||
|
|
||||
|
/** |
||||
|
* Returns this value bit-shifted left by the specified number of bits, |
||||
|
* filling in the new right bits with zeroes. |
||||
|
* @example {{{ 6 << 3 == 48 // in binary: 0110 << 3 == 0110000 }}} |
||||
|
*/ |
||||
|
def <<(x: Int): Int |
||||
|
/** |
||||
|
* Returns this value bit-shifted left by the specified number of bits, |
||||
|
* filling in the new right bits with zeroes. |
||||
|
* @example {{{ 6 << 3 == 48 // in binary: 0110 << 3 == 0110000 }}} |
||||
|
*/ |
||||
|
@deprecated("shifting a value by a `Long` argument is deprecated (except when the value is a `Long`).\nCall `toInt` on the argument to maintain the current behavior and avoid the deprecation warning.", "2.12.7") |
||||
|
def <<(x: Long): Int |
||||
|
/** |
||||
|
* Returns this value bit-shifted right by the specified number of bits, |
||||
|
* filling the new left bits with zeroes. |
||||
|
* @example {{{ 21 >>> 3 == 2 // in binary: 010101 >>> 3 == 010 }}} |
||||
|
* @example {{{ |
||||
|
* -21 >>> 3 == 536870909 |
||||
|
* // in binary: 11111111 11111111 11111111 11101011 >>> 3 == |
||||
|
* // 00011111 11111111 11111111 11111101 |
||||
|
* }}} |
||||
|
*/ |
||||
|
def >>>(x: Int): Int |
||||
|
/** |
||||
|
* Returns this value bit-shifted right by the specified number of bits, |
||||
|
* filling the new left bits with zeroes. |
||||
|
* @example {{{ 21 >>> 3 == 2 // in binary: 010101 >>> 3 == 010 }}} |
||||
|
* @example {{{ |
||||
|
* -21 >>> 3 == 536870909 |
||||
|
* // in binary: 11111111 11111111 11111111 11101011 >>> 3 == |
||||
|
* // 00011111 11111111 11111111 11111101 |
||||
|
* }}} |
||||
|
*/ |
||||
|
@deprecated("shifting a value by a `Long` argument is deprecated (except when the value is a `Long`).\nCall `toInt` on the argument to maintain the current behavior and avoid the deprecation warning.", "2.12.7") |
||||
|
def >>>(x: Long): Int |
||||
|
/** |
||||
|
* Returns this value bit-shifted right by the specified number of bits, |
||||
|
* filling in the left bits with the same value as the left-most bit of this. |
||||
|
* The effect of this is to retain the sign of the value. |
||||
|
* @example {{{ |
||||
|
* -21 >> 3 == -3 |
||||
|
* // in binary: 11111111 11111111 11111111 11101011 >> 3 == |
||||
|
* // 11111111 11111111 11111111 11111101 |
||||
|
* }}} |
||||
|
*/ |
||||
|
def >>(x: Int): Int |
||||
|
/** |
||||
|
* Returns this value bit-shifted right by the specified number of bits, |
||||
|
* filling in the left bits with the same value as the left-most bit of this. |
||||
|
* The effect of this is to retain the sign of the value. |
||||
|
* @example {{{ |
||||
|
* -21 >> 3 == -3 |
||||
|
* // in binary: 11111111 11111111 11111111 11101011 >> 3 == |
||||
|
* // 11111111 11111111 11111111 11111101 |
||||
|
* }}} |
||||
|
*/ |
||||
|
@deprecated("shifting a value by a `Long` argument is deprecated (except when the value is a `Long`).\nCall `toInt` on the argument to maintain the current behavior and avoid the deprecation warning.", "2.12.7") |
||||
|
def >>(x: Long): Int |
||||
|
|
||||
|
/** Returns `true` if this value is equal to x, `false` otherwise. */ |
||||
|
def ==(x: Byte): Boolean |
||||
|
/** Returns `true` if this value is equal to x, `false` otherwise. */ |
||||
|
def ==(x: Short): Boolean |
||||
|
/** Returns `true` if this value is equal to x, `false` otherwise. */ |
||||
|
def ==(x: Char): Boolean |
||||
|
/** Returns `true` if this value is equal to x, `false` otherwise. */ |
||||
|
def ==(x: Int): Boolean |
||||
|
/** Returns `true` if this value is equal to x, `false` otherwise. */ |
||||
|
def ==(x: Long): Boolean |
||||
|
/** Returns `true` if this value is equal to x, `false` otherwise. */ |
||||
|
def ==(x: Float): Boolean |
||||
|
/** Returns `true` if this value is equal to x, `false` otherwise. */ |
||||
|
def ==(x: Double): Boolean |
||||
|
|
||||
|
/** Returns `true` if this value is not equal to x, `false` otherwise. */ |
||||
|
def !=(x: Byte): Boolean |
||||
|
/** Returns `true` if this value is not equal to x, `false` otherwise. */ |
||||
|
def !=(x: Short): Boolean |
||||
|
/** Returns `true` if this value is not equal to x, `false` otherwise. */ |
||||
|
def !=(x: Char): Boolean |
||||
|
/** Returns `true` if this value is not equal to x, `false` otherwise. */ |
||||
|
def !=(x: Int): Boolean |
||||
|
/** Returns `true` if this value is not equal to x, `false` otherwise. */ |
||||
|
def !=(x: Long): Boolean |
||||
|
/** Returns `true` if this value is not equal to x, `false` otherwise. */ |
||||
|
def !=(x: Float): Boolean |
||||
|
/** Returns `true` if this value is not equal to x, `false` otherwise. */ |
||||
|
def !=(x: Double): Boolean |
||||
|
|
||||
|
/** Returns `true` if this value is less than x, `false` otherwise. */ |
||||
|
def <(x: Byte): Boolean |
||||
|
/** Returns `true` if this value is less than x, `false` otherwise. */ |
||||
|
def <(x: Short): Boolean |
||||
|
/** Returns `true` if this value is less than x, `false` otherwise. */ |
||||
|
def <(x: Char): Boolean |
||||
|
/** Returns `true` if this value is less than x, `false` otherwise. */ |
||||
|
def <(x: Int): Boolean |
||||
|
/** Returns `true` if this value is less than x, `false` otherwise. */ |
||||
|
def <(x: Long): Boolean |
||||
|
/** Returns `true` if this value is less than x, `false` otherwise. */ |
||||
|
def <(x: Float): Boolean |
||||
|
/** Returns `true` if this value is less than x, `false` otherwise. */ |
||||
|
def <(x: Double): Boolean |
||||
|
|
||||
|
/** Returns `true` if this value is less than or equal to x, `false` otherwise. */ |
||||
|
def <=(x: Byte): Boolean |
||||
|
/** Returns `true` if this value is less than or equal to x, `false` otherwise. */ |
||||
|
def <=(x: Short): Boolean |
||||
|
/** Returns `true` if this value is less than or equal to x, `false` otherwise. */ |
||||
|
def <=(x: Char): Boolean |
||||
|
/** Returns `true` if this value is less than or equal to x, `false` otherwise. */ |
||||
|
def <=(x: Int): Boolean |
||||
|
/** Returns `true` if this value is less than or equal to x, `false` otherwise. */ |
||||
|
def <=(x: Long): Boolean |
||||
|
/** Returns `true` if this value is less than or equal to x, `false` otherwise. */ |
||||
|
def <=(x: Float): Boolean |
||||
|
/** Returns `true` if this value is less than or equal to x, `false` otherwise. */ |
||||
|
def <=(x: Double): Boolean |
||||
|
|
||||
|
/** Returns `true` if this value is greater than x, `false` otherwise. */ |
||||
|
def >(x: Byte): Boolean |
||||
|
/** Returns `true` if this value is greater than x, `false` otherwise. */ |
||||
|
def >(x: Short): Boolean |
||||
|
/** Returns `true` if this value is greater than x, `false` otherwise. */ |
||||
|
def >(x: Char): Boolean |
||||
|
/** Returns `true` if this value is greater than x, `false` otherwise. */ |
||||
|
def >(x: Int): Boolean |
||||
|
/** Returns `true` if this value is greater than x, `false` otherwise. */ |
||||
|
def >(x: Long): Boolean |
||||
|
/** Returns `true` if this value is greater than x, `false` otherwise. */ |
||||
|
def >(x: Float): Boolean |
||||
|
/** Returns `true` if this value is greater than x, `false` otherwise. */ |
||||
|
def >(x: Double): Boolean |
||||
|
|
||||
|
/** Returns `true` if this value is greater than or equal to x, `false` otherwise. */ |
||||
|
def >=(x: Byte): Boolean |
||||
|
/** Returns `true` if this value is greater than or equal to x, `false` otherwise. */ |
||||
|
def >=(x: Short): Boolean |
||||
|
/** Returns `true` if this value is greater than or equal to x, `false` otherwise. */ |
||||
|
def >=(x: Char): Boolean |
||||
|
/** Returns `true` if this value is greater than or equal to x, `false` otherwise. */ |
||||
|
def >=(x: Int): Boolean |
||||
|
/** Returns `true` if this value is greater than or equal to x, `false` otherwise. */ |
||||
|
def >=(x: Long): Boolean |
||||
|
/** Returns `true` if this value is greater than or equal to x, `false` otherwise. */ |
||||
|
def >=(x: Float): Boolean |
||||
|
/** Returns `true` if this value is greater than or equal to x, `false` otherwise. */ |
||||
|
def >=(x: Double): Boolean |
||||
|
|
||||
|
/** |
||||
|
* Returns the bitwise OR of this value and `x`. |
||||
|
* @example {{{ |
||||
|
* (0xf0 | 0xaa) == 0xfa |
||||
|
* // in binary: 11110000 |
||||
|
* // | 10101010 |
||||
|
* // -------- |
||||
|
* // 11111010 |
||||
|
* }}} |
||||
|
*/ |
||||
|
def |(x: Byte): Int |
||||
|
/** |
||||
|
* Returns the bitwise OR of this value and `x`. |
||||
|
* @example {{{ |
||||
|
* (0xf0 | 0xaa) == 0xfa |
||||
|
* // in binary: 11110000 |
||||
|
* // | 10101010 |
||||
|
* // -------- |
||||
|
* // 11111010 |
||||
|
* }}} |
||||
|
*/ |
||||
|
def |(x: Short): Int |
||||
|
/** |
||||
|
* Returns the bitwise OR of this value and `x`. |
||||
|
* @example {{{ |
||||
|
* (0xf0 | 0xaa) == 0xfa |
||||
|
* // in binary: 11110000 |
||||
|
* // | 10101010 |
||||
|
* // -------- |
||||
|
* // 11111010 |
||||
|
* }}} |
||||
|
*/ |
||||
|
def |(x: Char): Int |
||||
|
/** |
||||
|
* Returns the bitwise OR of this value and `x`. |
||||
|
* @example {{{ |
||||
|
* (0xf0 | 0xaa) == 0xfa |
||||
|
* // in binary: 11110000 |
||||
|
* // | 10101010 |
||||
|
* // -------- |
||||
|
* // 11111010 |
||||
|
* }}} |
||||
|
*/ |
||||
|
def |(x: Int): Int |
||||
|
/** |
||||
|
* Returns the bitwise OR of this value and `x`. |
||||
|
* @example {{{ |
||||
|
* (0xf0 | 0xaa) == 0xfa |
||||
|
* // in binary: 11110000 |
||||
|
* // | 10101010 |
||||
|
* // -------- |
||||
|
* // 11111010 |
||||
|
* }}} |
||||
|
*/ |
||||
|
def |(x: Long): Long |
||||
|
|
||||
|
/** |
||||
|
* Returns the bitwise AND of this value and `x`. |
||||
|
* @example {{{ |
||||
|
* (0xf0 & 0xaa) == 0xa0 |
||||
|
* // in binary: 11110000 |
||||
|
* // & 10101010 |
||||
|
* // -------- |
||||
|
* // 10100000 |
||||
|
* }}} |
||||
|
*/ |
||||
|
def &(x: Byte): Int |
||||
|
/** |
||||
|
* Returns the bitwise AND of this value and `x`. |
||||
|
* @example {{{ |
||||
|
* (0xf0 & 0xaa) == 0xa0 |
||||
|
* // in binary: 11110000 |
||||
|
* // & 10101010 |
||||
|
* // -------- |
||||
|
* // 10100000 |
||||
|
* }}} |
||||
|
*/ |
||||
|
def &(x: Short): Int |
||||
|
/** |
||||
|
* Returns the bitwise AND of this value and `x`. |
||||
|
* @example {{{ |
||||
|
* (0xf0 & 0xaa) == 0xa0 |
||||
|
* // in binary: 11110000 |
||||
|
* // & 10101010 |
||||
|
* // -------- |
||||
|
* // 10100000 |
||||
|
* }}} |
||||
|
*/ |
||||
|
def &(x: Char): Int |
||||
|
/** |
||||
|
* Returns the bitwise AND of this value and `x`. |
||||
|
* @example {{{ |
||||
|
* (0xf0 & 0xaa) == 0xa0 |
||||
|
* // in binary: 11110000 |
||||
|
* // & 10101010 |
||||
|
* // -------- |
||||
|
* // 10100000 |
||||
|
* }}} |
||||
|
*/ |
||||
|
def &(x: Int): Int |
||||
|
/** |
||||
|
* Returns the bitwise AND of this value and `x`. |
||||
|
* @example {{{ |
||||
|
* (0xf0 & 0xaa) == 0xa0 |
||||
|
* // in binary: 11110000 |
||||
|
* // & 10101010 |
||||
|
* // -------- |
||||
|
* // 10100000 |
||||
|
* }}} |
||||
|
*/ |
||||
|
def &(x: Long): Long |
||||
|
|
||||
|
/** |
||||
|
* Returns the bitwise XOR of this value and `x`. |
||||
|
* @example {{{ |
||||
|
* (0xf0 ^ 0xaa) == 0x5a |
||||
|
* // in binary: 11110000 |
||||
|
* // ^ 10101010 |
||||
|
* // -------- |
||||
|
* // 01011010 |
||||
|
* }}} |
||||
|
*/ |
||||
|
def ^(x: Byte): Int |
||||
|
/** |
||||
|
* Returns the bitwise XOR of this value and `x`. |
||||
|
* @example {{{ |
||||
|
* (0xf0 ^ 0xaa) == 0x5a |
||||
|
* // in binary: 11110000 |
||||
|
* // ^ 10101010 |
||||
|
* // -------- |
||||
|
* // 01011010 |
||||
|
* }}} |
||||
|
*/ |
||||
|
def ^(x: Short): Int |
||||
|
/** |
||||
|
* Returns the bitwise XOR of this value and `x`. |
||||
|
* @example {{{ |
||||
|
* (0xf0 ^ 0xaa) == 0x5a |
||||
|
* // in binary: 11110000 |
||||
|
* // ^ 10101010 |
||||
|
* // -------- |
||||
|
* // 01011010 |
||||
|
* }}} |
||||
|
*/ |
||||
|
def ^(x: Char): Int |
||||
|
/** |
||||
|
* Returns the bitwise XOR of this value and `x`. |
||||
|
* @example {{{ |
||||
|
* (0xf0 ^ 0xaa) == 0x5a |
||||
|
* // in binary: 11110000 |
||||
|
* // ^ 10101010 |
||||
|
* // -------- |
||||
|
* // 01011010 |
||||
|
* }}} |
||||
|
*/ |
||||
|
def ^(x: Int): Int |
||||
|
/** |
||||
|
* Returns the bitwise XOR of this value and `x`. |
||||
|
* @example {{{ |
||||
|
* (0xf0 ^ 0xaa) == 0x5a |
||||
|
* // in binary: 11110000 |
||||
|
* // ^ 10101010 |
||||
|
* // -------- |
||||
|
* // 01011010 |
||||
|
* }}} |
||||
|
*/ |
||||
|
def ^(x: Long): Long |
||||
|
|
||||
|
/** Returns the sum of this value and `x`. */ |
||||
|
def +(x: Byte): Int |
||||
|
/** Returns the sum of this value and `x`. */ |
||||
|
def +(x: Short): Int |
||||
|
/** Returns the sum of this value and `x`. */ |
||||
|
def +(x: Char): Int |
||||
|
/** Returns the sum of this value and `x`. */ |
||||
|
def +(x: Int): Int |
||||
|
/** Returns the sum of this value and `x`. */ |
||||
|
def +(x: Long): Long |
||||
|
/** Returns the sum of this value and `x`. */ |
||||
|
def +(x: Float): Float |
||||
|
/** Returns the sum of this value and `x`. */ |
||||
|
def +(x: Double): Double |
||||
|
|
||||
|
/** Returns the difference of this value and `x`. */ |
||||
|
def -(x: Byte): Int |
||||
|
/** Returns the difference of this value and `x`. */ |
||||
|
def -(x: Short): Int |
||||
|
/** Returns the difference of this value and `x`. */ |
||||
|
def -(x: Char): Int |
||||
|
/** Returns the difference of this value and `x`. */ |
||||
|
def -(x: Int): Int |
||||
|
/** Returns the difference of this value and `x`. */ |
||||
|
def -(x: Long): Long |
||||
|
/** Returns the difference of this value and `x`. */ |
||||
|
def -(x: Float): Float |
||||
|
/** Returns the difference of this value and `x`. */ |
||||
|
def -(x: Double): Double |
||||
|
|
||||
|
/** Returns the product of this value and `x`. */ |
||||
|
def *(x: Byte): Int |
||||
|
/** Returns the product of this value and `x`. */ |
||||
|
def *(x: Short): Int |
||||
|
/** Returns the product of this value and `x`. */ |
||||
|
def *(x: Char): Int |
||||
|
/** Returns the product of this value and `x`. */ |
||||
|
def *(x: Int): Int |
||||
|
/** Returns the product of this value and `x`. */ |
||||
|
def *(x: Long): Long |
||||
|
/** Returns the product of this value and `x`. */ |
||||
|
def *(x: Float): Float |
||||
|
/** Returns the product of this value and `x`. */ |
||||
|
def *(x: Double): Double |
||||
|
|
||||
|
/** Returns the quotient of this value and `x`. */ |
||||
|
def /(x: Byte): Int |
||||
|
/** Returns the quotient of this value and `x`. */ |
||||
|
def /(x: Short): Int |
||||
|
/** Returns the quotient of this value and `x`. */ |
||||
|
def /(x: Char): Int |
||||
|
/** Returns the quotient of this value and `x`. */ |
||||
|
def /(x: Int): Int |
||||
|
/** Returns the quotient of this value and `x`. */ |
||||
|
def /(x: Long): Long |
||||
|
/** Returns the quotient of this value and `x`. */ |
||||
|
def /(x: Float): Float |
||||
|
/** Returns the quotient of this value and `x`. */ |
||||
|
def /(x: Double): Double |
||||
|
|
||||
|
/** Returns the remainder of the division of this value by `x`. */ |
||||
|
def %(x: Byte): Int |
||||
|
/** Returns the remainder of the division of this value by `x`. */ |
||||
|
def %(x: Short): Int |
||||
|
/** Returns the remainder of the division of this value by `x`. */ |
||||
|
def %(x: Char): Int |
||||
|
/** Returns the remainder of the division of this value by `x`. */ |
||||
|
def %(x: Int): Int |
||||
|
/** Returns the remainder of the division of this value by `x`. */ |
||||
|
def %(x: Long): Long |
||||
|
/** Returns the remainder of the division of this value by `x`. */ |
||||
|
def %(x: Float): Float |
||||
|
/** Returns the remainder of the division of this value by `x`. */ |
||||
|
def %(x: Double): Double |
||||
|
|
||||
|
// Provide a more specific return type for Scaladoc |
||||
|
override def getClass(): Class[Int] = ??? |
||||
|
} |
||||
|
|
||||
|
object Int extends AnyValCompanion { |
||||
|
/** The smallest value representable as an Int. */ |
||||
|
final val MinValue = java.lang.Integer.MIN_VALUE |
||||
|
|
||||
|
/** The largest value representable as an Int. */ |
||||
|
final val MaxValue = java.lang.Integer.MAX_VALUE |
||||
|
|
||||
|
/** Transform a value type into a boxed reference type. |
||||
|
* |
||||
|
* Runtime implementation determined by `scala.runtime.BoxesRunTime.boxToInteger`. See [[https://github.com/scala/scala src/library/scala/runtime/BoxesRunTime.java]]. |
||||
|
* |
||||
|
* @param x the Int to be boxed |
||||
|
* @return a java.lang.Integer offering `x` as its underlying value. |
||||
|
*/ |
||||
|
def box(x: Int): java.lang.Integer = ??? |
||||
|
|
||||
|
/** Transform a boxed type into a value type. Note that this |
||||
|
* method is not typesafe: it accepts any Object, but will throw |
||||
|
* an exception if the argument is not a java.lang.Integer. |
||||
|
* |
||||
|
* Runtime implementation determined by `scala.runtime.BoxesRunTime.unboxToInt`. See [[https://github.com/scala/scala src/library/scala/runtime/BoxesRunTime.java]]. |
||||
|
* |
||||
|
* @param x the java.lang.Integer to be unboxed. |
||||
|
* @throws ClassCastException if the argument is not a java.lang.Integer |
||||
|
* @return the Int resulting from calling intValue() on `x` |
||||
|
*/ |
||||
|
def unbox(x: java.lang.Object): Int = ??? |
||||
|
|
||||
|
/** The String representation of the scala.Int companion object. */ |
||||
|
override def toString = "object scala.Int" |
||||
|
/** Language mandated coercions from Int to "wider" types. */ |
||||
|
import scala.language.implicitConversions |
||||
|
@deprecated("Implicit conversion from Int to Float is dangerous because it loses precision. Write `.toFloat` instead.", "2.13.1") |
||||
|
implicit def int2float(x: Int): Float = x.toFloat |
||||
|
implicit def int2long(x: Int): Long = x.toLong |
||||
|
implicit def int2double(x: Int): Double = x.toDouble |
||||
|
} |
||||
|
|
@ -0,0 +1,581 @@ |
|||||
|
/* |
||||
|
* Scala (https://www.scala-lang.org) |
||||
|
* |
||||
|
* Copyright EPFL and Lightbend, Inc. |
||||
|
* |
||||
|
* Licensed under Apache License 2.0 |
||||
|
* (http://www.apache.org/licenses/LICENSE-2.0). |
||||
|
* |
||||
|
* See the NOTICE file distributed with this work for |
||||
|
* additional information regarding copyright ownership. |
||||
|
*/ |
||||
|
|
||||
|
package scala |
||||
|
|
||||
|
import scala.language.implicitConversions |
||||
|
|
||||
|
import scala.collection.{mutable, immutable, ArrayOps, StringOps}, immutable.WrappedString |
||||
|
import scala.annotation.{elidable, implicitNotFound}, elidable.ASSERTION |
||||
|
import scala.annotation.meta.{ companionClass, companionMethod } |
||||
|
|
||||
|
/** The `Predef` object provides definitions that are accessible in all Scala |
||||
|
* compilation units without explicit qualification. |
||||
|
* |
||||
|
* === Commonly Used Types === |
||||
|
* Predef provides type aliases for types which are commonly used, such as |
||||
|
* the immutable collection types [[scala.collection.immutable.Map]], |
||||
|
* [[scala.collection.immutable.Set]], and the [[scala.collection.immutable.List]] |
||||
|
* constructors ([[scala.collection.immutable.::]] and |
||||
|
* [[scala.collection.immutable.Nil]]). |
||||
|
* |
||||
|
* === Console Output === |
||||
|
* For basic console output, `Predef` provides convenience methods [[print(x:Any* print]] and [[println(x:Any* println]], |
||||
|
* which are aliases of the methods in the object [[scala.Console]]. |
||||
|
* |
||||
|
* === Assertions === |
||||
|
* A set of `assert` functions are provided for use as a way to document |
||||
|
* and dynamically check invariants in code. Invocations of `assert` can be elided |
||||
|
* at compile time by providing the command line option `-Xdisable-assertions`, |
||||
|
* which raises `-Xelide-below` above `elidable.ASSERTION`, to the `scalac` command. |
||||
|
* |
||||
|
* Variants of `assert` intended for use with static analysis tools are also |
||||
|
* provided: `assume`, `require` and `ensuring`. `require` and `ensuring` are |
||||
|
* intended for use as a means of design-by-contract style specification |
||||
|
* of pre- and post-conditions on functions, with the intention that these |
||||
|
* specifications could be consumed by a static analysis tool. For instance, |
||||
|
* |
||||
|
* {{{ |
||||
|
* def addNaturals(nats: List[Int]): Int = { |
||||
|
* require(nats forall (_ >= 0), "List contains negative numbers") |
||||
|
* nats.foldLeft(0)(_ + _) |
||||
|
* } ensuring(_ >= 0) |
||||
|
* }}} |
||||
|
* |
||||
|
* The declaration of `addNaturals` states that the list of integers passed should |
||||
|
* only contain natural numbers (i.e. non-negative), and that the result returned |
||||
|
* will also be natural. `require` is distinct from `assert` in that if the |
||||
|
* condition fails, then the caller of the function is to blame rather than a |
||||
|
* logical error having been made within `addNaturals` itself. `ensuring` is a |
||||
|
* form of `assert` that declares the guarantee the function is providing with |
||||
|
* regards to its return value. |
||||
|
* |
||||
|
* === Implicit Conversions === |
||||
|
* A number of commonly applied implicit conversions are also defined here, and |
||||
|
* in the parent type [[scala.LowPriorityImplicits]]. Implicit conversions |
||||
|
* are provided for the "widening" of numeric values, for instance, converting a |
||||
|
* Short value to a Long value as required, and to add additional higher-order |
||||
|
* functions to Array values. These are described in more detail in the documentation of [[scala.Array]]. |
||||
|
* |
||||
|
* @groupname utilities Utility Methods |
||||
|
* @groupprio utilities 10 |
||||
|
* |
||||
|
* @groupname assertions Assertions |
||||
|
* @groupprio assertions 20 |
||||
|
* @groupdesc assertions These methods support program verification and runtime correctness. |
||||
|
* |
||||
|
* @groupname console-output Console Output |
||||
|
* @groupprio console-output 30 |
||||
|
* @groupdesc console-output These methods provide output via the console. |
||||
|
* |
||||
|
* @groupname aliases Aliases |
||||
|
* @groupprio aliases 50 |
||||
|
* @groupdesc aliases These aliases bring selected immutable types into scope without any imports. |
||||
|
* |
||||
|
* @groupname conversions-string String Conversions |
||||
|
* @groupprio conversions-string 60 |
||||
|
* @groupdesc conversions-string Conversions from String to StringOps or WrappedString. |
||||
|
* |
||||
|
* @groupname implicit-classes-any Implicit Classes |
||||
|
* @groupprio implicit-classes-any 70 |
||||
|
* @groupdesc implicit-classes-any These implicit classes add useful extension methods to every type. |
||||
|
* |
||||
|
* @groupname implicit-classes-char CharSequence Conversions |
||||
|
* @groupprio implicit-classes-char 80 |
||||
|
* @groupdesc implicit-classes-char These implicit classes add CharSequence methods to Array[Char] and IndexedSeq[Char] instances. |
||||
|
* |
||||
|
* @groupname conversions-java-to-anyval Java to Scala |
||||
|
* @groupprio conversions-java-to-anyval 90 |
||||
|
* @groupdesc conversions-java-to-anyval Implicit conversion from Java primitive wrapper types to Scala equivalents. |
||||
|
* |
||||
|
* @groupname conversions-anyval-to-java Scala to Java |
||||
|
* @groupprio conversions-anyval-to-java 100 |
||||
|
* @groupdesc conversions-anyval-to-java Implicit conversion from Scala AnyVals to Java primitive wrapper types equivalents. |
||||
|
* |
||||
|
* @groupname conversions-array-to-wrapped-array Array to ArraySeq |
||||
|
* @groupprio conversions-array-to-wrapped-array 110 |
||||
|
* @groupdesc conversions-array-to-wrapped-array Conversions from Arrays to ArraySeqs. |
||||
|
*/ |
||||
|
object Predef extends LowPriorityImplicits { |
||||
|
/** |
||||
|
* Retrieve the runtime representation of a class type. `classOf[T]` is equivalent to |
||||
|
* the class literal `T.class` in Java. |
||||
|
* |
||||
|
* @example {{{ |
||||
|
* val listClass = classOf[List[_]] |
||||
|
* // listClass is java.lang.Class[List[_]] = class scala.collection.immutable.List |
||||
|
* |
||||
|
* val mapIntString = classOf[Map[Int,String]] |
||||
|
* // mapIntString is java.lang.Class[Map[Int,String]] = interface scala.collection.immutable.Map |
||||
|
* }}} |
||||
|
* |
||||
|
* @return The runtime [[Class]] representation of type `T`. |
||||
|
* @group utilities |
||||
|
*/ |
||||
|
def classOf[T]: Class[T] = null // This is a stub method. The actual implementation is filled in by the compiler. |
||||
|
|
||||
|
/** |
||||
|
* Retrieve the single value of a type with a unique inhabitant. |
||||
|
* |
||||
|
* @example {{{ |
||||
|
* object Foo |
||||
|
* val foo = valueOf[Foo.type] |
||||
|
* // foo is Foo.type = Foo |
||||
|
* |
||||
|
* val bar = valueOf[23] |
||||
|
* // bar is 23.type = 23 |
||||
|
* }}} |
||||
|
* @group utilities |
||||
|
*/ |
||||
|
@inline def valueOf[T](implicit vt: ValueOf[T]): T = vt.value |
||||
|
|
||||
|
/** The `String` type in Scala has all the methods of the underlying |
||||
|
* `java.lang.String`, of which it is just an alias. |
||||
|
* (See the documentation corresponding to your Java version, |
||||
|
* for example [[http://docs.oracle.com/javase/8/docs/api/java/lang/String.html]].) |
||||
|
* In addition, extension methods in [[scala.collection.StringOps]] |
||||
|
* are added implicitly through the conversion [[augmentString]]. |
||||
|
* @group aliases |
||||
|
*/ |
||||
|
type String = java.lang.String |
||||
|
/** @group aliases */ |
||||
|
type Class[T] = java.lang.Class[T] |
||||
|
|
||||
|
// miscellaneous ----------------------------------------------------- |
||||
|
scala.`package` // to force scala package object to be seen. |
||||
|
scala.collection.immutable.List // to force Nil, :: to be seen. |
||||
|
|
||||
|
/** @group aliases */ |
||||
|
type Function[-A, +B] = Function1[A, B] |
||||
|
|
||||
|
/** @group aliases */ |
||||
|
type Map[K, +V] = immutable.Map[K, V] |
||||
|
/** @group aliases */ |
||||
|
type Set[A] = immutable.Set[A] |
||||
|
/** @group aliases */ |
||||
|
val Map = immutable.Map |
||||
|
/** @group aliases */ |
||||
|
val Set = immutable.Set |
||||
|
|
||||
|
/** |
||||
|
* Allows destructuring tuples with the same syntax as constructing them. |
||||
|
* |
||||
|
* @example {{{ |
||||
|
* val tup = "foobar" -> 3 |
||||
|
* |
||||
|
* val c = tup match { |
||||
|
* case str -> i => str.charAt(i) |
||||
|
* } |
||||
|
* }}} |
||||
|
* @group aliases |
||||
|
*/ |
||||
|
val -> = Tuple2 |
||||
|
|
||||
|
// Manifest types, companions, and incantations for summoning |
||||
|
// TODO undeprecated until Scala reflection becomes non-experimental |
||||
|
// @deprecated("this notion doesn't have a corresponding concept in 2.10, because scala.reflect.runtime.universe.TypeTag can capture arbitrary types. Use type tags instead of manifests, and there will be no need in opt manifests.", "2.10.0") |
||||
|
type OptManifest[T] = scala.reflect.OptManifest[T] |
||||
|
@implicitNotFound(msg = "No Manifest available for ${T}.") |
||||
|
// TODO undeprecated until Scala reflection becomes non-experimental |
||||
|
// @deprecated("use `scala.reflect.ClassTag` (to capture erasures) or scala.reflect.runtime.universe.TypeTag (to capture types) or both instead", "2.10.0") |
||||
|
type Manifest[T] = scala.reflect.Manifest[T] |
||||
|
// TODO undeprecated until Scala reflection becomes non-experimental |
||||
|
// @deprecated("use `scala.reflect.ClassTag` (to capture erasures) or scala.reflect.runtime.universe.TypeTag (to capture types) or both instead", "2.10.0") |
||||
|
val Manifest = scala.reflect.Manifest |
||||
|
// TODO undeprecated until Scala reflection becomes non-experimental |
||||
|
// @deprecated("this notion doesn't have a corresponding concept in 2.10, because scala.reflect.runtime.universe.TypeTag can capture arbitrary types. Use type tags instead of manifests, and there will be no need in opt manifests.", "2.10.0") |
||||
|
val NoManifest = scala.reflect.NoManifest |
||||
|
|
||||
|
// TODO undeprecated until Scala reflection becomes non-experimental |
||||
|
// @deprecated("use scala.reflect.classTag[T] and scala.reflect.runtime.universe.typeTag[T] instead", "2.10.0") |
||||
|
def manifest[T](implicit m: Manifest[T]): Manifest[T] = m |
||||
|
// TODO undeprecated until Scala reflection becomes non-experimental |
||||
|
// @deprecated("this notion doesn't have a corresponding concept in 2.10, because scala.reflect.runtime.universe.TypeTag can capture arbitrary types. Use type tags instead of manifests, and there will be no need in opt manifests.", "2.10.0") |
||||
|
def optManifest[T](implicit m: OptManifest[T]): OptManifest[T] = m |
||||
|
|
||||
|
// Minor variations on identity functions |
||||
|
|
||||
|
/** |
||||
|
* A method that returns its input value. |
||||
|
* @tparam A type of the input value x. |
||||
|
* @param x the value of type `A` to be returned. |
||||
|
* @return the value `x`. |
||||
|
* @group utilities */ |
||||
|
@inline def identity[A](x: A): A = x // see `$conforms` for the implicit version |
||||
|
|
||||
|
/** Summon an implicit value of type `T`. Usually, the argument is not passed explicitly. |
||||
|
* |
||||
|
* @tparam T the type of the value to be summoned |
||||
|
* @return the implicit value of type `T` |
||||
|
* @group utilities |
||||
|
*/ |
||||
|
@inline def implicitly[T](implicit e: T): T = e // TODO: when dependent method types are on by default, give this result type `e.type`, so that inliner has better chance of knowing which method to inline in calls like `implicitly[MatchingStrategy[Option]].zero` |
||||
|
|
||||
|
/** Used to mark code blocks as being expressions, instead of being taken as part of anonymous classes and the like. |
||||
|
* This is just a different name for [[identity]]. |
||||
|
* |
||||
|
* @example Separating code blocks from `new`: |
||||
|
* {{{ |
||||
|
* val x = new AnyRef |
||||
|
* { |
||||
|
* val y = ... |
||||
|
* println(y) |
||||
|
* } |
||||
|
* // the { ... } block is seen as the body of an anonymous class |
||||
|
* |
||||
|
* val x = new AnyRef |
||||
|
* |
||||
|
* { |
||||
|
* val y = ... |
||||
|
* println(y) |
||||
|
* } |
||||
|
* // an empty line is a brittle "fix" |
||||
|
* |
||||
|
* val x = new AnyRef |
||||
|
* locally { |
||||
|
* val y = ... |
||||
|
* println(y) |
||||
|
* } |
||||
|
* // locally guards the block and helps communicate intent |
||||
|
* }}} |
||||
|
* @group utilities |
||||
|
*/ |
||||
|
@inline def locally[T](@deprecatedName("x") x: T): T = x |
||||
|
|
||||
|
// assertions --------------------------------------------------------- |
||||
|
|
||||
|
/** Tests an expression, throwing an `AssertionError` if false. |
||||
|
* Calls to this method will not be generated if `-Xelide-below` |
||||
|
* is greater than `ASSERTION`. |
||||
|
* |
||||
|
* @see [[scala.annotation.elidable elidable]] |
||||
|
* @param assertion the expression to test |
||||
|
* @group assertions |
||||
|
*/ |
||||
|
@elidable(ASSERTION) |
||||
|
def assert(assertion: Boolean): Unit = { |
||||
|
if (!assertion) |
||||
|
throw new java.lang.AssertionError("assertion failed") |
||||
|
} |
||||
|
|
||||
|
/** Tests an expression, throwing an `AssertionError` if false. |
||||
|
* Calls to this method will not be generated if `-Xelide-below` |
||||
|
* is greater than `ASSERTION`. |
||||
|
* |
||||
|
* @see [[scala.annotation.elidable elidable]] |
||||
|
* @param assertion the expression to test |
||||
|
* @param message a String to include in the failure message |
||||
|
* @group assertions |
||||
|
*/ |
||||
|
@elidable(ASSERTION) @inline |
||||
|
final def assert(assertion: Boolean, message: => Any): Unit = { |
||||
|
if (!assertion) |
||||
|
throw new java.lang.AssertionError("assertion failed: "+ message) |
||||
|
} |
||||
|
|
||||
|
/** Tests an expression, throwing an `AssertionError` if false. |
||||
|
* This method differs from assert only in the intent expressed: |
||||
|
* assert contains a predicate which needs to be proven, while |
||||
|
* assume contains an axiom for a static checker. Calls to this method |
||||
|
* will not be generated if `-Xelide-below` is greater than `ASSERTION`. |
||||
|
* |
||||
|
* @see [[scala.annotation.elidable elidable]] |
||||
|
* @param assumption the expression to test |
||||
|
* @group assertions |
||||
|
*/ |
||||
|
@elidable(ASSERTION) |
||||
|
def assume(assumption: Boolean): Unit = { |
||||
|
if (!assumption) |
||||
|
throw new java.lang.AssertionError("assumption failed") |
||||
|
} |
||||
|
|
||||
|
/** Tests an expression, throwing an `AssertionError` if false. |
||||
|
* This method differs from assert only in the intent expressed: |
||||
|
* assert contains a predicate which needs to be proven, while |
||||
|
* assume contains an axiom for a static checker. Calls to this method |
||||
|
* will not be generated if `-Xelide-below` is greater than `ASSERTION`. |
||||
|
* |
||||
|
* @see [[scala.annotation.elidable elidable]] |
||||
|
* @param assumption the expression to test |
||||
|
* @param message a String to include in the failure message |
||||
|
* @group assertions |
||||
|
*/ |
||||
|
@elidable(ASSERTION) @inline |
||||
|
final def assume(assumption: Boolean, message: => Any): Unit = { |
||||
|
if (!assumption) |
||||
|
throw new java.lang.AssertionError("assumption failed: "+ message) |
||||
|
} |
||||
|
|
||||
|
/** Tests an expression, throwing an `IllegalArgumentException` if false. |
||||
|
* This method is similar to `assert`, but blames the caller of the method |
||||
|
* for violating the condition. |
||||
|
* |
||||
|
* @param requirement the expression to test |
||||
|
* @group assertions |
||||
|
*/ |
||||
|
def require(requirement: Boolean): Unit = { |
||||
|
if (!requirement) |
||||
|
throw new IllegalArgumentException("requirement failed") |
||||
|
} |
||||
|
|
||||
|
/** Tests an expression, throwing an `IllegalArgumentException` if false. |
||||
|
* This method is similar to `assert`, but blames the caller of the method |
||||
|
* for violating the condition. |
||||
|
* |
||||
|
* @param requirement the expression to test |
||||
|
* @param message a String to include in the failure message |
||||
|
* @group assertions |
||||
|
*/ |
||||
|
@inline final def require(requirement: Boolean, message: => Any): Unit = { |
||||
|
if (!requirement) |
||||
|
throw new IllegalArgumentException("requirement failed: "+ message) |
||||
|
} |
||||
|
|
||||
|
/** `???` can be used for marking methods that remain to be implemented. |
||||
|
* @throws NotImplementedError when `???` is invoked. |
||||
|
* @group utilities |
||||
|
*/ |
||||
|
def ??? : Nothing = throw new NotImplementedError |
||||
|
|
||||
|
// implicit classes ----------------------------------------------------- |
||||
|
|
||||
|
/** @group implicit-classes-any */ |
||||
|
implicit final class ArrowAssoc[A](private val self: A) extends AnyVal { |
||||
|
@inline def -> [B](y: B): (A, B) = (self, y) |
||||
|
@deprecated("Use `->` instead. If you still wish to display it as one character, consider using a font with programming ligatures such as Fira Code.", "2.13.0") |
||||
|
def →[B](y: B): (A, B) = ->(y) |
||||
|
} |
||||
|
|
||||
|
/** @group implicit-classes-any */ |
||||
|
implicit final class Ensuring[A](private val self: A) extends AnyVal { |
||||
|
def ensuring(cond: Boolean): A = { assert(cond); self } |
||||
|
def ensuring(cond: Boolean, msg: => Any): A = { assert(cond, msg); self } |
||||
|
def ensuring(cond: A => Boolean): A = { assert(cond(self)); self } |
||||
|
def ensuring(cond: A => Boolean, msg: => Any): A = { assert(cond(self), msg); self } |
||||
|
} |
||||
|
|
||||
|
/** @group implicit-classes-any */ |
||||
|
implicit final class StringFormat[A](private val self: A) extends AnyVal { |
||||
|
/** Returns string formatted according to given `format` string. |
||||
|
* Format strings are as for `String.format` |
||||
|
* (@see java.lang.String.format). |
||||
|
*/ |
||||
|
@inline def formatted(fmtstr: String): String = fmtstr format self |
||||
|
} |
||||
|
|
||||
|
/** Injects String concatenation operator `+` to any classes. |
||||
|
* @group implicit-classes-any |
||||
|
*/ |
||||
|
@(deprecated @companionMethod)("Implicit injection of + is deprecated. Convert to String to call +", "2.13.0") |
||||
|
@(deprecated @companionClass)("Implicit injection of + is deprecated. Convert to String to call +", "2.13.0") // for Scaladoc |
||||
|
// scala/bug#8229 retaining the pre 2.11 name for source compatibility in shadowing this implicit |
||||
|
implicit final class any2stringadd[A](private val self: A) extends AnyVal { |
||||
|
def +(other: String): String = String.valueOf(self) + other |
||||
|
} |
||||
|
|
||||
|
implicit final class SeqCharSequence(sequenceOfChars: scala.collection.IndexedSeq[Char]) extends CharSequence { |
||||
|
def length: Int = sequenceOfChars.length |
||||
|
def charAt(index: Int): Char = sequenceOfChars(index) |
||||
|
def subSequence(start: Int, end: Int): CharSequence = new SeqCharSequence(sequenceOfChars.slice(start, end)) |
||||
|
override def toString = sequenceOfChars.mkString |
||||
|
} |
||||
|
|
||||
|
/** @group implicit-classes-char */ |
||||
|
implicit final class ArrayCharSequence(arrayOfChars: Array[Char]) extends CharSequence { |
||||
|
def length: Int = arrayOfChars.length |
||||
|
def charAt(index: Int): Char = arrayOfChars(index) |
||||
|
def subSequence(start: Int, end: Int): CharSequence = new runtime.ArrayCharSequence(arrayOfChars, start, end) |
||||
|
override def toString = arrayOfChars.mkString |
||||
|
} |
||||
|
|
||||
|
/** @group conversions-string */ |
||||
|
@inline implicit def augmentString(x: String): StringOps = new StringOps(x) |
||||
|
|
||||
|
// printing ----------------------------------------------------------- |
||||
|
|
||||
|
/** Prints an object to `out` using its `toString` method. |
||||
|
* |
||||
|
* @param x the object to print; may be null. |
||||
|
* @group console-output |
||||
|
*/ |
||||
|
def print(x: Any): Unit = Console.print(x) |
||||
|
|
||||
|
/** Prints a newline character on the default output. |
||||
|
* @group console-output |
||||
|
*/ |
||||
|
def println(): Unit = Console.println() |
||||
|
|
||||
|
/** Prints out an object to the default output, followed by a newline character. |
||||
|
* |
||||
|
* @param x the object to print. |
||||
|
* @group console-output |
||||
|
*/ |
||||
|
def println(x: Any): Unit = Console.println(x) |
||||
|
|
||||
|
/** Prints its arguments as a formatted string to the default output, |
||||
|
* based on a string pattern (in a fashion similar to printf in C). |
||||
|
* |
||||
|
* The interpretation of the formatting patterns is described in |
||||
|
* [[java.util.Formatter]]. |
||||
|
* |
||||
|
* Consider using the [[scala.StringContext.f f interpolator]] as more type safe and idiomatic. |
||||
|
* |
||||
|
* @param text the pattern for formatting the arguments. |
||||
|
* @param xs the arguments used to instantiate the pattern. |
||||
|
* @throws java.lang.IllegalArgumentException if there was a problem with the format string or arguments |
||||
|
* |
||||
|
* @see [[scala.StringContext.f StringContext.f]] |
||||
|
* @group console-output |
||||
|
*/ |
||||
|
def printf(text: String, xs: Any*): Unit = Console.print(text.format(xs: _*)) |
||||
|
|
||||
|
// views -------------------------------------------------------------- |
||||
|
|
||||
|
// these two are morally deprecated but the @deprecated annotation has been moved to the extension method themselves, |
||||
|
// in order to provide a more specific deprecation method. |
||||
|
implicit def tuple2ToZippedOps[T1, T2](x: (T1, T2)): runtime.Tuple2Zipped.Ops[T1, T2] = new runtime.Tuple2Zipped.Ops(x) |
||||
|
implicit def tuple3ToZippedOps[T1, T2, T3](x: (T1, T2, T3)): runtime.Tuple3Zipped.Ops[T1, T2, T3] = new runtime.Tuple3Zipped.Ops(x) |
||||
|
|
||||
|
// Not specialized anymore since 2.13 but we still need separate methods |
||||
|
// to avoid https://github.com/scala/bug/issues/10746 |
||||
|
// TODO: should not need @inline. add heuristic to inline factories for value classes. |
||||
|
@inline implicit def genericArrayOps[T](xs: Array[T]): ArrayOps[T] = new ArrayOps(xs) |
||||
|
@inline implicit def booleanArrayOps(xs: Array[Boolean]): ArrayOps[Boolean] = new ArrayOps(xs) |
||||
|
@inline implicit def byteArrayOps(xs: Array[Byte]): ArrayOps[Byte] = new ArrayOps(xs) |
||||
|
@inline implicit def charArrayOps(xs: Array[Char]): ArrayOps[Char] = new ArrayOps(xs) |
||||
|
@inline implicit def doubleArrayOps(xs: Array[Double]): ArrayOps[Double] = new ArrayOps(xs) |
||||
|
@inline implicit def floatArrayOps(xs: Array[Float]): ArrayOps[Float] = new ArrayOps(xs) |
||||
|
@inline implicit def intArrayOps(xs: Array[Int]): ArrayOps[Int] = new ArrayOps(xs) |
||||
|
@inline implicit def longArrayOps(xs: Array[Long]): ArrayOps[Long] = new ArrayOps(xs) |
||||
|
@inline implicit def refArrayOps[T <: AnyRef](xs: Array[T]): ArrayOps[T] = new ArrayOps(xs) |
||||
|
@inline implicit def shortArrayOps(xs: Array[Short]): ArrayOps[Short] = new ArrayOps(xs) |
||||
|
@inline implicit def unitArrayOps(xs: Array[Unit]): ArrayOps[Unit] = new ArrayOps(xs) |
||||
|
|
||||
|
// "Autoboxing" and "Autounboxing" --------------------------------------------------- |
||||
|
|
||||
|
/** @group conversions-anyval-to-java */ |
||||
|
implicit def byte2Byte(x: Byte): java.lang.Byte = x.asInstanceOf[java.lang.Byte] |
||||
|
/** @group conversions-anyval-to-java */ |
||||
|
implicit def short2Short(x: Short): java.lang.Short = x.asInstanceOf[java.lang.Short] |
||||
|
/** @group conversions-anyval-to-java */ |
||||
|
implicit def char2Character(x: Char): java.lang.Character = x.asInstanceOf[java.lang.Character] |
||||
|
/** @group conversions-anyval-to-java */ |
||||
|
implicit def int2Integer(x: Int): java.lang.Integer = x.asInstanceOf[java.lang.Integer] |
||||
|
/** @group conversions-anyval-to-java */ |
||||
|
implicit def long2Long(x: Long): java.lang.Long = x.asInstanceOf[java.lang.Long] |
||||
|
/** @group conversions-anyval-to-java */ |
||||
|
implicit def float2Float(x: Float): java.lang.Float = x.asInstanceOf[java.lang.Float] |
||||
|
/** @group conversions-anyval-to-java */ |
||||
|
implicit def double2Double(x: Double): java.lang.Double = x.asInstanceOf[java.lang.Double] |
||||
|
/** @group conversions-anyval-to-java */ |
||||
|
implicit def boolean2Boolean(x: Boolean): java.lang.Boolean = x.asInstanceOf[java.lang.Boolean] |
||||
|
|
||||
|
/** @group conversions-java-to-anyval */ |
||||
|
implicit def Byte2byte(x: java.lang.Byte): Byte = x.asInstanceOf[Byte] |
||||
|
/** @group conversions-java-to-anyval */ |
||||
|
implicit def Short2short(x: java.lang.Short): Short = x.asInstanceOf[Short] |
||||
|
/** @group conversions-java-to-anyval */ |
||||
|
implicit def Character2char(x: java.lang.Character): Char = x.asInstanceOf[Char] |
||||
|
/** @group conversions-java-to-anyval */ |
||||
|
implicit def Integer2int(x: java.lang.Integer): Int = x.asInstanceOf[Int] |
||||
|
/** @group conversions-java-to-anyval */ |
||||
|
implicit def Long2long(x: java.lang.Long): Long = x.asInstanceOf[Long] |
||||
|
/** @group conversions-java-to-anyval */ |
||||
|
implicit def Float2float(x: java.lang.Float): Float = x.asInstanceOf[Float] |
||||
|
/** @group conversions-java-to-anyval */ |
||||
|
implicit def Double2double(x: java.lang.Double): Double = x.asInstanceOf[Double] |
||||
|
/** @group conversions-java-to-anyval */ |
||||
|
implicit def Boolean2boolean(x: java.lang.Boolean): Boolean = x.asInstanceOf[Boolean] |
||||
|
|
||||
|
/** An implicit of type `A => A` is available for all `A` because it can always |
||||
|
* be implemented using the identity function. This also means that an |
||||
|
* implicit of type `A => B` is always available when `A <: B`, because |
||||
|
* `(A => A) <: (A => B)`. |
||||
|
*/ |
||||
|
// $ to avoid accidental shadowing (e.g. scala/bug#7788) |
||||
|
implicit def $conforms[A]: A => A = <:<.refl |
||||
|
} |
||||
|
|
||||
|
/** The `LowPriorityImplicits` class provides implicit values that |
||||
|
* are valid in all Scala compilation units without explicit qualification, |
||||
|
* but that are partially overridden by higher-priority conversions in object |
||||
|
* `Predef`. |
||||
|
*/ |
||||
|
// scala/bug#7335 Parents of Predef are defined in the same compilation unit to avoid |
||||
|
// cyclic reference errors compiling the standard library *without* a previously |
||||
|
// compiled copy on the classpath. |
||||
|
private[scala] abstract class LowPriorityImplicits extends LowPriorityImplicits2 { |
||||
|
import mutable.ArraySeq |
||||
|
|
||||
|
/** We prefer the java.lang.* boxed types to these wrappers in |
||||
|
* any potential conflicts. Conflicts do exist because the wrappers |
||||
|
* need to implement ScalaNumber in order to have a symmetric equals |
||||
|
* method, but that implies implementing java.lang.Number as well. |
||||
|
* |
||||
|
* Note - these are inlined because they are value classes, but |
||||
|
* the call to xxxWrapper is not eliminated even though it does nothing. |
||||
|
* Even inlined, every call site does a no-op retrieval of Predef's MODULE$ |
||||
|
* because maybe loading Predef has side effects! |
||||
|
*/ |
||||
|
@inline implicit def byteWrapper(x: Byte): runtime.RichByte = new runtime.RichByte(x) |
||||
|
@inline implicit def shortWrapper(x: Short): runtime.RichShort = new runtime.RichShort(x) |
||||
|
@inline implicit def intWrapper(x: Int): runtime.RichInt = new runtime.RichInt(x) |
||||
|
@inline implicit def charWrapper(c: Char): runtime.RichChar = new runtime.RichChar(c) |
||||
|
@inline implicit def longWrapper(x: Long): runtime.RichLong = new runtime.RichLong(x) |
||||
|
@inline implicit def floatWrapper(x: Float): runtime.RichFloat = new runtime.RichFloat(x) |
||||
|
@inline implicit def doubleWrapper(x: Double): runtime.RichDouble = new runtime.RichDouble(x) |
||||
|
@inline implicit def booleanWrapper(x: Boolean): runtime.RichBoolean = new runtime.RichBoolean(x) |
||||
|
|
||||
|
/** @group conversions-array-to-wrapped-array */ |
||||
|
implicit def genericWrapArray[T](xs: Array[T]): ArraySeq[T] = |
||||
|
if (xs eq null) null |
||||
|
else ArraySeq.make(xs) |
||||
|
|
||||
|
// Since the JVM thinks arrays are covariant, one 0-length Array[AnyRef] |
||||
|
// is as good as another for all T <: AnyRef. Instead of creating 100,000,000 |
||||
|
// unique ones by way of this implicit, let's share one. |
||||
|
/** @group conversions-array-to-wrapped-array */ |
||||
|
implicit def wrapRefArray[T <: AnyRef](xs: Array[T]): ArraySeq.ofRef[T] = { |
||||
|
if (xs eq null) null |
||||
|
else if (xs.length == 0) ArraySeq.empty[AnyRef].asInstanceOf[ArraySeq.ofRef[T]] |
||||
|
else new ArraySeq.ofRef[T](xs) |
||||
|
} |
||||
|
|
||||
|
/** @group conversions-array-to-wrapped-array */ |
||||
|
implicit def wrapIntArray(xs: Array[Int]): ArraySeq.ofInt = if (xs ne null) new ArraySeq.ofInt(xs) else null |
||||
|
/** @group conversions-array-to-wrapped-array */ |
||||
|
implicit def wrapDoubleArray(xs: Array[Double]): ArraySeq.ofDouble = if (xs ne null) new ArraySeq.ofDouble(xs) else null |
||||
|
/** @group conversions-array-to-wrapped-array */ |
||||
|
implicit def wrapLongArray(xs: Array[Long]): ArraySeq.ofLong = if (xs ne null) new ArraySeq.ofLong(xs) else null |
||||
|
/** @group conversions-array-to-wrapped-array */ |
||||
|
implicit def wrapFloatArray(xs: Array[Float]): ArraySeq.ofFloat = if (xs ne null) new ArraySeq.ofFloat(xs) else null |
||||
|
/** @group conversions-array-to-wrapped-array */ |
||||
|
implicit def wrapCharArray(xs: Array[Char]): ArraySeq.ofChar = if (xs ne null) new ArraySeq.ofChar(xs) else null |
||||
|
/** @group conversions-array-to-wrapped-array */ |
||||
|
implicit def wrapByteArray(xs: Array[Byte]): ArraySeq.ofByte = if (xs ne null) new ArraySeq.ofByte(xs) else null |
||||
|
/** @group conversions-array-to-wrapped-array */ |
||||
|
implicit def wrapShortArray(xs: Array[Short]): ArraySeq.ofShort = if (xs ne null) new ArraySeq.ofShort(xs) else null |
||||
|
/** @group conversions-array-to-wrapped-array */ |
||||
|
implicit def wrapBooleanArray(xs: Array[Boolean]): ArraySeq.ofBoolean = if (xs ne null) new ArraySeq.ofBoolean(xs) else null |
||||
|
/** @group conversions-array-to-wrapped-array */ |
||||
|
implicit def wrapUnitArray(xs: Array[Unit]): ArraySeq.ofUnit = if (xs ne null) new ArraySeq.ofUnit(xs) else null |
||||
|
|
||||
|
/** @group conversions-string */ |
||||
|
implicit def wrapString(s: String): WrappedString = if (s ne null) new WrappedString(s) else null |
||||
|
} |
||||
|
|
||||
|
private[scala] abstract class LowPriorityImplicits2 { |
||||
|
@deprecated("Implicit conversions from Array to immutable.IndexedSeq are implemented by copying; Use the more efficient non-copying ArraySeq.unsafeWrapArray or an explicit toIndexedSeq call", "2.13.0") |
||||
|
implicit def copyArrayToImmutableIndexedSeq[T](xs: Array[T]): IndexedSeq[T] = |
||||
|
if (xs eq null) null |
||||
|
else new ArrayOps(xs).toIndexedSeq |
||||
|
} |
@ -0,0 +1,33 @@ |
|||||
|
/* |
||||
|
* Scala (https://www.scala-lang.org) |
||||
|
* |
||||
|
* Copyright EPFL and Lightbend, Inc. |
||||
|
* |
||||
|
* Licensed under Apache License 2.0 |
||||
|
* (http://www.apache.org/licenses/LICENSE-2.0). |
||||
|
* |
||||
|
* See the NOTICE file distributed with this work for |
||||
|
* additional information regarding copyright ownership. |
||||
|
*/ |
||||
|
|
||||
|
package scala.annotation |
||||
|
|
||||
|
/** An annotation to be applied to a match expression. If present, |
||||
|
* the compiler will verify that the match has been compiled to a |
||||
|
* [[http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-3.html#jvms-3.10 tableswitch or lookupswitch]] |
||||
|
* and issue a warning if it instead compiles into a series of conditional expressions. |
||||
|
* Example usage: |
||||
|
{{{ |
||||
|
val Constant = 'Q' |
||||
|
def tokenMe(ch: Char) = (ch: @switch) match { |
||||
|
case ' ' | '\t' | '\n' => 1 |
||||
|
case 'A' | 'Z' | '$' => 2 |
||||
|
case '5' | Constant => 3 // a non-literal may prevent switch generation: this would not compile |
||||
|
case _ => 4 |
||||
|
} |
||||
|
}}} |
||||
|
* |
||||
|
* Note: for pattern matches with one or two cases, the compiler generates jump instructions. |
||||
|
* Annotating such a match with `@switch` does not issue any warning. |
||||
|
*/ |
||||
|
final class switch extends scala.annotation.StaticAnnotation |
File diff suppressed because it is too large
@ -0,0 +1,130 @@ |
|||||
|
/* |
||||
|
* Scala (https://www.scala-lang.org) |
||||
|
* |
||||
|
* Copyright EPFL and Lightbend, Inc. |
||||
|
* |
||||
|
* Licensed under Apache License 2.0 |
||||
|
* (http://www.apache.org/licenses/LICENSE-2.0). |
||||
|
* |
||||
|
* See the NOTICE file distributed with this work for |
||||
|
* additional information regarding copyright ownership. |
||||
|
*/ |
||||
|
|
||||
|
package scala |
||||
|
package collection |
||||
|
|
||||
|
import scala.annotation.tailrec |
||||
|
import scala.collection.Searching.{Found, InsertionPoint, SearchResult} |
||||
|
import scala.collection.Stepper.EfficientSplit |
||||
|
import scala.math.Ordering |
||||
|
|
||||
|
/** Base trait for indexed sequences that have efficient `apply` and `length` */ |
||||
|
trait IndexedSeq[+A] extends Seq[A] |
||||
|
with IndexedSeqOps[A, IndexedSeq, IndexedSeq[A]] |
||||
|
with IterableFactoryDefaults[A, IndexedSeq] { |
||||
|
override protected[this] def stringPrefix: String = "IndexedSeq" |
||||
|
|
||||
|
override def iterableFactory: SeqFactory[IndexedSeq] = IndexedSeq |
||||
|
} |
||||
|
|
||||
|
@SerialVersionUID(3L) |
||||
|
object IndexedSeq extends SeqFactory.Delegate[IndexedSeq](immutable.IndexedSeq) |
||||
|
|
||||
|
/** Base trait for indexed Seq operations */ |
||||
|
trait IndexedSeqOps[+A, +CC[_], +C] extends Any with SeqOps[A, CC, C] { self => |
||||
|
|
||||
|
def iterator: Iterator[A] = view.iterator |
||||
|
|
||||
|
override def stepper[S <: Stepper[_]](implicit shape: StepperShape[A, S]): S with EfficientSplit = { |
||||
|
import convert.impl._ |
||||
|
val s = shape.shape match { |
||||
|
case StepperShape.IntShape => new IntIndexedSeqStepper (this.asInstanceOf[IndexedSeqOps[Int, AnyConstr, _]], 0, length) |
||||
|
case StepperShape.LongShape => new LongIndexedSeqStepper (this.asInstanceOf[IndexedSeqOps[Long, AnyConstr, _]], 0, length) |
||||
|
case StepperShape.DoubleShape => new DoubleIndexedSeqStepper(this.asInstanceOf[IndexedSeqOps[Double, AnyConstr, _]], 0, length) |
||||
|
case _ => shape.parUnbox(new AnyIndexedSeqStepper[A](this, 0, length)) |
||||
|
} |
||||
|
s.asInstanceOf[S with EfficientSplit] |
||||
|
} |
||||
|
|
||||
|
override def reverseIterator: Iterator[A] = new AbstractIterator[A] { |
||||
|
private[this] var i = self.length |
||||
|
def hasNext: Boolean = 0 < i |
||||
|
def next(): A = |
||||
|
if (0 < i) { |
||||
|
i -= 1 |
||||
|
self(i) |
||||
|
} else Iterator.empty.next() |
||||
|
} |
||||
|
|
||||
|
override def foldRight[B](z: B)(op: (A, B) => B): B = { |
||||
|
val it = reverseIterator |
||||
|
var b = z |
||||
|
while (it.hasNext) |
||||
|
b = op(it.next(), b) |
||||
|
b |
||||
|
} |
||||
|
|
||||
|
override def view: IndexedSeqView[A] = new IndexedSeqView.Id[A](this) |
||||
|
|
||||
|
@deprecated("Use .view.slice(from, until) instead of .view(from, until)", "2.13.0") |
||||
|
override def view(from: Int, until: Int): IndexedSeqView[A] = view.slice(from, until) |
||||
|
|
||||
|
override protected def reversed: Iterable[A] = new IndexedSeqView.Reverse(this) |
||||
|
|
||||
|
// Override transformation operations to use more efficient views than the default ones |
||||
|
override def prepended[B >: A](elem: B): CC[B] = iterableFactory.from(new IndexedSeqView.Prepended(elem, this)) |
||||
|
|
||||
|
override def take(n: Int): C = fromSpecific(new IndexedSeqView.Take(this, n)) |
||||
|
|
||||
|
override def takeRight(n: Int): C = fromSpecific(new IndexedSeqView.TakeRight(this, n)) |
||||
|
|
||||
|
override def drop(n: Int): C = fromSpecific(new IndexedSeqView.Drop(this, n)) |
||||
|
|
||||
|
override def dropRight(n: Int): C = fromSpecific(new IndexedSeqView.DropRight(this, n)) |
||||
|
|
||||
|
override def map[B](f: A => B): CC[B] = iterableFactory.from(new IndexedSeqView.Map(this, f)) |
||||
|
|
||||
|
override def reverse: C = fromSpecific(new IndexedSeqView.Reverse(this)) |
||||
|
|
||||
|
override def slice(from: Int, until: Int): C = fromSpecific(new IndexedSeqView.Slice(this, from, until)) |
||||
|
|
||||
|
override def head: A = apply(0) |
||||
|
|
||||
|
override def headOption: Option[A] = if (isEmpty) None else Some(head) |
||||
|
|
||||
|
override def last: A = apply(length - 1) |
||||
|
|
||||
|
// We already inherit an efficient `lastOption = if (isEmpty) None else Some(last)` |
||||
|
|
||||
|
override final def lengthCompare(len: Int): Int = Integer.compare(length, len) |
||||
|
|
||||
|
override def knownSize: Int = length |
||||
|
|
||||
|
override final def lengthCompare(that: Iterable[_]): Int = { |
||||
|
val res = that.sizeCompare(length) |
||||
|
// can't just invert the result, because `-Int.MinValue == Int.MinValue` |
||||
|
if (res == Int.MinValue) 1 else -res |
||||
|
} |
||||
|
|
||||
|
override def search[B >: A](elem: B)(implicit ord: Ordering[B]): SearchResult = |
||||
|
binarySearch(elem, 0, length)(ord) |
||||
|
|
||||
|
override def search[B >: A](elem: B, from: Int, to: Int)(implicit ord: Ordering[B]): SearchResult = |
||||
|
binarySearch(elem, from, to)(ord) |
||||
|
|
||||
|
@tailrec |
||||
|
private[this] def binarySearch[B >: A](elem: B, from: Int, to: Int) |
||||
|
(implicit ord: Ordering[B]): SearchResult = { |
||||
|
if (from < 0) binarySearch(elem, 0, to) |
||||
|
else if (to > length) binarySearch(elem, from, length) |
||||
|
else if (to <= from) InsertionPoint(from) |
||||
|
else { |
||||
|
val idx = from + (to - from - 1) / 2 |
||||
|
math.signum(ord.compare(elem, apply(idx))) match { |
||||
|
case -1 => binarySearch(elem, from, idx)(ord) |
||||
|
case 1 => binarySearch(elem, idx + 1, to)(ord) |
||||
|
case _ => Found(idx) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
File diff suppressed because it is too large
File diff suppressed because it is too large
File diff suppressed because it is too large
@ -0,0 +1,288 @@ |
|||||
|
/* |
||||
|
* Scala (https://www.scala-lang.org) |
||||
|
* |
||||
|
* Copyright EPFL and Lightbend, Inc. |
||||
|
* |
||||
|
* Licensed under Apache License 2.0 |
||||
|
* (http://www.apache.org/licenses/LICENSE-2.0). |
||||
|
* |
||||
|
* See the NOTICE file distributed with this work for |
||||
|
* additional information regarding copyright ownership. |
||||
|
*/ |
||||
|
|
||||
|
package scala |
||||
|
package collection |
||||
|
|
||||
|
import scala.annotation.tailrec |
||||
|
|
||||
|
/** Base trait for linearly accessed sequences that have efficient `head` and |
||||
|
* `tail` operations. |
||||
|
* Known subclasses: List, LazyList |
||||
|
*/ |
||||
|
trait LinearSeq[+A] extends Seq[A] |
||||
|
with LinearSeqOps[A, LinearSeq, LinearSeq[A]] |
||||
|
with IterableFactoryDefaults[A, LinearSeq] { |
||||
|
override protected[this] def stringPrefix: String = "LinearSeq" |
||||
|
|
||||
|
override def iterableFactory: SeqFactory[LinearSeq] = LinearSeq |
||||
|
} |
||||
|
|
||||
|
@SerialVersionUID(3L) |
||||
|
object LinearSeq extends SeqFactory.Delegate[LinearSeq](immutable.LinearSeq) |
||||
|
|
||||
|
/** Base trait for linear Seq operations */ |
||||
|
trait LinearSeqOps[+A, +CC[X] <: LinearSeq[X], +C <: LinearSeq[A] with LinearSeqOps[A, CC, C]] extends Any with SeqOps[A, CC, C] { |
||||
|
|
||||
|
// To be overridden in implementations: |
||||
|
def isEmpty: Boolean |
||||
|
def head: A |
||||
|
def tail: C |
||||
|
|
||||
|
override def headOption: Option[A] = |
||||
|
if (isEmpty) None else Some(head) |
||||
|
|
||||
|
def iterator: Iterator[A] = |
||||
|
if (knownSize == 0) Iterator.empty |
||||
|
else new LinearSeqIterator[A](this) |
||||
|
|
||||
|
def length: Int = { |
||||
|
var these = coll |
||||
|
var len = 0 |
||||
|
while (these.nonEmpty) { |
||||
|
len += 1 |
||||
|
these = these.tail |
||||
|
} |
||||
|
len |
||||
|
} |
||||
|
|
||||
|
override def last: A = { |
||||
|
if (isEmpty) throw new NoSuchElementException("LinearSeq.last") |
||||
|
else { |
||||
|
var these = coll |
||||
|
var scout = tail |
||||
|
while (scout.nonEmpty) { |
||||
|
these = scout |
||||
|
scout = scout.tail |
||||
|
} |
||||
|
these.head |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
override def lengthCompare(len: Int): Int = { |
||||
|
@tailrec def loop(i: Int, xs: LinearSeq[A]): Int = { |
||||
|
if (i == len) |
||||
|
if (xs.isEmpty) 0 else 1 |
||||
|
else if (xs.isEmpty) |
||||
|
-1 |
||||
|
else |
||||
|
loop(i + 1, xs.tail) |
||||
|
} |
||||
|
if (len < 0) 1 |
||||
|
else loop(0, coll) |
||||
|
} |
||||
|
|
||||
|
override def lengthCompare(that: Iterable[_]): Int = { |
||||
|
val thatKnownSize = that.knownSize |
||||
|
|
||||
|
if (thatKnownSize >= 0) this lengthCompare thatKnownSize |
||||
|
else that match { |
||||
|
case that: LinearSeq[_] => |
||||
|
var thisSeq = this |
||||
|
var thatSeq = that |
||||
|
while (thisSeq.nonEmpty && thatSeq.nonEmpty) { |
||||
|
thisSeq = thisSeq.tail |
||||
|
thatSeq = thatSeq.tail |
||||
|
} |
||||
|
java.lang.Boolean.compare(thisSeq.nonEmpty, thatSeq.nonEmpty) |
||||
|
case _ => |
||||
|
var thisSeq = this |
||||
|
val thatIt = that.iterator |
||||
|
while (thisSeq.nonEmpty && thatIt.hasNext) { |
||||
|
thisSeq = thisSeq.tail |
||||
|
thatIt.next() |
||||
|
} |
||||
|
java.lang.Boolean.compare(thisSeq.nonEmpty, thatIt.hasNext) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
override def isDefinedAt(x: Int): Boolean = x >= 0 && lengthCompare(x) > 0 |
||||
|
|
||||
|
// `apply` is defined in terms of `drop`, which is in turn defined in |
||||
|
// terms of `tail`. |
||||
|
@throws[IndexOutOfBoundsException] |
||||
|
override def apply(n: Int): A = { |
||||
|
if (n < 0) throw new IndexOutOfBoundsException(n.toString) |
||||
|
val skipped = drop(n) |
||||
|
if (skipped.isEmpty) throw new IndexOutOfBoundsException(n.toString) |
||||
|
skipped.head |
||||
|
} |
||||
|
|
||||
|
override def foreach[U](f: A => U): Unit = { |
||||
|
var these: LinearSeq[A] = coll |
||||
|
while (!these.isEmpty) { |
||||
|
f(these.head) |
||||
|
these = these.tail |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
override def forall(p: A => Boolean): Boolean = { |
||||
|
var these: LinearSeq[A] = coll |
||||
|
while (!these.isEmpty) { |
||||
|
if (!p(these.head)) return false |
||||
|
these = these.tail |
||||
|
} |
||||
|
true |
||||
|
} |
||||
|
|
||||
|
override def exists(p: A => Boolean): Boolean = { |
||||
|
var these: LinearSeq[A] = coll |
||||
|
while (!these.isEmpty) { |
||||
|
if (p(these.head)) return true |
||||
|
these = these.tail |
||||
|
} |
||||
|
false |
||||
|
} |
||||
|
|
||||
|
override def contains[A1 >: A](elem: A1): Boolean = { |
||||
|
var these: LinearSeq[A] = coll |
||||
|
while (!these.isEmpty) { |
||||
|
if (these.head == elem) return true |
||||
|
these = these.tail |
||||
|
} |
||||
|
false |
||||
|
} |
||||
|
|
||||
|
override def find(p: A => Boolean): Option[A] = { |
||||
|
var these: LinearSeq[A] = coll |
||||
|
while (!these.isEmpty) { |
||||
|
if (p(these.head)) return Some(these.head) |
||||
|
these = these.tail |
||||
|
} |
||||
|
None |
||||
|
} |
||||
|
|
||||
|
override def foldLeft[B](z: B)(op: (B, A) => B): B = { |
||||
|
var acc = z |
||||
|
var these: LinearSeq[A] = coll |
||||
|
while (!these.isEmpty) { |
||||
|
acc = op(acc, these.head) |
||||
|
these = these.tail |
||||
|
} |
||||
|
acc |
||||
|
} |
||||
|
|
||||
|
override def sameElements[B >: A](that: IterableOnce[B]): Boolean = { |
||||
|
@tailrec def linearSeqEq(a: LinearSeq[B], b: LinearSeq[B]): Boolean = |
||||
|
(a eq b) || { |
||||
|
if (a.nonEmpty && b.nonEmpty && a.head == b.head) { |
||||
|
linearSeqEq(a.tail, b.tail) |
||||
|
} |
||||
|
else { |
||||
|
a.isEmpty && b.isEmpty |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
that match { |
||||
|
case that: LinearSeq[B] => linearSeqEq(coll, that) |
||||
|
case _ => super.sameElements(that) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
override def segmentLength(p: A => Boolean, from: Int): Int = { |
||||
|
var i = 0 |
||||
|
var seq = drop(from) |
||||
|
while (seq.nonEmpty && p(seq.head)) { |
||||
|
i += 1 |
||||
|
seq = seq.tail |
||||
|
} |
||||
|
i |
||||
|
} |
||||
|
|
||||
|
override def indexWhere(p: A => Boolean, from: Int): Int = { |
||||
|
var i = math.max(from, 0) |
||||
|
var these: LinearSeq[A] = this drop from |
||||
|
while (these.nonEmpty) { |
||||
|
if (p(these.head)) |
||||
|
return i |
||||
|
|
||||
|
i += 1 |
||||
|
these = these.tail |
||||
|
} |
||||
|
-1 |
||||
|
} |
||||
|
|
||||
|
override def lastIndexWhere(p: A => Boolean, end: Int): Int = { |
||||
|
var i = 0 |
||||
|
var these: LinearSeq[A] = coll |
||||
|
var last = -1 |
||||
|
while (!these.isEmpty && i <= end) { |
||||
|
if (p(these.head)) last = i |
||||
|
these = these.tail |
||||
|
i += 1 |
||||
|
} |
||||
|
last |
||||
|
} |
||||
|
|
||||
|
override def findLast(p: A => Boolean): Option[A] = { |
||||
|
var these: LinearSeq[A] = coll |
||||
|
var found = false |
||||
|
var last: A = null.asInstanceOf[A] // don't use `Option`, to prevent excessive `Some` allocation |
||||
|
while (these.nonEmpty) { |
||||
|
val elem = these.head |
||||
|
if (p(elem)) { |
||||
|
found = true |
||||
|
last = elem |
||||
|
} |
||||
|
these = these.tail |
||||
|
} |
||||
|
if (found) Some(last) else None |
||||
|
} |
||||
|
|
||||
|
override def tails: Iterator[C] = |
||||
|
Iterator.iterate(coll)(_.tail).takeWhile(_.nonEmpty) ++ Iterator.single(newSpecificBuilder.result()) |
||||
|
} |
||||
|
|
||||
|
trait StrictOptimizedLinearSeqOps[+A, +CC[X] <: LinearSeq[X], +C <: LinearSeq[A] with StrictOptimizedLinearSeqOps[A, CC, C]] extends Any with LinearSeqOps[A, CC, C] with StrictOptimizedSeqOps[A, CC, C] { |
||||
|
// A more efficient iterator implementation than the default LinearSeqIterator |
||||
|
override def iterator: Iterator[A] = new AbstractIterator[A] { |
||||
|
private[this] var current: Iterable[A] = toIterable |
||||
|
def hasNext = !current.isEmpty |
||||
|
def next() = { val r = current.head; current = current.tail; r } |
||||
|
} |
||||
|
|
||||
|
// Optimized version of `drop` that avoids copying |
||||
|
override def drop(n: Int): C = { |
||||
|
@tailrec def loop(n: Int, s: C): C = |
||||
|
if (n <= 0 || s.isEmpty) s |
||||
|
else loop(n - 1, s.tail) |
||||
|
loop(n, coll) |
||||
|
} |
||||
|
|
||||
|
override def dropWhile(p: A => Boolean): C = { |
||||
|
@tailrec def loop(s: C): C = |
||||
|
if (s.nonEmpty && p(s.head)) loop(s.tail) |
||||
|
else s |
||||
|
loop(coll) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** A specialized Iterator for LinearSeqs that is lazy enough for Stream and LazyList. This is accomplished by not |
||||
|
* evaluating the tail after returning the current head. |
||||
|
*/ |
||||
|
private[collection] final class LinearSeqIterator[A](coll: LinearSeqOps[A, LinearSeq, LinearSeq[A]]) extends AbstractIterator[A] { |
||||
|
// A call-by-need cell |
||||
|
private[this] final class LazyCell(st: => LinearSeqOps[A, LinearSeq, LinearSeq[A]]) { lazy val v = st } |
||||
|
|
||||
|
private[this] var these: LazyCell = new LazyCell(coll) |
||||
|
|
||||
|
def hasNext: Boolean = these.v.nonEmpty |
||||
|
|
||||
|
def next(): A = |
||||
|
if (isEmpty) Iterator.empty.next() |
||||
|
else { |
||||
|
val cur = these.v |
||||
|
val result = cur.head |
||||
|
these = new LazyCell(cur.tail) |
||||
|
result |
||||
|
} |
||||
|
} |
@ -0,0 +1,659 @@ |
|||||
|
/* |
||||
|
* Scala (https://www.scala-lang.org) |
||||
|
* |
||||
|
* Copyright EPFL and Lightbend, Inc. |
||||
|
* |
||||
|
* Licensed under Apache License 2.0 |
||||
|
* (http://www.apache.org/licenses/LICENSE-2.0). |
||||
|
* |
||||
|
* See the NOTICE file distributed with this work for |
||||
|
* additional information regarding copyright ownership. |
||||
|
*/ |
||||
|
|
||||
|
package scala |
||||
|
package collection |
||||
|
package immutable |
||||
|
|
||||
|
import scala.annotation.unchecked.uncheckedVariance |
||||
|
import scala.annotation.tailrec |
||||
|
import mutable.{Builder, ListBuffer} |
||||
|
import scala.collection.generic.DefaultSerializable |
||||
|
import scala.runtime.Statics.releaseFence |
||||
|
|
||||
|
/** A class for immutable linked lists representing ordered collections |
||||
|
* of elements of type `A`. |
||||
|
* |
||||
|
* This class comes with two implementing case classes `scala.Nil` |
||||
|
* and `scala.::` that implement the abstract members `isEmpty`, |
||||
|
* `head` and `tail`. |
||||
|
* |
||||
|
* This class is optimal for last-in-first-out (LIFO), stack-like access patterns. If you need another access |
||||
|
* pattern, for example, random access or FIFO, consider using a collection more suited to this than `List`. |
||||
|
* |
||||
|
* ==Performance== |
||||
|
* '''Time:''' `List` has `O(1)` prepend and head/tail access. Most other operations are `O(n)` on the number of elements in the list. |
||||
|
* This includes the index-based lookup of elements, `length`, `append` and `reverse`. |
||||
|
* |
||||
|
* '''Space:''' `List` implements '''structural sharing''' of the tail list. This means that many operations are either |
||||
|
* zero- or constant-memory cost. |
||||
|
* {{{ |
||||
|
* val mainList = List(3, 2, 1) |
||||
|
* val with4 = 4 :: mainList // re-uses mainList, costs one :: instance |
||||
|
* val with42 = 42 :: mainList // also re-uses mainList, cost one :: instance |
||||
|
* val shorter = mainList.tail // costs nothing as it uses the same 2::1::Nil instances as mainList |
||||
|
* }}} |
||||
|
* |
||||
|
* @example {{{ |
||||
|
* // Make a list via the companion object factory |
||||
|
* val days = List("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday") |
||||
|
* |
||||
|
* // Make a list element-by-element |
||||
|
* val when = "AM" :: "PM" :: Nil |
||||
|
* |
||||
|
* // Pattern match |
||||
|
* days match { |
||||
|
* case firstDay :: otherDays => |
||||
|
* println("The first day of the week is: " + firstDay) |
||||
|
* case Nil => |
||||
|
* println("There don't seem to be any week days.") |
||||
|
* } |
||||
|
* }}} |
||||
|
* |
||||
|
* @note The functional list is characterized by persistence and structural sharing, thus offering considerable |
||||
|
* performance and space consumption benefits in some scenarios if used correctly. |
||||
|
* However, note that objects having multiple references into the same functional list (that is, |
||||
|
* objects that rely on structural sharing), will be serialized and deserialized with multiple lists, one for |
||||
|
* each reference to it. I.e. structural sharing is lost after serialization/deserialization. |
||||
|
* |
||||
|
* @see [[http://docs.scala-lang.org/overviews/collections/concrete-immutable-collection-classes.html#lists "Scala's Collection Library overview"]] |
||||
|
* section on `Lists` for more information. |
||||
|
* |
||||
|
* @define coll list |
||||
|
* @define Coll `List` |
||||
|
* @define orderDependent |
||||
|
* @define orderDependentFold |
||||
|
* @define mayNotTerminateInf |
||||
|
* @define willNotTerminateInf |
||||
|
*/ |
||||
|
@SerialVersionUID(3L) |
||||
|
sealed abstract class List[+A] |
||||
|
extends AbstractSeq[A] |
||||
|
with LinearSeq[A] |
||||
|
with LinearSeqOps[A, List, List[A]] |
||||
|
with StrictOptimizedLinearSeqOps[A, List, List[A]] |
||||
|
with StrictOptimizedSeqOps[A, List, List[A]] |
||||
|
with IterableFactoryDefaults[A, List] |
||||
|
with DefaultSerializable { |
||||
|
|
||||
|
override def iterableFactory: SeqFactory[List] = List |
||||
|
|
||||
|
/** Adds an element at the beginning of this list. |
||||
|
* @param elem the element to prepend. |
||||
|
* @return a list which contains `x` as first element and |
||||
|
* which continues with this list. |
||||
|
* Example: |
||||
|
* {{{1 :: List(2, 3) = List(2, 3).::(1) = List(1, 2, 3)}}} |
||||
|
*/ |
||||
|
def :: [B >: A](elem: B): List[B] = new ::(elem, this) |
||||
|
|
||||
|
/** Adds the elements of a given list in front of this list. |
||||
|
* |
||||
|
* Example: |
||||
|
* {{{List(1, 2) ::: List(3, 4) = List(3, 4).:::(List(1, 2)) = List(1, 2, 3, 4)}}} |
||||
|
* |
||||
|
* @param prefix The list elements to prepend. |
||||
|
* @return a list resulting from the concatenation of the given |
||||
|
* list `prefix` and this list. |
||||
|
*/ |
||||
|
def ::: [B >: A](prefix: List[B]): List[B] = |
||||
|
if (isEmpty) prefix |
||||
|
else if (prefix.isEmpty) this |
||||
|
else { |
||||
|
val result = new ::[B](prefix.head, this) |
||||
|
var curr = result |
||||
|
var that = prefix.tail |
||||
|
while (!that.isEmpty) { |
||||
|
val temp = new ::[B](that.head, this) |
||||
|
curr.next = temp |
||||
|
curr = temp |
||||
|
that = that.tail |
||||
|
} |
||||
|
releaseFence() |
||||
|
result |
||||
|
} |
||||
|
|
||||
|
/** Adds the elements of a given list in reverse order in front of this list. |
||||
|
* `xs reverse_::: ys` is equivalent to |
||||
|
* `xs.reverse ::: ys` but is more efficient. |
||||
|
* |
||||
|
* @param prefix the prefix to reverse and then prepend |
||||
|
* @return the concatenation of the reversed prefix and the current list. |
||||
|
*/ |
||||
|
def reverse_:::[B >: A](prefix: List[B]): List[B] = { |
||||
|
var these: List[B] = this |
||||
|
var pres = prefix |
||||
|
while (!pres.isEmpty) { |
||||
|
these = pres.head :: these |
||||
|
pres = pres.tail |
||||
|
} |
||||
|
these |
||||
|
} |
||||
|
|
||||
|
override final def isEmpty: Boolean = this eq Nil |
||||
|
|
||||
|
override def prepended[B >: A](elem: B): List[B] = elem :: this |
||||
|
|
||||
|
override def prependedAll[B >: A](prefix: collection.IterableOnce[B]): List[B] = prefix match { |
||||
|
case xs: List[B] => xs ::: this |
||||
|
case _ if prefix.knownSize == 0 => this |
||||
|
case b: ListBuffer[B] if this.isEmpty => b.toList |
||||
|
case _ => |
||||
|
val iter = prefix.iterator |
||||
|
if (iter.hasNext) { |
||||
|
val result = new ::[B](iter.next(), this) |
||||
|
var curr = result |
||||
|
while (iter.hasNext) { |
||||
|
val temp = new ::[B](iter.next(), this) |
||||
|
curr.next = temp |
||||
|
curr = temp |
||||
|
} |
||||
|
releaseFence() |
||||
|
result |
||||
|
} else { |
||||
|
this |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// When calling appendAll with another list `suffix`, avoid copying `suffix` |
||||
|
override def appendedAll[B >: A](suffix: collection.IterableOnce[B]): List[B] = suffix match { |
||||
|
case xs: List[B] => this ::: xs |
||||
|
case _ => super.appendedAll(suffix) |
||||
|
} |
||||
|
|
||||
|
override def take(n: Int): List[A] = if (isEmpty || n <= 0) Nil else { |
||||
|
val h = new ::(head, Nil) |
||||
|
var t = h |
||||
|
var rest = tail |
||||
|
var i = 1 |
||||
|
while ({if (rest.isEmpty) return this; i < n}) { |
||||
|
i += 1 |
||||
|
val nx = new ::(rest.head, Nil) |
||||
|
t.next = nx |
||||
|
t = nx |
||||
|
rest = rest.tail |
||||
|
} |
||||
|
releaseFence() |
||||
|
h |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @example {{{ |
||||
|
* // Given a list |
||||
|
* val letters = List('a','b','c','d','e') |
||||
|
* |
||||
|
* // `slice` returns all elements beginning at index `from` and afterwards, |
||||
|
* // up until index `until` (excluding index `until`.) |
||||
|
* letters.slice(1,3) // Returns List('b','c') |
||||
|
* }}} |
||||
|
*/ |
||||
|
override def slice(from: Int, until: Int): List[A] = { |
||||
|
val lo = scala.math.max(from, 0) |
||||
|
if (until <= lo || isEmpty) Nil |
||||
|
else this drop lo take (until - lo) |
||||
|
} |
||||
|
|
||||
|
override def takeRight(n: Int): List[A] = { |
||||
|
@tailrec |
||||
|
def loop(lead: List[A], lag: List[A]): List[A] = lead match { |
||||
|
case Nil => lag |
||||
|
case _ :: tail => loop(tail, lag.tail) |
||||
|
} |
||||
|
loop(drop(n), this) |
||||
|
} |
||||
|
|
||||
|
// dropRight is inherited from LinearSeq |
||||
|
|
||||
|
override def splitAt(n: Int): (List[A], List[A]) = { |
||||
|
val b = new ListBuffer[A] |
||||
|
var i = 0 |
||||
|
var these = this |
||||
|
while (!these.isEmpty && i < n) { |
||||
|
i += 1 |
||||
|
b += these.head |
||||
|
these = these.tail |
||||
|
} |
||||
|
(b.toList, these) |
||||
|
} |
||||
|
|
||||
|
override def updated[B >: A](index: Int, elem: B): List[B] = { |
||||
|
var i = 0 |
||||
|
var current = this |
||||
|
val prefix = ListBuffer.empty[B] |
||||
|
while (i < index && current.nonEmpty) { |
||||
|
i += 1 |
||||
|
prefix += current.head |
||||
|
current = current.tail |
||||
|
} |
||||
|
if (i == index && current.nonEmpty) { |
||||
|
prefix.prependToList(elem :: current.tail) |
||||
|
} else { |
||||
|
throw new IndexOutOfBoundsException(s"$index is out of bounds (min 0, max ${length-1})") |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
final override def map[B](f: A => B): List[B] = { |
||||
|
if (this eq Nil) Nil else { |
||||
|
val h = new ::[B](f(head), Nil) |
||||
|
var t: ::[B] = h |
||||
|
var rest = tail |
||||
|
while (rest ne Nil) { |
||||
|
val nx = new ::(f(rest.head), Nil) |
||||
|
t.next = nx |
||||
|
t = nx |
||||
|
rest = rest.tail |
||||
|
} |
||||
|
releaseFence() |
||||
|
h |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
final override def collect[B](pf: PartialFunction[A, B]): List[B] = { |
||||
|
if (this eq Nil) Nil else { |
||||
|
var rest = this |
||||
|
var h: ::[B] = null |
||||
|
var x: Any = null |
||||
|
// Special case for first element |
||||
|
while (h eq null) { |
||||
|
x = pf.applyOrElse(rest.head, List.partialNotApplied) |
||||
|
if (x.asInstanceOf[AnyRef] ne List.partialNotApplied) h = new ::(x.asInstanceOf[B], Nil) |
||||
|
rest = rest.tail |
||||
|
if (rest eq Nil) return if (h eq null) Nil else h |
||||
|
} |
||||
|
var t = h |
||||
|
// Remaining elements |
||||
|
while (rest ne Nil) { |
||||
|
x = pf.applyOrElse(rest.head, List.partialNotApplied) |
||||
|
if (x.asInstanceOf[AnyRef] ne List.partialNotApplied) { |
||||
|
val nx = new ::(x.asInstanceOf[B], Nil) |
||||
|
t.next = nx |
||||
|
t = nx |
||||
|
} |
||||
|
rest = rest.tail |
||||
|
} |
||||
|
releaseFence() |
||||
|
h |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
final override def flatMap[B](f: A => IterableOnce[B]): List[B] = { |
||||
|
var rest = this |
||||
|
var h: ::[B] = null |
||||
|
var t: ::[B] = null |
||||
|
while (rest ne Nil) { |
||||
|
val it = f(rest.head).iterator |
||||
|
while (it.hasNext) { |
||||
|
val nx = new ::(it.next(), Nil) |
||||
|
if (t eq null) { |
||||
|
h = nx |
||||
|
} else { |
||||
|
t.next = nx |
||||
|
} |
||||
|
t = nx |
||||
|
} |
||||
|
rest = rest.tail |
||||
|
} |
||||
|
if (h eq null) Nil else {releaseFence(); h} |
||||
|
} |
||||
|
|
||||
|
@inline final override def takeWhile(p: A => Boolean): List[A] = { |
||||
|
val b = new ListBuffer[A] |
||||
|
var these = this |
||||
|
while (!these.isEmpty && p(these.head)) { |
||||
|
b += these.head |
||||
|
these = these.tail |
||||
|
} |
||||
|
b.toList |
||||
|
} |
||||
|
|
||||
|
@inline final override def span(p: A => Boolean): (List[A], List[A]) = { |
||||
|
val b = new ListBuffer[A] |
||||
|
var these = this |
||||
|
while (!these.isEmpty && p(these.head)) { |
||||
|
b += these.head |
||||
|
these = these.tail |
||||
|
} |
||||
|
(b.toList, these) |
||||
|
} |
||||
|
|
||||
|
// Overridden with an implementation identical to the inherited one (at this time) |
||||
|
// solely so it can be finalized and thus inlinable. |
||||
|
@inline final override def foreach[U](f: A => U): Unit = { |
||||
|
var these = this |
||||
|
while (!these.isEmpty) { |
||||
|
f(these.head) |
||||
|
these = these.tail |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
final override def reverse: List[A] = { |
||||
|
var result: List[A] = Nil |
||||
|
var these = this |
||||
|
while (!these.isEmpty) { |
||||
|
result = these.head :: result |
||||
|
these = these.tail |
||||
|
} |
||||
|
result |
||||
|
} |
||||
|
|
||||
|
final override def foldRight[B](z: B)(op: (A, B) => B): B = { |
||||
|
var acc = z |
||||
|
var these: List[A] = reverse |
||||
|
while (!these.isEmpty) { |
||||
|
acc = op(these.head, acc) |
||||
|
these = these.tail |
||||
|
} |
||||
|
acc |
||||
|
} |
||||
|
|
||||
|
// Copy/Paste overrides to avoid interface calls inside loops. |
||||
|
|
||||
|
override final def length: Int = { |
||||
|
var these = this |
||||
|
var len = 0 |
||||
|
while (!these.isEmpty) { |
||||
|
len += 1 |
||||
|
these = these.tail |
||||
|
} |
||||
|
len |
||||
|
} |
||||
|
|
||||
|
override final def lengthCompare(len: Int): Int = { |
||||
|
@tailrec def loop(i: Int, xs: List[A]): Int = { |
||||
|
if (i == len) |
||||
|
if (xs.isEmpty) 0 else 1 |
||||
|
else if (xs.isEmpty) |
||||
|
-1 |
||||
|
else |
||||
|
loop(i + 1, xs.tail) |
||||
|
} |
||||
|
if (len < 0) 1 |
||||
|
else loop(0, coll) |
||||
|
} |
||||
|
|
||||
|
override final def forall(p: A => Boolean): Boolean = { |
||||
|
var these: List[A] = this |
||||
|
while (!these.isEmpty) { |
||||
|
if (!p(these.head)) return false |
||||
|
these = these.tail |
||||
|
} |
||||
|
true |
||||
|
} |
||||
|
|
||||
|
override final def exists(p: A => Boolean): Boolean = { |
||||
|
var these: List[A] = this |
||||
|
while (!these.isEmpty) { |
||||
|
if (p(these.head)) return true |
||||
|
these = these.tail |
||||
|
} |
||||
|
false |
||||
|
} |
||||
|
|
||||
|
override final def contains[A1 >: A](elem: A1): Boolean = { |
||||
|
var these: List[A] = this |
||||
|
while (!these.isEmpty) { |
||||
|
if (these.head == elem) return true |
||||
|
these = these.tail |
||||
|
} |
||||
|
false |
||||
|
} |
||||
|
|
||||
|
override final def find(p: A => Boolean): Option[A] = { |
||||
|
var these: List[A] = this |
||||
|
while (!these.isEmpty) { |
||||
|
if (p(these.head)) return Some(these.head) |
||||
|
these = these.tail |
||||
|
} |
||||
|
None |
||||
|
} |
||||
|
|
||||
|
override def last: A = { |
||||
|
if (isEmpty) throw new NoSuchElementException("List.last") |
||||
|
else { |
||||
|
var these = this |
||||
|
var scout = tail |
||||
|
while (!scout.isEmpty) { |
||||
|
these = scout |
||||
|
scout = scout.tail |
||||
|
} |
||||
|
these.head |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
override def corresponds[B](that: collection.Seq[B])(p: (A, B) => Boolean): Boolean = that match { |
||||
|
case that: LinearSeq[B] => |
||||
|
var i = this |
||||
|
var j = that |
||||
|
while (!(i.isEmpty || j.isEmpty)) { |
||||
|
if (!p(i.head, j.head)) |
||||
|
return false |
||||
|
i = i.tail |
||||
|
j = j.tail |
||||
|
} |
||||
|
i.isEmpty && j.isEmpty |
||||
|
case _ => |
||||
|
super.corresponds(that)(p) |
||||
|
} |
||||
|
|
||||
|
override protected[this] def className = "List" |
||||
|
|
||||
|
/** Builds a new list by applying a function to all elements of this list. |
||||
|
* Like `xs map f`, but returns `xs` unchanged if function |
||||
|
* `f` maps all elements to themselves (as determined by `eq`). |
||||
|
* |
||||
|
* @param f the function to apply to each element. |
||||
|
* @tparam B the element type of the returned collection. |
||||
|
* @return a list resulting from applying the given function |
||||
|
* `f` to each element of this list and collecting the results. |
||||
|
*/ |
||||
|
@`inline` final def mapConserve[B >: A <: AnyRef](f: A => B): List[B] = { |
||||
|
// Note to developers: there exists a duplication between this function and `reflect.internal.util.Collections#map2Conserve`. |
||||
|
// If any successful optimization attempts or other changes are made, please rehash them there too. |
||||
|
@tailrec |
||||
|
def loop(mappedHead: List[B], mappedLast: ::[B], unchanged: List[A], pending: List[A]): List[B] = { |
||||
|
if (pending.isEmpty) { |
||||
|
if (mappedHead eq null) unchanged |
||||
|
else { |
||||
|
mappedLast.next = (unchanged: List[B]) |
||||
|
mappedHead |
||||
|
} |
||||
|
} |
||||
|
else { |
||||
|
val head0 = pending.head |
||||
|
val head1 = f(head0) |
||||
|
|
||||
|
if (head1 eq head0.asInstanceOf[AnyRef]) |
||||
|
loop(mappedHead, mappedLast, unchanged, pending.tail) |
||||
|
else { |
||||
|
var xc = unchanged |
||||
|
var mappedHead1: List[B] = mappedHead |
||||
|
var mappedLast1: ::[B] = mappedLast |
||||
|
while (xc ne pending) { |
||||
|
val next = new ::[B](xc.head, Nil) |
||||
|
if (mappedHead1 eq null) mappedHead1 = next |
||||
|
if (mappedLast1 ne null) mappedLast1.next = next |
||||
|
mappedLast1 = next |
||||
|
xc = xc.tail |
||||
|
} |
||||
|
val next = new ::(head1, Nil) |
||||
|
if (mappedHead1 eq null) mappedHead1 = next |
||||
|
if (mappedLast1 ne null) mappedLast1.next = next |
||||
|
mappedLast1 = next |
||||
|
val tail0 = pending.tail |
||||
|
loop(mappedHead1, mappedLast1, tail0, tail0) |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
val result = loop(null, null, this, this) |
||||
|
releaseFence() |
||||
|
result |
||||
|
} |
||||
|
|
||||
|
override def filter(p: A => Boolean): List[A] = filterCommon(p, isFlipped = false) |
||||
|
|
||||
|
override def filterNot(p: A => Boolean): List[A] = filterCommon(p, isFlipped = true) |
||||
|
|
||||
|
private[this] def filterCommon(p: A => Boolean, isFlipped: Boolean): List[A] = { |
||||
|
|
||||
|
// everything seen so far so far is not included |
||||
|
@tailrec def noneIn(l: List[A]): List[A] = { |
||||
|
if (l.isEmpty) |
||||
|
Nil |
||||
|
else { |
||||
|
val h = l.head |
||||
|
val t = l.tail |
||||
|
if (p(h) != isFlipped) |
||||
|
allIn(l, t) |
||||
|
else |
||||
|
noneIn(t) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// everything from 'start' is included, if everything from this point is in we can return the origin |
||||
|
// start otherwise if we discover an element that is out we must create a new partial list. |
||||
|
@tailrec def allIn(start: List[A], remaining: List[A]): List[A] = { |
||||
|
if (remaining.isEmpty) |
||||
|
start |
||||
|
else { |
||||
|
val x = remaining.head |
||||
|
if (p(x) != isFlipped) |
||||
|
allIn(start, remaining.tail) |
||||
|
else |
||||
|
partialFill(start, remaining) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// we have seen elements that should be included then one that should be excluded, start building |
||||
|
def partialFill(origStart: List[A], firstMiss: List[A]): List[A] = { |
||||
|
val newHead = new ::(origStart.head, Nil) |
||||
|
var toProcess = origStart.tail |
||||
|
var currentLast = newHead |
||||
|
|
||||
|
// we know that all elements are :: until at least firstMiss.tail |
||||
|
while (!(toProcess eq firstMiss)) { |
||||
|
val newElem = new ::(toProcess.head, Nil) |
||||
|
currentLast.next = newElem |
||||
|
currentLast = newElem |
||||
|
toProcess = toProcess.tail |
||||
|
} |
||||
|
|
||||
|
// at this point newHead points to a list which is a duplicate of all the 'in' elements up to the first miss. |
||||
|
// currentLast is the last element in that list. |
||||
|
|
||||
|
// now we are going to try and share as much of the tail as we can, only moving elements across when we have to. |
||||
|
var next = firstMiss.tail |
||||
|
var nextToCopy = next // the next element we would need to copy to our list if we cant share. |
||||
|
while (!next.isEmpty) { |
||||
|
// generally recommended is next.isNonEmpty but this incurs an extra method call. |
||||
|
val head: A = next.head |
||||
|
if (p(head) != isFlipped) { |
||||
|
next = next.tail |
||||
|
} else { |
||||
|
// its not a match - do we have outstanding elements? |
||||
|
while (!(nextToCopy eq next)) { |
||||
|
val newElem = new ::(nextToCopy.head, Nil) |
||||
|
currentLast.next = newElem |
||||
|
currentLast = newElem |
||||
|
nextToCopy = nextToCopy.tail |
||||
|
} |
||||
|
nextToCopy = next.tail |
||||
|
next = next.tail |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// we have remaining elements - they are unchanged attach them to the end |
||||
|
if (!nextToCopy.isEmpty) |
||||
|
currentLast.next = nextToCopy |
||||
|
|
||||
|
newHead |
||||
|
} |
||||
|
|
||||
|
val result = noneIn(this) |
||||
|
releaseFence() |
||||
|
result |
||||
|
} |
||||
|
|
||||
|
override def partition(p: A => Boolean): (List[A], List[A]) = { |
||||
|
if (isEmpty) List.TupleOfNil |
||||
|
else super.partition(p) match { |
||||
|
case (Nil, xs) => (Nil, this) |
||||
|
case (xs, Nil) => (this, Nil) |
||||
|
case pair => pair |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
final override def toList: List[A] = this |
||||
|
|
||||
|
// Override for performance |
||||
|
override def equals(o: scala.Any): Boolean = { |
||||
|
@tailrec def listEq(a: List[_], b: List[_]): Boolean = |
||||
|
(a eq b) || { |
||||
|
val aEmpty = a.isEmpty |
||||
|
val bEmpty = b.isEmpty |
||||
|
if (!(aEmpty || bEmpty) && a.head == b.head) { |
||||
|
listEq(a.tail, b.tail) |
||||
|
} |
||||
|
else { |
||||
|
aEmpty && bEmpty |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
o match { |
||||
|
case that: List[_] => listEq(this, that) |
||||
|
case _ => super.equals(o) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
// Internal code that mutates `next` _must_ call `Statics.releaseFence()` if either immediately, or |
||||
|
// before a newly-allocated, thread-local :: instance is aliased (e.g. in ListBuffer.toList) |
||||
|
final case class :: [+A](override val head: A, private[scala] var next: List[A @uncheckedVariance]) // sound because `next` is used only locally |
||||
|
extends List[A] { |
||||
|
releaseFence() |
||||
|
override def headOption: Some[A] = Some(head) |
||||
|
override def tail: List[A] = next |
||||
|
} |
||||
|
|
||||
|
case object Nil extends List[Nothing] { |
||||
|
override def head: Nothing = throw new NoSuchElementException("head of empty list") |
||||
|
override def headOption: None.type = None |
||||
|
override def tail: Nothing = throw new UnsupportedOperationException("tail of empty list") |
||||
|
override def last: Nothing = throw new NoSuchElementException("last of empty list") |
||||
|
override def init: Nothing = throw new UnsupportedOperationException("init of empty list") |
||||
|
override def knownSize: Int = 0 |
||||
|
override def iterator: Iterator[Nothing] = Iterator.empty |
||||
|
override def unzip[A1, A2](implicit asPair: Nothing => (A1, A2)): (List[A1], List[A2]) = EmptyUnzip |
||||
|
|
||||
|
@transient |
||||
|
private[this] val EmptyUnzip = (Nil, Nil) |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* $factoryInfo |
||||
|
* @define coll list |
||||
|
* @define Coll `List` |
||||
|
*/ |
||||
|
@SerialVersionUID(3L) |
||||
|
object List extends StrictOptimizedSeqFactory[List] { |
||||
|
private val TupleOfNil = (Nil, Nil) |
||||
|
|
||||
|
def from[B](coll: collection.IterableOnce[B]): List[B] = Nil.prependedAll(coll) |
||||
|
|
||||
|
def newBuilder[A]: Builder[A, List[A]] = new ListBuffer() |
||||
|
|
||||
|
def empty[A]: List[A] = Nil |
||||
|
|
||||
|
@transient |
||||
|
private[collection] val partialNotApplied = new Function1[Any, Any] { def apply(x: Any): Any = this } |
||||
|
} |
@ -0,0 +1,19 @@ |
|||||
|
/* |
||||
|
* Scala (https://www.scala-lang.org) |
||||
|
* |
||||
|
* Copyright EPFL and Lightbend, Inc. |
||||
|
* |
||||
|
* Licensed under Apache License 2.0 |
||||
|
* (http://www.apache.org/licenses/LICENSE-2.0). |
||||
|
* |
||||
|
* See the NOTICE file distributed with this work for |
||||
|
* additional information regarding copyright ownership. |
||||
|
*/ |
||||
|
|
||||
|
// GENERATED CODE: DO NOT EDIT. See scala.Function0 for timestamp. |
||||
|
|
||||
|
package scala.runtime |
||||
|
|
||||
|
abstract class AbstractFunction0[@specialized(Specializable.Primitives) +R] extends Function0[R] { |
||||
|
|
||||
|
} |
@ -0,0 +1,7 @@ |
|||||
|
{ |
||||
|
// Use IntelliSense to learn about possible attributes. |
||||
|
// Hover to view descriptions of existing attributes. |
||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 |
||||
|
"version": "0.2.0", |
||||
|
"configurations": [] |
||||
|
} |
@ -0,0 +1,5 @@ |
|||||
|
{ |
||||
|
"files.watcherExclude": { |
||||
|
"**/target": true |
||||
|
} |
||||
|
} |
@ -0,0 +1,77 @@ |
|||||
|
|
||||
|
// The simplest possible sbt build file is just one line: |
||||
|
|
||||
|
scalaVersion := "2.13.3" |
||||
|
// That is, to create a valid sbt build, all you've got to do is define the |
||||
|
// version of Scala you'd like your project to use. |
||||
|
|
||||
|
// ============================================================================ |
||||
|
|
||||
|
// Lines like the above defining `scalaVersion` are called "settings". Settings |
||||
|
// are key/value pairs. In the case of `scalaVersion`, the key is "scalaVersion" |
||||
|
// and the value is "2.13.3" |
||||
|
|
||||
|
// It's possible to define many kinds of settings, such as: |
||||
|
|
||||
|
name := "AdOfCo-09" |
||||
|
organization := "is.rud.scala" |
||||
|
version := "1.0" |
||||
|
|
||||
|
// Note, it's not required for you to define these three settings. These are |
||||
|
// mostly only necessary if you intend to publish your library's binaries on a |
||||
|
// place like Sonatype or Bintray. |
||||
|
|
||||
|
|
||||
|
// Want to use a published library in your project? |
||||
|
// You can define other libraries as dependencies in your build like this: |
||||
|
|
||||
|
libraryDependencies += "org.scala-lang.modules" %% "scala-parser-combinators" % "1.1.2" |
||||
|
|
||||
|
// Here, `libraryDependencies` is a set of dependencies, and by using `+=`, |
||||
|
// we're adding the scala-parser-combinators dependency to the set of dependencies |
||||
|
// that sbt will go and fetch when it starts up. |
||||
|
// Now, in any Scala file, you can import classes, objects, etc., from |
||||
|
// scala-parser-combinators with a regular import. |
||||
|
|
||||
|
// TIP: To find the "dependency" that you need to add to the |
||||
|
// `libraryDependencies` set, which in the above example looks like this: |
||||
|
|
||||
|
// "org.scala-lang.modules" %% "scala-parser-combinators" % "1.1.2" |
||||
|
|
||||
|
// You can use Scaladex, an index of all known published Scala libraries. There, |
||||
|
// after you find the library you want, you can just copy/paste the dependency |
||||
|
// information that you need into your build file. For example, on the |
||||
|
// scala/scala-parser-combinators Scaladex page, |
||||
|
// https://index.scala-lang.org/scala/scala-parser-combinators, you can copy/paste |
||||
|
// the sbt dependency from the sbt box on the right-hand side of the screen. |
||||
|
|
||||
|
// IMPORTANT NOTE: while build files look _kind of_ like regular Scala, it's |
||||
|
// important to note that syntax in *.sbt files doesn't always behave like |
||||
|
// regular Scala. For example, notice in this build file that it's not required |
||||
|
// to put our settings into an enclosing object or class. Always remember that |
||||
|
// sbt is a bit different, semantically, than vanilla Scala. |
||||
|
|
||||
|
// ============================================================================ |
||||
|
|
||||
|
// Most moderately interesting Scala projects don't make use of the very simple |
||||
|
// build file style (called "bare style") used in this build.sbt file. Most |
||||
|
// intermediate Scala projects make use of so-called "multi-project" builds. A |
||||
|
// multi-project build makes it possible to have different folders which sbt can |
||||
|
// be configured differently for. That is, you may wish to have different |
||||
|
// dependencies or different testing frameworks defined for different parts of |
||||
|
// your codebase. Multi-project builds make this possible. |
||||
|
|
||||
|
// Here's a quick glimpse of what a multi-project build looks like for this |
||||
|
// build, with only one "subproject" defined, called `root`: |
||||
|
|
||||
|
// lazy val root = (project in file(".")). |
||||
|
// settings( |
||||
|
// inThisBuild(List( |
||||
|
// organization := "ch.epfl.scala", |
||||
|
// scalaVersion := "2.13.3" |
||||
|
// )), |
||||
|
// name := "hello-world" |
||||
|
// ) |
||||
|
|
||||
|
// To learn more about multi-project builds, head over to the official sbt |
||||
|
// documentation at http://www.scala-sbt.org/documentation.html |
@ -0,0 +1,61 @@ |
|||||
|
// See R or Python code for today's challenge description |
||||
|
|
||||
|
import util.control.Breaks._ |
||||
|
import java.text.NumberFormat |
||||
|
|
||||
|
object Main extends App { |
||||
|
|
||||
|
val bufferedSource = io.Source.fromFile("/Users/hrbrmstr/Development/2020-code-advent/input/09-01.txt") |
||||
|
val input = (for (line <- bufferedSource.getLines()) yield line).toArray |
||||
|
bufferedSource.close |
||||
|
|
||||
|
// val input = Array(35, 20, 15, 25, 47, 40, 62, 55, 65, 95, 102, 117, 150, 182, 127, 219, 299, 277, 309, 576) |
||||
|
|
||||
|
var records = input.map((x) => x.toLong) |
||||
|
val preamble_length = 25 |
||||
|
var condition = true |
||||
|
|
||||
|
// 09-01 |
||||
|
|
||||
|
val pairs = (0 to (preamble_length-1)).combinations(2).toArray |
||||
|
|
||||
|
while (condition && (records.size > preamble_length)) { |
||||
|
|
||||
|
breakable { for (pair <- pairs) { |
||||
|
condition = (records(pair.head) + records(pair.last)) == records(preamble_length) |
||||
|
if (condition) break |
||||
|
}} |
||||
|
|
||||
|
if (condition) records = records.drop(1) |
||||
|
|
||||
|
} |
||||
|
|
||||
|
val invalid = records(preamble_length) |
||||
|
|
||||
|
println(invalid) |
||||
|
|
||||
|
// 09-02 |
||||
|
|
||||
|
def cumsum[A](xs: Seq[A])(implicit num: Numeric[A]): Seq[A] = { |
||||
|
xs.tail.scanLeft(xs.head)(num.plus) |
||||
|
} |
||||
|
|
||||
|
var startPos = -1 |
||||
|
var invalidPos = -1 |
||||
|
|
||||
|
records = input.map((x) => x.toLong) |
||||
|
|
||||
|
breakable { for (idx <- records.indices) { |
||||
|
val csum = cumsum(records.slice(idx, records.length)) |
||||
|
if (csum.contains(invalid)) { |
||||
|
startPos = idx |
||||
|
invalidPos = csum.indexOf(invalid) |
||||
|
break |
||||
|
} |
||||
|
}} |
||||
|
|
||||
|
val rng = records.slice(startPos, startPos+invalidPos+1) |
||||
|
|
||||
|
println(rng.min + rng.max) |
||||
|
|
||||
|
} |
Loading…
Reference in new issue