"Fossies" - the Fresh Open Source Software Archive

Member "scala-js-1.3.1/scalalib/overrides-2.13/scala/collection/mutable/ArrayBuilder.scala" (14 Nov 2020, 15596 Bytes) of package /linux/www/scala-js-1.3.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Scala source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 /*
    2  * Scala (https://www.scala-lang.org)
    3  *
    4  * Copyright EPFL and Lightbend, Inc.
    5  *
    6  * Licensed under Apache License 2.0
    7  * (http://www.apache.org/licenses/LICENSE-2.0).
    8  *
    9  * See the NOTICE file distributed with this work for
   10  * additional information regarding copyright ownership.
   11  */
   12 
   13 package scala.collection
   14 package mutable
   15 
   16 import scala.reflect.ClassTag
   17 import scala.runtime.BoxedUnit
   18 
   19 import scala.scalajs.js
   20 
   21 /** A builder class for arrays.
   22  *
   23  *  @since 2.8
   24  *
   25  *  @tparam T    the type of the elements for the builder.
   26  */
   27 @SerialVersionUID(3L)
   28 sealed abstract class ArrayBuilder[T]
   29   extends ReusableBuilder[T, Array[T]]
   30     with Serializable {
   31   protected[this] var capacity: Int = 0
   32   protected[this] def elems: Array[T]
   33   protected var size: Int = 0
   34 
   35   def length: Int = size
   36 
   37   override def knownSize: Int = size
   38 
   39   protected[this] final def ensureSize(size: Int): Unit = {
   40     if (capacity < size || capacity == 0) {
   41       var newsize = if (capacity == 0) 16 else capacity * 2
   42       while (newsize < size) newsize *= 2
   43       resize(newsize)
   44     }
   45   }
   46 
   47   override final def sizeHint(size: Int): Unit =
   48     if (capacity < size) resize(size)
   49 
   50   def clear(): Unit = size = 0
   51 
   52   protected[this] def resize(size: Int): Unit
   53 
   54   /** Add all elements of an array */
   55   def addAll(xs: Array[_ <: T]): this.type = addAll(xs, 0, xs.length)
   56 
   57   /** Add a slice of an array */
   58   def addAll(xs: Array[_ <: T], offset: Int, length: Int): this.type = {
   59     ensureSize(this.size + length)
   60     Array.copy(xs, offset, elems, this.size, length)
   61     size += length
   62     this
   63   }
   64 
   65   override def addAll(xs: IterableOnce[T]): this.type = {
   66     val k = xs.knownSize
   67     if(k > 0) {
   68       ensureSize(this.size + k)
   69       xs match {
   70         case xs: Iterable[T] => xs.copyToArray(elems, this.size)
   71         case _ => xs.iterator.copyToArray(elems, this.size)
   72       }
   73       size += k
   74     } else if(k < 0) super.addAll(xs)
   75     this
   76   }
   77 }
   78 
   79 /** A companion object for array builders.
   80  *
   81  *  @since 2.8
   82  */
   83 object ArrayBuilder {
   84 
   85   /** Creates a new arraybuilder of type `T`.
   86    *
   87    *  @tparam T     type of the elements for the array builder, with a `ClassTag` context bound.
   88    *  @return       a new empty array builder.
   89    */
   90   @inline
   91   def make[T: ClassTag]: ArrayBuilder[T] =
   92     new ArrayBuilder.generic[T](implicitly[ClassTag[T]].runtimeClass)
   93 
   94   /** A generic ArrayBuilder optimized for Scala.js.
   95    *
   96    *  @tparam T              type of elements for the array builder.
   97    *  @param  elementClass   runtime class of the elements in the array.
   98    */
   99   @inline
  100   private final class generic[T](elementClass: Class[_]) extends ArrayBuilder[T] {
  101 
  102     private val isCharArrayBuilder = classOf[Char] == elementClass
  103     protected[this] def elems: Array[T] = throw new Error("unreachable")
  104     private var jsElems: js.Array[Any] = js.Array()
  105 
  106     def addOne(elem: T): this.type = {
  107       val unboxedElem =
  108         if (isCharArrayBuilder) elem.asInstanceOf[Char].toInt
  109         else if (elem == null) zeroOf(elementClass)
  110         else elem
  111       jsElems.push(unboxedElem)
  112       this
  113     }
  114 
  115     /** Add a slice of an array */
  116     override def addAll(xs: Array[_ <: T], offset: Int, length: Int): this.type = {
  117       val end = offset + length
  118       var i = offset
  119       while (i < end) {
  120         this += xs(i)
  121         i += 1
  122       }
  123       this
  124     }
  125 
  126     override def addAll(xs: IterableOnce[T]): this.type = {
  127       val it = xs.iterator
  128       while (it.hasNext) {
  129         this += it.next()
  130       }
  131       this
  132     }
  133 
  134     override def clear(): Unit =
  135       jsElems = js.Array()
  136 
  137     protected[this] def resize(size: Int): Unit = ()
  138 
  139     def result(): Array[T] = {
  140       val elemRuntimeClass =
  141         if (classOf[Unit] == elementClass) classOf[BoxedUnit]
  142         else if (classOf[Null] == elementClass || classOf[Nothing] == elementClass) classOf[Object]
  143         else elementClass
  144       genericArrayBuilderResult(elemRuntimeClass, jsElems)
  145     }
  146 
  147     override def toString(): String = "ArrayBuilder.generic"
  148   }
  149 
  150   // Intrinsic
  151   private def zeroOf(runtimeClass: Class[_]): Any = runtimeClass match {
  152     case java.lang.Byte.TYPE      => 0.toByte
  153     case java.lang.Short.TYPE     => 0.toShort
  154     case java.lang.Character.TYPE => 0 // yes, as an Int
  155     case java.lang.Integer.TYPE   => 0
  156     case java.lang.Long.TYPE      => 0L
  157     case java.lang.Float.TYPE     => 0.0f
  158     case java.lang.Double.TYPE    => 0.0
  159     case java.lang.Boolean.TYPE   => false
  160     case java.lang.Void.TYPE      => ()
  161     case _                        => null
  162   }
  163 
  164   // Intrinsic
  165   private def genericArrayBuilderResult[T](runtimeClass: Class[_],
  166       a: js.Array[Any]): Array[T] = {
  167     val len = a.length
  168 
  169     if (classOf[Char] == runtimeClass) {
  170       val result = new Array[Char](len)
  171       var i = 0
  172       while (i != len) {
  173         result(i) = a(i).asInstanceOf[Int].toChar
  174         i += 1
  175       }
  176       result.asInstanceOf[Array[T]]
  177     } else {
  178       val result: Array[T] = java.lang.reflect.Array.newInstance(
  179           runtimeClass, len).asInstanceOf[Array[T]]
  180       var i = 0
  181       while (i != len) {
  182         result(i) = a(i).asInstanceOf[T]
  183         i += 1
  184       }
  185       result
  186     }
  187   }
  188 
  189   /** A class for array builders for arrays of reference types.
  190    *
  191    *  This builder can be reused.
  192    *
  193    *  @tparam T     type of elements for the array builder, subtype of `AnyRef` with a `ClassTag` context bound.
  194    */
  195   @SerialVersionUID(3L)
  196   final class ofRef[T <: AnyRef](implicit ct: ClassTag[T]) extends ArrayBuilder[T] {
  197 
  198     protected var elems: Array[T] = _
  199 
  200     private def mkArray(size: Int): Array[T] = {
  201       if (capacity == size && capacity > 0) elems
  202       else if (elems eq null) new Array[T](size)
  203       else java.util.Arrays.copyOf[T](elems, size)
  204     }
  205 
  206     protected[this] def resize(size: Int): Unit = {
  207       elems = mkArray(size)
  208       capacity = size
  209     }
  210 
  211     def addOne(elem: T): this.type = {
  212       ensureSize(size + 1)
  213       elems(size) = elem
  214       size += 1
  215       this
  216     }
  217 
  218     def result() = {
  219       if (capacity != 0 && capacity == size) {
  220         capacity = 0
  221         val res = elems
  222         elems = null
  223         res
  224       }
  225       else mkArray(size)
  226     }
  227 
  228     override def clear(): Unit = {
  229       super.clear()
  230       if(elems ne null) java.util.Arrays.fill(elems.asInstanceOf[Array[AnyRef]], null)
  231     }
  232 
  233     override def equals(other: Any): Boolean = other match {
  234       case x: ofRef[_] => (size == x.size) && (elems == x.elems)
  235       case _ => false
  236     }
  237 
  238     override def toString = "ArrayBuilder.ofRef"
  239   }
  240 
  241   /** A class for array builders for arrays of `byte`s. It can be reused. */
  242   @SerialVersionUID(3L)
  243   final class ofByte extends ArrayBuilder[Byte] {
  244 
  245     protected var elems: Array[Byte] = _
  246 
  247     private def mkArray(size: Int): Array[Byte] = {
  248       val newelems = new Array[Byte](size)
  249       if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size)
  250       newelems
  251     }
  252 
  253     protected[this] def resize(size: Int): Unit = {
  254       elems = mkArray(size)
  255       capacity = size
  256     }
  257 
  258     def addOne(elem: Byte): this.type = {
  259       ensureSize(size + 1)
  260       elems(size) = elem
  261       size += 1
  262       this
  263     }
  264 
  265     def result() = {
  266       if (capacity != 0 && capacity == size) {
  267         capacity = 0
  268         val res = elems
  269         elems = null
  270         res
  271       }
  272       else mkArray(size)
  273     }
  274 
  275     override def equals(other: Any): Boolean = other match {
  276       case x: ofByte => (size == x.size) && (elems == x.elems)
  277       case _ => false
  278     }
  279 
  280     override def toString = "ArrayBuilder.ofByte"
  281   }
  282 
  283   /** A class for array builders for arrays of `short`s. It can be reused. */
  284   @SerialVersionUID(3L)
  285   final class ofShort extends ArrayBuilder[Short] {
  286 
  287     protected var elems: Array[Short] = _
  288 
  289     private def mkArray(size: Int): Array[Short] = {
  290       val newelems = new Array[Short](size)
  291       if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size)
  292       newelems
  293     }
  294 
  295     protected[this] def resize(size: Int): Unit = {
  296       elems = mkArray(size)
  297       capacity = size
  298     }
  299 
  300     def addOne(elem: Short): this.type = {
  301       ensureSize(size + 1)
  302       elems(size) = elem
  303       size += 1
  304       this
  305     }
  306 
  307     def result() = {
  308       if (capacity != 0 && capacity == size) {
  309         capacity = 0
  310         val res = elems
  311         elems = null
  312         res
  313       }
  314       else mkArray(size)
  315     }
  316 
  317     override def equals(other: Any): Boolean = other match {
  318       case x: ofShort => (size == x.size) && (elems == x.elems)
  319       case _ => false
  320     }
  321 
  322     override def toString = "ArrayBuilder.ofShort"
  323   }
  324 
  325   /** A class for array builders for arrays of `char`s. It can be reused. */
  326   @SerialVersionUID(3L)
  327   final class ofChar extends ArrayBuilder[Char] {
  328 
  329     protected var elems: Array[Char] = _
  330 
  331     private def mkArray(size: Int): Array[Char] = {
  332       val newelems = new Array[Char](size)
  333       if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size)
  334       newelems
  335     }
  336 
  337     protected[this] def resize(size: Int): Unit = {
  338       elems = mkArray(size)
  339       capacity = size
  340     }
  341 
  342     def addOne(elem: Char): this.type = {
  343       ensureSize(size + 1)
  344       elems(size) = elem
  345       size += 1
  346       this
  347     }
  348 
  349     def result() = {
  350       if (capacity != 0 && capacity == size) {
  351         capacity = 0
  352         val res = elems
  353         elems = null
  354         res
  355       }
  356       else mkArray(size)
  357     }
  358 
  359     override def equals(other: Any): Boolean = other match {
  360       case x: ofChar => (size == x.size) && (elems == x.elems)
  361       case _ => false
  362     }
  363 
  364     override def toString = "ArrayBuilder.ofChar"
  365   }
  366 
  367   /** A class for array builders for arrays of `int`s. It can be reused. */
  368   @SerialVersionUID(3L)
  369   final class ofInt extends ArrayBuilder[Int] {
  370 
  371     protected var elems: Array[Int] = _
  372 
  373     private def mkArray(size: Int): Array[Int] = {
  374       val newelems = new Array[Int](size)
  375       if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size)
  376       newelems
  377     }
  378 
  379     protected[this] def resize(size: Int): Unit = {
  380       elems = mkArray(size)
  381       capacity = size
  382     }
  383 
  384     def addOne(elem: Int): this.type = {
  385       ensureSize(size + 1)
  386       elems(size) = elem
  387       size += 1
  388       this
  389     }
  390 
  391     def result() = {
  392       if (capacity != 0 && capacity == size) {
  393         capacity = 0
  394         val res = elems
  395         elems = null
  396         res
  397       }
  398       else mkArray(size)
  399     }
  400 
  401     override def equals(other: Any): Boolean = other match {
  402       case x: ofInt => (size == x.size) && (elems == x.elems)
  403       case _ => false
  404     }
  405 
  406     override def toString = "ArrayBuilder.ofInt"
  407   }
  408 
  409   /** A class for array builders for arrays of `long`s. It can be reused. */
  410   @SerialVersionUID(3L)
  411   final class ofLong extends ArrayBuilder[Long] {
  412 
  413     protected var elems: Array[Long] = _
  414 
  415     private def mkArray(size: Int): Array[Long] = {
  416       val newelems = new Array[Long](size)
  417       if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size)
  418       newelems
  419     }
  420 
  421     protected[this] def resize(size: Int): Unit = {
  422       elems = mkArray(size)
  423       capacity = size
  424     }
  425 
  426     def addOne(elem: Long): this.type = {
  427       ensureSize(size + 1)
  428       elems(size) = elem
  429       size += 1
  430       this
  431     }
  432 
  433     def result() = {
  434       if (capacity != 0 && capacity == size) {
  435         capacity = 0
  436         val res = elems
  437         elems = null
  438         res
  439       }
  440       else mkArray(size)
  441     }
  442 
  443     override def equals(other: Any): Boolean = other match {
  444       case x: ofLong => (size == x.size) && (elems == x.elems)
  445       case _ => false
  446     }
  447 
  448     override def toString = "ArrayBuilder.ofLong"
  449   }
  450 
  451   /** A class for array builders for arrays of `float`s. It can be reused. */
  452   @SerialVersionUID(3L)
  453   final class ofFloat extends ArrayBuilder[Float] {
  454 
  455     protected var elems: Array[Float] = _
  456 
  457     private def mkArray(size: Int): Array[Float] = {
  458       val newelems = new Array[Float](size)
  459       if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size)
  460       newelems
  461     }
  462 
  463     protected[this] def resize(size: Int): Unit = {
  464       elems = mkArray(size)
  465       capacity = size
  466     }
  467 
  468     def addOne(elem: Float): this.type = {
  469       ensureSize(size + 1)
  470       elems(size) = elem
  471       size += 1
  472       this
  473     }
  474 
  475     def result() = {
  476       if (capacity != 0 && capacity == size) {
  477         capacity = 0
  478         val res = elems
  479         elems = null
  480         res
  481       }
  482       else mkArray(size)
  483     }
  484 
  485     override def equals(other: Any): Boolean = other match {
  486       case x: ofFloat => (size == x.size) && (elems == x.elems)
  487       case _ => false
  488     }
  489 
  490     override def toString = "ArrayBuilder.ofFloat"
  491   }
  492 
  493   /** A class for array builders for arrays of `double`s. It can be reused. */
  494   @SerialVersionUID(3L)
  495   final class ofDouble extends ArrayBuilder[Double] {
  496 
  497     protected var elems: Array[Double] = _
  498 
  499     private def mkArray(size: Int): Array[Double] = {
  500       val newelems = new Array[Double](size)
  501       if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size)
  502       newelems
  503     }
  504 
  505     protected[this] def resize(size: Int): Unit = {
  506       elems = mkArray(size)
  507       capacity = size
  508     }
  509 
  510     def addOne(elem: Double): this.type = {
  511       ensureSize(size + 1)
  512       elems(size) = elem
  513       size += 1
  514       this
  515     }
  516 
  517     def result() = {
  518       if (capacity != 0 && capacity == size) {
  519         capacity = 0
  520         val res = elems
  521         elems = null
  522         res
  523       }
  524       else mkArray(size)
  525     }
  526 
  527     override def equals(other: Any): Boolean = other match {
  528       case x: ofDouble => (size == x.size) && (elems == x.elems)
  529       case _ => false
  530     }
  531 
  532     override def toString = "ArrayBuilder.ofDouble"
  533   }
  534 
  535   /** A class for array builders for arrays of `boolean`s. It can be reused. */
  536   @SerialVersionUID(3L)
  537   class ofBoolean extends ArrayBuilder[Boolean] {
  538 
  539     protected var elems: Array[Boolean] = _
  540 
  541     private def mkArray(size: Int): Array[Boolean] = {
  542       val newelems = new Array[Boolean](size)
  543       if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size)
  544       newelems
  545     }
  546 
  547     protected[this] def resize(size: Int): Unit = {
  548       elems = mkArray(size)
  549       capacity = size
  550     }
  551 
  552     def addOne(elem: Boolean): this.type = {
  553       ensureSize(size + 1)
  554       elems(size) = elem
  555       size += 1
  556       this
  557     }
  558 
  559     def result() = {
  560       if (capacity != 0 && capacity == size) {
  561         capacity = 0
  562         val res = elems
  563         elems = null
  564         res
  565       }
  566       else mkArray(size)
  567     }
  568 
  569     override def equals(other: Any): Boolean = other match {
  570       case x: ofBoolean => (size == x.size) && (elems == x.elems)
  571       case _ => false
  572     }
  573 
  574     override def toString = "ArrayBuilder.ofBoolean"
  575   }
  576 
  577   /** A class for array builders for arrays of `Unit` type. It can be reused. */
  578   @SerialVersionUID(3L)
  579   final class ofUnit extends ArrayBuilder[Unit] {
  580 
  581     protected def elems: Array[Unit] = throw new UnsupportedOperationException()
  582 
  583     def addOne(elem: Unit): this.type = {
  584       size += 1
  585       this
  586     }
  587 
  588     override def addAll(xs: IterableOnce[Unit]): this.type = {
  589       size += xs.iterator.size
  590       this
  591     }
  592 
  593     override def addAll(xs: Array[_ <: Unit], offset: Int, length: Int): this.type = {
  594       size += length
  595       this
  596     }
  597 
  598     def result() = {
  599       val ans = new Array[Unit](size)
  600       var i = 0
  601       while (i < size) { ans(i) = (); i += 1 }
  602       ans
  603     }
  604 
  605     override def equals(other: Any): Boolean = other match {
  606       case x: ofUnit => (size == x.size)
  607       case _ => false
  608     }
  609 
  610     protected[this] def resize(size: Int): Unit = ()
  611 
  612     override def toString = "ArrayBuilder.ofUnit"
  613   }
  614 }