"Fossies" - the Fresh Open Source Software Archive

Member "scala-js-1.3.1/javalib/src/main/scala/java/util/AbstractList.scala" (14 Nov 2020, 6833 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. See also the last Fossies "Diffs" side-by-side code changes report for "AbstractList.scala": 1.2.0_vs_1.3.0.

    1 /*
    2  * Scala.js (https://www.scala-js.org/)
    3  *
    4  * Copyright EPFL.
    5  *
    6  * Licensed under Apache License 2.0
    7  * (https://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 java.util
   14 
   15 import scala.annotation.tailrec
   16 
   17 import ScalaOps._
   18 
   19 abstract class AbstractList[E] protected () extends AbstractCollection[E]
   20     with List[E] {
   21   self =>
   22 
   23   override def add(element: E): Boolean = {
   24     add(size(), element)
   25     true
   26   }
   27 
   28   def set(index: Int, element: E): E =
   29     throw new UnsupportedOperationException
   30 
   31   def add(index: Int, element: E): Unit =
   32     throw new UnsupportedOperationException
   33 
   34   def remove(index: Int): E =
   35     throw new UnsupportedOperationException
   36 
   37   def indexOf(o: Any): Int =
   38     this.scalaOps.indexWhere(Objects.equals(_, o))
   39 
   40   def lastIndexOf(o: Any): Int = {
   41     @tailrec
   42     def findIndex(iter: ListIterator[E]): Int = {
   43       if (!iter.hasPrevious()) -1
   44       else if (Objects.equals(iter.previous(), o)) iter.nextIndex()
   45       else findIndex(iter)
   46     }
   47     findIndex(listIterator(size()))
   48   }
   49 
   50   override def clear(): Unit =
   51     removeRange(0, size())
   52 
   53   def addAll(index: Int, c: Collection[_ <: E]): Boolean = {
   54     checkIndexOnBounds(index)
   55     var i = index
   56     val iter = c.iterator()
   57     while (iter.hasNext()) {
   58       add(i, iter.next())
   59       i += 1
   60     }
   61     !c.isEmpty()
   62   }
   63 
   64   def iterator(): Iterator[E] =
   65     listIterator()
   66 
   67   def listIterator(): ListIterator[E] =
   68     listIterator(0)
   69 
   70   def listIterator(index: Int): ListIterator[E] = {
   71     checkIndexOnBounds(index)
   72     // By default we use RandomAccessListIterator because we only have access to
   73     // the get(index) operation in the API. Subclasses override this if needs
   74     // using their knowledge of the structure instead.
   75     new RandomAccessListIterator(self, index, 0, size())
   76   }
   77 
   78   def subList(fromIndex: Int, toIndex: Int): List[E] = {
   79     if (fromIndex < 0)
   80       throw new IndexOutOfBoundsException(fromIndex.toString)
   81     else if (toIndex > size())
   82       throw new IndexOutOfBoundsException(toIndex.toString)
   83     else if (fromIndex > toIndex)
   84       throw new IllegalArgumentException
   85 
   86     self match {
   87       case _: RandomAccess =>
   88         new AbstractListView(self, fromIndex, toIndex) with RandomAccess { selfView =>
   89           override def listIterator(index: Int): ListIterator[E] = {
   90             checkIndexOnBounds(index)
   91             // Iterator that accesses the original list directly
   92             new RandomAccessListIterator(self, fromIndex + index, fromIndex, selfView.toIndex) {
   93               override protected def onSizeChanged(delta: Int): Unit = changeViewSize(delta)
   94             }
   95           }
   96         }
   97       case _ =>
   98         new AbstractListView(self, fromIndex, toIndex) { selfView =>
   99           override def listIterator(index: Int): ListIterator[E] = {
  100             checkIndexOnBounds(index)
  101             // Iterator that accesses the original list using it's iterator
  102             new BackedUpListIterator(list.listIterator(fromIndex + index),
  103                 fromIndex, selfView.toIndex - fromIndex) {
  104               override protected def onSizeChanged(delta: Int): Unit = changeViewSize(delta)
  105             }
  106           }
  107         }
  108     }
  109   }
  110 
  111   override def equals(o: Any): Boolean = {
  112     if (o.asInstanceOf[AnyRef] eq this) {
  113       true
  114     } else {
  115       o match {
  116         case o: List[_] =>
  117           val oIter = o.listIterator()
  118           this.scalaOps.forall(oIter.hasNext() && Objects.equals(_, oIter.next())) && !oIter.hasNext()
  119         case _ => false
  120       }
  121     }
  122   }
  123 
  124   override def hashCode(): Int = {
  125     this.scalaOps.foldLeft(1) {
  126       (prev, elem) => 31 * prev + Objects.hashCode(elem)
  127     }
  128   }
  129 
  130   protected def removeRange(fromIndex: Int, toIndex: Int): Unit = {
  131     val iter = listIterator(fromIndex)
  132     for (_ <- fromIndex until toIndex) {
  133       iter.next()
  134       iter.remove()
  135     }
  136   }
  137 
  138   protected[this] def checkIndexInBounds(index: Int): Unit = {
  139     if (index < 0 || index >= size())
  140       throw new IndexOutOfBoundsException(index.toString)
  141   }
  142 
  143   protected[this] def checkIndexOnBounds(index: Int): Unit = {
  144     if (index < 0 || index > size())
  145       throw new IndexOutOfBoundsException(index.toString)
  146   }
  147 }
  148 
  149 private abstract class AbstractListView[E](protected val list: List[E],
  150     fromIndex: Int, protected var toIndex: Int) extends AbstractList[E] {
  151 
  152   override def add(index: Int, e: E): Unit = {
  153     checkIndexOnBounds(index)
  154     list.add(fromIndex + index, e)
  155     changeViewSize(1)
  156   }
  157 
  158   override def addAll(index: Int, c: Collection[_ <: E]): Boolean = {
  159     checkIndexOnBounds(index)
  160     list.addAll(fromIndex + index, c)
  161     val elementsAdded = c.size()
  162     toIndex += elementsAdded
  163     elementsAdded != 0
  164   }
  165 
  166   override def addAll(c: Collection[_ <: E]): Boolean =
  167     addAll(size(), c)
  168 
  169   def get(index: Int): E = {
  170     checkIndexInBounds(index)
  171     list.get(fromIndex + index)
  172   }
  173 
  174   override def remove(index: Int): E = {
  175     checkIndexInBounds(index)
  176     val elem = list.remove(fromIndex + index)
  177     changeViewSize(-1)
  178     elem
  179   }
  180 
  181   override def set(index: Int, e: E): E = {
  182     checkIndexInBounds(index)
  183     list.set(fromIndex + index, e)
  184   }
  185 
  186   def size(): Int =
  187     toIndex - fromIndex
  188 
  189   @inline
  190   protected def changeViewSize(delta: Int): Unit =
  191     toIndex += delta
  192 }
  193 
  194 /* BackedUpListIterator implementation assumes that the underling list is not
  195  * necessarily on a RandomAccess list. Hence it wraps the underling list
  196  * iterator and assumes that this one is more efficient than accessing
  197  * elements by index.
  198  */
  199 private class BackedUpListIterator[E](innerIterator: ListIterator[E], fromIndex: Int,
  200     override protected var end: Int) extends ListIterator[E] with SizeChangeEvent {
  201 
  202   def hasNext(): Boolean =
  203     i < end
  204 
  205   def next(): E =
  206     innerIterator.next()
  207 
  208   def hasPrevious(): Boolean =
  209     0 < i
  210 
  211   def previous(): E =
  212     innerIterator.previous()
  213 
  214   def nextIndex(): Int = i
  215 
  216   def previousIndex(): Int = i - 1
  217 
  218   override def remove(): Unit = {
  219     innerIterator.remove()
  220     changeSize(-1)
  221   }
  222 
  223   def set(e: E): Unit =
  224     innerIterator.set(e)
  225 
  226   def add(e: E): Unit = {
  227     innerIterator.add(e)
  228     changeSize(1)
  229   }
  230 
  231   private def i: Int =
  232     innerIterator.nextIndex() - fromIndex
  233 }
  234 
  235 /* RandomAccessListIterator implementation assumes that the has an efficient
  236  * .get(index) implementation.
  237  */
  238 private class RandomAccessListIterator[E](list: List[E], i: Int, start: Int, end: Int)
  239     extends AbstractRandomAccessListIterator[E](i, start, end) {
  240 
  241   protected def get(index: Int): E =
  242     list.get(index)
  243 
  244   protected def set(index: Int, e: E): Unit =
  245     list.set(index, e)
  246 
  247   protected def remove(index: Int): Unit =
  248     list.remove(index)
  249 
  250   protected def add(index: Int, e: E): Unit =
  251     list.add(index, e)
  252 }