Browse Source

Day 9 scala

master
boB Rudis 2 months ago
parent
commit
ed8a3de2f2
No known key found for this signature in database GPG Key ID: 1D7529BE14E2BBA9
38 changed files with 10315 additions and 25 deletions
  1. +5
    -10
      R/09.R
  2. +4
    -15
      js/09.js
  3. BIN
      scala/09/.metals/metals.h2.db
  4. +627
    -0
      scala/09/.metals/readonly/scala/Array.scala
  5. +325
    -0
      scala/09/.metals/readonly/scala/collection/LinearSeqOptimized.scala
  6. +375
    -0
      scala/09/.metals/readonly/scala/io/Source.scala
  7. +98
    -0
      scala/09/.metals/readonly/scala/util/control/Breaks.scala
  8. +7
    -0
      scala/09/.vscode/launch.json
  9. +5
    -0
      scala/09/.vscode/settings.json
  10. +16
    -0
      scala/09/09/.bloop/bloop.settings.json
  11. BIN
      scala/09/09/.bloop/root-04/bloop-internal-classes/classes-Metals-WftNm-PZT_-cgA5nv602vw==-0KbC61waTL-8aX1xG2uAJA==/META-INF/semanticdb/src/main/scala/Main.scala.semanticdb
  12. BIN
      scala/09/09/.bloop/root-04/bloop-internal-classes/classes-Metals-WftNm-PZT_-cgA5nv602vw==-wG-EOZ01QFaRN4A7uUYTsw==/META-INF/semanticdb/src/main/scala/Main.scala.semanticdb
  13. +167
    -0
      scala/09/09/.bloop/root-09-test.json
  14. +166
    -0
      scala/09/09/.bloop/root-09.json
  15. BIN
      scala/09/09/.bloop/root-09/bloop-bsp-clients-classes/classes-Metals-E_SBAB02SrCYpR_pDlxdTw==/META-INF/semanticdb/src/main/scala/Main.scala.semanticdb
  16. BIN
      scala/09/09/.bloop/root-09/bloop-internal-classes/classes-Metals-E_SBAB02SrCYpR_pDlxdTw==-_pr_4zdfTAC2ZM1Ps9Ri6g==/META-INF/semanticdb/src/main/scala/Main.scala.semanticdb
  17. +1
    -0
      scala/09/09/.bsp/sbt.json
  18. BIN
      scala/09/09/.metals/metals.h2.db
  19. +6
    -0
      scala/09/09/.metals/metals.lock.db
  20. +79
    -0
      scala/09/09/.metals/readonly/scala/App.scala
  21. +659
    -0
      scala/09/09/.metals/readonly/scala/Array.scala
  22. +140
    -0
      scala/09/09/.metals/readonly/scala/Boolean.scala
  23. +42
    -0
      scala/09/09/.metals/readonly/scala/Function0.scala
  24. +486
    -0
      scala/09/09/.metals/readonly/scala/Int.scala
  25. +581
    -0
      scala/09/09/.metals/readonly/scala/Predef.scala
  26. +33
    -0
      scala/09/09/.metals/readonly/scala/annotation/switch.scala
  27. +1640
    -0
      scala/09/09/.metals/readonly/scala/collection/ArrayOps.scala
  28. +130
    -0
      scala/09/09/.metals/readonly/scala/collection/IndexedSeq.scala
  29. +1030
    -0
      scala/09/09/.metals/readonly/scala/collection/Iterable.scala
  30. +1298
    -0
      scala/09/09/.metals/readonly/scala/collection/IterableOnce.scala
  31. +1279
    -0
      scala/09/09/.metals/readonly/scala/collection/Iterator.scala
  32. +288
    -0
      scala/09/09/.metals/readonly/scala/collection/LinearSeq.scala
  33. +659
    -0
      scala/09/09/.metals/readonly/scala/collection/immutable/List.scala
  34. +19
    -0
      scala/09/09/.metals/readonly/scala/runtime/AbstractFunction0.scala
  35. +7
    -0
      scala/09/09/.vscode/launch.json
  36. +5
    -0
      scala/09/09/.vscode/settings.json
  37. +77
    -0
      scala/09/09/build.sbt
  38. +61
    -0
      scala/09/09/src/main/scala/Main.scala

+ 5
- 10
R/09.R View File

@ -73,26 +73,21 @@ input <- as.numeric(read_lines("../input/09-01.txt"))
# preamble_length <- 5
preamble_length <- 25
window <- 1:preamble_length
input_start <- preamble_length + 1
condition <- TRUE
pairs <- combn(1:preamble_length, 2)
while(condition && (length(input)>=(preamble_length + 1))) {
as.data.frame(t(combn(window, 2))) %>%
mutate(
val1 = input[V1],
val2 = input[V2],
sum = input[V1] + input[V2]
) -> pair_sums
pair_sums <- input[pairs[1,]] + input[pairs[2,]]
condition <- any(pair_sums$sum == input[input_start])
condition <- any(pair_sums == input[preamble_length + 1])
if (condition) input <- tail(input, -1)
}
(invalid <- input[input_start])
(invalid <- input[preamble_length + 1])
# --- Part Two ---


+ 4
- 15
js/09.js View File

@ -16,13 +16,13 @@ input = fs.readFileSync("../input/09-01.txt", "utf-8")
//input = [ 35, 20, 15, 25, 47, 40, 62, 55, 65, 95, 102, 117, 150, 182, 127, 219, 299, 277, 309, 576 ]
preamble_length = 25
input_start = preamble_length
condition = true
pairs = [...combn.clone.combination([...Array(preamble_length).keys()], 2)]
while(condition && (input.length > (preamble_length))) {
for (var pair of combn.combination([...Array(preamble_length).keys()], 2)) {
condition = (input[pair[0]] + input[pair[1]]) == input[input_start]
for (var pair of pairs) {
condition = (input[pair[0]] + input[pair[1]]) == input[preamble_length]
if (condition) break
}
@ -30,7 +30,7 @@ while(condition && (input.length > (preamble_length))) {
}
invalid = input[input_start]
invalid = input[preamble_length]
console.log(invalid)
// 09-02
@ -54,14 +54,3 @@ for (var idx=0; idx<input.length; idx++) {
rng = input.slice(idx, idx+csum.indexOf(invalid))
console.log(Math.min(...rng) + Math.max(...rng))

BIN
scala/09/.metals/metals.h2.db View File


+ 627
- 0
scala/09/.metals/readonly/scala/Array.scala View File

@ -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()
}

+ 325
- 0
scala/09/.metals/readonly/scala/collection/LinearSeqOptimized.scala View File

@ -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)
}

+ 375
- 0
scala/09/.metals/readonly/scala/io/Source.scala View File

@ -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.")
}

+ 98
- 0
scala/09/.metals/readonly/scala/util/control/Breaks.scala View File

@ -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

+ 7
- 0
scala/09/.vscode/launch.json View File

@ -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": []
}

+ 5
- 0
scala/09/.vscode/settings.json View File

@ -0,0 +1,5 @@
{
"files.watcherExclude": {
"**/target": true
}