From 6d64fa0800507efb430dbd13d53bf49a54380670 Mon Sep 17 00:00:00 2001 From: Lukas Rytz Date: Wed, 13 Jun 2018 16:13:11 +0200 Subject: [PATCH 01/23] disable docs for now, no genjavadoc yet --- build.sbt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/build.sbt b/build.sbt index fbb4c54..05111e0 100644 --- a/build.sbt +++ b/build.sbt @@ -6,7 +6,7 @@ crossScalaVersions in ThisBuild := List("2.12.6", "2.11.12") val disableDocs = sys.props("nodocs") == "true" -lazy val JavaDoc = config("genjavadoc") extend Compile +//lazy val JavaDoc = config("genjavadoc") extend Compile def jwrite(dir: java.io.File, pck: String = "scala/compat/java8")(name: String, content: String) = { val f = dir / pck / s"${name}.java" @@ -105,6 +105,9 @@ lazy val root = (project in file(".")). } ). settings( + sources in (Compile,doc) := Seq.empty, + publishArtifact in (Compile, packageDoc) := false). +/* settings( (inConfig(JavaDoc)(Defaults.configSettings) ++ (if (disableDocs) Nil else Seq( packageDoc in Compile := (packageDoc in JavaDoc).value, sources in JavaDoc := { @@ -118,7 +121,7 @@ lazy val root = (project in file(".")). libraryDependencies += compilerPlugin("com.typesafe.genjavadoc" % "genjavadoc-plugin" % "0.11" cross CrossVersion.full), scalacOptions in Compile += "-P:genjavadoc:out=" + (target.value / "java") ))): _* - ). + ).*/ settings( initialCommands := """|import scala.concurrent._ From da376f7cdfa26901c804f60dc31b59566b9b76c3 Mon Sep 17 00:00:00 2001 From: Lukas Rytz Date: Wed, 13 Jun 2018 16:13:20 +0200 Subject: [PATCH 02/23] Compatibility with 2.13 collections --- .travis.yml | 5 +- build.sbt | 4 +- .../compat/java8/ScalaStreamSupport.java | 34 ++-- .../java8/runtime/CollectionInternals.java | 15 +- .../scala/compat/java8/StreamConverters.scala | 24 +-- .../java8/collectionImpl/Accumulator.scala | 10 +- .../collectionImpl/DoubleAccumulator.scala | 10 +- .../java8/collectionImpl/IntAccumulator.scala | 10 +- .../collectionImpl/LongAccumulator.scala | 10 +- .../compat/java8/collectionImpl/Stepper.scala | 4 +- .../java8/converterImpl/Accumulates.scala | 16 +- .../converterImpl/AccumulatorConverters.scala | 8 +- .../java8/converterImpl/StepConverters.scala | 8 +- .../converterImpl/StepsFlatHashTable.scala | 2 +- .../java8/converterImpl/StepsHashTable.scala | 160 +++++++++--------- .../java8/converterImpl/StepsIndexedSeq.scala | 20 +-- .../java8/FutureConvertersImpl.scala | 2 +- .../compat/java8/StepConvertersTest.scala | 94 +++++----- 18 files changed, 213 insertions(+), 223 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9d271a6..05ddddf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,10 +6,7 @@ jdk: - oraclejdk8 scala: - # no 2.13 for now in cross-build because of - # https://github.com/scala/scala-java8-compat/issues/97 - - 2.11.12 - - 2.12.6 + - 2.13.0-M4 env: global: diff --git a/build.sbt b/build.sbt index 05111e0..87f5e9e 100644 --- a/build.sbt +++ b/build.sbt @@ -1,8 +1,6 @@ import ScalaModulePlugin._ -// no 2.13 for now in cross-build because of -// https://github.com/scala/scala-java8-compat/issues/97 -crossScalaVersions in ThisBuild := List("2.12.6", "2.11.12") +crossScalaVersions in ThisBuild := List("2.13.0-M4") val disableDocs = sys.props("nodocs") == "true" diff --git a/src/main/java/scala/compat/java8/ScalaStreamSupport.java b/src/main/java/scala/compat/java8/ScalaStreamSupport.java index b0d3452..e403bf0 100644 --- a/src/main/java/scala/compat/java8/ScalaStreamSupport.java +++ b/src/main/java/scala/compat/java8/ScalaStreamSupport.java @@ -29,7 +29,7 @@ public class ScalaStreamSupport { * @return A Stream view of the collection which, by default, executes sequentially. */ public static Stream stream(scala.collection.IndexedSeq coll) { - return StreamSupport.stream(new StepsAnyIndexedSeq(coll, 0, coll.length()), false); + return StreamSupport.stream(new StepsAnyIndexedSeq((scala.collection.IndexedSeq)coll, 0, coll.length()), false); } /** @@ -90,7 +90,7 @@ public static Stream stream(scala.collection.immutable.HashSet coll) { * @return A Stream view of the collection which, by default, executes sequentially. */ public static Stream streamKeys(scala.collection.mutable.HashMap coll) { - scala.collection.mutable.HashEntry[] tbl = CollectionInternals.getTable(coll); + Object[] tbl = CollectionInternals.getTable(coll); return StreamSupport.stream(new StepsAnyHashTableKey(tbl, 0, tbl.length), false); } @@ -103,7 +103,7 @@ public static Stream streamKeys(scala.collection.mutable.HashMap co * @return A Stream view of the collection which, by default, executes sequentially. */ public static Stream streamValues(scala.collection.mutable.HashMap coll) { - scala.collection.mutable.HashEntry[] tbl = CollectionInternals.getTable(coll); + Object[] tbl = CollectionInternals.getTable(coll); return StreamSupport.stream(new StepsAnyDefaultHashTableValue(tbl, 0, tbl.length), false); } @@ -117,7 +117,7 @@ public static Stream streamValues(scala.collection.mutable.HashMap Stream< scala.Tuple2 > stream(scala.collection.mutable.HashMap coll) { - scala.collection.mutable.HashEntry< K, scala.collection.mutable.DefaultEntry >[] tbl = + Object[] tbl = CollectionInternals.getTable(coll); return StreamSupport.stream(new StepsAnyDefaultHashTable(tbl, 0, tbl.length), false); } @@ -226,7 +226,7 @@ public static Stream stream(scala.collection.Iterable coll) { * @param coll The collection to traverse * @return A Stream view of the collection which, by default, executes sequentially. */ - public static Stream streamAccumulated(scala.collection.TraversableOnce coll) { + public static Stream streamAccumulated(scala.collection.IterableOnce coll) { scala.compat.java8.collectionImpl.Accumulator acc = scala.compat.java8.collectionImpl.Accumulator.from(coll); return StreamSupport.stream(acc.spliterator(), false); } @@ -321,7 +321,7 @@ public static DoubleStream doubleStream(scala.collection.immutable.HashSet coll) { - scala.collection.mutable.HashEntry[] tbl = CollectionInternals.getTable(coll); + Object[] tbl = CollectionInternals.getTable(coll); return StreamSupport.doubleStream(new StepsDoubleHashTableKey(tbl, 0, tbl.length), false); } @@ -334,7 +334,7 @@ public static DoubleStream doubleStreamKeys(scala.collection.mutable.HashMap coll) { - scala.collection.mutable.HashEntry[] tbl = CollectionInternals.getTable(coll); + Object[] tbl = CollectionInternals.getTable(coll); return StreamSupport.doubleStream(new StepsDoubleDefaultHashTableValue(tbl, 0, tbl.length), false); } @@ -432,9 +432,9 @@ public static DoubleStream doubleStream(scala.collection.Iterable coll) * @param coll The collection to traverse * @return A Stream view of the collection which, by default, executes sequentially. */ - public static DoubleStream doubleStreamAccumulated(scala.collection.TraversableOnce coll) { + public static DoubleStream doubleStreamAccumulated(scala.collection.IterableOnce coll) { scala.compat.java8.collectionImpl.DoubleAccumulator acc = - scala.compat.java8.collectionImpl.DoubleAccumulator.from((scala.collection.TraversableOnce)coll); + scala.compat.java8.collectionImpl.DoubleAccumulator.from((scala.collection.IterableOnce)coll); return StreamSupport.doubleStream(acc.spliterator(), false); } @@ -557,7 +557,7 @@ public static IntStream intStream(scala.collection.immutable.HashSet co * @return A IntStream view of the collection which, by default, executes sequentially. */ public static IntStream intStreamKeys(scala.collection.mutable.HashMap coll) { - scala.collection.mutable.HashEntry[] tbl = CollectionInternals.getTable(coll); + Object[] tbl = CollectionInternals.getTable(coll); return StreamSupport.intStream(new StepsIntHashTableKey(tbl, 0, tbl.length), false); } @@ -570,7 +570,7 @@ public static IntStream intStreamKeys(scala.collection.mutable.HashMap coll) { - scala.collection.mutable.HashEntry[] tbl = CollectionInternals.getTable(coll); + Object[] tbl = CollectionInternals.getTable(coll); return StreamSupport.intStream(new StepsIntDefaultHashTableValue(tbl, 0, tbl.length), false); } @@ -668,9 +668,9 @@ public static IntStream intStream(scala.collection.Iterable coll) { * @param coll The collection to traverse * @return A Stream view of the collection which, by default, executes sequentially. */ - public static IntStream intStreamAccumulated(scala.collection.TraversableOnce coll) { + public static IntStream intStreamAccumulated(scala.collection.IterableOnce coll) { scala.compat.java8.collectionImpl.IntAccumulator acc = - scala.compat.java8.collectionImpl.IntAccumulator.from((scala.collection.TraversableOnce)coll); + scala.compat.java8.collectionImpl.IntAccumulator.from((scala.collection.IterableOnce)coll); return StreamSupport.intStream(acc.spliterator(), false); } @@ -766,7 +766,7 @@ public static LongStream longStream(scala.collection.immutable.HashSet col * @return A LongStream view of the collection which, by default, executes sequentially. */ public static LongStream longStreamKeys(scala.collection.mutable.HashMap coll) { - scala.collection.mutable.HashEntry[] tbl = CollectionInternals.getTable(coll); + Object[] tbl = CollectionInternals.getTable(coll); return StreamSupport.longStream(new StepsLongHashTableKey(tbl, 0, tbl.length), false); } @@ -779,7 +779,7 @@ public static LongStream longStreamKeys(scala.collection.mutable.HashMap coll) { - scala.collection.mutable.HashEntry[] tbl = CollectionInternals.getTable(coll); + Object[] tbl = CollectionInternals.getTable(coll); return StreamSupport.longStream(new StepsLongDefaultHashTableValue(tbl, 0, tbl.length), false); } @@ -877,9 +877,9 @@ public static LongStream longStream(scala.collection.Iterable coll) { * @param coll The collection to traverse * @return A Stream view of the collection which, by default, executes sequentially. */ - public static LongStream longStreamAccumulated(scala.collection.TraversableOnce coll) { + public static LongStream longStreamAccumulated(scala.collection.IterableOnce coll) { scala.compat.java8.collectionImpl.LongAccumulator acc = - scala.compat.java8.collectionImpl.LongAccumulator.from((scala.collection.TraversableOnce)coll); + scala.compat.java8.collectionImpl.LongAccumulator.from((scala.collection.IterableOnce)coll); return StreamSupport.longStream(acc.spliterator(), false); } diff --git a/src/main/java/scala/compat/java8/runtime/CollectionInternals.java b/src/main/java/scala/compat/java8/runtime/CollectionInternals.java index 6f8da89..5f34e15 100644 --- a/src/main/java/scala/compat/java8/runtime/CollectionInternals.java +++ b/src/main/java/scala/compat/java8/runtime/CollectionInternals.java @@ -3,14 +3,24 @@ // No imports! All type names are fully qualified to avoid confusion! public class CollectionInternals { - public static Object[] getTable(scala.collection.mutable.FlatHashTable fht) { return fht.hashTableContents().table(); } - public static > scala.collection.mutable.HashEntry[] getTable(scala.collection.mutable.HashTable ht) { return ht.hashTableContents().table(); } + public static Object[] getTable(scala.collection.mutable.HashSet hs) { return hs.getTable().table(); } + public static Object[] getTable(scala.collection.mutable.LinkedHashSet hm) { return hm.getTable().table(); } + + public static Object[] getTable(scala.collection.mutable.HashMap hm) { return hm.getTable().table(); } + public static Object[] getTable(scala.collection.mutable.LinkedHashMap hm) { return hm.getTable().table(); } + + public static K hashEntryKey(Object hashEntry) { return ((scala.collection.mutable.HashEntry)hashEntry).key(); } + public static Object hashEntryNext(Object hashEntry) { return ((scala.collection.mutable.HashEntry)hashEntry).next(); } + public static V linkedEntryValue(Object hashEntry) { return ((scala.collection.mutable.LinkedHashMap.LinkedEntry)hashEntry).value(); } + public static V defaultEntryValue(Object hashEntry) { return ((scala.collection.mutable.DefaultEntry)hashEntry).value(); } + public static Object[] getDisplay0(scala.collection.immutable.Vector v) { return v.display0(); } public static Object[] getDisplay1(scala.collection.immutable.Vector v) { return v.display1(); } public static Object[] getDisplay2(scala.collection.immutable.Vector v) { return v.display2(); } public static Object[] getDisplay3(scala.collection.immutable.Vector v) { return v.display3(); } public static Object[] getDisplay4(scala.collection.immutable.Vector v) { return v.display4(); } public static Object[] getDisplay5(scala.collection.immutable.Vector v) { return v.display5(); } + public static scala.Tuple2< scala.Tuple2< scala.collection.Iterator, Object >, scala.collection.Iterator > trieIteratorSplit(scala.collection.Iterator it) { if (it instanceof scala.collection.immutable.TrieIterator) { scala.collection.immutable.TrieIterator trie = (scala.collection.immutable.TrieIterator)it; @@ -18,6 +28,7 @@ public static scala.Tuple2< scala.Tuple2< scala.collection.Iterator, Obje } return null; } + public static long[] getBitSetInternals(scala.collection.mutable.BitSet bitSet) { return bitSet.elems(); } } diff --git a/src/main/scala/scala/compat/java8/StreamConverters.scala b/src/main/scala/scala/compat/java8/StreamConverters.scala index 4f773a9..48f85e1 100644 --- a/src/main/scala/scala/compat/java8/StreamConverters.scala +++ b/src/main/scala/scala/compat/java8/StreamConverters.scala @@ -92,10 +92,10 @@ trait Priority1StreamConverters extends Priority2StreamConverters { implicit class RichStream[A](stream: Stream[A]) { def accumulate = stream.collect(Accumulator.supplier[A], Accumulator.adder[A], Accumulator.merger[A]) - def toScala[Coll[_]](implicit cbf: collection.generic.CanBuildFrom[Nothing, A, Coll[A]]): Coll[A] = { - if (stream.isParallel) accumulate.to[Coll](cbf) + def toScala[Coll[_]](implicit factory: collection.Factory[A, Coll[A]]): Coll[A] = { + if (stream.isParallel) accumulate.to[Coll](factory) else { - val b = cbf() + val b = factory.newBuilder stream.forEachOrdered(new java.util.function.Consumer[A]{ def accept(a: A): Unit = { b += a } }) b.result() } @@ -264,10 +264,10 @@ with converterImpl.Priority1AccumulatorConverters implicit final class RichDoubleStream(private val stream: DoubleStream) extends AnyVal { def accumulate = stream.collect(DoubleAccumulator.supplier, DoubleAccumulator.adder, DoubleAccumulator.merger) - def toScala[Coll[_]](implicit cbf: collection.generic.CanBuildFrom[Nothing, Double, Coll[Double]]): Coll[Double] = { - if (stream.isParallel) accumulate.to[Coll](cbf) + def toScala[Coll[_]](implicit factory: collection.Factory[Double, Coll[Double]]): Coll[Double] = { + if (stream.isParallel) accumulate.to[Coll](factory) else { - val b = cbf() + val b = factory.newBuilder stream.forEachOrdered(new java.util.function.DoubleConsumer{ def accept(d: Double): Unit = { b += d } }) b.result() } @@ -277,10 +277,10 @@ with converterImpl.Priority1AccumulatorConverters implicit final class RichIntStream(private val stream: IntStream) extends AnyVal { def accumulate = stream.collect(IntAccumulator.supplier, IntAccumulator.adder, IntAccumulator.merger) - def toScala[Coll[_]](implicit cbf: collection.generic.CanBuildFrom[Nothing, Int, Coll[Int]]): Coll[Int] = { - if (stream.isParallel) accumulate.to[Coll](cbf) + def toScala[Coll[_]](implicit factory: collection.Factory[Int, Coll[Int]]): Coll[Int] = { + if (stream.isParallel) accumulate.to[Coll](factory) else { - val b = cbf() + val b = factory.newBuilder stream.forEachOrdered(new java.util.function.IntConsumer{ def accept(d: Int): Unit = { b += d } }) b.result() } @@ -290,10 +290,10 @@ with converterImpl.Priority1AccumulatorConverters implicit final class RichLongStream(private val stream: LongStream) extends AnyVal { def accumulate = stream.collect(LongAccumulator.supplier, LongAccumulator.adder, LongAccumulator.merger) - def toScala[Coll[_]](implicit cbf: collection.generic.CanBuildFrom[Nothing, Long, Coll[Long]]): Coll[Long] = { - if (stream.isParallel) accumulate.to[Coll](cbf) + def toScala[Coll[_]](implicit factory: collection.Factory[Long, Coll[Long]]): Coll[Long] = { + if (stream.isParallel) accumulate.to[Coll](factory) else { - val b = cbf() + val b = factory.newBuilder stream.forEachOrdered(new java.util.function.LongConsumer{ def accept(d: Long): Unit = { b += d } }) b.result() } diff --git a/src/main/scala/scala/compat/java8/collectionImpl/Accumulator.scala b/src/main/scala/scala/compat/java8/collectionImpl/Accumulator.scala index 39f68ac..a476a41 100644 --- a/src/main/scala/scala/compat/java8/collectionImpl/Accumulator.scala +++ b/src/main/scala/scala/compat/java8/collectionImpl/Accumulator.scala @@ -177,9 +177,9 @@ final class Accumulator[A] extends AccumulatorLike[A, Accumulator[A]] { self => /** Copies the elements in this `Accumulator` to a specified collection. * Usage example: `acc.to[Vector]` */ - final def to[Coll[_]](implicit cbf: collection.generic.CanBuildFrom[Nothing, A, Coll[A]]): Coll[A] = { + final def to[Coll[_]](implicit factory: collection.Factory[A, Coll[A]]): Coll[A] = { if (totalSize > Int.MaxValue) throw new IllegalArgumentException("Too many elements accumulated for a Scala collection: "+totalSize.toString) - val b = cbf() + val b = factory.newBuilder b.sizeHint(totalSize.toInt) var h = 0 var pv = 0L @@ -217,10 +217,10 @@ object Accumulator { /** A `BiConsumer` that merges `Accumulator`s, suitable for use with `java.util.stream.Stream`'s `collect` method. */ def merger[A] = new java.util.function.BiConsumer[Accumulator[A], Accumulator[A]]{ def accept(a1: Accumulator[A], a2: Accumulator[A]): Unit = { a1 drain a2 } } - /** Builds an `Accumulator` from any `TraversableOnce` */ - def from[A](source: TraversableOnce[A]) = { + /** Builds an `Accumulator` from any `IterableOnce` */ + def from[A](source: IterableOnce[A]) = { val a = new Accumulator[A] - source.foreach(a += _) + source.iterator.foreach(a += _) a } } diff --git a/src/main/scala/scala/compat/java8/collectionImpl/DoubleAccumulator.scala b/src/main/scala/scala/compat/java8/collectionImpl/DoubleAccumulator.scala index d43e40d..03fa2f6 100644 --- a/src/main/scala/scala/compat/java8/collectionImpl/DoubleAccumulator.scala +++ b/src/main/scala/scala/compat/java8/collectionImpl/DoubleAccumulator.scala @@ -173,9 +173,9 @@ final class DoubleAccumulator extends AccumulatorLike[Double, DoubleAccumulator] * Note that the target collection is not specialized. * Usage example: `acc.to[Vector]` */ - final def to[Coll[_]](implicit cbf: collection.generic.CanBuildFrom[Nothing, Double, Coll[Double]]): Coll[Double] = { + final def to[Coll[_]](implicit factory: collection.Factory[Double, Coll[Double]]): Coll[Double] = { if (totalSize > Int.MaxValue) throw new IllegalArgumentException("Too many elements accumulated for a Scala collection: "+totalSize.toString) - val b = cbf() + val b = factory.newBuilder b.sizeHint(totalSize.toInt) var h = 0 var pv = 0L @@ -214,10 +214,10 @@ object DoubleAccumulator { /** A `BiConsumer` that merges `DoubleAccumulator`s, suitable for use with `java.util.stream.DoubleStream`'s `collect` method. Suitable for `Stream[Double]` also. */ def merger = new java.util.function.BiConsumer[DoubleAccumulator, DoubleAccumulator]{ def accept(a1: DoubleAccumulator, a2: DoubleAccumulator): Unit = { a1 drain a2 } } - /** Builds a `DoubleAccumulator` from any `Double`-valued `TraversableOnce` */ - def from[A](source: TraversableOnce[Double]) = { + /** Builds a `DoubleAccumulator` from any `Double`-valued `IterableOnce` */ + def from[A](source: IterableOnce[Double]) = { val a = new DoubleAccumulator - source.foreach(a += _) + source.iterator.foreach(a += _) a } } diff --git a/src/main/scala/scala/compat/java8/collectionImpl/IntAccumulator.scala b/src/main/scala/scala/compat/java8/collectionImpl/IntAccumulator.scala index d962d24..a272fa6 100644 --- a/src/main/scala/scala/compat/java8/collectionImpl/IntAccumulator.scala +++ b/src/main/scala/scala/compat/java8/collectionImpl/IntAccumulator.scala @@ -178,9 +178,9 @@ final class IntAccumulator extends AccumulatorLike[Int, IntAccumulator] { self = * Note that the target collection is not specialized. * Usage example: `acc.to[Vector]` */ - final def to[Coll[_]](implicit cbf: collection.generic.CanBuildFrom[Nothing, Int, Coll[Int]]): Coll[Int] = { + final def to[Coll[_]](implicit factory: collection.Factory[Int, Coll[Int]]): Coll[Int] = { if (totalSize > Int.MaxValue) throw new IllegalArgumentException("Too many elements accumulated for a Scala collection: "+totalSize.toString) - val b = cbf() + val b = factory.newBuilder b.sizeHint(totalSize.toInt) var h = 0 var pv = 0L @@ -221,10 +221,10 @@ object IntAccumulator { /** A `BiConsumer` that merges `IntAccumulator`s, suitable for use with `java.util.stream.IntStream`'s `collect` method. Suitable for `Stream[Int]` also. */ def merger = new java.util.function.BiConsumer[IntAccumulator, IntAccumulator]{ def accept(a1: IntAccumulator, a2: IntAccumulator): Unit = { a1 drain a2 } } - /** Builds an `IntAccumulator` from any `Int`-valued `TraversableOnce` */ - def from[A](source: TraversableOnce[Int]) = { + /** Builds an `IntAccumulator` from any `Int`-valued `IterableOnce` */ + def from[A](source: IterableOnce[Int]) = { val a = new IntAccumulator - source.foreach(a += _) + source.iterator.foreach(a += _) a } } diff --git a/src/main/scala/scala/compat/java8/collectionImpl/LongAccumulator.scala b/src/main/scala/scala/compat/java8/collectionImpl/LongAccumulator.scala index 06faa21..c99601e 100644 --- a/src/main/scala/scala/compat/java8/collectionImpl/LongAccumulator.scala +++ b/src/main/scala/scala/compat/java8/collectionImpl/LongAccumulator.scala @@ -173,9 +173,9 @@ final class LongAccumulator extends AccumulatorLike[Long, LongAccumulator] { sel * Note that the target collection is not specialized. * Usage example: `acc.to[Vector]` */ - final def to[Coll[_]](implicit cbf: collection.generic.CanBuildFrom[Nothing, Long, Coll[Long]]): Coll[Long] = { + final def to[Coll[_]](implicit factory: collection.Factory[Long, Coll[Long]]): Coll[Long] = { if (totalSize > Int.MaxValue) throw new IllegalArgumentException("Too many elements accumulated for a Scala collection: "+totalSize.toString) - val b = cbf() + val b = factory.newBuilder b.sizeHint(totalSize.toInt) var h = 0 var pv = 0L @@ -215,10 +215,10 @@ object LongAccumulator { /** A `BiConsumer` that merges `LongAccumulator`s, suitable for use with `java.util.stream.LongStream`'s `collect` method. Suitable for `Stream[Long]` also. */ def merger = new java.util.function.BiConsumer[LongAccumulator, LongAccumulator]{ def accept(a1: LongAccumulator, a2: LongAccumulator): Unit = { a1 drain a2 } } - /** Builds a `LongAccumulator` from any `Long`-valued `TraversableOnce` */ - def from[A](source: TraversableOnce[Long]) = { + /** Builds a `LongAccumulator` from any `Long`-valued `IterableOnce` */ + def from[A](source: IterableOnce[Long]) = { val a = new LongAccumulator - source.foreach(a += _) + source.iterator.foreach(a += _) a } } diff --git a/src/main/scala/scala/compat/java8/collectionImpl/Stepper.scala b/src/main/scala/scala/compat/java8/collectionImpl/Stepper.scala index ffc94cb..06ed37a 100644 --- a/src/main/scala/scala/compat/java8/collectionImpl/Stepper.scala +++ b/src/main/scala/scala/compat/java8/collectionImpl/Stepper.scala @@ -167,8 +167,8 @@ trait StepperLike[@specialized(Double, Int, Long) A, +CC] { self: CC => } /** Returns a Scala collection of the type requested. */ - def to[Coll[_]](implicit cbf: collection.generic.CanBuildFrom[Nothing, A, Coll[A]]): Coll[A] = { - val b = cbf() + def to[Coll[_]](implicit factory: collection.Factory[A, Coll[A]]): Coll[A] = { + val b = factory.newBuilder while (hasStep) b += nextStep b.result() } diff --git a/src/main/scala/scala/compat/java8/converterImpl/Accumulates.scala b/src/main/scala/scala/compat/java8/converterImpl/Accumulates.scala index cb3c963..feeb8ed 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/Accumulates.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/Accumulates.scala @@ -6,34 +6,34 @@ trait AccumulatesFromStepper[@specialized(Double, Int, Long) A, Acc <: Accumulat def apply(stepper: Stepper[A]): Acc } -final class CollectionCanAccumulate[A](private val underlying: TraversableOnce[A]) extends AnyVal { +final class CollectionCanAccumulate[A](private val underlying: IterableOnce[A]) extends AnyVal { def accumulate: Accumulator[A] = { val a = new Accumulator[A] - underlying.foreach(a += _) + underlying.iterator.foreach(a += _) a } } -final class AccumulateDoubleCollection(private val underlying: TraversableOnce[Double]) extends AnyVal { +final class AccumulateDoubleCollection(private val underlying: IterableOnce[Double]) extends AnyVal { def accumulate: DoubleAccumulator = { val da = new DoubleAccumulator - underlying.foreach(da += _) + underlying.iterator.foreach(da += _) da } } -final class AccumulateIntCollection(private val underlying: TraversableOnce[Int]) extends AnyVal { +final class AccumulateIntCollection(private val underlying: IterableOnce[Int]) extends AnyVal { def accumulate: IntAccumulator = { val da = new IntAccumulator - underlying.foreach(da += _) + underlying.iterator.foreach(da += _) da } } -final class AccumulateLongCollection(private val underlying: TraversableOnce[Long]) extends AnyVal { +final class AccumulateLongCollection(private val underlying: IterableOnce[Long]) extends AnyVal { def accumulate: LongAccumulator = { val da = new LongAccumulator - underlying.foreach(da += _) + underlying.iterator.foreach(da += _) da } } diff --git a/src/main/scala/scala/compat/java8/converterImpl/AccumulatorConverters.scala b/src/main/scala/scala/compat/java8/converterImpl/AccumulatorConverters.scala index 8a43fd6..1375496 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/AccumulatorConverters.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/AccumulatorConverters.scala @@ -5,13 +5,13 @@ import language.implicitConversions import scala.compat.java8.collectionImpl._ trait Priority3AccumulatorConverters { - implicit def collectionCanAccumulate[A](underlying: TraversableOnce[A]) = new CollectionCanAccumulate[A](underlying) + implicit def collectionCanAccumulate[A](underlying: IterableOnce[A]) = new CollectionCanAccumulate[A](underlying) } trait Priority2AccumulatorConverters extends Priority3AccumulatorConverters { - implicit def accumulateDoubleCollection(underlying: TraversableOnce[Double]) = new AccumulateDoubleCollection(underlying) - implicit def accumulateIntCollection(underlying: TraversableOnce[Int]) = new AccumulateIntCollection(underlying) - implicit def accumulateLongCollection(underlying: TraversableOnce[Long]) = new AccumulateLongCollection(underlying) + implicit def accumulateDoubleCollection(underlying: IterableOnce[Double]) = new AccumulateDoubleCollection(underlying) + implicit def accumulateIntCollection(underlying: IterableOnce[Int]) = new AccumulateIntCollection(underlying) + implicit def accumulateLongCollection(underlying: IterableOnce[Long]) = new AccumulateLongCollection(underlying) implicit def accumulateAnyArray[A](underlying: Array[A]) = new AccumulateAnyArray(underlying) } diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepConverters.scala b/src/main/scala/scala/compat/java8/converterImpl/StepConverters.scala index 7fbf363..994eecb 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepConverters.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepConverters.scala @@ -9,15 +9,15 @@ trait Priority3StepConverters { trait Priority2StepConverters extends Priority3StepConverters { implicit def richLinearSeqCanStep[A](underlying: collection.LinearSeq[A]) = new RichLinearSeqCanStep[A](underlying) - implicit def richIndexedSeqCanStep[A](underlying: collection.IndexedSeqLike[A, _]) = new RichIndexedSeqCanStep[A](underlying) + implicit def richIndexedSeqCanStep[A](underlying: collection.IndexedSeqOps[A, Any, _]) = new RichIndexedSeqCanStep[A](underlying) } trait Priority1StepConverters extends Priority2StepConverters { - implicit def richDefaultHashTableCanStep[K, V](underlying: collection.mutable.HashTable[K, collection.mutable.DefaultEntry[K, V]]) = new RichDefaultHashTableCanStep[K, V](underlying) - implicit def richLinkedHashTableCanStep[K, V](underlying: collection.mutable.HashTable[K, collection.mutable.LinkedEntry[K, V]]) = new RichLinkedHashTableCanStep[K, V](underlying) + implicit def richDefaultHashMapCanStep[K, V](underlying: collection.mutable.HashMap[K, V]) = new RichHashMapCanStep[K, V](underlying) + implicit def richLinkedHashMapCanStep[K, V](underlying: collection.mutable.LinkedHashMap[K, V]) = new RichLinkedHashMapCanStep[K, V](underlying) implicit def richArrayCanStep[A](underlying: Array[A]) = new RichArrayCanStep[A](underlying) implicit def richWrappedArrayCanStep[A](underlying: collection.mutable.WrappedArray[A]) = new RichArrayCanStep[A](underlying.array) - implicit def richFlatHashTableCanStep[A](underlying: collection.mutable.FlatHashTable[A]) = new RichFlatHashTableCanStep[A](underlying) + implicit def richHashSetCanStep[A](underlying: collection.mutable.HashSet[A]) = new RichHashSetCanStep[A](underlying) implicit def richIteratorCanStep[A](underlying: Iterator[A]) = new RichIteratorCanStep(underlying) implicit def richImmHashMapCanStep[K, V](underlying: collection.immutable.HashMap[K, V]) = new RichImmHashMapCanStep[K, V](underlying) implicit def richImmHashSetCanStep[A](underlying: collection.immutable.HashSet[A]) = new RichImmHashSetCanStep[A](underlying) diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsFlatHashTable.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsFlatHashTable.scala index 8661105..39f8d18 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsFlatHashTable.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsFlatHashTable.scala @@ -39,7 +39,7 @@ extends StepsLongLikeGapped[StepsLongFlatHashTable](_underlying, _i0, _iN) { // Value class adapters // ////////////////////////// -final class RichFlatHashTableCanStep[T](private val underlying: collection.mutable.FlatHashTable[T]) extends AnyVal with MakesStepper[T, EfficientSubstep] { +final class RichHashSetCanStep[T](private val underlying: collection.mutable.HashSet[T]) extends AnyVal with MakesStepper[T, EfficientSubstep] { override def stepper[S <: Stepper[_]](implicit ss: StepperShape[T, S]) = { val tbl = CollectionInternals.getTable(underlying) ((ss.shape: @switch) match { diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsHashTable.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsHashTable.scala index f4869d6..d43558e 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsHashTable.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsHashTable.scala @@ -13,124 +13,124 @@ import Stepper._ // Steppers for keys (type of HashEntry doesn't matter) -private[java8] class StepsAnyHashTableKey[K](_underlying: Array[collection.mutable.HashEntry[K, _]], _i0: Int, _iN: Int) -extends StepsLikeGapped[K, StepsAnyHashTableKey[K]](_underlying.asInstanceOf[Array[AnyRef]], _i0, _iN) { - def next() = if (currentEntry eq null) throwNSEE else { val ans = currentEntry.asInstanceOf[collection.mutable.HashEntry[K, _]].key; currentEntry = currentEntry.asInstanceOf[collection.mutable.HashEntry[K, _]].next.asInstanceOf[AnyRef]; ans } - def semiclone(half: Int) = new StepsAnyHashTableKey[K](underlying.asInstanceOf[Array[collection.mutable.HashEntry[K, _]]], i0, half) +private[java8] class StepsAnyHashTableKey[K](_underlying: Array[AnyRef], _i0: Int, _iN: Int) +extends StepsLikeGapped[K, StepsAnyHashTableKey[K]](_underlying, _i0, _iN) { + def next() = if (currentEntry eq null) throwNSEE else { val ans = CollectionInternals.hashEntryKey[K](currentEntry); currentEntry = CollectionInternals.hashEntryNext(currentEntry); ans } + def semiclone(half: Int) = new StepsAnyHashTableKey[K](underlying, i0, half) } -private[java8] class StepsDoubleHashTableKey(_underlying: Array[collection.mutable.HashEntry[Double, _]], _i0: Int, _iN: Int) -extends StepsDoubleLikeGapped[StepsDoubleHashTableKey](_underlying.asInstanceOf[Array[AnyRef]], _i0, _iN) { - def nextDouble() = if (currentEntry eq null) throwNSEE else { val ans = currentEntry.asInstanceOf[collection.mutable.HashEntry[Double, _]].key; currentEntry = currentEntry.asInstanceOf[collection.mutable.HashEntry[Double, _]].next.asInstanceOf[AnyRef]; ans } - def semiclone(half: Int) = new StepsDoubleHashTableKey(underlying.asInstanceOf[Array[collection.mutable.HashEntry[Double, _]]], i0, half) +private[java8] class StepsDoubleHashTableKey(_underlying: Array[AnyRef], _i0: Int, _iN: Int) +extends StepsDoubleLikeGapped[StepsDoubleHashTableKey](_underlying, _i0, _iN) { + def nextDouble() = if (currentEntry eq null) throwNSEE else { val ans = CollectionInternals.hashEntryKey[Double](currentEntry); currentEntry = CollectionInternals.hashEntryNext(currentEntry); ans } + def semiclone(half: Int) = new StepsDoubleHashTableKey(underlying, i0, half) } -private[java8] class StepsIntHashTableKey(_underlying: Array[collection.mutable.HashEntry[Int, _]], _i0: Int, _iN: Int) -extends StepsIntLikeGapped[StepsIntHashTableKey](_underlying.asInstanceOf[Array[AnyRef]], _i0, _iN) { - def nextInt() = if (currentEntry eq null) throwNSEE else { val ans = currentEntry.asInstanceOf[collection.mutable.HashEntry[Int, _]].key; currentEntry = currentEntry.asInstanceOf[collection.mutable.HashEntry[Int, _]].next.asInstanceOf[AnyRef]; ans } - def semiclone(half: Int) = new StepsIntHashTableKey(underlying.asInstanceOf[Array[collection.mutable.HashEntry[Int, _]]], i0, half) +private[java8] class StepsIntHashTableKey(_underlying: Array[AnyRef], _i0: Int, _iN: Int) +extends StepsIntLikeGapped[StepsIntHashTableKey](_underlying, _i0, _iN) { + def nextInt() = if (currentEntry eq null) throwNSEE else { val ans = CollectionInternals.hashEntryKey[Int](currentEntry); currentEntry = CollectionInternals.hashEntryNext(currentEntry); ans } + def semiclone(half: Int) = new StepsIntHashTableKey(underlying, i0, half) } -private[java8] class StepsLongHashTableKey(_underlying: Array[collection.mutable.HashEntry[Long, _]], _i0: Int, _iN: Int) -extends StepsLongLikeGapped[StepsLongHashTableKey](_underlying.asInstanceOf[Array[AnyRef]], _i0, _iN) { - def nextLong() = if (currentEntry eq null) throwNSEE else { val ans = currentEntry.asInstanceOf[collection.mutable.HashEntry[Long, _]].key; currentEntry = currentEntry.asInstanceOf[collection.mutable.HashEntry[Long, _]].next.asInstanceOf[AnyRef]; ans } - def semiclone(half: Int) = new StepsLongHashTableKey(underlying.asInstanceOf[Array[collection.mutable.HashEntry[Long, _]]], i0, half) +private[java8] class StepsLongHashTableKey(_underlying: Array[AnyRef], _i0: Int, _iN: Int) +extends StepsLongLikeGapped[StepsLongHashTableKey](_underlying, _i0, _iN) { + def nextLong() = if (currentEntry eq null) throwNSEE else { val ans = CollectionInternals.hashEntryKey[Long](currentEntry); currentEntry = CollectionInternals.hashEntryNext(currentEntry); ans } + def semiclone(half: Int) = new StepsLongHashTableKey(underlying, i0, half) } // Steppers for entries stored in DefaultEntry HashEntry // (both for key-value pair and for values alone) -private[java8] class StepsAnyDefaultHashTable[K, V](_underlying: Array[collection.mutable.HashEntry[K, collection.mutable.DefaultEntry[K, V]]], _i0: Int, _iN: Int) -extends StepsLikeGapped[(K, V), StepsAnyDefaultHashTable[K, V]](_underlying.asInstanceOf[Array[AnyRef]], _i0, _iN) { +private[java8] class StepsAnyDefaultHashTable[K, V](_underlying: Array[AnyRef], _i0: Int, _iN: Int) +extends StepsLikeGapped[(K, V), StepsAnyDefaultHashTable[K, V]](_underlying, _i0, _iN) { def next() = if (currentEntry eq null) throwNSEE - else { val de = currentEntry.asInstanceOf[collection.mutable.DefaultEntry[K, V]]; currentEntry = de.next; (de.key, de.value) } + else { val e = currentEntry; currentEntry = CollectionInternals.hashEntryNext(e); (CollectionInternals.hashEntryKey[K](e), CollectionInternals.defaultEntryValue[V](e)) } def semiclone(half: Int) = - new StepsAnyDefaultHashTable[K, V](underlying.asInstanceOf[Array[collection.mutable.HashEntry[K, collection.mutable.DefaultEntry[K, V]]]], i0, half) + new StepsAnyDefaultHashTable[K, V](underlying, i0, half) } -private[java8] class StepsAnyDefaultHashTableValue[K, V](_underlying: Array[collection.mutable.HashEntry[K, collection.mutable.DefaultEntry[K, V]]], _i0: Int, _iN: Int) -extends StepsLikeGapped[V, StepsAnyDefaultHashTableValue[K, V]](_underlying.asInstanceOf[Array[AnyRef]], _i0, _iN) { +private[java8] class StepsAnyDefaultHashTableValue[K, V](_underlying: Array[AnyRef], _i0: Int, _iN: Int) +extends StepsLikeGapped[V, StepsAnyDefaultHashTableValue[K, V]](_underlying, _i0, _iN) { def next() = if (currentEntry eq null) throwNSEE - else { val de = currentEntry.asInstanceOf[collection.mutable.DefaultEntry[K, V]]; currentEntry = de.next; de.value } + else { val e = currentEntry; currentEntry = CollectionInternals.hashEntryNext(e); CollectionInternals.defaultEntryValue[V](e) } def semiclone(half: Int) = - new StepsAnyDefaultHashTableValue[K, V](underlying.asInstanceOf[Array[collection.mutable.HashEntry[K, collection.mutable.DefaultEntry[K, V]]]], i0, half) + new StepsAnyDefaultHashTableValue[K, V](underlying, i0, half) } -private[java8] class StepsDoubleDefaultHashTableValue[K](_underlying: Array[collection.mutable.HashEntry[K, collection.mutable.DefaultEntry[K, Double]]], _i0: Int, _iN: Int) -extends StepsDoubleLikeGapped[StepsDoubleDefaultHashTableValue[K]](_underlying.asInstanceOf[Array[AnyRef]], _i0, _iN) { +private[java8] class StepsDoubleDefaultHashTableValue[K](_underlying: Array[AnyRef], _i0: Int, _iN: Int) +extends StepsDoubleLikeGapped[StepsDoubleDefaultHashTableValue[K]](_underlying, _i0, _iN) { def nextDouble() = if (currentEntry eq null) throwNSEE - else { val de = currentEntry.asInstanceOf[collection.mutable.DefaultEntry[K, Double]]; currentEntry = de.next; de.value } + else { val e = currentEntry; currentEntry = CollectionInternals.hashEntryNext(e); CollectionInternals.defaultEntryValue[Double](e) } def semiclone(half: Int) = - new StepsDoubleDefaultHashTableValue[K](underlying.asInstanceOf[Array[collection.mutable.HashEntry[K, collection.mutable.DefaultEntry[K, Double]]]], i0, half) + new StepsDoubleDefaultHashTableValue[K](underlying, i0, half) } -private[java8] class StepsIntDefaultHashTableValue[K](_underlying: Array[collection.mutable.HashEntry[K, collection.mutable.DefaultEntry[K, Int]]], _i0: Int, _iN: Int) -extends StepsIntLikeGapped[StepsIntDefaultHashTableValue[K]](_underlying.asInstanceOf[Array[AnyRef]], _i0, _iN) { +private[java8] class StepsIntDefaultHashTableValue[K](_underlying: Array[AnyRef], _i0: Int, _iN: Int) +extends StepsIntLikeGapped[StepsIntDefaultHashTableValue[K]](_underlying, _i0, _iN) { def nextInt() = if (currentEntry eq null) throwNSEE - else { val de = currentEntry.asInstanceOf[collection.mutable.DefaultEntry[K, Int]]; currentEntry = de.next; de.value } + else { val e = currentEntry; currentEntry = CollectionInternals.hashEntryNext(e); CollectionInternals.defaultEntryValue[Int](e) } def semiclone(half: Int) = - new StepsIntDefaultHashTableValue[K](underlying.asInstanceOf[Array[collection.mutable.HashEntry[K, collection.mutable.DefaultEntry[K, Int]]]], i0, half) + new StepsIntDefaultHashTableValue[K](underlying, i0, half) } -private[java8] class StepsLongDefaultHashTableValue[K](_underlying: Array[collection.mutable.HashEntry[K, collection.mutable.DefaultEntry[K, Long]]], _i0: Int, _iN: Int) -extends StepsLongLikeGapped[StepsLongDefaultHashTableValue[K]](_underlying.asInstanceOf[Array[AnyRef]], _i0, _iN) { +private[java8] class StepsLongDefaultHashTableValue[K](_underlying: Array[AnyRef], _i0: Int, _iN: Int) +extends StepsLongLikeGapped[StepsLongDefaultHashTableValue[K]](_underlying, _i0, _iN) { def nextLong() = if (currentEntry eq null) throwNSEE - else { val de = currentEntry.asInstanceOf[collection.mutable.DefaultEntry[K, Long]]; currentEntry = de.next; de.value } + else { val e = currentEntry; currentEntry = CollectionInternals.hashEntryNext(e); CollectionInternals.defaultEntryValue[Long](e) } def semiclone(half: Int) = - new StepsLongDefaultHashTableValue[K](underlying.asInstanceOf[Array[collection.mutable.HashEntry[K, collection.mutable.DefaultEntry[K, Long]]]], i0, half) + new StepsLongDefaultHashTableValue[K](underlying, i0, half) } // Steppers for entries stored in LinkedEntry HashEntry // (both for key-value pair and for values alone) -private[java8] class StepsAnyLinkedHashTable[K, V](_underlying: Array[collection.mutable.HashEntry[K, collection.mutable.LinkedEntry[K, V]]], _i0: Int, _iN: Int) -extends StepsLikeGapped[(K, V), StepsAnyLinkedHashTable[K, V]](_underlying.asInstanceOf[Array[AnyRef]], _i0, _iN) { +private[java8] class StepsAnyLinkedHashTable[K, V](_underlying: Array[AnyRef], _i0: Int, _iN: Int) +extends StepsLikeGapped[(K, V), StepsAnyLinkedHashTable[K, V]](_underlying, _i0, _iN) { def next() = if (currentEntry eq null) throwNSEE - else { val de = currentEntry.asInstanceOf[collection.mutable.LinkedEntry[K, V]]; currentEntry = de.next; (de.key, de.value) } + else { val e = currentEntry; currentEntry = CollectionInternals.hashEntryNext(e); (CollectionInternals.hashEntryKey[K](e), CollectionInternals.linkedEntryValue[V](e)) } def semiclone(half: Int) = - new StepsAnyLinkedHashTable[K, V](underlying.asInstanceOf[Array[collection.mutable.HashEntry[K, collection.mutable.LinkedEntry[K, V]]]], i0, half) + new StepsAnyLinkedHashTable[K, V](underlying, i0, half) } -private[java8] class StepsAnyLinkedHashTableValue[K, V](_underlying: Array[collection.mutable.HashEntry[K, collection.mutable.LinkedEntry[K, V]]], _i0: Int, _iN: Int) -extends StepsLikeGapped[V, StepsAnyLinkedHashTableValue[K, V]](_underlying.asInstanceOf[Array[AnyRef]], _i0, _iN) { +private[java8] class StepsAnyLinkedHashTableValue[K, V](_underlying: Array[AnyRef], _i0: Int, _iN: Int) +extends StepsLikeGapped[V, StepsAnyLinkedHashTableValue[K, V]](_underlying, _i0, _iN) { def next() = if (currentEntry eq null) throwNSEE - else { val de = currentEntry.asInstanceOf[collection.mutable.LinkedEntry[K, V]]; currentEntry = de.next; de.value } + else { val e = currentEntry; currentEntry = CollectionInternals.hashEntryNext(e); CollectionInternals.linkedEntryValue[V](e) } def semiclone(half: Int) = - new StepsAnyLinkedHashTableValue[K, V](underlying.asInstanceOf[Array[collection.mutable.HashEntry[K, collection.mutable.LinkedEntry[K, V]]]], i0, half) + new StepsAnyLinkedHashTableValue[K, V](underlying, i0, half) } -private[java8] class StepsDoubleLinkedHashTableValue[K](_underlying: Array[collection.mutable.HashEntry[K, collection.mutable.LinkedEntry[K, Double]]], _i0: Int, _iN: Int) -extends StepsDoubleLikeGapped[StepsDoubleLinkedHashTableValue[K]](_underlying.asInstanceOf[Array[AnyRef]], _i0, _iN) { +private[java8] class StepsDoubleLinkedHashTableValue[K](_underlying: Array[AnyRef], _i0: Int, _iN: Int) +extends StepsDoubleLikeGapped[StepsDoubleLinkedHashTableValue[K]](_underlying, _i0, _iN) { def nextDouble() = if (currentEntry eq null) throwNSEE - else { val de = currentEntry.asInstanceOf[collection.mutable.LinkedEntry[K, Double]]; currentEntry = de.next; de.value } + else { val e = currentEntry; currentEntry = CollectionInternals.hashEntryNext(e); CollectionInternals.linkedEntryValue[Double](e) } def semiclone(half: Int) = - new StepsDoubleLinkedHashTableValue[K](underlying.asInstanceOf[Array[collection.mutable.HashEntry[K, collection.mutable.LinkedEntry[K, Double]]]], i0, half) + new StepsDoubleLinkedHashTableValue[K](underlying, i0, half) } -private[java8] class StepsIntLinkedHashTableValue[K](_underlying: Array[collection.mutable.HashEntry[K, collection.mutable.LinkedEntry[K, Int]]], _i0: Int, _iN: Int) -extends StepsIntLikeGapped[StepsIntLinkedHashTableValue[K]](_underlying.asInstanceOf[Array[AnyRef]], _i0, _iN) { +private[java8] class StepsIntLinkedHashTableValue[K](_underlying: Array[AnyRef], _i0: Int, _iN: Int) +extends StepsIntLikeGapped[StepsIntLinkedHashTableValue[K]](_underlying, _i0, _iN) { def nextInt() = if (currentEntry eq null) throwNSEE - else { val de = currentEntry.asInstanceOf[collection.mutable.LinkedEntry[K, Int]]; currentEntry = de.next; de.value } + else { val e = currentEntry; currentEntry = CollectionInternals.hashEntryNext(e); CollectionInternals.linkedEntryValue[Int](e) } def semiclone(half: Int) = - new StepsIntLinkedHashTableValue[K](underlying.asInstanceOf[Array[collection.mutable.HashEntry[K, collection.mutable.LinkedEntry[K, Int]]]], i0, half) + new StepsIntLinkedHashTableValue[K](underlying, i0, half) } -private[java8] class StepsLongLinkedHashTableValue[K](_underlying: Array[collection.mutable.HashEntry[K, collection.mutable.LinkedEntry[K, Long]]], _i0: Int, _iN: Int) -extends StepsLongLikeGapped[StepsLongLinkedHashTableValue[K]](_underlying.asInstanceOf[Array[AnyRef]], _i0, _iN) { +private[java8] class StepsLongLinkedHashTableValue[K](_underlying: Array[AnyRef], _i0: Int, _iN: Int) +extends StepsLongLikeGapped[StepsLongLinkedHashTableValue[K]](_underlying, _i0, _iN) { def nextLong() = if (currentEntry eq null) throwNSEE - else { val de = currentEntry.asInstanceOf[collection.mutable.LinkedEntry[K, Long]]; currentEntry = de.next; de.value } + else { val e = currentEntry; currentEntry = CollectionInternals.hashEntryNext(e); CollectionInternals.linkedEntryValue[Long](e) } def semiclone(half: Int) = - new StepsLongLinkedHashTableValue[K](underlying.asInstanceOf[Array[collection.mutable.HashEntry[K, collection.mutable.LinkedEntry[K, Long]]]], i0, half) + new StepsLongLinkedHashTableValue[K](underlying, i0, half) } @@ -140,58 +140,58 @@ extends StepsLongLikeGapped[StepsLongLinkedHashTableValue[K]](_underlying.asInst // Steppers for entries stored in DefaultEntry HashEntry -final class RichDefaultHashTableCanStep[K, V](private val underlying: collection.mutable.HashTable[K, collection.mutable.DefaultEntry[K, V]]) extends AnyVal with MakesKeyValueStepper[K, V, EfficientSubstep] with MakesStepper[(K, V), EfficientSubstep] { +final class RichHashMapCanStep[K, V](private val underlying: collection.mutable.HashMap[K, V]) extends AnyVal with MakesKeyValueStepper[K, V, EfficientSubstep] with MakesStepper[(K, V), EfficientSubstep] { def stepper[S <: Stepper[_]](implicit ss: StepperShape[(K, V), S]) = { - val tbl = CollectionInternals.getTable[K, collection.mutable.DefaultEntry[K, V]](underlying) + val tbl = CollectionInternals.getTable[K, V](underlying) new StepsAnyDefaultHashTable(tbl, 0, tbl.length).asInstanceOf[S with EfficientSubstep] } def keyStepper[S <: Stepper[_]](implicit ss: StepperShape[K, S]) = { - val tbl = CollectionInternals.getTable[K, collection.mutable.DefaultEntry[K, V]](underlying) + val tbl = CollectionInternals.getTable[K, V](underlying) ((ss.shape: @switch) match { - case StepperShape.IntValue => new StepsIntHashTableKey (tbl.asInstanceOf[Array[collection.mutable.HashEntry[Int, _]]], 0, tbl.length) - case StepperShape.LongValue => new StepsLongHashTableKey (tbl.asInstanceOf[Array[collection.mutable.HashEntry[Long, _]]], 0, tbl.length) - case StepperShape.DoubleValue => new StepsDoubleHashTableKey(tbl.asInstanceOf[Array[collection.mutable.HashEntry[Double, _]]], 0, tbl.length) - case _ => ss.parUnbox(new StepsAnyHashTableKey (tbl.asInstanceOf[Array[collection.mutable.HashEntry[K, _]]], 0, tbl.length)) + case StepperShape.IntValue => new StepsIntHashTableKey (tbl, 0, tbl.length) + case StepperShape.LongValue => new StepsLongHashTableKey (tbl, 0, tbl.length) + case StepperShape.DoubleValue => new StepsDoubleHashTableKey(tbl, 0, tbl.length) + case _ => ss.parUnbox(new StepsAnyHashTableKey (tbl, 0, tbl.length)) }).asInstanceOf[S with EfficientSubstep] } def valueStepper[S <: Stepper[_]](implicit ss: StepperShape[V, S]) = { - val tbl = CollectionInternals.getTable[K, collection.mutable.DefaultEntry[K, V]](underlying) + val tbl = CollectionInternals.getTable[K, V](underlying) ((ss.shape: @switch) match { - case StepperShape.IntValue => new StepsIntDefaultHashTableValue (tbl.asInstanceOf[Array[collection.mutable.HashEntry[K, collection.mutable.DefaultEntry[K, Int ]]]], 0, tbl.length) - case StepperShape.LongValue => new StepsLongDefaultHashTableValue (tbl.asInstanceOf[Array[collection.mutable.HashEntry[K, collection.mutable.DefaultEntry[K, Long ]]]], 0, tbl.length) - case StepperShape.DoubleValue => new StepsDoubleDefaultHashTableValue(tbl.asInstanceOf[Array[collection.mutable.HashEntry[K, collection.mutable.DefaultEntry[K, Double]]]], 0, tbl.length) - case _ => ss.parUnbox(new StepsAnyDefaultHashTableValue (tbl, 0, tbl.length)) + case StepperShape.IntValue => new StepsIntDefaultHashTableValue (tbl, 0, tbl.length) + case StepperShape.LongValue => new StepsLongDefaultHashTableValue (tbl, 0, tbl.length) + case StepperShape.DoubleValue => new StepsDoubleDefaultHashTableValue(tbl, 0, tbl.length) + case _ => ss.parUnbox(new StepsAnyDefaultHashTableValue (tbl, 0, tbl.length)) }).asInstanceOf[S with EfficientSubstep] } } // Steppers for entries stored in LinkedEntry HashEntry -final class RichLinkedHashTableCanStep[K, V](private val underlying: collection.mutable.HashTable[K, collection.mutable.LinkedEntry[K, V]]) extends AnyVal with MakesKeyValueStepper[K, V, EfficientSubstep] with MakesStepper[(K, V), EfficientSubstep] { +final class RichLinkedHashMapCanStep[K, V](private val underlying: collection.mutable.LinkedHashMap[K, V]) extends AnyVal with MakesKeyValueStepper[K, V, EfficientSubstep] with MakesStepper[(K, V), EfficientSubstep] { def stepper[S <: Stepper[_]](implicit ss: StepperShape[(K, V), S]) = { - val tbl = CollectionInternals.getTable[K, collection.mutable.LinkedEntry[K, V]](underlying) + val tbl = CollectionInternals.getTable[K, V](underlying) new StepsAnyLinkedHashTable(tbl, 0, tbl.length).asInstanceOf[S with EfficientSubstep] } def keyStepper[S <: Stepper[_]](implicit ss: StepperShape[K, S]) = { - val tbl = CollectionInternals.getTable[K, collection.mutable.LinkedEntry[K, V]](underlying) + val tbl = CollectionInternals.getTable[K, V](underlying) ((ss.shape: @switch) match { - case StepperShape.IntValue => new StepsIntHashTableKey (tbl.asInstanceOf[Array[collection.mutable.HashEntry[Int, _]]], 0, tbl.length) - case StepperShape.LongValue => new StepsLongHashTableKey (tbl.asInstanceOf[Array[collection.mutable.HashEntry[Long, _]]], 0, tbl.length) - case StepperShape.DoubleValue => new StepsDoubleHashTableKey(tbl.asInstanceOf[Array[collection.mutable.HashEntry[Double, _]]], 0, tbl.length) - case _ => ss.parUnbox(new StepsAnyHashTableKey (tbl.asInstanceOf[Array[collection.mutable.HashEntry[K, _]]], 0, tbl.length)) + case StepperShape.IntValue => new StepsIntHashTableKey (tbl, 0, tbl.length) + case StepperShape.LongValue => new StepsLongHashTableKey (tbl, 0, tbl.length) + case StepperShape.DoubleValue => new StepsDoubleHashTableKey(tbl, 0, tbl.length) + case _ => ss.parUnbox(new StepsAnyHashTableKey (tbl, 0, tbl.length)) }).asInstanceOf[S with EfficientSubstep] } def valueStepper[S <: Stepper[_]](implicit ss: StepperShape[V, S]) = { - val tbl = CollectionInternals.getTable[K, collection.mutable.LinkedEntry[K, V]](underlying) + val tbl = CollectionInternals.getTable[K, V](underlying) ((ss.shape: @switch) match { - case StepperShape.IntValue => new StepsIntLinkedHashTableValue (tbl.asInstanceOf[Array[collection.mutable.HashEntry[K, collection.mutable.LinkedEntry[K, Int ]]]], 0, tbl.length) - case StepperShape.LongValue => new StepsLongLinkedHashTableValue (tbl.asInstanceOf[Array[collection.mutable.HashEntry[K, collection.mutable.LinkedEntry[K, Long ]]]], 0, tbl.length) - case StepperShape.DoubleValue => new StepsDoubleLinkedHashTableValue(tbl.asInstanceOf[Array[collection.mutable.HashEntry[K, collection.mutable.LinkedEntry[K, Double]]]], 0, tbl.length) - case _ => ss.parUnbox(new StepsAnyLinkedHashTableValue (tbl, 0, tbl.length)) + case StepperShape.IntValue => new StepsIntLinkedHashTableValue (tbl, 0, tbl.length) + case StepperShape.LongValue => new StepsLongLinkedHashTableValue (tbl, 0, tbl.length) + case StepperShape.DoubleValue => new StepsDoubleLinkedHashTableValue(tbl, 0, tbl.length) + case _ => ss.parUnbox(new StepsAnyLinkedHashTableValue (tbl, 0, tbl.length)) }).asInstanceOf[S with EfficientSubstep] } } diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsIndexedSeq.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsIndexedSeq.scala index 1065f0d..b8e65c7 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsIndexedSeq.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsIndexedSeq.scala @@ -1,34 +1,32 @@ package scala.compat.java8.converterImpl import scala.annotation.switch - import scala.compat.java8.collectionImpl._ - import Stepper._ ///////////////////////////// // Stepper implementations // ///////////////////////////// -private[java8] class StepsAnyIndexedSeq[A](underlying: collection.IndexedSeqLike[A, _], _i0: Int, _iN: Int) +private[java8] class StepsAnyIndexedSeq[A](underlying: collection.IndexedSeqOps[A, Any, _], _i0: Int, _iN: Int) extends StepsLikeIndexed[A, StepsAnyIndexedSeq[A]](_i0, _iN) { def next() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE def semiclone(half: Int) = new StepsAnyIndexedSeq[A](underlying, i0, half) } -private[java8] class StepsDoubleIndexedSeq[CC <: collection.IndexedSeqLike[Double, _]](underlying: CC, _i0: Int, _iN: Int) +private[java8] class StepsDoubleIndexedSeq[CC <: collection.IndexedSeqOps[Double, Any, _]](underlying: CC, _i0: Int, _iN: Int) extends StepsDoubleLikeIndexed[StepsDoubleIndexedSeq[CC]](_i0, _iN) { def nextDouble() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE def semiclone(half: Int) = new StepsDoubleIndexedSeq[CC](underlying, i0, half) } -private[java8] class StepsIntIndexedSeq[CC <: collection.IndexedSeqLike[Int, _]](underlying: CC, _i0: Int, _iN: Int) +private[java8] class StepsIntIndexedSeq[CC <: collection.IndexedSeqOps[Int, Any, _]](underlying: CC, _i0: Int, _iN: Int) extends StepsIntLikeIndexed[StepsIntIndexedSeq[CC]](_i0, _iN) { def nextInt() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE def semiclone(half: Int) = new StepsIntIndexedSeq[CC](underlying, i0, half) } -private[java8] class StepsLongIndexedSeq[CC <: collection.IndexedSeqLike[Long, _]](underlying: CC, _i0: Int, _iN: Int) +private[java8] class StepsLongIndexedSeq[CC <: collection.IndexedSeqOps[Long, Any, _]](underlying: CC, _i0: Int, _iN: Int) extends StepsLongLikeIndexed[StepsLongIndexedSeq[CC]](_i0, _iN) { def nextLong() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE def semiclone(half: Int) = new StepsLongIndexedSeq[CC](underlying, i0, half) @@ -38,11 +36,11 @@ extends StepsLongLikeIndexed[StepsLongIndexedSeq[CC]](_i0, _iN) { // Value class adapters // ////////////////////////// -final class RichIndexedSeqCanStep[T](private val underlying: collection.IndexedSeqLike[T, _]) extends AnyVal with MakesStepper[T, EfficientSubstep] { +final class RichIndexedSeqCanStep[T](private val underlying: collection.IndexedSeqOps[T, Any, _]) extends AnyVal with MakesStepper[T, EfficientSubstep] { def stepper[S <: Stepper[_]](implicit ss: StepperShape[T, S]) = ((ss.shape: @switch) match { - case StepperShape.IntValue => new StepsIntIndexedSeq (underlying.asInstanceOf[collection.IndexedSeqLike[Int, _]], 0, underlying.length) - case StepperShape.LongValue => new StepsLongIndexedSeq (underlying.asInstanceOf[collection.IndexedSeqLike[Long, _]], 0, underlying.length) - case StepperShape.DoubleValue => new StepsDoubleIndexedSeq(underlying.asInstanceOf[collection.IndexedSeqLike[Double, _]], 0, underlying.length) - case _ => ss.parUnbox(new StepsAnyIndexedSeq[T](underlying, 0, underlying.length)) + case StepperShape.IntValue => new StepsIntIndexedSeq (underlying.asInstanceOf[collection.IndexedSeqOps[Int, Any, _]], 0, underlying.length) + case StepperShape.LongValue => new StepsLongIndexedSeq (underlying.asInstanceOf[collection.IndexedSeqOps[Long, Any, _]], 0, underlying.length) + case StepperShape.DoubleValue => new StepsDoubleIndexedSeq(underlying.asInstanceOf[collection.IndexedSeqOps[Double, Any, _]], 0, underlying.length) + case _ => ss.parUnbox(new StepsAnyIndexedSeq[T](underlying, 0, underlying.length)) }).asInstanceOf[S with EfficientSubstep] } diff --git a/src/main/scala/scala/concurrent/java8/FutureConvertersImpl.scala b/src/main/scala/scala/concurrent/java8/FutureConvertersImpl.scala index 61a2a6a..40873a4 100644 --- a/src/main/scala/scala/concurrent/java8/FutureConvertersImpl.scala +++ b/src/main/scala/scala/concurrent/java8/FutureConvertersImpl.scala @@ -5,7 +5,7 @@ package scala.concurrent.java8 // Located in this package to access private[concurrent] members -import scala.concurrent.{ Future, ExecutionContext } +import scala.concurrent.Future import java.util.concurrent._ import scala.concurrent.impl.Promise.DefaultPromise import scala.util.{ Try, Success, Failure } diff --git a/src/test/scala/scala/compat/java8/StepConvertersTest.scala b/src/test/scala/scala/compat/java8/StepConvertersTest.scala index b7a43e4..6324fa3 100644 --- a/src/test/scala/scala/compat/java8/StepConvertersTest.scala +++ b/src/test/scala/scala/compat/java8/StepConvertersTest.scala @@ -4,7 +4,6 @@ import org.junit.Test import org.junit.Assert._ class StepConvertersTest { - import java.util._ import collectionImpl._ import converterImpl._ import StreamConverters._ // Includes StepConverters! @@ -96,9 +95,9 @@ class StepConvertersTest { Okay( co.SortedMap[String, String]("fish" -> "salmon").keyStepper ) Okay( co.SortedMap[String, String]("fish" -> "salmon").valueStepper ) Okay( co.SortedSet[String]("salmon").stepper ) - IFFY( co.Traversable[String]("salmon").accumulate.stepper ) - IFFY( (co.Iterator[String]("salmon"): co.TraversableOnce[String]).accumulate.stepper ) - IFFY( co.Traversable[String]("salmon").view.accumulate.stepper ) + IFFY( co.Iterable[String]("salmon").accumulate.stepper ) + IFFY( (co.Iterator[String]("salmon"): co.IterableOnce[String]).accumulate.stepper ) + IFFY( co.Iterable[String]("salmon").view.accumulate.stepper ) // Immutable section Okay( ci.::("salmon", Nil).stepper ) @@ -131,10 +130,11 @@ class StepConvertersTest { Okay( ci.SortedMap[String, String]("fish" -> "salmon").keyStepper ) Okay( ci.SortedMap[String, String]("fish" -> "salmon").valueStepper ) Okay( ci.SortedSet[String]("salmon").stepper ) - Okay( ci.Stack[String]("salmon").stepper ) Okay( ci.Stream[String]("salmon").stepper ) _eh_( ci.Stream[String]("salmon").view.stepper ) - IFFY( ci.Traversable[String]("salmon").accumulate.stepper ) + Okay( ci.LazyList[String]("salmon").stepper ) + _eh_( ci.LazyList[String]("salmon").view.stepper ) + IFFY( ci.Iterable[String]("salmon").accumulate.stepper ) Okay( ci.TreeMap[String, String]("fish" -> "salmon").stepper ) Okay( ci.TreeMap[String, String]("fish" -> "salmon").keyStepper ) Okay( ci.TreeMap[String, String]("fish" -> "salmon").valueStepper ) @@ -153,8 +153,7 @@ class StepConvertersTest { Okay( cm.AnyRefMap[String,String]("fish" -> "salmon").keyStepper ) Okay( cm.AnyRefMap[String,String]("fish" -> "salmon").valueStepper ) good( cm.ArrayBuffer[String]("salmon").stepper ) - good( ((Array("salmon"): cm.WrappedArray[String]): cm.ArrayLike[String, cm.WrappedArray[String]]).stepper ) - good( (Array("salmon"): cm.ArrayOps[String]).stepper ) + good( (Array("salmon"): cm.WrappedArray[String]).stepper ) good( cm.ArraySeq[String]("salmon").stepper ) _eh_( cm.ArrayStack[String]("salmon").stepper ) Okay( (cm.ArrayBuffer[String]("salmon"): cm.Buffer[String]).stepper ) @@ -165,7 +164,6 @@ class StepConvertersTest { good( cm.IndexedSeq[String]("salmon").stepper ) good( cm.IndexedSeq[String]("salmon").view.stepper ) Okay( cm.Iterable[String]("salmon").stepper ) - Okay( cm.LinearSeq[String]("salmon").stepper ) good( cm.LinkedHashMap[String, String]("fish" -> "salmon").stepper ) good( cm.LinkedHashMap[String, String]("fish" -> "salmon").keyStepper ) good( cm.LinkedHashMap[String, String]("fish" -> "salmon").valueStepper ) @@ -179,18 +177,16 @@ class StepConvertersTest { Okay( cm.Map[String, String]("fish" -> "salmon").stepper ) Okay( cm.Map[String, String]("fish" -> "salmon").keyStepper ) Okay( cm.Map[String, String]("fish" -> "salmon").valueStepper ) - Okay( cm.MutableList[String]("salmon").stepper ) Okay( cm.OpenHashMap[String, String]("fish" -> "salmon").stepper ) Okay( cm.OpenHashMap[String, String]("fish" -> "salmon").keyStepper ) Okay( cm.OpenHashMap[String, String]("fish" -> "salmon").valueStepper ) Okay( cm.PriorityQueue[String]("salmon").stepper ) - Okay( cm.Queue[String]("salmon").stepper ) - good( cm.ResizableArray[String]("salmon").stepper ) + Fine( cm.Queue[String]("salmon").stepper ) // Used to be `Good` in 2.12, in 2.13 `Queue` is no longer a `LinearSeq` Okay( cm.Seq[String]("salmon").stepper ) Okay( cm.Set[String]("salmon").stepper ) Okay( cm.SortedSet[String]("salmon").stepper ) - Okay( cm.Stack[String]("salmon").stepper ) - IFFY( cm.Traversable[String]("salmon").accumulate.stepper ) + Fine( cm.Stack[String]("salmon").stepper ) // Used to be `Good` in 2.12, in 2.13 `Stack` is no longer a `LinearSeq` + IFFY( cm.Iterable[String]("salmon").accumulate.stepper ) Okay( cm.TreeSet[String]("salmon").stepper ) Okay( cm.UnrolledBuffer[String]("salmon").stepper ) Okay( cm.WeakHashMap[String, String]("fish" -> "salmon").stepper ) @@ -229,9 +225,9 @@ class StepConvertersTest { Okay( co.SortedMap[Double, Double](2.718281828 -> 3.14159).keyStepper ) Okay( co.SortedMap[Double, Double](2.718281828 -> 3.14159).valueStepper ) Okay( co.SortedSet[Double](3.14159).stepper ) - IFFY( co.Traversable[Double](3.14159).accumulate.stepper ) - IFFY( (co.Iterator[Double](3.14159): co.TraversableOnce[Double]).accumulate.stepper ) - IFFY( co.Traversable[Double](3.14159).view.accumulate.stepper ) + IFFY( co.Iterable[Double](3.14159).accumulate.stepper ) + IFFY( (co.Iterator[Double](3.14159): co.IterableOnce[Double]).accumulate.stepper ) + IFFY( co.Iterable[Double](3.14159).view.accumulate.stepper ) // Immutable section Okay( ci.::(3.14159, Nil).stepper ) @@ -257,10 +253,11 @@ class StepConvertersTest { Okay( ci.SortedMap[Double, Double](2.718281828 -> 3.14159).keyStepper ) Okay( ci.SortedMap[Double, Double](2.718281828 -> 3.14159).valueStepper ) Okay( ci.SortedSet[Double](3.14159).stepper ) - Okay( ci.Stack[Double](3.14159).stepper ) Okay( ci.Stream[Double](3.14159).stepper ) _eh_( ci.Stream[Double](3.14159).view.stepper ) - IFFY( ci.Traversable[Double](3.14159).accumulate.stepper ) + Okay( ci.LazyList[Double](3.14159).stepper ) + _eh_( ci.LazyList[Double](3.14159).view.stepper ) + IFFY( ci.Iterable[Double](3.14159).accumulate.stepper ) Okay( ci.TreeMap[Double, Double](2.718281828 -> 3.14159).keyStepper ) Okay( ci.TreeMap[Double, Double](2.718281828 -> 3.14159).valueStepper ) Okay( ci.TreeSet[Double](3.14159).stepper ) @@ -275,8 +272,7 @@ class StepConvertersTest { Okay( (cm.HashSet[Double](3.14159): cm.AbstractSet[Double]).stepper ) Okay( cm.AnyRefMap[String,Double]("fish" -> 3.14159).valueStepper ) good( cm.ArrayBuffer[Double](3.14159).stepper ) - good( ((Array(3.14159): cm.WrappedArray[Double]): cm.ArrayLike[Double, cm.WrappedArray[Double]]).stepper ) - good( (Array(3.14159): cm.ArrayOps[Double]).stepper ) + good( (Array(3.14159): cm.WrappedArray[Double]).stepper ) good( cm.ArraySeq[Double](3.14159).stepper ) _eh_( cm.ArrayStack[Double](3.14159).stepper ) Okay( (cm.ArrayBuffer[Double](3.14159): cm.Buffer[Double]).stepper ) @@ -286,7 +282,6 @@ class StepConvertersTest { good( cm.IndexedSeq[Double](3.14159).stepper ) good( cm.IndexedSeq[Double](3.14159).view.stepper ) Okay( cm.Iterable[Double](3.14159).stepper ) - Okay( cm.LinearSeq[Double](3.14159).stepper ) good( cm.LinkedHashMap[Double, Double](2.718281828 -> 3.14159).keyStepper ) good( cm.LinkedHashMap[Double, Double](2.718281828 -> 3.14159).valueStepper ) Okay( cm.LinkedHashSet[Double](3.14159).stepper ) @@ -296,17 +291,15 @@ class StepConvertersTest { Okay( cm.LongMap[Double](9876543210L -> 3.14159).valueStepper ) Okay( cm.Map[Double, Double](2.718281828 -> 3.14159).keyStepper ) Okay( cm.Map[Double, Double](2.718281828 -> 3.14159).valueStepper ) - Okay( cm.MutableList[Double](3.14159).stepper ) Okay( cm.OpenHashMap[Double, Double](2.718281828 -> 3.14159).keyStepper ) Okay( cm.OpenHashMap[Double, Double](2.718281828 -> 3.14159).valueStepper ) Okay( cm.PriorityQueue[Double](3.14159).stepper ) - Okay( cm.Queue[Double](3.14159).stepper ) - good( cm.ResizableArray[Double](3.14159).stepper ) + Fine( cm.Queue[Double](3.14159).stepper ) // Used to be `Good` in 2.12, in 2.13 `Queue` is no longer a `LinearSeq` Okay( cm.Seq[Double](3.14159).stepper ) Okay( cm.Set[Double](3.14159).stepper ) Okay( cm.SortedSet[Double](3.14159).stepper ) - Okay( cm.Stack[Double](3.14159).stepper ) - IFFY( cm.Traversable[Double](3.14159).accumulate.stepper ) + Fine( cm.Stack[Double](3.14159).stepper ) // Used to be `Good` in 2.12, in 2.13 `Stack` is no longer a `LinearSeq` + IFFY( cm.Iterable[Double](3.14159).accumulate.stepper ) Okay( cm.TreeSet[Double](3.14159).stepper ) Okay( cm.UnrolledBuffer[Double](3.14159).stepper ) Okay( cm.WeakHashMap[Double, Double](2.718281828 -> 3.14159).keyStepper ) @@ -351,9 +344,9 @@ class StepConvertersTest { Okay( co.SortedMap[Int, Int](0xDEEDED -> 654321).keyStepper ) Okay( co.SortedMap[Int, Int](0xDEEDED -> 654321).valueStepper ) Okay( co.SortedSet[Int](654321).stepper ) - IFFY( co.Traversable[Int](654321).accumulate.stepper ) - IFFY( (co.Iterator[Int](654321): co.TraversableOnce[Int]).accumulate.stepper ) - IFFY( co.Traversable[Int](654321).view.accumulate.stepper ) + IFFY( co.Iterable[Int](654321).accumulate.stepper ) + IFFY( (co.Iterator[Int](654321): co.IterableOnce[Int]).accumulate.stepper ) + IFFY( co.Iterable[Int](654321).view.accumulate.stepper ) // Immutable section Okay( ci.::(654321, Nil).stepper ) @@ -380,10 +373,11 @@ class StepConvertersTest { Okay( ci.SortedMap[Int, Int](0xDEEDED -> 654321).keyStepper ) Okay( ci.SortedMap[Int, Int](0xDEEDED -> 654321).valueStepper ) Okay( ci.SortedSet[Int](654321).stepper ) - Okay( ci.Stack[Int](654321).stepper ) Okay( ci.Stream[Int](654321).stepper ) _eh_( ci.Stream[Int](654321).view.stepper ) - IFFY( ci.Traversable[Int](654321).accumulate.stepper ) + Okay( ci.LazyList[Int](654321).stepper ) + _eh_( ci.LazyList[Int](654321).view.stepper ) + IFFY( ci.Iterable[Int](654321).accumulate.stepper ) Okay( ci.TreeMap[Int, Int](0xDEEDED -> 654321).keyStepper ) Okay( ci.TreeMap[Int, Int](0xDEEDED -> 654321).valueStepper ) Okay( ci.TreeSet[Int](654321).stepper ) @@ -398,8 +392,7 @@ class StepConvertersTest { Okay( (cm.HashSet[Int](654321): cm.AbstractSet[Int]).stepper ) Okay( cm.AnyRefMap[String, Int]("fish" -> 654321).valueStepper ) good( cm.ArrayBuffer[Int](654321).stepper ) - good( ((Array(654321): cm.WrappedArray[Int]): cm.ArrayLike[Int, cm.WrappedArray[Int]]).stepper ) - good( (Array(654321): cm.ArrayOps[Int]).stepper ) + good( (Array(654321): cm.WrappedArray[Int]).stepper ) good( cm.ArraySeq[Int](654321).stepper ) _eh_( cm.ArrayStack[Int](654321).stepper ) Okay( (cm.ArrayBuffer[Int](654321): cm.Buffer[Int]).stepper ) @@ -409,7 +402,6 @@ class StepConvertersTest { good( cm.IndexedSeq[Int](654321).stepper ) good( cm.IndexedSeq[Int](654321).view.stepper ) Okay( cm.Iterable[Int](654321).stepper ) - Okay( cm.LinearSeq[Int](654321).stepper ) good( cm.LinkedHashMap[Int, Int](0xDEEDED -> 654321).keyStepper ) good( cm.LinkedHashMap[Int, Int](0xDEEDED -> 654321).valueStepper ) Okay( cm.LinkedHashSet[Int](654321).stepper ) @@ -419,17 +411,15 @@ class StepConvertersTest { Okay( cm.LongMap[Int](9876543210L -> 654321).valueStepper ) Okay( cm.Map[Int, Int](0xDEEDED -> 654321).keyStepper ) Okay( cm.Map[Int, Int](0xDEEDED -> 654321).valueStepper ) - Okay( cm.MutableList[Int](654321).stepper ) Okay( cm.OpenHashMap[Int, Int](0xDEEDED -> 654321).keyStepper ) Okay( cm.OpenHashMap[Int, Int](0xDEEDED -> 654321).valueStepper ) Okay( cm.PriorityQueue[Int](654321).stepper ) - Okay( cm.Queue[Int](654321).stepper ) - good( cm.ResizableArray[Int](654321).stepper ) + Fine( cm.Queue[Int](654321).stepper ) // Used to be `Good` in 2.12, in 2.13 `Queue` is no longer a `LinearSeq` Okay( cm.Seq[Int](654321).stepper ) Okay( cm.Set[Int](654321).stepper ) Okay( cm.SortedSet[Int](654321).stepper ) - Okay( cm.Stack[Int](654321).stepper ) - IFFY( cm.Traversable[Int](654321).accumulate.stepper ) + Fine( cm.Stack[Int](654321).stepper ) // Used to be `Good` in 2.12, in 2.13 `Stack` is no longer a `LinearSeq` + IFFY( cm.Iterable[Int](654321).accumulate.stepper ) Okay( cm.TreeSet[Int](654321).stepper ) Okay( cm.UnrolledBuffer[Int](654321).stepper ) Okay( cm.WeakHashMap[Int, Int](0xDEEDED -> 654321).keyStepper ) @@ -488,9 +478,9 @@ class StepConvertersTest { Okay( co.SortedMap[Long, Long](1234567654321L -> 0x123456789L).keyStepper ) Okay( co.SortedMap[Long, Long](1234567654321L -> 0x123456789L).valueStepper ) Okay( co.SortedSet[Long](0x123456789L).stepper ) - IFFY( co.Traversable[Long](0x123456789L).accumulate.stepper ) - IFFY( (co.Iterator[Long](0x123456789L): co.TraversableOnce[Long]).accumulate.stepper ) - IFFY( co.Traversable[Long](0x123456789L).view.accumulate.stepper ) + IFFY( co.Iterable[Long](0x123456789L).accumulate.stepper ) + IFFY( (co.Iterator[Long](0x123456789L): co.IterableOnce[Long]).accumulate.stepper ) + IFFY( co.Iterable[Long](0x123456789L).view.accumulate.stepper ) // Immutable section Okay( ci.::(0x123456789L, Nil).stepper ) @@ -517,10 +507,11 @@ class StepConvertersTest { Okay( ci.SortedMap[Long, Long](1234567654321L -> 0x123456789L).keyStepper ) Okay( ci.SortedMap[Long, Long](1234567654321L -> 0x123456789L).valueStepper ) Okay( ci.SortedSet[Long](0x123456789L).stepper ) - Okay( ci.Stack[Long](0x123456789L).stepper ) Okay( ci.Stream[Long](0x123456789L).stepper ) _eh_( ci.Stream[Long](0x123456789L).view.stepper ) - IFFY( ci.Traversable[Long](0x123456789L).accumulate.stepper ) + Okay( ci.LazyList[Long](0x123456789L).stepper ) + _eh_( ci.LazyList[Long](0x123456789L).view.stepper ) + IFFY( ci.Iterable[Long](0x123456789L).accumulate.stepper ) Okay( ci.TreeMap[Long, Long](1234567654321L -> 0x123456789L).keyStepper ) Okay( ci.TreeMap[Long, Long](1234567654321L -> 0x123456789L).valueStepper ) Okay( ci.TreeSet[Long](0x123456789L).stepper ) @@ -535,8 +526,7 @@ class StepConvertersTest { Okay( (cm.HashSet[Long](0x123456789L): cm.AbstractSet[Long]).stepper ) Okay( cm.AnyRefMap[String,Long]("fish" -> 0x123456789L).valueStepper ) good( cm.ArrayBuffer[Long](0x123456789L).stepper ) - good( ((Array(0x123456789L): cm.WrappedArray[Long]): cm.ArrayLike[Long, cm.WrappedArray[Long]]).stepper ) - good( (Array(0x123456789L): cm.ArrayOps[Long]).stepper ) + good( (Array(0x123456789L): cm.WrappedArray[Long]).stepper ) good( cm.ArraySeq[Long](0x123456789L).stepper ) _eh_( cm.ArrayStack[Long](0x123456789L).stepper ) Okay( (cm.ArrayBuffer[Long](0x123456789L): cm.Buffer[Long]).stepper ) @@ -546,7 +536,6 @@ class StepConvertersTest { good( cm.IndexedSeq[Long](0x123456789L).stepper ) good( cm.IndexedSeq[Long](0x123456789L).view.stepper ) Okay( cm.Iterable[Long](0x123456789L).stepper ) - Okay( cm.LinearSeq[Long](0x123456789L).stepper ) good( cm.LinkedHashMap[Long, Long](1234567654321L -> 0x123456789L).keyStepper ) good( cm.LinkedHashMap[Long, Long](1234567654321L -> 0x123456789L).valueStepper ) Okay( cm.LinkedHashSet[Long](0x123456789L).stepper ) @@ -557,17 +546,15 @@ class StepConvertersTest { Okay( cm.LongMap[Long](9876543210L -> 0x123456789L).valueStepper ) Okay( cm.Map[Long, Long](1234567654321L -> 0x123456789L).keyStepper ) Okay( cm.Map[Long, Long](1234567654321L -> 0x123456789L).valueStepper ) - Okay( cm.MutableList[Long](0x123456789L).stepper ) Okay( cm.OpenHashMap[Long, Long](1234567654321L -> 0x123456789L).keyStepper ) Okay( cm.OpenHashMap[Long, Long](1234567654321L -> 0x123456789L).valueStepper ) Okay( cm.PriorityQueue[Long](0x123456789L).stepper ) - Okay( cm.Queue[Long](0x123456789L).stepper ) - good( cm.ResizableArray[Long](0x123456789L).stepper ) + Fine( cm.Queue[Long](0x123456789L).stepper ) // Used to be `Good` in 2.12, in 2.13 `Queue` is no longer a `LinearSeq` Okay( cm.Seq[Long](0x123456789L).stepper ) Okay( cm.Set[Long](0x123456789L).stepper ) Okay( cm.SortedSet[Long](0x123456789L).stepper ) - Okay( cm.Stack[Long](0x123456789L).stepper ) - IFFY( cm.Traversable[Long](0x123456789L).accumulate.stepper ) + Fine( cm.Stack[Long](0x123456789L).stepper ) // Used to be `Good` in 2.12, in 2.13 `Stack` is no longer a `LinearSeq` + IFFY( cm.Iterable[Long](0x123456789L).accumulate.stepper ) Okay( cm.TreeSet[Long](0x123456789L).stepper ) Okay( cm.UnrolledBuffer[Long](0x123456789L).stepper ) Okay( cm.WeakHashMap[Long, Long](1234567654321L -> 0x123456789L).keyStepper ) @@ -588,7 +575,6 @@ class StepConvertersTest { implicit val spec = SpecCheck(_.isInstanceOf[IntStepper], x => s"$x should be an IntStepper") good( ci.NumericRange(277: Short, 279: Short, 1: Short).stepper ) - good( ("salmon": ci.StringOps).stepper ) good( ("salmon": ci.WrappedString).stepper ) } } From d7299b656c9f052ed6a70da7a958f3ee2073a2cb Mon Sep 17 00:00:00 2001 From: Lukas Rytz Date: Wed, 13 Jun 2018 16:01:48 +0200 Subject: [PATCH 03/23] WrappedArray -> ArraySeq --- README.md | 2 +- .../main/scala/bench/CollectionSource.scala | 4 ++-- .../src/main/scala/bench/ParseJmhLog.scala | 2 +- .../scala/compat/java8/StreamConverters.scala | 6 +++--- .../java8/converterImpl/StepConverters.scala | 2 +- .../compat/java8/StepConvertersTest.scala | 16 ++++++---------- .../compat/java8/StreamConvertersTest.scala | 18 +++++++++--------- 7 files changed, 23 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index 4f89b6d..0057af3 100644 --- a/README.md +++ b/README.md @@ -161,7 +161,7 @@ as the collection can (in some cases) be built in parallel. Because the wrappers are invoked based on the static type of the collection, there are also cases where parallelization is inefficient when interfacing with Java 8 Streams (e.g. when a collection is typed as `Seq[String]` so might have linear -access like `List`, but actually is a `WrappedArray[String]` that can be efficiently parallelized) but can be efficient +access like `List`, but actually is an `ArraySeq[String]` that can be efficiently parallelized) but can be efficient with Scala parallel collections. The `parStream` method is only available when the static type is known to be compatible with rapid parallel operation; `seqStream` can be parallelized by using `.parallel`, but may or may not be efficient. diff --git a/benchmark/src/main/scala/bench/CollectionSource.scala b/benchmark/src/main/scala/bench/CollectionSource.scala index 2713543..2dc0305 100644 --- a/benchmark/src/main/scala/bench/CollectionSource.scala +++ b/benchmark/src/main/scala/bench/CollectionSource.scala @@ -256,7 +256,7 @@ package object generate { class MuqThings(val sizes: Array[Int]) extends AbstractThings[collection.mutable.Queue]("mutable.Queue") {} - class WraThings(val sizes: Array[Int]) extends AbstractThings[collection.mutable.WrappedArray]("mutable.WrappedArray") {} + class AsqThings(val sizes: Array[Int]) extends AbstractThings[collection.mutable.ArraySeq]("mutable.ArraySeq") {} class JixThings(val sizes: Array[Int]) extends AbstractThings[java.util.ArrayList]("java.util.ArrayList") {} @@ -279,7 +279,7 @@ package object generate { lazy val lhs = new LhsThings(sizes) lazy val prq = new PrqThings(sizes) lazy val muq = new MuqThings(sizes) - lazy val wra = new WraThings(sizes) + lazy val asq = new AsqThings(sizes) lazy val jix = new JixThings(sizes) lazy val jln = new JlnThings(sizes) } diff --git a/benchmark/src/main/scala/bench/ParseJmhLog.scala b/benchmark/src/main/scala/bench/ParseJmhLog.scala index 90cc9d3..9e77792 100644 --- a/benchmark/src/main/scala/bench/ParseJmhLog.scala +++ b/benchmark/src/main/scala/bench/ParseJmhLog.scala @@ -24,7 +24,7 @@ object ParseJmhLog { "stm" -> "collection.immutable.Stream", "trs" -> "collection.immutable.TreeSet", "vec" -> "collection.immutable.Vector", - "wra" -> "collection.mutable.WrappedArray", + "asq" -> "collection.mutable.ArraySeq", "jix" -> "java.util.ArrayList", "jln" -> "java.util.LinkedList" ) diff --git a/src/main/scala/scala/compat/java8/StreamConverters.scala b/src/main/scala/scala/compat/java8/StreamConverters.scala index 48f85e1..a7893de 100644 --- a/src/main/scala/scala/compat/java8/StreamConverters.scala +++ b/src/main/scala/scala/compat/java8/StreamConverters.scala @@ -195,19 +195,19 @@ with converterImpl.Priority1AccumulatorConverters def parStream: LongStream = seqStream.parallel } - implicit final class EnrichDoubleWrappedArrayWithStream(private val a: collection.mutable.WrappedArray[Double]) + implicit final class EnrichDoubleArraySeqWithStream(private val a: collection.mutable.ArraySeq[Double]) extends AnyVal with MakesSequentialStream[Double, DoubleStream] with MakesParallelStream[Double, DoubleStream] { def seqStream: DoubleStream = java.util.Arrays.stream(a.array) def parStream: DoubleStream = seqStream.parallel } - implicit final class EnrichIntWrappedArrayWithStream(private val a: collection.mutable.WrappedArray[Int]) + implicit final class EnrichIntArraySeqWithStream(private val a: collection.mutable.ArraySeq[Int]) extends AnyVal with MakesSequentialStream[Int, IntStream] with MakesParallelStream[Int, IntStream] { def seqStream: IntStream = java.util.Arrays.stream(a.array) def parStream: IntStream = seqStream.parallel } - implicit final class EnrichLongWrappedArrayWithStream(private val a: collection.mutable.WrappedArray[Long]) + implicit final class EnrichLongArraySeqWithStream(private val a: collection.mutable.ArraySeq[Long]) extends AnyVal with MakesSequentialStream[Long, LongStream] with MakesParallelStream[Long, LongStream] { def seqStream: LongStream = java.util.Arrays.stream(a.array) def parStream: LongStream = seqStream.parallel diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepConverters.scala b/src/main/scala/scala/compat/java8/converterImpl/StepConverters.scala index 994eecb..fbeee4c 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepConverters.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepConverters.scala @@ -16,7 +16,7 @@ trait Priority1StepConverters extends Priority2StepConverters { implicit def richDefaultHashMapCanStep[K, V](underlying: collection.mutable.HashMap[K, V]) = new RichHashMapCanStep[K, V](underlying) implicit def richLinkedHashMapCanStep[K, V](underlying: collection.mutable.LinkedHashMap[K, V]) = new RichLinkedHashMapCanStep[K, V](underlying) implicit def richArrayCanStep[A](underlying: Array[A]) = new RichArrayCanStep[A](underlying) - implicit def richWrappedArrayCanStep[A](underlying: collection.mutable.WrappedArray[A]) = new RichArrayCanStep[A](underlying.array) + implicit def richArraySeqCanStep[A](underlying: collection.mutable.ArraySeq[A]) = new RichArrayCanStep[A](underlying.array) implicit def richHashSetCanStep[A](underlying: collection.mutable.HashSet[A]) = new RichHashSetCanStep[A](underlying) implicit def richIteratorCanStep[A](underlying: Iterator[A]) = new RichIteratorCanStep(underlying) implicit def richImmHashMapCanStep[K, V](underlying: collection.immutable.HashMap[K, V]) = new RichImmHashMapCanStep[K, V](underlying) diff --git a/src/test/scala/scala/compat/java8/StepConvertersTest.scala b/src/test/scala/scala/compat/java8/StepConvertersTest.scala index 6324fa3..1544d91 100644 --- a/src/test/scala/scala/compat/java8/StepConvertersTest.scala +++ b/src/test/scala/scala/compat/java8/StepConvertersTest.scala @@ -153,7 +153,7 @@ class StepConvertersTest { Okay( cm.AnyRefMap[String,String]("fish" -> "salmon").keyStepper ) Okay( cm.AnyRefMap[String,String]("fish" -> "salmon").valueStepper ) good( cm.ArrayBuffer[String]("salmon").stepper ) - good( (Array("salmon"): cm.WrappedArray[String]).stepper ) + good( (Array("salmon"): cm.ArraySeq[String]).stepper ) good( cm.ArraySeq[String]("salmon").stepper ) _eh_( cm.ArrayStack[String]("salmon").stepper ) Okay( (cm.ArrayBuffer[String]("salmon"): cm.Buffer[String]).stepper ) @@ -192,7 +192,6 @@ class StepConvertersTest { Okay( cm.WeakHashMap[String, String]("fish" -> "salmon").stepper ) Okay( cm.WeakHashMap[String, String]("fish" -> "salmon").keyStepper ) Okay( cm.WeakHashMap[String, String]("fish" -> "salmon").valueStepper ) - good( (Array("salmon"): cm.WrappedArray[String]).stepper ) // Java 6 converters section @@ -272,7 +271,7 @@ class StepConvertersTest { Okay( (cm.HashSet[Double](3.14159): cm.AbstractSet[Double]).stepper ) Okay( cm.AnyRefMap[String,Double]("fish" -> 3.14159).valueStepper ) good( cm.ArrayBuffer[Double](3.14159).stepper ) - good( (Array(3.14159): cm.WrappedArray[Double]).stepper ) + good( (Array(3.14159): cm.ArraySeq[Double]).stepper ) good( cm.ArraySeq[Double](3.14159).stepper ) _eh_( cm.ArrayStack[Double](3.14159).stepper ) Okay( (cm.ArrayBuffer[Double](3.14159): cm.Buffer[Double]).stepper ) @@ -304,7 +303,6 @@ class StepConvertersTest { Okay( cm.UnrolledBuffer[Double](3.14159).stepper ) Okay( cm.WeakHashMap[Double, Double](2.718281828 -> 3.14159).keyStepper ) Okay( cm.WeakHashMap[Double, Double](2.718281828 -> 3.14159).valueStepper ) - good( (Array(3.14159): cm.WrappedArray[Double]).stepper ) // Java 6 converters section @@ -392,7 +390,7 @@ class StepConvertersTest { Okay( (cm.HashSet[Int](654321): cm.AbstractSet[Int]).stepper ) Okay( cm.AnyRefMap[String, Int]("fish" -> 654321).valueStepper ) good( cm.ArrayBuffer[Int](654321).stepper ) - good( (Array(654321): cm.WrappedArray[Int]).stepper ) + good( (Array(654321): cm.ArraySeq[Int]).stepper ) good( cm.ArraySeq[Int](654321).stepper ) _eh_( cm.ArrayStack[Int](654321).stepper ) Okay( (cm.ArrayBuffer[Int](654321): cm.Buffer[Int]).stepper ) @@ -424,7 +422,6 @@ class StepConvertersTest { Okay( cm.UnrolledBuffer[Int](654321).stepper ) Okay( cm.WeakHashMap[Int, Int](0xDEEDED -> 654321).keyStepper ) Okay( cm.WeakHashMap[Int, Int](0xDEEDED -> 654321).valueStepper ) - good( (Array(654321): cm.WrappedArray[Int]).stepper ) // Java 6 converters section @@ -440,12 +437,12 @@ class StepConvertersTest { implicit val spec = SpecCheck(_.isInstanceOf[IntStepper], x => s"$x should be an IntStepper") good( Array[Short](654321.toShort).stepper ) - good( (Array[Short](654321.toShort): cm.WrappedArray[Short]).stepper ) + good( (Array[Short](654321.toShort): cm.ArraySeq[Short]).stepper ) //TODO: None of these currently work because there are no native Stepper implementations: //good( ci.NumericRange(123456.toShort, 123458.toShort, 1.toShort).stepper ) - //good( ((Array[Short](654321.toShort): cm.WrappedArray[Short]): cm.ArrayLike[Short, cm.WrappedArray[Short]]).stepper ) + //good( ((Array[Short](654321.toShort): cm.ArraySeq[Short]): cm.ArrayLike[Short, cm.ArraySeq[Short]]).stepper ) //good( (Array[Short](654321.toShort): cm.ArrayOps[Short]).stepper ) //good( cm.ResizableArray[Short](654321.toShort).stepper ) } @@ -526,7 +523,7 @@ class StepConvertersTest { Okay( (cm.HashSet[Long](0x123456789L): cm.AbstractSet[Long]).stepper ) Okay( cm.AnyRefMap[String,Long]("fish" -> 0x123456789L).valueStepper ) good( cm.ArrayBuffer[Long](0x123456789L).stepper ) - good( (Array(0x123456789L): cm.WrappedArray[Long]).stepper ) + good( (Array(0x123456789L): cm.ArraySeq[Long]).stepper ) good( cm.ArraySeq[Long](0x123456789L).stepper ) _eh_( cm.ArrayStack[Long](0x123456789L).stepper ) Okay( (cm.ArrayBuffer[Long](0x123456789L): cm.Buffer[Long]).stepper ) @@ -559,7 +556,6 @@ class StepConvertersTest { Okay( cm.UnrolledBuffer[Long](0x123456789L).stepper ) Okay( cm.WeakHashMap[Long, Long](1234567654321L -> 0x123456789L).keyStepper ) Okay( cm.WeakHashMap[Long, Long](1234567654321L -> 0x123456789L).valueStepper ) - good( (Array(0x123456789L): cm.WrappedArray[Long]).stepper ) // Java 6 converters section diff --git a/src/test/scala/scala/compat/java8/StreamConvertersTest.scala b/src/test/scala/scala/compat/java8/StreamConvertersTest.scala index fbecae5..5acf41c 100644 --- a/src/test/scala/scala/compat/java8/StreamConvertersTest.scala +++ b/src/test/scala/scala/compat/java8/StreamConvertersTest.scala @@ -111,15 +111,15 @@ class StreamConvertersTest { assert(newLongStream(1).boxed.unboxed.isInstanceOf[LongStream]) } - import collection.mutable.{ ArrayBuffer, WrappedArray } + import collection.mutable.{ ArrayBuffer, ArraySeq } def abufO(n: Int) = { val ab = new ArrayBuffer[String]; arrayO(n).foreach(ab += _); ab } def abufD(n: Int) = { val ab = new ArrayBuffer[Double]; arrayD(n).foreach(ab += _); ab } def abufI(n: Int) = { val ab = new ArrayBuffer[Int]; arrayI(n).foreach(ab += _); ab } def abufL(n: Int) = { val ab = new ArrayBuffer[Long]; arrayL(n).foreach(ab += _); ab } - def wrapO(n: Int): WrappedArray[String] = arrayO(n) - def wrapD(n: Int): WrappedArray[Double] = arrayD(n) - def wrapI(n: Int): WrappedArray[Int] = arrayI(n) - def wrapL(n: Int): WrappedArray[Long] = arrayL(n) + def wrapO(n: Int): ArraySeq[String] = arrayO(n) + def wrapD(n: Int): ArraySeq[Double] = arrayD(n) + def wrapI(n: Int): ArraySeq[Int] = arrayI(n) + def wrapL(n: Int): ArraySeq[Long] = arrayL(n) def vectO(n: Int) = arrayO(n).toVector def vectD(n: Int) = arrayD(n).toVector def vectI(n: Int) = arrayI(n).toVector @@ -257,10 +257,10 @@ class StreamConvertersTest { @Test def streamMaterialization(): Unit = { - val coll = collection.mutable.WrappedArray.make[Int](Array(1,2,3)) - val streamize = implicitly[collection.mutable.WrappedArray[Int] => MakesSequentialStream[Int, IntStream]] - assertTrue(streamize(coll).getClass.getName.contains("EnrichIntWrappedArrayWithStream")) - val steppize = implicitly[collection.mutable.WrappedArray[Int] => MakesStepper[Int, Any]] + val coll = collection.mutable.ArraySeq.make[Int](Array(1,2,3)) + val streamize = implicitly[collection.mutable.ArraySeq[Int] => MakesSequentialStream[Int, IntStream]] + assertTrue(streamize(coll).getClass.getName.contains("EnrichIntArraySeqWithStream")) + val steppize = implicitly[collection.mutable.ArraySeq[Int] => MakesStepper[Int, Any]] assertTrue(steppize(coll).getClass.getName.contains("RichArrayCanStep")) val stepper = steppize(coll).stepper assertTrue(stepper.getClass.getName.contains("StepsIntArray")) From d72f6bd05ce4745c0de6f4bf5c4bda34b91442d5 Mon Sep 17 00:00:00 2001 From: Lukas Rytz Date: Sat, 16 Jun 2018 20:29:30 +0200 Subject: [PATCH 04/23] Re-enable docs --- build.sbt | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/build.sbt b/build.sbt index 87f5e9e..d4fad94 100644 --- a/build.sbt +++ b/build.sbt @@ -4,7 +4,7 @@ crossScalaVersions in ThisBuild := List("2.13.0-M4") val disableDocs = sys.props("nodocs") == "true" -//lazy val JavaDoc = config("genjavadoc") extend Compile +lazy val JavaDoc = config("genjavadoc") extend Compile def jwrite(dir: java.io.File, pck: String = "scala/compat/java8")(name: String, content: String) = { val f = dir / pck / s"${name}.java" @@ -103,9 +103,6 @@ lazy val root = (project in file(".")). } ). settings( - sources in (Compile,doc) := Seq.empty, - publishArtifact in (Compile, packageDoc) := false). -/* settings( (inConfig(JavaDoc)(Defaults.configSettings) ++ (if (disableDocs) Nil else Seq( packageDoc in Compile := (packageDoc in JavaDoc).value, sources in JavaDoc := { @@ -119,7 +116,7 @@ lazy val root = (project in file(".")). libraryDependencies += compilerPlugin("com.typesafe.genjavadoc" % "genjavadoc-plugin" % "0.11" cross CrossVersion.full), scalacOptions in Compile += "-P:genjavadoc:out=" + (target.value / "java") ))): _* - ).*/ + ). settings( initialCommands := """|import scala.concurrent._ From c426decebf0b3f97d7bcb23e5d98ba3ad71eec36 Mon Sep 17 00:00:00 2001 From: xuwei-k <6b656e6a69@gmail.com> Date: Mon, 18 Jun 2018 11:41:29 +0900 Subject: [PATCH 05/23] fix compile errors in latest Scala 2.13 - https://github.com/scala/scala/commit/1e21c918361b22d66575acb82b57d532823b198a#diff-c4d00ae1df2a449ae3d28a7a4469e28a - https://scala-ci.typesafe.com/job/scala-2.13.x-integrate-community-build/1187/consoleFull ``` [scala-java8-compat] [error] /home/jenkins/workspace/scala-2.13.x-integrate-community-build/target-0.9.12/project-builds/scala-java8-compat-e21fca9479a0769dd077af3a1d088d2f68798316/src/main/scala/scala/compat/java8/converterImpl/StepConverters.scala:19: type mismatch; [scala-java8-compat] [error] found : Array[_$2] where type _$2 [scala-java8-compat] [error] required: Array[A] [scala-java8-compat] [error] Note: implicit method richArraySeqCanStep is not applicable here because it comes after the application point and it lacks an explicit result type [scala-java8-compat] [error] implicit def richArraySeqCanStep[A](underlying: collection.mutable.ArraySeq[A]) = new RichArrayCanStep[A](underlying.array) [scala-java8-compat] [error] ^ [scala-java8-compat] [error] /home/jenkins/workspace/scala-2.13.x-integrate-community-build/target-0.9.12/project-builds/scala-java8-compat-e21fca9479a0769dd077af3a1d088d2f68798316/src/main/scala/scala/compat/java8/StreamConverters.scala:200: type mismatch; [scala-java8-compat] [error] found : Array[_$2] where type _$2 [scala-java8-compat] [error] required: Array[Double] [scala-java8-compat] [error] Note: implicit value accumulateLongStepper is not applicable here because it comes after the application point and it lacks an explicit result type [scala-java8-compat] [error] def seqStream: DoubleStream = java.util.Arrays.stream(a.array) [scala-java8-compat] [error] ^ [scala-java8-compat] [error] /home/jenkins/workspace/scala-2.13.x-integrate-community-build/target-0.9.12/project-builds/scala-java8-compat-e21fca9479a0769dd077af3a1d088d2f68798316/src/main/scala/scala/compat/java8/StreamConverters.scala:206: type mismatch; [scala-java8-compat] [error] found : Array[_$2] where type _$2 [scala-java8-compat] [error] required: Array[Int] [scala-java8-compat] [error] Note: implicit value accumulateLongStepper is not applicable here because it comes after the application point and it lacks an explicit result type [scala-java8-compat] [error] def seqStream: IntStream = java.util.Arrays.stream(a.array) [scala-java8-compat] [error] ^ [scala-java8-compat] [error] /home/jenkins/workspace/scala-2.13.x-integrate-community-build/target-0.9.12/project-builds/scala-java8-compat-e21fca9479a0769dd077af3a1d088d2f68798316/src/main/scala/scala/compat/java8/StreamConverters.scala:212: type mismatch; [scala-java8-compat] [error] found : Array[_$2] where type _$2 [scala-java8-compat] [error] required: Array[Long] [scala-java8-compat] [error] Note: implicit value accumulateLongStepper is not applicable here because it comes after the application point and it lacks an explicit result type [scala-java8-compat] [error] def seqStream: LongStream = java.util.Arrays.stream(a.array) [scala-java8-compat] [error] ^ ``` --- .../scala/compat/java8/StreamConverters.scala | 14 +++++++++++--- .../java8/converterImpl/StepConverters.scala | 6 ++++-- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/main/scala/scala/compat/java8/StreamConverters.scala b/src/main/scala/scala/compat/java8/StreamConverters.scala index a7893de..933bc29 100644 --- a/src/main/scala/scala/compat/java8/StreamConverters.scala +++ b/src/main/scala/scala/compat/java8/StreamConverters.scala @@ -5,6 +5,7 @@ import scala.language.higherKinds import java.util.stream._ import scala.compat.java8.collectionImpl._ import scala.compat.java8.converterImpl._ +import scala.reflect.ClassTag /** Classes or objects implementing this trait create streams suitable for sequential use */ trait MakesSequentialStream[T, SS <: java.util.stream.BaseStream[_, SS]] extends Any { @@ -177,6 +178,13 @@ extends Priority1StreamConverters with converterImpl.Priority1StepConverters with converterImpl.Priority1AccumulatorConverters { + private[java8] def unsafeArrayIfPossible[A](a: collection.mutable.ArraySeq[A])(implicit c: ClassTag[A]): Array[A] = { + if (a.elemTag == c) + a.array.asInstanceOf[Array[A]] + else + a.toArray + } + implicit final class EnrichDoubleArrayWithStream(private val a: Array[Double]) extends AnyVal with MakesSequentialStream[Double, DoubleStream] with MakesParallelStream[Double, DoubleStream] { def seqStream: DoubleStream = java.util.Arrays.stream(a) @@ -197,19 +205,19 @@ with converterImpl.Priority1AccumulatorConverters implicit final class EnrichDoubleArraySeqWithStream(private val a: collection.mutable.ArraySeq[Double]) extends AnyVal with MakesSequentialStream[Double, DoubleStream] with MakesParallelStream[Double, DoubleStream] { - def seqStream: DoubleStream = java.util.Arrays.stream(a.array) + def seqStream: DoubleStream = java.util.Arrays.stream(unsafeArrayIfPossible(a)) def parStream: DoubleStream = seqStream.parallel } implicit final class EnrichIntArraySeqWithStream(private val a: collection.mutable.ArraySeq[Int]) extends AnyVal with MakesSequentialStream[Int, IntStream] with MakesParallelStream[Int, IntStream] { - def seqStream: IntStream = java.util.Arrays.stream(a.array) + def seqStream: IntStream = java.util.Arrays.stream(unsafeArrayIfPossible(a)) def parStream: IntStream = seqStream.parallel } implicit final class EnrichLongArraySeqWithStream(private val a: collection.mutable.ArraySeq[Long]) extends AnyVal with MakesSequentialStream[Long, LongStream] with MakesParallelStream[Long, LongStream] { - def seqStream: LongStream = java.util.Arrays.stream(a.array) + def seqStream: LongStream = java.util.Arrays.stream(unsafeArrayIfPossible(a)) def parStream: LongStream = seqStream.parallel } diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepConverters.scala b/src/main/scala/scala/compat/java8/converterImpl/StepConverters.scala index fbeee4c..a2e7015 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepConverters.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepConverters.scala @@ -1,6 +1,8 @@ -package scala.compat.java8.converterImpl +package scala.compat.java8 +package converterImpl import language.implicitConversions +import scala.reflect.ClassTag trait Priority3StepConverters { implicit def richIterableCanStep[A](underlying: Iterable[A]) = new RichIterableCanStep(underlying) @@ -16,7 +18,7 @@ trait Priority1StepConverters extends Priority2StepConverters { implicit def richDefaultHashMapCanStep[K, V](underlying: collection.mutable.HashMap[K, V]) = new RichHashMapCanStep[K, V](underlying) implicit def richLinkedHashMapCanStep[K, V](underlying: collection.mutable.LinkedHashMap[K, V]) = new RichLinkedHashMapCanStep[K, V](underlying) implicit def richArrayCanStep[A](underlying: Array[A]) = new RichArrayCanStep[A](underlying) - implicit def richArraySeqCanStep[A](underlying: collection.mutable.ArraySeq[A]) = new RichArrayCanStep[A](underlying.array) + implicit def richArraySeqCanStep[A: ClassTag](underlying: collection.mutable.ArraySeq[A]) = new RichArrayCanStep[A](StreamConverters.unsafeArrayIfPossible(underlying)) implicit def richHashSetCanStep[A](underlying: collection.mutable.HashSet[A]) = new RichHashSetCanStep[A](underlying) implicit def richIteratorCanStep[A](underlying: Iterator[A]) = new RichIteratorCanStep(underlying) implicit def richImmHashMapCanStep[K, V](underlying: collection.immutable.HashMap[K, V]) = new RichImmHashMapCanStep[K, V](underlying) From da3bef5b5813b8dc8457867547bb35a7f4469a64 Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Tue, 10 Jul 2018 18:04:56 -0700 Subject: [PATCH 06/23] adapt to post 2.13.0-M4 changes adding explicit result types to implicits. not sure what Scala change made these fail to compile otherwise, but they are good changes regardless --- .../scala/compat/java8/StreamConverters.scala | 123 ++++++++++-------- .../java8/converterImpl/StepConverters.scala | 51 +++++--- 2 files changed, 100 insertions(+), 74 deletions(-) diff --git a/src/main/scala/scala/compat/java8/StreamConverters.scala b/src/main/scala/scala/compat/java8/StreamConverters.scala index 933bc29..439d4ec 100644 --- a/src/main/scala/scala/compat/java8/StreamConverters.scala +++ b/src/main/scala/scala/compat/java8/StreamConverters.scala @@ -221,52 +221,58 @@ with converterImpl.Priority1AccumulatorConverters def parStream: LongStream = seqStream.parallel } - implicit val primitiveAccumulateDoubleStream = new PrimitiveStreamAccumulator[Stream[Double], DoubleAccumulator] { - def streamAccumulate(stream: Stream[Double]): DoubleAccumulator = - stream.collect(DoubleAccumulator.supplier, DoubleAccumulator.boxedAdder, DoubleAccumulator.merger) - } - - implicit val primitiveAccumulateDoubleStream2 = + implicit val primitiveAccumulateDoubleStream: PrimitiveStreamAccumulator[Stream[Double], DoubleAccumulator] = + new PrimitiveStreamAccumulator[Stream[Double], DoubleAccumulator] { + def streamAccumulate(stream: Stream[Double]): DoubleAccumulator = + stream.collect(DoubleAccumulator.supplier, DoubleAccumulator.boxedAdder, DoubleAccumulator.merger) + } + + implicit val primitiveAccumulateDoubleStream2: PrimitiveStreamAccumulator[Stream[java.lang.Double], DoubleAccumulator] = primitiveAccumulateDoubleStream.asInstanceOf[PrimitiveStreamAccumulator[Stream[java.lang.Double], DoubleAccumulator]] - - implicit val primitiveUnboxDoubleStream = new PrimitiveStreamUnboxer[Double, DoubleStream] { - def apply(boxed: Stream[Double]): DoubleStream = - boxed.mapToDouble(new java.util.function.ToDoubleFunction[Double]{ def applyAsDouble(d: Double) = d }) - } - - implicit val primitiveUnboxDoubleStream2 = + + implicit val primitiveUnboxDoubleStream: PrimitiveStreamUnboxer[Double, DoubleStream] = + new PrimitiveStreamUnboxer[Double, DoubleStream] { + def apply(boxed: Stream[Double]): DoubleStream = + boxed.mapToDouble(new java.util.function.ToDoubleFunction[Double]{ def applyAsDouble(d: Double) = d }) + } + + implicit val primitiveUnboxDoubleStream2: PrimitiveStreamUnboxer[java.lang.Double, DoubleStream] = primitiveUnboxDoubleStream.asInstanceOf[PrimitiveStreamUnboxer[java.lang.Double, DoubleStream]] - - implicit val primitiveAccumulateIntStream = new PrimitiveStreamAccumulator[Stream[Int], IntAccumulator] { - def streamAccumulate(stream: Stream[Int]): IntAccumulator = - stream.collect(IntAccumulator.supplier, IntAccumulator.boxedAdder, IntAccumulator.merger) - } - implicit val primitiveAccumulateIntStream2 = + implicit val primitiveAccumulateIntStream: PrimitiveStreamAccumulator[Stream[Int], IntAccumulator] = + new PrimitiveStreamAccumulator[Stream[Int], IntAccumulator] { + def streamAccumulate(stream: Stream[Int]): IntAccumulator = + stream.collect(IntAccumulator.supplier, IntAccumulator.boxedAdder, IntAccumulator.merger) + } + + implicit val primitiveAccumulateIntStream2: PrimitiveStreamAccumulator[Stream[java.lang.Integer], IntAccumulator] = primitiveAccumulateIntStream.asInstanceOf[PrimitiveStreamAccumulator[Stream[java.lang.Integer], IntAccumulator]] - - implicit val primitiveUnboxIntStream = new PrimitiveStreamUnboxer[Int, IntStream] { - def apply(boxed: Stream[Int]): IntStream = - boxed.mapToInt(new java.util.function.ToIntFunction[Int]{ def applyAsInt(d: Int) = d }) - } - - implicit val primitiveUnboxIntStream2 = + + implicit val primitiveUnboxIntStream: PrimitiveStreamUnboxer[Int, IntStream] = + new PrimitiveStreamUnboxer[Int, IntStream] { + def apply(boxed: Stream[Int]): IntStream = + boxed.mapToInt(new java.util.function.ToIntFunction[Int]{ def applyAsInt(d: Int) = d }) + } + + implicit val primitiveUnboxIntStream2: PrimitiveStreamUnboxer[java.lang.Integer, IntStream] = primitiveUnboxIntStream.asInstanceOf[PrimitiveStreamUnboxer[java.lang.Integer, IntStream]] - - implicit val primitiveAccumulateLongStream = new PrimitiveStreamAccumulator[Stream[Long], LongAccumulator] { - def streamAccumulate(stream: Stream[Long]): LongAccumulator = - stream.collect(LongAccumulator.supplier, LongAccumulator.boxedAdder, LongAccumulator.merger) - } - implicit val primitiveAccumulateLongStream2 = + implicit val primitiveAccumulateLongStream: PrimitiveStreamAccumulator[Stream[Long], LongAccumulator] = + new PrimitiveStreamAccumulator[Stream[Long], LongAccumulator] { + def streamAccumulate(stream: Stream[Long]): LongAccumulator = + stream.collect(LongAccumulator.supplier, LongAccumulator.boxedAdder, LongAccumulator.merger) + } + + implicit val primitiveAccumulateLongStream2: PrimitiveStreamAccumulator[Stream[java.lang.Long], LongAccumulator] = primitiveAccumulateLongStream.asInstanceOf[PrimitiveStreamAccumulator[Stream[java.lang.Long], LongAccumulator]] - - implicit val primitiveUnboxLongStream = new PrimitiveStreamUnboxer[Long, LongStream] { - def apply(boxed: Stream[Long]): LongStream = - boxed.mapToLong(new java.util.function.ToLongFunction[Long]{ def applyAsLong(d: Long) = d }) - } - - implicit val primitiveUnboxLongStream2 = + + implicit val primitiveUnboxLongStream: PrimitiveStreamUnboxer[Long, LongStream] = + new PrimitiveStreamUnboxer[Long, LongStream] { + def apply(boxed: Stream[Long]): LongStream = + boxed.mapToLong(new java.util.function.ToLongFunction[Long]{ def applyAsLong(d: Long) = d }) + } + + implicit val primitiveUnboxLongStream2: PrimitiveStreamUnboxer[java.lang.Long, LongStream] = primitiveUnboxLongStream.asInstanceOf[PrimitiveStreamUnboxer[java.lang.Long, LongStream]] implicit final class RichDoubleStream(private val stream: DoubleStream) extends AnyVal { @@ -308,27 +314,30 @@ with converterImpl.Priority1AccumulatorConverters } } - implicit val accumulateDoubleStepper = new AccumulatesFromStepper[Double, DoubleAccumulator] { - def apply(stepper: Stepper[Double]) = { - val a = new DoubleAccumulator - while (stepper.hasStep) a += stepper.nextStep - a + implicit val accumulateDoubleStepper: AccumulatesFromStepper[Double, DoubleAccumulator] = + new AccumulatesFromStepper[Double, DoubleAccumulator] { + def apply(stepper: Stepper[Double]) = { + val a = new DoubleAccumulator + while (stepper.hasStep) a += stepper.nextStep + a + } } - } - implicit val accumulateIntStepper = new AccumulatesFromStepper[Int, IntAccumulator] { - def apply(stepper: Stepper[Int]) = { - val a = new IntAccumulator - while (stepper.hasStep) a += stepper.nextStep - a + implicit val accumulateIntStepper: AccumulatesFromStepper[Int, IntAccumulator] = + new AccumulatesFromStepper[Int, IntAccumulator] { + def apply(stepper: Stepper[Int]) = { + val a = new IntAccumulator + while (stepper.hasStep) a += stepper.nextStep + a + } } - } - implicit val accumulateLongStepper = new AccumulatesFromStepper[Long, LongAccumulator] { - def apply(stepper: Stepper[Long]) = { - val a = new LongAccumulator - while (stepper.hasStep) a += stepper.nextStep - a + implicit val accumulateLongStepper: AccumulatesFromStepper[Long, LongAccumulator] = + new AccumulatesFromStepper[Long, LongAccumulator] { + def apply(stepper: Stepper[Long]) = { + val a = new LongAccumulator + while (stepper.hasStep) a += stepper.nextStep + a + } } - } } diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepConverters.scala b/src/main/scala/scala/compat/java8/converterImpl/StepConverters.scala index a2e7015..7f7a903 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepConverters.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepConverters.scala @@ -5,27 +5,44 @@ import language.implicitConversions import scala.reflect.ClassTag trait Priority3StepConverters { - implicit def richIterableCanStep[A](underlying: Iterable[A]) = new RichIterableCanStep(underlying) - implicit def richMapCanStep[K, V](underlying: collection.Map[K, V]) = new RichMapCanStep[K, V](underlying) + implicit def richIterableCanStep[A](underlying: Iterable[A]): RichIterableCanStep[A] = + new RichIterableCanStep(underlying) + implicit def richMapCanStep[K, V](underlying: collection.Map[K, V]): RichMapCanStep[K, V] = + new RichMapCanStep[K, V](underlying) } trait Priority2StepConverters extends Priority3StepConverters { - implicit def richLinearSeqCanStep[A](underlying: collection.LinearSeq[A]) = new RichLinearSeqCanStep[A](underlying) - implicit def richIndexedSeqCanStep[A](underlying: collection.IndexedSeqOps[A, Any, _]) = new RichIndexedSeqCanStep[A](underlying) + implicit def richLinearSeqCanStep[A](underlying: collection.LinearSeq[A]): RichLinearSeqCanStep[A] = + new RichLinearSeqCanStep[A](underlying) + implicit def richIndexedSeqCanStep[A](underlying: collection.IndexedSeqOps[A, Any, _]): RichIndexedSeqCanStep[A] = + new RichIndexedSeqCanStep[A](underlying) } trait Priority1StepConverters extends Priority2StepConverters { - implicit def richDefaultHashMapCanStep[K, V](underlying: collection.mutable.HashMap[K, V]) = new RichHashMapCanStep[K, V](underlying) - implicit def richLinkedHashMapCanStep[K, V](underlying: collection.mutable.LinkedHashMap[K, V]) = new RichLinkedHashMapCanStep[K, V](underlying) - implicit def richArrayCanStep[A](underlying: Array[A]) = new RichArrayCanStep[A](underlying) - implicit def richArraySeqCanStep[A: ClassTag](underlying: collection.mutable.ArraySeq[A]) = new RichArrayCanStep[A](StreamConverters.unsafeArrayIfPossible(underlying)) - implicit def richHashSetCanStep[A](underlying: collection.mutable.HashSet[A]) = new RichHashSetCanStep[A](underlying) - implicit def richIteratorCanStep[A](underlying: Iterator[A]) = new RichIteratorCanStep(underlying) - implicit def richImmHashMapCanStep[K, V](underlying: collection.immutable.HashMap[K, V]) = new RichImmHashMapCanStep[K, V](underlying) - implicit def richImmHashSetCanStep[A](underlying: collection.immutable.HashSet[A]) = new RichImmHashSetCanStep[A](underlying) - implicit def richNumericRangeCanStep[T](underlying: collection.immutable.NumericRange[T]) = new RichNumericRangeCanStep(underlying) - implicit def richVectorCanStep[A](underlying: Vector[A]) = new RichVectorCanStep[A](underlying) - implicit def richBitSetCanStep(underlying: collection.BitSet) = new RichBitSetCanStep(underlying) - implicit def richRangeCanStep(underlying: Range) = new RichRangeCanStep(underlying) - implicit def richStringCanStep(underlying: String) = new RichStringCanStep(underlying) + implicit def richDefaultHashMapCanStep[K, V](underlying: collection.mutable.HashMap[K, V]): RichHashMapCanStep[K, V] = + new RichHashMapCanStep[K, V](underlying) + implicit def richLinkedHashMapCanStep[K, V](underlying: collection.mutable.LinkedHashMap[K, V]): RichLinkedHashMapCanStep[K, V] = + new RichLinkedHashMapCanStep[K, V](underlying) + implicit def richArrayCanStep[A](underlying: Array[A]): RichArrayCanStep[A] = + new RichArrayCanStep[A](underlying) + implicit def richArraySeqCanStep[A: ClassTag](underlying: collection.mutable.ArraySeq[A]): RichArrayCanStep[A] = + new RichArrayCanStep[A](StreamConverters.unsafeArrayIfPossible(underlying)) + implicit def richHashSetCanStep[A](underlying: collection.mutable.HashSet[A]): RichHashSetCanStep[A] = + new RichHashSetCanStep[A](underlying) + implicit def richIteratorCanStep[A](underlying: Iterator[A]): RichIteratorCanStep[A] = + new RichIteratorCanStep(underlying) + implicit def richImmHashMapCanStep[K, V](underlying: collection.immutable.HashMap[K, V]): RichImmHashMapCanStep[K, V] = + new RichImmHashMapCanStep[K, V](underlying) + implicit def richImmHashSetCanStep[A](underlying: collection.immutable.HashSet[A]): RichImmHashSetCanStep[A] = + new RichImmHashSetCanStep[A](underlying) + implicit def richNumericRangeCanStep[T](underlying: collection.immutable.NumericRange[T]): RichNumericRangeCanStep[T] = + new RichNumericRangeCanStep(underlying) + implicit def richVectorCanStep[A](underlying: Vector[A]): RichVectorCanStep[A] = + new RichVectorCanStep[A](underlying) + implicit def richBitSetCanStep(underlying: collection.BitSet): RichBitSetCanStep = + new RichBitSetCanStep(underlying) + implicit def richRangeCanStep(underlying: Range): RichRangeCanStep[Int] = + new RichRangeCanStep(underlying) + implicit def richStringCanStep(underlying: String): RichStringCanStep = + new RichStringCanStep(underlying) } From 3334e28cff36c2fe55889a82d8d6ab2e6381b4a7 Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Sat, 18 Aug 2018 09:12:50 -0700 Subject: [PATCH 07/23] remove pieces specific to old 2.12 HashMap implementation I suppose we ought to replace this instead of just remove it? but for now, I'm just trying to get the 2.13 community build green for 2.13.0-M5 --- .../compat/java8/ScalaStreamSupport.java | 109 ------------- .../java8/converterImpl/StepConverters.scala | 2 - .../java8/converterImpl/StepsImmHashMap.scala | 144 ------------------ .../converterImpl/StepsLikeImmHashMap.scala | 53 ------- .../compat/java8/StepConvertersTest.scala | 9 -- 5 files changed, 317 deletions(-) delete mode 100644 src/main/scala/scala/compat/java8/converterImpl/StepsImmHashMap.scala delete mode 100644 src/main/scala/scala/compat/java8/converterImpl/StepsLikeImmHashMap.scala diff --git a/src/main/java/scala/compat/java8/ScalaStreamSupport.java b/src/main/java/scala/compat/java8/ScalaStreamSupport.java index e403bf0..0af2622 100644 --- a/src/main/java/scala/compat/java8/ScalaStreamSupport.java +++ b/src/main/java/scala/compat/java8/ScalaStreamSupport.java @@ -32,43 +32,6 @@ public static Stream stream(scala.collection.IndexedSeq coll) { return StreamSupport.stream(new StepsAnyIndexedSeq((scala.collection.IndexedSeq)coll, 0, coll.length()), false); } - /** - * Generates a Stream that traverses the keys of a scala.collection.immutable.HashMap. - *

- * Both sequential and parallel operations will be efficient. - * - * @param coll The immutable.HashMap to traverse - * @return A Stream view of the collection which, by default, executes sequentially. - */ - public static Stream streamKeys(scala.collection.immutable.HashMap coll) { - return StreamSupport.stream(new StepsAnyImmHashMapKey(coll, 0, coll.size()), false); - } - - /** - * Generates a Stream that traverses the values of a scala.collection.immutable.HashMap. - *

- * Both sequential and parallel operations will be efficient. - * - * @param coll The immutable.HashMap to traverse - * @return A Stream view of the collection which, by default, executes sequentially. - */ - public static Stream streamValues(scala.collection.immutable.HashMap coll) { - return StreamSupport.stream(new StepsAnyImmHashMapValue(coll, 0, coll.size()), false); - } - - /** - * Generates a Stream that traverses the key-value pairs of a scala.collection.immutable.HashMap. - * The key-value pairs are presented as instances of scala.Tuple2. - *

- * Both sequential and parallel operations will be efficient. - * - * @param coll The immutable.HashMap to traverse - * @return A Stream view of the collection which, by default, executes sequentially. - */ - public static Stream< scala.Tuple2 > stream(scala.collection.immutable.HashMap coll) { - return StreamSupport.stream(new StepsAnyImmHashMap(coll, 0, coll.size()), false); - } - /** * Generates a Stream that traverses a scala.collection.immutable.HashSet. *

@@ -275,30 +238,6 @@ public static DoubleStream doubleStream(scala.collection.IndexedSeq coll return StreamSupport.doubleStream(new StepsDoubleIndexedSeq(coll, 0, coll.length()), false); } - /** - * Generates a DoubleStream that traverses double-valued keys of a scala.collection.immutable.HashMap. - *

- * Both sequential and parallel operations will be efficient. - * - * @param coll The immutable.HashMap to traverse - * @return A DoubleStream view of the collection which, by default, executes sequentially. - */ - public static DoubleStream doubleStreamKeys(scala.collection.immutable.HashMap coll) { - return StreamSupport.doubleStream(new StepsDoubleImmHashMapKey(coll, 0, coll.size()), false); - } - - /** - * Generates a DoubleStream that traverses double-valued values of a scala.collection.immutable.HashMap. - *

- * Both sequential and parallel operations will be efficient. - * - * @param coll The immutable.HashMap to traverse - * @return A DoubleStream view of the collection which, by default, executes sequentially. - */ - public static DoubleStream doubleStreamValues(scala.collection.immutable.HashMap coll) { - return StreamSupport.doubleStream(new StepsDoubleImmHashMapValue(coll, 0, coll.size()), false); - } - /** * Generates a DoubleStream that traverses a scala.collection.immutable.HashSet of Doubles. *

@@ -511,30 +450,6 @@ public static IntStream intStream(scala.collection.IndexedSeq coll) { return StreamSupport.intStream(new StepsIntIndexedSeq(coll, 0, coll.length()), false); } - /** - * Generates a IntStream that traverses int-valued keys of a scala.collection.immutable.HashMap. - *

- * Both sequential and parallel operations will be efficient. - * - * @param coll The immutable.HashMap to traverse - * @return A IntStream view of the collection which, by default, executes sequentially. - */ - public static IntStream intStreamKeys(scala.collection.immutable.HashMap coll) { - return StreamSupport.intStream(new StepsIntImmHashMapKey(coll, 0, coll.size()), false); - } - - /** - * Generates a IntStream that traverses int-valued values of a scala.collection.immutable.HashMap. - *

- * Both sequential and parallel operations will be efficient. - * - * @param coll The immutable.HashMap to traverse - * @return A IntStream view of the collection which, by default, executes sequentially. - */ - public static IntStream intStreamValues(scala.collection.immutable.HashMap coll) { - return StreamSupport.intStream(new StepsIntImmHashMapValue(coll, 0, coll.size()), false); - } - /** * Generates a IntStream that traverses a scala.collection.immutable.HashSet of Ints. *

@@ -720,30 +635,6 @@ public static LongStream longStream(scala.collection.IndexedSeq coll) { return StreamSupport.longStream(new StepsLongIndexedSeq(coll, 0, coll.length()), false); } - /** - * Generates a LongStream that traverses long-valued keys of a scala.collection.immutable.HashMap. - *

- * Both sequential and parallel operations will be efficient. - * - * @param coll The immutable.HashMap to traverse - * @return A LongStream view of the collection which, by default, executes sequentially. - */ - public static LongStream longStreamKeys(scala.collection.immutable.HashMap coll) { - return StreamSupport.longStream(new StepsLongImmHashMapKey(coll, 0, coll.size()), false); - } - - /** - * Generates a LongStream that traverses long-valued values of a scala.collection.immutable.HashMap. - *

- * Both sequential and parallel operations will be efficient. - * - * @param coll The immutable.HashMap to traverse - * @return A LongStream view of the collection which, by default, executes sequentially. - */ - public static LongStream longStreamValues(scala.collection.immutable.HashMap coll) { - return StreamSupport.longStream(new StepsLongImmHashMapValue(coll, 0, coll.size()), false); - } - /** * Generates a LongStream that traverses a scala.collection.immutable.HashSet of Longs. *

diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepConverters.scala b/src/main/scala/scala/compat/java8/converterImpl/StepConverters.scala index 7f7a903..12fc4da 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepConverters.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepConverters.scala @@ -31,8 +31,6 @@ trait Priority1StepConverters extends Priority2StepConverters { new RichHashSetCanStep[A](underlying) implicit def richIteratorCanStep[A](underlying: Iterator[A]): RichIteratorCanStep[A] = new RichIteratorCanStep(underlying) - implicit def richImmHashMapCanStep[K, V](underlying: collection.immutable.HashMap[K, V]): RichImmHashMapCanStep[K, V] = - new RichImmHashMapCanStep[K, V](underlying) implicit def richImmHashSetCanStep[A](underlying: collection.immutable.HashSet[A]): RichImmHashSetCanStep[A] = new RichImmHashSetCanStep[A](underlying) implicit def richNumericRangeCanStep[T](underlying: collection.immutable.NumericRange[T]): RichNumericRangeCanStep[T] = diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsImmHashMap.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsImmHashMap.scala deleted file mode 100644 index 4875a4a..0000000 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsImmHashMap.scala +++ /dev/null @@ -1,144 +0,0 @@ -package scala.compat.java8.converterImpl - -import scala.annotation.switch - -import scala.compat.java8.collectionImpl._ - -import Stepper._ - -// Note that there are separate implementations for keys, values, and key-value pairs - -///////////////////////////// -// Stepper implementations // -///////////////////////////// - -private[java8] class StepsAnyImmHashMap[K, V](_underlying: collection.immutable.HashMap[K, V], _i0: Int, _iN: Int) -extends StepsLikeImmHashMap[K, V, (K, V), StepsAnyImmHashMap[K, V]](_underlying, _i0, _iN) { - protected def demiclone(u: collection.immutable.HashMap[K,V], j0: Int, jN: Int) = new StepsAnyImmHashMap[K, V](u, j0, jN) - def next(): (K, V) = - if (hasNext) { - if (theIterator eq null) theIterator = underlying.iterator - i += 1 - theIterator.next - } - else throwNSEE -} - -private[java8] class StepsAnyImmHashMapKey[K, V](_underlying: collection.immutable.HashMap[K, V], _i0: Int, _iN: Int) -extends StepsLikeImmHashMap[K, V, K, StepsAnyImmHashMapKey[K, V]](_underlying, _i0, _iN) { - protected def demiclone(u: collection.immutable.HashMap[K,V], j0: Int, jN: Int) = new StepsAnyImmHashMapKey[K, V](u, j0, jN) - def next(): K = - if (hasNext) { - if (theIterator eq null) theIterator = underlying.keysIterator - i += 1 - theIterator.next - } - else throwNSEE -} - -private[java8] class StepsAnyImmHashMapValue[K, V](_underlying: collection.immutable.HashMap[K, V], _i0: Int, _iN: Int) -extends StepsLikeImmHashMap[K, V, V, StepsAnyImmHashMapValue[K, V]](_underlying, _i0, _iN) { - protected def demiclone(u: collection.immutable.HashMap[K,V], j0: Int, jN: Int) = new StepsAnyImmHashMapValue[K, V](u, j0, jN) - def next(): V = - if (hasNext) { - if (theIterator eq null) theIterator = underlying.valuesIterator - i += 1 - theIterator.next - } - else throwNSEE -} - -private[java8] class StepsDoubleImmHashMapKey[V](_underlying: collection.immutable.HashMap[Double, V], _i0: Int, _iN: Int) -extends StepsDoubleLikeImmHashMap[Double, V, StepsDoubleImmHashMapKey[V]](_underlying, _i0, _iN) { - protected def demiclone(u: collection.immutable.HashMap[Double,V], j0: Int, jN: Int) = new StepsDoubleImmHashMapKey[V](u, j0, jN) - def nextDouble() = - if (hasNext) { - if (theIterator eq null) theIterator = underlying.keysIterator - i += 1 - theIterator.next - } - else throwNSEE -} - -private[java8] class StepsDoubleImmHashMapValue[K](_underlying: collection.immutable.HashMap[K, Double], _i0: Int, _iN: Int) -extends StepsDoubleLikeImmHashMap[K, Double, StepsDoubleImmHashMapValue[K]](_underlying, _i0, _iN) { - protected def demiclone(u: collection.immutable.HashMap[K,Double], j0: Int, jN: Int) = new StepsDoubleImmHashMapValue[K](u, j0, jN) - def nextDouble() = - if (hasNext) { - if (theIterator eq null) theIterator = underlying.valuesIterator - i += 1 - theIterator.next - } - else throwNSEE -} - -private[java8] class StepsIntImmHashMapKey[V](_underlying: collection.immutable.HashMap[Int, V], _i0: Int, _iN: Int) -extends StepsIntLikeImmHashMap[Int, V, StepsIntImmHashMapKey[V]](_underlying, _i0, _iN) { - protected def demiclone(u: collection.immutable.HashMap[Int,V], j0: Int, jN: Int) = new StepsIntImmHashMapKey[V](u, j0, jN) - def nextInt() = - if (hasNext) { - if (theIterator eq null) theIterator = underlying.keysIterator - i += 1 - theIterator.next - } - else throwNSEE -} - -private[java8] class StepsIntImmHashMapValue[K](_underlying: collection.immutable.HashMap[K, Int], _i0: Int, _iN: Int) -extends StepsIntLikeImmHashMap[K, Int, StepsIntImmHashMapValue[K]](_underlying, _i0, _iN) { - protected def demiclone(u: collection.immutable.HashMap[K,Int], j0: Int, jN: Int) = new StepsIntImmHashMapValue[K](u, j0, jN) - def nextInt() = - if (hasNext) { - if (theIterator eq null) theIterator = underlying.valuesIterator - i += 1 - theIterator.next - } - else throwNSEE -} - -private[java8] class StepsLongImmHashMapKey[V](_underlying: collection.immutable.HashMap[Long, V], _i0: Int, _iN: Int) -extends StepsLongLikeImmHashMap[Long, V, StepsLongImmHashMapKey[V]](_underlying, _i0, _iN) { - protected def demiclone(u: collection.immutable.HashMap[Long,V], j0: Int, jN: Int) = new StepsLongImmHashMapKey[V](u, j0, jN) - def nextLong() = - if (hasNext) { - if (theIterator eq null) theIterator = underlying.keysIterator - i += 1 - theIterator.next - } - else throwNSEE -} - -private[java8] class StepsLongImmHashMapValue[K](_underlying: collection.immutable.HashMap[K, Long], _i0: Int, _iN: Int) -extends StepsLongLikeImmHashMap[K, Long, StepsLongImmHashMapValue[K]](_underlying, _i0, _iN) { - protected def demiclone(u: collection.immutable.HashMap[K,Long], j0: Int, jN: Int) = new StepsLongImmHashMapValue[K](u, j0, jN) - def nextLong() = - if (hasNext) { - if (theIterator eq null) theIterator = underlying.valuesIterator - i += 1 - theIterator.next - } - else throwNSEE -} - -////////////////////////// -// Value class adapters // -////////////////////////// - -final class RichImmHashMapCanStep[K, V](private val underlying: collection.immutable.HashMap[K, V]) extends AnyVal with MakesKeyValueStepper[K, V, EfficientSubstep] with MakesStepper[(K, V), EfficientSubstep] { - def stepper[S <: Stepper[_]](implicit ss: StepperShape[(K, V), S]) = - new StepsAnyImmHashMap[K, V](underlying, 0, underlying.size).asInstanceOf[S with EfficientSubstep] - - def keyStepper[S <: Stepper[_]](implicit ss: StepperShape[K, S]) = ((ss.shape: @switch) match { - case StepperShape.IntValue => new StepsIntImmHashMapKey (underlying.asInstanceOf[collection.immutable.HashMap[Int, V]], 0, underlying.size) - case StepperShape.LongValue => new StepsLongImmHashMapKey (underlying.asInstanceOf[collection.immutable.HashMap[Long, V]], 0, underlying.size) - case StepperShape.DoubleValue => new StepsDoubleImmHashMapKey (underlying.asInstanceOf[collection.immutable.HashMap[Double, V]], 0, underlying.size) - case _ => ss.parUnbox(new StepsAnyImmHashMapKey[K, V](underlying, 0, underlying.size)) - }).asInstanceOf[S with EfficientSubstep] - - def valueStepper[S <: Stepper[_]](implicit ss: StepperShape[V, S]) = ((ss.shape: @switch) match { - case StepperShape.IntValue => new StepsIntImmHashMapValue (underlying.asInstanceOf[collection.immutable.HashMap[K, Int]], 0, underlying.size) - case StepperShape.LongValue => new StepsLongImmHashMapValue (underlying.asInstanceOf[collection.immutable.HashMap[K, Long]], 0, underlying.size) - case StepperShape.DoubleValue => new StepsDoubleImmHashMapValue (underlying.asInstanceOf[collection.immutable.HashMap[K, Double]], 0, underlying.size) - case _ => ss.parUnbox(new StepsAnyImmHashMapValue[K, V](underlying, 0, underlying.size)) - }).asInstanceOf[S with EfficientSubstep] -} diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeImmHashMap.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeImmHashMap.scala deleted file mode 100644 index de4cdf1..0000000 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeImmHashMap.scala +++ /dev/null @@ -1,53 +0,0 @@ -package scala.compat.java8.converterImpl - -import scala.compat.java8.collectionImpl._ -import Stepper._ - -/** Abstracts all the generic operations of stepping over an immutable HashMap by slicing it into pieces. - * `next` must update `i` but not `i0` so that later splitting steps can keep track of whether the - * collection needs some sort of modification before transmission to the subclass. - */ -private[java8] trait AbstractStepsLikeImmHashMap[K, V, A, Sub >: Null, Semi >: Null <: Sub with AbstractStepsLikeImmHashMap[K, V, A, Sub, _]] -extends AbstractStepsLikeSliced[collection.immutable.HashMap[K, V], Sub, Semi] { - protected var theIterator: Iterator[A] = null - protected def demiclone(u: collection.immutable.HashMap[K,V], j0: Int, jN: Int): Semi - override def characteristics() = Immutable - def hasNext(): Boolean = i < iN - def semiclone(halfHint: Int): Semi = - if (i >= iN) null - else underlying match { - case trie: collection.immutable.HashMap.HashTrieMap[K, V] => - val parts = if (i > i0) trie.drop(i-i0).split else trie.split - if (parts.length != 2) null - else { - val ans = demiclone(parts.head, 0, parts.head.size) - i = iN - parts.last.size - underlying = parts.last - ans.theIterator = theIterator - theIterator = null - i0 = i - ans - } - case _ => null - } -} - -private[java8] abstract class StepsLikeImmHashMap[K, V, A, SIHM >: Null <: StepsLikeImmHashMap[K, V, A, _]](_underlying: collection.immutable.HashMap[K, V], _i0: Int, _iN: Int) - extends StepsLikeSliced[A, collection.immutable.HashMap[K, V], SIHM](_underlying, _i0, _iN) - with AbstractStepsLikeImmHashMap[K, V, A, AnyStepper[A], SIHM] -{} - -private[java8] abstract class StepsDoubleLikeImmHashMap[K, V, SIHM >: Null <: StepsDoubleLikeImmHashMap[K, V, SIHM]](_underlying: collection.immutable.HashMap[K, V], _i0: Int, _iN: Int) - extends StepsDoubleLikeSliced[collection.immutable.HashMap[K, V], SIHM](_underlying, _i0, _iN) - with AbstractStepsLikeImmHashMap[K, V, Double, DoubleStepper, SIHM] -{} - -private[java8] abstract class StepsIntLikeImmHashMap[K, V, SIHM >: Null <: StepsIntLikeImmHashMap[K, V, SIHM]](_underlying: collection.immutable.HashMap[K, V], _i0: Int, _iN: Int) - extends StepsIntLikeSliced[collection.immutable.HashMap[K, V], SIHM](_underlying, _i0, _iN) - with AbstractStepsLikeImmHashMap[K, V, Int, IntStepper, SIHM] -{} - -private[java8] abstract class StepsLongLikeImmHashMap[K, V, SIHM >: Null <: StepsLongLikeImmHashMap[K, V, SIHM]](_underlying: collection.immutable.HashMap[K, V], _i0: Int, _iN: Int) - extends StepsLongLikeSliced[collection.immutable.HashMap[K, V], SIHM](_underlying, _i0, _iN) - with AbstractStepsLikeImmHashMap[K, V, Long, LongStepper, SIHM] -{} diff --git a/src/test/scala/scala/compat/java8/StepConvertersTest.scala b/src/test/scala/scala/compat/java8/StepConvertersTest.scala index 1544d91..0567898 100644 --- a/src/test/scala/scala/compat/java8/StepConvertersTest.scala +++ b/src/test/scala/scala/compat/java8/StepConvertersTest.scala @@ -104,9 +104,6 @@ class StepConvertersTest { Okay( (ci.HashMap[String, String]("fish" -> "salmon"): ci.AbstractMap[String, String]).stepper ) Okay( (ci.HashMap[String, String]("fish" -> "salmon"): ci.AbstractMap[String, String]).keyStepper ) Okay( (ci.HashMap[String, String]("fish" -> "salmon"): ci.AbstractMap[String, String]).valueStepper ) - good( ci.HashMap[String, String]("fish" -> "salmon").stepper ) - good( ci.HashMap[String, String]("fish" -> "salmon").keyStepper ) - good( ci.HashMap[String, String]("fish" -> "salmon").valueStepper ) good( ci.HashSet[String]("salmon").stepper ) good( ci.IndexedSeq[String]("salmon").stepper ) Okay( ci.IntMap[String](123456 -> "salmon").stepper ) @@ -232,8 +229,6 @@ class StepConvertersTest { Okay( ci.::(3.14159, Nil).stepper ) Okay( (ci.HashMap[Double, Double](2.718281828 -> 3.14159): ci.AbstractMap[Double, Double]).keyStepper ) Okay( (ci.HashMap[Double, Double](2.718281828 -> 3.14159): ci.AbstractMap[Double, Double]).valueStepper ) - good( ci.HashMap[Double, Double](2.718281828 -> 3.14159).keyStepper ) - good( ci.HashMap[Double, Double](2.718281828 -> 3.14159).valueStepper ) good( ci.HashSet[Double](3.14159).stepper ) good( ci.IndexedSeq[Double](3.14159).stepper ) Okay( ci.IntMap[Double](123456 -> 3.14159).valueStepper ) @@ -350,8 +345,6 @@ class StepConvertersTest { Okay( ci.::(654321, Nil).stepper ) Okay( (ci.HashMap[Int, Int](0xDEEDED -> 654321): ci.AbstractMap[Int, Int]).keyStepper ) Okay( (ci.HashMap[Int, Int](0xDEEDED -> 654321): ci.AbstractMap[Int, Int]).valueStepper ) - good( ci.HashMap[Int, Int](0xDEEDED -> 654321).keyStepper ) - good( ci.HashMap[Int, Int](0xDEEDED -> 654321).valueStepper ) good( ci.HashSet[Int](654321).stepper ) good( ci.IndexedSeq[Int](654321).stepper ) Okay( ci.IntMap[Int](123456 -> 654321).keyStepper ) @@ -483,8 +476,6 @@ class StepConvertersTest { Okay( ci.::(0x123456789L, Nil).stepper ) Okay( (ci.HashMap[Long, Long](1234567654321L -> 0x123456789L): ci.AbstractMap[Long, Long]).keyStepper ) Okay( (ci.HashMap[Long, Long](1234567654321L -> 0x123456789L): ci.AbstractMap[Long, Long]).valueStepper ) - good( ci.HashMap[Long, Long](1234567654321L -> 0x123456789L).keyStepper ) - good( ci.HashMap[Long, Long](1234567654321L -> 0x123456789L).valueStepper ) good( ci.HashSet[Long](0x123456789L).stepper ) good( ci.IndexedSeq[Long](0x123456789L).stepper ) Okay( ci.IntMap[Long](123456 -> 0x123456789L).valueStepper ) From af235607c95d161ead61179c9d9a113ec4c972c6 Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Tue, 18 Sep 2018 19:35:43 -0700 Subject: [PATCH 08/23] add Scala 2.13.0-M5 (and drop M4) --- .travis.yml | 2 +- build.sbt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 05ddddf..b27206e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,7 @@ jdk: - oraclejdk8 scala: - - 2.13.0-M4 + - 2.13.0-M5 env: global: diff --git a/build.sbt b/build.sbt index d4fad94..05b4b32 100644 --- a/build.sbt +++ b/build.sbt @@ -1,6 +1,6 @@ import ScalaModulePlugin._ -crossScalaVersions in ThisBuild := List("2.13.0-M4") +crossScalaVersions in ThisBuild := List("2.13.0-M5") val disableDocs = sys.props("nodocs") == "true" From 994154f5de0487547c81411a62b8f71ae81a9a3b Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Thu, 20 Sep 2018 17:29:45 -0700 Subject: [PATCH 09/23] work around scala/bug#11152 in a 2.13 friendly way I forgot .linesIterator was removed entirely in 2.13 and won't return until 2.13.0-RC1 --- fnGen/WrapFnGen.scala | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/fnGen/WrapFnGen.scala b/fnGen/WrapFnGen.scala index f3d959a..63487d8 100644 --- a/fnGen/WrapFnGen.scala +++ b/fnGen/WrapFnGen.scala @@ -58,12 +58,14 @@ object WrapFnGen { } implicit class SplitMyLinesAndStuff(s: String) { - def toVec = s.linesIterator.toVector + // work around scala/bug#11125 + def toVec = Predef.augmentString(s).lines.toVector def nonBlank = s.trim.length > 0 } implicit class TreeToText(t: Tree) { - def text = showCode(t).replace("$", "").linesIterator.toVector + // work around scala/bug#11125 + def text = Predef.augmentString(showCode(t).replace("$", "")).lines.toVector } case class Prioritized(lines: Vector[String], priority: Int) { @@ -288,7 +290,8 @@ object WrapFnGen { def sameText(f: java.io.File, text: String): Boolean = { val x = scala.io.Source.fromFile(f) val lines = try { x.getLines.toVector } finally { x.close } - lines.iterator.filter(_.nonBlank) == text.linesIterator.filter(_.nonBlank) + // work around scala/bug#11125 + lines.iterator.filter(_.nonBlank) == Predef.augmentString(text).lines.filter(_.nonBlank) } def write(f: java.io.File, text: String): Unit = { From be17e35935649332b00327afe5db4462f0eee99e Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Wed, 6 Mar 2019 14:36:51 -0800 Subject: [PATCH 10/23] bump sbt version (0.13.17 -> 0.13.18) --- project/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/build.properties b/project/build.properties index 133a8f1..8e682c5 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=0.13.17 +sbt.version=0.13.18 From 91b22f85a00806bad39fdbdb029429b416b4f600 Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Tue, 19 Feb 2019 20:19:57 -0800 Subject: [PATCH 11/23] upgrade to sbt 1 --- admin/build.sh | 2 +- admin/gpg.sbt | 3 +-- build.sbt | 1 - project/build.properties | 2 +- project/plugins.sbt | 2 +- 5 files changed, 4 insertions(+), 6 deletions(-) diff --git a/admin/build.sh b/admin/build.sh index db8692b..929aa55 100755 --- a/admin/build.sh +++ b/admin/build.sh @@ -29,7 +29,7 @@ if [[ "$TRAVIS_TAG" =~ $tagPat ]]; then currentJvmVer=$(java -version 2>&1 | awk -F '"' '/version/ {print $2}' | sed 's/^1\.//' | sed 's/[^0-9].*//') echo "Releasing $tagVer with Scala $TRAVIS_SCALA_VERSION on Java version $currentJvmVer." - publishTask="publish-signed" + publishTask="publishSigned" cat admin/gpg.sbt >> project/plugins.sbt cp admin/publish-settings.sbt . diff --git a/admin/gpg.sbt b/admin/gpg.sbt index d60e366..e6f00f4 100644 --- a/admin/gpg.sbt +++ b/admin/gpg.sbt @@ -1,2 +1 @@ - -addSbtPlugin("com.typesafe.sbt" % "sbt-pgp" % "0.8.3") // only added when publishing: +addSbtPlugin("com.jsuereth" % "sbt-pgp" % "1.1.2-1") // only added when publishing diff --git a/build.sbt b/build.sbt index dadbd55..9b2378a 100644 --- a/build.sbt +++ b/build.sbt @@ -64,7 +64,6 @@ lazy val root = (project in file(".")). val runTarget = (mainClass in Compile in fnGen).value getOrElse "No main class defined for function conversion generator" val classPath = (fullClasspath in Compile in fnGen).value runner.value.run(runTarget, classPath.files, args, streams.value.log) - .foreach(sys.error) (out ** "*.scala").get }.taskValue, diff --git a/project/build.properties b/project/build.properties index 8e682c5..c0bab04 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=0.13.18 +sbt.version=1.2.8 diff --git a/project/plugins.sbt b/project/plugins.sbt index 1e7f7c0..2de9ecd 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -5,4 +5,4 @@ scalacOptions ++= (sys.props("java.specification.version") match { case _ => Seq("-Xfatal-warnings") }) -addSbtPlugin("org.scala-lang.modules" % "sbt-scala-module" % "1.0.14") +addSbtPlugin("org.scala-lang.modules" % "sbt-scala-module" % "2.0.0") From a76ed3feb0bb708aa5667e9a037bd83a7e62280a Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Wed, 6 Mar 2019 14:40:42 -0800 Subject: [PATCH 12/23] add OpenJDK 11 to CI matrix fixes #130 --- .travis.yml | 1 + build.sbt | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index b27206e..0b1403b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,7 @@ sudo: false jdk: - oraclejdk8 + - openjdk11 scala: - 2.13.0-M5 diff --git a/build.sbt b/build.sbt index 9b2378a..88e9299 100644 --- a/build.sbt +++ b/build.sbt @@ -2,7 +2,10 @@ import ScalaModulePlugin._ crossScalaVersions in ThisBuild := List("2.13.0-M5") -val disableDocs = sys.props("nodocs") == "true" +val disableDocs = + sys.props("nodocs") == "true" || + // can't build doc on JDK 11 until sbt/sbt#4350 is fixed + !sys.props("java.version").startsWith("1.") lazy val JavaDoc = config("genjavadoc") extend Compile From d6d99f884751420caaeb4a3a8b6d5754e70ce6f7 Mon Sep 17 00:00:00 2001 From: Lukas Rytz Date: Tue, 27 Nov 2018 18:12:01 +0100 Subject: [PATCH 13/23] Minor cleanups --- .../scala/compat/java8/StreamConverters.scala | 2 +- .../java8/collectionImpl/Accumulator.scala | 7 +++-- .../collectionImpl/AccumulatorLike.scala | 2 +- .../compat/java8/collectionImpl/Stepper.scala | 2 +- .../java8/converterImpl/StepsArray.scala | 18 ++++++------ .../java8/converterImpl/StepsBitSet.scala | 5 ++-- .../converterImpl/StepsFlatHashTable.scala | 8 +++--- .../java8/converterImpl/StepsHashTable.scala | 28 +++++++++---------- .../java8/converterImpl/StepsIndexedSeq.scala | 8 +++--- .../java8/converterImpl/StepsIterator.scala | 8 +++--- .../java8/converterImpl/StepsLikeGapped.scala | 2 +- .../converterImpl/StepsLikeIndexed.scala | 2 +- .../converterImpl/StepsLikeIterator.scala | 2 +- .../java8/converterImpl/StepsLikeSliced.scala | 2 +- .../converterImpl/StepsLikeTrieIterator.scala | 2 +- .../java8/converterImpl/StepsLinearSeq.scala | 8 +++--- .../java8/converterImpl/StepsRange.scala | 8 +++--- .../java8/converterImpl/StepsString.scala | 2 +- .../java8/converterImpl/StepsVector.scala | 8 +++--- .../java8/converterImpl/StepsWithTail.scala | 2 +- 20 files changed, 64 insertions(+), 62 deletions(-) diff --git a/src/main/scala/scala/compat/java8/StreamConverters.scala b/src/main/scala/scala/compat/java8/StreamConverters.scala index 5fd8f33..0975d9e 100644 --- a/src/main/scala/scala/compat/java8/StreamConverters.scala +++ b/src/main/scala/scala/compat/java8/StreamConverters.scala @@ -103,7 +103,7 @@ trait Priority2StreamConverters { trait Priority1StreamConverters extends Priority2StreamConverters { implicit class RichStream[A](stream: Stream[A]) { - def accumulate = stream.collect(Accumulator.supplier[A], Accumulator.adder[A], Accumulator.merger[A]) + def accumulate: Accumulator[A] = stream.collect(Accumulator.supplier[A], Accumulator.adder[A], Accumulator.merger[A]) def toScala[Coll[_]](implicit factory: collection.Factory[A, Coll[A]]): Coll[A] = { if (stream.isParallel) accumulate.to[Coll](factory) diff --git a/src/main/scala/scala/compat/java8/collectionImpl/Accumulator.scala b/src/main/scala/scala/compat/java8/collectionImpl/Accumulator.scala index eb9f61c..b8c6743 100644 --- a/src/main/scala/scala/compat/java8/collectionImpl/Accumulator.scala +++ b/src/main/scala/scala/compat/java8/collectionImpl/Accumulator.scala @@ -19,11 +19,14 @@ import scala.language.higherKinds * Accumulators can contain more than `Int.MaxValue` elements. */ final class Accumulator[A] extends AccumulatorLike[A, Accumulator[A]] { self => + // Elements are added to `current`. Once full, it's added to `history`, and a new `current` is + // created with `nextBlockSize` (which depends on `totalSize`). + // `cumul(i)` is `(0 until i).map(history(_).length)` private[java8] var current: Array[AnyRef] = Accumulator.emptyAnyRefArray private[java8] var history: Array[Array[AnyRef]] = Accumulator.emptyAnyRefArrayArray private[java8] var cumul: Array[Long] = Accumulator.emptyLongArray - - private[java8] def cumulative(i: Int) = cumul(i) + + private[java8] def cumulative(i: Int): Long = cumul(i) private def expand(): Unit = { if (index > 0) { diff --git a/src/main/scala/scala/compat/java8/collectionImpl/AccumulatorLike.scala b/src/main/scala/scala/compat/java8/collectionImpl/AccumulatorLike.scala index 56519d2..f7f3143 100644 --- a/src/main/scala/scala/compat/java8/collectionImpl/AccumulatorLike.scala +++ b/src/main/scala/scala/compat/java8/collectionImpl/AccumulatorLike.scala @@ -31,7 +31,7 @@ trait AccumulatorLike[@specialized(Double, Int, Long) A, AC] { } /** Size of the accumulated collection, as a `Long` */ - final def size = totalSize + final def size: Long = totalSize /** Remove all accumulated elements from this accumulator. */ def clear(): Unit = { diff --git a/src/main/scala/scala/compat/java8/collectionImpl/Stepper.scala b/src/main/scala/scala/compat/java8/collectionImpl/Stepper.scala index 4bf3f98..8760b5c 100644 --- a/src/main/scala/scala/compat/java8/collectionImpl/Stepper.scala +++ b/src/main/scala/scala/compat/java8/collectionImpl/Stepper.scala @@ -44,7 +44,7 @@ import java.util.Spliterator * {{{ * val s = Stepper.of(Vector(1,2,3,4)) * if (s.hasStep) println(s.nextStep) // Prints 1 - * println(s.tryStep(i => println(i*i))) // Prints 4, then true + * println(s.tryStep(i => println(i*i))) // Prints 2, then true * s.substep.foreach(println) // Prints 3 * println(s.count(_ > 3)) // Prints 4 * println(s.hasStep) // Prints `false` diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsArray.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsArray.scala index d77daac..410d0f4 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsArray.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsArray.scala @@ -25,55 +25,55 @@ import Stepper._ private[java8] class StepsObjectArray[A <: Object](underlying: Array[A], _i0: Int, _iN: Int) extends StepsLikeIndexed[A, StepsObjectArray[A]](_i0, _iN) { def next() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE - def semiclone(half: Int) = new StepsObjectArray[A](underlying, i0, half) + protected def semiclone(half: Int) = new StepsObjectArray[A](underlying, i0, half) } private[java8] class StepsBoxedBooleanArray(underlying: Array[Boolean], _i0: Int, _iN: Int) extends StepsLikeIndexed[Boolean, StepsBoxedBooleanArray](_i0, _iN) { def next() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE - def semiclone(half: Int) = new StepsBoxedBooleanArray(underlying, i0, half) + protected def semiclone(half: Int) = new StepsBoxedBooleanArray(underlying, i0, half) } private[java8] class StepsWidenedByteArray(underlying: Array[Byte], _i0: Int, _iN: Int) extends StepsIntLikeIndexed[StepsWidenedByteArray](_i0, _iN) { def nextInt() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE - def semiclone(half: Int) = new StepsWidenedByteArray(underlying, i0, half) + protected def semiclone(half: Int) = new StepsWidenedByteArray(underlying, i0, half) } private[java8] class StepsWidenedCharArray(underlying: Array[Char], _i0: Int, _iN: Int) extends StepsIntLikeIndexed[StepsWidenedCharArray](_i0, _iN) { def nextInt() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE - def semiclone(half: Int) = new StepsWidenedCharArray(underlying, i0, half) + protected def semiclone(half: Int) = new StepsWidenedCharArray(underlying, i0, half) } private[java8] class StepsWidenedShortArray(underlying: Array[Short], _i0: Int, _iN: Int) extends StepsIntLikeIndexed[StepsWidenedShortArray](_i0, _iN) { def nextInt() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE - def semiclone(half: Int) = new StepsWidenedShortArray(underlying, i0, half) + protected def semiclone(half: Int) = new StepsWidenedShortArray(underlying, i0, half) } private[java8] class StepsWidenedFloatArray(underlying: Array[Float], _i0: Int, _iN: Int) extends StepsDoubleLikeIndexed[StepsWidenedFloatArray](_i0, _iN) { def nextDouble() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE - def semiclone(half: Int) = new StepsWidenedFloatArray(underlying, i0, half) + protected def semiclone(half: Int) = new StepsWidenedFloatArray(underlying, i0, half) } private[java8] class StepsDoubleArray(underlying: Array[Double], _i0: Int, _iN: Int) extends StepsDoubleLikeIndexed[StepsDoubleArray](_i0, _iN) { def nextDouble() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE - def semiclone(half: Int) = new StepsDoubleArray(underlying, i0, half) + protected def semiclone(half: Int) = new StepsDoubleArray(underlying, i0, half) } private[java8] class StepsIntArray(underlying: Array[Int], _i0: Int, _iN: Int) extends StepsIntLikeIndexed[StepsIntArray](_i0, _iN) { def nextInt() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE - def semiclone(half: Int) = new StepsIntArray(underlying, i0, half) + protected def semiclone(half: Int) = new StepsIntArray(underlying, i0, half) } private[java8] class StepsLongArray(underlying: Array[Long], _i0: Int, _iN: Int) extends StepsLongLikeIndexed[StepsLongArray](_i0, _iN) { def nextLong() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE - def semiclone(half: Int) = new StepsLongArray(underlying, i0, half) + protected def semiclone(half: Int) = new StepsLongArray(underlying, i0, half) } ////////////////////////// diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsBitSet.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsBitSet.scala index 279035b..d0392f6 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsBitSet.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsBitSet.scala @@ -26,7 +26,7 @@ extends StepsIntLikeSliced[Array[Long], StepsIntBitSet](_underlying, _i0, _iN) { private var mask: Long = (-1L) << (i & 0x3F) private var cache: Long = underlying(i >>> 6) private var found: Boolean = false - def semiclone(half: Int) = { + protected def semiclone(half: Int) = { val ans = new StepsIntBitSet(underlying, i, half) i = half mask = (-1L) << (i & 0x3F) @@ -50,8 +50,7 @@ extends StepsIntLikeSliced[Array[Long], StepsIntBitSet](_underlying, _i0, _iN) { if (i < 0 || i >= iN) { i = iN false - } - else { + } else { found = true true } diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsFlatHashTable.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsFlatHashTable.scala index e254cf0..94174d9 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsFlatHashTable.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsFlatHashTable.scala @@ -26,25 +26,25 @@ import Stepper._ private[java8] class StepsAnyFlatHashTable[A](_underlying: Array[AnyRef], _i0: Int, _iN: Int) extends StepsLikeGapped[A, StepsAnyFlatHashTable[A]](_underlying, _i0, _iN) { def next() = if (currentEntry eq null) throwNSEE else { val ans = currentEntry.asInstanceOf[A]; currentEntry = null; ans } - def semiclone(half: Int) = new StepsAnyFlatHashTable[A](underlying, i0, half) + protected def semiclone(half: Int) = new StepsAnyFlatHashTable[A](underlying, i0, half) } private[java8] class StepsDoubleFlatHashTable(_underlying: Array[AnyRef], _i0: Int, _iN: Int) extends StepsDoubleLikeGapped[StepsDoubleFlatHashTable](_underlying, _i0, _iN) { def nextDouble() = if (currentEntry eq null) throwNSEE else { val ans = currentEntry.asInstanceOf[Double]; currentEntry = null; ans } - def semiclone(half: Int) = new StepsDoubleFlatHashTable(underlying, i0, half) + protected def semiclone(half: Int) = new StepsDoubleFlatHashTable(underlying, i0, half) } private[java8] class StepsIntFlatHashTable(_underlying: Array[AnyRef], _i0: Int, _iN: Int) extends StepsIntLikeGapped[StepsIntFlatHashTable](_underlying, _i0, _iN) { def nextInt() = if (currentEntry eq null) throwNSEE else { val ans = currentEntry.asInstanceOf[Int]; currentEntry = null; ans } - def semiclone(half: Int) = new StepsIntFlatHashTable(underlying, i0, half) + protected def semiclone(half: Int) = new StepsIntFlatHashTable(underlying, i0, half) } private[java8] class StepsLongFlatHashTable(_underlying: Array[AnyRef], _i0: Int, _iN: Int) extends StepsLongLikeGapped[StepsLongFlatHashTable](_underlying, _i0, _iN) { def nextLong() = if (currentEntry eq null) throwNSEE else { val ans = currentEntry.asInstanceOf[Long]; currentEntry = null; ans } - def semiclone(half: Int) = new StepsLongFlatHashTable(underlying, i0, half) + protected def semiclone(half: Int) = new StepsLongFlatHashTable(underlying, i0, half) } ////////////////////////// diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsHashTable.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsHashTable.scala index 7a5ad21..d75b3d8 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsHashTable.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsHashTable.scala @@ -28,25 +28,25 @@ import Stepper._ private[java8] class StepsAnyHashTableKey[K](_underlying: Array[AnyRef], _i0: Int, _iN: Int) extends StepsLikeGapped[K, StepsAnyHashTableKey[K]](_underlying, _i0, _iN) { def next() = if (currentEntry eq null) throwNSEE else { val ans = CollectionInternals.hashEntryKey[K](currentEntry); currentEntry = CollectionInternals.hashEntryNext(currentEntry); ans } - def semiclone(half: Int) = new StepsAnyHashTableKey[K](underlying, i0, half) + protected def semiclone(half: Int) = new StepsAnyHashTableKey[K](underlying, i0, half) } private[java8] class StepsDoubleHashTableKey(_underlying: Array[AnyRef], _i0: Int, _iN: Int) extends StepsDoubleLikeGapped[StepsDoubleHashTableKey](_underlying, _i0, _iN) { def nextDouble() = if (currentEntry eq null) throwNSEE else { val ans = CollectionInternals.hashEntryKey[Double](currentEntry); currentEntry = CollectionInternals.hashEntryNext(currentEntry); ans } - def semiclone(half: Int) = new StepsDoubleHashTableKey(underlying, i0, half) + protected def semiclone(half: Int) = new StepsDoubleHashTableKey(underlying, i0, half) } private[java8] class StepsIntHashTableKey(_underlying: Array[AnyRef], _i0: Int, _iN: Int) extends StepsIntLikeGapped[StepsIntHashTableKey](_underlying, _i0, _iN) { def nextInt() = if (currentEntry eq null) throwNSEE else { val ans = CollectionInternals.hashEntryKey[Int](currentEntry); currentEntry = CollectionInternals.hashEntryNext(currentEntry); ans } - def semiclone(half: Int) = new StepsIntHashTableKey(underlying, i0, half) + protected def semiclone(half: Int) = new StepsIntHashTableKey(underlying, i0, half) } private[java8] class StepsLongHashTableKey(_underlying: Array[AnyRef], _i0: Int, _iN: Int) extends StepsLongLikeGapped[StepsLongHashTableKey](_underlying, _i0, _iN) { def nextLong() = if (currentEntry eq null) throwNSEE else { val ans = CollectionInternals.hashEntryKey[Long](currentEntry); currentEntry = CollectionInternals.hashEntryNext(currentEntry); ans } - def semiclone(half: Int) = new StepsLongHashTableKey(underlying, i0, half) + protected def semiclone(half: Int) = new StepsLongHashTableKey(underlying, i0, half) } // Steppers for entries stored in DefaultEntry HashEntry @@ -57,7 +57,7 @@ extends StepsLikeGapped[(K, V), StepsAnyDefaultHashTable[K, V]](_underlying, _i0 def next() = if (currentEntry eq null) throwNSEE else { val e = currentEntry; currentEntry = CollectionInternals.hashEntryNext(e); (CollectionInternals.hashEntryKey[K](e), CollectionInternals.defaultEntryValue[V](e)) } - def semiclone(half: Int) = + protected def semiclone(half: Int) = new StepsAnyDefaultHashTable[K, V](underlying, i0, half) } @@ -66,7 +66,7 @@ extends StepsLikeGapped[V, StepsAnyDefaultHashTableValue[K, V]](_underlying, _i0 def next() = if (currentEntry eq null) throwNSEE else { val e = currentEntry; currentEntry = CollectionInternals.hashEntryNext(e); CollectionInternals.defaultEntryValue[V](e) } - def semiclone(half: Int) = + protected def semiclone(half: Int) = new StepsAnyDefaultHashTableValue[K, V](underlying, i0, half) } @@ -75,7 +75,7 @@ extends StepsDoubleLikeGapped[StepsDoubleDefaultHashTableValue[K]](_underlying, def nextDouble() = if (currentEntry eq null) throwNSEE else { val e = currentEntry; currentEntry = CollectionInternals.hashEntryNext(e); CollectionInternals.defaultEntryValue[Double](e) } - def semiclone(half: Int) = + protected def semiclone(half: Int) = new StepsDoubleDefaultHashTableValue[K](underlying, i0, half) } @@ -84,7 +84,7 @@ extends StepsIntLikeGapped[StepsIntDefaultHashTableValue[K]](_underlying, _i0, _ def nextInt() = if (currentEntry eq null) throwNSEE else { val e = currentEntry; currentEntry = CollectionInternals.hashEntryNext(e); CollectionInternals.defaultEntryValue[Int](e) } - def semiclone(half: Int) = + protected def semiclone(half: Int) = new StepsIntDefaultHashTableValue[K](underlying, i0, half) } @@ -93,7 +93,7 @@ extends StepsLongLikeGapped[StepsLongDefaultHashTableValue[K]](_underlying, _i0, def nextLong() = if (currentEntry eq null) throwNSEE else { val e = currentEntry; currentEntry = CollectionInternals.hashEntryNext(e); CollectionInternals.defaultEntryValue[Long](e) } - def semiclone(half: Int) = + protected def semiclone(half: Int) = new StepsLongDefaultHashTableValue[K](underlying, i0, half) } @@ -105,7 +105,7 @@ extends StepsLikeGapped[(K, V), StepsAnyLinkedHashTable[K, V]](_underlying, _i0, def next() = if (currentEntry eq null) throwNSEE else { val e = currentEntry; currentEntry = CollectionInternals.hashEntryNext(e); (CollectionInternals.hashEntryKey[K](e), CollectionInternals.linkedEntryValue[V](e)) } - def semiclone(half: Int) = + protected def semiclone(half: Int) = new StepsAnyLinkedHashTable[K, V](underlying, i0, half) } @@ -114,7 +114,7 @@ extends StepsLikeGapped[V, StepsAnyLinkedHashTableValue[K, V]](_underlying, _i0, def next() = if (currentEntry eq null) throwNSEE else { val e = currentEntry; currentEntry = CollectionInternals.hashEntryNext(e); CollectionInternals.linkedEntryValue[V](e) } - def semiclone(half: Int) = + protected def semiclone(half: Int) = new StepsAnyLinkedHashTableValue[K, V](underlying, i0, half) } @@ -123,7 +123,7 @@ extends StepsDoubleLikeGapped[StepsDoubleLinkedHashTableValue[K]](_underlying, _ def nextDouble() = if (currentEntry eq null) throwNSEE else { val e = currentEntry; currentEntry = CollectionInternals.hashEntryNext(e); CollectionInternals.linkedEntryValue[Double](e) } - def semiclone(half: Int) = + protected def semiclone(half: Int) = new StepsDoubleLinkedHashTableValue[K](underlying, i0, half) } @@ -132,7 +132,7 @@ extends StepsIntLikeGapped[StepsIntLinkedHashTableValue[K]](_underlying, _i0, _i def nextInt() = if (currentEntry eq null) throwNSEE else { val e = currentEntry; currentEntry = CollectionInternals.hashEntryNext(e); CollectionInternals.linkedEntryValue[Int](e) } - def semiclone(half: Int) = + protected def semiclone(half: Int) = new StepsIntLinkedHashTableValue[K](underlying, i0, half) } @@ -141,7 +141,7 @@ extends StepsLongLikeGapped[StepsLongLinkedHashTableValue[K]](_underlying, _i0, def nextLong() = if (currentEntry eq null) throwNSEE else { val e = currentEntry; currentEntry = CollectionInternals.hashEntryNext(e); CollectionInternals.linkedEntryValue[Long](e) } - def semiclone(half: Int) = + protected def semiclone(half: Int) = new StepsLongLinkedHashTableValue[K](underlying, i0, half) } diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsIndexedSeq.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsIndexedSeq.scala index 9222c38..3627236 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsIndexedSeq.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsIndexedSeq.scala @@ -23,25 +23,25 @@ import Stepper._ private[java8] class StepsAnyIndexedSeq[A](underlying: collection.IndexedSeqOps[A, Any, _], _i0: Int, _iN: Int) extends StepsLikeIndexed[A, StepsAnyIndexedSeq[A]](_i0, _iN) { def next() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE - def semiclone(half: Int) = new StepsAnyIndexedSeq[A](underlying, i0, half) + protected def semiclone(half: Int) = new StepsAnyIndexedSeq[A](underlying, i0, half) } private[java8] class StepsDoubleIndexedSeq[CC <: collection.IndexedSeqOps[Double, Any, _]](underlying: CC, _i0: Int, _iN: Int) extends StepsDoubleLikeIndexed[StepsDoubleIndexedSeq[CC]](_i0, _iN) { def nextDouble() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE - def semiclone(half: Int) = new StepsDoubleIndexedSeq[CC](underlying, i0, half) + protected def semiclone(half: Int) = new StepsDoubleIndexedSeq[CC](underlying, i0, half) } private[java8] class StepsIntIndexedSeq[CC <: collection.IndexedSeqOps[Int, Any, _]](underlying: CC, _i0: Int, _iN: Int) extends StepsIntLikeIndexed[StepsIntIndexedSeq[CC]](_i0, _iN) { def nextInt() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE - def semiclone(half: Int) = new StepsIntIndexedSeq[CC](underlying, i0, half) + protected def semiclone(half: Int) = new StepsIntIndexedSeq[CC](underlying, i0, half) } private[java8] class StepsLongIndexedSeq[CC <: collection.IndexedSeqOps[Long, Any, _]](underlying: CC, _i0: Int, _iN: Int) extends StepsLongLikeIndexed[StepsLongIndexedSeq[CC]](_i0, _iN) { def nextLong() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE - def semiclone(half: Int) = new StepsLongIndexedSeq[CC](underlying, i0, half) + protected def semiclone(half: Int) = new StepsLongIndexedSeq[CC](underlying, i0, half) } ////////////////////////// diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsIterator.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsIterator.scala index 62549a1..b5d0700 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsIterator.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsIterator.scala @@ -22,25 +22,25 @@ import scala.compat.java8.collectionImpl._ private[java8] class StepsAnyIterator[A](_underlying: Iterator[A]) extends StepsLikeIterator[A, StepsAnyIterator[A]](_underlying) { - def semiclone() = new StepsAnyIterator(null) + protected def semiclone() = new StepsAnyIterator(null) def next() = if (proxied ne null) proxied.nextStep else underlying.next } private[java8] class StepsDoubleIterator(_underlying: Iterator[Double]) extends StepsDoubleLikeIterator[StepsDoubleIterator](_underlying) { - def semiclone() = new StepsDoubleIterator(null) + protected def semiclone() = new StepsDoubleIterator(null) def nextDouble() = if (proxied ne null) proxied.nextStep else underlying.next } private[java8] class StepsIntIterator(_underlying: Iterator[Int]) extends StepsIntLikeIterator[StepsIntIterator](_underlying) { - def semiclone() = new StepsIntIterator(null) + protected def semiclone() = new StepsIntIterator(null) def nextInt() = if (proxied ne null) proxied.nextStep else underlying.next } private[java8] class StepsLongIterator(_underlying: Iterator[Long]) extends StepsLongLikeIterator[StepsLongIterator](_underlying) { - def semiclone() = new StepsLongIterator(null) + protected def semiclone() = new StepsLongIterator(null) def nextLong() = if (proxied ne null) proxied.nextStep else underlying.next } diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeGapped.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeGapped.scala index 27c3bff..6d0fa5b 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeGapped.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeGapped.scala @@ -25,7 +25,7 @@ private[java8] abstract class AbstractStepsLikeGapped[Sub >: Null, Semi <: Sub]( extends EfficientSubstep { protected var currentEntry: AnyRef = null - def semiclone(half: Int): Semi + protected def semiclone(half: Int): Semi def characteristics(): Int = Ordered def estimateSize(): Long = if (!hasNext) 0 else iN - i0 def hasNext(): Boolean = currentEntry != null || (i0 < iN && { diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeIndexed.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeIndexed.scala index 325b064..9a0aae8 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeIndexed.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeIndexed.scala @@ -19,7 +19,7 @@ import Stepper._ private[java8] abstract class AbstractStepsLikeIndexed[Sub >: Null, Semi <: Sub](protected var i0: Int, protected var iN: Int) extends EfficientSubstep { - def semiclone(half: Int): Semi + protected def semiclone(half: Int): Semi def characteristics(): Int = Ordered + Sized + SubSized def estimateSize(): Long = iN - i0 def hasNext(): Boolean = i0 < iN diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeIterator.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeIterator.scala index 518cee3..3f1abe0 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeIterator.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeIterator.scala @@ -19,7 +19,7 @@ import Stepper._ private[java8] abstract class AbstractStepsLikeIterator[A, SP >: Null <: Stepper[A], Semi <: SP](final protected var underlying: Iterator[A]) { final protected var nextChunkSize = 16 final protected var proxied: SP = null - def semiclone(): Semi // Must initialize with null iterator! + protected def semiclone(): Semi // Must initialize with null iterator! def characteristics(): Int = if (proxied ne null) Ordered | Sized | SubSized else Ordered def estimateSize(): Long = if (proxied ne null) proxied.knownSize else Long.MaxValue def hasNext(): Boolean = if (proxied ne null) proxied.hasStep else underlying.hasNext diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeSliced.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeSliced.scala index ed3c695..b26d302 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeSliced.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeSliced.scala @@ -23,7 +23,7 @@ private[java8] abstract class AbstractStepsLikeSliced[Coll, Sub >: Null, Semi <: extends EfficientSubstep { protected var i0: Int = i - def semiclone(halfHint: Int): Semi // Must really do all the work for both this and cloned collection! + protected def semiclone(halfHint: Int): Semi // Must really do all the work for both this and cloned collection! def characteristics(): Int = Ordered def estimateSize(): Long = iN - i def substep(): Sub = if (estimateSize > 0) semiclone((iN + i) >>> 1) else null diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeTrieIterator.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeTrieIterator.scala index 78abd12..1d33216 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeTrieIterator.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeTrieIterator.scala @@ -23,7 +23,7 @@ extends AbstractStepsLikeSliced[Iterator[A], Sub, Semi] { protected def demiclone(it: Iterator[A], N: Int): Semi override def characteristics() = Immutable def hasNext(): Boolean = underlying.hasNext - def semiclone(halfHint: Int): Semi = + protected def semiclone(halfHint: Int): Semi = if (!underlying.hasNext || i > iN-2) null else scala.compat.java8.runtime.CollectionInternals.trieIteratorSplit(underlying) match { case null => null diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsLinearSeq.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsLinearSeq.scala index d78c893..d4c0958 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsLinearSeq.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsLinearSeq.scala @@ -27,7 +27,7 @@ extends StepsWithTail[A, collection.LinearSeq[A], StepsAnyLinearSeq[A]](_underly protected def myIsEmpty(cc: collection.LinearSeq[A]): Boolean = cc.isEmpty protected def myTailOf(cc: collection.LinearSeq[A]) = cc.tail def next() = if (hasNext()) { maxN -= 1; val ans = underlying.head; underlying = underlying.tail; ans } else throwNSEE - def semiclone(half: Int) = new StepsAnyLinearSeq[A](underlying, half) + protected def semiclone(half: Int) = new StepsAnyLinearSeq[A](underlying, half) } private[java8] class StepsDoubleLinearSeq(_underlying: collection.LinearSeq[Double], _maxN: Long) @@ -35,7 +35,7 @@ extends StepsDoubleWithTail[collection.LinearSeq[Double], StepsDoubleLinearSeq]( protected def myIsEmpty(cc: collection.LinearSeq[Double]): Boolean = cc.isEmpty protected def myTailOf(cc: collection.LinearSeq[Double]) = cc.tail def nextDouble() = if (hasNext()) { maxN -= 1; val ans = underlying.head; underlying = underlying.tail; ans } else throwNSEE - def semiclone(half: Int) = new StepsDoubleLinearSeq(underlying, half) + protected def semiclone(half: Int) = new StepsDoubleLinearSeq(underlying, half) } private[java8] class StepsIntLinearSeq(_underlying: collection.LinearSeq[Int], _maxN: Long) @@ -43,7 +43,7 @@ extends StepsIntWithTail[collection.LinearSeq[Int], StepsIntLinearSeq](_underlyi protected def myIsEmpty(cc: collection.LinearSeq[Int]): Boolean = cc.isEmpty protected def myTailOf(cc: collection.LinearSeq[Int]) = cc.tail def nextInt() = if (hasNext()) { maxN -= 1; val ans = underlying.head; underlying = underlying.tail; ans } else throwNSEE - def semiclone(half: Int) = new StepsIntLinearSeq(underlying, half) + protected def semiclone(half: Int) = new StepsIntLinearSeq(underlying, half) } private[java8] class StepsLongLinearSeq(_underlying: collection.LinearSeq[Long], _maxN: Long) @@ -51,7 +51,7 @@ extends StepsLongWithTail[collection.LinearSeq[Long], StepsLongLinearSeq](_under protected def myIsEmpty(cc: collection.LinearSeq[Long]): Boolean = cc.isEmpty protected def myTailOf(cc: collection.LinearSeq[Long]) = cc.tail def nextLong() = if (hasNext()) { maxN -= 1; val ans = underlying.head; underlying = underlying.tail; ans } else throwNSEE - def semiclone(half: Int) = new StepsLongLinearSeq(underlying, half) + protected def semiclone(half: Int) = new StepsLongLinearSeq(underlying, half) } ////////////////////////// diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsRange.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsRange.scala index a4c92a3..4060011 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsRange.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsRange.scala @@ -25,25 +25,25 @@ import Stepper._ private[java8] class StepsIntRange(underlying: Range, _i0: Int, _iN: Int) extends StepsIntLikeIndexed[StepsIntRange](_i0, _iN) { def nextInt() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE - def semiclone(half: Int) = new StepsIntRange(underlying, i0, half) + protected def semiclone(half: Int) = new StepsIntRange(underlying, i0, half) } private[java8] class StepsAnyNumericRange[T](underlying: collection.immutable.NumericRange[T], _i0: Int, _iN: Int) extends StepsLikeIndexed[T, StepsAnyNumericRange[T]](_i0, _iN) { def next() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE - def semiclone(half: Int) = new StepsAnyNumericRange[T](underlying, i0, half) + protected def semiclone(half: Int) = new StepsAnyNumericRange[T](underlying, i0, half) } private[java8] class StepsIntNumericRange(underlying: collection.immutable.NumericRange[Int], _i0: Int, _iN: Int) extends StepsIntLikeIndexed[StepsIntNumericRange](_i0, _iN) { def nextInt() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE - def semiclone(half: Int) = new StepsIntNumericRange(underlying, i0, half) + protected def semiclone(half: Int) = new StepsIntNumericRange(underlying, i0, half) } private[java8] class StepsLongNumericRange(underlying: collection.immutable.NumericRange[Long], _i0: Int, _iN: Int) extends StepsLongLikeIndexed[StepsLongNumericRange](_i0, _iN) { def nextLong() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE - def semiclone(half: Int) = new StepsLongNumericRange(underlying, i0, half) + protected def semiclone(half: Int) = new StepsLongNumericRange(underlying, i0, half) } ////////////////////////// diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsString.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsString.scala index adc78f7..c7a5dff 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsString.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsString.scala @@ -23,7 +23,7 @@ import Stepper._ private[java8] class StepperStringChar(underlying: CharSequence, _i0: Int, _iN: Int) extends StepsIntLikeIndexed[StepperStringChar](_i0, _iN) { def nextInt() = if (hasNext()) { val j = i0; i0 += 1; underlying.charAt(j) } else throwNSEE - def semiclone(half: Int) = new StepperStringChar(underlying, i0, half) + protected def semiclone(half: Int) = new StepperStringChar(underlying, i0, half) } private[java8] class StepperStringCodePoint(underlying: String, var i0: Int, var iN: Int) extends IntStepper with EfficientSubstep { diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsVector.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsVector.scala index 0c9a23e..c4aa7e3 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsVector.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsVector.scala @@ -116,7 +116,7 @@ with StepsVectorLike[A] { i0 += 1 data(index).asInstanceOf[A] } else throwNSEE - def semiclone(half: Int) = { + protected def semiclone(half: Int) = { val ans = new StepsAnyVector(underlying, i0, half) index = 32 index1 = 32 @@ -137,7 +137,7 @@ with StepsVectorLike[Double] { i0 += 1 data(index).asInstanceOf[Double] } else throwNSEE - def semiclone(half: Int) = { + protected def semiclone(half: Int) = { val ans = new StepsDoubleVector(underlying, i0, half) index = 32 index1 = 32 @@ -158,7 +158,7 @@ with StepsVectorLike[Int] { i0 += 1 data(index).asInstanceOf[Int] } else throwNSEE - def semiclone(half: Int) = { + protected def semiclone(half: Int) = { val ans = new StepsIntVector(underlying, i0, half) index = 32 index1 = 32 @@ -179,7 +179,7 @@ with StepsVectorLike[Long] { i0 += 1 data(index).asInstanceOf[Long] } else throwNSEE - def semiclone(half: Int) = { + protected def semiclone(half: Int) = { val ans = new StepsLongVector(underlying, i0, half) index = 32 index1 = 32 diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsWithTail.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsWithTail.scala index 04505a9..c20f997 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsWithTail.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsWithTail.scala @@ -37,7 +37,7 @@ private[java8] abstract class AbstractStepsWithTail[CC >: Null, Sub >: Null, Sem } this } - def semiclone(chunk: Int): Semi + protected def semiclone(chunk: Int): Semi def characteristics(): Int = if (maxN < Int.MaxValue) Ordered | Sized | SubSized else Ordered def estimateSize(): Long = if (maxN < Int.MaxValue) maxN else Long.MaxValue def hasNext(): Boolean = if (maxN < Int.MaxValue) maxN > 0 else if (myIsEmpty(underlying)) { maxN = 0; false } else true From f05a43b571082f712401827b296f207192d69743 Mon Sep 17 00:00:00 2001 From: Lukas Rytz Date: Wed, 28 Nov 2018 08:51:37 +0100 Subject: [PATCH 14/23] Consistently use empty param list for effectful methods --- .../main/scala/bench/CollectionSource.scala | 2 +- fnGen/WrapFnGen.scala | 4 +- .../java8/PrimitiveIteratorConversions.scala | 12 +- .../scala/compat/java8/StreamConverters.scala | 8 +- .../java8/collectionImpl/Accumulator.scala | 6 +- .../collectionImpl/DoubleAccumulator.scala | 4 +- .../java8/collectionImpl/IntAccumulator.scala | 4 +- .../collectionImpl/LongAccumulator.scala | 4 +- .../compat/java8/collectionImpl/Stepper.scala | 110 +++++++++--------- .../converterImpl/AccumulatorConverters.scala | 2 +- .../java8/converterImpl/StepsArray.scala | 18 +-- .../java8/converterImpl/StepsBitSet.scala | 2 +- .../java8/converterImpl/StepsImmHashSet.scala | 8 +- .../java8/converterImpl/StepsIndexedSeq.scala | 8 +- .../java8/converterImpl/StepsIterator.scala | 8 +- .../java8/converterImpl/StepsLikeGapped.scala | 4 +- .../converterImpl/StepsLikeIndexed.scala | 4 +- .../converterImpl/StepsLikeIterator.scala | 28 ++--- .../java8/converterImpl/StepsLikeSliced.scala | 2 +- .../converterImpl/StepsLikeTrieIterator.scala | 4 +- .../java8/converterImpl/StepsLinearSeq.scala | 8 +- .../java8/converterImpl/StepsRange.scala | 8 +- .../java8/converterImpl/StepsString.scala | 6 +- .../java8/converterImpl/StepsVector.scala | 8 +- .../java8/converterImpl/StepsWithTail.scala | 4 +- .../scala/compat/java8/StepperTest.scala | 20 ++-- 26 files changed, 148 insertions(+), 148 deletions(-) diff --git a/benchmark/src/main/scala/bench/CollectionSource.scala b/benchmark/src/main/scala/bench/CollectionSource.scala index 38c1291..5f0bb49 100644 --- a/benchmark/src/main/scala/bench/CollectionSource.scala +++ b/benchmark/src/main/scala/bench/CollectionSource.scala @@ -233,7 +233,7 @@ package object generate { implicit val arrayIntToIterator: (Array[Int] => Iterator[Int]) = (a: Array[Int]) => new Iterator[Int] { private[this] var i = 0 def hasNext = i < a.length - def next = if (hasNext) { var ans = a(i); i += 1; ans } else throw new NoSuchElementException(i.toString) + def next() = if (hasNext) { var ans = a(i); i += 1; ans } else throw new NoSuchElementException(i.toString) } implicit val arrayStringToIterator: (Array[String] => Iterator[String]) = _.iterator } diff --git a/fnGen/WrapFnGen.scala b/fnGen/WrapFnGen.scala index 3d0b560..7045f0b 100644 --- a/fnGen/WrapFnGen.scala +++ b/fnGen/WrapFnGen.scala @@ -247,7 +247,7 @@ object WrapFnGen { numberedA ++= scalaTargs.map(_.toString).collect{ case An(digits) if (digits.length < 10) => digits.toInt } val scalafnTnames = (jfn.pTypes :+ jfn.rType).zipWithIndex.map{ case (pt, i) if (i < jfn.pTypes.length && pt.isFinalType) || (!pt.isFinalType && jfn.pTypes.take(i).exists(_ == pt)) => - val j = Iterator.from(i).dropWhile(numberedA).next + val j = Iterator.from(i).dropWhile(numberedA).next() val genericName = TypeName(s"A$j") numberedA += j evidences += ((genericName, pt.typeSymbol.name.toTypeName)) @@ -312,6 +312,6 @@ object WrapFnGen { def main(args: Array[String]): Unit = { val names = args.iterator.map(x => new java.io.File(x)) - write(names.next, converterContents) + write(names.next(), converterContents) } } diff --git a/src/main/scala/scala/compat/java8/PrimitiveIteratorConversions.scala b/src/main/scala/scala/compat/java8/PrimitiveIteratorConversions.scala index 2d80ba6..d0abb4d 100644 --- a/src/main/scala/scala/compat/java8/PrimitiveIteratorConversions.scala +++ b/src/main/scala/scala/compat/java8/PrimitiveIteratorConversions.scala @@ -53,10 +53,10 @@ object PrimitiveIteratorConverters { def nextDouble() = it.next() override def remove(): Unit = { throw new UnsupportedOperationException("remove on scala.collection.Iterator") } override def forEachRemaining(c: java.util.function.Consumer[_ >: java.lang.Double]): Unit = { - while (it.hasNext) c.accept(it.next) + while (it.hasNext) c.accept(it.next()) } override def forEachRemaining(c: java.util.function.DoubleConsumer): Unit = { - while (it.hasNext) c.accept(it.next) + while (it.hasNext) c.accept(it.next()) } } } @@ -74,10 +74,10 @@ object PrimitiveIteratorConverters { def nextInt() = it.next() override def remove(): Unit = { throw new UnsupportedOperationException("remove on scala.collection.Iterator") } override def forEachRemaining(c: java.util.function.Consumer[_ >: java.lang.Integer]): Unit = { - while (it.hasNext) c.accept(it.next) + while (it.hasNext) c.accept(it.next()) } override def forEachRemaining(c: java.util.function.IntConsumer): Unit = { - while (it.hasNext) c.accept(it.next) + while (it.hasNext) c.accept(it.next()) } } } @@ -95,10 +95,10 @@ object PrimitiveIteratorConverters { def nextLong() = it.next() override def remove(): Unit = { throw new UnsupportedOperationException("remove on scala.collection.Iterator") } override def forEachRemaining(c: java.util.function.Consumer[_ >: java.lang.Long]): Unit = { - while (it.hasNext) c.accept(it.next) + while (it.hasNext) c.accept(it.next()) } override def forEachRemaining(c: java.util.function.LongConsumer): Unit = { - while (it.hasNext) c.accept(it.next) + while (it.hasNext) c.accept(it.next()) } } } diff --git a/src/main/scala/scala/compat/java8/StreamConverters.scala b/src/main/scala/scala/compat/java8/StreamConverters.scala index 0975d9e..e902491 100644 --- a/src/main/scala/scala/compat/java8/StreamConverters.scala +++ b/src/main/scala/scala/compat/java8/StreamConverters.scala @@ -51,7 +51,7 @@ trait StreamShapeLowPriority { final def fromStepper (mk: MakesStepper[T, _], par: Boolean): S = stream(mk.stepper, par) final def fromKeyStepper (mk: MakesKeyValueStepper[T, _, _], par: Boolean): S = stream(mk.keyStepper, par) final def fromValueStepper(mk: MakesKeyValueStepper[_, T, _], par: Boolean): S = stream(mk.valueStepper, par) - @inline private[this] def stream(st: St, par: Boolean): S = mkStream(if(par) st.anticipateParallelism else st, par) + @inline private[this] def stream(st: St, par: Boolean): S = mkStream(if(par) st.anticipateParallelism() else st, par) protected[this] def mkStream(st: St, par: Boolean): S } protected[this] def intStreamShape[T](implicit ss: StepperShape[T, IntStepper]): StreamShape[T, IntStream] = new BaseStreamShape[T, IntStream, IntStepper] { @@ -330,7 +330,7 @@ with converterImpl.Priority1AccumulatorConverters new AccumulatesFromStepper[Double, DoubleAccumulator] { def apply(stepper: Stepper[Double]) = { val a = new DoubleAccumulator - while (stepper.hasStep) a += stepper.nextStep + while (stepper.hasStep) a += stepper.nextStep() a } } @@ -339,7 +339,7 @@ with converterImpl.Priority1AccumulatorConverters new AccumulatesFromStepper[Int, IntAccumulator] { def apply(stepper: Stepper[Int]) = { val a = new IntAccumulator - while (stepper.hasStep) a += stepper.nextStep + while (stepper.hasStep) a += stepper.nextStep() a } } @@ -348,7 +348,7 @@ with converterImpl.Priority1AccumulatorConverters new AccumulatesFromStepper[Long, LongAccumulator] { def apply(stepper: Stepper[Long]) = { val a = new LongAccumulator - while (stepper.hasStep) a += stepper.nextStep + while (stepper.hasStep) a += stepper.nextStep() a } } diff --git a/src/main/scala/scala/compat/java8/collectionImpl/Accumulator.scala b/src/main/scala/scala/compat/java8/collectionImpl/Accumulator.scala index b8c6743..c7642eb 100644 --- a/src/main/scala/scala/compat/java8/collectionImpl/Accumulator.scala +++ b/src/main/scala/scala/compat/java8/collectionImpl/Accumulator.scala @@ -121,7 +121,7 @@ final class Accumulator[A] extends AccumulatorLike[A, Accumulator[A]] { self => history((w >>> 32).toInt)((w & 0xFFFFFFFFL).toInt).asInstanceOf[A] } } - + /** Retrieves the `ix`th element, using an `Int` index. */ final def apply(i: Int): A = apply(i.toLong) @@ -266,13 +266,13 @@ private[java8] class AccumulatorStepper[A](private val acc: Accumulator[A]) exte i = 0 } - def characteristics() = ORDERED | SIZED | SUBSIZED + def characteristics = ORDERED | SIZED | SUBSIZED def estimateSize = N def hasNext = N > 0 - def next: A = + def next(): A = if (N <= 0) throw new NoSuchElementException("Next in empty Stepper") else { if (i >= n) loadMore() diff --git a/src/main/scala/scala/compat/java8/collectionImpl/DoubleAccumulator.scala b/src/main/scala/scala/compat/java8/collectionImpl/DoubleAccumulator.scala index 00487e5..b40b997 100644 --- a/src/main/scala/scala/compat/java8/collectionImpl/DoubleAccumulator.scala +++ b/src/main/scala/scala/compat/java8/collectionImpl/DoubleAccumulator.scala @@ -260,13 +260,13 @@ private[java8] class DoubleAccumulatorStepper(private val acc: DoubleAccumulator i = 0 } - def characteristics() = ORDERED | SIZED | SUBSIZED | NONNULL + def characteristics = ORDERED | SIZED | SUBSIZED | NONNULL def estimateSize = N def hasNext = N > 0 - def nextDouble: Double = + def nextDouble(): Double = if (n <= 0) throw new NoSuchElementException("next on empty Stepper") else { if (i >= n) loadMore() diff --git a/src/main/scala/scala/compat/java8/collectionImpl/IntAccumulator.scala b/src/main/scala/scala/compat/java8/collectionImpl/IntAccumulator.scala index 2ff0ef7..2100bb6 100644 --- a/src/main/scala/scala/compat/java8/collectionImpl/IntAccumulator.scala +++ b/src/main/scala/scala/compat/java8/collectionImpl/IntAccumulator.scala @@ -267,13 +267,13 @@ private[java8] class IntAccumulatorStepper(private val acc: IntAccumulator) exte i = 0 } - def characteristics() = ORDERED | SIZED | SUBSIZED | NONNULL + def characteristics = ORDERED | SIZED | SUBSIZED | NONNULL def estimateSize = N def hasNext = N > 0 - def nextInt: Int = + def nextInt(): Int = if (N <= 0) throw new NoSuchElementException("next on empty Stepper") else { if (i >= n) loadMore() diff --git a/src/main/scala/scala/compat/java8/collectionImpl/LongAccumulator.scala b/src/main/scala/scala/compat/java8/collectionImpl/LongAccumulator.scala index 84c9495..978fba3 100644 --- a/src/main/scala/scala/compat/java8/collectionImpl/LongAccumulator.scala +++ b/src/main/scala/scala/compat/java8/collectionImpl/LongAccumulator.scala @@ -261,13 +261,13 @@ private[java8] class LongAccumulatorStepper(private val acc: LongAccumulator) ex i = 0 } - def characteristics() = ORDERED | SIZED | SUBSIZED | NONNULL + def characteristics = ORDERED | SIZED | SUBSIZED | NONNULL def estimateSize = N def hasNext = N > 0 - def nextLong: Long = + def nextLong(): Long = if (n <= 0) throw new NoSuchElementException("next on empty Stepper") else { if (i >= n) loadMore() diff --git a/src/main/scala/scala/compat/java8/collectionImpl/Stepper.scala b/src/main/scala/scala/compat/java8/collectionImpl/Stepper.scala index 8760b5c..2a35ff5 100644 --- a/src/main/scala/scala/compat/java8/collectionImpl/Stepper.scala +++ b/src/main/scala/scala/compat/java8/collectionImpl/Stepper.scala @@ -43,7 +43,7 @@ import java.util.Spliterator * Example: * {{{ * val s = Stepper.of(Vector(1,2,3,4)) - * if (s.hasStep) println(s.nextStep) // Prints 1 + * if (s.hasStep) println(s.nextStep()) // Prints 1 * println(s.tryStep(i => println(i*i))) // Prints 2, then true * s.substep.foreach(println) // Prints 3 * println(s.count(_ > 3)) // Prints 4 @@ -80,7 +80,7 @@ trait StepperLike[@specialized(Double, Int, Long) A, +CC] { self: CC => * guaranteed to be any safer than modification of any generic mutable collection, and if the underlying collection is ordered by * virtue of sorting, `Stepper` will not keep track of that fact. */ - def characteristics(): Int + def characteristics: Int /** Returns the size of the collection, if known exactly, or `-1` if not. */ def knownSize: Long @@ -105,7 +105,7 @@ trait StepperLike[@specialized(Double, Int, Long) A, +CC] { self: CC => def substep(): CC /** Warns this `Stepper` that it is likely to be used in a parallel context (used for efficiency only) */ - def anticipateParallelism: this.type = this + def anticipateParallelism(): this.type = this //// @@ -117,48 +117,48 @@ trait StepperLike[@specialized(Double, Int, Long) A, +CC] { self: CC => * iterate over the elements. */ def count(): Long = knownSize match { - case x if x < 0 => var n = 0L; while (hasStep) { nextStep; n += 1 }; n + case x if x < 0 => var n = 0L; while (hasStep) { nextStep(); n += 1 }; n case x => x } /** Consumes all remaining elements in this `Stepper` and counts how many satisfy condition `p`. * This is a terminal operation. */ - def count(p: A => Boolean): Long = { var n = 0L; while (hasStep) { if (p(nextStep)) n += 1 }; n } + def count(p: A => Boolean): Long = { var n = 0L; while (hasStep) { if (p(nextStep())) n += 1 }; n } /** Searches for an element that satisfies condition `p`. If none are found, it returns `false`. * This is a terminal operation. */ - def exists(p: A => Boolean): Boolean = { while(hasStep) { if (p(nextStep)) return true }; false } + def exists(p: A => Boolean): Boolean = { while(hasStep) { if (p(nextStep())) return true }; false } /** Searches for an element that satisifes condition `p`, returning it wrapped in `Some` if one is found, or `None` otherwise. * This is a terminal operation. */ - def find(p: A => Boolean): Option[A] = { while (hasStep) { val a = nextStep; if (p(a)) return Some(a) }; None } + def find(p: A => Boolean): Option[A] = { while (hasStep) { val a = nextStep(); if (p(a)) return Some(a) }; None } /** Repeatedly applies `op` to propagate an initial value `zero` through all elements of the collection. * Traversal order is left-to-right. * This is a terminal operation. */ - def fold[@specialized(Double, Int, Long) B](zero: B)(op: (B, A) => B) = { var b = zero; while (hasStep) { b = op(b, nextStep) }; b } + def fold[@specialized(Double, Int, Long) B](zero: B)(op: (B, A) => B) = { var b = zero; while (hasStep) { b = op(b, nextStep()) }; b } /** Repeatedly applies `op` to propagate an initial value `zero` through the collection until a condition `p` is met. * If `p` is never met, the result of the last operation is returned. * This is a terminal operation. */ - def foldTo[@specialized(Double, Int, Long) B](zero: B)(op: (B, A) => B)(p: B => Boolean) = { var b = zero; while (!p(b) && hasStep) { b = op(b, nextStep) }; b } + def foldTo[@specialized(Double, Int, Long) B](zero: B)(op: (B, A) => B)(p: B => Boolean) = { var b = zero; while (!p(b) && hasStep) { b = op(b, nextStep()) }; b } /** Applies `f` to every remaining element in the collection. * This is a terminal operation. */ - def foreach(f: A => Unit): Unit = { while (hasStep) f(nextStep) } + def foreach(f: A => Unit): Unit = { while (hasStep) f(nextStep()) } /** Repeatedly merges elements with `op` until only a single element remains. * Throws an exception if the `Stepper` is empty. * Merging occurs from left to right. * This is a terminal operation. */ - def reduce(op: (A, A) => A): A = { var a = nextStep; while (hasStep) { a = op(a, nextStep) }; a } + def reduce(op: (A, A) => A): A = { var a = nextStep(); while (hasStep) { a = op(a, nextStep()) }; a } //// @@ -175,13 +175,13 @@ trait StepperLike[@specialized(Double, Int, Long) A, +CC] { self: CC => */ def iterator: Iterator[A] = new scala.collection.AbstractIterator[A] { def hasNext = self.hasStep - def next = self.nextStep + def next() = self.nextStep() } /** Returns a Scala collection of the type requested. */ def to[Coll[_]](implicit factory: collection.Factory[A, Coll[A]]): Coll[A] = { val b = factory.newBuilder - while (hasStep) b += nextStep + while (hasStep) b += nextStep() b.result() } } @@ -193,7 +193,7 @@ trait NextStepper[@specialized(Double, Int, Long) A] extends Stepper[A] with Ste def spliterator: Spliterator[A] = new ProxySpliteratorViaNext[A](this) } private[collectionImpl] class ProxySpliteratorViaNext[A](underlying: NextStepper[A]) extends Spliterator[A] { - def characteristics() = underlying.characteristics + def characteristics = underlying.characteristics def estimateSize() = underlying.knownSize def tryAdvance(f: java.util.function.Consumer[_ >: A]): Boolean = if (underlying.hasStep) { f.accept(underlying.nextStep()); true } else false def trySplit() = underlying.substep() match { case null => null; case x => new ProxySpliteratorViaNext[A](x) } @@ -213,7 +213,7 @@ trait TryStepper[@specialized(Double, Int, Long) A] extends Stepper[A] with Step myCacheIsFull } final def hasStep = myCacheIsFull || load() - final def nextStep = { + final def nextStep() = { if (!myCacheIsFull) { load() if (!myCacheIsFull) Stepper.throwNSEE @@ -232,7 +232,7 @@ trait TryStepper[@specialized(Double, Int, Long) A] extends Stepper[A] with Step def spliterator: Spliterator[A] = new ProxySpliteratorViaTry[A](this) } private[collectionImpl] class ProxySpliteratorViaTry[A](underlying: TryStepper[A]) extends Spliterator[A] { - def characteristics() = underlying.characteristics + def characteristics = underlying.characteristics def estimateSize() = underlying.knownSize def tryAdvance(f: java.util.function.Consumer[_ >: A]): Boolean = underlying.tryStep(a => f.accept(a)) override def forEachRemaining(f: java.util.function.Consumer[_ >: A]): Unit = { underlying.foreach(a => f.accept(a)) } @@ -241,13 +241,13 @@ private[collectionImpl] class ProxySpliteratorViaTry[A](underlying: TryStepper[A /** Any `AnyStepper` combines the functionality of a Java `Iterator`, a Java `Spliterator`, and a `Stepper`. */ trait AnyStepper[A] extends Stepper[A] with java.util.Iterator[A] with Spliterator[A] with StepperLike[A, AnyStepper[A]] { - override def forEachRemaining(c: java.util.function.Consumer[_ >: A]): Unit = { while (hasNext) { c.accept(next) } } - def hasStep = hasNext() + override def forEachRemaining(c: java.util.function.Consumer[_ >: A]): Unit = { while (hasNext) { c.accept(next()) } } + def hasStep = hasNext def knownSize = getExactSizeIfKnown - def nextStep = next - def tryAdvance(c: java.util.function.Consumer[_ >: A]): Boolean = if (hasNext) { c.accept(next); true } else false - def tryStep(f: A => Unit): Boolean = if (hasNext) { f(next); true } else false - def trySplit() = substep + def nextStep() = next() + def tryAdvance(c: java.util.function.Consumer[_ >: A]): Boolean = if (hasNext) { c.accept(next()); true } else false + def tryStep(f: A => Unit): Boolean = if (hasNext) { f(next()); true } else false + def trySplit() = substep() override def spliterator: Spliterator[A] = this def seqStream: java.util.stream.Stream[A] = java.util.stream.StreamSupport.stream(this, false) def parStream: java.util.stream.Stream[A] = java.util.stream.StreamSupport.stream(this, true) @@ -255,25 +255,25 @@ trait AnyStepper[A] extends Stepper[A] with java.util.Iterator[A] with Spliterat private[collectionImpl] object AnyStepper { final class BoxedDoubleStepper(st: DoubleStepper) extends AnyStepper[Double] { - def hasNext(): Boolean = st.hasNext() + def hasNext: Boolean = st.hasNext def next(): Double = st.next() - def characteristics(): Int = st.characteristics() + def characteristics: Int = st.characteristics def estimateSize(): Long = st.estimateSize() def substep(): AnyStepper[Double] = new BoxedDoubleStepper(st.substep()) } final class BoxedIntStepper(st: IntStepper) extends AnyStepper[Int] { - def hasNext(): Boolean = st.hasNext() + def hasNext: Boolean = st.hasNext def next(): Int = st.next() - def characteristics(): Int = st.characteristics() + def characteristics: Int = st.characteristics def estimateSize(): Long = st.estimateSize() def substep(): AnyStepper[Int] = new BoxedIntStepper(st.substep()) } final class BoxedLongStepper(st: LongStepper) extends AnyStepper[Long] { - def hasNext(): Boolean = st.hasNext() + def hasNext: Boolean = st.hasNext def next(): Long = st.next() - def characteristics(): Int = st.characteristics() + def characteristics: Int = st.characteristics def estimateSize(): Long = st.estimateSize() def substep(): AnyStepper[Long] = new BoxedLongStepper(st.substep()) } @@ -283,13 +283,13 @@ private[collectionImpl] object AnyStepper { trait DoubleStepper extends Stepper[Double] with java.util.PrimitiveIterator.OfDouble with Spliterator.OfDouble with StepperLike[Double, DoubleStepper] { override def forEachRemaining(c: java.util.function.Consumer[_ >: java.lang.Double]): Unit = { while (hasNext) { c.accept(java.lang.Double.valueOf(nextDouble)) } } override def forEachRemaining(c: java.util.function.DoubleConsumer): Unit = { while (hasNext) { c.accept(nextDouble) } } - def hasStep = hasNext() + def hasStep = hasNext def knownSize = getExactSizeIfKnown - def nextStep = nextDouble + def nextStep() = nextDouble override def tryAdvance(c: java.util.function.Consumer[_ >: java.lang.Double]): Boolean = if (hasNext) { c.accept(java.lang.Double.valueOf(nextDouble)); true } else false def tryAdvance(c: java.util.function.DoubleConsumer): Boolean = if (hasNext) { c.accept(nextDouble); true } else false def tryStep(f: Double => Unit): Boolean = if (hasNext) { f(nextDouble); true } else false - def trySplit() = substep + def trySplit() = substep() override def spliterator: Spliterator[Double] = this.asInstanceOf[Spliterator[Double]] // Scala and Java disagree about whether it's java.lang.Double or double def seqStream: java.util.stream.DoubleStream = java.util.stream.StreamSupport.doubleStream(this, false) def parStream: java.util.stream.DoubleStream = java.util.stream.StreamSupport.doubleStream(this, true) @@ -299,13 +299,13 @@ trait DoubleStepper extends Stepper[Double] with java.util.PrimitiveIterator.OfD trait IntStepper extends Stepper[Int] with java.util.PrimitiveIterator.OfInt with Spliterator.OfInt with StepperLike[Int, IntStepper] { override def forEachRemaining(c: java.util.function.Consumer[_ >: java.lang.Integer]): Unit = { while (hasNext) { c.accept(java.lang.Integer.valueOf(nextInt)) } } override def forEachRemaining(c: java.util.function.IntConsumer): Unit = { while (hasNext) { c.accept(nextInt) } } - def hasStep = hasNext() + def hasStep = hasNext def knownSize = getExactSizeIfKnown - def nextStep = nextInt + def nextStep() = nextInt override def tryAdvance(c: java.util.function.Consumer[_ >: java.lang.Integer]): Boolean = if (hasNext) { c.accept(java.lang.Integer.valueOf(nextInt)); true } else false def tryAdvance(c: java.util.function.IntConsumer): Boolean = if (hasNext) { c.accept(nextInt); true } else false def tryStep(f: Int => Unit): Boolean = if (hasNext) { f(nextInt); true } else false - def trySplit() = substep + def trySplit() = substep() override def spliterator: Spliterator[Int] = this.asInstanceOf[Spliterator[Int]] // Scala and Java disagree about whether it's java.lang.Integer or int def seqStream: java.util.stream.IntStream = java.util.stream.StreamSupport.intStream(this, false) def parStream: java.util.stream.IntStream = java.util.stream.StreamSupport.intStream(this, true) @@ -315,13 +315,13 @@ trait IntStepper extends Stepper[Int] with java.util.PrimitiveIterator.OfInt wit trait LongStepper extends Stepper[Long] with java.util.PrimitiveIterator.OfLong with Spliterator.OfLong with StepperLike[Long, LongStepper] { override def forEachRemaining(c: java.util.function.Consumer[_ >: java.lang.Long]): Unit = { while (hasNext) { c.accept(java.lang.Long.valueOf(nextLong)) } } override def forEachRemaining(c: java.util.function.LongConsumer): Unit = { while (hasNext) { c.accept(nextLong) } } - def hasStep = hasNext() + def hasStep = hasNext def knownSize = getExactSizeIfKnown - def nextStep = nextLong + def nextStep() = nextLong override def tryAdvance(c: java.util.function.Consumer[_ >: java.lang.Long]): Boolean = if (hasNext) { c.accept(java.lang.Long.valueOf(nextLong)); true } else false def tryAdvance(c: java.util.function.LongConsumer): Boolean = if (hasNext) { c.accept(nextLong); true } else false def tryStep(f: Long => Unit): Boolean = if (hasNext) { f(nextLong); true } else false - def trySplit() = substep + def trySplit() = substep() override def spliterator: Spliterator[Long] = this.asInstanceOf[Spliterator[Long]] // Scala and Java disagree about whether it's java.lang.Long or long def seqStream: java.util.stream.LongStream = java.util.stream.StreamSupport.longStream(this, false) def parStream: java.util.stream.LongStream = java.util.stream.StreamSupport.longStream(this, true) @@ -378,7 +378,7 @@ object Stepper { sp.forEachRemaining(c) } def hasNext = cached || loadCache - def next = { + def next() = { if (!hasNext) throwNSEE val ans = cache cache = null.asInstanceOf[A] @@ -429,7 +429,7 @@ object Stepper { sp.forEachRemaining(c) } def hasNext = cached || loadCache - def nextDouble = { + def nextDouble() = { if (!hasNext) throwNSEE val ans = cache cached = false @@ -478,7 +478,7 @@ object Stepper { sp.forEachRemaining(c) } def hasNext = cached || loadCache - def nextInt = { + def nextInt() = { if (!hasNext) throwNSEE val ans = cache cached = false @@ -527,7 +527,7 @@ object Stepper { sp.forEachRemaining(c) } def hasNext = cached || loadCache - def nextLong = { + def nextLong() = { if (!hasNext) throwNSEE val ans = cache cached = false @@ -584,57 +584,57 @@ object Stepper { * (see for example StepsIntArray and StepsWidenedByteArray). */ private[java8] class UnboxingDoubleStepper(st: AnyStepper[Double]) extends DoubleStepper { - def hasNext(): Boolean = st.hasNext() + def hasNext: Boolean = st.hasNext def nextDouble(): Double = st.next() - def characteristics(): Int = st.characteristics() + def characteristics: Int = st.characteristics def estimateSize(): Long = st.estimateSize() def substep(): DoubleStepper = new UnboxingDoubleStepper(st.substep()) } private[java8] class UnboxingIntStepper(st: AnyStepper[Int]) extends IntStepper { - def hasNext(): Boolean = st.hasNext() + def hasNext: Boolean = st.hasNext def nextInt(): Int = st.next() - def characteristics(): Int = st.characteristics() + def characteristics: Int = st.characteristics def estimateSize(): Long = st.estimateSize() def substep(): IntStepper = new UnboxingIntStepper(st.substep()) } private[java8] class UnboxingLongStepper(st: AnyStepper[Long]) extends LongStepper { - def hasNext(): Boolean = st.hasNext() + def hasNext: Boolean = st.hasNext def nextLong(): Long = st.next() - def characteristics(): Int = st.characteristics() + def characteristics: Int = st.characteristics def estimateSize(): Long = st.estimateSize() def substep(): LongStepper = new UnboxingLongStepper(st.substep()) } private[java8] class UnboxingByteStepper(st: AnyStepper[Byte]) extends IntStepper { - def hasNext(): Boolean = st.hasNext() + def hasNext: Boolean = st.hasNext def nextInt(): Int = st.next() - def characteristics(): Int = st.characteristics() | NonNull + def characteristics: Int = st.characteristics | NonNull def estimateSize(): Long = st.estimateSize() def substep(): IntStepper = new UnboxingByteStepper(st.substep()) } private[java8] class UnboxingCharStepper(st: AnyStepper[Char]) extends IntStepper { - def hasNext(): Boolean = st.hasNext() + def hasNext: Boolean = st.hasNext def nextInt(): Int = st.next() - def characteristics(): Int = st.characteristics() | NonNull + def characteristics: Int = st.characteristics | NonNull def estimateSize(): Long = st.estimateSize() def substep(): IntStepper = new UnboxingCharStepper(st.substep()) } private[java8] class UnboxingShortStepper(st: AnyStepper[Short]) extends IntStepper { - def hasNext(): Boolean = st.hasNext() + def hasNext: Boolean = st.hasNext def nextInt(): Int = st.next() - def characteristics(): Int = st.characteristics() | NonNull + def characteristics: Int = st.characteristics | NonNull def estimateSize(): Long = st.estimateSize() def substep(): IntStepper = new UnboxingShortStepper(st.substep()) } private[java8] class UnboxingFloatStepper(st: AnyStepper[Float]) extends DoubleStepper { - def hasNext(): Boolean = st.hasNext() + def hasNext: Boolean = st.hasNext def nextDouble(): Double = st.next() - def characteristics(): Int = st.characteristics() | NonNull + def characteristics: Int = st.characteristics | NonNull def estimateSize(): Long = st.estimateSize() def substep(): DoubleStepper = new UnboxingFloatStepper(st.substep()) } diff --git a/src/main/scala/scala/compat/java8/converterImpl/AccumulatorConverters.scala b/src/main/scala/scala/compat/java8/converterImpl/AccumulatorConverters.scala index beeabf1..8a1c46f 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/AccumulatorConverters.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/AccumulatorConverters.scala @@ -40,7 +40,7 @@ private[java8] object PrivateAccumulatorConverters { val genericAccumulateAnyStepper: AccumulatesFromStepper[Any, Accumulator[Any]] = new AccumulatesFromStepper[Any, Accumulator[Any]] { def apply(stepper: Stepper[Any]) = { val a = new Accumulator[Any] - while (stepper.hasStep) a += stepper.nextStep + while (stepper.hasStep) a += stepper.nextStep() a } } diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsArray.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsArray.scala index 410d0f4..8ebaf34 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsArray.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsArray.scala @@ -24,55 +24,55 @@ import Stepper._ private[java8] class StepsObjectArray[A <: Object](underlying: Array[A], _i0: Int, _iN: Int) extends StepsLikeIndexed[A, StepsObjectArray[A]](_i0, _iN) { - def next() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE + def next() = if (hasNext) { val j = i0; i0 += 1; underlying(j) } else throwNSEE protected def semiclone(half: Int) = new StepsObjectArray[A](underlying, i0, half) } private[java8] class StepsBoxedBooleanArray(underlying: Array[Boolean], _i0: Int, _iN: Int) extends StepsLikeIndexed[Boolean, StepsBoxedBooleanArray](_i0, _iN) { - def next() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE + def next() = if (hasNext) { val j = i0; i0 += 1; underlying(j) } else throwNSEE protected def semiclone(half: Int) = new StepsBoxedBooleanArray(underlying, i0, half) } private[java8] class StepsWidenedByteArray(underlying: Array[Byte], _i0: Int, _iN: Int) extends StepsIntLikeIndexed[StepsWidenedByteArray](_i0, _iN) { - def nextInt() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE + def nextInt() = if (hasNext) { val j = i0; i0 += 1; underlying(j) } else throwNSEE protected def semiclone(half: Int) = new StepsWidenedByteArray(underlying, i0, half) } private[java8] class StepsWidenedCharArray(underlying: Array[Char], _i0: Int, _iN: Int) extends StepsIntLikeIndexed[StepsWidenedCharArray](_i0, _iN) { - def nextInt() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE + def nextInt() = if (hasNext) { val j = i0; i0 += 1; underlying(j) } else throwNSEE protected def semiclone(half: Int) = new StepsWidenedCharArray(underlying, i0, half) } private[java8] class StepsWidenedShortArray(underlying: Array[Short], _i0: Int, _iN: Int) extends StepsIntLikeIndexed[StepsWidenedShortArray](_i0, _iN) { - def nextInt() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE + def nextInt() = if (hasNext) { val j = i0; i0 += 1; underlying(j) } else throwNSEE protected def semiclone(half: Int) = new StepsWidenedShortArray(underlying, i0, half) } private[java8] class StepsWidenedFloatArray(underlying: Array[Float], _i0: Int, _iN: Int) extends StepsDoubleLikeIndexed[StepsWidenedFloatArray](_i0, _iN) { - def nextDouble() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE + def nextDouble() = if (hasNext) { val j = i0; i0 += 1; underlying(j) } else throwNSEE protected def semiclone(half: Int) = new StepsWidenedFloatArray(underlying, i0, half) } private[java8] class StepsDoubleArray(underlying: Array[Double], _i0: Int, _iN: Int) extends StepsDoubleLikeIndexed[StepsDoubleArray](_i0, _iN) { - def nextDouble() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE + def nextDouble() = if (hasNext) { val j = i0; i0 += 1; underlying(j) } else throwNSEE protected def semiclone(half: Int) = new StepsDoubleArray(underlying, i0, half) } private[java8] class StepsIntArray(underlying: Array[Int], _i0: Int, _iN: Int) extends StepsIntLikeIndexed[StepsIntArray](_i0, _iN) { - def nextInt() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE + def nextInt() = if (hasNext) { val j = i0; i0 += 1; underlying(j) } else throwNSEE protected def semiclone(half: Int) = new StepsIntArray(underlying, i0, half) } private[java8] class StepsLongArray(underlying: Array[Long], _i0: Int, _iN: Int) extends StepsLongLikeIndexed[StepsLongArray](_i0, _iN) { - def nextLong() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE + def nextLong() = if (hasNext) { val j = i0; i0 += 1; underlying(j) } else throwNSEE protected def semiclone(half: Int) = new StepsLongArray(underlying, i0, half) } diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsBitSet.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsBitSet.scala index d0392f6..c7c95c3 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsBitSet.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsBitSet.scala @@ -34,7 +34,7 @@ extends StepsIntLikeSliced[Array[Long], StepsIntBitSet](_underlying, _i0, _iN) { found = false ans } - def hasNext(): Boolean = found || ((i < iN) && { + def hasNext: Boolean = found || ((i < iN) && { while ((mask & cache) == 0) { i += java.lang.Long.numberOfLeadingZeros(~mask) if (i < 0 || i >= iN) { i = iN; return false } diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsImmHashSet.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsImmHashSet.scala index 864a3c2..a2a4eeb 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsImmHashSet.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsImmHashSet.scala @@ -23,25 +23,25 @@ import scala.compat.java8.collectionImpl._ private[java8] class StepsAnyImmHashSet[A](_underlying: Iterator[A], _N: Int) extends StepsLikeTrieIterator[A, StepsAnyImmHashSet[A]](_underlying, _N) { protected def demiclone(it: Iterator[A], N: Int) = new StepsAnyImmHashSet(it, N) - def next(): A = { val ans = underlying.next; i += 1; ans } + def next(): A = { val ans = underlying.next(); i += 1; ans } } private[java8] class StepsDoubleImmHashSet(_underlying: Iterator[Double], _N: Int) extends StepsDoubleLikeTrieIterator[StepsDoubleImmHashSet](_underlying, _N) { protected def demiclone(it: Iterator[Double], N: Int) = new StepsDoubleImmHashSet(it, N) - def nextDouble() = { val ans = underlying.next; i += 1; ans } + def nextDouble() = { val ans = underlying.next(); i += 1; ans } } private[java8] class StepsIntImmHashSet(_underlying: Iterator[Int], _N: Int) extends StepsIntLikeTrieIterator[StepsIntImmHashSet](_underlying, _N) { protected def demiclone(it: Iterator[Int], N: Int) = new StepsIntImmHashSet(it, N) - def nextInt() = { val ans = underlying.next; i += 1; ans } + def nextInt() = { val ans = underlying.next(); i += 1; ans } } private[java8] class StepsLongImmHashSet(_underlying: Iterator[Long], _N: Int) extends StepsLongLikeTrieIterator[StepsLongImmHashSet](_underlying, _N) { protected def demiclone(it: Iterator[Long], N: Int) = new StepsLongImmHashSet(it, N) - def nextLong() = { val ans = underlying.next; i += 1; ans } + def nextLong() = { val ans = underlying.next(); i += 1; ans } } ////////////////////////// diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsIndexedSeq.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsIndexedSeq.scala index 3627236..abf9485 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsIndexedSeq.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsIndexedSeq.scala @@ -22,25 +22,25 @@ import Stepper._ private[java8] class StepsAnyIndexedSeq[A](underlying: collection.IndexedSeqOps[A, Any, _], _i0: Int, _iN: Int) extends StepsLikeIndexed[A, StepsAnyIndexedSeq[A]](_i0, _iN) { - def next() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE + def next() = if (hasNext) { val j = i0; i0 += 1; underlying(j) } else throwNSEE protected def semiclone(half: Int) = new StepsAnyIndexedSeq[A](underlying, i0, half) } private[java8] class StepsDoubleIndexedSeq[CC <: collection.IndexedSeqOps[Double, Any, _]](underlying: CC, _i0: Int, _iN: Int) extends StepsDoubleLikeIndexed[StepsDoubleIndexedSeq[CC]](_i0, _iN) { - def nextDouble() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE + def nextDouble() = if (hasNext) { val j = i0; i0 += 1; underlying(j) } else throwNSEE protected def semiclone(half: Int) = new StepsDoubleIndexedSeq[CC](underlying, i0, half) } private[java8] class StepsIntIndexedSeq[CC <: collection.IndexedSeqOps[Int, Any, _]](underlying: CC, _i0: Int, _iN: Int) extends StepsIntLikeIndexed[StepsIntIndexedSeq[CC]](_i0, _iN) { - def nextInt() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE + def nextInt() = if (hasNext) { val j = i0; i0 += 1; underlying(j) } else throwNSEE protected def semiclone(half: Int) = new StepsIntIndexedSeq[CC](underlying, i0, half) } private[java8] class StepsLongIndexedSeq[CC <: collection.IndexedSeqOps[Long, Any, _]](underlying: CC, _i0: Int, _iN: Int) extends StepsLongLikeIndexed[StepsLongIndexedSeq[CC]](_i0, _iN) { - def nextLong() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE + def nextLong() = if (hasNext) { val j = i0; i0 += 1; underlying(j) } else throwNSEE protected def semiclone(half: Int) = new StepsLongIndexedSeq[CC](underlying, i0, half) } diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsIterator.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsIterator.scala index b5d0700..fd2e17b 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsIterator.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsIterator.scala @@ -23,25 +23,25 @@ import scala.compat.java8.collectionImpl._ private[java8] class StepsAnyIterator[A](_underlying: Iterator[A]) extends StepsLikeIterator[A, StepsAnyIterator[A]](_underlying) { protected def semiclone() = new StepsAnyIterator(null) - def next() = if (proxied ne null) proxied.nextStep else underlying.next + def next() = if (proxied ne null) proxied.nextStep() else underlying.next() } private[java8] class StepsDoubleIterator(_underlying: Iterator[Double]) extends StepsDoubleLikeIterator[StepsDoubleIterator](_underlying) { protected def semiclone() = new StepsDoubleIterator(null) - def nextDouble() = if (proxied ne null) proxied.nextStep else underlying.next + def nextDouble() = if (proxied ne null) proxied.nextStep() else underlying.next() } private[java8] class StepsIntIterator(_underlying: Iterator[Int]) extends StepsIntLikeIterator[StepsIntIterator](_underlying) { protected def semiclone() = new StepsIntIterator(null) - def nextInt() = if (proxied ne null) proxied.nextStep else underlying.next + def nextInt() = if (proxied ne null) proxied.nextStep() else underlying.next() } private[java8] class StepsLongIterator(_underlying: Iterator[Long]) extends StepsLongLikeIterator[StepsLongIterator](_underlying) { protected def semiclone() = new StepsLongIterator(null) - def nextLong() = if (proxied ne null) proxied.nextStep else underlying.next + def nextLong() = if (proxied ne null) proxied.nextStep() else underlying.next() } ////////////////////////// diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeGapped.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeGapped.scala index 6d0fa5b..e17ff2a 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeGapped.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeGapped.scala @@ -26,9 +26,9 @@ private[java8] abstract class AbstractStepsLikeGapped[Sub >: Null, Semi <: Sub]( protected var currentEntry: AnyRef = null protected def semiclone(half: Int): Semi - def characteristics(): Int = Ordered + def characteristics: Int = Ordered def estimateSize(): Long = if (!hasNext) 0 else iN - i0 - def hasNext(): Boolean = currentEntry != null || (i0 < iN && { + def hasNext: Boolean = currentEntry != null || (i0 < iN && { do { currentEntry = underlying(i0); i0 += 1 } while (currentEntry == null && i0 < iN) currentEntry != null }) diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeIndexed.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeIndexed.scala index 9a0aae8..dc386e0 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeIndexed.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeIndexed.scala @@ -20,9 +20,9 @@ private[java8] abstract class AbstractStepsLikeIndexed[Sub >: Null, Semi <: Sub] extends EfficientSubstep { protected def semiclone(half: Int): Semi - def characteristics(): Int = Ordered + Sized + SubSized + def characteristics: Int = Ordered + Sized + SubSized def estimateSize(): Long = iN - i0 - def hasNext(): Boolean = i0 < iN + def hasNext: Boolean = i0 < iN def substep(): Sub = { if (iN-1 > i0) { val half = (i0+iN) >>> 1 diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeIterator.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeIterator.scala index 3f1abe0..f5695d2 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeIterator.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeIterator.scala @@ -20,9 +20,9 @@ private[java8] abstract class AbstractStepsLikeIterator[A, SP >: Null <: Stepper final protected var nextChunkSize = 16 final protected var proxied: SP = null protected def semiclone(): Semi // Must initialize with null iterator! - def characteristics(): Int = if (proxied ne null) Ordered | Sized | SubSized else Ordered + def characteristics: Int = if (proxied ne null) Ordered | Sized | SubSized else Ordered def estimateSize(): Long = if (proxied ne null) proxied.knownSize else Long.MaxValue - def hasNext(): Boolean = if (proxied ne null) proxied.hasStep else underlying.hasNext + def hasNext: Boolean = if (proxied ne null) proxied.hasStep else underlying.hasNext } /** Abstracts the operation of stepping over an iterator (that needs to be cached when splitting) */ @@ -30,14 +30,14 @@ private[java8] abstract class StepsLikeIterator[A, SLI >: Null <: StepsLikeItera extends AbstractStepsLikeIterator[A, AnyStepper[A], SLI](_underlying) with AnyStepper[A] { - override def substep(): AnyStepper[A] = if (proxied ne null) proxied.substep else { + override def substep(): AnyStepper[A] = if (proxied ne null) proxied.substep() else { val acc = new Accumulator[A] var i = 0 val n = (nextChunkSize & 0xFFFFFFFC) - while (i < n && underlying.hasNext) { acc += underlying.next; i += 1 } + while (i < n && underlying.hasNext) { acc += underlying.next(); i += 1 } if (i < n || !underlying.hasNext) { proxied = acc.stepper - proxied.substep + proxied.substep() } else { val ans = semiclone() @@ -53,14 +53,14 @@ private[java8] abstract class StepsDoubleLikeIterator[SLI >: Null <: StepsDouble extends AbstractStepsLikeIterator[Double, DoubleStepper, SLI](_underlying) with DoubleStepper { - override def substep(): DoubleStepper = if (proxied ne null) proxied.substep else { + override def substep(): DoubleStepper = if (proxied ne null) proxied.substep() else { val acc = new DoubleAccumulator var i = 0 val n = (nextChunkSize & 0xFFFFFFFC) - while (i < n && underlying.hasNext) { acc += underlying.next; i += 1 } + while (i < n && underlying.hasNext) { acc += underlying.next(); i += 1 } if (i < n || !underlying.hasNext) { proxied = acc.stepper - proxied.substep + proxied.substep() } else { val ans = semiclone() @@ -76,14 +76,14 @@ private[java8] abstract class StepsIntLikeIterator[SLI >: Null <: StepsIntLikeIt extends AbstractStepsLikeIterator[Int, IntStepper, SLI](_underlying) with IntStepper { - override def substep(): IntStepper = if (proxied ne null) proxied.substep else { + override def substep(): IntStepper = if (proxied ne null) proxied.substep() else { val acc = new IntAccumulator var i = 0 val n = (nextChunkSize & 0xFFFFFFFC) - while (i < n && underlying.hasNext) { acc += underlying.next; i += 1 } + while (i < n && underlying.hasNext) { acc += underlying.next(); i += 1 } if (i < n || !underlying.hasNext) { proxied = acc.stepper - proxied.substep + proxied.substep() } else { val ans = semiclone() @@ -99,14 +99,14 @@ private[java8] abstract class StepsLongLikeIterator[SLI >: Null <: StepsLongLike extends AbstractStepsLikeIterator[Long, LongStepper, SLI](_underlying) with LongStepper { - override def substep: LongStepper = if (proxied ne null) proxied.substep else { + override def substep(): LongStepper = if (proxied ne null) proxied.substep() else { val acc = new LongAccumulator var i = 0 val n = (nextChunkSize & 0xFFFFFFFC) - while (i < n && underlying.hasNext) { acc += underlying.next; i += 1 } + while (i < n && underlying.hasNext) { acc += underlying.next(); i += 1 } if (i < n || !underlying.hasNext) { proxied = acc.stepper - proxied.substep + proxied.substep() } else { val ans = semiclone() diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeSliced.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeSliced.scala index b26d302..1044481 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeSliced.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeSliced.scala @@ -24,7 +24,7 @@ private[java8] abstract class AbstractStepsLikeSliced[Coll, Sub >: Null, Semi <: protected var i0: Int = i protected def semiclone(halfHint: Int): Semi // Must really do all the work for both this and cloned collection! - def characteristics(): Int = Ordered + def characteristics: Int = Ordered def estimateSize(): Long = iN - i def substep(): Sub = if (estimateSize > 0) semiclone((iN + i) >>> 1) else null } diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeTrieIterator.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeTrieIterator.scala index 1d33216..1c2334b 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeTrieIterator.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeTrieIterator.scala @@ -21,8 +21,8 @@ import Stepper._ private[java8] trait AbstractStepsLikeTrieIterator[A, Sub >: Null, Semi >: Null <: Sub with AbstractStepsLikeTrieIterator[A, Sub, _]] extends AbstractStepsLikeSliced[Iterator[A], Sub, Semi] { protected def demiclone(it: Iterator[A], N: Int): Semi - override def characteristics() = Immutable - def hasNext(): Boolean = underlying.hasNext + override def characteristics = Immutable + def hasNext: Boolean = underlying.hasNext protected def semiclone(halfHint: Int): Semi = if (!underlying.hasNext || i > iN-2) null else scala.compat.java8.runtime.CollectionInternals.trieIteratorSplit(underlying) match { diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsLinearSeq.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsLinearSeq.scala index d4c0958..52b0d0e 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsLinearSeq.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsLinearSeq.scala @@ -26,7 +26,7 @@ private[java8] class StepsAnyLinearSeq[A](_underlying: collection.LinearSeq[A], extends StepsWithTail[A, collection.LinearSeq[A], StepsAnyLinearSeq[A]](_underlying, _maxN) { protected def myIsEmpty(cc: collection.LinearSeq[A]): Boolean = cc.isEmpty protected def myTailOf(cc: collection.LinearSeq[A]) = cc.tail - def next() = if (hasNext()) { maxN -= 1; val ans = underlying.head; underlying = underlying.tail; ans } else throwNSEE + def next() = if (hasNext) { maxN -= 1; val ans = underlying.head; underlying = underlying.tail; ans } else throwNSEE protected def semiclone(half: Int) = new StepsAnyLinearSeq[A](underlying, half) } @@ -34,7 +34,7 @@ private[java8] class StepsDoubleLinearSeq(_underlying: collection.LinearSeq[Doub extends StepsDoubleWithTail[collection.LinearSeq[Double], StepsDoubleLinearSeq](_underlying, _maxN) { protected def myIsEmpty(cc: collection.LinearSeq[Double]): Boolean = cc.isEmpty protected def myTailOf(cc: collection.LinearSeq[Double]) = cc.tail - def nextDouble() = if (hasNext()) { maxN -= 1; val ans = underlying.head; underlying = underlying.tail; ans } else throwNSEE + def nextDouble() = if (hasNext) { maxN -= 1; val ans = underlying.head; underlying = underlying.tail; ans } else throwNSEE protected def semiclone(half: Int) = new StepsDoubleLinearSeq(underlying, half) } @@ -42,7 +42,7 @@ private[java8] class StepsIntLinearSeq(_underlying: collection.LinearSeq[Int], _ extends StepsIntWithTail[collection.LinearSeq[Int], StepsIntLinearSeq](_underlying, _maxN) { protected def myIsEmpty(cc: collection.LinearSeq[Int]): Boolean = cc.isEmpty protected def myTailOf(cc: collection.LinearSeq[Int]) = cc.tail - def nextInt() = if (hasNext()) { maxN -= 1; val ans = underlying.head; underlying = underlying.tail; ans } else throwNSEE + def nextInt() = if (hasNext) { maxN -= 1; val ans = underlying.head; underlying = underlying.tail; ans } else throwNSEE protected def semiclone(half: Int) = new StepsIntLinearSeq(underlying, half) } @@ -50,7 +50,7 @@ private[java8] class StepsLongLinearSeq(_underlying: collection.LinearSeq[Long], extends StepsLongWithTail[collection.LinearSeq[Long], StepsLongLinearSeq](_underlying, _maxN) { protected def myIsEmpty(cc: collection.LinearSeq[Long]): Boolean = cc.isEmpty protected def myTailOf(cc: collection.LinearSeq[Long]) = cc.tail - def nextLong() = if (hasNext()) { maxN -= 1; val ans = underlying.head; underlying = underlying.tail; ans } else throwNSEE + def nextLong() = if (hasNext) { maxN -= 1; val ans = underlying.head; underlying = underlying.tail; ans } else throwNSEE protected def semiclone(half: Int) = new StepsLongLinearSeq(underlying, half) } diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsRange.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsRange.scala index 4060011..fdeaaf8 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsRange.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsRange.scala @@ -24,25 +24,25 @@ import Stepper._ private[java8] class StepsIntRange(underlying: Range, _i0: Int, _iN: Int) extends StepsIntLikeIndexed[StepsIntRange](_i0, _iN) { - def nextInt() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE + def nextInt() = if (hasNext) { val j = i0; i0 += 1; underlying(j) } else throwNSEE protected def semiclone(half: Int) = new StepsIntRange(underlying, i0, half) } private[java8] class StepsAnyNumericRange[T](underlying: collection.immutable.NumericRange[T], _i0: Int, _iN: Int) extends StepsLikeIndexed[T, StepsAnyNumericRange[T]](_i0, _iN) { - def next() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE + def next() = if (hasNext) { val j = i0; i0 += 1; underlying(j) } else throwNSEE protected def semiclone(half: Int) = new StepsAnyNumericRange[T](underlying, i0, half) } private[java8] class StepsIntNumericRange(underlying: collection.immutable.NumericRange[Int], _i0: Int, _iN: Int) extends StepsIntLikeIndexed[StepsIntNumericRange](_i0, _iN) { - def nextInt() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE + def nextInt() = if (hasNext) { val j = i0; i0 += 1; underlying(j) } else throwNSEE protected def semiclone(half: Int) = new StepsIntNumericRange(underlying, i0, half) } private[java8] class StepsLongNumericRange(underlying: collection.immutable.NumericRange[Long], _i0: Int, _iN: Int) extends StepsLongLikeIndexed[StepsLongNumericRange](_i0, _iN) { - def nextLong() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE + def nextLong() = if (hasNext) { val j = i0; i0 += 1; underlying(j) } else throwNSEE protected def semiclone(half: Int) = new StepsLongNumericRange(underlying, i0, half) } diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsString.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsString.scala index c7a5dff..0f15fc9 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsString.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsString.scala @@ -22,16 +22,16 @@ import Stepper._ private[java8] class StepperStringChar(underlying: CharSequence, _i0: Int, _iN: Int) extends StepsIntLikeIndexed[StepperStringChar](_i0, _iN) { - def nextInt() = if (hasNext()) { val j = i0; i0 += 1; underlying.charAt(j) } else throwNSEE + def nextInt() = if (hasNext) { val j = i0; i0 += 1; underlying.charAt(j) } else throwNSEE protected def semiclone(half: Int) = new StepperStringChar(underlying, i0, half) } private[java8] class StepperStringCodePoint(underlying: String, var i0: Int, var iN: Int) extends IntStepper with EfficientSubstep { - def characteristics() = NonNull + def characteristics = NonNull def estimateSize = iN - i0 def hasNext = i0 < iN def nextInt() = { - if (hasNext()) { + if (hasNext) { val cp = underlying.codePointAt(i0) i0 += java.lang.Character.charCount(cp) cp diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsVector.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsVector.scala index c4aa7e3..5cefaef 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsVector.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsVector.scala @@ -110,7 +110,7 @@ with StepsVectorLike[A] { protected val myVector = if (CollectionInternals.getDirt(underlying)) null else underlying protected val myVectorIterator = if (myVector == null) underlying.iterator else null protected val myVectorLength = underlying.length - def next() = if (hasNext()) { + def next() = if (hasNext) { index += 1 if (index >= 32) advanceData(i0) i0 += 1 @@ -131,7 +131,7 @@ with StepsVectorLike[Double] { protected val myVector = if (CollectionInternals.getDirt(underlying)) null else underlying protected val myVectorIterator = if (myVector == null) underlying.iterator else null protected val myVectorLength = underlying.length - def nextDouble() = if (hasNext()) { + def nextDouble() = if (hasNext) { index += 1 if (index >= 32) advanceData(i0) i0 += 1 @@ -152,7 +152,7 @@ with StepsVectorLike[Int] { protected val myVector = if (CollectionInternals.getDirt(underlying)) null else underlying protected val myVectorIterator = if (myVector == null) underlying.iterator else null protected val myVectorLength = underlying.length - def nextInt() = if (hasNext()) { + def nextInt() = if (hasNext) { index += 1 if (index >= 32) advanceData(i0) i0 += 1 @@ -173,7 +173,7 @@ with StepsVectorLike[Long] { protected val myVector = if (CollectionInternals.getDirt(underlying)) null else underlying protected val myVectorIterator = if (myVector == null) underlying.iterator else null protected val myVectorLength = underlying.length - def nextLong() = if (hasNext()) { + def nextLong() = if (hasNext) { index += 1 if (index >= 32) advanceData(i0) i0 += 1 diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsWithTail.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsWithTail.scala index c20f997..8a66033 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsWithTail.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsWithTail.scala @@ -38,9 +38,9 @@ private[java8] abstract class AbstractStepsWithTail[CC >: Null, Sub >: Null, Sem this } protected def semiclone(chunk: Int): Semi - def characteristics(): Int = if (maxN < Int.MaxValue) Ordered | Sized | SubSized else Ordered + def characteristics: Int = if (maxN < Int.MaxValue) Ordered | Sized | SubSized else Ordered def estimateSize(): Long = if (maxN < Int.MaxValue) maxN else Long.MaxValue - def hasNext(): Boolean = if (maxN < Int.MaxValue) maxN > 0 else if (myIsEmpty(underlying)) { maxN = 0; false } else true + def hasNext: Boolean = if (maxN < Int.MaxValue) maxN > 0 else if (myIsEmpty(underlying)) { maxN = 0; false } else true def substep(): Sub = { prepareParallelOperation() maxN match { diff --git a/src/test/scala/scala/compat/java8/StepperTest.scala b/src/test/scala/scala/compat/java8/StepperTest.scala index 7bbbcd9..704d9c7 100644 --- a/src/test/scala/scala/compat/java8/StepperTest.scala +++ b/src/test/scala/scala/compat/java8/StepperTest.scala @@ -53,7 +53,7 @@ class IncStepperB(private val size0: Long) extends TryStepper[Int] { class IncSpliterator(private val size0: Long) extends Spliterator.OfInt { if (size0 < 0) throw new IllegalArgumentException("Size must be >= 0L") private var i = 0L - def characteristics() = Stepper.Sized | Stepper.SubSized | Stepper.Ordered + def characteristics = Stepper.Sized | Stepper.SubSized | Stepper.Ordered def estimateSize() = math.max(0L, size0 - i) def tryAdvance(f: java.util.function.IntConsumer): Boolean = if (i >= size0) false else { f.accept(i.toInt); i += 1; true } def trySplit(): Spliterator.OfInt = if (i+1 >= size0) null else { @@ -157,12 +157,12 @@ class StepperTest { @Test def stepping(): Unit = { - sources.foreach{ case (i, s) => assert((0 until i).forall{ j => s.hasStep && s.nextStep == j } && !s.hasStep) } + sources.foreach{ case (i, s) => assert((0 until i).forall{ j => s.hasStep && s.nextStep() == j } && !s.hasStep) } sources.foreach{ case (i, s) => val set = collection.mutable.BitSet.empty subs(0)(s)( { x => - while (x.hasStep) { val y = x.nextStep; assert(!(set contains y)); set += y } + while (x.hasStep) { val y = x.nextStep(); assert(!(set contains y)); set += y } 0 }, _ + _ @@ -194,16 +194,16 @@ class StepperTest { @Test def substepping(): Unit = { sources.foreach{ case (i,s) => - val ss = s.substep + val ss = s.substep() assertEquals(ss == null, i < 2) if (ss != null) { assertTrue(s.hasStep) assertTrue(ss.hasStep) - val c1 = s.count - val c2 = ss.count + val c1 = s.count() + val c2 = ss.count() assertEquals(s"$i != $c1 + $c2 from ${s.getClass.getName}", i, c1 + c2) } - else assertEquals(i, s.count) + else assertEquals(i, s.count()) } } @@ -222,8 +222,8 @@ class StepperTest { @Test def count_only(): Unit = { - sources.foreach{ case (i, s) => assertEquals(i, s.count) } - sources.foreach{ case (i, s) => assertEquals(i, subs(0)(s)(_.count.toInt, _ + _)) } + sources.foreach{ case (i, s) => assertEquals(i, s.count()) } + sources.foreach{ case (i, s) => assertEquals(i, subs(0)(s)(_.count().toInt, _ + _)) } } @Test @@ -267,7 +267,7 @@ class StepperTest { sources.foreach{ case (i,s) => assertEquals(expected(i), s.foldTo(0)(_ + _)(_ >= 6*i)) } sources.foreach{ case (_,s) => assertEquals(-1, s.foldTo(-1)(_ * _)(_ => true)) } sources.foreach{ case (i,s) => - val ss = s.substep + val ss = s.substep() val x = s.foldTo( if (ss == null) 0 else ss.foldTo(0)(_ + _)(_ >= 6*i) )(_ + _)(_ >= 6*i) assertEquals(expected(i), x) } From a80061ce17c53c1a077f7839961769f660903b32 Mon Sep 17 00:00:00 2001 From: Lukas Rytz Date: Tue, 9 Apr 2019 12:22:00 +0200 Subject: [PATCH 15/23] 2.13.0-RC1 version bump only --- .travis.yml | 2 +- build.sbt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0b1403b..af0c85a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,7 @@ jdk: - openjdk11 scala: - - 2.13.0-M5 + - 2.13.0-RC1 env: global: diff --git a/build.sbt b/build.sbt index 71f6728..d570920 100644 --- a/build.sbt +++ b/build.sbt @@ -1,6 +1,6 @@ import ScalaModulePlugin._ -crossScalaVersions in ThisBuild := List("2.13.0-M5") +crossScalaVersions in ThisBuild := List("2.13.0-RC1") val disableDocs = sys.props("nodocs") == "true" || From 5d9bd5de56c2ae1aab2f1d1629c1f2649be80688 Mon Sep 17 00:00:00 2001 From: Lukas Rytz Date: Tue, 9 Apr 2019 16:38:16 +0200 Subject: [PATCH 16/23] Fix FutureConverters for RC1 --- src/main/scala/scala/compat/java8/FutureConverters.scala | 2 +- .../scala/scala/concurrent/java8/FutureConvertersImpl.scala | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/scala/scala/compat/java8/FutureConverters.scala b/src/main/scala/scala/compat/java8/FutureConverters.scala index 341f400..a0a9c6c 100644 --- a/src/main/scala/scala/compat/java8/FutureConverters.scala +++ b/src/main/scala/scala/compat/java8/FutureConverters.scala @@ -68,7 +68,7 @@ object FutureConverters { case p: P[T] => p.wrapped case _ => val cf = new CF[T](f) - implicit val ec = InternalCallbackExecutor + implicit val ec = ExecutionContext.parasitic f onComplete cf cf } diff --git a/src/main/scala/scala/concurrent/java8/FutureConvertersImpl.scala b/src/main/scala/scala/concurrent/java8/FutureConvertersImpl.scala index d4ab402..9d06fc8 100644 --- a/src/main/scala/scala/concurrent/java8/FutureConvertersImpl.scala +++ b/src/main/scala/scala/concurrent/java8/FutureConvertersImpl.scala @@ -22,8 +22,6 @@ import java.util.function.{ BiConsumer, Function ⇒ JF, Consumer, BiFunction } // TODO: make this private[scala] when genjavadoc allows for that. object FuturesConvertersImpl { - def InternalCallbackExecutor = Future.InternalCallbackExecutor - class CF[T](val wrapped: Future[T]) extends CompletableFuture[T] with (Try[T] => Unit) { override def apply(t: Try[T]): Unit = t match { case Success(v) ⇒ complete(v) From 186e8cc6418cb09baad3fb3408a5a55c3b2da93e Mon Sep 17 00:00:00 2001 From: Lukas Rytz Date: Tue, 9 Apr 2019 16:38:21 +0200 Subject: [PATCH 17/23] Change StreamConverters to use the implementation from 2.13.0-RC1 This drops the Stepper and Accumulator implementations from this repository. It introduces new extension methods that use the implementations from 2.13.0-RC1, but with the names from 2.12 java8-compat. For example, `stream.accumulate` continues works when using java8-compat for 2.13. When using `scala.jdk.StreamConverters`, the user would have to write `stream.toScala(Accumulator)`. The core use cases should continue to work, see the changes to test files --- project/CodeGen.scala | 4 +- .../compat/java8/ScalaStreamSupport.java | 720 ++++-------------- .../java8/runtime/CollectionInternals.java | 52 -- .../compat/java8/SpliteratorConverters.scala | 41 - .../scala/compat/java8/StreamConverters.scala | 573 ++++++++------ .../java8/collectionImpl/Accumulator.scala | 361 --------- .../collectionImpl/AccumulatorLike.scala | 53 -- .../collectionImpl/DoubleAccumulator.scala | 353 --------- .../java8/collectionImpl/IntAccumulator.scala | 360 --------- .../collectionImpl/LongAccumulator.scala | 354 --------- .../compat/java8/collectionImpl/Stepper.scala | 641 ---------------- .../compat/java8/collectionImpl/package.scala | 30 + .../java8/converterImpl/Accumulates.scala | 56 +- .../converterImpl/AccumulatorConverters.scala | 17 +- .../java8/converterImpl/MakesSteppers.scala | 102 --- .../java8/converterImpl/StepConverters.scala | 58 -- .../converterImpl/StepperExtensions.scala | 77 ++ .../java8/converterImpl/StepsArray.scala | 97 --- .../java8/converterImpl/StepsBitSet.scala | 80 -- .../converterImpl/StepsFlatHashTable.scala | 64 -- .../java8/converterImpl/StepsHashTable.scala | 209 ----- .../java8/converterImpl/StepsImmHashSet.scala | 58 -- .../java8/converterImpl/StepsIndexedSeq.scala | 58 -- .../java8/converterImpl/StepsIterable.scala | 29 - .../java8/converterImpl/StepsIterator.scala | 58 -- .../java8/converterImpl/StepsLikeGapped.scala | 79 -- .../converterImpl/StepsLikeIndexed.scala | 62 -- .../converterImpl/StepsLikeIterator.scala | 118 --- .../java8/converterImpl/StepsLikeSliced.scala | 54 -- .../converterImpl/StepsLikeTrieIterator.scala | 59 -- .../java8/converterImpl/StepsLinearSeq.scala | 68 -- .../compat/java8/converterImpl/StepsMap.scala | 38 - .../java8/converterImpl/StepsRange.scala | 64 -- .../java8/converterImpl/StepsString.scala | 61 -- .../java8/converterImpl/StepsVector.scala | 202 ----- .../java8/converterImpl/StepsWithTail.scala | 98 --- .../java/scala/compat/java8/BoxingTest.java | 6 +- .../compat/java8/StepConvertersTest.scala | 16 +- .../scala/compat/java8/StepperTest.scala | 108 +-- .../compat/java8/StreamConvertersTest.scala | 176 ++--- 40 files changed, 721 insertions(+), 4993 deletions(-) delete mode 100644 src/main/java/scala/compat/java8/runtime/CollectionInternals.java delete mode 100644 src/main/scala/scala/compat/java8/SpliteratorConverters.scala delete mode 100644 src/main/scala/scala/compat/java8/collectionImpl/Accumulator.scala delete mode 100644 src/main/scala/scala/compat/java8/collectionImpl/AccumulatorLike.scala delete mode 100644 src/main/scala/scala/compat/java8/collectionImpl/DoubleAccumulator.scala delete mode 100644 src/main/scala/scala/compat/java8/collectionImpl/IntAccumulator.scala delete mode 100644 src/main/scala/scala/compat/java8/collectionImpl/LongAccumulator.scala delete mode 100644 src/main/scala/scala/compat/java8/collectionImpl/Stepper.scala create mode 100644 src/main/scala/scala/compat/java8/collectionImpl/package.scala delete mode 100644 src/main/scala/scala/compat/java8/converterImpl/MakesSteppers.scala delete mode 100644 src/main/scala/scala/compat/java8/converterImpl/StepConverters.scala create mode 100644 src/main/scala/scala/compat/java8/converterImpl/StepperExtensions.scala delete mode 100644 src/main/scala/scala/compat/java8/converterImpl/StepsArray.scala delete mode 100644 src/main/scala/scala/compat/java8/converterImpl/StepsBitSet.scala delete mode 100644 src/main/scala/scala/compat/java8/converterImpl/StepsFlatHashTable.scala delete mode 100644 src/main/scala/scala/compat/java8/converterImpl/StepsHashTable.scala delete mode 100644 src/main/scala/scala/compat/java8/converterImpl/StepsImmHashSet.scala delete mode 100644 src/main/scala/scala/compat/java8/converterImpl/StepsIndexedSeq.scala delete mode 100644 src/main/scala/scala/compat/java8/converterImpl/StepsIterable.scala delete mode 100644 src/main/scala/scala/compat/java8/converterImpl/StepsIterator.scala delete mode 100644 src/main/scala/scala/compat/java8/converterImpl/StepsLikeGapped.scala delete mode 100644 src/main/scala/scala/compat/java8/converterImpl/StepsLikeIndexed.scala delete mode 100644 src/main/scala/scala/compat/java8/converterImpl/StepsLikeIterator.scala delete mode 100644 src/main/scala/scala/compat/java8/converterImpl/StepsLikeSliced.scala delete mode 100644 src/main/scala/scala/compat/java8/converterImpl/StepsLikeTrieIterator.scala delete mode 100644 src/main/scala/scala/compat/java8/converterImpl/StepsLinearSeq.scala delete mode 100644 src/main/scala/scala/compat/java8/converterImpl/StepsMap.scala delete mode 100644 src/main/scala/scala/compat/java8/converterImpl/StepsRange.scala delete mode 100644 src/main/scala/scala/compat/java8/converterImpl/StepsString.scala delete mode 100644 src/main/scala/scala/compat/java8/converterImpl/StepsVector.scala delete mode 100644 src/main/scala/scala/compat/java8/converterImpl/StepsWithTail.scala diff --git a/project/CodeGen.scala b/project/CodeGen.scala index 4289973..b3f3f11 100644 --- a/project/CodeGen.scala +++ b/project/CodeGen.scala @@ -519,9 +519,9 @@ object CodeGen { val specialized = List("V", "V,IJFD", "V,IJD,IJD").flatMap(specialize).map { case (i, a, sp) => - s" public static scala.Function$i<$a> procSpecialized(JFunction$i$sp f) { return f; }" } ++ + s" public static scala.Function$i<$a> procSpecialized(JFunction$i$sp f) { return (scala.Function$i<$a>)(Object)f; }" } ++ List("BSIJCFDZ", "ZIFJD,IJFD", "ZIFJD,IJD,IJD").flatMap(specialize).map { case (i, a, sp) => - s" public static scala.Function$i<$a> funcSpecialized(JFunction$i$sp f) { return f; }" } + s" public static scala.Function$i<$a> funcSpecialized(JFunction$i$sp f) { return (scala.Function$i<$a>)(Object)f; }" } (blocks.map(_._1) ++ blocks.map(_._2)) :+ ( "JFunction", diff --git a/src/main/java/scala/compat/java8/ScalaStreamSupport.java b/src/main/java/scala/compat/java8/ScalaStreamSupport.java index 6a8499c..112833e 100644 --- a/src/main/java/scala/compat/java8/ScalaStreamSupport.java +++ b/src/main/java/scala/compat/java8/ScalaStreamSupport.java @@ -12,10 +12,10 @@ package scala.compat.java8; -import scala.compat.java8.converterImpl.*; -import scala.compat.java8.collectionImpl.*; import java.util.stream.*; -import scala.compat.java8.runtime.CollectionInternals; + +import scala.collection.*; +import scala.jdk.StreamConverters; /** * This class contains static utility methods for creating Java Streams from Scala Collections, similar @@ -33,166 +33,62 @@ public class ScalaStreamSupport { ///////////////////// /** - * Generates a Stream that traverses an IndexedSeq. - *

- * Both sequential and parallel operations will be efficient. - * - * @param coll The IndexedSeq to traverse - * @return A Stream view of the collection which, by default, executes sequentially. - */ - public static Stream stream(scala.collection.IndexedSeq coll) { - return StreamSupport.stream(new StepsAnyIndexedSeq((scala.collection.IndexedSeq)coll, 0, coll.length()), false); - } - - /** - * Generates a Stream that traverses a scala.collection.immutable.HashSet. + * Generates a Stream that traverses a Scala collection. *

- * Both sequential and parallel operations will be efficient. + * Parallel processing is only efficient for collections that have a Stepper implementation + * which supports efficient splitting. For collections where this is the case, the stepper + * method has a return type marked with EfficientSplit. * - * @param coll The immutable.HashSet to traverse + * @param coll The IterableOnce to traverse * @return A Stream view of the collection which, by default, executes sequentially. */ - public static Stream stream(scala.collection.immutable.HashSet coll) { - return StreamSupport.stream(new StepsAnyImmHashSet(coll.iterator(), coll.size()), false); - } - - /** - * Generates a Stream that traverses the keys of a scala.collection.mutable.HashMap. - *

- * Both sequential and parallel operations will be efficient. - * - * @param coll The mutable.HashMap to traverse - * @return A Stream view of the collection which, by default, executes sequentially. - */ - public static Stream streamKeys(scala.collection.mutable.HashMap coll) { - Object[] tbl = CollectionInternals.getTable(coll); - return StreamSupport.stream(new StepsAnyHashTableKey(tbl, 0, tbl.length), false); - } - - /** - * Generates a Stream that traverses the values of a scala.collection.mutable.HashMap. - *

- * Both sequential and parallel operations will be efficient. - * - * @param coll The mutable.HashMap to traverse - * @return A Stream view of the collection which, by default, executes sequentially. - */ - public static Stream streamValues(scala.collection.mutable.HashMap coll) { - Object[] tbl = CollectionInternals.getTable(coll); - return StreamSupport.stream(new StepsAnyDefaultHashTableValue(tbl, 0, tbl.length), false); - } - - /** - * Generates a Stream that traverses the key-value pairs of a scala.collection.mutable.HashMap. - * The key-value pairs are presented as instances of scala.Tuple2. - *

- * Both sequential and parallel operations will be efficient. - * - * @param coll The mutable.HashMap to traverse - * @return A Stream view of the collection which, by default, executes sequentially. - */ - public static Stream< scala.Tuple2 > stream(scala.collection.mutable.HashMap coll) { - Object[] tbl = - CollectionInternals.getTable(coll); - return StreamSupport.stream(new StepsAnyDefaultHashTable(tbl, 0, tbl.length), false); - } - - /** - * Generates a Stream that traverses a scala.collection.mutable.HashSet. - *

- * Both sequential and parallel operations will be efficient. - * - * @param coll The mutable.HashSet to traverse - * @return A Stream view of the collection which, by default, executes sequentially. - */ - public static Stream stream(scala.collection.mutable.HashSet coll) { - Object[] tbl = CollectionInternals.getTable(coll); - return StreamSupport.stream(new StepsAnyFlatHashTable(tbl, 0, tbl.length), false); - } - - /** - * Generates a Stream that traverses a scala.collection.immutable.Vector. - *

- * Both sequential and parallel operations will be efficient. - * - * @param coll The Vector to traverse - * @return A Stream view of the collection which, by default, executes sequentially. - */ - public static Stream stream(scala.collection.immutable.Vector coll) { - return StreamSupport.stream(new StepsAnyVector(coll, 0, coll.length()), false); + public static Stream stream(IterableOnce coll) { + return StreamConverters.asJavaSeqStream(coll); } /** * Generates a Stream that traverses the keys of a scala.collection.Map. *

- * Only sequential operations will be efficient. - * For efficient parallel operation, use the streamAccumulatedKeys method instead, but - * note that this creates a new collection containing the Map's keys. + * Parallel processing is only efficient for Maps that have a keyStepper implementation + * which supports efficient splitting. For collections where this is the case, the keyStepper + * method has a return type marked with EfficientSplit. * * @param coll The Map to traverse * @return A Stream view of the collection which, by default, executes sequentially. */ - public static Stream streamKeys(scala.collection.Map coll) { - return StreamSupport.stream(new StepsAnyIterator(coll.keysIterator()), false); + public static Stream streamKeys(Map coll) { + return StreamSupport.stream(coll.keyStepper(StepperShape.anyStepperShape()).spliterator(), false); } /** * Generates a Stream that traverses the values of a scala.collection.Map. *

- * Only sequential operations will be efficient. - * For efficient parallel operation, use the streamAccumulatedValues method instead, but - * note that this creates a new collection containing the Map's values. + * Parallel processing is only efficient for Maps that have a valueStepper implementation + * which supports efficient splitting. For collections where this is the case, the valueStepper + * method has a return type marked with EfficientSplit. * * @param coll The Map to traverse * @return A Stream view of the collection which, by default, executes sequentially. */ - public static Stream streamValues(scala.collection.Map coll) { - return StreamSupport.stream(new StepsAnyIterator(coll.valuesIterator()), false); + public static Stream streamValues(Map coll) { + return StreamSupport.stream(coll.>valueStepper(StepperShape.anyStepperShape()).spliterator(), false); } /** * Generates a Stream that traverses the key-value pairs of a scala.collection.Map. *

- * Only sequential operations will be efficient. - * For efficient parallel operation, use the streamAccumulated method instead, but - * note that this creates a new collection containing the Map's key-value pairs. + * Parallel processing is only efficient for collections that have a Stepper implementation + * which supports efficient splitting. For collections where this is the case, the stepper + * method has a return type marked with EfficientSplit. * * @param coll The Map to traverse * @return A Stream view of the collection which, by default, executes sequentially. */ - public static Stream< scala.Tuple2 > stream(scala.collection.Map coll) { - return StreamSupport.stream(new StepsAnyIterator< scala.Tuple2 >(coll.iterator()), false); + public static Stream< scala.Tuple2 > stream(Map coll) { + return StreamConverters.asJavaSeqStream(coll); } - /** - * Generates a Stream that traverses a scala.collection.Iterator. - *

- * Only sequential operations will be efficient. - * For efficient parallel operation, use the streamAccumulated method instead, - * but note that this creates a copy of the contents of the Iterator. - * - * @param coll The scala.collection.Iterator to traverse - * @return A Stream view of the collection which, by default, executes sequentially. - */ - public static Stream stream(scala.collection.Iterator coll) { - return StreamSupport.stream(new StepsAnyIterator(coll), false); - } - - /** - * Generates a Stream that traverses a scala.collection.Iterable. - *

- * Only sequential operations will be efficient. - * For efficient parallel operation, use the streamAccumulated method instead, - * but note that this creates a copy of the contents of the Iterable - * - * @param coll The scala.collection.Iterable to traverse - * @return A Stream view of the collection which, by default, executes sequentially. - */ - public static Stream stream(scala.collection.Iterable coll) { - return StreamSupport.stream(new StepsAnyIterator(coll.iterator()), false); - } - - /** + /** * Generates a Stream that traverses any Scala collection by accumulating its entries * into a buffer class (Accumulator). *

@@ -201,9 +97,8 @@ public static Stream stream(scala.collection.Iterable coll) { * @param coll The collection to traverse * @return A Stream view of the collection which, by default, executes sequentially. */ - public static Stream streamAccumulated(scala.collection.IterableOnce coll) { - scala.compat.java8.collectionImpl.Accumulator acc = scala.compat.java8.collectionImpl.Accumulator.from(coll); - return StreamSupport.stream(acc.spliterator(), false); + public static Stream streamAccumulated(IterableOnce coll) { + return StreamConverters.asJavaSeqStream(scala.jdk.AnyAccumulator.from(coll)); } /** @@ -215,9 +110,8 @@ public static Stream streamAccumulated(scala.collection.IterableOnce c * @param coll The map containing keys to traverse * @return A Stream view of the collection which, by default, executes sequentially. */ - public static Stream streamAccumulatedKeys(scala.collection.Map coll) { - scala.compat.java8.collectionImpl.Accumulator acc = scala.compat.java8.collectionImpl.Accumulator.from(coll.keysIterator()); - return StreamSupport.stream(acc.spliterator(), false); + public static Stream streamAccumulatedKeys(Map coll) { + return StreamConverters.asJavaSeqStream(scala.jdk.AnyAccumulator.from(coll.keysIterator())); } /** @@ -229,590 +123,262 @@ public static Stream streamAccumulatedKeys(scala.collection.Map col * @param coll The map containing values to traverse * @return A Stream view of the collection which, by default, executes sequentially. */ - public static Stream streamAccumulatedValues(scala.collection.Map coll) { - scala.compat.java8.collectionImpl.Accumulator acc = scala.compat.java8.collectionImpl.Accumulator.from(coll.valuesIterator()); - return StreamSupport.stream(acc.spliterator(), false); + public static Stream streamAccumulatedValues(Map coll) { + return StreamConverters.asJavaSeqStream(scala.jdk.AnyAccumulator.from(coll.valuesIterator())); } //////////////////// // Double Streams // //////////////////// - /** - * Generates a DoubleStream that traverses an IndexedSeq of Doubles. - *

- * Both sequential and parallel operations will be efficient. - * - * @param coll The IndexedSeq to traverse - * @return A DoubleStream view of the collection which, by default, executes sequentially. - */ - public static DoubleStream doubleStream(scala.collection.IndexedSeq coll) { - return StreamSupport.doubleStream(new StepsDoubleIndexedSeq(coll, 0, coll.length()), false); - } - - /** - * Generates a DoubleStream that traverses a scala.collection.immutable.HashSet of Doubles. + /** + * Generates a DoubleStream that traverses a Scala collection. *

- * Both sequential and parallel operations will be efficient. + * Parallel processing is only efficient for collections that have a Stepper implementation + * which supports efficient splitting. For collections where this is the case, the stepper + * method has a return type marked with EfficientSplit. * - * @param coll The immutable.HashSet to traverse + * @param coll The IterableOnce to traverse * @return A DoubleStream view of the collection which, by default, executes sequentially. */ - public static DoubleStream doubleStream(scala.collection.immutable.HashSet coll) { - scala.collection.Iterator iter = (scala.collection.Iterator)coll.iterator(); - return StreamSupport.doubleStream(new StepsDoubleImmHashSet(iter, coll.size()), false); + public static DoubleStream doubleStream(IterableOnce coll) { + return StreamConverters.asJavaSeqDoubleStream((IterableOnce)(Object)coll); } - /** - * Generates a DoubleStream that traverses double-valued keys of a scala.collection.mutable.HashMap. + /** + * Generates a DoubleStream that traverses the keys of a scala.collection.Map. *

- * Both sequential and parallel operations will be efficient. - * - * @param coll The mutable.HashMap to traverse - * @return A DoubleStream view of the collection which, by default, executes sequentially. - */ - public static DoubleStream doubleStreamKeys(scala.collection.mutable.HashMap coll) { - Object[] tbl = CollectionInternals.getTable(coll); - return StreamSupport.doubleStream(new StepsDoubleHashTableKey(tbl, 0, tbl.length), false); - } - - /** - * Generates a DoubleStream that traverses double-valued values of a scala.collection.mutable.HashMap. - *

- * Both sequential and parallel operations will be efficient. - * - * @param coll The mutable.HashMap to traverse - * @return A DoubleStream view of the collection which, by default, executes sequentially. - */ - public static DoubleStream doubleStreamValues(scala.collection.mutable.HashMap coll) { - Object[] tbl = CollectionInternals.getTable(coll); - return StreamSupport.doubleStream(new StepsDoubleDefaultHashTableValue(tbl, 0, tbl.length), false); - } - - /** - * Generates a DoubleStream that traverses a scala.collection.mutable.HashSet of Doubles. - *

- * Both sequential and parallel operations will be efficient. - * - * @param coll The mutable.HashSet to traverse - * @return A DoubleStream view of the collection which, by default, executes sequentially. - */ - public static DoubleStream doubleStream(scala.collection.mutable.HashSet coll) { - Object[] tbl = CollectionInternals.getTable(coll); - return StreamSupport.doubleStream(new StepsDoubleFlatHashTable(tbl, 0, tbl.length), false); - } - - /** - * Generates a DoubleStream that traverses a scala.collection.immutable.Vector of Doubles. - *

- * Both sequential and parallel operations will be efficient. - * - * @param coll The Vector to traverse - * @return A DoubleStream view of the collection which, by default, executes sequentially. - */ - public static DoubleStream doubleStream(scala.collection.immutable.Vector coll) { - scala.collection.immutable.Vector erased = (scala.collection.immutable.Vector)coll; - return StreamSupport.doubleStream(new StepsDoubleVector(erased, 0, coll.length()), false); - } - - /** - * Generates a DoubleStream that traverses the double-valued keys of a scala.collection.Map. - *

- * Only sequential operations will be efficient. - * For efficient parallel operation, use the doubleStreamAccumulatedKeys method instead, but - * note that this creates a new collection containing the Map's keys. + * Parallel processing is only efficient for Maps that have a keyStepper implementation + * which supports efficient splitting. For collections where this is the case, the keyStepper + * method has a return type marked with EfficientSplit. * * @param coll The Map to traverse * @return A DoubleStream view of the collection which, by default, executes sequentially. */ - public static DoubleStream doubleStreamKeys(scala.collection.Map coll) { - scala.collection.Iterator iter = (scala.collection.Iterator)coll.keysIterator(); - return StreamSupport.doubleStream(new StepsDoubleIterator(iter), false); + public static DoubleStream doubleStreamKeys(Map coll) { + return StreamSupport.doubleStream(coll.keyStepper((StepperShape)(Object)StepperShape.doubleStepperShape()).spliterator(), false); } - /** - * Generates a DoubleStream that traverses the double-valued values of a scala.collection.Map. + /** + * Generates a DoubleStream that traverses the values of a scala.collection.Map. *

- * Only sequential operations will be efficient. - * For efficient parallel operation, use the doubleStreamAccumulatedValues method instead, but - * note that this creates a new collection containing the Map's values. + * Parallel processing is only efficient for Maps that have a valueStepper implementation + * which supports efficient splitting. For collections where this is the case, the valueStepper + * method has a return type marked with EfficientSplit. * * @param coll The Map to traverse * @return A DoubleStream view of the collection which, by default, executes sequentially. */ - public static DoubleStream doubleStreamValues(scala.collection.Map coll) { - scala.collection.Iterator iter = (scala.collection.Iterator)coll.valuesIterator(); - return StreamSupport.doubleStream(new StepsDoubleIterator(iter), false); + public static DoubleStream doubleStreamValues(Map coll) { + return StreamSupport.doubleStream(coll.valueStepper((StepperShape)(Object)StepperShape.doubleStepperShape()).spliterator(), false); } - /** - * Generates a DoubleStream that traverses a double-valued scala.collection.Iterator. - *

- * Only sequential operations will be efficient. - * For efficient parallel operation, use the doubleStreamAccumulated method instead, - * but note that this creates a copy of the contents of the Iterator. - * - * @param coll The scala.collection.Iterator to traverse - * @return A DoubleStream view of the collection which, by default, executes sequentially. - */ - public static DoubleStream doubleStream(scala.collection.Iterator coll) { - return StreamSupport.doubleStream(new StepsDoubleIterator((scala.collection.Iterator)coll), false); - } - - /** - * Generates a DoubleStream that traverses a double-valued scala.collection.Iterable. - *

- * Only sequential operations will be efficient. - * For efficient parallel operation, use the doubleStreamAccumulated method instead, - * but note that this creates a copy of the contents of the Iterable. - * - * @param coll The scala.collection.Iterable to traverse - * @return A DoubleStream view of the collection which, by default, executes sequentially. - */ - public static DoubleStream doubleStream(scala.collection.Iterable coll) { - scala.collection.Iterator iter = (scala.collection.Iterator)coll.iterator(); - return StreamSupport.doubleStream(new StepsDoubleIterator(iter), false); - } - - /** - * Generates a Stream that traverses any Scala collection by accumulating its entries + /** + * Generates a DoubleStream that traverses any Scala collection by accumulating its entries * into a buffer class (Accumulator). *

* Both sequential and parallel operations will be efficient. * * @param coll The collection to traverse - * @return A Stream view of the collection which, by default, executes sequentially. + * @return A DoubleStream view of the collection which, by default, executes sequentially. */ - public static DoubleStream doubleStreamAccumulated(scala.collection.IterableOnce coll) { - scala.compat.java8.collectionImpl.DoubleAccumulator acc = - scala.compat.java8.collectionImpl.DoubleAccumulator.from((scala.collection.IterableOnce)coll); - return StreamSupport.doubleStream(acc.spliterator(), false); + public static DoubleStream doubleStreamAccumulated(IterableOnce coll) { + return StreamConverters.asJavaSeqDoubleStream(scala.jdk.DoubleAccumulator$.MODULE$.fromSpecific((IterableOnce)(Object)coll)); } - /** - * Generates a Stream that traverses the keys of any Scala map by + /** + * Generates a DoubleStream that traverses the keys of any Scala map by * accumulating those keys into a buffer class (Accumulator). *

* Both sequential and parallel operations will be efficient. * * @param coll The map containing keys to traverse - * @return A Stream view of the collection which, by default, executes sequentially. + * @return A DoubleStream view of the collection which, by default, executes sequentially. */ - public static DoubleStream doubleStreamAccumulatedKeys(scala.collection.Map coll) { - scala.compat.java8.collectionImpl.DoubleAccumulator acc = - scala.compat.java8.collectionImpl.DoubleAccumulator.from((scala.collection.Iterator)coll.keysIterator()); - return StreamSupport.doubleStream(acc.spliterator(), false); + public static DoubleStream doubleStreamAccumulatedKeys(Map coll) { + return StreamConverters.asJavaSeqDoubleStream(scala.jdk.DoubleAccumulator$.MODULE$.fromSpecific((IterableOnce)(Object)coll.keysIterator())); } - /** - * Generates a Stream that traverses the values of any Scala map by + /** + * Generates a DoubleStream that traverses the values of any Scala map by * accumulating those values into a buffer class (Accumulator). *

* Both sequential and parallel operations will be efficient. * * @param coll The map containing values to traverse - * @return A Stream view of the collection which, by default, executes sequentially. + * @return A DoubleStream view of the collection which, by default, executes sequentially. */ - public static DoubleStream doubleStreamAccumulatedValues(scala.collection.Map coll) { - scala.compat.java8.collectionImpl.DoubleAccumulator acc = - scala.compat.java8.collectionImpl.DoubleAccumulator.from((scala.collection.Iterator)coll.valuesIterator()); - return StreamSupport.doubleStream(acc.spliterator(), false); + public static DoubleStream doubleStreamAccumulatedValues(Map coll) { + return StreamConverters.asJavaSeqDoubleStream(scala.jdk.DoubleAccumulator$.MODULE$.fromSpecific((IterableOnce)(Object)coll.valuesIterator())); } ///////////////// // Int Streams // ///////////////// - /** - * Generates a IntStream that traverses a BitSet. + /** + * Generates a IntStream that traverses a Scala collection. *

- * Both sequential and parallel operations will be efficient. + * Parallel processing is only efficient for collections that have a Stepper implementation + * which supports efficient splitting. For collections where this is the case, the stepper + * method has a return type marked with EfficientSplit. * - * @param coll The BitSet to traverse + * @param coll The IterableOnce to traverse * @return A IntStream view of the collection which, by default, executes sequentially. */ - public static IntStream intStream(scala.collection.BitSet coll) { - // Let the value class figure out the casting! - scala.compat.java8.converterImpl.RichBitSetCanStep rbscs = - new scala.compat.java8.converterImpl.RichBitSetCanStep(coll); - return StreamSupport.intStream(rbscs.stepper(StepperShape$.MODULE$.intStepperShape()), false); + public static IntStream intStream(IterableOnce coll) { + return StreamConverters.asJavaSeqIntStream((IterableOnce)(Object)coll); } - /** - * Generates a IntStream that traverses a Range. + /** + * Generates a IntStream that traverses the keys of a scala.collection.Map. *

- * Both sequential and parallel operations will be efficient. - * - * @param coll The Range to traverse - * @return A IntStream view of the collection which, by default, executes sequentially. - */ - public static IntStream intStream(scala.collection.immutable.Range coll) { - return StreamSupport.intStream(new scala.compat.java8.converterImpl.StepsIntRange(coll, 0, coll.length()), false); - } - - /** - * Generates a IntStream that traverses an IndexedSeq of Ints. - *

- * Both sequential and parallel operations will be efficient. - * - * @param coll The IndexedSeq to traverse - * @return A IntStream view of the collection which, by default, executes sequentially. - */ - public static IntStream intStream(scala.collection.IndexedSeq coll) { - return StreamSupport.intStream(new StepsIntIndexedSeq(coll, 0, coll.length()), false); - } - - /** - * Generates a IntStream that traverses a scala.collection.immutable.HashSet of Ints. - *

- * Both sequential and parallel operations will be efficient. - * - * @param coll The immutable.HashSet to traverse - * @return A IntStream view of the collection which, by default, executes sequentially. - */ - public static IntStream intStream(scala.collection.immutable.HashSet coll) { - scala.collection.Iterator iter = (scala.collection.Iterator)coll.iterator(); - return StreamSupport.intStream(new StepsIntImmHashSet(iter, coll.size()), false); - } - - /** - * Generates a IntStream that traverses int-valued keys of a scala.collection.mutable.HashMap. - *

- * Both sequential and parallel operations will be efficient. - * - * @param coll The mutable.HashMap to traverse - * @return A IntStream view of the collection which, by default, executes sequentially. - */ - public static IntStream intStreamKeys(scala.collection.mutable.HashMap coll) { - Object[] tbl = CollectionInternals.getTable(coll); - return StreamSupport.intStream(new StepsIntHashTableKey(tbl, 0, tbl.length), false); - } - - /** - * Generates a IntStream that traverses int-valued values of a scala.collection.mutable.HashMap. - *

- * Both sequential and parallel operations will be efficient. - * - * @param coll The mutable.HashMap to traverse - * @return A IntStream view of the collection which, by default, executes sequentially. - */ - public static IntStream intStreamValues(scala.collection.mutable.HashMap coll) { - Object[] tbl = CollectionInternals.getTable(coll); - return StreamSupport.intStream(new StepsIntDefaultHashTableValue(tbl, 0, tbl.length), false); - } - - /** - * Generates a IntStream that traverses a scala.collection.mutable.HashSet of Ints. - *

- * Both sequential and parallel operations will be efficient. - * - * @param coll The mutable.HashSet to traverse - * @return A IntStream view of the collection which, by default, executes sequentially. - */ - public static IntStream intStream(scala.collection.mutable.HashSet coll) { - Object[] tbl = CollectionInternals.getTable(coll); - return StreamSupport.intStream(new StepsIntFlatHashTable(tbl, 0, tbl.length), false); - } - - /** - * Generates a IntStream that traverses a scala.collection.immutable.Vector of Ints. - *

- * Both sequential and parallel operations will be efficient. - * - * @param coll The Vector to traverse - * @return A IntStream view of the collection which, by default, executes sequentially. - */ - public static IntStream intStream(scala.collection.immutable.Vector coll) { - scala.collection.immutable.Vector erased = (scala.collection.immutable.Vector)coll; - return StreamSupport.intStream(new StepsIntVector(erased, 0, coll.length()), false); - } - - /** - * Generates a IntStream that traverses the int-valued keys of a scala.collection.Map. - *

- * Only sequential operations will be efficient. - * For efficient parallel operation, use the intStreamAccumulatedKeys method instead, but - * note that this creates a new collection containing the Map's keys. + * Parallel processing is only efficient for Maps that have a keyStepper implementation + * which supports efficient splitting. For collections where this is the case, the keyStepper + * method has a return type marked with EfficientSplit. * * @param coll The Map to traverse * @return A IntStream view of the collection which, by default, executes sequentially. */ - public static IntStream intStreamKeys(scala.collection.Map coll) { - scala.collection.Iterator iter = (scala.collection.Iterator)coll.keysIterator(); - return StreamSupport.intStream(new StepsIntIterator(iter), false); + public static IntStream intStreamKeys(Map coll) { + return StreamSupport.intStream(coll.keyStepper((StepperShape)(Object)StepperShape.intStepperShape()).spliterator(), false); } - /** - * Generates a IntStream that traverses the int-valued values of a scala.collection.Map. + /** + * Generates a IntStream that traverses the values of a scala.collection.Map. *

- * Only sequential operations will be efficient. - * For efficient parallel operation, use the intStreamAccumulatedValues method instead, but - * note that this creates a new collection containing the Map's values. + * Parallel processing is only efficient for Maps that have a valueStepper implementation + * which supports efficient splitting. For collections where this is the case, the valueStepper + * method has a return type marked with EfficientSplit. * * @param coll The Map to traverse * @return A IntStream view of the collection which, by default, executes sequentially. */ - public static IntStream intStreamValues(scala.collection.Map coll) { - scala.collection.Iterator iter = (scala.collection.Iterator)coll.valuesIterator(); - return StreamSupport.intStream(new StepsIntIterator(iter), false); - } - - /** - * Generates a IntStream that traverses a int-valued scala.collection.Iterator. - *

- * Only sequential operations will be efficient. - * For efficient parallel operation, use the intStreamAccumulated method instead, - * but note that this creates a copy of the contents of the Iterator. - * - * @param coll The scala.collection.Iterator to traverse - * @return A IntStream view of the collection which, by default, executes sequentially. - */ - public static IntStream intStream(scala.collection.Iterator coll) { - return StreamSupport.intStream(new StepsIntIterator((scala.collection.Iterator)coll), false); + public static IntStream intStreamValues(Map coll) { + return StreamSupport.intStream(coll.valueStepper((StepperShape)(Object)StepperShape.intStepperShape()).spliterator(), false); } - /** - * Generates a IntStream that traverses a int-valued scala.collection.Iterable. - *

- * Only sequential operations will be efficient. - * For efficient parallel operation, use the intStreamAccumulated method instead, - * but note that this creates a copy of the contents of the Iterable. - * - * @param coll The scala.collection.Iterable to traverse - * @return A IntStream view of the collection which, by default, executes sequentially. - */ - public static IntStream intStream(scala.collection.Iterable coll) { - scala.collection.Iterator iter = (scala.collection.Iterator)coll.iterator(); - return StreamSupport.intStream(new StepsIntIterator(iter), false); - } - - /** - * Generates a Stream that traverses any Scala collection by accumulating its entries + /** + * Generates a IntStream that traverses any Scala collection by accumulating its entries * into a buffer class (Accumulator). *

* Both sequential and parallel operations will be efficient. * * @param coll The collection to traverse - * @return A Stream view of the collection which, by default, executes sequentially. + * @return A IntStream view of the collection which, by default, executes sequentially. */ - public static IntStream intStreamAccumulated(scala.collection.IterableOnce coll) { - scala.compat.java8.collectionImpl.IntAccumulator acc = - scala.compat.java8.collectionImpl.IntAccumulator.from((scala.collection.IterableOnce)coll); - return StreamSupport.intStream(acc.spliterator(), false); + public static IntStream intStreamAccumulated(IterableOnce coll) { + return StreamConverters.asJavaSeqIntStream(scala.jdk.IntAccumulator$.MODULE$.fromSpecific((IterableOnce)(Object)coll)); } - /** - * Generates a Stream that traverses the keys of any Scala map by + /** + * Generates a IntStream that traverses the keys of any Scala map by * accumulating those keys into a buffer class (Accumulator). *

* Both sequential and parallel operations will be efficient. * * @param coll The map containing keys to traverse - * @return A Stream view of the collection which, by default, executes sequentially. + * @return A IntStream view of the collection which, by default, executes sequentially. */ - public static IntStream intStreamAccumulatedKeys(scala.collection.Map coll) { - scala.compat.java8.collectionImpl.IntAccumulator acc = - scala.compat.java8.collectionImpl.IntAccumulator.from((scala.collection.Iterator)coll.keysIterator()); - return StreamSupport.intStream(acc.spliterator(), false); + public static IntStream intStreamAccumulatedKeys(Map coll) { + return StreamConverters.asJavaSeqIntStream(scala.jdk.IntAccumulator$.MODULE$.fromSpecific((IterableOnce)(Object)coll.keysIterator())); } - /** - * Generates a Stream that traverses the values of any Scala map by + /** + * Generates a IntStream that traverses the values of any Scala map by * accumulating those values into a buffer class (Accumulator). *

* Both sequential and parallel operations will be efficient. * * @param coll The map containing values to traverse - * @return A Stream view of the collection which, by default, executes sequentially. + * @return A IntStream view of the collection which, by default, executes sequentially. */ - public static IntStream intStreamAccumulatedValues(scala.collection.Map coll) { - scala.compat.java8.collectionImpl.IntAccumulator acc = - scala.compat.java8.collectionImpl.IntAccumulator.from((scala.collection.Iterator)coll.valuesIterator()); - return StreamSupport.intStream(acc.spliterator(), false); + public static IntStream intStreamAccumulatedValues(Map coll) { + return StreamConverters.asJavaSeqIntStream(scala.jdk.IntAccumulator$.MODULE$.fromSpecific((IterableOnce)(Object)coll.valuesIterator())); } ////////////////// // Long Streams // ////////////////// - /** - * Generates a LongStream that traverses an IndexedSeq of Longs. - *

- * Both sequential and parallel operations will be efficient. - * - * @param coll The IndexedSeq to traverse - * @return A LongStream view of the collection which, by default, executes sequentially. - */ - public static LongStream longStream(scala.collection.IndexedSeq coll) { - return StreamSupport.longStream(new StepsLongIndexedSeq(coll, 0, coll.length()), false); - } - - /** - * Generates a LongStream that traverses a scala.collection.immutable.HashSet of Longs. - *

- * Both sequential and parallel operations will be efficient. - * - * @param coll The immutable.HashSet to traverse - * @return A LongStream view of the collection which, by default, executes sequentially. - */ - public static LongStream longStream(scala.collection.immutable.HashSet coll) { - scala.collection.Iterator iter = (scala.collection.Iterator)coll.iterator(); - return StreamSupport.longStream(new StepsLongImmHashSet(iter, coll.size()), false); - } - - /** - * Generates a LongStream that traverses long-valued keys of a scala.collection.mutable.HashMap. - *

- * Both sequential and parallel operations will be efficient. - * - * @param coll The mutable.HashMap to traverse - * @return A LongStream view of the collection which, by default, executes sequentially. - */ - public static LongStream longStreamKeys(scala.collection.mutable.HashMap coll) { - Object[] tbl = CollectionInternals.getTable(coll); - return StreamSupport.longStream(new StepsLongHashTableKey(tbl, 0, tbl.length), false); - } - - /** - * Generates a LongStream that traverses long-valued values of a scala.collection.mutable.HashMap. - *

- * Both sequential and parallel operations will be efficient. - * - * @param coll The mutable.HashMap to traverse - * @return A LongStream view of the collection which, by default, executes sequentially. - */ - public static LongStream longStreamValues(scala.collection.mutable.HashMap coll) { - Object[] tbl = CollectionInternals.getTable(coll); - return StreamSupport.longStream(new StepsLongDefaultHashTableValue(tbl, 0, tbl.length), false); - } - - /** - * Generates a LongStream that traverses a scala.collection.mutable.HashSet of Longs. - *

- * Both sequential and parallel operations will be efficient. - * - * @param coll The mutable.HashSet to traverse - * @return A LongStream view of the collection which, by default, executes sequentially. - */ - public static LongStream longStream(scala.collection.mutable.HashSet coll) { - Object[] tbl = CollectionInternals.getTable(coll); - return StreamSupport.longStream(new StepsLongFlatHashTable(tbl, 0, tbl.length), false); - } - - /** - * Generates a LongStream that traverses a scala.collection.immutable.Vector of Longs. + /** + * Generates a LongStream that traverses a Scala collection. *

- * Both sequential and parallel operations will be efficient. + * Parallel processing is only efficient for collections that have a Stepper implementation + * which supports efficient splitting. For collections where this is the case, the stepper + * method has a return type marked with EfficientSplit. * - * @param coll The Vector to traverse + * @param coll The IterableOnce to traverse * @return A LongStream view of the collection which, by default, executes sequentially. */ - public static LongStream longStream(scala.collection.immutable.Vector coll) { - scala.collection.immutable.Vector erased = (scala.collection.immutable.Vector)coll; - return StreamSupport.longStream(new StepsLongVector(erased, 0, coll.length()), false); + public static LongStream longStream(IterableOnce coll) { + return StreamConverters.asJavaSeqLongStream((IterableOnce)(Object)coll); } - /** - * Generates a LongStream that traverses the long-valued keys of a scala.collection.Map. + /** + * Generates a LongStream that traverses the keys of a scala.collection.Map. *

- * Only sequential operations will be efficient. - * For efficient parallel operation, use the longStreamAccumulatedKeys method instead, but - * note that this creates a new collection containing the Map's keys. + * Parallel processing is only efficient for Maps that have a keyStepper implementation + * which supports efficient splitting. For collections where this is the case, the keyStepper + * method has a return type marked with EfficientSplit. * * @param coll The Map to traverse * @return A LongStream view of the collection which, by default, executes sequentially. */ - public static LongStream longStreamKeys(scala.collection.Map coll) { - scala.collection.Iterator iter = (scala.collection.Iterator)coll.keysIterator(); - return StreamSupport.longStream(new StepsLongIterator(iter), false); + public static LongStream longStreamKeys(Map coll) { + return StreamSupport.longStream(coll.keyStepper((StepperShape)(Object)StepperShape.doubleStepperShape()).spliterator(), false); } - /** - * Generates a LongStream that traverses the long-valued values of a scala.collection.Map. + /** + * Generates a LongStream that traverses the values of a scala.collection.Map. *

- * Only sequential operations will be efficient. - * For efficient parallel operation, use the longStreamAccumulatedValues method instead, but - * note that this creates a new collection containing the Map's values. + * Parallel processing is only efficient for Maps that have a valueStepper implementation + * which supports efficient splitting. For collections where this is the case, the valueStepper + * method has a return type marked with EfficientSplit. * * @param coll The Map to traverse * @return A LongStream view of the collection which, by default, executes sequentially. */ - public static LongStream longStreamValues(scala.collection.Map coll) { - scala.collection.Iterator iter = (scala.collection.Iterator)coll.valuesIterator(); - return StreamSupport.longStream(new StepsLongIterator(iter), false); - } - - /** - * Generates a LongStream that traverses a long-valued scala.collection.Iterator. - *

- * Only sequential operations will be efficient. - * For efficient parallel operation, use the longStreamAccumulated method instead, - * but note that this creates a copy of the contents of the Iterator. - * - * @param coll The scala.collection.Iterator to traverse - * @return A LongStream view of the collection which, by default, executes sequentially. - */ - public static LongStream longStream(scala.collection.Iterator coll) { - return StreamSupport.longStream(new StepsLongIterator((scala.collection.Iterator)coll), false); - } - - /** - * Generates a LongStream that traverses a long-valued scala.collection.Iterable. - *

- * Only sequential operations will be efficient. - * For efficient parallel operation, use the longStreamAccumulated method instead, - * but note that this creates a copy of the contents of the Iterable. - * - * @param coll The scala.collection.Iterable to traverse - * @return A LongStream view of the collection which, by default, executes sequentially. - */ - public static LongStream longStream(scala.collection.Iterable coll) { - scala.collection.Iterator iter = (scala.collection.Iterator)coll.iterator(); - return StreamSupport.longStream(new StepsLongIterator(iter), false); + public static LongStream longStreamValues(Map coll) { + return StreamSupport.longStream(coll.valueStepper((StepperShape)(Object)StepperShape.doubleStepperShape()).spliterator(), false); } - /** - * Generates a Stream that traverses any Scala collection by accumulating its entries + /** + * Generates a LongStream that traverses any Scala collection by accumulating its entries * into a buffer class (Accumulator). *

* Both sequential and parallel operations will be efficient. * * @param coll The collection to traverse - * @return A Stream view of the collection which, by default, executes sequentially. + * @return A LongStream view of the collection which, by default, executes sequentially. */ - public static LongStream longStreamAccumulated(scala.collection.IterableOnce coll) { - scala.compat.java8.collectionImpl.LongAccumulator acc = - scala.compat.java8.collectionImpl.LongAccumulator.from((scala.collection.IterableOnce)coll); - return StreamSupport.longStream(acc.spliterator(), false); + public static LongStream longStreamAccumulated(IterableOnce coll) { + return StreamConverters.asJavaSeqLongStream(scala.jdk.LongAccumulator$.MODULE$.fromSpecific((IterableOnce)(Object)coll)); } - /** - * Generates a Stream that traverses the keys of any Scala map by + /** + * Generates a LongStream that traverses the keys of any Scala map by * accumulating those keys into a buffer class (Accumulator). *

* Both sequential and parallel operations will be efficient. * * @param coll The map containing keys to traverse - * @return A Stream view of the collection which, by default, executes sequentially. + * @return A LongStream view of the collection which, by default, executes sequentially. */ - public static LongStream longStreamAccumulatedKeys(scala.collection.Map coll) { - scala.compat.java8.collectionImpl.LongAccumulator acc = - scala.compat.java8.collectionImpl.LongAccumulator.from((scala.collection.Iterator)coll.keysIterator()); - return StreamSupport.longStream(acc.spliterator(), false); + public static LongStream longStreamAccumulatedKeys(Map coll) { + return StreamConverters.asJavaSeqLongStream(scala.jdk.LongAccumulator$.MODULE$.fromSpecific((IterableOnce)(Object)coll.keysIterator())); } - /** - * Generates a Stream that traverses the values of any Scala map by + /** + * Generates a LongStream that traverses the values of any Scala map by * accumulating those values into a buffer class (Accumulator). *

* Both sequential and parallel operations will be efficient. * * @param coll The map containing values to traverse - * @return A Stream view of the collection which, by default, executes sequentially. + * @return A LongStream view of the collection which, by default, executes sequentially. */ - public static LongStream longStreamAccumulatedValues(scala.collection.Map coll) { - scala.compat.java8.collectionImpl.LongAccumulator acc = - scala.compat.java8.collectionImpl.LongAccumulator.from((scala.collection.Iterator)coll.valuesIterator()); - return StreamSupport.longStream(acc.spliterator(), false); + public static LongStream longStreamAccumulatedValues(Map coll) { + return StreamConverters.asJavaSeqLongStream(scala.jdk.LongAccumulator$.MODULE$.fromSpecific((IterableOnce)(Object)coll.valuesIterator())); } } diff --git a/src/main/java/scala/compat/java8/runtime/CollectionInternals.java b/src/main/java/scala/compat/java8/runtime/CollectionInternals.java deleted file mode 100644 index 8485081..0000000 --- a/src/main/java/scala/compat/java8/runtime/CollectionInternals.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * 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.compat.java8.runtime; - -// No imports! All type names are fully qualified to avoid confusion! - -public class CollectionInternals { - public static Object[] getTable(scala.collection.mutable.HashSet hs) { return hs.getTable().table(); } - public static Object[] getTable(scala.collection.mutable.LinkedHashSet hm) { return hm.getTable().table(); } - - public static Object[] getTable(scala.collection.mutable.HashMap hm) { return hm.getTable().table(); } - public static Object[] getTable(scala.collection.mutable.LinkedHashMap hm) { return hm.getTable().table(); } - - public static K hashEntryKey(Object hashEntry) { return ((scala.collection.mutable.HashEntry)hashEntry).key(); } - public static Object hashEntryNext(Object hashEntry) { return ((scala.collection.mutable.HashEntry)hashEntry).next(); } - public static V linkedEntryValue(Object hashEntry) { return ((scala.collection.mutable.LinkedHashMap.LinkedEntry)hashEntry).value(); } - public static V defaultEntryValue(Object hashEntry) { return ((scala.collection.mutable.DefaultEntry)hashEntry).value(); } - - public static boolean getDirt(scala.collection.immutable.Vector v) { return v.dirty(); } - public static Object[] getDisplay0(scala.collection.immutable.Vector v) { return v.display0(); } - public static Object[] getDisplay0(scala.collection.immutable.VectorIterator p) { return p.display0(); } - public static Object[] getDisplay1(scala.collection.immutable.Vector v) { return v.display1(); } - public static Object[] getDisplay1(scala.collection.immutable.VectorIterator p) { return p.display1(); } - public static Object[] getDisplay2(scala.collection.immutable.Vector v) { return v.display2(); } - public static Object[] getDisplay2(scala.collection.immutable.VectorIterator p) { return p.display2(); } - public static Object[] getDisplay3(scala.collection.immutable.Vector v) { return v.display3(); } - public static Object[] getDisplay3(scala.collection.immutable.VectorIterator p) { return p.display3(); } - public static Object[] getDisplay4(scala.collection.immutable.Vector v) { return v.display4(); } - public static Object[] getDisplay4(scala.collection.immutable.VectorIterator p) { return p.display4(); } - public static Object[] getDisplay5(scala.collection.immutable.Vector v) { return v.display5(); } - public static Object[] getDisplay5(scala.collection.immutable.VectorIterator p) { return p.display5(); } - public static scala.Tuple2< scala.Tuple2< scala.collection.Iterator, Object >, scala.collection.Iterator > trieIteratorSplit(scala.collection.Iterator it) { - if (it instanceof scala.collection.immutable.TrieIterator) { - scala.collection.immutable.TrieIterator trie = (scala.collection.immutable.TrieIterator)it; - return trie.split(); - } - return null; - } - - public static long[] getBitSetInternals(scala.collection.mutable.BitSet bitSet) { return bitSet.elems(); } -} - diff --git a/src/main/scala/scala/compat/java8/SpliteratorConverters.scala b/src/main/scala/scala/compat/java8/SpliteratorConverters.scala deleted file mode 100644 index 36838f3..0000000 --- a/src/main/scala/scala/compat/java8/SpliteratorConverters.scala +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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.compat.java8 - -import language.implicitConversions - -import java.util._ -import scala.compat.java8.collectionImpl._ - -package SpliteratorConverters { - class SpliteratorToStepper[A] private[java8] (private val underlying: Spliterator[A]) extends AnyVal { - def stepper: AnyStepper[A] = Stepper.ofSpliterator(underlying) - } - - trait Priority2SpliteratorConverters { - implicit def spliteratorToStepper[A](sp: Spliterator[A]) = new SpliteratorToStepper[A](sp) - } -} - - -package object SpliteratorConverters extends SpliteratorConverters.Priority2SpliteratorConverters { - implicit final class SpliteratorOfDoubleToStepper(private val underlying: Spliterator.OfDouble) extends AnyVal { - def stepper: DoubleStepper = Stepper.ofSpliterator(underlying) - } - implicit final class SpliteratorOfIntToStepper(private val underlying: Spliterator.OfInt) extends AnyVal { - def stepper: IntStepper = Stepper.ofSpliterator(underlying) - } - implicit final class SpliteratorOfLongToStepper(private val underlying: Spliterator.OfLong) extends AnyVal { - def stepper: LongStepper = Stepper.ofSpliterator(underlying) - } -} diff --git a/src/main/scala/scala/compat/java8/StreamConverters.scala b/src/main/scala/scala/compat/java8/StreamConverters.scala index e902491..55e8bc9 100644 --- a/src/main/scala/scala/compat/java8/StreamConverters.scala +++ b/src/main/scala/scala/compat/java8/StreamConverters.scala @@ -12,113 +12,350 @@ package scala.compat.java8 -import scala.language.higherKinds - import java.util.stream._ -import scala.compat.java8.collectionImpl._ + +import scala.annotation.implicitNotFound +import scala.collection.Stepper.EfficientSplit +import scala.collection.convert.StreamExtensions.{AccumulatorFactoryInfo, StreamShape, StreamUnboxer} +import scala.collection.{IterableOnce, Stepper, StepperShape} import scala.compat.java8.converterImpl._ -import scala.reflect.ClassTag +import scala.jdk._ +import scala.language.higherKinds +import scala.jdk.CollectionConverters.Ops._ -/** Classes or objects implementing this trait create streams suitable for sequential use */ -trait MakesSequentialStream[T, SS <: java.util.stream.BaseStream[_, SS]] extends Any { - def seqStream: SS -} -/** Classes or objects implementing this trait create streams suitable for parallel use */ -trait MakesParallelStream[T, SS <: java.util.stream.BaseStream[_, SS]] extends Any { - def parStream: SS -} +/** Defines extension methods to create Java Streams for Scala collections, available through + * [[scala.jdk.StreamConverters.Ops]]. + */ +trait StreamExtensions { + implicit def richStepper[A](s: Stepper[A]): StepperExtensions[A] = new StepperExtensions[A](s) + + // collections + + implicit class IterableHasSeqStream[A](cc: IterableOnce[A]) { + /** Create a sequential [[java.util.stream.Stream Java Stream]] for this collection. If the + * collection contains primitive values, a corresponding specialized Stream is returned (e.g., + * [[java.util.stream.IntStream `IntStream`]]). + */ + def seqStream[S <: BaseStream[_, _], St <: Stepper[_]](implicit s: StreamShape[A, S, St], st: StepperShape[A, St]): S = + s.fromStepper(cc.stepper, par = false) + } -sealed trait StreamShape[T, S <: BaseStream[_, S]] { - def fromStepper (mk: MakesStepper[T, _], par: Boolean): S - def fromKeyStepper (mk: MakesKeyValueStepper[T, _, _], par: Boolean): S - def fromValueStepper(mk: MakesKeyValueStepper[_, T, _], par: Boolean): S -} -object StreamShape extends StreamShapeLowPriority { - // primitive - implicit val IntValue = intStreamShape[Int] - implicit val LongValue = longStreamShape[Long] - implicit val DoubleValue = doubleStreamShape[Double] - - // widening - implicit val ByteValue = intStreamShape[Byte] - implicit val ShortValue = intStreamShape[Short] - implicit val CharValue = intStreamShape[Char] - implicit val FloatValue = doubleStreamShape[Float] -} -trait StreamShapeLowPriority { - protected[this] abstract class BaseStreamShape[T, S <: BaseStream[_, S], St <: Stepper[_]](implicit ss: StepperShape[T, St]) extends StreamShape[T, S] { - final def fromStepper (mk: MakesStepper[T, _], par: Boolean): S = stream(mk.stepper, par) - final def fromKeyStepper (mk: MakesKeyValueStepper[T, _, _], par: Boolean): S = stream(mk.keyStepper, par) - final def fromValueStepper(mk: MakesKeyValueStepper[_, T, _], par: Boolean): S = stream(mk.valueStepper, par) - @inline private[this] def stream(st: St, par: Boolean): S = mkStream(if(par) st.anticipateParallelism() else st, par) - protected[this] def mkStream(st: St, par: Boolean): S + protected type IterableOnceWithEfficientStepper[A] = IterableOnce[A] { + def stepper[B >: A, S <: Stepper[_]](implicit shape : StepperShape[B, S]) : S with EfficientSplit } - protected[this] def intStreamShape[T](implicit ss: StepperShape[T, IntStepper]): StreamShape[T, IntStream] = new BaseStreamShape[T, IntStream, IntStepper] { - protected[this] def mkStream(st: IntStepper, par: Boolean): IntStream = StreamSupport.intStream(st, par) + + // Not `CC[X] <: IterableOnce[X]`, but `C` with an extra constraint, to support non-parametric classes like IntAccumulator + implicit class IterableNonGenericHasParStream[A, C <: IterableOnce[_]](c: C)(implicit ev: C <:< IterableOnce[A]) { + /** Create a parallel [[java.util.stream.Stream Java Stream]] for this collection. If the + * collection contains primitive values, a corresponding specialized Stream is returned (e.g., + * [[java.util.stream.IntStream `IntStream`]]). + */ + def parStream[S <: BaseStream[_, _], St <: Stepper[_]](implicit + s: StreamShape[A, S, St], + st: StepperShape[A, St], + @implicitNotFound("`parStream` can only be called on collections where `stepper` returns a `Stepper with EfficientSplit`") + isEfficient: C <:< IterableOnceWithEfficientStepper[A]): S = + s.fromStepper(ev(c).stepper, par = true) } - protected[this] def longStreamShape[T](implicit ss: StepperShape[T, LongStepper]): StreamShape[T, LongStream] = new BaseStreamShape[T, LongStream, LongStepper] { - protected[this] def mkStream(st: LongStepper, par: Boolean): LongStream = StreamSupport.longStream(st, par) + + // maps + + implicit class MapHasSeqKeyValueStream[K, V, CC[X, Y] <: collection.MapOps[X, Y, CC, _]](cc: CC[K, V]) { + /** Create a sequential [[java.util.stream.Stream Java Stream]] for the keys of this map. If + * the keys are primitive values, a corresponding specialized Stream is returned (e.g., + * [[java.util.stream.IntStream `IntStream`]]). + */ + def seqKeyStream[S <: BaseStream[_, _], St <: Stepper[_]](implicit s: StreamShape[K, S, St], st: StepperShape[K, St]): S = + s.fromStepper(cc.keyStepper, par = false) + + /** Create a sequential [[java.util.stream.Stream Java Stream]] for the values of this map. If + * the values are primitives, a corresponding specialized Stream is returned (e.g., + * [[java.util.stream.IntStream `IntStream`]]). + */ + def seqValueStream[S <: BaseStream[_, _], St <: Stepper[_]](implicit s: StreamShape[V, S, St], st: StepperShape[V, St]): S = + s.fromStepper(cc.valueStepper, par = false) + + // The seqStream extension method for IterableOnce doesn't apply because its `CC` takes a single type parameter, whereas the one here takes two + /** Create a sequential [[java.util.stream.Stream Java Stream]] for the `(key, value)` pairs of + * this map. + */ + def seqStream[S <: BaseStream[_, _], St <: Stepper[_]](implicit s: StreamShape[(K, V), S, St], st: StepperShape[(K, V), St]): S = + s.fromStepper(cc.stepper, par = false) } - protected[this] def doubleStreamShape[T](implicit ss: StepperShape[T, DoubleStepper]): StreamShape[T, DoubleStream] = new BaseStreamShape[T, DoubleStream, DoubleStepper] { - protected[this] def mkStream(st: DoubleStepper, par: Boolean): DoubleStream = StreamSupport.doubleStream(st, par) + + + implicit class MapHasParKeyValueStream[K, V, CC[X, Y] <: collection.MapOps[X, Y, CC, _]](cc: CC[K, V]) { + private type MapOpsWithEfficientKeyStepper[K, V] = collection.MapOps[K, V, CC, _] { def keyStepper[S <: Stepper[_]](implicit shape : StepperShape[K, S]) : S with EfficientSplit } + private type MapOpsWithEfficientValueStepper[K, V] = collection.MapOps[K, V, CC, _] { def valueStepper[V1 >: V, S <: Stepper[_]](implicit shape : StepperShape[V1, S]) : S with EfficientSplit } + private type MapOpsWithEfficientStepper[K, V] = collection.MapOps[K, V, CC, _] { def stepper[B >: (K, V), S <: Stepper[_]](implicit shape : StepperShape[B, S]) : S with EfficientSplit } + + /** Create a parallel [[java.util.stream.Stream Java Stream]] for the keys of this map. If + * the keys are primitive values, a corresponding specialized Stream is returned (e.g., + * [[java.util.stream.IntStream `IntStream`]]). + */ + def parKeyStream[S <: BaseStream[_, _], St <: Stepper[_]](implicit + s: StreamShape[K, S, St], + st: StepperShape[K, St], + @implicitNotFound("parKeyStream can only be called on maps where `keyStepper` returns a `Stepper with EfficientSplit`") + isEfficient: CC[K, V] <:< MapOpsWithEfficientKeyStepper[K, V]): S = + s.fromStepper(cc.keyStepper, par = true) + + /** Create a parallel [[java.util.stream.Stream Java Stream]] for the values of this map. If + * the values are primitives, a corresponding specialized Stream is returned (e.g., + * [[java.util.stream.IntStream `IntStream`]]). + */ + def parValueStream[S <: BaseStream[_, _], St <: Stepper[_]](implicit + s: StreamShape[V, S, St], + st: StepperShape[V, St], + @implicitNotFound("parValueStream can only be called on maps where `valueStepper` returns a `Stepper with EfficientSplit`") + isEfficient: CC[K, V] <:< MapOpsWithEfficientValueStepper[K, V]): S = + s.fromStepper(cc.valueStepper, par = true) + + // The parStream extension method for IterableOnce doesn't apply because its `CC` takes a single type parameter, whereas the one here takes two + /** Create a parallel [[java.util.stream.Stream Java Stream]] for the `(key, value)` pairs of + * this map. + */ + def parStream[S <: BaseStream[_, _], St <: Stepper[_]](implicit + s: StreamShape[(K, V), S, St], + st: StepperShape[(K, V), St], + @implicitNotFound("parStream can only be called on maps where `stepper` returns a `Stepper with EfficientSplit`") + isEfficient: CC[K, V] <:< MapOpsWithEfficientStepper[K, V]): S = + s.fromStepper(cc.stepper, par = true) } - // reference - implicit def anyStreamShape[T]: StreamShape[T, Stream[T]] = new BaseStreamShape[T, Stream[T], AnyStepper[T]] { - protected[this] def mkStream(st: AnyStepper[T], par: Boolean): Stream[T] = StreamSupport.stream(st, par) + // steppers + + implicit class StepperHasSeqStream[A](stepper: Stepper[A]) { + /** Create a sequential [[java.util.stream.Stream Java Stream]] for this stepper. If the + * stepper yields primitive values, a corresponding specialized Stream is returned (e.g., + * [[java.util.stream.IntStream `IntStream`]]). + */ + def seqStream[S <: BaseStream[_, _], St <: Stepper[_]](implicit s: StreamShape[A, S, St], st: StepperShape[A, St]): S = + s.fromStepper(stepper.asInstanceOf[St], par = false) } -} -trait PrimitiveStreamAccumulator[S, AA] { - def streamAccumulate(stream: S): AA -} + implicit class StepperHasParStream[A](stepper: Stepper[A] with EfficientSplit) { + /** Create a parallel [[java.util.stream.Stream Java Stream]] for this stepper. If the + * stepper yields primitive values, a corresponding specialized Stream is returned (e.g., + * [[java.util.stream.IntStream `IntStream`]]). + */ + def parStream[S <: BaseStream[_, _], St <: Stepper[_]](implicit s: StreamShape[A, S, St], st: StepperShape[A, St]): S = + s.fromStepper(stepper.asInstanceOf[St], par = true) + } -trait PrimitiveStreamUnboxer[A, S] { - def apply(boxed: Stream[A]): S -} + // arrays + // uses the JDK array spliterators (`DoubleArraySpliterator`). users can also call + // `array.stepper.seqStream`, which then uses the Scala steppers (`DoubleArrayStepper`). the + // steppers are also available on byte/short/char/float arrays (`WidenedByteArrayStepper`), + // JDK spliterators only for double/int/long/reference. -trait Priority2StreamConverters { - implicit class EnrichAnySteppableWithParStream[A, S <: BaseStream[_, S], CC](cc: CC)(implicit steppize: CC => MakesStepper[A, EfficientSubstep], ss: StreamShape[A, S]) - extends MakesParallelStream[A, S] { - def parStream: S = ss.fromStepper(steppize(cc), true) + implicit class DoubleArrayHasSeqParStream(a: Array[Double]) { + /** Create a sequential [[java.util.stream.DoubleStream Java DoubleStream]] for this array. */ + def seqStream: DoubleStream = java.util.Arrays.stream(a) + /** Create a parallel [[java.util.stream.DoubleStream Java DoubleStream]] for this array. */ + def parStream: DoubleStream = seqStream.parallel } - implicit class EnrichAnySteppableWithSeqStream[A, S <: BaseStream[_, S], CC](cc: CC)(implicit steppize: CC => MakesStepper[A, Any], ss: StreamShape[A, S]) - extends MakesSequentialStream[A, S] { - def seqStream: S = ss.fromStepper(steppize(cc), false) + + implicit class IntArrayHasSeqParStream(a: Array[Int]) { + /** Create a sequential [[java.util.stream.IntStream Java IntStream]] for this array. */ + def seqStream: IntStream = java.util.Arrays.stream(a) + /** Create a parallel [[java.util.stream.IntStream Java IntStream]] for this array. */ + def parStream: IntStream = seqStream.parallel } - implicit class EnrichAnySteppableWithParKeyStream[A, S <: BaseStream[_, S], CC](cc: CC)(implicit steppize: CC => MakesKeyValueStepper[A, _, EfficientSubstep], ss: StreamShape[A, S]) { - def parKeyStream: S = ss.fromKeyStepper(steppize(cc), true) + + implicit class LongArrayHasSeqParStream(a: Array[Long]) { + /** Create a sequential [[java.util.stream.LongStream Java LongStream]] for this array. */ + def seqStream: LongStream = java.util.Arrays.stream(a) + /** Create a parallel [[java.util.stream.LongStream Java LongStream]] for this array. */ + def parStream: LongStream = seqStream.parallel } - implicit class EnrichScalaCollectionWithSeqKeyStream[A, S <: BaseStream[_, S], CC](cc: CC)(implicit steppize: CC => MakesKeyValueStepper[A, _, Any], ss: StreamShape[A, S]) { - def seqKeyStream: S = ss.fromKeyStepper(steppize(cc), false) + + implicit class AnyArrayHasSeqParStream[A <: AnyRef](a: Array[A]) { + /** Create a sequential [[java.util.stream.Stream Java Stream]] for this array. */ + def seqStream: Stream[A] = java.util.Arrays.stream(a) + /** Create a parallel [[java.util.stream.Stream Java Stream]] for this array. */ + def parStream: Stream[A] = seqStream.parallel } - implicit class EnrichAnySteppableWithParValueStream[A, S <: BaseStream[_, S], CC](cc: CC)(implicit steppize: CC => MakesKeyValueStepper[_, A, EfficientSubstep], ss: StreamShape[A, S]) { - def parValueStream: S = ss.fromValueStepper(steppize(cc), true) + + implicit class ByteArrayHasSeqParStream(a: Array[Byte]) { + /** Create a sequential [[java.util.stream.IntStream Java IntStream]] for this array. */ + def seqStream: IntStream = a.stepper.seqStream + /** Create a parallel [[java.util.stream.IntStream Java IntStream]] for this array. */ + def parStream: IntStream = a.stepper.parStream } - implicit class EnrichScalaCollectionWithSeqValueStream[A, S <: BaseStream[_, S], CC](cc: CC)(implicit steppize: CC => MakesKeyValueStepper[_, A, Any], ss: StreamShape[A, S]) { - def seqValueStream: S = ss.fromValueStepper(steppize(cc), false) + + implicit class ShortArrayHasSeqParStream(a: Array[Short]) { + /** Create a sequential [[java.util.stream.IntStream Java IntStream]] for this array. */ + def seqStream: IntStream = a.stepper.seqStream + /** Create a parallel [[java.util.stream.IntStream Java IntStream]] for this array. */ + def parStream: IntStream = a.stepper.parStream + } + + implicit class CharArrayHasSeqParStream(a: Array[Char]) { + /** Create a sequential [[java.util.stream.IntStream Java IntStream]] for this array. */ + def seqStream: IntStream = a.stepper.seqStream + /** Create a parallel [[java.util.stream.IntStream Java IntStream]] for this array. */ + def parStream: IntStream = a.stepper.parStream + } + + implicit class FloatArrayHasSeqParStream(a: Array[Float]) { + /** Create a sequential [[java.util.stream.DoubleStream Java DoubleStream]] for this array. */ + def seqStream: DoubleStream = a.stepper.seqStream + + /** Create a parallel [[java.util.stream.DoubleStream Java DoubleStream]] for this array. */ + def parStream: DoubleStream = a.stepper.parStream } -} -trait Priority1StreamConverters extends Priority2StreamConverters { - implicit class RichStream[A](stream: Stream[A]) { - def accumulate: Accumulator[A] = stream.collect(Accumulator.supplier[A], Accumulator.adder[A], Accumulator.merger[A]) - - def toScala[Coll[_]](implicit factory: collection.Factory[A, Coll[A]]): Coll[A] = { - if (stream.isParallel) accumulate.to[Coll](factory) - else { - val b = factory.newBuilder - stream.forEachOrdered(new java.util.function.Consumer[A]{ def accept(a: A): Unit = { b += a } }) - b.result() - } + // toScala for streams + + implicit class StreamHasToScala[A](stream: Stream[A]) { + def accumulate: AnyAccumulator[A] = toScala(Accumulator) + + + /** + * Copy the elements of this stream into a Scala collection. + * + * Converting a parallel streams to an [[Accumulator]] using `stream.toScala(Accumulator)` + * builds the result in parallel. + * + * A `toScala(Accumulator)` call automatically converts streams of boxed integers, longs or + * doubles are converted to the primitive accumulators ([[IntAccumulator]], etc.). + * + * When converting a parallel stream to a different Scala collection, the stream is first + * converted into an [[Accumulator]], which supports parallel building. The accumulator is + * then converted to the target collection. Note that the stream is processed eagerly while + * building the accumulator, even if the target collection is lazy. + * + * Sequential streams are directly converted to the target collection. If the target collection + * is lazy, the conversion is lazy as well. + */ + def toScala[C1](factory: collection.Factory[A, C1])(implicit info: AccumulatorFactoryInfo[A, C1]): C1 = { + + def anyAcc = stream.collect(AnyAccumulator.supplier[A], AnyAccumulator.adder[A], AnyAccumulator.merger[A]) + if (info.companion == AnyAccumulator) anyAcc.asInstanceOf[C1] + else if (info.companion == IntAccumulator) stream.asInstanceOf[Stream[Int]].collect(IntAccumulator.supplier, IntAccumulator.boxedAdder, IntAccumulator.merger).asInstanceOf[C1] + else if (info.companion == LongAccumulator) stream.asInstanceOf[Stream[Long]].collect(LongAccumulator.supplier, LongAccumulator.boxedAdder, LongAccumulator.merger).asInstanceOf[C1] + else if (info.companion == DoubleAccumulator) stream.asInstanceOf[Stream[Double]].collect(DoubleAccumulator.supplier, DoubleAccumulator.boxedAdder, DoubleAccumulator.merger).asInstanceOf[C1] + else if (stream.isParallel) anyAcc.to(factory) + else factory.fromSpecific(stream.iterator.asScala) } - - def unboxed[S](implicit ubx: PrimitiveStreamUnboxer[A, S]): S = ubx(stream) + + /** Convert a generic Java Stream wrapping a primitive type to a corresponding primitive + * Stream. + */ + def unboxed[S](implicit unboxer: StreamUnboxer[A, S]): S = unboxer(stream) + } + + implicit class StreamIntHasAccumulatePrimitive(s: Stream[Int]) { + def accumulatePrimitive: IntAccumulator = s.toScala(Accumulator) } - - implicit class RichStreamCanAccumulatePrimitive[S](stream: S) { - def accumulatePrimitive[AA](implicit psa: PrimitiveStreamAccumulator[S, AA]) = psa.streamAccumulate(stream) + + implicit class StreamLongHasAccumulatePrimitive(s: Stream[Long]) { + def accumulatePrimitive: LongAccumulator = s.toScala(Accumulator) + } + + implicit class StreamDoubleHasAccumulatePrimitive(s: Stream[Double]) { + def accumulatePrimitive: DoubleAccumulator = s.toScala(Accumulator) + } + + implicit class StreamJIntegerHasAccumulatePrimitive(s: Stream[java.lang.Integer]) { + def accumulatePrimitive: IntAccumulator = s.toScala(Accumulator) + } + + implicit class StreamJLongHasAccumulatePrimitive(s: Stream[java.lang.Long]) { + def accumulatePrimitive: LongAccumulator = s.toScala(Accumulator) + } + + implicit class StreamJDoubleHasAccumulatePrimitive(s: Stream[java.lang.Double]) { + def accumulatePrimitive: DoubleAccumulator = s.toScala(Accumulator) + } + + implicit class IntStreamHasToScala(stream: IntStream) { + def accumulate: IntAccumulator = toScala(IntAccumulator) + + /** + * Copy the elements of this stream into a Scala collection. + * + * Converting a parallel streams to an [[Accumulator]] using `stream.toScala(Accumulator)` + * builds the result in parallel. + * + * A `toScala(Accumulator)` call automatically converts the `IntStream` to a primitive + * [[IntAccumulator]]. + * + * When converting a parallel stream to a different Scala collection, the stream is first + * converted into an [[Accumulator]], which supports parallel building. The accumulator is + * then converted to the target collection. Note that the stream is processed eagerly while + * building the accumulator, even if the target collection is lazy. + * + * Sequential streams are directly converted to the target collection. If the target collection + * is lazy, the conversion is lazy as well. + */ + def toScala[C1](factory: collection.Factory[Int, C1])(implicit info: AccumulatorFactoryInfo[Int, C1]): C1 = { + def intAcc = stream.collect(IntAccumulator.supplier, IntAccumulator.adder, IntAccumulator.merger) + if (info.companion == AnyAccumulator) stream.collect(AnyAccumulator.supplier[Int], AnyAccumulator.unboxedIntAdder, AnyAccumulator.merger[Int]).asInstanceOf[C1] + else if (info.companion == IntAccumulator) intAcc.asInstanceOf[C1] + else if (stream.isParallel) intAcc.to(factory) + else factory.fromSpecific(stream.iterator.asInstanceOf[java.util.Iterator[Int]].asScala) + } + } + + implicit class LongStreamHasToScala(stream: LongStream) { + def accumulate: LongAccumulator = toScala(LongAccumulator) + + /** + * Copy the elements of this stream into a Scala collection. + * + * Converting a parallel streams to an [[Accumulator]] using `stream.toScala(Accumulator)` + * builds the result in parallel. + * + * A `toScala(Accumulator)` call automatically converts the `LongStream` to a primitive + * [[LongAccumulator]]. + * + * When converting a parallel stream to a different Scala collection, the stream is first + * converted into an [[Accumulator]], which supports parallel building. The accumulator is + * then converted to the target collection. Note that the stream is processed eagerly while + * building the accumulator, even if the target collection is lazy. + * + * Sequential streams are directly converted to the target collection. If the target collection + * is lazy, the conversion is lazy as well. + */ + def toScala[C1](factory: collection.Factory[Long, C1])(implicit info: AccumulatorFactoryInfo[Long, C1]): C1 = { + def longAcc = stream.collect(LongAccumulator.supplier, LongAccumulator.adder, LongAccumulator.merger) + if (info.companion == AnyAccumulator) stream.collect(AnyAccumulator.supplier[Long], AnyAccumulator.unboxedLongAdder, AnyAccumulator.merger[Long]).asInstanceOf[C1] + else if (info.companion == LongAccumulator) longAcc.asInstanceOf[C1] + else if (stream.isParallel) longAcc.to(factory) + else factory.fromSpecific(stream.iterator.asInstanceOf[java.util.Iterator[Long]].asScala) + } + } + + implicit class DoubleStreamHasToScala(stream: DoubleStream) { + def accumulate: DoubleAccumulator = toScala(DoubleAccumulator) + + /** + * Copy the elements of this stream into a Scala collection. + * + * Converting a parallel streams to an [[Accumulator]] using `stream.toScala(Accumulator)` + * builds the result in parallel. + * + * A `toScala(Accumulator)` call automatically converts the `DoubleStream` to a primitive + * [[DoubleAccumulator]]. + * + * When converting a parallel stream to a different Scala collection, the stream is first + * converted into an [[Accumulator]], which supports parallel building. The accumulator is + * then converted to the target collection. Note that the stream is processed eagerly while + * building the accumulator, even if the target collection is lazy. + * + * Sequential streams are directly converted to the target collection. If the target collection + * is lazy, the conversion is lazy as well. + */ + def toScala[C1](factory: collection.Factory[Double, C1])(implicit info: AccumulatorFactoryInfo[Double, C1]): C1 = { + def doubleAcc = stream.collect(DoubleAccumulator.supplier, DoubleAccumulator.adder, DoubleAccumulator.merger) + if (info.companion == AnyAccumulator) stream.collect(AnyAccumulator.supplier[Double], AnyAccumulator.unboxedDoubleAdder, AnyAccumulator.merger[Double]).asInstanceOf[C1] + else if (info.companion == DoubleAccumulator) doubleAcc.asInstanceOf[C1] + else if (stream.isParallel) doubleAcc.to(factory) + else factory.fromSpecific(stream.iterator.asInstanceOf[java.util.Iterator[Double]].asScala) + } } } @@ -186,170 +423,10 @@ trait Priority1StreamConverters extends Priority2StreamConverters { * }}} */ object StreamConverters -extends Priority1StreamConverters -with converterImpl.Priority1StepConverters +extends StreamExtensions with converterImpl.Priority1AccumulatorConverters { - private[java8] def unsafeArrayIfPossible[A](a: collection.mutable.ArraySeq[A])(implicit c: ClassTag[A]): Array[A] = { - if (a.elemTag == c) - a.array.asInstanceOf[Array[A]] - else - a.toArray - } - - implicit final class EnrichDoubleArrayWithStream(private val a: Array[Double]) - extends AnyVal with MakesSequentialStream[Double, DoubleStream] with MakesParallelStream[Double, DoubleStream] { - def seqStream: DoubleStream = java.util.Arrays.stream(a) - def parStream: DoubleStream = seqStream.parallel - } - - implicit final class EnrichIntArrayWithStream(private val a: Array[Int]) - extends AnyVal with MakesSequentialStream[Int, IntStream] with MakesParallelStream[Int, IntStream] { - def seqStream: IntStream = java.util.Arrays.stream(a) - def parStream: IntStream = seqStream.parallel - } - - implicit final class EnrichLongArrayWithStream(private val a: Array[Long]) - extends AnyVal with MakesSequentialStream[Long, LongStream] with MakesParallelStream[Long, LongStream] { - def seqStream: LongStream = java.util.Arrays.stream(a) - def parStream: LongStream = seqStream.parallel - } - - implicit final class EnrichDoubleArraySeqWithStream(private val a: collection.mutable.ArraySeq[Double]) - extends AnyVal with MakesSequentialStream[Double, DoubleStream] with MakesParallelStream[Double, DoubleStream] { - def seqStream: DoubleStream = java.util.Arrays.stream(unsafeArrayIfPossible(a)) - def parStream: DoubleStream = seqStream.parallel - } - - implicit final class EnrichIntArraySeqWithStream(private val a: collection.mutable.ArraySeq[Int]) - extends AnyVal with MakesSequentialStream[Int, IntStream] with MakesParallelStream[Int, IntStream] { - def seqStream: IntStream = java.util.Arrays.stream(unsafeArrayIfPossible(a)) - def parStream: IntStream = seqStream.parallel - } - - implicit final class EnrichLongArraySeqWithStream(private val a: collection.mutable.ArraySeq[Long]) - extends AnyVal with MakesSequentialStream[Long, LongStream] with MakesParallelStream[Long, LongStream] { - def seqStream: LongStream = java.util.Arrays.stream(unsafeArrayIfPossible(a)) - def parStream: LongStream = seqStream.parallel - } - - implicit val primitiveAccumulateDoubleStream: PrimitiveStreamAccumulator[Stream[Double], DoubleAccumulator] = - new PrimitiveStreamAccumulator[Stream[Double], DoubleAccumulator] { - def streamAccumulate(stream: Stream[Double]): DoubleAccumulator = - stream.collect(DoubleAccumulator.supplier, DoubleAccumulator.boxedAdder, DoubleAccumulator.merger) - } - - implicit val primitiveAccumulateDoubleStream2: PrimitiveStreamAccumulator[Stream[java.lang.Double], DoubleAccumulator] = - primitiveAccumulateDoubleStream.asInstanceOf[PrimitiveStreamAccumulator[Stream[java.lang.Double], DoubleAccumulator]] - - implicit val primitiveUnboxDoubleStream: PrimitiveStreamUnboxer[Double, DoubleStream] = - new PrimitiveStreamUnboxer[Double, DoubleStream] { - def apply(boxed: Stream[Double]): DoubleStream = - boxed.mapToDouble(new java.util.function.ToDoubleFunction[Double]{ def applyAsDouble(d: Double) = d }) - } - - implicit val primitiveUnboxDoubleStream2: PrimitiveStreamUnboxer[java.lang.Double, DoubleStream] = - primitiveUnboxDoubleStream.asInstanceOf[PrimitiveStreamUnboxer[java.lang.Double, DoubleStream]] - - implicit val primitiveAccumulateIntStream: PrimitiveStreamAccumulator[Stream[Int], IntAccumulator] = - new PrimitiveStreamAccumulator[Stream[Int], IntAccumulator] { - def streamAccumulate(stream: Stream[Int]): IntAccumulator = - stream.collect(IntAccumulator.supplier, IntAccumulator.boxedAdder, IntAccumulator.merger) - } - - implicit val primitiveAccumulateIntStream2: PrimitiveStreamAccumulator[Stream[java.lang.Integer], IntAccumulator] = - primitiveAccumulateIntStream.asInstanceOf[PrimitiveStreamAccumulator[Stream[java.lang.Integer], IntAccumulator]] - - implicit val primitiveUnboxIntStream: PrimitiveStreamUnboxer[Int, IntStream] = - new PrimitiveStreamUnboxer[Int, IntStream] { - def apply(boxed: Stream[Int]): IntStream = - boxed.mapToInt(new java.util.function.ToIntFunction[Int]{ def applyAsInt(d: Int) = d }) - } - - implicit val primitiveUnboxIntStream2: PrimitiveStreamUnboxer[java.lang.Integer, IntStream] = - primitiveUnboxIntStream.asInstanceOf[PrimitiveStreamUnboxer[java.lang.Integer, IntStream]] - - implicit val primitiveAccumulateLongStream: PrimitiveStreamAccumulator[Stream[Long], LongAccumulator] = - new PrimitiveStreamAccumulator[Stream[Long], LongAccumulator] { - def streamAccumulate(stream: Stream[Long]): LongAccumulator = - stream.collect(LongAccumulator.supplier, LongAccumulator.boxedAdder, LongAccumulator.merger) - } - - implicit val primitiveAccumulateLongStream2: PrimitiveStreamAccumulator[Stream[java.lang.Long], LongAccumulator] = - primitiveAccumulateLongStream.asInstanceOf[PrimitiveStreamAccumulator[Stream[java.lang.Long], LongAccumulator]] - - implicit val primitiveUnboxLongStream: PrimitiveStreamUnboxer[Long, LongStream] = - new PrimitiveStreamUnboxer[Long, LongStream] { - def apply(boxed: Stream[Long]): LongStream = - boxed.mapToLong(new java.util.function.ToLongFunction[Long]{ def applyAsLong(d: Long) = d }) - } - - implicit val primitiveUnboxLongStream2: PrimitiveStreamUnboxer[java.lang.Long, LongStream] = - primitiveUnboxLongStream.asInstanceOf[PrimitiveStreamUnboxer[java.lang.Long, LongStream]] - - implicit final class RichDoubleStream(private val stream: DoubleStream) extends AnyVal { - def accumulate = stream.collect(DoubleAccumulator.supplier, DoubleAccumulator.adder, DoubleAccumulator.merger) - - def toScala[Coll[_]](implicit factory: collection.Factory[Double, Coll[Double]]): Coll[Double] = { - if (stream.isParallel) accumulate.to[Coll](factory) - else { - val b = factory.newBuilder - stream.forEachOrdered(new java.util.function.DoubleConsumer{ def accept(d: Double): Unit = { b += d } }) - b.result() - } - } - } - - implicit final class RichIntStream(private val stream: IntStream) extends AnyVal { - def accumulate = stream.collect(IntAccumulator.supplier, IntAccumulator.adder, IntAccumulator.merger) - - def toScala[Coll[_]](implicit factory: collection.Factory[Int, Coll[Int]]): Coll[Int] = { - if (stream.isParallel) accumulate.to[Coll](factory) - else { - val b = factory.newBuilder - stream.forEachOrdered(new java.util.function.IntConsumer{ def accept(d: Int): Unit = { b += d } }) - b.result() - } - } - } - - implicit final class RichLongStream(private val stream: LongStream) extends AnyVal { - def accumulate = stream.collect(LongAccumulator.supplier, LongAccumulator.adder, LongAccumulator.merger) - - def toScala[Coll[_]](implicit factory: collection.Factory[Long, Coll[Long]]): Coll[Long] = { - if (stream.isParallel) accumulate.to[Coll](factory) - else { - val b = factory.newBuilder - stream.forEachOrdered(new java.util.function.LongConsumer{ def accept(d: Long): Unit = { b += d } }) - b.result() - } - } - } - - implicit val accumulateDoubleStepper: AccumulatesFromStepper[Double, DoubleAccumulator] = - new AccumulatesFromStepper[Double, DoubleAccumulator] { - def apply(stepper: Stepper[Double]) = { - val a = new DoubleAccumulator - while (stepper.hasStep) a += stepper.nextStep() - a - } - } - - implicit val accumulateIntStepper: AccumulatesFromStepper[Int, IntAccumulator] = - new AccumulatesFromStepper[Int, IntAccumulator] { - def apply(stepper: Stepper[Int]) = { - val a = new IntAccumulator - while (stepper.hasStep) a += stepper.nextStep() - a - } - } - - implicit val accumulateLongStepper: AccumulatesFromStepper[Long, LongAccumulator] = - new AccumulatesFromStepper[Long, LongAccumulator] { - def apply(stepper: Stepper[Long]) = { - val a = new LongAccumulator - while (stepper.hasStep) a += stepper.nextStep() - a - } - } + implicit def richIntStepper(s: Stepper[Int]): StepperExtensions[Int] = new StepperExtensions[Int](s) + implicit def richLongStepper(s: Stepper[Long]): StepperExtensions[Long] = new StepperExtensions[Long](s) + implicit def richDoubleStepper(s: Stepper[Double]): StepperExtensions[Double] = new StepperExtensions[Double](s) } diff --git a/src/main/scala/scala/compat/java8/collectionImpl/Accumulator.scala b/src/main/scala/scala/compat/java8/collectionImpl/Accumulator.scala deleted file mode 100644 index c7642eb..0000000 --- a/src/main/scala/scala/compat/java8/collectionImpl/Accumulator.scala +++ /dev/null @@ -1,361 +0,0 @@ -/* - * 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.compat.java8.collectionImpl - -import scala.language.higherKinds - -/** An `Accumulator` is a low-level collection specialized for gathering - * elements in parallel and then joining them in order by merging Accumulators. - * Accumulators can contain more than `Int.MaxValue` elements. - */ -final class Accumulator[A] extends AccumulatorLike[A, Accumulator[A]] { self => - // Elements are added to `current`. Once full, it's added to `history`, and a new `current` is - // created with `nextBlockSize` (which depends on `totalSize`). - // `cumul(i)` is `(0 until i).map(history(_).length)` - private[java8] var current: Array[AnyRef] = Accumulator.emptyAnyRefArray - private[java8] var history: Array[Array[AnyRef]] = Accumulator.emptyAnyRefArrayArray - private[java8] var cumul: Array[Long] = Accumulator.emptyLongArray - - private[java8] def cumulative(i: Int): Long = cumul(i) - - private def expand(): Unit = { - if (index > 0) { - if (hIndex >= history.length) hExpand() - history(hIndex) = current - cumul(hIndex) = (if (hIndex > 0) cumulative(hIndex-1) else 0) + index - hIndex += 1 - } - current = new Array[AnyRef](nextBlockSize) - index = 0 - } - - private def hExpand(): Unit = { - if (hIndex == 0) { - history = new Array[Array[AnyRef]](4) - cumul = new Array[Long](4) - } - else { - history = java.util.Arrays.copyOf(history, history.length << 1) - cumul = java.util.Arrays.copyOf(cumul, cumul.length << 1) - } - } - - /** Appends an element to this `Accumulator`. */ - final def +=(a: A): Unit = { - totalSize += 1 - if (index >= current.length) expand() - current(index) = a.asInstanceOf[AnyRef] - index += 1 - } - - /** Removes all elements from `that` and appends them to this `Accumulator`. */ - final def drain[A1 <: A](that: Accumulator[A1]): Unit = { - var h = 0 - var prev = 0L - var more = true - while (more && h < that.hIndex) { - val n = (that.cumulative(h) - prev).toInt - if (current.length - index >= n) { - System.arraycopy(that.history(h), 0, current, index, n) - prev = that.cumulative(h) - index += n - h += 1 - } - else more = false - } - if (h >= that.hIndex && current.length - index >= that.index) { - if (that.index > 0) System.arraycopy(that.current, 0, current, index, that.index) - index += that.index - } - else { - val slots = (if (index > 0) 1 else 0) + that.hIndex - h - if (hIndex + slots > history.length) { - val n = math.max(4, 1 << (32 - java.lang.Integer.numberOfLeadingZeros(1 + hIndex + slots))) - history = java.util.Arrays.copyOf(history, n) - cumul = java.util.Arrays.copyOf(cumul, n) - } - var pv = (if (hIndex > 0) cumulative(hIndex-1) else 0L) - if (index > 0) { - pv += index - cumul(hIndex) = pv - history(hIndex) = (if (index < (current.length >>> 3) && current.length > 32) java.util.Arrays.copyOf(current, index) else current) - hIndex += 1 - } - while (h < that.hIndex) { - pv += that.cumulative(h) - prev - prev = that.cumulative(h) - cumul(hIndex) = pv - history(hIndex) = that.history(h) - h += 1 - hIndex += 1 - } - index = that.index - current = that.current - } - totalSize += that.totalSize - that.clear - } - - override def clear(): Unit = { - super.clear() - current = Accumulator.emptyAnyRefArray - history = Accumulator.emptyAnyRefArrayArray - cumul = Accumulator.emptyLongArray - } - - /** Retrieves the `ix`th element. */ - final def apply(ix: Long): A = { - if (totalSize - ix <= index || hIndex == 0) current((ix - (totalSize - index)).toInt).asInstanceOf[A] - else { - val w = seekSlot(ix) - history((w >>> 32).toInt)((w & 0xFFFFFFFFL).toInt).asInstanceOf[A] - } - } - - /** Retrieves the `ix`th element, using an `Int` index. */ - final def apply(i: Int): A = apply(i.toLong) - - /** Returns a `Stepper` over the contents of this `Accumulator`*/ - final def stepper: AnyStepper[A] = new AccumulatorStepper[A](this) - - /** Returns an `Iterator` over the contents of this `Accumulator`. */ - final def iterator = stepper.iterator - - /** Returns a `java.util.Spliterator` over the contents of this `Accumulator`*/ - final def spliterator: java.util.Spliterator[A] = stepper.spliterator - - /** Produces a sequential Java 8 Stream over the elements of this `Accumulator`*/ - final def seqStream: java.util.stream.Stream[A] = java.util.stream.StreamSupport.stream(spliterator, false) - - /** Produces a parallel Java 8 Stream over the elements of this `Accumulator`*/ - final def parStream: java.util.stream.Stream[A] = java.util.stream.StreamSupport.stream(spliterator, true) - - /** Copies the elements in this `Accumulator` into an `Array` */ - final def toArray(implicit tag: reflect.ClassTag[A]) = { - if (totalSize > Int.MaxValue) throw new IllegalArgumentException("Too many elements accumulated for an array: "+totalSize.toString) - val a = new Array[A](totalSize.toInt) - var j = 0 - var h = 0 - var pv = 0L - while (h < hIndex) { - val x = history(h) - val n = cumulative(h) - pv - pv = cumulative(h) - var i = 0 - while (i < n) { - a(j) = x(i).asInstanceOf[A] - i += 1 - j += 1 - } - h += 1 - } - var i = 0 - while (i < index) { - a(j) = current(i).asInstanceOf[A] - i += 1 - j += 1 - } - a - } - - /** Copies the elements in this `Accumulator` to a `List` */ - final def toList: List[A] = { - var ans: List[A] = Nil - var i = index - 1 - while (i >= 0) { - ans = current(i).asInstanceOf[A] :: ans - i -= 1 - } - var h = hIndex - 1 - while (h >= 0) { - val a = history(h) - i = (cumulative(h) - (if (h == 0) 0L else cumulative(h-1))).toInt - 1 - while (i >= 0) { - ans = a(i).asInstanceOf[A] :: ans - i -= 1 - } - h -= 1 - } - ans - } - - /** Copies the elements in this `Accumulator` to a specified collection. - * Usage example: `acc.to[Vector]` - */ - final def to[Coll[_]](implicit factory: collection.Factory[A, Coll[A]]): Coll[A] = { - if (totalSize > Int.MaxValue) throw new IllegalArgumentException("Too many elements accumulated for a Scala collection: "+totalSize.toString) - val b = factory.newBuilder - b.sizeHint(totalSize.toInt) - var h = 0 - var pv = 0L - while (h < hIndex) { - val x = history(h) - val n = cumulative(h) - pv - pv = cumulative(h) - var i = 0 - while (i < n) { - b += x(i).asInstanceOf[A] - i += 1 - } - h += 1 - } - var i = 0 - while (i < index) { - b += current(i).asInstanceOf[A] - i += 1 - } - b.result - } -} - -object Accumulator { - private val emptyAnyRefArray = new Array[AnyRef](0) - private val emptyAnyRefArrayArray = new Array[Array[AnyRef]](0) - private val emptyLongArray = new Array[Long](0) - - /** A `Supplier` of `Accumulator`s, suitable for use with `java.util.stream.Stream`'s `collect` method. */ - def supplier[A] = new java.util.function.Supplier[Accumulator[A]]{ def get: Accumulator[A] = new Accumulator[A] } - - /** A `BiConsumer` that adds an element to an `Accumulator`, suitable for use with `java.util.stream.Stream`'s `collect` method. */ - def adder[A] = new java.util.function.BiConsumer[Accumulator[A], A]{ def accept(ac: Accumulator[A], a: A): Unit = { ac += a } } - - /** A `BiConsumer` that merges `Accumulator`s, suitable for use with `java.util.stream.Stream`'s `collect` method. */ - def merger[A] = new java.util.function.BiConsumer[Accumulator[A], Accumulator[A]]{ def accept(a1: Accumulator[A], a2: Accumulator[A]): Unit = { a1 drain a2 } } - - /** Builds an `Accumulator` from any `IterableOnce` */ - def from[A](source: IterableOnce[A]) = { - val a = new Accumulator[A] - source.iterator.foreach(a += _) - a - } -} - -private[java8] class AccumulatorStepper[A](private val acc: Accumulator[A]) extends AnyStepper[A] { - import java.util.Spliterator._ - - private var h = 0 - private var i = 0 - private var a = if (acc.hIndex > 0) acc.history(0) else acc.current - private var n = if (acc.hIndex > 0) acc.cumulative(0) else acc.index - private var N = acc.totalSize - - private def duplicateSelf(limit: Long): AccumulatorStepper[A] = { - val ans = new AccumulatorStepper(acc) - ans.h = h - ans.i = i - ans.a = a - ans.n = n - ans.N = limit - ans - } - - private def loadMore(): Unit = { - h += 1 - if (h < acc.hIndex) { a = acc.history(h); n = acc.cumulative(h) - acc.cumulative(h-1) } - else { a = acc.current; n = acc.index } - i = 0 - } - - def characteristics = ORDERED | SIZED | SUBSIZED - - def estimateSize = N - - def hasNext = N > 0 - - def next(): A = - if (N <= 0) throw new NoSuchElementException("Next in empty Stepper") - else { - if (i >= n) loadMore() - val ans = a(i).asInstanceOf[A] - i += 1 - N -= 1 - ans - } - - // Overidden for efficiency - override def tryStep(f: A => Unit): Boolean = - if (N <= 0) false - else { - if (i >= n) loadMore() - f(a(i).asInstanceOf[A]) - i += 1 - N -= 1 - true - } - - // Overidden for efficiency - override def tryAdvance(f: java.util.function.Consumer[_ >: A]): Boolean = - if (N <= 0) false - else { - if (i >= n) loadMore() - f.accept(a(i).asInstanceOf[A]) - i += 1 - N -= 1 - true - } - - // Overridden for efficiency - override def foreach(f: A => Unit): Unit = { - while (N > 0) { - if (i >= n) loadMore() - val i0 = i - if ((n-i) > N) n = i + N.toInt - while (i < n) { - f(a(i).asInstanceOf[A]) - i += 1 - } - N -= (n - i0) - } - } - - // Overridden for efficiency - override def forEachRemaining(f: java.util.function.Consumer[_ >: A]): Unit = { - while (N > 0) { - if (i >= n) loadMore() - val i0 = i - if ((n-i) > N) n = i + N.toInt - while (i < n) { - f.accept(a(i).asInstanceOf[A]) - i += 1 - } - N -= (n - i0) - } - } - - def substep(): AnyStepper[A] = - if (N <= 1) null - else { - val half = (N >> 1) - val M = (if (h <= 0) 0L else acc.cumulative(h-1)) + i - val R = M + half - val ans = duplicateSelf(half) - if (h < acc.hIndex) { - val w = acc.seekSlot(R) - h = (w >>> 32).toInt - if (h < acc.hIndex) { - a = acc.history(h) - n = acc.cumulative(h) - (if (h > 0) acc.cumulative(h-1) else 0) - } - else { - a = acc.current - n = acc.index - } - i = (w & 0xFFFFFFFFL).toInt - } - else i += half.toInt - N -= half - ans - } - - override def toString = s"$h $i ${a.mkString("{",",","}")} $n $N" -} diff --git a/src/main/scala/scala/compat/java8/collectionImpl/AccumulatorLike.scala b/src/main/scala/scala/compat/java8/collectionImpl/AccumulatorLike.scala deleted file mode 100644 index f7f3143..0000000 --- a/src/main/scala/scala/compat/java8/collectionImpl/AccumulatorLike.scala +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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.compat.java8.collectionImpl - -/** An accumulator that works with Java 8 streams; it accepts elements of type `A`, - * is itself an `AC`. Accumulators can handle more than `Int.MaxValue` elements. - */ -trait AccumulatorLike[@specialized(Double, Int, Long) A, AC] { - private[java8] var index: Int = 0 - private[java8] var hIndex: Int = 0 - private[java8] var totalSize: Long = 0L - private[java8] def cumulative(i: Int): Long - - private[java8] def nextBlockSize: Int = { - if (totalSize < 32) 16 - else if (totalSize <= Int.MaxValue) { - val bit = (64 - java.lang.Long.numberOfLeadingZeros(totalSize)) - 1 << (bit - (bit >> 2)) - } - else 1 << 24 - } - - /** Size of the accumulated collection, as a `Long` */ - final def size: Long = totalSize - - /** Remove all accumulated elements from this accumulator. */ - def clear(): Unit = { - index = 0 - hIndex = 0 - totalSize = 0L - } - - private[java8] def seekSlot(ix: Long): Long = { - var lo = -1 - var hi = hIndex - while (lo + 1 < hi) { - val m = (lo + hi) >>> 1 // Shift allows division-as-unsigned, prevents overflow - if (cumulative(m) > ix) hi = m - else lo = m - } - (hi.toLong << 32) | (if (hi==0) ix else (ix - cumulative(hi-1))).toInt - } -} diff --git a/src/main/scala/scala/compat/java8/collectionImpl/DoubleAccumulator.scala b/src/main/scala/scala/compat/java8/collectionImpl/DoubleAccumulator.scala deleted file mode 100644 index b40b997..0000000 --- a/src/main/scala/scala/compat/java8/collectionImpl/DoubleAccumulator.scala +++ /dev/null @@ -1,353 +0,0 @@ -/* - * 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.compat.java8.collectionImpl - -import scala.language.higherKinds - -/** A `DoubleAccumulator` is a low-level collection specialized for gathering - * elements in parallel and then joining them in order by merging them. - * This is a manually specialized variant of `Accumulator` with no actual - * subclassing relationship with `Accumulator`. - */ -final class DoubleAccumulator extends AccumulatorLike[Double, DoubleAccumulator] { self => - private[java8] var current: Array[Double] = DoubleAccumulator.emptyDoubleArray - private[java8] var history: Array[Array[Double]] = DoubleAccumulator.emptyDoubleArrayArray - - private[java8] def cumulative(i: Int) = { val x = history(i); x(x.length-1).toLong } - - private def expand(): Unit = { - if (index > 0) { - current(current.length-1) = (if (hIndex > 0) { val x = history(hIndex-1); x(x.length-1) } else 0) + index - if (hIndex >= history.length) hExpand() - history(hIndex) = current - hIndex += 1 - } - current = new Array[Double](nextBlockSize+1) - index = 0 - } - - private def hExpand(): Unit = { - if (hIndex == 0) history = new Array[Array[Double]](4) - else history = java.util.Arrays.copyOf(history, history.length << 1) - } - - /** Appends an element to this `DoubleAccumulator`. */ - final def +=(a: Double): Unit = { - totalSize += 1 - if (index+1 >= current.length) expand() - current(index) = a - index += 1 - } - - /** Removes all elements from `that` and appends them to this `DoubleAccumulator`. */ - final def drain(that: DoubleAccumulator): Unit = { - var h = 0 - var prev = 0L - var more = true - while (more && h < that.hIndex) { - val cuml = that.cumulative(h) - val n = (cuml - prev).toInt - if (current.length - index - 1 >= n) { - System.arraycopy(that.history(h), 0, current, index, n) - prev = cuml - index += n - h += 1 - } - else more = false - } - if (h >= that.hIndex && current.length - index - 1>= that.index) { - if (that.index > 0) System.arraycopy(that.current, 0, current, index, that.index) - index += that.index - } - else { - val slots = (if (index > 0) 1 else 0) + that.hIndex - h - if (hIndex + slots > history.length) { - val n = math.max(4, 1 << (32 - java.lang.Integer.numberOfLeadingZeros(1 + hIndex + slots))) - history = java.util.Arrays.copyOf(history, n) - } - var pv = (if (hIndex > 0) cumulative(hIndex-1) else 0L) - if (index > 0) { - val x = - if (index < (current.length >>> 3) && current.length - 1 > 32) { - val ans = java.util.Arrays.copyOf(current, index + 1) - ans(ans.length - 1) = current(current.length - 1) - ans - } - else current - pv = pv + index - x(x.length - 1) = pv - history(hIndex) = x - hIndex += 1 - } - while (h < that.hIndex) { - val cuml = that.cumulative(h) - pv = pv + cuml - prev - prev = cuml - val x = that.history(h) - x(x.length - 1) = pv - history(hIndex) = x - h += 1 - hIndex += 1 - } - index = that.index - current = that.current - } - totalSize += that.totalSize - that.clear - } - - override def clear(): Unit = { - super.clear() - current = DoubleAccumulator.emptyDoubleArray - history = DoubleAccumulator.emptyDoubleArrayArray - } - - /** Retrieves the `ix`th element. */ - final def apply(ix: Long): Double = { - if (totalSize - ix <= index || hIndex == 0) current((ix - (totalSize - index)).toInt) - else { - val w = seekSlot(ix) - history((w >>> 32).toInt)((w & 0xFFFFFFFFL).toInt) - } - } - - /** Retrieves the `ix`th element, using an `Int` index. */ - final def apply(i: Int): Double = apply(i.toLong) - - /** Returns a `DoubleStepper` over the contents of this `DoubleAccumulator`. */ - final def stepper: DoubleStepper = new DoubleAccumulatorStepper(this) - - /** Returns an `Iterator` over the contents of this `DoubleAccumulator`. The `Iterator` is not specialized. */ - final def iterator = stepper.iterator - - /** Returns a `java.util.Spliterator.OfDouble` over the contents of this `DoubleAccumulator`*/ - final def spliterator: java.util.Spliterator.OfDouble = stepper - - /** Produces a sequential Java 8 `DoubleStream` over the elements of this `DoubleAccumulator`*/ - final def seqStream: java.util.stream.DoubleStream = java.util.stream.StreamSupport.doubleStream(spliterator, false) - - /** Produces a parallel Java 8 `DoubleStream` over the elements of this `DoubleAccumulator`*/ - final def parStream: java.util.stream.DoubleStream = java.util.stream.StreamSupport.doubleStream(spliterator, true) - - /** Copies the elements in this `DoubleAccumulator` into an `Array[Double]` */ - final def toArray = { - if (totalSize > Int.MaxValue) throw new IllegalArgumentException("Too many elements accumulated for an array: "+totalSize.toString) - val a = new Array[Double](totalSize.toInt) - var j = 0 - var h = 0 - var pv = 0L - while (h < hIndex) { - val x = history(h) - val cuml = x(x.length-1).toLong - val n = (cuml - pv).toInt - pv = cuml - System.arraycopy(x, 0, a, j, n) - j += n - h += 1 - } - System.arraycopy(current, 0, a, j, index) - j += index - a - } - - /** Copies the elements in this `DoubleAccumulator` to a `List` */ - final def toList: List[Double] = { - var ans: List[Double] = Nil - var i = index - 1 - while (i >= 0) { - ans = current(i) :: ans - i -= 1 - } - var h = hIndex - 1 - while (h >= 0) { - val a = history(h) - i = (cumulative(h) - (if (h == 0) 0L else cumulative(h-1))).toInt - 1 - while (i >= 0) { - ans = a(i) :: ans - i -= 1 - } - h -= 1 - } - ans - } - - /** Copies the elements in this `DoubleAccumulator` to a specified collection. - * Note that the target collection is not specialized. - * Usage example: `acc.to[Vector]` - */ - final def to[Coll[_]](implicit factory: collection.Factory[Double, Coll[Double]]): Coll[Double] = { - if (totalSize > Int.MaxValue) throw new IllegalArgumentException("Too many elements accumulated for a Scala collection: "+totalSize.toString) - val b = factory.newBuilder - b.sizeHint(totalSize.toInt) - var h = 0 - var pv = 0L - while (h < hIndex) { - val x = history(h) - val n = cumulative(h) - pv - pv = cumulative(h) - var i = 0 - while (i < n) { - b += x(i) - i += 1 - } - h += 1 - } - var i = 0 - while (i < index) { - b += current(i) - i += 1 - } - b.result - } -} -object DoubleAccumulator { - private val emptyDoubleArray = new Array[Double](0) - private val emptyDoubleArrayArray = new Array[Array[Double]](0) - - /** A `Supplier` of `DoubleAccumulator`s, suitable for use with `java.util.stream.DoubleStream`'s `collect` method. Suitable for `Stream[Double]` also. */ - def supplier = new java.util.function.Supplier[DoubleAccumulator]{ def get: DoubleAccumulator = new DoubleAccumulator } - - /** A `BiConsumer` that adds an element to an `Accumulator`, suitable for use with `java.util.stream.DoubleStream`'s `collect` method. */ - def adder = new java.util.function.ObjDoubleConsumer[DoubleAccumulator]{ def accept(ac: DoubleAccumulator, a: Double): Unit = { ac += a } } - - /** A `BiConsumer` that adds a boxed `Double` to an `DoubleAccumulator`, suitable for use with `java.util.stream.Stream`'s `collect` method. */ - def boxedAdder = new java.util.function.BiConsumer[DoubleAccumulator, Double]{ def accept(ac: DoubleAccumulator, a: Double): Unit = { ac += a } } - - /** A `BiConsumer` that merges `DoubleAccumulator`s, suitable for use with `java.util.stream.DoubleStream`'s `collect` method. Suitable for `Stream[Double]` also. */ - def merger = new java.util.function.BiConsumer[DoubleAccumulator, DoubleAccumulator]{ def accept(a1: DoubleAccumulator, a2: DoubleAccumulator): Unit = { a1 drain a2 } } - - /** Builds a `DoubleAccumulator` from any `Double`-valued `IterableOnce` */ - def from[A](source: IterableOnce[Double]) = { - val a = new DoubleAccumulator - source.iterator.foreach(a += _) - a - } -} - -private[java8] class DoubleAccumulatorStepper(private val acc: DoubleAccumulator) extends DoubleStepper { - import java.util.Spliterator._ - - private var h = 0 - private var i = 0 - private var a = if (acc.hIndex > 0) acc.history(0) else acc.current - private var n = if (acc.hIndex > 0) acc.cumulative(0) else acc.index - private var N = acc.totalSize - - private def duplicateSelf(limit: Long): DoubleAccumulatorStepper = { - val ans = new DoubleAccumulatorStepper(acc) - ans.h = h - ans.i = i - ans.a = a - ans.n = n - ans.N = limit - ans - } - - private def loadMore(): Unit = { - h += 1 - if (h < acc.hIndex) { a = acc.history(h); n = acc.cumulative(h) - acc.cumulative(h-1) } - else { a = acc.current; n = acc.index } - i = 0 - } - - def characteristics = ORDERED | SIZED | SUBSIZED | NONNULL - - def estimateSize = N - - def hasNext = N > 0 - - def nextDouble(): Double = - if (n <= 0) throw new NoSuchElementException("next on empty Stepper") - else { - if (i >= n) loadMore() - val ans = a(i) - i += 1 - N -= 1 - ans - } - - // Overridden for efficiency - override def tryStep(f: Double => Unit): Boolean = - if (N <= 0) false - else { - if (i >= n) loadMore() - f(a(i)) - i += 1 - N -= 1 - true - } - - // Overridden for efficiency - override def tryAdvance(f: java.util.function.DoubleConsumer): Boolean = - if (N <= 0) false - else { - if (i >= n) loadMore() - f.accept(a(i)) - i += 1 - N -= 1 - true - } - - // Overridden for efficiency - override def foreach(f: Double => Unit): Unit = { - while (N > 0) { - if (i >= n) loadMore() - val i0 = i - if ((n-i) > N) n = i + N.toInt - while (i < n) { - f(a(i)) - i += 1 - } - N -= (n - i0) - } - } - - // Overridden for efficiency - override def forEachRemaining(f: java.util.function.DoubleConsumer): Unit = { - while (N > 0) { - if (i >= n) loadMore() - val i0 = i - if ((n-i) > N) n = i + N.toInt - while (i < n) { - f.accept(a(i)) - i += 1 - } - N -= (n - i0) - } - } - - def substep(): DoubleStepper = - if (N <= 1) null - else { - val half = (N >> 1) - val M = (if (h <= 0) 0L else acc.cumulative(h-1)) + i - val R = M + half - val ans = duplicateSelf(half) - if (h < acc.hIndex) { - val w = acc.seekSlot(R) - h = (w >>> 32).toInt - if (h < acc.hIndex) { - a = acc.history(h) - n = acc.cumulative(h) - (if (h > 0) acc.cumulative(h-1) else 0) - } - else { - a = acc.current - n = acc.index - } - i = (w & 0xFFFFFFFFL).toInt - } - else i += half.toInt - N -= half - ans - } -} diff --git a/src/main/scala/scala/compat/java8/collectionImpl/IntAccumulator.scala b/src/main/scala/scala/compat/java8/collectionImpl/IntAccumulator.scala deleted file mode 100644 index 2100bb6..0000000 --- a/src/main/scala/scala/compat/java8/collectionImpl/IntAccumulator.scala +++ /dev/null @@ -1,360 +0,0 @@ -/* - * 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.compat.java8.collectionImpl - -import scala.language.higherKinds - -/** A `IntAccumulator` is a low-level collection specialized for gathering - * elements in parallel and then joining them in order by merging them. - * This is a manually specialized variant of `Accumulator` with no actual - * subclassing relationship with `Accumulator`. - */ -final class IntAccumulator extends AccumulatorLike[Int, IntAccumulator] { self => - private[java8] var current: Array[Int] = IntAccumulator.emptyIntArray - private[java8] var history: Array[Array[Int]] = IntAccumulator.emptyIntArrayArray - - private[java8] def cumulative(i: Int) = { val x = history(i); x(x.length-2).toLong << 32 | (x(x.length-1)&0xFFFFFFFFL) } - - private def expand(): Unit = { - if (index > 0) { - val cuml = (if (hIndex > 0) cumulative(hIndex-1) else 0) + index - current(current.length-2) = (cuml >>> 32).toInt - current(current.length-1) = (cuml & 0xFFFFFFFFL).toInt - if (hIndex >= history.length) hExpand() - history(hIndex) = current - hIndex += 1 - } - current = new Array[Int](nextBlockSize+1) - index = 0 - } - - private def hExpand(): Unit = { - if (hIndex == 0) history = new Array[Array[Int]](4) - else history = java.util.Arrays.copyOf(history, history.length << 1) - } - - /** Appends an element to this `IntAccumulator`. */ - final def +=(a: Int): Unit = { - totalSize += 1 - if (index+2 >= current.length) expand() - current(index) = a - index += 1 - } - - /** Removes all elements from `that` and appends them to this `IntAccumulator`. */ - final def drain(that: IntAccumulator): Unit = { - var h = 0 - var prev = 0L - var more = true - while (more && h < that.hIndex) { - val cuml = that.cumulative(h) - val n = (cuml - prev).toInt - if (current.length - index - 2 >= n) { - System.arraycopy(that.history(h), 0, current, index, n) - prev = cuml - index += n - h += 1 - } - else more = false - } - if (h >= that.hIndex && current.length - index - 2 >= that.index) { - if (that.index > 0) System.arraycopy(that.current, 0, current, index, that.index) - index += that.index - } - else { - val slots = (if (index > 0) 1 else 0) + that.hIndex - h - if (hIndex + slots > history.length) { - val n = math.max(4, 1 << (32 - java.lang.Integer.numberOfLeadingZeros(1 + hIndex + slots))) - history = java.util.Arrays.copyOf(history, n) - } - var pv = (if (hIndex > 0) cumulative(hIndex-1) else 0L) - if (index > 0) { - val x = - if (index < (current.length >>> 3) && current.length - 1 > 32) { - val ans = java.util.Arrays.copyOf(current, index + 2) - ans(ans.length - 2) = current(current.length - 2) - ans(ans.length - 1) = current(current.length - 1) - ans - } - else current - pv = pv + index - x(x.length - 2) = (pv >>> 32).toInt - x(x.length - 1) = (pv & 0xFFFFFFFFL).toInt - history(hIndex) = x - hIndex += 1 - } - while (h < that.hIndex) { - val cuml = that.cumulative(h) - pv = pv + cuml - prev - prev = cuml - val x = that.history(h) - x(x.length - 2) = (pv >>> 32).toInt - x(x.length - 1) = (pv & 0xFFFFFFFFL).toInt - history(hIndex) = x - h += 1 - hIndex += 1 - } - index = that.index - current = that.current - } - totalSize += that.totalSize - that.clear - } - - override def clear(): Unit = { - super.clear() - current = IntAccumulator.emptyIntArray - history = IntAccumulator.emptyIntArrayArray - } - - /** Retrieves the `ix`th element. */ - final def apply(ix: Long): Int = { - if (totalSize - ix <= index || hIndex == 0) current((ix - (totalSize - index)).toInt) - else { - val w = seekSlot(ix) - history((w >>> 32).toInt)((w & 0xFFFFFFFFL).toInt) - } - } - - /** Retrieves the `ix`th element, using an `Int` index. */ - final def apply(i: Int): Int = apply(i.toLong) - - /** Returns an `IntStepper` over the contents of this `IntAccumulator` */ - final def stepper: IntStepper = new IntAccumulatorStepper(this) - - /** Returns an `Iterator` over the contents of this `IntAccumulator`. The `Iterator` is not specialized. */ - final def iterator = stepper.iterator - - /** Returns a `java.util.Spliterator.OfInt` over the contents of this `IntAccumulator`*/ - final def spliterator: java.util.Spliterator.OfInt = stepper - - /** Produces a sequential Java 8 `IntStream` over the elements of this `IntAccumulator`*/ - final def seqStream: java.util.stream.IntStream = java.util.stream.StreamSupport.intStream(spliterator, false) - - /** Produces a parallel Java 8 `IntStream` over the elements of this `IntAccumulator`*/ - final def parStream: java.util.stream.IntStream = java.util.stream.StreamSupport.intStream(spliterator, true) - - /** Copies the elements in this `IntAccumulator` into an `Array[Int]` */ - final def toArray = { - if (totalSize > Int.MaxValue) throw new IllegalArgumentException("Too many elements accumulated for an array: "+totalSize.toString) - val a = new Array[Int](totalSize.toInt) - var j = 0 - var h = 0 - var pv = 0L - while (h < hIndex) { - val x = history(h) - val cuml = cumulative(h) - val n = (cuml - pv).toInt - pv = cuml - System.arraycopy(x, 0, a, j, n) - j += n - h += 1 - } - System.arraycopy(current, 0, a, j, index) - j += index - a - } - - /** Copies the elements in this `IntAccumulator` to a `List` */ - final def toList: List[Int] = { - var ans: List[Int] = Nil - var i = index - 1 - while (i >= 0) { - ans = current(i) :: ans - i -= 1 - } - var h = hIndex - 1 - while (h >= 0) { - val a = history(h) - i = (cumulative(h) - (if (h == 0) 0L else cumulative(h-1))).toInt - 1 - while (i >= 0) { - ans = a(i) :: ans - i -= 1 - } - h -= 1 - } - ans - } - - /** Copies the elements in this `IntAccumulator` to a specified collection. - * Note that the target collection is not specialized. - * Usage example: `acc.to[Vector]` - */ - final def to[Coll[_]](implicit factory: collection.Factory[Int, Coll[Int]]): Coll[Int] = { - if (totalSize > Int.MaxValue) throw new IllegalArgumentException("Too many elements accumulated for a Scala collection: "+totalSize.toString) - val b = factory.newBuilder - b.sizeHint(totalSize.toInt) - var h = 0 - var pv = 0L - while (h < hIndex) { - val x = history(h) - val cuml = cumulative(h) - val n = cuml - pv - pv = cuml - var i = 0 - while (i < n) { - b += x(i) - i += 1 - } - h += 1 - } - var i = 0 - while (i < index) { - b += current(i) - i += 1 - } - b.result - } -} - -object IntAccumulator { - private val emptyIntArray = new Array[Int](0) - private val emptyIntArrayArray = new Array[Array[Int]](0) - - /** A `Supplier` of `IntAccumulator`s, suitable for use with `java.util.stream.IntStream`'s `collect` method. Suitable for `Stream[Int]` also. */ - def supplier = new java.util.function.Supplier[IntAccumulator]{ def get: IntAccumulator = new IntAccumulator } - - /** A `BiConsumer` that adds an element to an `Accumulator`, suitable for use with `java.util.stream.IntStream`'s `collect` method. */ - def adder = new java.util.function.ObjIntConsumer[IntAccumulator]{ def accept(ac: IntAccumulator, a: Int): Unit = { ac += a } } - - /** A `BiConsumer` that adds a boxed `Int` to an `IntAccumulator`, suitable for use with `java.util.stream.Stream`'s `collect` method. */ - def boxedAdder = new java.util.function.BiConsumer[IntAccumulator, Int]{ def accept(ac: IntAccumulator, a: Int): Unit = { ac += a } } - - /** A `BiConsumer` that merges `IntAccumulator`s, suitable for use with `java.util.stream.IntStream`'s `collect` method. Suitable for `Stream[Int]` also. */ - def merger = new java.util.function.BiConsumer[IntAccumulator, IntAccumulator]{ def accept(a1: IntAccumulator, a2: IntAccumulator): Unit = { a1 drain a2 } } - - /** Builds an `IntAccumulator` from any `Int`-valued `IterableOnce` */ - def from[A](source: IterableOnce[Int]) = { - val a = new IntAccumulator - source.iterator.foreach(a += _) - a - } -} - -private[java8] class IntAccumulatorStepper(private val acc: IntAccumulator) extends IntStepper { - import java.util.Spliterator._ - - private var h = 0 - private var i = 0 - private var a = if (acc.hIndex > 0) acc.history(0) else acc.current - private var n = if (acc.hIndex > 0) acc.cumulative(0) else acc.index - private var N = acc.totalSize - - private def duplicateSelf(limit: Long): IntAccumulatorStepper = { - val ans = new IntAccumulatorStepper(acc) - ans.h = h - ans.i = i - ans.a = a - ans.n = n - ans.N = limit - ans - } - - private def loadMore(): Unit = { - h += 1 - if (h < acc.hIndex) { a = acc.history(h); n = acc.cumulative(h) - acc.cumulative(h-1) } - else { a = acc.current; n = acc.index } - i = 0 - } - - def characteristics = ORDERED | SIZED | SUBSIZED | NONNULL - - def estimateSize = N - - def hasNext = N > 0 - - def nextInt(): Int = - if (N <= 0) throw new NoSuchElementException("next on empty Stepper") - else { - if (i >= n) loadMore() - val ans = a(i) - i += 1 - N -= 1 - ans - } - - // Overridden for efficiency - override def tryStep(f: Int => Unit): Boolean = - if (N <= 0) false - else { - if (i >= n) loadMore() - f(a(i)) - i += 1 - N -= 1 - true - } - - // Overridden for efficiency - override def tryAdvance(f: java.util.function.IntConsumer): Boolean = - if (N <= 0) false - else { - if (i >= n) loadMore() - f.accept(a(i)) - i += 1 - N -= 1 - true - } - - // Overridden for efficiency - override def foreach(f: Int => Unit): Unit = { - while (N > 0) { - if (i >= n) loadMore() - val i0 = i - if ((n-i) > N) n = i + N.toInt - while (i < n) { - f(a(i)) - i += 1 - } - N -= (n - i0) - } - } - - // Overridden for efficiency - override def forEachRemaining(f: java.util.function.IntConsumer): Unit = { - while (N > 0) { - if (i >= n) loadMore() - val i0 = i - if ((n-i) > N) n = i + N.toInt - while (i < n) { - f.accept(a(i)) - i += 1 - } - N -= (n - i0) - } - } - - def substep(): IntStepper = - if (N <= 1) null - else { - val half = (N >> 1) - val M = (if (h <= 0) 0L else acc.cumulative(h-1)) + i - val R = M + half - val ans = duplicateSelf(half) - if (h < acc.hIndex) { - val w = acc.seekSlot(R) - h = (w >>> 32).toInt - if (h < acc.hIndex) { - a = acc.history(h) - n = acc.cumulative(h) - (if (h > 0) acc.cumulative(h-1) else 0) - } - else { - a = acc.current - n = acc.index - } - i = (w & 0xFFFFFFFFL).toInt - } - else i += half.toInt - N -= half - ans - } -} diff --git a/src/main/scala/scala/compat/java8/collectionImpl/LongAccumulator.scala b/src/main/scala/scala/compat/java8/collectionImpl/LongAccumulator.scala deleted file mode 100644 index 978fba3..0000000 --- a/src/main/scala/scala/compat/java8/collectionImpl/LongAccumulator.scala +++ /dev/null @@ -1,354 +0,0 @@ -/* - * 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.compat.java8.collectionImpl - -import scala.language.higherKinds - -/** A `LongAccumulator` is a low-level collection specialized for gathering - * elements in parallel and then joining them in order by merging them. - * This is a manually specialized variant of `Accumulator` with no actual - * subclassing relationship with `Accumulator`. - */ -final class LongAccumulator extends AccumulatorLike[Long, LongAccumulator] { self => - private[java8] var current: Array[Long] = LongAccumulator.emptyLongArray - private[java8] var history: Array[Array[Long]] = LongAccumulator.emptyLongArrayArray - - private[java8] def cumulative(i: Int) = { val x = history(i); x(x.length-1) } - - private def expand(): Unit = { - if (index > 0) { - current(current.length-1) = (if (hIndex > 0) { val x = history(hIndex-1); x(x.length-1) } else 0) + index - if (hIndex >= history.length) hExpand() - history(hIndex) = current - hIndex += 1 - } - current = new Array[Long](nextBlockSize+1) - index = 0 - } - - private def hExpand(): Unit = { - if (hIndex == 0) history = new Array[Array[Long]](4) - else history = java.util.Arrays.copyOf(history, history.length << 1) - } - - /** Appends an element to this `LongAccumulator`. */ - final def +=(a: Long): Unit = { - totalSize += 1 - if (index+1 >= current.length) expand() - current(index) = a - index += 1 - } - - /** Removes all elements from `that` and appends them to this `LongAccumulator`. */ - final def drain(that: LongAccumulator): Unit = { - var h = 0 - var prev = 0L - var more = true - while (more && h < that.hIndex) { - val cuml = that.cumulative(h) - val n = (cuml - prev).toInt - if (current.length - index - 1 >= n) { - System.arraycopy(that.history(h), 0, current, index, n) - prev = cuml - index += n - h += 1 - } - else more = false - } - if (h >= that.hIndex && current.length - index - 1>= that.index) { - if (that.index > 0) System.arraycopy(that.current, 0, current, index, that.index) - index += that.index - } - else { - val slots = (if (index > 0) 1 else 0) + that.hIndex - h - if (hIndex + slots > history.length) { - val n = math.max(4, 1 << (32 - java.lang.Integer.numberOfLeadingZeros(1 + hIndex + slots))) - history = java.util.Arrays.copyOf(history, n) - } - var pv = (if (hIndex > 0) cumulative(hIndex-1) else 0L) - if (index > 0) { - val x = - if (index < (current.length >>> 3) && current.length - 1 > 32) { - val ans = java.util.Arrays.copyOf(current, index + 1) - ans(ans.length - 1) = current(current.length - 1) - ans - } - else current - pv = pv + index - x(x.length - 1) = pv - history(hIndex) = x - hIndex += 1 - } - while (h < that.hIndex) { - val cuml = that.cumulative(h) - pv = pv + cuml - prev - prev = cuml - val x = that.history(h) - x(x.length - 1) = pv - history(hIndex) = x - h += 1 - hIndex += 1 - } - index = that.index - current = that.current - } - totalSize += that.totalSize - that.clear - } - - override def clear(): Unit = { - super.clear() - current = LongAccumulator.emptyLongArray - history = LongAccumulator.emptyLongArrayArray - } - - /** Retrieves the `ix`th element. */ - final def apply(ix: Long): Long = { - if (totalSize - ix <= index || hIndex == 0) current((ix - (totalSize - index)).toInt) - else { - val w = seekSlot(ix) - history((w >>> 32).toInt)((w & 0xFFFFFFFFL).toInt) - } - } - - /** Retrieves the `ix`th element, using an `Int` index. */ - final def apply(i: Int): Long = apply(i.toLong) - - /** Returns a `LongStepper` over the contents of this `LongAccumulator`. */ - final def stepper: LongStepper = new LongAccumulatorStepper(this) - - /** Returns an `Iterator` over the contents of this `LongAccumulator`. The `Iterator` is not specialized. */ - final def iterator = stepper.iterator - - /** Returns a `java.util.Spliterator.OfLong` over the contents of this `LongAccumulator`*/ - final def spliterator: java.util.Spliterator.OfLong = stepper - - /** Produces a sequential Java 8 `LongStream` over the elements of this `LongAccumulator`*/ - final def seqStream: java.util.stream.LongStream = java.util.stream.StreamSupport.longStream(spliterator, false) - - /** Produces a parallel Java 8 `LongStream` over the elements of this `LongAccumulator`*/ - final def parStream: java.util.stream.LongStream = java.util.stream.StreamSupport.longStream(spliterator, true) - - /** Copies the elements in this `LongAccumulator` into an `Array[Long]` */ - final def toArray = { - if (totalSize > Int.MaxValue) throw new IllegalArgumentException("Too many elements accumulated for an array: "+totalSize.toString) - val a = new Array[Long](totalSize.toInt) - var j = 0 - var h = 0 - var pv = 0L - while (h < hIndex) { - val x = history(h) - val cuml = x(x.length-1) - val n = (cuml - pv).toInt - pv = cuml - System.arraycopy(x, 0, a, j, n) - j += n - h += 1 - } - System.arraycopy(current, 0, a, j, index) - j += index - a - } - - /** Copies the elements in this `LongAccumulator` to a `List` */ - final def toList: List[Long] = { - var ans: List[Long] = Nil - var i = index - 1 - while (i >= 0) { - ans = current(i) :: ans - i -= 1 - } - var h = hIndex - 1 - while (h >= 0) { - val a = history(h) - i = (cumulative(h) - (if (h == 0) 0L else cumulative(h-1))).toInt - 1 - while (i >= 0) { - ans = a(i) :: ans - i -= 1 - } - h -= 1 - } - ans - } - - /** Copies the elements in this `LongAccumulator` to a specified collection. - * Note that the target collection is not specialized. - * Usage example: `acc.to[Vector]` - */ - final def to[Coll[_]](implicit factory: collection.Factory[Long, Coll[Long]]): Coll[Long] = { - if (totalSize > Int.MaxValue) throw new IllegalArgumentException("Too many elements accumulated for a Scala collection: "+totalSize.toString) - val b = factory.newBuilder - b.sizeHint(totalSize.toInt) - var h = 0 - var pv = 0L - while (h < hIndex) { - val x = history(h) - val n = cumulative(h) - pv - pv = cumulative(h) - var i = 0 - while (i < n) { - b += x(i) - i += 1 - } - h += 1 - } - var i = 0 - while (i < index) { - b += current(i) - i += 1 - } - b.result - } -} - -object LongAccumulator { - private val emptyLongArray = new Array[Long](0) - private val emptyLongArrayArray = new Array[Array[Long]](0) - - /** A `Supplier` of `LongAccumulator`s, suitable for use with `java.util.stream.LongStream`'s `collect` method. Suitable for `Stream[Long]` also. */ - def supplier = new java.util.function.Supplier[LongAccumulator]{ def get: LongAccumulator = new LongAccumulator } - - /** A `BiConsumer` that adds an element to an `Accumulator`, suitable for use with `java.util.stream.LongStream`'s `collect` method. */ - def adder = new java.util.function.ObjLongConsumer[LongAccumulator]{ def accept(ac: LongAccumulator, a: Long): Unit = { ac += a } } - - /** A `BiConsumer` that adds a boxed `Long` to an `LongAccumulator`, suitable for use with `java.util.stream.Stream`'s `collect` method. */ - def boxedAdder = new java.util.function.BiConsumer[LongAccumulator, Long]{ def accept(ac: LongAccumulator, a: Long): Unit = { ac += a } } - - /** A `BiConsumer` that merges `LongAccumulator`s, suitable for use with `java.util.stream.LongStream`'s `collect` method. Suitable for `Stream[Long]` also. */ - def merger = new java.util.function.BiConsumer[LongAccumulator, LongAccumulator]{ def accept(a1: LongAccumulator, a2: LongAccumulator): Unit = { a1 drain a2 } } - - /** Builds a `LongAccumulator` from any `Long`-valued `IterableOnce` */ - def from[A](source: IterableOnce[Long]) = { - val a = new LongAccumulator - source.iterator.foreach(a += _) - a - } -} - -private[java8] class LongAccumulatorStepper(private val acc: LongAccumulator) extends LongStepper { - import java.util.Spliterator._ - - private var h = 0 - private var i = 0 - private var a = if (acc.hIndex > 0) acc.history(0) else acc.current - private var n = if (acc.hIndex > 0) acc.cumulative(0) else acc.index - private var N = acc.totalSize - - private def duplicateSelf(limit: Long): LongAccumulatorStepper = { - val ans = new LongAccumulatorStepper(acc) - ans.h = h - ans.i = i - ans.a = a - ans.n = n - ans.N = limit - ans - } - - private def loadMore(): Unit = { - h += 1 - if (h < acc.hIndex) { a = acc.history(h); n = acc.cumulative(h) - acc.cumulative(h-1) } - else { a = acc.current; n = acc.index } - i = 0 - } - - def characteristics = ORDERED | SIZED | SUBSIZED | NONNULL - - def estimateSize = N - - def hasNext = N > 0 - - def nextLong(): Long = - if (n <= 0) throw new NoSuchElementException("next on empty Stepper") - else { - if (i >= n) loadMore() - val ans = a(i) - i += 1 - N -= 1 - ans - } - - // Overridden for efficiency - override def tryStep(f: Long => Unit): Boolean = - if (N <= 0) false - else { - if (i >= n) loadMore() - f(a(i)) - i += 1 - N -= 1 - true - } - - // Overridden for efficiency - override def tryAdvance(f: java.util.function.LongConsumer): Boolean = - if (N <= 0) false - else { - if (i >= n) loadMore() - f.accept(a(i)) - i += 1 - N -= 1 - true - } - - // Overridden for efficiency - override def foreach(f: Long => Unit): Unit = { - while (N > 0) { - if (i >= n) loadMore() - val i0 = i - if ((n-i) > N) n = i + N.toInt - while (i < n) { - f(a(i)) - i += 1 - } - N -= (n - i0) - } - } - - // Overridden for efficiency - override def forEachRemaining(f: java.util.function.LongConsumer): Unit = { - while (N > 0) { - if (i >= n) loadMore() - val i0 = i - if ((n-i) > N) n = i + N.toInt - while (i < n) { - f.accept(a(i)) - i += 1 - } - N -= (n - i0) - } - } - - def substep(): LongStepper = - if (N <= 1) null - else { - val half = (N >> 1) - val M = (if (h <= 0) 0L else acc.cumulative(h-1)) + i - val R = M + half - val ans = duplicateSelf(half) - if (h < acc.hIndex) { - val w = acc.seekSlot(R) - h = (w >>> 32).toInt - if (h < acc.hIndex) { - a = acc.history(h) - n = acc.cumulative(h) - (if (h > 0) acc.cumulative(h-1) else 0) - } - else { - a = acc.current - n = acc.index - } - i = (w & 0xFFFFFFFFL).toInt - } - else i += half.toInt - N -= half - ans - } -} diff --git a/src/main/scala/scala/compat/java8/collectionImpl/Stepper.scala b/src/main/scala/scala/compat/java8/collectionImpl/Stepper.scala deleted file mode 100644 index 2a35ff5..0000000 --- a/src/main/scala/scala/compat/java8/collectionImpl/Stepper.scala +++ /dev/null @@ -1,641 +0,0 @@ -/* - * 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.compat.java8.collectionImpl - -import scala.language.higherKinds - -import java.util.Spliterator - -/** A Stepper is a specialized collection that can step through its - * contents once. It provides the same test-and-get methods as - * does `Iterator`, named `hasStep` and `nextStep` so they can - * coexist with iterator methods. However, like `Spliterator`, - * steppers provide a `tryStep` method to call a closure if another - * element exists, a `substep()` method to split into pieces, and - * `characteristics` and size-reporting methods that - * implement the subdivision and report what is known about the remaining - * size of the `Stepper`. `Stepper` thus naturally implements both - * `Iterator` and `Spliterator`. - * - * A `Stepper` can present itself as a Spliterator via the `spliterator` - * method, or as a Scala Iterator via the `iterator` method. The `Stepper` - * trait is compatible with both `Spliterator` and Java's generic and - * primitive iterators, so a `Stepper` may already be one or both. - * - * Subtraits `NextStepper` and `TryStepper` fill in the basic capability - * by either implementing `tryStep` in terms of `hasStep` and `nextStep`, - * or vice versa. - * - * Subtraits `AnyStepper`, `DoubleStepper`, `IntStepper`, and `LongStepper` - * implement both the `Stepper` trait and the corresponding Java - * `Spliterator` and `Iterator`/`PrimitiveIterator`. - * - * Example: - * {{{ - * val s = Stepper.of(Vector(1,2,3,4)) - * if (s.hasStep) println(s.nextStep()) // Prints 1 - * println(s.tryStep(i => println(i*i))) // Prints 2, then true - * s.substep.foreach(println) // Prints 3 - * println(s.count(_ > 3)) // Prints 4 - * println(s.hasStep) // Prints `false` - * }}} - */ -trait Stepper[@specialized(Double, Int, Long) A] extends StepperLike[A, Stepper[A]] { - /** Drains the contents of this stepper into an `Accumulator` or specialized variant thereof as appropriate. - * This is a terminal operation. - * - * Note: accumulation will occur sequentially. To accumulate in parallel, use a `Stream` (i.e. `.parStream.accumulate`). - */ - def accumulate[Acc <: AccumulatorLike[A, Acc]](implicit accer: scala.compat.java8.converterImpl.AccumulatesFromStepper[A, Acc]) = accer(this) -} - -/** An (optional) marker trait that indicates that a `Stepper` can call `substep` with - * at worst O(log N) time and space complexity, and that the division is likely to - * be reasonably even. - */ -trait EfficientSubstep {} - -/** Provides functionality for Stepper while keeping track of a more precise type of the collection. - */ -trait StepperLike[@specialized(Double, Int, Long) A, +CC] { self: CC => - /** Characteristics are bit flags that indicate runtime characteristics of this Stepper. - * - * - `Distinct` means that no duplicates exist - * - `Immutable` means that the underlying collection is guaranteed not to change during traversal - * - `NonNull` means that no nulls will be returned during traversal - * - `Sized` means that the collection knows its exact size - * - `SubSized` means that sub-Steppers created with `substep()` will also know their own size. `SubSized` steppers must also be `Sized`. - * - * The Java flags `CONCURRENT` and `SORTED` are not supported; modification of a concurrency-aware underlying collection is not - * guaranteed to be any safer than modification of any generic mutable collection, and if the underlying collection is ordered by - * virtue of sorting, `Stepper` will not keep track of that fact. - */ - def characteristics: Int - - /** Returns the size of the collection, if known exactly, or `-1` if not. */ - def knownSize: Long - - /** `true` if there are more elements to step through, `false` if not. */ - def hasStep: Boolean - - /** The next element traversed by this Stepper. - * `nextStep()` throws an exception if no elements exist, so check `hasStep` immediately prior - * to calling. Note that `tryStep` also consumes an element, so the result of `hasStep` will - * be invalid after `tryStep` is called. - */ - def nextStep(): A - - /** If another element exists, apply `f` to it and return `true`; otherwise, return `false`. */ - def tryStep(f: A => Unit): Boolean - - /** Attempt to split this `Stepper` in half, with the new (returned) copy taking the first half - * of the collection, and this one advancing to cover the second half. If subdivision is not - * possible or not advisable, `substep()` will return `null`. - */ - def substep(): CC - - /** Warns this `Stepper` that it is likely to be used in a parallel context (used for efficiency only) */ - def anticipateParallelism(): this.type = this - - - //// - // Terminal operations (do not produce another Stepper) - //// - - /** Consumes all remaining elements in this `Stepper` and counts how many there are. - * This is a terminal operation, though if `knownSize` is non-negative, it won't actually - * iterate over the elements. - */ - def count(): Long = knownSize match { - case x if x < 0 => var n = 0L; while (hasStep) { nextStep(); n += 1 }; n - case x => x - } - - /** Consumes all remaining elements in this `Stepper` and counts how many satisfy condition `p`. - * This is a terminal operation. - */ - def count(p: A => Boolean): Long = { var n = 0L; while (hasStep) { if (p(nextStep())) n += 1 }; n } - - /** Searches for an element that satisfies condition `p`. If none are found, it returns `false`. - * This is a terminal operation. - */ - def exists(p: A => Boolean): Boolean = { while(hasStep) { if (p(nextStep())) return true }; false } - - /** Searches for an element that satisifes condition `p`, returning it wrapped in `Some` if one is found, or `None` otherwise. - * This is a terminal operation. - */ - def find(p: A => Boolean): Option[A] = { while (hasStep) { val a = nextStep(); if (p(a)) return Some(a) }; None } - - /** Repeatedly applies `op` to propagate an initial value `zero` through all elements of the collection. - * Traversal order is left-to-right. - * This is a terminal operation. - */ - def fold[@specialized(Double, Int, Long) B](zero: B)(op: (B, A) => B) = { var b = zero; while (hasStep) { b = op(b, nextStep()) }; b } - - /** Repeatedly applies `op` to propagate an initial value `zero` through the collection until a condition `p` is met. - * If `p` is never met, the result of the last operation is returned. - * This is a terminal operation. - */ - def foldTo[@specialized(Double, Int, Long) B](zero: B)(op: (B, A) => B)(p: B => Boolean) = { var b = zero; while (!p(b) && hasStep) { b = op(b, nextStep()) }; b } - - /** Applies `f` to every remaining element in the collection. - * This is a terminal operation. - */ - def foreach(f: A => Unit): Unit = { while (hasStep) f(nextStep()) } - - /** Repeatedly merges elements with `op` until only a single element remains. - * Throws an exception if the `Stepper` is empty. - * Merging occurs from left to right. - * This is a terminal operation. - */ - def reduce(op: (A, A) => A): A = { var a = nextStep(); while (hasStep) { a = op(a, nextStep()) }; a } - - - //// - // Operations that convert to another related type - //// - - /** Returns this `Stepper` as a `java.util.Spliterator`. - * This is a terminal operation. - */ - def spliterator: Spliterator[A] - - /** Returns this `Stepper` as a Scala `Iterator`. - * This is a terminal operation. - */ - def iterator: Iterator[A] = new scala.collection.AbstractIterator[A] { - def hasNext = self.hasStep - def next() = self.nextStep() - } - - /** Returns a Scala collection of the type requested. */ - def to[Coll[_]](implicit factory: collection.Factory[A, Coll[A]]): Coll[A] = { - val b = factory.newBuilder - while (hasStep) b += nextStep() - b.result() - } -} - - -/** This trait indicates that a `Stepper` will implement `tryStep` in terms of `hasNext` and `nextStep`. */ -trait NextStepper[@specialized(Double, Int, Long) A] extends Stepper[A] with StepperLike[A, NextStepper[A]] { - def tryStep(f: A => Unit) = if (hasStep) { f(nextStep()); true } else false - def spliterator: Spliterator[A] = new ProxySpliteratorViaNext[A](this) -} -private[collectionImpl] class ProxySpliteratorViaNext[A](underlying: NextStepper[A]) extends Spliterator[A] { - def characteristics = underlying.characteristics - def estimateSize() = underlying.knownSize - def tryAdvance(f: java.util.function.Consumer[_ >: A]): Boolean = if (underlying.hasStep) { f.accept(underlying.nextStep()); true } else false - def trySplit() = underlying.substep() match { case null => null; case x => new ProxySpliteratorViaNext[A](x) } -} - -/** This trait indicates that a `Stepper` will implement `hasNext` and `nextStep` by caching applications of `tryStep`. - * Subclasses must implement `tryUncached` instead of `tryStep`, and should leave it protected, and must implement - * `knownUncachedSize` instead of `knownSize`. For speed, `foreachUncached` may also be overridden. It is recommended - * that all of the `Uncached` methods be left protected. - */ -trait TryStepper[@specialized(Double, Int, Long) A] extends Stepper[A] with StepperLike[A, TryStepper[A]] { - protected def myCache: A - protected def myCache_=(a: A): Unit - protected final var myCacheIsFull = false - private def load(): Boolean = { - myCacheIsFull = tryStep(myCache = _) - myCacheIsFull - } - final def hasStep = myCacheIsFull || load() - final def nextStep() = { - if (!myCacheIsFull) { - load() - if (!myCacheIsFull) Stepper.throwNSEE - } - val ans = myCache - myCacheIsFull = false - myCache = null.asInstanceOf[A] - ans - } - final def knownSize = knownUncachedSize + (if (myCacheIsFull) 1 else 0) - protected def knownUncachedSize: Long - final def tryStep(f: A => Unit): Boolean = if (myCacheIsFull) { f(myCache); myCacheIsFull = false; true } else tryUncached(f) - protected def tryUncached(f: A => Unit): Boolean - final override def foreach(f: A => Unit): Unit = { if (myCacheIsFull) { f(myCache); myCacheIsFull = false }; foreachUncached(f) } - protected def foreachUncached(f: A => Unit): Unit = { while (tryUncached(f)) {} } - def spliterator: Spliterator[A] = new ProxySpliteratorViaTry[A](this) -} -private[collectionImpl] class ProxySpliteratorViaTry[A](underlying: TryStepper[A]) extends Spliterator[A] { - def characteristics = underlying.characteristics - def estimateSize() = underlying.knownSize - def tryAdvance(f: java.util.function.Consumer[_ >: A]): Boolean = underlying.tryStep(a => f.accept(a)) - override def forEachRemaining(f: java.util.function.Consumer[_ >: A]): Unit = { underlying.foreach(a => f.accept(a)) } - def trySplit() = underlying.substep() match { case null => null; case x => new ProxySpliteratorViaTry[A](x) } -} - -/** Any `AnyStepper` combines the functionality of a Java `Iterator`, a Java `Spliterator`, and a `Stepper`. */ -trait AnyStepper[A] extends Stepper[A] with java.util.Iterator[A] with Spliterator[A] with StepperLike[A, AnyStepper[A]] { - override def forEachRemaining(c: java.util.function.Consumer[_ >: A]): Unit = { while (hasNext) { c.accept(next()) } } - def hasStep = hasNext - def knownSize = getExactSizeIfKnown - def nextStep() = next() - def tryAdvance(c: java.util.function.Consumer[_ >: A]): Boolean = if (hasNext) { c.accept(next()); true } else false - def tryStep(f: A => Unit): Boolean = if (hasNext) { f(next()); true } else false - def trySplit() = substep() - override def spliterator: Spliterator[A] = this - def seqStream: java.util.stream.Stream[A] = java.util.stream.StreamSupport.stream(this, false) - def parStream: java.util.stream.Stream[A] = java.util.stream.StreamSupport.stream(this, true) -} - -private[collectionImpl] object AnyStepper { - final class BoxedDoubleStepper(st: DoubleStepper) extends AnyStepper[Double] { - def hasNext: Boolean = st.hasNext - def next(): Double = st.next() - def characteristics: Int = st.characteristics - def estimateSize(): Long = st.estimateSize() - def substep(): AnyStepper[Double] = new BoxedDoubleStepper(st.substep()) - } - - final class BoxedIntStepper(st: IntStepper) extends AnyStepper[Int] { - def hasNext: Boolean = st.hasNext - def next(): Int = st.next() - def characteristics: Int = st.characteristics - def estimateSize(): Long = st.estimateSize() - def substep(): AnyStepper[Int] = new BoxedIntStepper(st.substep()) - } - - final class BoxedLongStepper(st: LongStepper) extends AnyStepper[Long] { - def hasNext: Boolean = st.hasNext - def next(): Long = st.next() - def characteristics: Int = st.characteristics - def estimateSize(): Long = st.estimateSize() - def substep(): AnyStepper[Long] = new BoxedLongStepper(st.substep()) - } -} - -/** A `DoubleStepper` combines the functionality of a Java `PrimitiveIterator`, a Java `Spliterator`, and a `Stepper`, all specialized for `Double` values. */ -trait DoubleStepper extends Stepper[Double] with java.util.PrimitiveIterator.OfDouble with Spliterator.OfDouble with StepperLike[Double, DoubleStepper] { - override def forEachRemaining(c: java.util.function.Consumer[_ >: java.lang.Double]): Unit = { while (hasNext) { c.accept(java.lang.Double.valueOf(nextDouble)) } } - override def forEachRemaining(c: java.util.function.DoubleConsumer): Unit = { while (hasNext) { c.accept(nextDouble) } } - def hasStep = hasNext - def knownSize = getExactSizeIfKnown - def nextStep() = nextDouble - override def tryAdvance(c: java.util.function.Consumer[_ >: java.lang.Double]): Boolean = if (hasNext) { c.accept(java.lang.Double.valueOf(nextDouble)); true } else false - def tryAdvance(c: java.util.function.DoubleConsumer): Boolean = if (hasNext) { c.accept(nextDouble); true } else false - def tryStep(f: Double => Unit): Boolean = if (hasNext) { f(nextDouble); true } else false - def trySplit() = substep() - override def spliterator: Spliterator[Double] = this.asInstanceOf[Spliterator[Double]] // Scala and Java disagree about whether it's java.lang.Double or double - def seqStream: java.util.stream.DoubleStream = java.util.stream.StreamSupport.doubleStream(this, false) - def parStream: java.util.stream.DoubleStream = java.util.stream.StreamSupport.doubleStream(this, true) -} - -/** An `IntStepper` combines the functionality of a Java `PrimitiveIterator`, a Java `Spliterator`, and a `Stepper`, all specialized for `Int` values. */ -trait IntStepper extends Stepper[Int] with java.util.PrimitiveIterator.OfInt with Spliterator.OfInt with StepperLike[Int, IntStepper] { - override def forEachRemaining(c: java.util.function.Consumer[_ >: java.lang.Integer]): Unit = { while (hasNext) { c.accept(java.lang.Integer.valueOf(nextInt)) } } - override def forEachRemaining(c: java.util.function.IntConsumer): Unit = { while (hasNext) { c.accept(nextInt) } } - def hasStep = hasNext - def knownSize = getExactSizeIfKnown - def nextStep() = nextInt - override def tryAdvance(c: java.util.function.Consumer[_ >: java.lang.Integer]): Boolean = if (hasNext) { c.accept(java.lang.Integer.valueOf(nextInt)); true } else false - def tryAdvance(c: java.util.function.IntConsumer): Boolean = if (hasNext) { c.accept(nextInt); true } else false - def tryStep(f: Int => Unit): Boolean = if (hasNext) { f(nextInt); true } else false - def trySplit() = substep() - override def spliterator: Spliterator[Int] = this.asInstanceOf[Spliterator[Int]] // Scala and Java disagree about whether it's java.lang.Integer or int - def seqStream: java.util.stream.IntStream = java.util.stream.StreamSupport.intStream(this, false) - def parStream: java.util.stream.IntStream = java.util.stream.StreamSupport.intStream(this, true) -} - -/** A `LongStepper` combines the functionality of a Java `PrimitiveIterator`, a Java `Spliterator`, and a `Stepper`, all specialized for `Long` values. */ -trait LongStepper extends Stepper[Long] with java.util.PrimitiveIterator.OfLong with Spliterator.OfLong with StepperLike[Long, LongStepper] { - override def forEachRemaining(c: java.util.function.Consumer[_ >: java.lang.Long]): Unit = { while (hasNext) { c.accept(java.lang.Long.valueOf(nextLong)) } } - override def forEachRemaining(c: java.util.function.LongConsumer): Unit = { while (hasNext) { c.accept(nextLong) } } - def hasStep = hasNext - def knownSize = getExactSizeIfKnown - def nextStep() = nextLong - override def tryAdvance(c: java.util.function.Consumer[_ >: java.lang.Long]): Boolean = if (hasNext) { c.accept(java.lang.Long.valueOf(nextLong)); true } else false - def tryAdvance(c: java.util.function.LongConsumer): Boolean = if (hasNext) { c.accept(nextLong); true } else false - def tryStep(f: Long => Unit): Boolean = if (hasNext) { f(nextLong); true } else false - def trySplit() = substep() - override def spliterator: Spliterator[Long] = this.asInstanceOf[Spliterator[Long]] // Scala and Java disagree about whether it's java.lang.Long or long - def seqStream: java.util.stream.LongStream = java.util.stream.StreamSupport.longStream(this, false) - def parStream: java.util.stream.LongStream = java.util.stream.StreamSupport.longStream(this, true) -} - - -object Stepper { - /** Indicates that a Stepper delivers distinct values (e.g. is backed by a `Set`) */ - val Distinct = Spliterator.DISTINCT - - /** Indicates that a Stepper runs over an immutable collection */ - val Immutable = Spliterator.IMMUTABLE - - /** Indicates that a Stepper will not return any `null` values */ - val NonNull = Spliterator.NONNULL - - /** Indicates that a Stepper delivers elements in a particular order that should be maintained */ - val Ordered = Spliterator.ORDERED - - /** Indicates that a Stepper knows exactly how many elements it contains */ - val Sized = Spliterator.SIZED - - /** Indicates that a Stepper's children (created with substep()) will all know their size. Steppers that are SubSized must also be Sized. */ - val SubSized = Spliterator.SUBSIZED - - private[java8] final def throwNSEE: Nothing = throw new NoSuchElementException("Empty Stepper") - - - private class OfSpliterator[A](sp: Spliterator[A]) - extends AnyStepper[A] with java.util.function.Consumer[A] { - private var cache: A = null.asInstanceOf[A] - private var cached: Boolean = false - def accept(a: A): Unit = { cache = a; cached = true } - - private def loadCache: Boolean = sp.tryAdvance(this) - private def useCache(c: java.util.function.Consumer[_ >: A]): Boolean = { - if (cached) { - c.accept(cache) - cache = null.asInstanceOf[A] - cached = false - true - } - else false - } - - def characteristics = sp.characteristics - def estimateSize = { - val sz = sp.estimateSize - if (cached && sz < Long.MaxValue && sz >= 0) sz + 1 - else sz - } - override def forEachRemaining(c: java.util.function.Consumer[_ >: A]): Unit = { - useCache(c) - sp.forEachRemaining(c) - } - def hasNext = cached || loadCache - def next() = { - if (!hasNext) throwNSEE - val ans = cache - cache = null.asInstanceOf[A] - cached = false - ans - } - def substep(): AnyStepper[A] = { - val subSp = sp.trySplit() - if (subSp eq null) null - else { - val sub = new OfSpliterator(subSp) - if (cached) { - sub.cache = cache - sub.cached = true - cache = null.asInstanceOf[A] - cached = false - } - sub - } - } - override def tryAdvance(c: java.util.function.Consumer[_ >: A]) = useCache(c) || sp.tryAdvance(c) - } - - private class OfDoubleSpliterator(sp: Spliterator.OfDouble) - extends DoubleStepper with java.util.function.DoubleConsumer { - private var cache: Double = Double.NaN - private var cached: Boolean = false - def accept(d: Double): Unit = { cache = d; cached = true } - - private def loadCache: Boolean = sp.tryAdvance(this) - private def useCache(c: java.util.function.DoubleConsumer): Boolean = { - if (cached) { - c.accept(cache) - cached = false - true - } - else false - } - - def characteristics = sp.characteristics - def estimateSize = { - val sz = sp.estimateSize - if (cached && sz < Long.MaxValue && sz >= 0) sz + 1 - else sz - } - override def forEachRemaining(c: java.util.function.DoubleConsumer): Unit = { - useCache(c) - sp.forEachRemaining(c) - } - def hasNext = cached || loadCache - def nextDouble() = { - if (!hasNext) throwNSEE - val ans = cache - cached = false - ans - } - def substep(): DoubleStepper = { - val subSp = sp.trySplit() - if (subSp eq null) null - else { - val sub = new OfDoubleSpliterator(subSp) - if (cached) { - sub.cache = cache - sub.cached = true - cached = false - } - sub - } - } - override def tryAdvance(c: java.util.function.DoubleConsumer) = useCache(c) || sp.tryAdvance(c) - } - - private class OfIntSpliterator(sp: Spliterator.OfInt) - extends IntStepper with java.util.function.IntConsumer { - private var cache: Int = 0 - private var cached: Boolean = false - def accept(i: Int): Unit = { cache = i; cached = true } - - private def loadCache: Boolean = sp.tryAdvance(this) - private def useCache(c: java.util.function.IntConsumer): Boolean = { - if (cached) { - c.accept(cache) - cached = false - true - } - else false - } - - def characteristics = sp.characteristics - def estimateSize = { - val sz = sp.estimateSize - if (cached && sz < Long.MaxValue && sz >= 0) sz + 1 - else sz - } - override def forEachRemaining(c: java.util.function.IntConsumer): Unit = { - useCache(c) - sp.forEachRemaining(c) - } - def hasNext = cached || loadCache - def nextInt() = { - if (!hasNext) throwNSEE - val ans = cache - cached = false - ans - } - def substep(): IntStepper = { - val subSp = sp.trySplit() - if (subSp eq null) null - else { - val sub = new OfIntSpliterator(subSp) - if (cached) { - sub.cache = cache - sub.cached = true - cached = false - } - sub - } - } - override def tryAdvance(c: java.util.function.IntConsumer) = useCache(c) || sp.tryAdvance(c) - } - - private class OfLongSpliterator(sp: Spliterator.OfLong) - extends LongStepper with java.util.function.LongConsumer { - private var cache: Long = 0L - private var cached: Boolean = false - def accept(l: Long): Unit = { cache = l; cached = true } - - private def loadCache: Boolean = sp.tryAdvance(this) - private def useCache(c: java.util.function.LongConsumer): Boolean = { - if (cached) { - c.accept(cache) - cached = false - true - } - else false - } - - def characteristics = sp.characteristics - def estimateSize = { - val sz = sp.estimateSize - if (cached && sz < Long.MaxValue && sz >= 0) sz + 1 - else sz - } - override def forEachRemaining(c: java.util.function.LongConsumer): Unit = { - useCache(c) - sp.forEachRemaining(c) - } - def hasNext = cached || loadCache - def nextLong() = { - if (!hasNext) throwNSEE - val ans = cache - cached = false - ans - } - def substep(): LongStepper = { - val subSp = sp.trySplit() - if (subSp eq null) null - else { - val sub = new OfLongSpliterator(subSp) - if (cached) { - sub.cache = cache - sub.cached = true - cached = false - } - sub - } - } - override def tryAdvance(c: java.util.function.LongConsumer) = useCache(c) || sp.tryAdvance(c) - } - - /** Creates a `Stepper` over a generic `Spliterator`. */ - def ofSpliterator[A](sp: Spliterator[A]): AnyStepper[A] = sp match { - case as: AnyStepper[A] => as - case s: DoubleStepper => new AnyStepper.BoxedDoubleStepper(s).asInstanceOf[AnyStepper[A]] - case s: IntStepper => new AnyStepper.BoxedIntStepper(s).asInstanceOf[AnyStepper[A]] - case s: LongStepper => new AnyStepper.BoxedLongStepper(s).asInstanceOf[AnyStepper[A]] - case _ => new OfSpliterator[A](sp) - } - - - /** Creates a `Stepper` over a `DoubleSpliterator`. */ - def ofSpliterator(sp: Spliterator.OfDouble): DoubleStepper = sp match { - case ds: DoubleStepper => ds - case _ => new OfDoubleSpliterator(sp) - } - - /** Creates a `Stepper` over an `IntSpliterator`. */ - def ofSpliterator(sp: Spliterator.OfInt): IntStepper = sp match { - case is: IntStepper => is - case _ => new OfIntSpliterator(sp) - } - - - /** Creates a `Stepper` over a `LongSpliterator`. */ - def ofSpliterator(sp: Spliterator.OfLong): LongStepper = sp match { - case ls: LongStepper => ls - case _ => new OfLongSpliterator(sp) - } - - /* These adapter classes can wrap an AnyStepper of anumeric type into a possibly widened primitive Stepper type. - * This provides a basis for more efficient stream processing on unboxed values provided that the original source - * of the data is boxed. In other cases native implementations of the primitive stepper types should be provided - * (see for example StepsIntArray and StepsWidenedByteArray). */ - - private[java8] class UnboxingDoubleStepper(st: AnyStepper[Double]) extends DoubleStepper { - def hasNext: Boolean = st.hasNext - def nextDouble(): Double = st.next() - def characteristics: Int = st.characteristics - def estimateSize(): Long = st.estimateSize() - def substep(): DoubleStepper = new UnboxingDoubleStepper(st.substep()) - } - - private[java8] class UnboxingIntStepper(st: AnyStepper[Int]) extends IntStepper { - def hasNext: Boolean = st.hasNext - def nextInt(): Int = st.next() - def characteristics: Int = st.characteristics - def estimateSize(): Long = st.estimateSize() - def substep(): IntStepper = new UnboxingIntStepper(st.substep()) - } - - private[java8] class UnboxingLongStepper(st: AnyStepper[Long]) extends LongStepper { - def hasNext: Boolean = st.hasNext - def nextLong(): Long = st.next() - def characteristics: Int = st.characteristics - def estimateSize(): Long = st.estimateSize() - def substep(): LongStepper = new UnboxingLongStepper(st.substep()) - } - - private[java8] class UnboxingByteStepper(st: AnyStepper[Byte]) extends IntStepper { - def hasNext: Boolean = st.hasNext - def nextInt(): Int = st.next() - def characteristics: Int = st.characteristics | NonNull - def estimateSize(): Long = st.estimateSize() - def substep(): IntStepper = new UnboxingByteStepper(st.substep()) - } - - private[java8] class UnboxingCharStepper(st: AnyStepper[Char]) extends IntStepper { - def hasNext: Boolean = st.hasNext - def nextInt(): Int = st.next() - def characteristics: Int = st.characteristics | NonNull - def estimateSize(): Long = st.estimateSize() - def substep(): IntStepper = new UnboxingCharStepper(st.substep()) - } - - private[java8] class UnboxingShortStepper(st: AnyStepper[Short]) extends IntStepper { - def hasNext: Boolean = st.hasNext - def nextInt(): Int = st.next() - def characteristics: Int = st.characteristics | NonNull - def estimateSize(): Long = st.estimateSize() - def substep(): IntStepper = new UnboxingShortStepper(st.substep()) - } - - private[java8] class UnboxingFloatStepper(st: AnyStepper[Float]) extends DoubleStepper { - def hasNext: Boolean = st.hasNext - def nextDouble(): Double = st.next() - def characteristics: Int = st.characteristics | NonNull - def estimateSize(): Long = st.estimateSize() - def substep(): DoubleStepper = new UnboxingFloatStepper(st.substep()) - } -} diff --git a/src/main/scala/scala/compat/java8/collectionImpl/package.scala b/src/main/scala/scala/compat/java8/collectionImpl/package.scala new file mode 100644 index 0000000..ab5cfca --- /dev/null +++ b/src/main/scala/scala/compat/java8/collectionImpl/package.scala @@ -0,0 +1,30 @@ +package scala.compat.java8 + +package object collectionImpl { + type Accumulator[A] = scala.jdk.AnyAccumulator[A] + val Accumulator = scala.jdk.AnyAccumulator + + type IntAccumulator = scala.jdk.IntAccumulator + val IntAccumulator = scala.jdk.IntAccumulator + + type LongAccumulator = scala.jdk.LongAccumulator + val LongAccumulator = scala.jdk.LongAccumulator + + type DoubleAccumulator = scala.jdk.DoubleAccumulator + val DoubleAccumulator = scala.jdk.DoubleAccumulator + + type Stepper[A] = scala.collection.Stepper[A] + val Stepper = scala.collection.Stepper + + type AnyStepper[A] = scala.collection.AnyStepper[A] + val AnyStepper = scala.collection.AnyStepper + + type IntStepper = scala.collection.IntStepper + val IntStepper = scala.collection.IntStepper + + type LongStepper = scala.collection.LongStepper + val LongStepper = scala.collection.LongStepper + + type DoubleStepper = scala.collection.DoubleStepper + val DoubleStepper = scala.collection.DoubleStepper +} diff --git a/src/main/scala/scala/compat/java8/converterImpl/Accumulates.scala b/src/main/scala/scala/compat/java8/converterImpl/Accumulates.scala index 6bf537e..fa28114 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/Accumulates.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/Accumulates.scala @@ -14,74 +14,34 @@ package scala.compat.java8.converterImpl import scala.compat.java8.collectionImpl._ -trait AccumulatesFromStepper[@specialized(Double, Int, Long) A, Acc <: AccumulatorLike[A, Acc]] { - def apply(stepper: Stepper[A]): Acc -} - final class CollectionCanAccumulate[A](private val underlying: IterableOnce[A]) extends AnyVal { - def accumulate: Accumulator[A] = { - val a = new Accumulator[A] - underlying.iterator.foreach(a += _) - a - } + def accumulate: Accumulator[A] = underlying.iterator.to(Accumulator) } final class AccumulateDoubleCollection(private val underlying: IterableOnce[Double]) extends AnyVal { - def accumulate: DoubleAccumulator = { - val da = new DoubleAccumulator - underlying.iterator.foreach(da += _) - da - } + def accumulate: DoubleAccumulator = underlying.iterator.to(DoubleAccumulator) } final class AccumulateIntCollection(private val underlying: IterableOnce[Int]) extends AnyVal { - def accumulate: IntAccumulator = { - val da = new IntAccumulator - underlying.iterator.foreach(da += _) - da - } + def accumulate: IntAccumulator = underlying.iterator.to(IntAccumulator) } final class AccumulateLongCollection(private val underlying: IterableOnce[Long]) extends AnyVal { - def accumulate: LongAccumulator = { - val da = new LongAccumulator - underlying.iterator.foreach(da += _) - da - } + def accumulate: LongAccumulator = underlying.iterator.to(LongAccumulator) } final class AccumulateAnyArray[A](private val underlying: Array[A]) extends AnyVal { - def accumulate: Accumulator[A] = { - val a = new Accumulator[A] - var i = 0 - while (i < underlying.length) { a += underlying(i); i += 1 } - a - } + def accumulate: Accumulator[A] = underlying.to(Accumulator) } final class AccumulateDoubleArray(private val underlying: Array[Double]) extends AnyVal { - def accumulate: DoubleAccumulator = { - val da = new DoubleAccumulator - var i = 0 - while (i < underlying.length) { da += underlying(i); i += 1 } - da - } + def accumulate: DoubleAccumulator = underlying.to(DoubleAccumulator) } final class AccumulateIntArray(private val underlying: Array[Int]) extends AnyVal { - def accumulate: IntAccumulator = { - val da = new IntAccumulator - var i = 0 - while (i < underlying.length) { da += underlying(i); i += 1 } - da - } + def accumulate: IntAccumulator = underlying.to(IntAccumulator) } final class AccumulateLongArray(private val underlying: Array[Long]) extends AnyVal { - def accumulate: LongAccumulator = { - val da = new LongAccumulator - var i = 0 - while (i < underlying.length) { da += underlying(i); i += 1 } - da - } + def accumulate: LongAccumulator = underlying.to(LongAccumulator) } diff --git a/src/main/scala/scala/compat/java8/converterImpl/AccumulatorConverters.scala b/src/main/scala/scala/compat/java8/converterImpl/AccumulatorConverters.scala index 8a1c46f..4ff943a 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/AccumulatorConverters.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/AccumulatorConverters.scala @@ -12,9 +12,7 @@ package scala.compat.java8.converterImpl -import language.implicitConversions - -import scala.compat.java8.collectionImpl._ +import scala.language.implicitConversions trait Priority3AccumulatorConverters { implicit def collectionCanAccumulate[A](underlying: IterableOnce[A]) = new CollectionCanAccumulate[A](underlying) @@ -31,17 +29,4 @@ trait Priority1AccumulatorConverters extends Priority2AccumulatorConverters { implicit def accumulateDoubleArray(underlying: Array[Double]) = new AccumulateDoubleArray(underlying) implicit def accumulateIntArray(underlying: Array[Int]) = new AccumulateIntArray(underlying) implicit def accumulateLongArray(underlying: Array[Long]) = new AccumulateLongArray(underlying) - - implicit def accumulateAnyStepper[A]: AccumulatesFromStepper[A, Accumulator[A]] = - PrivateAccumulatorConverters.genericAccumulateAnyStepper.asInstanceOf[AccumulatesFromStepper[A, Accumulator[A]]] -} - -private[java8] object PrivateAccumulatorConverters { - val genericAccumulateAnyStepper: AccumulatesFromStepper[Any, Accumulator[Any]] = new AccumulatesFromStepper[Any, Accumulator[Any]] { - def apply(stepper: Stepper[Any]) = { - val a = new Accumulator[Any] - while (stepper.hasStep) a += stepper.nextStep() - a - } - } } diff --git a/src/main/scala/scala/compat/java8/converterImpl/MakesSteppers.scala b/src/main/scala/scala/compat/java8/converterImpl/MakesSteppers.scala deleted file mode 100644 index e73e4d2..0000000 --- a/src/main/scala/scala/compat/java8/converterImpl/MakesSteppers.scala +++ /dev/null @@ -1,102 +0,0 @@ -/* - * 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.compat.java8.converterImpl - -import scala.compat.java8.collectionImpl._ - -trait MakesStepper[T, +Extra] extends Any { - /** Generates a fresh stepper of type `S` for element type `T` */ - def stepper[S <: Stepper[_]](implicit ss: StepperShape[T, S]): S with Extra -} - -trait MakesKeyValueStepper[K, V, +Extra] extends Any { - /** Generates a fresh stepper of type `S` over map keys of type `K` */ - def keyStepper[S <: Stepper[_]](implicit ss: StepperShape[K, S]): S with Extra - - /** Generates a fresh stepper of type `S` over map values of type `V` */ - def valueStepper[S <: Stepper[_]](implicit ss: StepperShape[V, S]): S with Extra -} - -/** Encodes the translation from an element type `T` to the corresponding Stepper type `S` */ -sealed trait StepperShape[T, S <: Stepper[_]] { - /** Return the Int constant (as defined in the `StepperShape` companion object) for this `StepperShape`. */ - def shape: Int - - /** Create an unboxing primitive sequential Stepper from a boxed `AnyStepper`. - * This is an identity operation for reference shapes. */ - def seqUnbox(st: AnyStepper[T]): S - - /** Create an unboxing primitive parallel (i.e. `with EfficientSubstep`) Stepper from a boxed `AnyStepper`. - * This is an identity operation for reference shapes. */ - def parUnbox(st: AnyStepper[T] with EfficientSubstep): S with EfficientSubstep -} -object StepperShape extends StepperShapeLowPriority { - // reference - final val Reference = 0 - - // primitive - final val IntValue = 1 - final val LongValue = 2 - final val DoubleValue = 3 - - // widening - final val ByteValue = 4 - final val ShortValue = 5 - final val CharValue = 6 - final val FloatValue = 7 - - implicit val intStepperShape: StepperShape[Int, IntStepper] = new StepperShape[Int, IntStepper] { - def shape = IntValue - def seqUnbox(st: AnyStepper[Int]): IntStepper = new Stepper.UnboxingIntStepper(st) - def parUnbox(st: AnyStepper[Int] with EfficientSubstep): IntStepper with EfficientSubstep = new Stepper.UnboxingIntStepper(st) with EfficientSubstep - } - implicit val longStepperShape: StepperShape[Long, LongStepper] = new StepperShape[Long, LongStepper] { - def shape = LongValue - def seqUnbox(st: AnyStepper[Long]): LongStepper = new Stepper.UnboxingLongStepper(st) - def parUnbox(st: AnyStepper[Long] with EfficientSubstep): LongStepper with EfficientSubstep = new Stepper.UnboxingLongStepper(st) with EfficientSubstep - } - implicit val doubleStepperShape: StepperShape[Double, DoubleStepper] = new StepperShape[Double, DoubleStepper] { - def shape = DoubleValue - def seqUnbox(st: AnyStepper[Double]): DoubleStepper = new Stepper.UnboxingDoubleStepper(st) - def parUnbox(st: AnyStepper[Double] with EfficientSubstep): DoubleStepper with EfficientSubstep = new Stepper.UnboxingDoubleStepper(st) with EfficientSubstep - } - implicit val byteStepperShape: StepperShape[Byte, IntStepper] = new StepperShape[Byte, IntStepper] { - def shape = ByteValue - def seqUnbox(st: AnyStepper[Byte]): IntStepper = new Stepper.UnboxingByteStepper(st) - def parUnbox(st: AnyStepper[Byte] with EfficientSubstep): IntStepper with EfficientSubstep = new Stepper.UnboxingByteStepper(st) with EfficientSubstep - } - implicit val shortStepperShape: StepperShape[Short, IntStepper] = new StepperShape[Short, IntStepper] { - def shape = ShortValue - def seqUnbox(st: AnyStepper[Short]): IntStepper = new Stepper.UnboxingShortStepper(st) - def parUnbox(st: AnyStepper[Short] with EfficientSubstep): IntStepper with EfficientSubstep = new Stepper.UnboxingShortStepper(st) with EfficientSubstep - } - implicit val charStepperShape: StepperShape[Char, IntStepper] = new StepperShape[Char, IntStepper] { - def shape = CharValue - def seqUnbox(st: AnyStepper[Char]): IntStepper = new Stepper.UnboxingCharStepper(st) - def parUnbox(st: AnyStepper[Char] with EfficientSubstep): IntStepper with EfficientSubstep = new Stepper.UnboxingCharStepper(st) with EfficientSubstep - } - implicit val floatStepperShape: StepperShape[Float, DoubleStepper] = new StepperShape[Float, DoubleStepper] { - def shape = FloatValue - def seqUnbox(st: AnyStepper[Float]): DoubleStepper = new Stepper.UnboxingFloatStepper(st) - def parUnbox(st: AnyStepper[Float] with EfficientSubstep): DoubleStepper with EfficientSubstep = new Stepper.UnboxingFloatStepper(st) with EfficientSubstep - } -} -trait StepperShapeLowPriority { - implicit def anyStepperShape[T] = anyStepperShapePrototype.asInstanceOf[StepperShape[T, AnyStepper[T]]] - - private[this] val anyStepperShapePrototype: StepperShape[AnyRef, AnyStepper[AnyRef]] = new StepperShape[AnyRef, AnyStepper[AnyRef]] { - def shape = StepperShape.Reference - def seqUnbox(st: AnyStepper[AnyRef]): AnyStepper[AnyRef] = st - def parUnbox(st: AnyStepper[AnyRef] with EfficientSubstep): AnyStepper[AnyRef] with EfficientSubstep = st - } -} diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepConverters.scala b/src/main/scala/scala/compat/java8/converterImpl/StepConverters.scala deleted file mode 100644 index 9f96db0..0000000 --- a/src/main/scala/scala/compat/java8/converterImpl/StepConverters.scala +++ /dev/null @@ -1,58 +0,0 @@ -/* - * 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.compat.java8 -package converterImpl - -import language.implicitConversions -import scala.reflect.ClassTag - -trait Priority3StepConverters { - implicit def richIterableCanStep[A](underlying: Iterable[A]): RichIterableCanStep[A] = - new RichIterableCanStep(underlying) - implicit def richMapCanStep[K, V](underlying: collection.Map[K, V]): RichMapCanStep[K, V] = - new RichMapCanStep[K, V](underlying) -} - -trait Priority2StepConverters extends Priority3StepConverters { - implicit def richLinearSeqCanStep[A](underlying: collection.LinearSeq[A]): RichLinearSeqCanStep[A] = - new RichLinearSeqCanStep[A](underlying) - implicit def richIndexedSeqCanStep[A](underlying: collection.IndexedSeqOps[A, Any, _]): RichIndexedSeqCanStep[A] = - new RichIndexedSeqCanStep[A](underlying) -} - -trait Priority1StepConverters extends Priority2StepConverters { - implicit def richDefaultHashMapCanStep[K, V](underlying: collection.mutable.HashMap[K, V]): RichHashMapCanStep[K, V] = - new RichHashMapCanStep[K, V](underlying) - implicit def richLinkedHashMapCanStep[K, V](underlying: collection.mutable.LinkedHashMap[K, V]): RichLinkedHashMapCanStep[K, V] = - new RichLinkedHashMapCanStep[K, V](underlying) - implicit def richArrayCanStep[A](underlying: Array[A]): RichArrayCanStep[A] = - new RichArrayCanStep[A](underlying) - implicit def richArraySeqCanStep[A: ClassTag](underlying: collection.mutable.ArraySeq[A]): RichArrayCanStep[A] = - new RichArrayCanStep[A](StreamConverters.unsafeArrayIfPossible(underlying)) - implicit def richHashSetCanStep[A](underlying: collection.mutable.HashSet[A]): RichHashSetCanStep[A] = - new RichHashSetCanStep[A](underlying) - implicit def richIteratorCanStep[A](underlying: Iterator[A]): RichIteratorCanStep[A] = - new RichIteratorCanStep(underlying) - implicit def richImmHashSetCanStep[A](underlying: collection.immutable.HashSet[A]): RichImmHashSetCanStep[A] = - new RichImmHashSetCanStep[A](underlying) - implicit def richNumericRangeCanStep[T](underlying: collection.immutable.NumericRange[T]): RichNumericRangeCanStep[T] = - new RichNumericRangeCanStep(underlying) - implicit def richVectorCanStep[A](underlying: Vector[A]): RichVectorCanStep[A] = - new RichVectorCanStep[A](underlying) - implicit def richBitSetCanStep(underlying: collection.BitSet): RichBitSetCanStep = - new RichBitSetCanStep(underlying) - implicit def richRangeCanStep(underlying: Range): RichRangeCanStep[Int] = - new RichRangeCanStep(underlying) - implicit def richStringCanStep(underlying: String): RichStringCanStep = - new RichStringCanStep(underlying) -} diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepperExtensions.scala b/src/main/scala/scala/compat/java8/converterImpl/StepperExtensions.scala new file mode 100644 index 0000000..15f384a --- /dev/null +++ b/src/main/scala/scala/compat/java8/converterImpl/StepperExtensions.scala @@ -0,0 +1,77 @@ +package scala.compat.java8.converterImpl + +import scala.collection.convert.StreamExtensions.AccumulatorFactoryInfo +import scala.compat.java8.collectionImpl.{DoubleAccumulator, IntAccumulator, LongAccumulator, Stepper} +import scala.jdk.AnyAccumulator + +class StepperExtensions[@specialized(Double, Int, Long) A](private val s: Stepper[A]) { + def accumulate[C](implicit info: AccumulatorFactoryInfo[A, C]): C = { + info.companion match { + case IntAccumulator => + val a = new IntAccumulator() + val is = s.asInstanceOf[Stepper[Int]] + while (is.hasStep) a += is.nextStep() + a.asInstanceOf[C] + case LongAccumulator => + val a = new LongAccumulator() + val is = s.asInstanceOf[Stepper[Long]] + while (is.hasStep) a += is.nextStep() + a.asInstanceOf[C] + case DoubleAccumulator => + val a = new DoubleAccumulator() + val is = s.asInstanceOf[Stepper[Double]] + while (is.hasStep) a += is.nextStep() + a.asInstanceOf[C] + case AnyAccumulator | null => + val a = new AnyAccumulator[A] + while (s.hasStep) a += s.nextStep() + a.asInstanceOf[C] + } + } + + def substep(): Stepper[A] = s.trySplit() + + /** Consumes all remaining elements in this `Stepper` and counts how many there are. + * This is a terminal operation. + */ + def count(): Long = { var n = 0L; while (s.hasStep) { s.nextStep(); n += 1 }; n } + + /** Consumes all remaining elements in this `Stepper` and counts how many satisfy condition `p`. + * This is a terminal operation. + */ + def count(p: A => Boolean): Long = { var n = 0L; while (s.hasStep) { if (p(s.nextStep())) n += 1 }; n } + + /** Searches for an element that satisfies condition `p`. If none are found, it returns `false`. + * This is a terminal operation. + */ + def exists(p: A => Boolean): Boolean = { while(s.hasStep) { if (p(s.nextStep())) return true }; false } + + /** Searches for an element that satisifes condition `p`, returning it wrapped in `Some` if one is found, or `None` otherwise. + * This is a terminal operation. + */ + def find(p: A => Boolean): Option[A] = { while (s.hasStep) { val a = s.nextStep(); if (p(a)) return Some(a) }; None } + + /** Repeatedly applies `op` to propagate an initial value `zero` through all elements of the collection. + * Traversal order is left-to-right. + * This is a terminal operation. + */ + def fold[@specialized(Double, Int, Long) B](zero: B)(op: (B, A) => B) = { var b = zero; while (s.hasStep) { b = op(b, s.nextStep()) }; b } + + /** Repeatedly applies `op` to propagate an initial value `zero` through the collection until a condition `p` is met. + * If `p` is never met, the result of the last operation is returned. + * This is a terminal operation. + */ + def foldTo[@specialized(Double, Int, Long) B](zero: B)(op: (B, A) => B)(p: B => Boolean) = { var b = zero; while (!p(b) && s.hasStep) { b = op(b, s.nextStep()) }; b } + + /** Applies `f` to every remaining element in the collection. + * This is a terminal operation. + */ + def foreach(f: A => Unit): Unit = { while (s.hasStep) f(s.nextStep()) } + + /** Repeatedly merges elements with `op` until only a single element remains. + * Throws an exception if the `Stepper` is empty. + * Merging occurs from left to right. + * This is a terminal operation. + */ + def reduce(op: (A, A) => A): A = { var a = s.nextStep(); while (s.hasStep) { a = op(a, s.nextStep()) }; a } +} diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsArray.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsArray.scala deleted file mode 100644 index 8ebaf34..0000000 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsArray.scala +++ /dev/null @@ -1,97 +0,0 @@ -/* - * 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.compat.java8.converterImpl - -import scala.annotation.switch - -import scala.compat.java8.collectionImpl._ - -import Stepper._ - -///////////////////////////// -// Stepper implementations // -///////////////////////////// - -private[java8] class StepsObjectArray[A <: Object](underlying: Array[A], _i0: Int, _iN: Int) -extends StepsLikeIndexed[A, StepsObjectArray[A]](_i0, _iN) { - def next() = if (hasNext) { val j = i0; i0 += 1; underlying(j) } else throwNSEE - protected def semiclone(half: Int) = new StepsObjectArray[A](underlying, i0, half) -} - -private[java8] class StepsBoxedBooleanArray(underlying: Array[Boolean], _i0: Int, _iN: Int) -extends StepsLikeIndexed[Boolean, StepsBoxedBooleanArray](_i0, _iN) { - def next() = if (hasNext) { val j = i0; i0 += 1; underlying(j) } else throwNSEE - protected def semiclone(half: Int) = new StepsBoxedBooleanArray(underlying, i0, half) -} - -private[java8] class StepsWidenedByteArray(underlying: Array[Byte], _i0: Int, _iN: Int) -extends StepsIntLikeIndexed[StepsWidenedByteArray](_i0, _iN) { - def nextInt() = if (hasNext) { val j = i0; i0 += 1; underlying(j) } else throwNSEE - protected def semiclone(half: Int) = new StepsWidenedByteArray(underlying, i0, half) -} - -private[java8] class StepsWidenedCharArray(underlying: Array[Char], _i0: Int, _iN: Int) -extends StepsIntLikeIndexed[StepsWidenedCharArray](_i0, _iN) { - def nextInt() = if (hasNext) { val j = i0; i0 += 1; underlying(j) } else throwNSEE - protected def semiclone(half: Int) = new StepsWidenedCharArray(underlying, i0, half) -} - -private[java8] class StepsWidenedShortArray(underlying: Array[Short], _i0: Int, _iN: Int) -extends StepsIntLikeIndexed[StepsWidenedShortArray](_i0, _iN) { - def nextInt() = if (hasNext) { val j = i0; i0 += 1; underlying(j) } else throwNSEE - protected def semiclone(half: Int) = new StepsWidenedShortArray(underlying, i0, half) -} - -private[java8] class StepsWidenedFloatArray(underlying: Array[Float], _i0: Int, _iN: Int) -extends StepsDoubleLikeIndexed[StepsWidenedFloatArray](_i0, _iN) { - def nextDouble() = if (hasNext) { val j = i0; i0 += 1; underlying(j) } else throwNSEE - protected def semiclone(half: Int) = new StepsWidenedFloatArray(underlying, i0, half) -} - -private[java8] class StepsDoubleArray(underlying: Array[Double], _i0: Int, _iN: Int) -extends StepsDoubleLikeIndexed[StepsDoubleArray](_i0, _iN) { - def nextDouble() = if (hasNext) { val j = i0; i0 += 1; underlying(j) } else throwNSEE - protected def semiclone(half: Int) = new StepsDoubleArray(underlying, i0, half) -} - -private[java8] class StepsIntArray(underlying: Array[Int], _i0: Int, _iN: Int) -extends StepsIntLikeIndexed[StepsIntArray](_i0, _iN) { - def nextInt() = if (hasNext) { val j = i0; i0 += 1; underlying(j) } else throwNSEE - protected def semiclone(half: Int) = new StepsIntArray(underlying, i0, half) -} - -private[java8] class StepsLongArray(underlying: Array[Long], _i0: Int, _iN: Int) -extends StepsLongLikeIndexed[StepsLongArray](_i0, _iN) { - def nextLong() = if (hasNext) { val j = i0; i0 += 1; underlying(j) } else throwNSEE - protected def semiclone(half: Int) = new StepsLongArray(underlying, i0, half) -} - -////////////////////////// -// Value class adapters // -////////////////////////// - -final class RichArrayCanStep[T](private val underlying: Array[T]) extends AnyVal with MakesStepper[T, EfficientSubstep] { - override def stepper[S <: Stepper[_]](implicit ss: StepperShape[T, S]) = ((ss.shape: @switch) match { - case StepperShape.Reference => - if(underlying.isInstanceOf[Array[Boolean]]) - new StepsBoxedBooleanArray (underlying.asInstanceOf[Array[Boolean]], 0, underlying.length) - else new StepsObjectArray[AnyRef](underlying.asInstanceOf[Array[AnyRef ]], 0, underlying.length) - case StepperShape.IntValue => new StepsIntArray (underlying.asInstanceOf[Array[Int ]], 0, underlying.length) - case StepperShape.LongValue => new StepsLongArray (underlying.asInstanceOf[Array[Long ]], 0, underlying.length) - case StepperShape.DoubleValue => new StepsDoubleArray (underlying.asInstanceOf[Array[Double ]], 0, underlying.length) - case StepperShape.ByteValue => new StepsWidenedByteArray (underlying.asInstanceOf[Array[Byte ]], 0, underlying.length) - case StepperShape.ShortValue => new StepsWidenedShortArray (underlying.asInstanceOf[Array[Short ]], 0, underlying.length) - case StepperShape.CharValue => new StepsWidenedCharArray (underlying.asInstanceOf[Array[Char ]], 0, underlying.length) - case StepperShape.FloatValue => new StepsWidenedFloatArray (underlying.asInstanceOf[Array[Float ]], 0, underlying.length) - }).asInstanceOf[S with EfficientSubstep] -} diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsBitSet.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsBitSet.scala deleted file mode 100644 index c7c95c3..0000000 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsBitSet.scala +++ /dev/null @@ -1,80 +0,0 @@ -/* - * 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.compat.java8.converterImpl - -import scala.compat.java8.collectionImpl._ -import scala.compat.java8.runtime._ - -import Stepper._ - -//////////////////////////// -// Stepper implementation // -//////////////////////////// - -private[java8] class StepsIntBitSet(_underlying: Array[Long], _i0: Int, _iN: Int) -extends StepsIntLikeSliced[Array[Long], StepsIntBitSet](_underlying, _i0, _iN) { - private var mask: Long = (-1L) << (i & 0x3F) - private var cache: Long = underlying(i >>> 6) - private var found: Boolean = false - protected def semiclone(half: Int) = { - val ans = new StepsIntBitSet(underlying, i, half) - i = half - mask = (-1L) << (i & 0x3F) - cache = underlying(i >>> 6) - found = false - ans - } - def hasNext: Boolean = found || ((i < iN) && { - while ((mask & cache) == 0) { - i += java.lang.Long.numberOfLeadingZeros(~mask) - if (i < 0 || i >= iN) { i = iN; return false } - mask = -1L - cache = underlying(i >>> 6) - } - var m = mask << 1 - while ((mask & cache) == (m & cache)) { - mask = m - m = mask << 1 - i += 1 - } - if (i < 0 || i >= iN) { - i = iN - false - } else { - found = true - true - } - }) - def nextInt() = if (hasNext) { val j = i; found = false; mask = mask << 1; i += 1; j } else throwNSEE -} - -///////////////////////// -// Value class adapter // -///////////////////////// - -final class RichBitSetCanStep(private val underlying: collection.BitSet) extends AnyVal with MakesStepper[Int, EfficientSubstep] { - override def stepper[S <: Stepper[_]](implicit ss: StepperShape[Int, S]) = { - val bits: Array[Long] = underlying match { - case m: collection.mutable.BitSet => CollectionInternals.getBitSetInternals(m) - case n: collection.immutable.BitSet.BitSetN => RichBitSetCanStep.reflectInternalsN(n) - case x => x.toBitMask - } - new StepsIntBitSet(bits, 0, math.min(bits.length*64L, Int.MaxValue).toInt).asInstanceOf[S with EfficientSubstep] - } -} - -private[java8] object RichBitSetCanStep { - private val reflector = classOf[collection.immutable.BitSet.BitSetN].getMethod("elems") - def reflectInternalsN(bsn: collection.immutable.BitSet.BitSetN): Array[Long] = reflector.invoke(bsn).asInstanceOf[Array[Long]] -} - diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsFlatHashTable.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsFlatHashTable.scala deleted file mode 100644 index 94174d9..0000000 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsFlatHashTable.scala +++ /dev/null @@ -1,64 +0,0 @@ -/* - * 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.compat.java8.converterImpl - -import scala.annotation.switch - -import scala.compat.java8.collectionImpl._ -import scala.compat.java8.runtime._ - -import Stepper._ - -///////////////////////////// -// Stepper implementations // -///////////////////////////// - -private[java8] class StepsAnyFlatHashTable[A](_underlying: Array[AnyRef], _i0: Int, _iN: Int) -extends StepsLikeGapped[A, StepsAnyFlatHashTable[A]](_underlying, _i0, _iN) { - def next() = if (currentEntry eq null) throwNSEE else { val ans = currentEntry.asInstanceOf[A]; currentEntry = null; ans } - protected def semiclone(half: Int) = new StepsAnyFlatHashTable[A](underlying, i0, half) -} - -private[java8] class StepsDoubleFlatHashTable(_underlying: Array[AnyRef], _i0: Int, _iN: Int) -extends StepsDoubleLikeGapped[StepsDoubleFlatHashTable](_underlying, _i0, _iN) { - def nextDouble() = if (currentEntry eq null) throwNSEE else { val ans = currentEntry.asInstanceOf[Double]; currentEntry = null; ans } - protected def semiclone(half: Int) = new StepsDoubleFlatHashTable(underlying, i0, half) -} - -private[java8] class StepsIntFlatHashTable(_underlying: Array[AnyRef], _i0: Int, _iN: Int) -extends StepsIntLikeGapped[StepsIntFlatHashTable](_underlying, _i0, _iN) { - def nextInt() = if (currentEntry eq null) throwNSEE else { val ans = currentEntry.asInstanceOf[Int]; currentEntry = null; ans } - protected def semiclone(half: Int) = new StepsIntFlatHashTable(underlying, i0, half) -} - -private[java8] class StepsLongFlatHashTable(_underlying: Array[AnyRef], _i0: Int, _iN: Int) -extends StepsLongLikeGapped[StepsLongFlatHashTable](_underlying, _i0, _iN) { - def nextLong() = if (currentEntry eq null) throwNSEE else { val ans = currentEntry.asInstanceOf[Long]; currentEntry = null; ans } - protected def semiclone(half: Int) = new StepsLongFlatHashTable(underlying, i0, half) -} - -////////////////////////// -// Value class adapters // -////////////////////////// - -final class RichHashSetCanStep[T](private val underlying: collection.mutable.HashSet[T]) extends AnyVal with MakesStepper[T, EfficientSubstep] { - override def stepper[S <: Stepper[_]](implicit ss: StepperShape[T, S]) = { - val tbl = CollectionInternals.getTable(underlying) - ((ss.shape: @switch) match { - case StepperShape.IntValue => new StepsIntFlatHashTable (tbl, 0, tbl.length) - case StepperShape.LongValue => new StepsLongFlatHashTable (tbl, 0, tbl.length) - case StepperShape.DoubleValue => new StepsDoubleFlatHashTable(tbl, 0, tbl.length) - case _ => ss.parUnbox(new StepsAnyFlatHashTable[T](tbl, 0, tbl.length)) - }).asInstanceOf[S with EfficientSubstep] - } -} diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsHashTable.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsHashTable.scala deleted file mode 100644 index d75b3d8..0000000 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsHashTable.scala +++ /dev/null @@ -1,209 +0,0 @@ -/* - * 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.compat.java8.converterImpl - -import scala.annotation.switch - -import scala.compat.java8.collectionImpl._ -import scala.compat.java8.runtime._ - -import Stepper._ - -///////////////////////////// -// Stepper implementations // -///////////////////////////// - -// Steppers for keys (type of HashEntry doesn't matter) - -private[java8] class StepsAnyHashTableKey[K](_underlying: Array[AnyRef], _i0: Int, _iN: Int) -extends StepsLikeGapped[K, StepsAnyHashTableKey[K]](_underlying, _i0, _iN) { - def next() = if (currentEntry eq null) throwNSEE else { val ans = CollectionInternals.hashEntryKey[K](currentEntry); currentEntry = CollectionInternals.hashEntryNext(currentEntry); ans } - protected def semiclone(half: Int) = new StepsAnyHashTableKey[K](underlying, i0, half) -} - -private[java8] class StepsDoubleHashTableKey(_underlying: Array[AnyRef], _i0: Int, _iN: Int) -extends StepsDoubleLikeGapped[StepsDoubleHashTableKey](_underlying, _i0, _iN) { - def nextDouble() = if (currentEntry eq null) throwNSEE else { val ans = CollectionInternals.hashEntryKey[Double](currentEntry); currentEntry = CollectionInternals.hashEntryNext(currentEntry); ans } - protected def semiclone(half: Int) = new StepsDoubleHashTableKey(underlying, i0, half) -} - -private[java8] class StepsIntHashTableKey(_underlying: Array[AnyRef], _i0: Int, _iN: Int) -extends StepsIntLikeGapped[StepsIntHashTableKey](_underlying, _i0, _iN) { - def nextInt() = if (currentEntry eq null) throwNSEE else { val ans = CollectionInternals.hashEntryKey[Int](currentEntry); currentEntry = CollectionInternals.hashEntryNext(currentEntry); ans } - protected def semiclone(half: Int) = new StepsIntHashTableKey(underlying, i0, half) -} - -private[java8] class StepsLongHashTableKey(_underlying: Array[AnyRef], _i0: Int, _iN: Int) -extends StepsLongLikeGapped[StepsLongHashTableKey](_underlying, _i0, _iN) { - def nextLong() = if (currentEntry eq null) throwNSEE else { val ans = CollectionInternals.hashEntryKey[Long](currentEntry); currentEntry = CollectionInternals.hashEntryNext(currentEntry); ans } - protected def semiclone(half: Int) = new StepsLongHashTableKey(underlying, i0, half) -} - -// Steppers for entries stored in DefaultEntry HashEntry -// (both for key-value pair and for values alone) - -private[java8] class StepsAnyDefaultHashTable[K, V](_underlying: Array[AnyRef], _i0: Int, _iN: Int) -extends StepsLikeGapped[(K, V), StepsAnyDefaultHashTable[K, V]](_underlying, _i0, _iN) { - def next() = - if (currentEntry eq null) throwNSEE - else { val e = currentEntry; currentEntry = CollectionInternals.hashEntryNext(e); (CollectionInternals.hashEntryKey[K](e), CollectionInternals.defaultEntryValue[V](e)) } - protected def semiclone(half: Int) = - new StepsAnyDefaultHashTable[K, V](underlying, i0, half) -} - -private[java8] class StepsAnyDefaultHashTableValue[K, V](_underlying: Array[AnyRef], _i0: Int, _iN: Int) -extends StepsLikeGapped[V, StepsAnyDefaultHashTableValue[K, V]](_underlying, _i0, _iN) { - def next() = - if (currentEntry eq null) throwNSEE - else { val e = currentEntry; currentEntry = CollectionInternals.hashEntryNext(e); CollectionInternals.defaultEntryValue[V](e) } - protected def semiclone(half: Int) = - new StepsAnyDefaultHashTableValue[K, V](underlying, i0, half) -} - -private[java8] class StepsDoubleDefaultHashTableValue[K](_underlying: Array[AnyRef], _i0: Int, _iN: Int) -extends StepsDoubleLikeGapped[StepsDoubleDefaultHashTableValue[K]](_underlying, _i0, _iN) { - def nextDouble() = - if (currentEntry eq null) throwNSEE - else { val e = currentEntry; currentEntry = CollectionInternals.hashEntryNext(e); CollectionInternals.defaultEntryValue[Double](e) } - protected def semiclone(half: Int) = - new StepsDoubleDefaultHashTableValue[K](underlying, i0, half) -} - -private[java8] class StepsIntDefaultHashTableValue[K](_underlying: Array[AnyRef], _i0: Int, _iN: Int) -extends StepsIntLikeGapped[StepsIntDefaultHashTableValue[K]](_underlying, _i0, _iN) { - def nextInt() = - if (currentEntry eq null) throwNSEE - else { val e = currentEntry; currentEntry = CollectionInternals.hashEntryNext(e); CollectionInternals.defaultEntryValue[Int](e) } - protected def semiclone(half: Int) = - new StepsIntDefaultHashTableValue[K](underlying, i0, half) -} - -private[java8] class StepsLongDefaultHashTableValue[K](_underlying: Array[AnyRef], _i0: Int, _iN: Int) -extends StepsLongLikeGapped[StepsLongDefaultHashTableValue[K]](_underlying, _i0, _iN) { - def nextLong() = - if (currentEntry eq null) throwNSEE - else { val e = currentEntry; currentEntry = CollectionInternals.hashEntryNext(e); CollectionInternals.defaultEntryValue[Long](e) } - protected def semiclone(half: Int) = - new StepsLongDefaultHashTableValue[K](underlying, i0, half) -} - -// Steppers for entries stored in LinkedEntry HashEntry -// (both for key-value pair and for values alone) - -private[java8] class StepsAnyLinkedHashTable[K, V](_underlying: Array[AnyRef], _i0: Int, _iN: Int) -extends StepsLikeGapped[(K, V), StepsAnyLinkedHashTable[K, V]](_underlying, _i0, _iN) { - def next() = - if (currentEntry eq null) throwNSEE - else { val e = currentEntry; currentEntry = CollectionInternals.hashEntryNext(e); (CollectionInternals.hashEntryKey[K](e), CollectionInternals.linkedEntryValue[V](e)) } - protected def semiclone(half: Int) = - new StepsAnyLinkedHashTable[K, V](underlying, i0, half) -} - -private[java8] class StepsAnyLinkedHashTableValue[K, V](_underlying: Array[AnyRef], _i0: Int, _iN: Int) -extends StepsLikeGapped[V, StepsAnyLinkedHashTableValue[K, V]](_underlying, _i0, _iN) { - def next() = - if (currentEntry eq null) throwNSEE - else { val e = currentEntry; currentEntry = CollectionInternals.hashEntryNext(e); CollectionInternals.linkedEntryValue[V](e) } - protected def semiclone(half: Int) = - new StepsAnyLinkedHashTableValue[K, V](underlying, i0, half) -} - -private[java8] class StepsDoubleLinkedHashTableValue[K](_underlying: Array[AnyRef], _i0: Int, _iN: Int) -extends StepsDoubleLikeGapped[StepsDoubleLinkedHashTableValue[K]](_underlying, _i0, _iN) { - def nextDouble() = - if (currentEntry eq null) throwNSEE - else { val e = currentEntry; currentEntry = CollectionInternals.hashEntryNext(e); CollectionInternals.linkedEntryValue[Double](e) } - protected def semiclone(half: Int) = - new StepsDoubleLinkedHashTableValue[K](underlying, i0, half) -} - -private[java8] class StepsIntLinkedHashTableValue[K](_underlying: Array[AnyRef], _i0: Int, _iN: Int) -extends StepsIntLikeGapped[StepsIntLinkedHashTableValue[K]](_underlying, _i0, _iN) { - def nextInt() = - if (currentEntry eq null) throwNSEE - else { val e = currentEntry; currentEntry = CollectionInternals.hashEntryNext(e); CollectionInternals.linkedEntryValue[Int](e) } - protected def semiclone(half: Int) = - new StepsIntLinkedHashTableValue[K](underlying, i0, half) -} - -private[java8] class StepsLongLinkedHashTableValue[K](_underlying: Array[AnyRef], _i0: Int, _iN: Int) -extends StepsLongLikeGapped[StepsLongLinkedHashTableValue[K]](_underlying, _i0, _iN) { - def nextLong() = - if (currentEntry eq null) throwNSEE - else { val e = currentEntry; currentEntry = CollectionInternals.hashEntryNext(e); CollectionInternals.linkedEntryValue[Long](e) } - protected def semiclone(half: Int) = - new StepsLongLinkedHashTableValue[K](underlying, i0, half) -} - - -////////////////////////// -// Value class adapters // -////////////////////////// - -// Steppers for entries stored in DefaultEntry HashEntry - -final class RichHashMapCanStep[K, V](private val underlying: collection.mutable.HashMap[K, V]) extends AnyVal with MakesKeyValueStepper[K, V, EfficientSubstep] with MakesStepper[(K, V), EfficientSubstep] { - def stepper[S <: Stepper[_]](implicit ss: StepperShape[(K, V), S]) = { - val tbl = CollectionInternals.getTable[K, V](underlying) - new StepsAnyDefaultHashTable(tbl, 0, tbl.length).asInstanceOf[S with EfficientSubstep] - } - - def keyStepper[S <: Stepper[_]](implicit ss: StepperShape[K, S]) = { - val tbl = CollectionInternals.getTable[K, V](underlying) - ((ss.shape: @switch) match { - case StepperShape.IntValue => new StepsIntHashTableKey (tbl, 0, tbl.length) - case StepperShape.LongValue => new StepsLongHashTableKey (tbl, 0, tbl.length) - case StepperShape.DoubleValue => new StepsDoubleHashTableKey(tbl, 0, tbl.length) - case _ => ss.parUnbox(new StepsAnyHashTableKey (tbl, 0, tbl.length)) - }).asInstanceOf[S with EfficientSubstep] - } - - def valueStepper[S <: Stepper[_]](implicit ss: StepperShape[V, S]) = { - val tbl = CollectionInternals.getTable[K, V](underlying) - ((ss.shape: @switch) match { - case StepperShape.IntValue => new StepsIntDefaultHashTableValue (tbl, 0, tbl.length) - case StepperShape.LongValue => new StepsLongDefaultHashTableValue (tbl, 0, tbl.length) - case StepperShape.DoubleValue => new StepsDoubleDefaultHashTableValue(tbl, 0, tbl.length) - case _ => ss.parUnbox(new StepsAnyDefaultHashTableValue (tbl, 0, tbl.length)) - }).asInstanceOf[S with EfficientSubstep] - } -} - -// Steppers for entries stored in LinkedEntry HashEntry - -final class RichLinkedHashMapCanStep[K, V](private val underlying: collection.mutable.LinkedHashMap[K, V]) extends AnyVal with MakesKeyValueStepper[K, V, EfficientSubstep] with MakesStepper[(K, V), EfficientSubstep] { - def stepper[S <: Stepper[_]](implicit ss: StepperShape[(K, V), S]) = { - val tbl = CollectionInternals.getTable[K, V](underlying) - new StepsAnyLinkedHashTable(tbl, 0, tbl.length).asInstanceOf[S with EfficientSubstep] - } - - def keyStepper[S <: Stepper[_]](implicit ss: StepperShape[K, S]) = { - val tbl = CollectionInternals.getTable[K, V](underlying) - ((ss.shape: @switch) match { - case StepperShape.IntValue => new StepsIntHashTableKey (tbl, 0, tbl.length) - case StepperShape.LongValue => new StepsLongHashTableKey (tbl, 0, tbl.length) - case StepperShape.DoubleValue => new StepsDoubleHashTableKey(tbl, 0, tbl.length) - case _ => ss.parUnbox(new StepsAnyHashTableKey (tbl, 0, tbl.length)) - }).asInstanceOf[S with EfficientSubstep] - } - - def valueStepper[S <: Stepper[_]](implicit ss: StepperShape[V, S]) = { - val tbl = CollectionInternals.getTable[K, V](underlying) - ((ss.shape: @switch) match { - case StepperShape.IntValue => new StepsIntLinkedHashTableValue (tbl, 0, tbl.length) - case StepperShape.LongValue => new StepsLongLinkedHashTableValue (tbl, 0, tbl.length) - case StepperShape.DoubleValue => new StepsDoubleLinkedHashTableValue(tbl, 0, tbl.length) - case _ => ss.parUnbox(new StepsAnyLinkedHashTableValue (tbl, 0, tbl.length)) - }).asInstanceOf[S with EfficientSubstep] - } -} diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsImmHashSet.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsImmHashSet.scala deleted file mode 100644 index a2a4eeb..0000000 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsImmHashSet.scala +++ /dev/null @@ -1,58 +0,0 @@ -/* - * 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.compat.java8.converterImpl - -import scala.annotation.switch - -import scala.compat.java8.collectionImpl._ - -///////////////////////////// -// Stepper implementations // -///////////////////////////// - -private[java8] class StepsAnyImmHashSet[A](_underlying: Iterator[A], _N: Int) -extends StepsLikeTrieIterator[A, StepsAnyImmHashSet[A]](_underlying, _N) { - protected def demiclone(it: Iterator[A], N: Int) = new StepsAnyImmHashSet(it, N) - def next(): A = { val ans = underlying.next(); i += 1; ans } -} - -private[java8] class StepsDoubleImmHashSet(_underlying: Iterator[Double], _N: Int) -extends StepsDoubleLikeTrieIterator[StepsDoubleImmHashSet](_underlying, _N) { - protected def demiclone(it: Iterator[Double], N: Int) = new StepsDoubleImmHashSet(it, N) - def nextDouble() = { val ans = underlying.next(); i += 1; ans } -} - -private[java8] class StepsIntImmHashSet(_underlying: Iterator[Int], _N: Int) -extends StepsIntLikeTrieIterator[StepsIntImmHashSet](_underlying, _N) { - protected def demiclone(it: Iterator[Int], N: Int) = new StepsIntImmHashSet(it, N) - def nextInt() = { val ans = underlying.next(); i += 1; ans } -} - -private[java8] class StepsLongImmHashSet(_underlying: Iterator[Long], _N: Int) -extends StepsLongLikeTrieIterator[StepsLongImmHashSet](_underlying, _N) { - protected def demiclone(it: Iterator[Long], N: Int) = new StepsLongImmHashSet(it, N) - def nextLong() = { val ans = underlying.next(); i += 1; ans } -} - -////////////////////////// -// Value class adapters // -////////////////////////// - -final class RichImmHashSetCanStep[T](private val underlying: collection.immutable.HashSet[T]) extends AnyVal with MakesStepper[T, EfficientSubstep] { - def stepper[S <: Stepper[_]](implicit ss: StepperShape[T, S]) = ((ss.shape: @switch) match { - case StepperShape.IntValue => new StepsIntImmHashSet (underlying.iterator.asInstanceOf[Iterator[Int]], underlying.size) - case StepperShape.LongValue => new StepsLongImmHashSet (underlying.iterator.asInstanceOf[Iterator[Long]], underlying.size) - case StepperShape.DoubleValue => new StepsDoubleImmHashSet(underlying.iterator.asInstanceOf[Iterator[Double]], underlying.size) - case _ => ss.parUnbox(new StepsAnyImmHashSet[T](underlying.iterator, underlying.size)) - }).asInstanceOf[S with EfficientSubstep] -} diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsIndexedSeq.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsIndexedSeq.scala deleted file mode 100644 index abf9485..0000000 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsIndexedSeq.scala +++ /dev/null @@ -1,58 +0,0 @@ -/* - * 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.compat.java8.converterImpl - -import scala.annotation.switch -import scala.compat.java8.collectionImpl._ -import Stepper._ - -///////////////////////////// -// Stepper implementations // -///////////////////////////// - -private[java8] class StepsAnyIndexedSeq[A](underlying: collection.IndexedSeqOps[A, Any, _], _i0: Int, _iN: Int) -extends StepsLikeIndexed[A, StepsAnyIndexedSeq[A]](_i0, _iN) { - def next() = if (hasNext) { val j = i0; i0 += 1; underlying(j) } else throwNSEE - protected def semiclone(half: Int) = new StepsAnyIndexedSeq[A](underlying, i0, half) -} - -private[java8] class StepsDoubleIndexedSeq[CC <: collection.IndexedSeqOps[Double, Any, _]](underlying: CC, _i0: Int, _iN: Int) -extends StepsDoubleLikeIndexed[StepsDoubleIndexedSeq[CC]](_i0, _iN) { - def nextDouble() = if (hasNext) { val j = i0; i0 += 1; underlying(j) } else throwNSEE - protected def semiclone(half: Int) = new StepsDoubleIndexedSeq[CC](underlying, i0, half) -} - -private[java8] class StepsIntIndexedSeq[CC <: collection.IndexedSeqOps[Int, Any, _]](underlying: CC, _i0: Int, _iN: Int) -extends StepsIntLikeIndexed[StepsIntIndexedSeq[CC]](_i0, _iN) { - def nextInt() = if (hasNext) { val j = i0; i0 += 1; underlying(j) } else throwNSEE - protected def semiclone(half: Int) = new StepsIntIndexedSeq[CC](underlying, i0, half) -} - -private[java8] class StepsLongIndexedSeq[CC <: collection.IndexedSeqOps[Long, Any, _]](underlying: CC, _i0: Int, _iN: Int) -extends StepsLongLikeIndexed[StepsLongIndexedSeq[CC]](_i0, _iN) { - def nextLong() = if (hasNext) { val j = i0; i0 += 1; underlying(j) } else throwNSEE - protected def semiclone(half: Int) = new StepsLongIndexedSeq[CC](underlying, i0, half) -} - -////////////////////////// -// Value class adapters // -////////////////////////// - -final class RichIndexedSeqCanStep[T](private val underlying: collection.IndexedSeqOps[T, Any, _]) extends AnyVal with MakesStepper[T, EfficientSubstep] { - def stepper[S <: Stepper[_]](implicit ss: StepperShape[T, S]) = ((ss.shape: @switch) match { - case StepperShape.IntValue => new StepsIntIndexedSeq (underlying.asInstanceOf[collection.IndexedSeqOps[Int, Any, _]], 0, underlying.length) - case StepperShape.LongValue => new StepsLongIndexedSeq (underlying.asInstanceOf[collection.IndexedSeqOps[Long, Any, _]], 0, underlying.length) - case StepperShape.DoubleValue => new StepsDoubleIndexedSeq(underlying.asInstanceOf[collection.IndexedSeqOps[Double, Any, _]], 0, underlying.length) - case _ => ss.parUnbox(new StepsAnyIndexedSeq[T](underlying, 0, underlying.length)) - }).asInstanceOf[S with EfficientSubstep] -} diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsIterable.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsIterable.scala deleted file mode 100644 index 4343206..0000000 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsIterable.scala +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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.compat.java8.converterImpl - -import scala.annotation.switch - -import scala.compat.java8.collectionImpl._ - -// Iterables just defer to iterator unless they can pattern match something better. -// TODO: implement pattern matching! - -final class RichIterableCanStep[T](private val underlying: Iterable[T]) extends AnyVal with MakesStepper[T, Any] { - override def stepper[S <: Stepper[_]](implicit ss: StepperShape[T, S]) = ((ss.shape: @switch) match { - case StepperShape.IntValue => new StepsIntIterator (underlying.iterator.asInstanceOf[Iterator[Int]]) - case StepperShape.LongValue => new StepsLongIterator (underlying.iterator.asInstanceOf[Iterator[Long]]) - case StepperShape.DoubleValue => new StepsDoubleIterator(underlying.iterator.asInstanceOf[Iterator[Double]]) - case _ => ss.seqUnbox(new StepsAnyIterator[T](underlying.iterator)) - }).asInstanceOf[S] -} diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsIterator.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsIterator.scala deleted file mode 100644 index fd2e17b..0000000 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsIterator.scala +++ /dev/null @@ -1,58 +0,0 @@ -/* - * 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.compat.java8.converterImpl - -import scala.annotation.switch - -import scala.compat.java8.collectionImpl._ - -///////////////////////////// -// Stepper implementations // -///////////////////////////// - -private[java8] class StepsAnyIterator[A](_underlying: Iterator[A]) -extends StepsLikeIterator[A, StepsAnyIterator[A]](_underlying) { - protected def semiclone() = new StepsAnyIterator(null) - def next() = if (proxied ne null) proxied.nextStep() else underlying.next() -} - -private[java8] class StepsDoubleIterator(_underlying: Iterator[Double]) -extends StepsDoubleLikeIterator[StepsDoubleIterator](_underlying) { - protected def semiclone() = new StepsDoubleIterator(null) - def nextDouble() = if (proxied ne null) proxied.nextStep() else underlying.next() -} - -private[java8] class StepsIntIterator(_underlying: Iterator[Int]) -extends StepsIntLikeIterator[StepsIntIterator](_underlying) { - protected def semiclone() = new StepsIntIterator(null) - def nextInt() = if (proxied ne null) proxied.nextStep() else underlying.next() -} - -private[java8] class StepsLongIterator(_underlying: Iterator[Long]) -extends StepsLongLikeIterator[StepsLongIterator](_underlying) { - protected def semiclone() = new StepsLongIterator(null) - def nextLong() = if (proxied ne null) proxied.nextStep() else underlying.next() -} - -////////////////////////// -// Value class adapters // -////////////////////////// - -final class RichIteratorCanStep[T](private val underlying: Iterator[T]) extends AnyVal with MakesStepper[T, Any] { - def stepper[S <: Stepper[_]](implicit ss: StepperShape[T, S]) = ((ss.shape: @switch) match { - case StepperShape.IntValue => new StepsIntIterator (underlying.asInstanceOf[Iterator[Int]]) - case StepperShape.LongValue => new StepsLongIterator (underlying.asInstanceOf[Iterator[Long]]) - case StepperShape.DoubleValue => new StepsDoubleIterator(underlying.asInstanceOf[Iterator[Double]]) - case _ => ss.seqUnbox(new StepsAnyIterator[T](underlying)) - }).asInstanceOf[S] -} diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeGapped.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeGapped.scala deleted file mode 100644 index e17ff2a..0000000 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeGapped.scala +++ /dev/null @@ -1,79 +0,0 @@ -/* - * 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.compat.java8.converterImpl - -import scala.compat.java8.collectionImpl._ -import Stepper._ - -/** Abstracts all the generic operations of stepping over a backing array - * for some collection where the elements are stored generically and some - * may be missing. Subclasses should set `currentEntry` to `null` when it - * is used as a signal to look for more entries in the array. (This also - * allows a subclass to traverse a sublist by updating `currentEntry`.) - */ -private[java8] abstract class AbstractStepsLikeGapped[Sub >: Null, Semi <: Sub](protected val underlying: Array[AnyRef], protected var i0: Int, protected var iN: Int) - extends EfficientSubstep { - - protected var currentEntry: AnyRef = null - protected def semiclone(half: Int): Semi - def characteristics: Int = Ordered - def estimateSize(): Long = if (!hasNext) 0 else iN - i0 - def hasNext: Boolean = currentEntry != null || (i0 < iN && { - do { currentEntry = underlying(i0); i0 += 1 } while (currentEntry == null && i0 < iN) - currentEntry != null - }) - def substep(): Sub = { - if (iN-1 > i0) { - val half = (i0+iN) >>> 1 - val ans = semiclone(half) - i0 = half - ans - } - else null - } -} - -/** Abstracts the process of stepping through an incompletely filled array of `AnyRefs` - * and interpreting the contents as the elements of a collection. - */ -private[java8] abstract class StepsLikeGapped[A, STA >: Null <: StepsLikeGapped[A, _]](_underlying: Array[AnyRef], _i0: Int, _iN: Int) - extends AbstractStepsLikeGapped[AnyStepper[A], STA](_underlying, _i0, _iN) - with AnyStepper[A] -{} - -/** Abstracts the process of stepping through an incompletely filled array of `AnyRefs` - * and interpreting the contents as the elements of a collection of `Double`s. Subclasses - * are responsible for unboxing the `AnyRef` inside `nextDouble`. - */ -private[java8] abstract class StepsDoubleLikeGapped[STD >: Null <: StepsDoubleLikeGapped[_]](_underlying: Array[AnyRef], _i0: Int, _iN: Int) - extends AbstractStepsLikeGapped[DoubleStepper, STD](_underlying, _i0, _iN) - with DoubleStepper -{} - -/** Abstracts the process of stepping through an incompletely filled array of `AnyRefs` - * and interpreting the contents as the elements of a collection of `Int`s. Subclasses - * are responsible for unboxing the `AnyRef` inside `nextInt`. - */ -private[java8] abstract class StepsIntLikeGapped[STI >: Null <: StepsIntLikeGapped[_]](_underlying: Array[AnyRef], _i0: Int, _iN: Int) - extends AbstractStepsLikeGapped[IntStepper, STI](_underlying, _i0, _iN) - with IntStepper -{} - -/** Abstracts the process of stepping through an incompletely filled array of `AnyRefs` - * and interpreting the contents as the elements of a collection of `Long`s. Subclasses - * are responsible for unboxing the `AnyRef` inside `nextLong`. - */ -private[java8] abstract class StepsLongLikeGapped[STL >: Null <: StepsLongLikeGapped[_]](_underlying: Array[AnyRef], _i0: Int, _iN: Int) - extends AbstractStepsLikeGapped[LongStepper, STL](_underlying, _i0, _iN) - with LongStepper -{} diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeIndexed.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeIndexed.scala deleted file mode 100644 index dc386e0..0000000 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeIndexed.scala +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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.compat.java8.converterImpl - -import scala.compat.java8.collectionImpl._ -import Stepper._ - -/** Abstracts all the generic operations of stepping over an indexable collection */ -private[java8] abstract class AbstractStepsLikeIndexed[Sub >: Null, Semi <: Sub](protected var i0: Int, protected var iN: Int) - extends EfficientSubstep { - - protected def semiclone(half: Int): Semi - def characteristics: Int = Ordered + Sized + SubSized - def estimateSize(): Long = iN - i0 - def hasNext: Boolean = i0 < iN - def substep(): Sub = { - if (iN-1 > i0) { - val half = (i0+iN) >>> 1 - val ans = semiclone(half) - i0 = half - ans - } - else null - } -} - -/** Abstracts the operation of stepping over a generic indexable collection */ -private[java8] abstract class StepsLikeIndexed[A, STA >: Null <: StepsLikeIndexed[A, _]](_i0: Int, _iN: Int) - extends AbstractStepsLikeIndexed[AnyStepper[A], STA](_i0, _iN) - with AnyStepper[A] -{} - -/** Abstracts the operation of stepping over an indexable collection of Doubles */ -private[java8] abstract class StepsDoubleLikeIndexed[STD >: Null <: StepsDoubleLikeIndexed[_]](_i0: Int, _iN: Int) - extends AbstractStepsLikeIndexed[DoubleStepper, STD](_i0, _iN) - with DoubleStepper - with java.util.Spliterator.OfDouble // Compiler wants this for mixin forwarder -{} - -/** Abstracts the operation of stepping over an indexable collection of Ints */ -private[java8] abstract class StepsIntLikeIndexed[STI >: Null <: StepsIntLikeIndexed[_]](_i0: Int, _iN: Int) - extends AbstractStepsLikeIndexed[IntStepper, STI](_i0, _iN) - with IntStepper - with java.util.Spliterator.OfInt // Compiler wants this for mixin forwarder -{} - -/** Abstracts the operation of stepping over an indexable collection of Longs */ -private[java8] abstract class StepsLongLikeIndexed[STL >: Null <: StepsLongLikeIndexed[_]](_i0: Int, _iN: Int) - extends AbstractStepsLikeIndexed[LongStepper, STL](_i0, _iN) - with LongStepper - with java.util.Spliterator.OfLong // Compiler wants this for mixin forwarder -{} diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeIterator.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeIterator.scala deleted file mode 100644 index f5695d2..0000000 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeIterator.scala +++ /dev/null @@ -1,118 +0,0 @@ -/* - * 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.compat.java8.converterImpl - -import scala.compat.java8.collectionImpl._ -import Stepper._ - -/** Common functionality for Steppers that step through an Iterator, caching the results as needed when a split is requested. */ -private[java8] abstract class AbstractStepsLikeIterator[A, SP >: Null <: Stepper[A], Semi <: SP](final protected var underlying: Iterator[A]) { - final protected var nextChunkSize = 16 - final protected var proxied: SP = null - protected def semiclone(): Semi // Must initialize with null iterator! - def characteristics: Int = if (proxied ne null) Ordered | Sized | SubSized else Ordered - def estimateSize(): Long = if (proxied ne null) proxied.knownSize else Long.MaxValue - def hasNext: Boolean = if (proxied ne null) proxied.hasStep else underlying.hasNext -} - -/** Abstracts the operation of stepping over an iterator (that needs to be cached when splitting) */ -private[java8] abstract class StepsLikeIterator[A, SLI >: Null <: StepsLikeIterator[A, SLI] with AnyStepper[A]](_underlying: Iterator[A]) - extends AbstractStepsLikeIterator[A, AnyStepper[A], SLI](_underlying) - with AnyStepper[A] -{ - override def substep(): AnyStepper[A] = if (proxied ne null) proxied.substep() else { - val acc = new Accumulator[A] - var i = 0 - val n = (nextChunkSize & 0xFFFFFFFC) - while (i < n && underlying.hasNext) { acc += underlying.next(); i += 1 } - if (i < n || !underlying.hasNext) { - proxied = acc.stepper - proxied.substep() - } - else { - val ans = semiclone() - ans.proxied = acc.stepper - nextChunkSize = if ((nextChunkSize&3) == 3) { if (n < 0x40000000) n*2 else n } else nextChunkSize + 1 - ans - } - } -} - -/** Abstracts the operation of stepping over an iterator of Doubles (needs caching when split) */ -private[java8] abstract class StepsDoubleLikeIterator[SLI >: Null <: StepsDoubleLikeIterator[SLI] with DoubleStepper](_underlying: Iterator[Double]) - extends AbstractStepsLikeIterator[Double, DoubleStepper, SLI](_underlying) - with DoubleStepper -{ - override def substep(): DoubleStepper = if (proxied ne null) proxied.substep() else { - val acc = new DoubleAccumulator - var i = 0 - val n = (nextChunkSize & 0xFFFFFFFC) - while (i < n && underlying.hasNext) { acc += underlying.next(); i += 1 } - if (i < n || !underlying.hasNext) { - proxied = acc.stepper - proxied.substep() - } - else { - val ans = semiclone() - ans.proxied = acc.stepper - nextChunkSize = if ((nextChunkSize&3) == 3) { if (n < 0x40000000) n*2 else n } else nextChunkSize + 1 - ans - } - } -} - -/** Abstracts the operation of stepping over an iterator of Ints (needs caching when split) */ -private[java8] abstract class StepsIntLikeIterator[SLI >: Null <: StepsIntLikeIterator[SLI] with IntStepper](_underlying: Iterator[Int]) - extends AbstractStepsLikeIterator[Int, IntStepper, SLI](_underlying) - with IntStepper -{ - override def substep(): IntStepper = if (proxied ne null) proxied.substep() else { - val acc = new IntAccumulator - var i = 0 - val n = (nextChunkSize & 0xFFFFFFFC) - while (i < n && underlying.hasNext) { acc += underlying.next(); i += 1 } - if (i < n || !underlying.hasNext) { - proxied = acc.stepper - proxied.substep() - } - else { - val ans = semiclone() - ans.proxied = acc.stepper - nextChunkSize = if ((nextChunkSize&3) == 3) { if (n < 0x40000000) n*2 else n } else nextChunkSize + 1 - ans - } - } -} - -/** Abstracts the operation of stepping over an iterator of Longs (needs caching when split) */ -private[java8] abstract class StepsLongLikeIterator[SLI >: Null <: StepsLongLikeIterator[SLI] with LongStepper](_underlying: Iterator[Long]) - extends AbstractStepsLikeIterator[Long, LongStepper, SLI](_underlying) - with LongStepper -{ - override def substep(): LongStepper = if (proxied ne null) proxied.substep() else { - val acc = new LongAccumulator - var i = 0 - val n = (nextChunkSize & 0xFFFFFFFC) - while (i < n && underlying.hasNext) { acc += underlying.next(); i += 1 } - if (i < n || !underlying.hasNext) { - proxied = acc.stepper - proxied.substep() - } - else { - val ans = semiclone() - ans.proxied = acc.stepper - nextChunkSize = if ((nextChunkSize&3) == 3) { if (n < 0x40000000) n*2 else n } else nextChunkSize + 1 - ans - } - } -} diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeSliced.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeSliced.scala deleted file mode 100644 index 1044481..0000000 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeSliced.scala +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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.compat.java8.converterImpl - -import scala.compat.java8.collectionImpl._ -import Stepper._ - -/** Abstracts all the generic operations of stepping over a collection that can be sliced into pieces. - * `next` must update `i` but not `i0` so that later splitting steps can keep track of whether the - * collection needs some sort of modification before transmission to the subclass. - */ -private[java8] abstract class AbstractStepsLikeSliced[Coll, Sub >: Null, Semi <: Sub](protected var underlying: Coll, protected var i: Int, protected var iN: Int) - extends EfficientSubstep { - - protected var i0: Int = i - protected def semiclone(halfHint: Int): Semi // Must really do all the work for both this and cloned collection! - def characteristics: Int = Ordered - def estimateSize(): Long = iN - i - def substep(): Sub = if (estimateSize > 0) semiclone((iN + i) >>> 1) else null -} - -/** Abstracts the operation of stepping over a generic collection that can be efficiently sliced or otherwise subdivided */ -private[java8] abstract class StepsLikeSliced[A, AA, STA >: Null <: StepsLikeSliced[A, AA, _]](_underlying: AA, _i0: Int, _iN: Int) - extends AbstractStepsLikeSliced[AA, AnyStepper[A], STA](_underlying, _i0, _iN) - with AnyStepper[A] -{} - -/** Abstracts the operation of stepping over a collection of Doubles that can be efficiently sliced or otherwise subdivided */ -private[java8] abstract class StepsDoubleLikeSliced[AA, STA >: Null <: StepsDoubleLikeSliced[AA, STA]](_underlying: AA, _i0: Int, _iN: Int) - extends AbstractStepsLikeSliced[AA, DoubleStepper, STA](_underlying, _i0, _iN) - with DoubleStepper -{} - -/** Abstracts the operation of stepping over a collection of Ints that can be efficiently sliced or otherwise subdivided */ -private[java8] abstract class StepsIntLikeSliced[AA, STA >: Null <: StepsIntLikeSliced[AA, STA]](_underlying: AA, _i0: Int, _iN: Int) - extends AbstractStepsLikeSliced[AA, IntStepper, STA](_underlying, _i0, _iN) - with IntStepper -{} - -/** Abstracts the operation of stepping over a collection of Longs that can be efficiently sliced or otherwise subdivided */ -private[java8] abstract class StepsLongLikeSliced[AA, STA >: Null <: StepsLongLikeSliced[AA, STA]](_underlying: AA, _i0: Int, _iN: Int) - extends AbstractStepsLikeSliced[AA, LongStepper, STA](_underlying, _i0, _iN) - with LongStepper -{} diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeTrieIterator.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeTrieIterator.scala deleted file mode 100644 index 1c2334b..0000000 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeTrieIterator.scala +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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.compat.java8.converterImpl - -import scala.compat.java8.collectionImpl._ -import Stepper._ - -/** Abstracts all the generic operations of stepping over a TrieIterator by asking itself to - * slice itself into pieces. Note that `i` must be kept up to date in subclasses. - */ -private[java8] trait AbstractStepsLikeTrieIterator[A, Sub >: Null, Semi >: Null <: Sub with AbstractStepsLikeTrieIterator[A, Sub, _]] -extends AbstractStepsLikeSliced[Iterator[A], Sub, Semi] { - protected def demiclone(it: Iterator[A], N: Int): Semi - override def characteristics = Immutable - def hasNext: Boolean = underlying.hasNext - protected def semiclone(halfHint: Int): Semi = - if (!underlying.hasNext || i > iN-2) null - else scala.compat.java8.runtime.CollectionInternals.trieIteratorSplit(underlying) match { - case null => null - case ((pre: Iterator[A], pno), post: Iterator[A]) => - val pn = (pno: Any) match { case i: Int => i; case _ => throw new Exception("Unexpected type") } - val ans = demiclone(pre, pn) - i += pn - underlying = post - i0 = i - ans - case _ => null - } -} - -private[java8] abstract class StepsLikeTrieIterator[A, STI >: Null <: StepsLikeTrieIterator[A, _]](_underlying: Iterator[A], _N: Int) - extends StepsLikeSliced[A, Iterator[A], STI](_underlying, 0, _N) - with AbstractStepsLikeTrieIterator[A, AnyStepper[A], STI] -{} - -private[java8] abstract class StepsDoubleLikeTrieIterator[STI >: Null <: StepsDoubleLikeTrieIterator[STI]](_underlying: Iterator[Double], _N: Int) - extends StepsDoubleLikeSliced[Iterator[Double], STI](_underlying, 0, _N) - with AbstractStepsLikeTrieIterator[Double, DoubleStepper, STI] -{} - -private[java8] abstract class StepsIntLikeTrieIterator[STI >: Null <: StepsIntLikeTrieIterator[STI]](_underlying: Iterator[Int], _N: Int) - extends StepsIntLikeSliced[Iterator[Int], STI](_underlying, 0, _N) - with AbstractStepsLikeTrieIterator[Int, IntStepper, STI] -{} - -private[java8] abstract class StepsLongLikeTrieIterator[STI >: Null <: StepsLongLikeTrieIterator[STI]](_underlying: Iterator[Long], _N: Int) - extends StepsLongLikeSliced[Iterator[Long], STI](_underlying, 0, _N) - with AbstractStepsLikeTrieIterator[Long, LongStepper, STI] -{} diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsLinearSeq.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsLinearSeq.scala deleted file mode 100644 index 52b0d0e..0000000 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsLinearSeq.scala +++ /dev/null @@ -1,68 +0,0 @@ -/* - * 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.compat.java8.converterImpl - -import scala.annotation.switch - -import scala.compat.java8.collectionImpl._ - -import Stepper._ - -///////////////////////////// -// Stepper implementations // -///////////////////////////// - -private[java8] class StepsAnyLinearSeq[A](_underlying: collection.LinearSeq[A], _maxN: Long) -extends StepsWithTail[A, collection.LinearSeq[A], StepsAnyLinearSeq[A]](_underlying, _maxN) { - protected def myIsEmpty(cc: collection.LinearSeq[A]): Boolean = cc.isEmpty - protected def myTailOf(cc: collection.LinearSeq[A]) = cc.tail - def next() = if (hasNext) { maxN -= 1; val ans = underlying.head; underlying = underlying.tail; ans } else throwNSEE - protected def semiclone(half: Int) = new StepsAnyLinearSeq[A](underlying, half) -} - -private[java8] class StepsDoubleLinearSeq(_underlying: collection.LinearSeq[Double], _maxN: Long) -extends StepsDoubleWithTail[collection.LinearSeq[Double], StepsDoubleLinearSeq](_underlying, _maxN) { - protected def myIsEmpty(cc: collection.LinearSeq[Double]): Boolean = cc.isEmpty - protected def myTailOf(cc: collection.LinearSeq[Double]) = cc.tail - def nextDouble() = if (hasNext) { maxN -= 1; val ans = underlying.head; underlying = underlying.tail; ans } else throwNSEE - protected def semiclone(half: Int) = new StepsDoubleLinearSeq(underlying, half) -} - -private[java8] class StepsIntLinearSeq(_underlying: collection.LinearSeq[Int], _maxN: Long) -extends StepsIntWithTail[collection.LinearSeq[Int], StepsIntLinearSeq](_underlying, _maxN) { - protected def myIsEmpty(cc: collection.LinearSeq[Int]): Boolean = cc.isEmpty - protected def myTailOf(cc: collection.LinearSeq[Int]) = cc.tail - def nextInt() = if (hasNext) { maxN -= 1; val ans = underlying.head; underlying = underlying.tail; ans } else throwNSEE - protected def semiclone(half: Int) = new StepsIntLinearSeq(underlying, half) -} - -private[java8] class StepsLongLinearSeq(_underlying: collection.LinearSeq[Long], _maxN: Long) -extends StepsLongWithTail[collection.LinearSeq[Long], StepsLongLinearSeq](_underlying, _maxN) { - protected def myIsEmpty(cc: collection.LinearSeq[Long]): Boolean = cc.isEmpty - protected def myTailOf(cc: collection.LinearSeq[Long]) = cc.tail - def nextLong() = if (hasNext) { maxN -= 1; val ans = underlying.head; underlying = underlying.tail; ans } else throwNSEE - protected def semiclone(half: Int) = new StepsLongLinearSeq(underlying, half) -} - -////////////////////////// -// Value class adapters // -////////////////////////// - -final class RichLinearSeqCanStep[T](private val underlying: collection.LinearSeq[T]) extends AnyVal with MakesStepper[T, Any] { - def stepper[S <: Stepper[_]](implicit ss: StepperShape[T, S]) = ((ss.shape: @switch) match { - case StepperShape.IntValue => new StepsIntLinearSeq (underlying.asInstanceOf[collection.LinearSeq[Int]], Long.MaxValue) - case StepperShape.LongValue => new StepsLongLinearSeq (underlying.asInstanceOf[collection.LinearSeq[Long]], Long.MaxValue) - case StepperShape.DoubleValue => new StepsDoubleLinearSeq(underlying.asInstanceOf[collection.LinearSeq[Double]], Long.MaxValue) - case _ => ss.seqUnbox(new StepsAnyLinearSeq[T](underlying, Long.MaxValue)) - }).asInstanceOf[S] -} diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsMap.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsMap.scala deleted file mode 100644 index c6e8862..0000000 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsMap.scala +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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.compat.java8.converterImpl - -import scala.annotation.switch - -import scala.compat.java8.collectionImpl._ - -// Generic maps defer to the iterator steppers if a more precise type cannot be found via pattern matching -// TODO: implement pattern matching - -final class RichMapCanStep[K, V](private val underlying: collection.Map[K, V]) extends AnyVal with MakesKeyValueStepper[K, V, Any] { - // No generic stepper because RichIterableCanStep will get that anyway, and we don't pattern match here - - def keyStepper[S <: Stepper[_]](implicit ss: StepperShape[K, S]) = ((ss.shape: @switch) match { - case StepperShape.IntValue => new StepsIntIterator (underlying.keysIterator.asInstanceOf[Iterator[Int]]) - case StepperShape.LongValue => new StepsLongIterator (underlying.keysIterator.asInstanceOf[Iterator[Long]]) - case StepperShape.DoubleValue => new StepsDoubleIterator(underlying.keysIterator.asInstanceOf[Iterator[Double]]) - case _ => ss.seqUnbox(new StepsAnyIterator (underlying.keysIterator)) - }).asInstanceOf[S] - - def valueStepper[S <: Stepper[_]](implicit ss: StepperShape[V, S]) = ((ss.shape: @switch) match { - case StepperShape.IntValue => new StepsIntIterator (underlying.valuesIterator.asInstanceOf[Iterator[Int]]) - case StepperShape.LongValue => new StepsLongIterator (underlying.valuesIterator.asInstanceOf[Iterator[Long]]) - case StepperShape.DoubleValue => new StepsDoubleIterator(underlying.valuesIterator.asInstanceOf[Iterator[Double]]) - case _ => ss.seqUnbox(new StepsAnyIterator (underlying.valuesIterator)) - }).asInstanceOf[S] -} diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsRange.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsRange.scala deleted file mode 100644 index fdeaaf8..0000000 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsRange.scala +++ /dev/null @@ -1,64 +0,0 @@ -/* - * 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.compat.java8.converterImpl - -import scala.annotation.switch - -import scala.compat.java8.collectionImpl._ - -import Stepper._ - -///////////////////////////// -// Stepper implementations // -///////////////////////////// - -private[java8] class StepsIntRange(underlying: Range, _i0: Int, _iN: Int) -extends StepsIntLikeIndexed[StepsIntRange](_i0, _iN) { - def nextInt() = if (hasNext) { val j = i0; i0 += 1; underlying(j) } else throwNSEE - protected def semiclone(half: Int) = new StepsIntRange(underlying, i0, half) -} - -private[java8] class StepsAnyNumericRange[T](underlying: collection.immutable.NumericRange[T], _i0: Int, _iN: Int) -extends StepsLikeIndexed[T, StepsAnyNumericRange[T]](_i0, _iN) { - def next() = if (hasNext) { val j = i0; i0 += 1; underlying(j) } else throwNSEE - protected def semiclone(half: Int) = new StepsAnyNumericRange[T](underlying, i0, half) -} - -private[java8] class StepsIntNumericRange(underlying: collection.immutable.NumericRange[Int], _i0: Int, _iN: Int) -extends StepsIntLikeIndexed[StepsIntNumericRange](_i0, _iN) { - def nextInt() = if (hasNext) { val j = i0; i0 += 1; underlying(j) } else throwNSEE - protected def semiclone(half: Int) = new StepsIntNumericRange(underlying, i0, half) -} - -private[java8] class StepsLongNumericRange(underlying: collection.immutable.NumericRange[Long], _i0: Int, _iN: Int) -extends StepsLongLikeIndexed[StepsLongNumericRange](_i0, _iN) { - def nextLong() = if (hasNext) { val j = i0; i0 += 1; underlying(j) } else throwNSEE - protected def semiclone(half: Int) = new StepsLongNumericRange(underlying, i0, half) -} - -////////////////////////// -// Value class adapters // -////////////////////////// - -final class RichRangeCanStep[T](private val underlying: Range) extends AnyVal with MakesStepper[Int, EfficientSubstep] { - def stepper[S <: Stepper[_]](implicit ss: StepperShape[Int, S]) = - new StepsIntRange(underlying, 0, underlying.length).asInstanceOf[S with EfficientSubstep] -} - -final class RichNumericRangeCanStep[T](private val underlying: collection.immutable.NumericRange[T]) extends AnyVal with MakesStepper[T, EfficientSubstep] { - def stepper[S <: Stepper[_]](implicit ss: StepperShape[T, S]) = ((ss.shape: @switch) match { - case StepperShape.IntValue => new StepsIntNumericRange (underlying.asInstanceOf[collection.immutable.NumericRange[Int]], 0, underlying.length) - case StepperShape.LongValue => new StepsLongNumericRange (underlying.asInstanceOf[collection.immutable.NumericRange[Long]], 0, underlying.length) - case _ => ss.parUnbox(new StepsAnyNumericRange[T](underlying, 0, underlying.length)) - }).asInstanceOf[S with EfficientSubstep] -} diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsString.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsString.scala deleted file mode 100644 index 0f15fc9..0000000 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsString.scala +++ /dev/null @@ -1,61 +0,0 @@ -/* - * 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.compat.java8.converterImpl - -import scala.compat.java8.collectionImpl._ - -import Stepper._ - -//////////////////////////// -// Stepper implementation // -//////////////////////////// - -private[java8] class StepperStringChar(underlying: CharSequence, _i0: Int, _iN: Int) - extends StepsIntLikeIndexed[StepperStringChar](_i0, _iN) { - def nextInt() = if (hasNext) { val j = i0; i0 += 1; underlying.charAt(j) } else throwNSEE - protected def semiclone(half: Int) = new StepperStringChar(underlying, i0, half) -} - -private[java8] class StepperStringCodePoint(underlying: String, var i0: Int, var iN: Int) extends IntStepper with EfficientSubstep { - def characteristics = NonNull - def estimateSize = iN - i0 - def hasNext = i0 < iN - def nextInt() = { - if (hasNext) { - val cp = underlying.codePointAt(i0) - i0 += java.lang.Character.charCount(cp) - cp - } - else throwNSEE - } - def substep() = { - if (iN-3 > i0) { - var half = (i0+iN) >>> 1 - if (java.lang.Character.isLowSurrogate(underlying.charAt(half))) half -= 1 - val ans = new StepperStringCodePoint(underlying, i0, half) - i0 = half - ans - } - else null - } -} - -///////////////////////// -// Value class adapter // -///////////////////////// - -final class RichStringCanStep(private val underlying: String) extends AnyVal with MakesStepper[Char, EfficientSubstep] { - def stepper[S <: Stepper[_]](implicit ss: StepperShape[Char, S]) = charStepper.asInstanceOf[S with EfficientSubstep] - @inline def charStepper: IntStepper with EfficientSubstep = new StepperStringChar(underlying, 0, underlying.length) - @inline def codepointStepper: IntStepper with EfficientSubstep = new StepperStringCodePoint(underlying, 0, underlying.length) -} diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsVector.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsVector.scala deleted file mode 100644 index 5cefaef..0000000 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsVector.scala +++ /dev/null @@ -1,202 +0,0 @@ -/* - * 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.compat.java8.converterImpl - -import scala.annotation.switch - -import scala.collection.immutable.VectorIterator - -import scala.compat.java8.collectionImpl._ -import scala.compat.java8.runtime._ - -import Stepper._ - -///////////////////////////// -// Stepper implementations // -///////////////////////////// - -private[java8] trait StepsVectorLike[A] { - protected def myVector: Vector[A] - protected def myVectorIterator: VectorIterator[A] - protected def myVectorLength: Int - protected var index: Int = 32 - protected var data: Array[AnyRef] = null - protected var index1: Int = 32 - protected var data1: Array[AnyRef] = null - protected final def advanceData(iX: Int): Unit = { - index1 += 1 - if (index >= 32) { - if (myVector != null) initTo(iX) - else initVpTo(iX) - } - else { - data = data1(index1).asInstanceOf[Array[AnyRef]] - index = 0 - } - } - protected final def initTo(iX: Int): Unit = { - // WARNING--initVpTo is an exact copy of this except for the type! If you change one you must change the other! - // (Manually specialized this way for speed.) - myVectorLength match { - case x if x <= 0x20 => - index = iX - data = CollectionInternals.getDisplay0(myVector) - case x if x <= 0x400 => - index1 = iX >>> 5 - data1 = CollectionInternals.getDisplay1(myVector) - index = iX & 0x1F - data = data1(index1).asInstanceOf[Array[AnyRef]] - case x => - var N = 0 - var dataN: Array[AnyRef] = - if (x <= 0x8000) { N = 2; CollectionInternals.getDisplay2(myVector) } - else if (x <= 0x100000) { N = 3; CollectionInternals.getDisplay3(myVector) } - else if (x <= 0x2000000) { N = 4; CollectionInternals.getDisplay4(myVector) } - else /*x <= 0x40000000*/{ N = 5; CollectionInternals.getDisplay5(myVector) } - while (N > 2) { - dataN = dataN((iX >>> (5*N))&0x1F).asInstanceOf[Array[AnyRef]] - N -= 1 - } - index1 = (iX >>> 5) & 0x1F - data1 = dataN((iX >>> 10) & 0x1F).asInstanceOf[Array[AnyRef]] - index = iX & 0x1F - data = data1(index1).asInstanceOf[Array[AnyRef]] - } - } - protected final def initVpTo(iX: Int): Unit = { - // WARNING--this is an exact copy of initTo! If you change one you must change the other! - // (Manually specialized this way for speed.) - myVectorLength match { - case x if x <= 0x20 => - index = iX - data = CollectionInternals.getDisplay0(myVectorIterator) - case x if x <= 0x400 => - index1 = iX >>> 5 - data1 = CollectionInternals.getDisplay1(myVectorIterator) - index = iX & 0x1F - data = data1(index1).asInstanceOf[Array[AnyRef]] - case x => - var N = 0 - var dataN: Array[AnyRef] = - if (x <= 0x8000) { N = 2; CollectionInternals.getDisplay2(myVectorIterator) } - else if (x <= 0x100000) { N = 3; CollectionInternals.getDisplay3(myVectorIterator) } - else if (x <= 0x2000000) { N = 4; CollectionInternals.getDisplay4(myVectorIterator) } - else /*x <= 0x40000000*/{ N = 5; CollectionInternals.getDisplay5(myVectorIterator) } - while (N > 2) { - dataN = dataN((iX >>> (5*N))&0x1F).asInstanceOf[Array[AnyRef]] - N -= 1 - } - index1 = (iX >>> 5) & 0x1F - data1 = dataN((iX >>> 10) & 0x1F).asInstanceOf[Array[AnyRef]] - index = iX & 0x1F - data = data1(index1).asInstanceOf[Array[AnyRef]] - } - } -} - -private[java8] class StepsAnyVector[A](underlying: Vector[A], _i0: Int, _iN: Int) -extends StepsLikeIndexed[A, StepsAnyVector[A]](_i0, _iN) -with StepsVectorLike[A] { - protected val myVector = if (CollectionInternals.getDirt(underlying)) null else underlying - protected val myVectorIterator = if (myVector == null) underlying.iterator else null - protected val myVectorLength = underlying.length - def next() = if (hasNext) { - index += 1 - if (index >= 32) advanceData(i0) - i0 += 1 - data(index).asInstanceOf[A] - } else throwNSEE - protected def semiclone(half: Int) = { - val ans = new StepsAnyVector(underlying, i0, half) - index = 32 - index1 = 32 - i0 = half - ans - } -} - -private[java8] class StepsDoubleVector(underlying: Vector[Double], _i0: Int, _iN: Int) -extends StepsDoubleLikeIndexed[StepsDoubleVector](_i0, _iN) -with StepsVectorLike[Double] { - protected val myVector = if (CollectionInternals.getDirt(underlying)) null else underlying - protected val myVectorIterator = if (myVector == null) underlying.iterator else null - protected val myVectorLength = underlying.length - def nextDouble() = if (hasNext) { - index += 1 - if (index >= 32) advanceData(i0) - i0 += 1 - data(index).asInstanceOf[Double] - } else throwNSEE - protected def semiclone(half: Int) = { - val ans = new StepsDoubleVector(underlying, i0, half) - index = 32 - index1 = 32 - i0 = half - ans - } -} - -private[java8] class StepsIntVector(underlying: Vector[Int], _i0: Int, _iN: Int) -extends StepsIntLikeIndexed[StepsIntVector](_i0, _iN) -with StepsVectorLike[Int] { - protected val myVector = if (CollectionInternals.getDirt(underlying)) null else underlying - protected val myVectorIterator = if (myVector == null) underlying.iterator else null - protected val myVectorLength = underlying.length - def nextInt() = if (hasNext) { - index += 1 - if (index >= 32) advanceData(i0) - i0 += 1 - data(index).asInstanceOf[Int] - } else throwNSEE - protected def semiclone(half: Int) = { - val ans = new StepsIntVector(underlying, i0, half) - index = 32 - index1 = 32 - i0 = half - ans - } -} - -private[java8] class StepsLongVector(underlying: Vector[Long], _i0: Int, _iN: Int) -extends StepsLongLikeIndexed[StepsLongVector](_i0, _iN) -with StepsVectorLike[Long] { - protected val myVector = if (CollectionInternals.getDirt(underlying)) null else underlying - protected val myVectorIterator = if (myVector == null) underlying.iterator else null - protected val myVectorLength = underlying.length - def nextLong() = if (hasNext) { - index += 1 - if (index >= 32) advanceData(i0) - i0 += 1 - data(index).asInstanceOf[Long] - } else throwNSEE - protected def semiclone(half: Int) = { - val ans = new StepsLongVector(underlying, i0, half) - index = 32 - index1 = 32 - i0 = half - ans - } -} - -////////////////////////// -// Value class adapters // -////////////////////////// - -final class RichVectorCanStep[T](private val underlying: Vector[T]) extends AnyVal with MakesStepper[T, EfficientSubstep] { - def stepper[S <: Stepper[_]](implicit ss: StepperShape[T, S]) = ((ss.shape: @switch) match { - case StepperShape.IntValue => new StepsIntVector (underlying.asInstanceOf[Vector[Int]], 0, underlying.length) - case StepperShape.LongValue => new StepsLongVector (underlying.asInstanceOf[Vector[Long]], 0, underlying.length) - case StepperShape.DoubleValue => new StepsDoubleVector(underlying.asInstanceOf[Vector[Double]], 0, underlying.length) - case _ => ss.parUnbox(new StepsAnyVector[T](underlying, 0, underlying.length)) - }).asInstanceOf[S with EfficientSubstep] -} diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsWithTail.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsWithTail.scala deleted file mode 100644 index 8a66033..0000000 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsWithTail.scala +++ /dev/null @@ -1,98 +0,0 @@ -/* - * 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.compat.java8.converterImpl - -import scala.compat.java8.collectionImpl._ -import Stepper._ - -/** Abstracts all the generic operations of stepping over a collection with a fast tail operation. - * Because of how Java 8 streams subdivide their spliterators, we do this by chunking a bit at - * a time, generating a long chain of chunks. These won't necessarily all be the same size, - * but if there are enough hopefully it won't matter. - * - * Subclasses MUST decrement `maxN` when consuming elements, or this will not work! - */ -private[java8] abstract class AbstractStepsWithTail[CC >: Null, Sub >: Null, Semi <: Sub](final protected var underlying: CC, final protected var maxN: Long) { - private var nextChunkSize: Int = 0 - protected def myIsEmpty(cc: CC): Boolean - protected def myTailOf(cc: CC): CC - def prepareParallelOperation(): this.type = { - if (maxN >= Int.MaxValue && nextChunkSize == 0) { - // Need parallel context to know whether to run this or not! - var u = underlying - var i = 0 - while (i < 1024 && !myIsEmpty(u)) { u = myTailOf(u); i += 1 } - if (i < 1024) maxN = i - else nextChunkSize = 64 // Guaranteed at least 16 chunks - } - this - } - protected def semiclone(chunk: Int): Semi - def characteristics: Int = if (maxN < Int.MaxValue) Ordered | Sized | SubSized else Ordered - def estimateSize(): Long = if (maxN < Int.MaxValue) maxN else Long.MaxValue - def hasNext: Boolean = if (maxN < Int.MaxValue) maxN > 0 else if (myIsEmpty(underlying)) { maxN = 0; false } else true - def substep(): Sub = { - prepareParallelOperation() - maxN match { - case x if x < 2 => null - case x if x >= Int.MaxValue => - var u = underlying - var i = 0 - val n = (nextChunkSize & 0xFFFFFFFC) // Use bottom two bits to count up - while (i < n && !myIsEmpty(u)) { - u = myTailOf(u) - i += 1 - } - if (myIsEmpty(u)) { - maxN = i - substep() // Different branch now, recursion is an easy way to get it - } - else { - val sub = semiclone(n) - underlying = u - if ((nextChunkSize & 3) == 3) nextChunkSize = if (n < 0x40000000) 2*n else n else nextChunkSize += 1 - sub - } - case x => - var half = x.toInt >>> 1 - val sub = semiclone(half) - maxN -= half - while (half > 0) { underlying = myTailOf(underlying); half -= 1 } - sub - } - } -} - -/** Abstracts the operation of stepping over a generic indexable collection */ -private[java8] abstract class StepsWithTail[A, CC >: Null, STA >: Null <: StepsWithTail[A, CC, _]](_underlying: CC, _maxN: Long) - extends AbstractStepsWithTail[CC, AnyStepper[A], STA](_underlying, _maxN) - with AnyStepper[A] -{} - -/** Abstracts the operation of stepping over an indexable collection of Doubles */ -private[java8] abstract class StepsDoubleWithTail[CC >: Null, STD >: Null <: StepsDoubleWithTail[CC, _]](_underlying: CC, _maxN: Long) - extends AbstractStepsWithTail[CC, DoubleStepper, STD](_underlying, _maxN) - with DoubleStepper -{} - -/** Abstracts the operation of stepping over an indexable collection of Ints */ -private[java8] abstract class StepsIntWithTail[CC >: Null, STI >: Null <: StepsIntWithTail[CC, _]](_underlying: CC, _maxN: Long) - extends AbstractStepsWithTail[CC, IntStepper, STI](_underlying, _maxN) - with IntStepper -{} - -/** Abstracts the operation of stepping over an indexable collection of Longs */ -private[java8] abstract class StepsLongWithTail[CC >: Null, STL >: Null <: StepsLongWithTail[CC, _]](_underlying: CC, _maxN: Long) - extends AbstractStepsWithTail[CC, LongStepper, STL](_underlying, _maxN) - with LongStepper -{} diff --git a/src/test/java/scala/compat/java8/BoxingTest.java b/src/test/java/scala/compat/java8/BoxingTest.java index e0a2c03..7f798ff 100644 --- a/src/test/java/scala/compat/java8/BoxingTest.java +++ b/src/test/java/scala/compat/java8/BoxingTest.java @@ -18,24 +18,26 @@ public class BoxingTest { @Test public void nullBoxesInterpretedAsZeroF1() { - scala.Function1 jFunction1 = new JFunction1$mcII$sp() { + Object o = new JFunction1$mcII$sp() { @Override public int apply$mcII$sp(int v1) { return v1 + 1; } }; + scala.Function1 jFunction1 = (scala.Function1)o; Integer result = (Integer) jFunction1.apply(null); assert (result.intValue() == 1); } @Test public void nullBoxesInterpretedAsZeroF2() { - scala.Function2 jFunction2 = new JFunction2$mcIII$sp() { + Object o = new JFunction2$mcIII$sp() { @Override public int apply$mcIII$sp(int v1, int v2) { return v1 + v2 + 1; } }; + scala.Function2 jFunction2 = (scala.Function2)o; Integer result = (Integer) jFunction2.apply(null, null); assert (result.intValue() == 1); } diff --git a/src/test/scala/scala/compat/java8/StepConvertersTest.scala b/src/test/scala/scala/compat/java8/StepConvertersTest.scala index 484e1bf..667e13c 100644 --- a/src/test/scala/scala/compat/java8/StepConvertersTest.scala +++ b/src/test/scala/scala/compat/java8/StepConvertersTest.scala @@ -22,19 +22,7 @@ class StepConvertersTest { import scala.{ collection => co } import collection.{ mutable => cm, immutable => ci, concurrent => cc } - def isAcc[X](x: X): Boolean = x match { - case _: AccumulatorStepper[_] => true - case _: DoubleAccumulatorStepper => true - case _: IntAccumulatorStepper => true - case _: LongAccumulatorStepper => true - case _ => false - } - - def isLin[X](x: X): Boolean = x match { - case _: AbstractStepsLikeIterator[_, _, _] => true - case _: AbstractStepsWithTail[_, _, _] => true - case _ => false - } + def isAcc[X](x: X): Boolean = x.getClass.getSimpleName.contains("AccumulatorStepper") trait SpecCheck { def check[X](x: X): Boolean @@ -64,7 +52,6 @@ class StepConvertersTest { assertTrue(x.isInstanceOf[Stepper[_]]) correctSpec.assert(x) assertTrue(!isAcc(x)) - assertTrue(isLin(x)) } def Fine[X](x: => X)(implicit correctSpec: SpecCheck): Unit = { @@ -77,7 +64,6 @@ class StepConvertersTest { assertTrue(x.isInstanceOf[Stepper[_]]) correctSpec.assert(x) assertTrue(!isAcc(x)) - assertTrue(!isLin(x)) } def Tell[X](x: => X)(implicit correctSpec: SpecCheck): Unit = { diff --git a/src/test/scala/scala/compat/java8/StepperTest.scala b/src/test/scala/scala/compat/java8/StepperTest.scala index 704d9c7..b1d0e2a 100644 --- a/src/test/scala/scala/compat/java8/StepperTest.scala +++ b/src/test/scala/scala/compat/java8/StepperTest.scala @@ -12,22 +12,25 @@ package scala.compat.java8 +import java.util + import org.junit.Test import org.junit.Assert._ - import java.util.Spliterator import collectionImpl._ +import StreamConverters._ +import scala.collection.{AnyStepper, IntStepper} -class IncStepperA(private val size0: Long) extends NextStepper[Int] { +class IncStepperA(private val size0: Long) extends IntStepper { if (size0 < 0) throw new IllegalArgumentException("Size must be >= 0L") private var i = 0L - def characteristics = Stepper.Sized | Stepper.SubSized | Stepper.Ordered - def knownSize = math.max(0L, size0 - i) + def characteristics = Spliterator.SIZED | Spliterator.SUBSIZED | Spliterator.ORDERED + override def estimateSize: Long = math.max(0L, size0 - i) def hasStep = i < size0 def nextStep() = { i += 1; (i - 1).toInt } - def substep() = if (knownSize <= 1) null else { + def trySplit() = if (estimateSize <= 1) null else { val sub = new IncStepperA(size0 - (size0 - i)/2) sub.i = i i = sub.size0 @@ -35,25 +38,10 @@ class IncStepperA(private val size0: Long) extends NextStepper[Int] { } } -class IncStepperB(private val size0: Long) extends TryStepper[Int] { - if (size0 < 0) throw new IllegalArgumentException("Size must be >= 0L") - protected var myCache: Int = 0 - private var i = 0L - def characteristics = Stepper.Sized | Stepper.SubSized | Stepper.Ordered - def knownUncachedSize = math.max(0L, size0 - i) - protected def tryUncached(f: Int => Unit): Boolean = if (i >= size0) false else { f(i.toInt); i += 1; true } - def substep() = if (knownSize <= 1) null else { - val sub = new IncStepperB(size0 - (size0 - i)/2) - sub.i = i - i = sub.size0 - sub - } -} - class IncSpliterator(private val size0: Long) extends Spliterator.OfInt { if (size0 < 0) throw new IllegalArgumentException("Size must be >= 0L") private var i = 0L - def characteristics = Stepper.Sized | Stepper.SubSized | Stepper.Ordered + def characteristics = Spliterator.SIZED | Spliterator.SUBSIZED | Spliterator.ORDERED def estimateSize() = math.max(0L, size0 - i) def tryAdvance(f: java.util.function.IntConsumer): Boolean = if (i >= size0) false else { f.accept(i.toInt); i += 1; true } def trySplit(): Spliterator.OfInt = if (i+1 >= size0) null else { @@ -67,17 +55,26 @@ class IncSpliterator(private val size0: Long) extends Spliterator.OfInt { class MappingStepper[@specialized (Double, Int, Long) A, @specialized(Double, Int, Long) B](underlying: Stepper[A], mapping: A => B) extends Stepper[B] { def characteristics = underlying.characteristics - def knownSize = underlying.knownSize def hasStep = underlying.hasStep def nextStep() = mapping(underlying.nextStep()) - def tryStep(f: B => Unit): Boolean = underlying.tryStep(a => f(mapping(a))) - override def foreach(f: B => Unit): Unit = { underlying.foreach(a => f(mapping(a))) } + + override def trySplit(): Stepper[B] = { + val r = underlying.trySplit() + if (r == null) null else new MappingStepper[A, B](r, mapping) + } + + override def estimateSize: Long = underlying.estimateSize + + override def javaIterator: util.Iterator[_] = new util.Iterator[B] { + override def hasNext: Boolean = underlying.hasStep + override def next(): B = mapping(underlying.nextStep()) + } def substep() = { val undersub = underlying.substep() if (undersub == null) null else new MappingStepper(undersub, mapping) } - def spliterator: Spliterator[B] = new MappingSpliterator[A, B](underlying.spliterator, mapping) + def spliterator: Spliterator[_] = new MappingSpliterator[A, B](underlying.spliterator.asInstanceOf[Spliterator[A]], mapping) } class MappingSpliterator[A, B](private val underlying: Spliterator[A], mapping: A => B) extends Spliterator[B] { @@ -121,6 +118,26 @@ class IntToLongSpliterator(private val underlying: Spliterator.OfInt, mapping: I } } +class SpliteratorStepper[A](sp: Spliterator[A]) extends AnyStepper[A] { + override def trySplit(): AnyStepper[A] = { + val r = sp.trySplit() + if (r == null) null else new SpliteratorStepper(r) + } + + var cache: AnyRef = null + + override def hasStep: Boolean = cache != null || sp.tryAdvance(x => cache = x.asInstanceOf[AnyRef]) + + override def nextStep(): A = if (hasStep) { + val r = cache + cache = null + r.asInstanceOf[A] + } else throw new NoSuchElementException("") + + override def estimateSize: Long = sp.estimateSize() + + override def characteristics: Int = sp.characteristics() +} class StepperTest { def subs[Z, A, CC <: Stepper[A]](zero: Z)(s: Stepper[A])(f: Stepper[A] => Z, op: (Z, Z) => Z): Z = { @@ -133,26 +150,15 @@ class StepperTest { } val sizes = Vector(0, 1, 2, 4, 15, 17, 2512) - def sources: Vector[(Int, Stepper[Int])] = sizes.flatMap{ i => + def sources: Vector[(Int, Stepper[Int])] = sizes.flatMap{ i => Vector( i -> new IncStepperA(i), - i -> new IncStepperB(i), - i -> Stepper.ofSpliterator(new IncSpliterator(i)), + i -> new SpliteratorStepper(new IncSpliterator(i).asInstanceOf[Spliterator[Int]]), i -> new MappingStepper[Int,Int](new IncStepperA(i), x => x), - i -> new MappingStepper[Long, Int](Stepper.ofSpliterator(new IntToLongSpliterator(new IncSpliterator(i), _.toLong)), _.toInt), - i -> new MappingStepper[Double, Int](Stepper.ofSpliterator(new IntToDoubleSpliterator(new IncSpliterator(i), _.toDouble)), _.toInt), - i -> new MappingStepper[String, Int](Stepper.ofSpliterator(new IntToGenericSpliterator[String](new IncSpliterator(i), _.toString)), _.toInt) - ) ++ - { - // Implicitly converted instead of explicitly - import SpliteratorConverters._ - Vector[(Int, Stepper[Int])]( - i -> (new IncSpliterator(i)).stepper, - i -> new MappingStepper[Long, Int]((new IntToLongSpliterator(new IncSpliterator(i), _.toLong)).stepper, _.toInt), - i -> new MappingStepper[Double, Int]((new IntToDoubleSpliterator(new IncSpliterator(i), _.toDouble)).stepper, _.toInt), - i -> new MappingStepper[String, Int]((new IntToGenericSpliterator[String](new IncSpliterator(i), _.toString)).stepper, _.toInt) - ) - } + i -> new MappingStepper[Long, Int](new SpliteratorStepper(new IntToLongSpliterator(new IncSpliterator(i), _.toLong).asInstanceOf[Spliterator[Long]]), _.toInt), + i -> new MappingStepper[Double, Int](new SpliteratorStepper(new IntToDoubleSpliterator(new IncSpliterator(i), _.toDouble).asInstanceOf[Spliterator[Double]]), _.toInt), + i -> new MappingStepper[String, Int](new SpliteratorStepper(new IntToGenericSpliterator[String](new IncSpliterator(i), _.toString)), _.toInt) + ) } @Test @@ -175,14 +181,14 @@ class StepperTest { def trying(): Unit = { sources.foreach{ case (i,s) => val set = collection.mutable.BitSet.empty - while (s.tryStep{ y => assert(!(set contains y)); set += y }) {} + while (s.hasStep) { val y = s.nextStep(); assert(!(set contains y)); set += y } assert((0 until i).toSet == set) } sources.foreach{ case (i,s) => val set = collection.mutable.BitSet.empty subs(0)(s)( { x => - while(x.tryStep{ y => assert(!(set contains y)); set += y }) {} + while (x.hasStep) { val y = x.nextStep(); assert(!(set contains y)); set += y } 0 }, _ + _ @@ -209,17 +215,11 @@ class StepperTest { @Test def characteristically(): Unit = { - val expected = Stepper.Sized | Stepper.SubSized | Stepper.Ordered + val expected = Spliterator.SIZED | Spliterator.SUBSIZED | Spliterator.ORDERED sources.foreach{ case (_,s) => assertEquals(s.characteristics, expected)} sources.foreach{ case (_,s) => subs(0)(s)(x => { assertEquals(x.characteristics, expected); 0 }, _ + _) } } - @Test - def knownSizes(): Unit = { - sources.foreach{ case (i,s) => assertEquals(i.toLong, s.knownSize) } - sources.foreach{ case (i,s) => if (i > 0) subs(0)(s)(x => { assertEquals(x.knownSize, 1L); 0 }, _ + _) } - } - @Test def count_only(): Unit = { sources.foreach{ case (i, s) => assertEquals(i, s.count()) } @@ -244,7 +244,7 @@ class StepperTest { def finding(): Unit = { for (k <- 0 until 100) { (sources zip sources).foreach{ case ((i,s), (j,t)) => - val x = util.Random.nextInt(math.min(i,j)+3) + val x = scala.util.Random.nextInt(math.min(i,j)+3) val a = s.find(_ == x) val b = subs(None: Option[Int])(t)(_.find(_ == x), _ orElse _) assertEquals(a, b) @@ -307,11 +307,11 @@ class StepperTest { def spliterating(): Unit = { sources.foreach{ case (i,s) => var sum = 0 - s.spliterator.forEachRemaining(new java.util.function.Consumer[Int]{ def accept(i: Int): Unit = { sum += i } }) + s.spliterator.asInstanceOf[Spliterator[Int]].forEachRemaining(new java.util.function.Consumer[Int]{ def accept(i: Int): Unit = { sum += i } }) assertEquals(sum, (0 until i).sum) } sources.foreach{ case (i,s) => - val sum = subs(0)(s)(x => { var sm = 0; x.spliterator.forEachRemaining(new java.util.function.Consumer[Int]{ def accept(i: Int): Unit = { sm += i } }); sm }, _ + _) + val sum = subs(0)(s)(x => { var sm = 0; x.spliterator.asInstanceOf[Spliterator[Int]].forEachRemaining(new java.util.function.Consumer[Int]{ def accept(i: Int): Unit = { sm += i } }); sm }, _ + _) assertEquals(sum, (0 until i).sum) } } diff --git a/src/test/scala/scala/compat/java8/StreamConvertersTest.scala b/src/test/scala/scala/compat/java8/StreamConvertersTest.scala index 05e011d..f2a084f 100644 --- a/src/test/scala/scala/compat/java8/StreamConvertersTest.scala +++ b/src/test/scala/scala/compat/java8/StreamConvertersTest.scala @@ -19,8 +19,6 @@ import org.junit.Assert._ import java.util.stream._ import StreamConverters._ -import scala.compat.java8.collectionImpl.IntStepper -import scala.compat.java8.converterImpl.MakesStepper class StreamConvertersTest { @@ -46,8 +44,8 @@ class StreamConvertersTest { for (n <- ns) { val vecO = arrayO(n).toVector val accO = newStream(n).parallel.accumulate - assertEq(vecO, newStream(n).accumulate.to[Vector], s"stream $n to vector") - assertEq(vecO, accO.to[Vector], s"stream $n to vector in parallel") + assertEq(vecO, newStream(n).accumulate.to(Vector), s"stream $n to vector") + assertEq(vecO, accO.to(Vector), s"stream $n to vector in parallel") assertEq(vecO, accO.toArray.toVector, s"stream $n to vector via array in parallel") assertEq(vecO, accO.iterator.toVector, s"stream $n to vector via iterator in parallel") assertEq(vecO, accO.toList.toVector, s"stream $n to vector via list in parallel") @@ -60,8 +58,8 @@ class StreamConvertersTest { val accD = if (boxless) newDoubleStream(n).parallel.accumulate else newDoubleStream(n).boxed.parallel.accumulatePrimitive - assertEq(vecD, newDoubleStream(n).accumulate.to[Vector], s"double stream $n to vector $sbox") - assertEq(vecD, accD.to[Vector], s"double stream $n to vector in parallel $sbox") + assertEq(vecD, newDoubleStream(n).accumulate.to(Vector), s"double stream $n to vector $sbox") + assertEq(vecD, accD.to(Vector), s"double stream $n to vector in parallel $sbox") assertEq(vecD, accD.toArray.toVector, s"double stream $n to vector via array in parallel $sbox") assertEq(vecD, accD.iterator.toVector, s"double stream $n to vector via iterator in parallel $sbox") assertEq(vecD, accD.toList.toVector, s"double stream $n to vector via list in parallel $sbox") @@ -72,8 +70,8 @@ class StreamConvertersTest { val accI = if (boxless) newIntStream(n).parallel.accumulate else newIntStream(n).boxed.parallel.accumulatePrimitive - assertEq(vecI, newIntStream(n).accumulate.to[Vector], s"int stream $n to vector $sbox") - assertEq(vecI, accI.to[Vector], s"int stream $n to vector in parallel $sbox") + assertEq(vecI, newIntStream(n).accumulate.to(Vector), s"int stream $n to vector $sbox") + assertEq(vecI, accI.to(Vector), s"int stream $n to vector in parallel $sbox") assertEq(vecI, accI.toArray.toVector, s"int stream $n to vector via array in parallel $sbox") assertEq(vecI, accI.iterator.toVector, s"int stream $n to vector via iterator in parallel $sbox") assertEq(vecI, accI.toList.toVector, s"int stream $n to vector via list in parallel $sbox") @@ -84,8 +82,8 @@ class StreamConvertersTest { val accL = if (boxless) newLongStream(n).parallel.accumulate else newLongStream(n).boxed.parallel.accumulatePrimitive - assertEq(vecL, newLongStream(n).accumulate.to[Vector], s"long stream $n to vector $sbox") - assertEq(vecL, accL.to[Vector], s"long stream $n to vector in parallel $sbox") + assertEq(vecL, newLongStream(n).accumulate.to(Vector), s"long stream $n to vector $sbox") + assertEq(vecL, accL.to(Vector), s"long stream $n to vector in parallel $sbox") assertEq(vecL, accL.toArray.toVector, s"long stream $n to vector via array in parallel $sbox") assertEq(vecL, accL.iterator.toVector, s"long stream $n to vector via iterator in parallel $sbox") assertEq(vecL, accL.toList.toVector, s"long stream $n to vector via list in parallel $sbox") @@ -99,20 +97,20 @@ class StreamConvertersTest { def streamToScala(): Unit = { for (n <- ns) { val vecO = arrayO(n).toVector - assertEq(vecO, newStream(n).toScala[Vector]) - assertEq(vecO, newStream(n).parallel.toScala[Vector]) + assertEq(vecO, newStream(n).toScala(Vector)) + assertEq(vecO, newStream(n).parallel.toScala(Vector)) val vecD = arrayD(n).toVector - assertEq(vecD, newDoubleStream(n).toScala[Vector]) - assertEq(vecD, newDoubleStream(n).parallel.toScala[Vector]) + assertEq(vecD, newDoubleStream(n).toScala(Vector)) + assertEq(vecD, newDoubleStream(n).parallel.toScala(Vector)) val vecI = arrayI(n).toVector - assertEq(vecI, newIntStream(n).toScala[Vector]) - assertEq(vecI, newIntStream(n).parallel.toScala[Vector]) + assertEq(vecI, newIntStream(n).toScala(Vector)) + assertEq(vecI, newIntStream(n).parallel.toScala(Vector)) val vecL = arrayL(n).toVector - assertEq(vecL, newLongStream(n).toScala[Vector]) - assertEq(vecL, newLongStream(n).parallel.toScala[Vector]) + assertEq(vecL, newLongStream(n).toScala(Vector)) + assertEq(vecL, newLongStream(n).parallel.toScala(Vector)) } } @@ -152,18 +150,18 @@ class StreamConvertersTest { val vecO = vectO(n) val hsO = hsetO(n) // Seems like a lot of boilerplate, but we need it to test implicit resolution - assertEq(seqO, seqO.seqStream.toScala[Seq]) - assertEq(seqO, seqO.stepper.parStream.toScala[Seq]) // Must go through stepper if we're unsure whether we can parallelize well - assertEq(seqO, arrO.seqStream.toScala[Seq]) - assertEq(seqO, arrO.parStream.toScala[Seq]) - assertEq(seqO, abO.seqStream.toScala[Seq]) - assertEq(seqO, abO.parStream.toScala[Seq]) - assertEq(seqO, wrO.seqStream.toScala[Seq]) - assertEq(seqO, wrO.parStream.toScala[Seq]) - assertEq(seqO, vecO.seqStream.toScala[Seq]) - assertEq(seqO, vecO.parStream.toScala[Seq]) - assertEq(seqO, hsO.seqStream.toScala[Seq].sortBy(_.toInt)) - assertEq(seqO, hsO.parStream.toScala[Seq].sortBy(_.toInt)) + assertEq(seqO, seqO.seqStream.toScala(Seq)) +// assertEq(seqO, seqO.stepper.parStream.toScala(Seq) // Must go through stepper if we're unsure whether we can parallelize well + assertEq(seqO, arrO.seqStream.toScala(Seq)) + assertEq(seqO, arrO.parStream.toScala(Seq)) + assertEq(seqO, abO.seqStream.toScala(Seq)) + assertEq(seqO, abO.parStream.toScala(Seq)) + assertEq(seqO, wrO.seqStream.toScala(Seq)) + assertEq(seqO, wrO.parStream.toScala(Seq)) + assertEq(seqO, vecO.seqStream.toScala(Seq)) + assertEq(seqO, vecO.parStream.toScala(Seq)) +// assertEq(seqO, hsO.seqStream.toScala(Seq.sortBy(_.toInt)) +// assertEq(seqO, hsO.parStream.toScala(Seq.sortBy(_.toInt)) val arrD = arrayD(n) val seqD = arrD.toSeq @@ -171,28 +169,28 @@ class StreamConvertersTest { val wrD = wrapD(n) val vecD = vectD(n) val hsD = hsetD(n) - assertEq(seqD, seqD.seqStream.toScala[Seq]) - assertEq(seqD, seqD.stepper.parStream.toScala[Seq]) - assertEq(seqD, arrD.seqStream.toScala[Seq]) - assertEq(seqD, arrD.parStream.toScala[Seq]) + assertEq(seqD, seqD.seqStream.toScala(Seq)) +// assertEq(seqD, seqD.stepper.parStream.toScala(Seq) + assertEq(seqD, arrD.seqStream.toScala(Seq)) + assertEq(seqD, arrD.parStream.toScala(Seq)) assert(arrD.seqStream.isInstanceOf[DoubleStream]) assert(arrD.parStream.isInstanceOf[DoubleStream]) - assertEq(seqD, abD.seqStream.toScala[Seq]) - assertEq(seqD, abD.parStream.toScala[Seq]) + assertEq(seqD, abD.seqStream.toScala(Seq)) + assertEq(seqD, abD.parStream.toScala(Seq)) assert(abD.seqStream.isInstanceOf[DoubleStream]) assert(abD.parStream.isInstanceOf[DoubleStream]) - assertEq(seqD, wrD.seqStream.toScala[Seq]) - assertEq(seqD, wrD.parStream.toScala[Seq]) + assertEq(seqD, wrD.seqStream.toScala(Seq)) + assertEq(seqD, wrD.parStream.toScala(Seq)) assert(wrD.seqStream.isInstanceOf[DoubleStream]) assert(wrD.parStream.isInstanceOf[DoubleStream]) - assertEq(seqD, vecD.seqStream.toScala[Seq]) - assertEq(seqD, vecD.parStream.toScala[Seq]) + assertEq(seqD, vecD.seqStream.toScala(Seq)) + assertEq(seqD, vecD.parStream.toScala(Seq)) assert(vecD.seqStream.isInstanceOf[DoubleStream]) assert(vecD.parStream.isInstanceOf[DoubleStream]) - assertEq(seqD, hsD.seqStream.toScala[Seq].sorted) - assertEq(seqD, hsD.parStream.toScala[Seq].sorted) - assert(hsD.seqStream.isInstanceOf[DoubleStream]) - assert(hsD.parStream.isInstanceOf[DoubleStream]) +// assertEq(seqD, hsD.seqStream.toScala(Seq.sorted) +// assertEq(seqD, hsD.parStream.toScala(Seq.sorted) +// assert(hsD.seqStream.isInstanceOf[DoubleStream]) +// assert(hsD.parStream.isInstanceOf[DoubleStream]) val arrI = arrayI(n) val seqI = arrI.toSeq @@ -200,28 +198,28 @@ class StreamConvertersTest { val wrI = wrapI(n) val vecI = vectI(n) val hsI = hsetI(n) - assertEq(seqI, seqI.seqStream.toScala[Seq]) - assertEq(seqI, seqI.stepper.parStream.toScala[Seq]) - assertEq(seqI, arrI.seqStream.toScala[Seq]) - assertEq(seqI, arrI.parStream.toScala[Seq]) + assertEq(seqI, seqI.seqStream.toScala(Seq)) +// assertEq(seqI, seqI.stepper.parStream.toScala(Seq) + assertEq(seqI, arrI.seqStream.toScala(Seq)) + assertEq(seqI, arrI.parStream.toScala(Seq)) assert(arrI.seqStream.isInstanceOf[IntStream]) assert(arrI.parStream.isInstanceOf[IntStream]) - assertEq(seqI, abI.seqStream.toScala[Seq]) - assertEq(seqI, abI.parStream.toScala[Seq]) + assertEq(seqI, abI.seqStream.toScala(Seq)) + assertEq(seqI, abI.parStream.toScala(Seq)) assert(abI.seqStream.isInstanceOf[IntStream]) assert(abI.parStream.isInstanceOf[IntStream]) - assertEq(seqI, wrI.seqStream.toScala[Seq]) - assertEq(seqI, wrI.parStream.toScala[Seq]) + assertEq(seqI, wrI.seqStream.toScala(Seq)) + assertEq(seqI, wrI.parStream.toScala(Seq)) assert(wrI.seqStream.isInstanceOf[IntStream]) assert(wrI.parStream.isInstanceOf[IntStream]) - assertEq(seqI, vecI.seqStream.toScala[Seq]) - assertEq(seqI, vecI.parStream.toScala[Seq]) + assertEq(seqI, vecI.seqStream.toScala(Seq)) + assertEq(seqI, vecI.parStream.toScala(Seq)) assert(vecI.seqStream.isInstanceOf[IntStream]) assert(vecI.parStream.isInstanceOf[IntStream]) - assertEq(seqI, hsI.seqStream.toScala[Seq].sorted) - assertEq(seqI, hsI.parStream.toScala[Seq].sorted) - assert(hsI.seqStream.isInstanceOf[IntStream]) - assert(hsI.parStream.isInstanceOf[IntStream]) +// assertEq(seqI, hsI.seqStream.toScala(Seq.sorted) +// assertEq(seqI, hsI.parStream.toScala(Seq.sorted) +// assert(hsI.seqStream.isInstanceOf[IntStream]) +// assert(hsI.parStream.isInstanceOf[IntStream]) val arrL = arrayL(n) val seqL = arrL.toSeq @@ -229,64 +227,42 @@ class StreamConvertersTest { val wrL = wrapL(n) val vecL = vectL(n) val hsL = hsetL(n) - assertEq(seqL, seqL.seqStream.toScala[Seq]) - //assertEq(seqL, seqL.stepper.parStream.toScala[Seq]) - assertEq(seqL, arrL.seqStream.toScala[Seq]) - assertEq(seqL, arrL.parStream.toScala[Seq]) + assertEq(seqL, seqL.seqStream.toScala(Seq)) +// assertEq(seqL, seqL.stepper.parStream.toScala(Seq) + assertEq(seqL, arrL.seqStream.toScala(Seq)) + assertEq(seqL, arrL.parStream.toScala(Seq)) assert(arrL.seqStream.isInstanceOf[LongStream]) assert(arrL.parStream.isInstanceOf[LongStream]) - assertEq(seqL, abL.seqStream.toScala[Seq]) - assertEq(seqL, abL.parStream.toScala[Seq]) + assertEq(seqL, abL.seqStream.toScala(Seq)) + assertEq(seqL, abL.parStream.toScala(Seq)) assert(abL.seqStream.isInstanceOf[LongStream]) assert(abL.parStream.isInstanceOf[LongStream]) - assertEq(seqD, wrD.seqStream.toScala[Seq]) - assertEq(seqD, wrD.parStream.toScala[Seq]) + assertEq(seqD, wrD.seqStream.toScala(Seq)) + assertEq(seqD, wrD.parStream.toScala(Seq)) assert(wrL.seqStream.isInstanceOf[LongStream]) assert(wrL.parStream.isInstanceOf[LongStream]) - assertEq(seqD, wrD.seqStream.toScala[Seq]) - assertEq(seqD, wrD.parStream.toScala[Seq]) + assertEq(seqD, wrD.seqStream.toScala(Seq)) + assertEq(seqD, wrD.parStream.toScala(Seq)) assert(vecL.seqStream.isInstanceOf[LongStream]) assert(vecL.parStream.isInstanceOf[LongStream]) - assertEq(seqL, hsL.seqStream.toScala[Seq].sorted) - assertEq(seqL, hsL.parStream.toScala[Seq].sorted) - assert(hsL.seqStream.isInstanceOf[LongStream]) - assert(hsL.parStream.isInstanceOf[LongStream]) +// assertEq(seqL, hsL.seqStream.toScala(Seq.sorted) +// assertEq(seqL, hsL.parStream.toScala(Seq.sorted) +// assert(hsL.seqStream.isInstanceOf[LongStream]) +// assert(hsL.parStream.isInstanceOf[LongStream]) } } @Test def primitiveStreamTypes(): Unit = { // Unboxed native + widening Steppers available: - assertEquals(Vector[Int](1, 2, 3), (Array[Int](1, 2, 3).seqStream: IntStream).toScala[Vector]) - assertEquals(Vector[Short](1.toShort, 2.toShort, 3.toShort), (Array[Short](1.toShort, 2.toShort, 3.toShort).seqStream: IntStream).toScala[Vector]) - assertEquals(Vector[String]("a", "b"), (Array[String]("a", "b").seqStream: Stream[String]).toScala[Vector]) + assertEquals(Vector[Int](1, 2, 3), (Array[Int](1, 2, 3).seqStream: IntStream).toScala(Vector)) + assertEquals(Vector[Short](1.toShort, 2.toShort, 3.toShort), (Array[Short](1.toShort, 2.toShort, 3.toShort).seqStream: IntStream).toScala(Vector)) + assertEquals(Vector[String]("a", "b"), (Array[String]("a", "b").seqStream: Stream[String]).toScala(Vector)) // Boxed collections, widening via boxed AnySteppers: - assertEquals(Vector[Int](1, 2, 3), (Vector[Int](1, 2, 3).seqStream: IntStream).toScala[Vector]) - assertEquals(Vector[Short](1.toShort, 2.toShort, 3.toShort), (Vector[Short](1.toShort, 2.toShort, 3.toShort).seqStream: IntStream).toScala[Vector]) - assertEquals(Vector[String]("a", "b"), (Vector[String]("a", "b").seqStream: Stream[String]).toScala[Vector]) - } - - @Test - def streamMaterialization(): Unit = { - val coll = collection.mutable.ArraySeq.make[Int](Array(1,2,3)) - val streamize = implicitly[collection.mutable.ArraySeq[Int] => MakesSequentialStream[Int, IntStream]] - assertTrue(streamize(coll).getClass.getName.contains("EnrichIntArraySeqWithStream")) - val steppize = implicitly[collection.mutable.ArraySeq[Int] => MakesStepper[Int, Any]] - assertTrue(steppize(coll).getClass.getName.contains("RichArrayCanStep")) - val stepper = steppize(coll).stepper - assertTrue(stepper.getClass.getName.contains("StepsIntArray")) - - val ss = Vector(1,2,3).seqStream - val ss2: IntStream = ss - - val coll2 = Vector(1,2,3) - val streamize2 = implicitly[Vector[Int] => MakesSequentialStream[Int, IntStream]] - assertTrue(streamize2(coll2).getClass.getName.contains("EnrichAnySteppableWithSeqStream")) - val steppize2 = implicitly[Vector[Int] => MakesStepper[Int, Any]] - assertTrue(steppize2(coll2).getClass.getName.contains("RichVectorCanStep")) - val stepper2 = steppize2(coll2).stepper - assertTrue(stepper2.getClass.getName.contains("StepsIntVector")) + assertEquals(Vector[Int](1, 2, 3), (Vector[Int](1, 2, 3).seqStream: IntStream).toScala(Vector)) + assertEquals(Vector[Short](1.toShort, 2.toShort, 3.toShort), (Vector[Short](1.toShort, 2.toShort, 3.toShort).seqStream: IntStream).toScala(Vector)) + assertEquals(Vector[String]("a", "b"), (Vector[String]("a", "b").seqStream: Stream[String]).toScala(Vector)) } @Test From 3ac3dc7801971c004fa5667f43caaaa1252baccd Mon Sep 17 00:00:00 2001 From: Lukas Rytz Date: Mon, 20 May 2019 11:34:23 +0200 Subject: [PATCH 18/23] StreamConverters.toScala in 2.12-style --- .../scala/compat/java8/StreamConverters.scala | 141 ++++++++++++++---- .../compat/java8/StreamConvertersTest.scala | 116 +++++++------- 2 files changed, 170 insertions(+), 87 deletions(-) diff --git a/src/main/scala/scala/compat/java8/StreamConverters.scala b/src/main/scala/scala/compat/java8/StreamConverters.scala index 55e8bc9..36afc19 100644 --- a/src/main/scala/scala/compat/java8/StreamConverters.scala +++ b/src/main/scala/scala/compat/java8/StreamConverters.scala @@ -210,16 +210,16 @@ trait StreamExtensions { // toScala for streams implicit class StreamHasToScala[A](stream: Stream[A]) { - def accumulate: AnyAccumulator[A] = toScala(Accumulator) + def accumulate: AnyAccumulator[A] = toScalaFactory(Accumulator) /** * Copy the elements of this stream into a Scala collection. * - * Converting a parallel streams to an [[Accumulator]] using `stream.toScala(Accumulator)` + * Converting a parallel streams to an [[Accumulator]] using `stream.toScalaFactory(Accumulator)` * builds the result in parallel. * - * A `toScala(Accumulator)` call automatically converts streams of boxed integers, longs or + * A `toScalaFactory(Accumulator)` call automatically converts streams of boxed integers, longs or * doubles are converted to the primitive accumulators ([[IntAccumulator]], etc.). * * When converting a parallel stream to a different Scala collection, the stream is first @@ -230,17 +230,35 @@ trait StreamExtensions { * Sequential streams are directly converted to the target collection. If the target collection * is lazy, the conversion is lazy as well. */ - def toScala[C1](factory: collection.Factory[A, C1])(implicit info: AccumulatorFactoryInfo[A, C1]): C1 = { - + private[java8] def toScalaFactory[C](factory: collection.Factory[A, C])(implicit info: AccumulatorFactoryInfo[A, C]): C = { def anyAcc = stream.collect(AnyAccumulator.supplier[A], AnyAccumulator.adder[A], AnyAccumulator.merger[A]) - if (info.companion == AnyAccumulator) anyAcc.asInstanceOf[C1] - else if (info.companion == IntAccumulator) stream.asInstanceOf[Stream[Int]].collect(IntAccumulator.supplier, IntAccumulator.boxedAdder, IntAccumulator.merger).asInstanceOf[C1] - else if (info.companion == LongAccumulator) stream.asInstanceOf[Stream[Long]].collect(LongAccumulator.supplier, LongAccumulator.boxedAdder, LongAccumulator.merger).asInstanceOf[C1] - else if (info.companion == DoubleAccumulator) stream.asInstanceOf[Stream[Double]].collect(DoubleAccumulator.supplier, DoubleAccumulator.boxedAdder, DoubleAccumulator.merger).asInstanceOf[C1] + if (info.companion == AnyAccumulator) anyAcc.asInstanceOf[C] + else if (info.companion == IntAccumulator) stream.asInstanceOf[Stream[Int]].collect(IntAccumulator.supplier, IntAccumulator.boxedAdder, IntAccumulator.merger).asInstanceOf[C] + else if (info.companion == LongAccumulator) stream.asInstanceOf[Stream[Long]].collect(LongAccumulator.supplier, LongAccumulator.boxedAdder, LongAccumulator.merger).asInstanceOf[C] + else if (info.companion == DoubleAccumulator) stream.asInstanceOf[Stream[Double]].collect(DoubleAccumulator.supplier, DoubleAccumulator.boxedAdder, DoubleAccumulator.merger).asInstanceOf[C] else if (stream.isParallel) anyAcc.to(factory) else factory.fromSpecific(stream.iterator.asScala) } + /** + * Copy the elements of this stream into a Scala collection. + * + * For parallel streams, using [[accumulate]] is recommended as it builds the [[Accumulator]] + * in parallel. + * + * When converting a parallel stream to a different Scala collection, the stream is first + * converted into an [[Accumulator]], which supports parallel building. The accumulator is + * then converted to the target collection. Note that the stream is processed eagerly while + * building the accumulator, even if the target collection is lazy. + * + * Sequential streams are directly converted to the target collection. If the target collection + * is lazy, the conversion is lazy as well. + */ + def toScala[CC[_]](implicit factory: collection.Factory[A, CC[A]]): CC[A] = { + if (stream.isParallel) toScalaFactory(Accumulator).to(factory) + else factory.fromSpecific(stream.iterator.asScala) + } + /** Convert a generic Java Stream wrapping a primitive type to a corresponding primitive * Stream. */ @@ -248,39 +266,39 @@ trait StreamExtensions { } implicit class StreamIntHasAccumulatePrimitive(s: Stream[Int]) { - def accumulatePrimitive: IntAccumulator = s.toScala(Accumulator) + def accumulatePrimitive: IntAccumulator = s.toScalaFactory(Accumulator) } implicit class StreamLongHasAccumulatePrimitive(s: Stream[Long]) { - def accumulatePrimitive: LongAccumulator = s.toScala(Accumulator) + def accumulatePrimitive: LongAccumulator = s.toScalaFactory(Accumulator) } implicit class StreamDoubleHasAccumulatePrimitive(s: Stream[Double]) { - def accumulatePrimitive: DoubleAccumulator = s.toScala(Accumulator) + def accumulatePrimitive: DoubleAccumulator = s.toScalaFactory(Accumulator) } implicit class StreamJIntegerHasAccumulatePrimitive(s: Stream[java.lang.Integer]) { - def accumulatePrimitive: IntAccumulator = s.toScala(Accumulator) + def accumulatePrimitive: IntAccumulator = s.toScalaFactory(Accumulator) } implicit class StreamJLongHasAccumulatePrimitive(s: Stream[java.lang.Long]) { - def accumulatePrimitive: LongAccumulator = s.toScala(Accumulator) + def accumulatePrimitive: LongAccumulator = s.toScalaFactory(Accumulator) } implicit class StreamJDoubleHasAccumulatePrimitive(s: Stream[java.lang.Double]) { - def accumulatePrimitive: DoubleAccumulator = s.toScala(Accumulator) + def accumulatePrimitive: DoubleAccumulator = s.toScalaFactory(Accumulator) } implicit class IntStreamHasToScala(stream: IntStream) { - def accumulate: IntAccumulator = toScala(IntAccumulator) + def accumulate: IntAccumulator = toScalaFactory(IntAccumulator) /** * Copy the elements of this stream into a Scala collection. * - * Converting a parallel streams to an [[Accumulator]] using `stream.toScala(Accumulator)` + * Converting a parallel streams to an [[Accumulator]] using `stream.toScalaFactory(Accumulator)` * builds the result in parallel. * - * A `toScala(Accumulator)` call automatically converts the `IntStream` to a primitive + * A `toScalaFactory(Accumulator)` call automatically converts the `IntStream` to a primitive * [[IntAccumulator]]. * * When converting a parallel stream to a different Scala collection, the stream is first @@ -291,25 +309,44 @@ trait StreamExtensions { * Sequential streams are directly converted to the target collection. If the target collection * is lazy, the conversion is lazy as well. */ - def toScala[C1](factory: collection.Factory[Int, C1])(implicit info: AccumulatorFactoryInfo[Int, C1]): C1 = { + private[java8] def toScalaFactory[C](factory: collection.Factory[Int, C])(implicit info: AccumulatorFactoryInfo[Int, C]): C = { def intAcc = stream.collect(IntAccumulator.supplier, IntAccumulator.adder, IntAccumulator.merger) - if (info.companion == AnyAccumulator) stream.collect(AnyAccumulator.supplier[Int], AnyAccumulator.unboxedIntAdder, AnyAccumulator.merger[Int]).asInstanceOf[C1] - else if (info.companion == IntAccumulator) intAcc.asInstanceOf[C1] + if (info.companion == AnyAccumulator) stream.collect(AnyAccumulator.supplier[Int], AnyAccumulator.unboxedIntAdder, AnyAccumulator.merger[Int]).asInstanceOf[C] + else if (info.companion == IntAccumulator) intAcc.asInstanceOf[C] else if (stream.isParallel) intAcc.to(factory) else factory.fromSpecific(stream.iterator.asInstanceOf[java.util.Iterator[Int]].asScala) } + + /** + * Copy the elements of this stream into a Scala collection. + * + * For parallel streams, using [[accumulate]] is recommended as it builds the [[IntAccumulator]] + * in parallel. + * + * When converting a parallel stream to a different Scala collection, the stream is first + * converted into an [[Accumulator]], which supports parallel building. The accumulator is + * then converted to the target collection. Note that the stream is processed eagerly while + * building the accumulator, even if the target collection is lazy. + * + * Sequential streams are directly converted to the target collection. If the target collection + * is lazy, the conversion is lazy as well. + */ + def toScala[CC[_]](implicit factory: collection.Factory[Int, CC[Int]]): CC[Int] = { + if (stream.isParallel) toScalaFactory(IntAccumulator).to(factory) + else factory.fromSpecific(stream.iterator.asInstanceOf[java.util.Iterator[Int]].asScala) + } } implicit class LongStreamHasToScala(stream: LongStream) { - def accumulate: LongAccumulator = toScala(LongAccumulator) + def accumulate: LongAccumulator = toScalaFactory(LongAccumulator) /** * Copy the elements of this stream into a Scala collection. * - * Converting a parallel streams to an [[Accumulator]] using `stream.toScala(Accumulator)` + * Converting a parallel streams to an [[Accumulator]] using `stream.toScalaFactory(Accumulator)` * builds the result in parallel. * - * A `toScala(Accumulator)` call automatically converts the `LongStream` to a primitive + * A `toScalaFactory(Accumulator)` call automatically converts the `LongStream` to a primitive * [[LongAccumulator]]. * * When converting a parallel stream to a different Scala collection, the stream is first @@ -320,25 +357,44 @@ trait StreamExtensions { * Sequential streams are directly converted to the target collection. If the target collection * is lazy, the conversion is lazy as well. */ - def toScala[C1](factory: collection.Factory[Long, C1])(implicit info: AccumulatorFactoryInfo[Long, C1]): C1 = { + private[java8] def toScalaFactory[C](factory: collection.Factory[Long, C])(implicit info: AccumulatorFactoryInfo[Long, C]): C = { def longAcc = stream.collect(LongAccumulator.supplier, LongAccumulator.adder, LongAccumulator.merger) - if (info.companion == AnyAccumulator) stream.collect(AnyAccumulator.supplier[Long], AnyAccumulator.unboxedLongAdder, AnyAccumulator.merger[Long]).asInstanceOf[C1] - else if (info.companion == LongAccumulator) longAcc.asInstanceOf[C1] + if (info.companion == AnyAccumulator) stream.collect(AnyAccumulator.supplier[Long], AnyAccumulator.unboxedLongAdder, AnyAccumulator.merger[Long]).asInstanceOf[C] + else if (info.companion == LongAccumulator) longAcc.asInstanceOf[C] else if (stream.isParallel) longAcc.to(factory) else factory.fromSpecific(stream.iterator.asInstanceOf[java.util.Iterator[Long]].asScala) } + + /** + * Copy the elements of this stream into a Scala collection. + * + * For parallel streams, using [[accumulate]] is recommended as it builds the [[LongAccumulator]] + * in parallel. + * + * When converting a parallel stream to a different Scala collection, the stream is first + * converted into an [[Accumulator]], which supports parallel building. The accumulator is + * then converted to the target collection. Note that the stream is processed eagerly while + * building the accumulator, even if the target collection is lazy. + * + * Sequential streams are directly converted to the target collection. If the target collection + * is lazy, the conversion is lazy as well. + */ + def toScala[CC[_]](implicit factory: collection.Factory[Long, CC[Long]]): CC[Long] = { + if (stream.isParallel) toScalaFactory(LongAccumulator).to(factory) + else factory.fromSpecific(stream.iterator.asInstanceOf[java.util.Iterator[Long]].asScala) + } } implicit class DoubleStreamHasToScala(stream: DoubleStream) { - def accumulate: DoubleAccumulator = toScala(DoubleAccumulator) + def accumulate: DoubleAccumulator = toScalaFactory(DoubleAccumulator) /** * Copy the elements of this stream into a Scala collection. * - * Converting a parallel streams to an [[Accumulator]] using `stream.toScala(Accumulator)` + * Converting a parallel streams to an [[Accumulator]] using `stream.toScalaFactory(Accumulator)` * builds the result in parallel. * - * A `toScala(Accumulator)` call automatically converts the `DoubleStream` to a primitive + * A `toScalaFactory(Accumulator)` call automatically converts the `DoubleStream` to a primitive * [[DoubleAccumulator]]. * * When converting a parallel stream to a different Scala collection, the stream is first @@ -349,13 +405,32 @@ trait StreamExtensions { * Sequential streams are directly converted to the target collection. If the target collection * is lazy, the conversion is lazy as well. */ - def toScala[C1](factory: collection.Factory[Double, C1])(implicit info: AccumulatorFactoryInfo[Double, C1]): C1 = { + private[java8] def toScalaFactory[C](factory: collection.Factory[Double, C])(implicit info: AccumulatorFactoryInfo[Double, C]): C = { def doubleAcc = stream.collect(DoubleAccumulator.supplier, DoubleAccumulator.adder, DoubleAccumulator.merger) - if (info.companion == AnyAccumulator) stream.collect(AnyAccumulator.supplier[Double], AnyAccumulator.unboxedDoubleAdder, AnyAccumulator.merger[Double]).asInstanceOf[C1] - else if (info.companion == DoubleAccumulator) doubleAcc.asInstanceOf[C1] + if (info.companion == AnyAccumulator) stream.collect(AnyAccumulator.supplier[Double], AnyAccumulator.unboxedDoubleAdder, AnyAccumulator.merger[Double]).asInstanceOf[C] + else if (info.companion == DoubleAccumulator) doubleAcc.asInstanceOf[C] else if (stream.isParallel) doubleAcc.to(factory) else factory.fromSpecific(stream.iterator.asInstanceOf[java.util.Iterator[Double]].asScala) } + + /** + * Copy the elements of this stream into a Scala collection. + * + * For parallel streams, using [[accumulate]] is recommended as it builds the [[DoubleAccumulator]] + * in parallel. + * + * When converting a parallel stream to a different Scala collection, the stream is first + * converted into an [[Accumulator]], which supports parallel building. The accumulator is + * then converted to the target collection. Note that the stream is processed eagerly while + * building the accumulator, even if the target collection is lazy. + * + * Sequential streams are directly converted to the target collection. If the target collection + * is lazy, the conversion is lazy as well. + */ + def toScala[CC[_]](implicit factory: collection.Factory[Double, CC[Double]]): CC[Double] = { + if (stream.isParallel) toScalaFactory(DoubleAccumulator).to(factory) + else factory.fromSpecific(stream.iterator.asInstanceOf[java.util.Iterator[Double]].asScala) + } } } diff --git a/src/test/scala/scala/compat/java8/StreamConvertersTest.scala b/src/test/scala/scala/compat/java8/StreamConvertersTest.scala index f2a084f..7ec3778 100644 --- a/src/test/scala/scala/compat/java8/StreamConvertersTest.scala +++ b/src/test/scala/scala/compat/java8/StreamConvertersTest.scala @@ -99,18 +99,26 @@ class StreamConvertersTest { val vecO = arrayO(n).toVector assertEq(vecO, newStream(n).toScala(Vector)) assertEq(vecO, newStream(n).parallel.toScala(Vector)) + assertEq(vecO, newStream(n).toScala[Vector]) + assertEq(vecO, newStream(n).parallel.toScala[Vector]) val vecD = arrayD(n).toVector assertEq(vecD, newDoubleStream(n).toScala(Vector)) assertEq(vecD, newDoubleStream(n).parallel.toScala(Vector)) + assertEq(vecD, newDoubleStream(n).toScala[Vector]) + assertEq(vecD, newDoubleStream(n).parallel.toScala[Vector]) val vecI = arrayI(n).toVector assertEq(vecI, newIntStream(n).toScala(Vector)) assertEq(vecI, newIntStream(n).parallel.toScala(Vector)) + assertEq(vecI, newIntStream(n).toScala[Vector]) + assertEq(vecI, newIntStream(n).parallel.toScala[Vector]) val vecL = arrayL(n).toVector assertEq(vecL, newLongStream(n).toScala(Vector)) assertEq(vecL, newLongStream(n).parallel.toScala(Vector)) + assertEq(vecL, newLongStream(n).toScala[Vector]) + assertEq(vecL, newLongStream(n).parallel.toScala[Vector]) } } @@ -150,18 +158,18 @@ class StreamConvertersTest { val vecO = vectO(n) val hsO = hsetO(n) // Seems like a lot of boilerplate, but we need it to test implicit resolution - assertEq(seqO, seqO.seqStream.toScala(Seq)) -// assertEq(seqO, seqO.stepper.parStream.toScala(Seq) // Must go through stepper if we're unsure whether we can parallelize well - assertEq(seqO, arrO.seqStream.toScala(Seq)) - assertEq(seqO, arrO.parStream.toScala(Seq)) - assertEq(seqO, abO.seqStream.toScala(Seq)) - assertEq(seqO, abO.parStream.toScala(Seq)) - assertEq(seqO, wrO.seqStream.toScala(Seq)) - assertEq(seqO, wrO.parStream.toScala(Seq)) - assertEq(seqO, vecO.seqStream.toScala(Seq)) - assertEq(seqO, vecO.parStream.toScala(Seq)) -// assertEq(seqO, hsO.seqStream.toScala(Seq.sortBy(_.toInt)) -// assertEq(seqO, hsO.parStream.toScala(Seq.sortBy(_.toInt)) + assertEq(seqO, seqO.seqStream.toScala[Seq]) +// assertEq(seqO, seqO.stepper.parStream.toScala[Seq] // Must go through stepper if we're unsure whether we can parallelize well + assertEq(seqO, arrO.seqStream.toScala[Seq]) + assertEq(seqO, arrO.parStream.toScala[Seq]) + assertEq(seqO, abO.seqStream.toScala[Seq]) + assertEq(seqO, abO.parStream.toScala[Seq]) + assertEq(seqO, wrO.seqStream.toScala[Seq]) + assertEq(seqO, wrO.parStream.toScala[Seq]) + assertEq(seqO, vecO.seqStream.toScala[Seq]) + assertEq(seqO, vecO.parStream.toScala[Seq]) +// assertEq(seqO, hsO.seqStream.toScala[Seq]sortBy(_.toInt)) +// assertEq(seqO, hsO.parStream.toScala[Seq]sortBy(_.toInt)) val arrD = arrayD(n) val seqD = arrD.toSeq @@ -169,26 +177,26 @@ class StreamConvertersTest { val wrD = wrapD(n) val vecD = vectD(n) val hsD = hsetD(n) - assertEq(seqD, seqD.seqStream.toScala(Seq)) -// assertEq(seqD, seqD.stepper.parStream.toScala(Seq) - assertEq(seqD, arrD.seqStream.toScala(Seq)) - assertEq(seqD, arrD.parStream.toScala(Seq)) + assertEq(seqD, seqD.seqStream.toScala[Seq]) +// assertEq(seqD, seqD.stepper.parStream.toScala[Seq] + assertEq(seqD, arrD.seqStream.toScala[Seq]) + assertEq(seqD, arrD.parStream.toScala[Seq]) assert(arrD.seqStream.isInstanceOf[DoubleStream]) assert(arrD.parStream.isInstanceOf[DoubleStream]) - assertEq(seqD, abD.seqStream.toScala(Seq)) - assertEq(seqD, abD.parStream.toScala(Seq)) + assertEq(seqD, abD.seqStream.toScala[Seq]) + assertEq(seqD, abD.parStream.toScala[Seq]) assert(abD.seqStream.isInstanceOf[DoubleStream]) assert(abD.parStream.isInstanceOf[DoubleStream]) - assertEq(seqD, wrD.seqStream.toScala(Seq)) - assertEq(seqD, wrD.parStream.toScala(Seq)) + assertEq(seqD, wrD.seqStream.toScala[Seq]) + assertEq(seqD, wrD.parStream.toScala[Seq]) assert(wrD.seqStream.isInstanceOf[DoubleStream]) assert(wrD.parStream.isInstanceOf[DoubleStream]) - assertEq(seqD, vecD.seqStream.toScala(Seq)) - assertEq(seqD, vecD.parStream.toScala(Seq)) + assertEq(seqD, vecD.seqStream.toScala[Seq]) + assertEq(seqD, vecD.parStream.toScala[Seq]) assert(vecD.seqStream.isInstanceOf[DoubleStream]) assert(vecD.parStream.isInstanceOf[DoubleStream]) -// assertEq(seqD, hsD.seqStream.toScala(Seq.sorted) -// assertEq(seqD, hsD.parStream.toScala(Seq.sorted) +// assertEq(seqD, hsD.seqStream.toScala[Seq]sorted) +// assertEq(seqD, hsD.parStream.toScala[Seq]sorted) // assert(hsD.seqStream.isInstanceOf[DoubleStream]) // assert(hsD.parStream.isInstanceOf[DoubleStream]) @@ -198,26 +206,26 @@ class StreamConvertersTest { val wrI = wrapI(n) val vecI = vectI(n) val hsI = hsetI(n) - assertEq(seqI, seqI.seqStream.toScala(Seq)) -// assertEq(seqI, seqI.stepper.parStream.toScala(Seq) - assertEq(seqI, arrI.seqStream.toScala(Seq)) - assertEq(seqI, arrI.parStream.toScala(Seq)) + assertEq(seqI, seqI.seqStream.toScala[Seq]) +// assertEq(seqI, seqI.stepper.parStream.toScala[Seq] + assertEq(seqI, arrI.seqStream.toScala[Seq]) + assertEq(seqI, arrI.parStream.toScala[Seq]) assert(arrI.seqStream.isInstanceOf[IntStream]) assert(arrI.parStream.isInstanceOf[IntStream]) - assertEq(seqI, abI.seqStream.toScala(Seq)) - assertEq(seqI, abI.parStream.toScala(Seq)) + assertEq(seqI, abI.seqStream.toScala[Seq]) + assertEq(seqI, abI.parStream.toScala[Seq]) assert(abI.seqStream.isInstanceOf[IntStream]) assert(abI.parStream.isInstanceOf[IntStream]) - assertEq(seqI, wrI.seqStream.toScala(Seq)) - assertEq(seqI, wrI.parStream.toScala(Seq)) + assertEq(seqI, wrI.seqStream.toScala[Seq]) + assertEq(seqI, wrI.parStream.toScala[Seq]) assert(wrI.seqStream.isInstanceOf[IntStream]) assert(wrI.parStream.isInstanceOf[IntStream]) - assertEq(seqI, vecI.seqStream.toScala(Seq)) - assertEq(seqI, vecI.parStream.toScala(Seq)) + assertEq(seqI, vecI.seqStream.toScala[Seq]) + assertEq(seqI, vecI.parStream.toScala[Seq]) assert(vecI.seqStream.isInstanceOf[IntStream]) assert(vecI.parStream.isInstanceOf[IntStream]) -// assertEq(seqI, hsI.seqStream.toScala(Seq.sorted) -// assertEq(seqI, hsI.parStream.toScala(Seq.sorted) +// assertEq(seqI, hsI.seqStream.toScala[Seq]sorted) +// assertEq(seqI, hsI.parStream.toScala[Seq]sorted) // assert(hsI.seqStream.isInstanceOf[IntStream]) // assert(hsI.parStream.isInstanceOf[IntStream]) @@ -227,26 +235,26 @@ class StreamConvertersTest { val wrL = wrapL(n) val vecL = vectL(n) val hsL = hsetL(n) - assertEq(seqL, seqL.seqStream.toScala(Seq)) -// assertEq(seqL, seqL.stepper.parStream.toScala(Seq) - assertEq(seqL, arrL.seqStream.toScala(Seq)) - assertEq(seqL, arrL.parStream.toScala(Seq)) + assertEq(seqL, seqL.seqStream.toScala[Seq]) +// assertEq(seqL, seqL.stepper.parStream.toScala[Seq] + assertEq(seqL, arrL.seqStream.toScala[Seq]) + assertEq(seqL, arrL.parStream.toScala[Seq]) assert(arrL.seqStream.isInstanceOf[LongStream]) assert(arrL.parStream.isInstanceOf[LongStream]) - assertEq(seqL, abL.seqStream.toScala(Seq)) - assertEq(seqL, abL.parStream.toScala(Seq)) + assertEq(seqL, abL.seqStream.toScala[Seq]) + assertEq(seqL, abL.parStream.toScala[Seq]) assert(abL.seqStream.isInstanceOf[LongStream]) assert(abL.parStream.isInstanceOf[LongStream]) - assertEq(seqD, wrD.seqStream.toScala(Seq)) - assertEq(seqD, wrD.parStream.toScala(Seq)) + assertEq(seqD, wrD.seqStream.toScala[Seq]) + assertEq(seqD, wrD.parStream.toScala[Seq]) assert(wrL.seqStream.isInstanceOf[LongStream]) assert(wrL.parStream.isInstanceOf[LongStream]) - assertEq(seqD, wrD.seqStream.toScala(Seq)) - assertEq(seqD, wrD.parStream.toScala(Seq)) + assertEq(seqD, wrD.seqStream.toScala[Seq]) + assertEq(seqD, wrD.parStream.toScala[Seq]) assert(vecL.seqStream.isInstanceOf[LongStream]) assert(vecL.parStream.isInstanceOf[LongStream]) -// assertEq(seqL, hsL.seqStream.toScala(Seq.sorted) -// assertEq(seqL, hsL.parStream.toScala(Seq.sorted) +// assertEq(seqL, hsL.seqStream.toScala[Seq]sorted) +// assertEq(seqL, hsL.parStream.toScala[Seq]sorted) // assert(hsL.seqStream.isInstanceOf[LongStream]) // assert(hsL.parStream.isInstanceOf[LongStream]) } @@ -255,14 +263,14 @@ class StreamConvertersTest { @Test def primitiveStreamTypes(): Unit = { // Unboxed native + widening Steppers available: - assertEquals(Vector[Int](1, 2, 3), (Array[Int](1, 2, 3).seqStream: IntStream).toScala(Vector)) - assertEquals(Vector[Short](1.toShort, 2.toShort, 3.toShort), (Array[Short](1.toShort, 2.toShort, 3.toShort).seqStream: IntStream).toScala(Vector)) - assertEquals(Vector[String]("a", "b"), (Array[String]("a", "b").seqStream: Stream[String]).toScala(Vector)) + assertEquals(Vector[Int](1, 2, 3), (Array[Int](1, 2, 3).seqStream: IntStream).toScala[Vector]) + assertEquals(Vector[Short](1.toShort, 2.toShort, 3.toShort), (Array[Short](1.toShort, 2.toShort, 3.toShort).seqStream: IntStream).toScala[Vector]) + assertEquals(Vector[String]("a", "b"), (Array[String]("a", "b").seqStream: Stream[String]).toScala[Vector]) // Boxed collections, widening via boxed AnySteppers: - assertEquals(Vector[Int](1, 2, 3), (Vector[Int](1, 2, 3).seqStream: IntStream).toScala(Vector)) - assertEquals(Vector[Short](1.toShort, 2.toShort, 3.toShort), (Vector[Short](1.toShort, 2.toShort, 3.toShort).seqStream: IntStream).toScala(Vector)) - assertEquals(Vector[String]("a", "b"), (Vector[String]("a", "b").seqStream: Stream[String]).toScala(Vector)) + assertEquals(Vector[Int](1, 2, 3), (Vector[Int](1, 2, 3).seqStream: IntStream).toScala[Vector]) + assertEquals(Vector[Short](1.toShort, 2.toShort, 3.toShort), (Vector[Short](1.toShort, 2.toShort, 3.toShort).seqStream: IntStream).toScala[Vector]) + assertEquals(Vector[String]("a", "b"), (Vector[String]("a", "b").seqStream: Stream[String]).toScala[Vector]) } @Test From 873ddf8a872c99538d90e25e38f0d42e44dc0f55 Mon Sep 17 00:00:00 2001 From: Lukas Rytz Date: Mon, 20 May 2019 13:54:00 +0200 Subject: [PATCH 19/23] fix typos in comments --- .../compat/java8/StreamConvertersTest.scala | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/test/scala/scala/compat/java8/StreamConvertersTest.scala b/src/test/scala/scala/compat/java8/StreamConvertersTest.scala index 7ec3778..0beb9ae 100644 --- a/src/test/scala/scala/compat/java8/StreamConvertersTest.scala +++ b/src/test/scala/scala/compat/java8/StreamConvertersTest.scala @@ -159,7 +159,7 @@ class StreamConvertersTest { val hsO = hsetO(n) // Seems like a lot of boilerplate, but we need it to test implicit resolution assertEq(seqO, seqO.seqStream.toScala[Seq]) -// assertEq(seqO, seqO.stepper.parStream.toScala[Seq] // Must go through stepper if we're unsure whether we can parallelize well +// assertEq(seqO, seqO.stepper.parStream.toScala[Seq]) // Must go through stepper if we're unsure whether we can parallelize well assertEq(seqO, arrO.seqStream.toScala[Seq]) assertEq(seqO, arrO.parStream.toScala[Seq]) assertEq(seqO, abO.seqStream.toScala[Seq]) @@ -168,8 +168,8 @@ class StreamConvertersTest { assertEq(seqO, wrO.parStream.toScala[Seq]) assertEq(seqO, vecO.seqStream.toScala[Seq]) assertEq(seqO, vecO.parStream.toScala[Seq]) -// assertEq(seqO, hsO.seqStream.toScala[Seq]sortBy(_.toInt)) -// assertEq(seqO, hsO.parStream.toScala[Seq]sortBy(_.toInt)) +// assertEq(seqO, hsO.seqStream.toScala[Seq].sortBy(_.toInt)) +// assertEq(seqO, hsO.parStream.toScala[Seq].sortBy(_.toInt)) val arrD = arrayD(n) val seqD = arrD.toSeq @@ -178,7 +178,7 @@ class StreamConvertersTest { val vecD = vectD(n) val hsD = hsetD(n) assertEq(seqD, seqD.seqStream.toScala[Seq]) -// assertEq(seqD, seqD.stepper.parStream.toScala[Seq] +// assertEq(seqD, seqD.stepper.parStream.toScala[Seq]) assertEq(seqD, arrD.seqStream.toScala[Seq]) assertEq(seqD, arrD.parStream.toScala[Seq]) assert(arrD.seqStream.isInstanceOf[DoubleStream]) @@ -195,8 +195,8 @@ class StreamConvertersTest { assertEq(seqD, vecD.parStream.toScala[Seq]) assert(vecD.seqStream.isInstanceOf[DoubleStream]) assert(vecD.parStream.isInstanceOf[DoubleStream]) -// assertEq(seqD, hsD.seqStream.toScala[Seq]sorted) -// assertEq(seqD, hsD.parStream.toScala[Seq]sorted) +// assertEq(seqD, hsD.seqStream.toScala[Seq].sorted) +// assertEq(seqD, hsD.parStream.toScala[Seq].sorted) // assert(hsD.seqStream.isInstanceOf[DoubleStream]) // assert(hsD.parStream.isInstanceOf[DoubleStream]) @@ -207,7 +207,7 @@ class StreamConvertersTest { val vecI = vectI(n) val hsI = hsetI(n) assertEq(seqI, seqI.seqStream.toScala[Seq]) -// assertEq(seqI, seqI.stepper.parStream.toScala[Seq] +// assertEq(seqI, seqI.stepper.parStream.toScala[Seq]) assertEq(seqI, arrI.seqStream.toScala[Seq]) assertEq(seqI, arrI.parStream.toScala[Seq]) assert(arrI.seqStream.isInstanceOf[IntStream]) @@ -224,8 +224,8 @@ class StreamConvertersTest { assertEq(seqI, vecI.parStream.toScala[Seq]) assert(vecI.seqStream.isInstanceOf[IntStream]) assert(vecI.parStream.isInstanceOf[IntStream]) -// assertEq(seqI, hsI.seqStream.toScala[Seq]sorted) -// assertEq(seqI, hsI.parStream.toScala[Seq]sorted) +// assertEq(seqI, hsI.seqStream.toScala[Seq].sorted) +// assertEq(seqI, hsI.parStream.toScala[Seq].sorted) // assert(hsI.seqStream.isInstanceOf[IntStream]) // assert(hsI.parStream.isInstanceOf[IntStream]) @@ -236,7 +236,7 @@ class StreamConvertersTest { val vecL = vectL(n) val hsL = hsetL(n) assertEq(seqL, seqL.seqStream.toScala[Seq]) -// assertEq(seqL, seqL.stepper.parStream.toScala[Seq] +// assertEq(seqL, seqL.stepper.parStream.toScala[Seq]) assertEq(seqL, arrL.seqStream.toScala[Seq]) assertEq(seqL, arrL.parStream.toScala[Seq]) assert(arrL.seqStream.isInstanceOf[LongStream]) @@ -253,8 +253,8 @@ class StreamConvertersTest { assertEq(seqD, wrD.parStream.toScala[Seq]) assert(vecL.seqStream.isInstanceOf[LongStream]) assert(vecL.parStream.isInstanceOf[LongStream]) -// assertEq(seqL, hsL.seqStream.toScala[Seq]sorted) -// assertEq(seqL, hsL.parStream.toScala[Seq]sorted) +// assertEq(seqL, hsL.seqStream.toScala[Seq].sorted) +// assertEq(seqL, hsL.parStream.toScala[Seq].sorted) // assert(hsL.seqStream.isInstanceOf[LongStream]) // assert(hsL.parStream.isInstanceOf[LongStream]) } From 164a5f4833bb9d535db3a2c06e9034801b0c79cd Mon Sep 17 00:00:00 2001 From: Lukas Rytz Date: Wed, 1 May 2019 12:11:10 +0200 Subject: [PATCH 20/23] adapt to changes for 2.13.0-RC2 --- .travis.yml | 2 +- build.sbt | 2 +- .../compat/java8/ScalaStreamSupport.java | 26 +++++++++---------- .../scala/compat/java8/StreamConverters.scala | 4 +-- .../scala/compat/java8/StepperTest.scala | 4 +-- 5 files changed, 19 insertions(+), 19 deletions(-) diff --git a/.travis.yml b/.travis.yml index af0c85a..24e00c5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,7 @@ jdk: - openjdk11 scala: - - 2.13.0-RC1 + - 2.13.0-RC2 env: global: diff --git a/build.sbt b/build.sbt index 4340667..5cb40dd 100644 --- a/build.sbt +++ b/build.sbt @@ -1,6 +1,6 @@ import ScalaModulePlugin._ -crossScalaVersions in ThisBuild := List("2.13.0-RC1") +crossScalaVersions in ThisBuild := List("2.13.0-RC2") val disableDocs = sys.props("nodocs") == "true" || diff --git a/src/main/java/scala/compat/java8/ScalaStreamSupport.java b/src/main/java/scala/compat/java8/ScalaStreamSupport.java index 112833e..c1ac69b 100644 --- a/src/main/java/scala/compat/java8/ScalaStreamSupport.java +++ b/src/main/java/scala/compat/java8/ScalaStreamSupport.java @@ -15,7 +15,7 @@ import java.util.stream.*; import scala.collection.*; -import scala.jdk.StreamConverters; +import scala.jdk.javaapi.StreamConverters; /** * This class contains static utility methods for creating Java Streams from Scala Collections, similar @@ -142,7 +142,7 @@ public static Stream streamAccumulatedValues(Map coll) { * @return A DoubleStream view of the collection which, by default, executes sequentially. */ public static DoubleStream doubleStream(IterableOnce coll) { - return StreamConverters.asJavaSeqDoubleStream((IterableOnce)(Object)coll); + return StreamConverters.asJavaSeqDoubleStream(coll); } /** @@ -183,7 +183,7 @@ public static DoubleStream doubleStreamValues(Map coll) { * @return A DoubleStream view of the collection which, by default, executes sequentially. */ public static DoubleStream doubleStreamAccumulated(IterableOnce coll) { - return StreamConverters.asJavaSeqDoubleStream(scala.jdk.DoubleAccumulator$.MODULE$.fromSpecific((IterableOnce)(Object)coll)); + return StreamConverters.asJavaSeqDoubleStream((IterableOnce)(Object)scala.jdk.DoubleAccumulator$.MODULE$.fromSpecific((IterableOnce)(Object)coll)); } /** @@ -196,7 +196,7 @@ public static DoubleStream doubleStreamAccumulated(IterableOnce coll) { * @return A DoubleStream view of the collection which, by default, executes sequentially. */ public static DoubleStream doubleStreamAccumulatedKeys(Map coll) { - return StreamConverters.asJavaSeqDoubleStream(scala.jdk.DoubleAccumulator$.MODULE$.fromSpecific((IterableOnce)(Object)coll.keysIterator())); + return StreamConverters.asJavaSeqDoubleStream((IterableOnce)(Object)scala.jdk.DoubleAccumulator$.MODULE$.fromSpecific((IterableOnce)(Object)coll.keysIterator())); } /** @@ -209,7 +209,7 @@ public static DoubleStream doubleStreamAccumulatedKeys(Map coll) { * @return A DoubleStream view of the collection which, by default, executes sequentially. */ public static DoubleStream doubleStreamAccumulatedValues(Map coll) { - return StreamConverters.asJavaSeqDoubleStream(scala.jdk.DoubleAccumulator$.MODULE$.fromSpecific((IterableOnce)(Object)coll.valuesIterator())); + return StreamConverters.asJavaSeqDoubleStream((IterableOnce)(Object)scala.jdk.DoubleAccumulator$.MODULE$.fromSpecific((IterableOnce)(Object)coll.valuesIterator())); } ///////////////// @@ -227,7 +227,7 @@ public static DoubleStream doubleStreamAccumulatedValues(Map coll) { * @return A IntStream view of the collection which, by default, executes sequentially. */ public static IntStream intStream(IterableOnce coll) { - return StreamConverters.asJavaSeqIntStream((IterableOnce)(Object)coll); + return StreamConverters.asJavaSeqIntStream(coll); } /** @@ -268,7 +268,7 @@ public static IntStream intStreamValues(Map coll) { * @return A IntStream view of the collection which, by default, executes sequentially. */ public static IntStream intStreamAccumulated(IterableOnce coll) { - return StreamConverters.asJavaSeqIntStream(scala.jdk.IntAccumulator$.MODULE$.fromSpecific((IterableOnce)(Object)coll)); + return StreamConverters.asJavaSeqIntStream((IterableOnce)(Object)scala.jdk.IntAccumulator$.MODULE$.fromSpecific((IterableOnce)(Object)coll)); } /** @@ -281,7 +281,7 @@ public static IntStream intStreamAccumulated(IterableOnce coll) { * @return A IntStream view of the collection which, by default, executes sequentially. */ public static IntStream intStreamAccumulatedKeys(Map coll) { - return StreamConverters.asJavaSeqIntStream(scala.jdk.IntAccumulator$.MODULE$.fromSpecific((IterableOnce)(Object)coll.keysIterator())); + return StreamConverters.asJavaSeqIntStream((IterableOnce)(Object)scala.jdk.IntAccumulator$.MODULE$.fromSpecific((IterableOnce)(Object)coll.keysIterator())); } /** @@ -294,7 +294,7 @@ public static IntStream intStreamAccumulatedKeys(Map coll) { * @return A IntStream view of the collection which, by default, executes sequentially. */ public static IntStream intStreamAccumulatedValues(Map coll) { - return StreamConverters.asJavaSeqIntStream(scala.jdk.IntAccumulator$.MODULE$.fromSpecific((IterableOnce)(Object)coll.valuesIterator())); + return StreamConverters.asJavaSeqIntStream((IterableOnce)(Object)scala.jdk.IntAccumulator$.MODULE$.fromSpecific((IterableOnce)(Object)coll.valuesIterator())); } ////////////////// @@ -312,7 +312,7 @@ public static IntStream intStreamAccumulatedValues(Map coll) { * @return A LongStream view of the collection which, by default, executes sequentially. */ public static LongStream longStream(IterableOnce coll) { - return StreamConverters.asJavaSeqLongStream((IterableOnce)(Object)coll); + return StreamConverters.asJavaSeqLongStream(coll); } /** @@ -353,7 +353,7 @@ public static LongStream longStreamValues(Map coll) { * @return A LongStream view of the collection which, by default, executes sequentially. */ public static LongStream longStreamAccumulated(IterableOnce coll) { - return StreamConverters.asJavaSeqLongStream(scala.jdk.LongAccumulator$.MODULE$.fromSpecific((IterableOnce)(Object)coll)); + return StreamConverters.asJavaSeqLongStream((IterableOnce)(Object)scala.jdk.LongAccumulator$.MODULE$.fromSpecific((IterableOnce)(Object)coll)); } /** @@ -366,7 +366,7 @@ public static LongStream longStreamAccumulated(IterableOnce coll) { * @return A LongStream view of the collection which, by default, executes sequentially. */ public static LongStream longStreamAccumulatedKeys(Map coll) { - return StreamConverters.asJavaSeqLongStream(scala.jdk.LongAccumulator$.MODULE$.fromSpecific((IterableOnce)(Object)coll.keysIterator())); + return StreamConverters.asJavaSeqLongStream((IterableOnce)(Object)scala.jdk.LongAccumulator$.MODULE$.fromSpecific((IterableOnce)(Object)coll.keysIterator())); } /** @@ -379,6 +379,6 @@ public static LongStream longStreamAccumulatedKeys(Map coll) { * @return A LongStream view of the collection which, by default, executes sequentially. */ public static LongStream longStreamAccumulatedValues(Map coll) { - return StreamConverters.asJavaSeqLongStream(scala.jdk.LongAccumulator$.MODULE$.fromSpecific((IterableOnce)(Object)coll.valuesIterator())); + return StreamConverters.asJavaSeqLongStream((IterableOnce)(Object)scala.jdk.LongAccumulator$.MODULE$.fromSpecific((IterableOnce)(Object)coll.valuesIterator())); } } diff --git a/src/main/scala/scala/compat/java8/StreamConverters.scala b/src/main/scala/scala/compat/java8/StreamConverters.scala index 36afc19..fbdef17 100644 --- a/src/main/scala/scala/compat/java8/StreamConverters.scala +++ b/src/main/scala/scala/compat/java8/StreamConverters.scala @@ -21,11 +21,11 @@ import scala.collection.{IterableOnce, Stepper, StepperShape} import scala.compat.java8.converterImpl._ import scala.jdk._ import scala.language.higherKinds -import scala.jdk.CollectionConverters.Ops._ +import scala.jdk.CollectionConverters._ /** Defines extension methods to create Java Streams for Scala collections, available through - * [[scala.jdk.StreamConverters.Ops]]. + * [[scala.compat.java8.StreamConverters]]. */ trait StreamExtensions { implicit def richStepper[A](s: Stepper[A]): StepperExtensions[A] = new StepperExtensions[A](s) diff --git a/src/test/scala/scala/compat/java8/StepperTest.scala b/src/test/scala/scala/compat/java8/StepperTest.scala index b1d0e2a..e8e51ec 100644 --- a/src/test/scala/scala/compat/java8/StepperTest.scala +++ b/src/test/scala/scala/compat/java8/StepperTest.scala @@ -65,7 +65,7 @@ class MappingStepper[@specialized (Double, Int, Long) A, @specialized(Double, In override def estimateSize: Long = underlying.estimateSize - override def javaIterator: util.Iterator[_] = new util.Iterator[B] { + override def javaIterator[C >: B]: util.Iterator[_] = new util.Iterator[B] { override def hasNext: Boolean = underlying.hasStep override def next(): B = mapping(underlying.nextStep()) } @@ -74,7 +74,7 @@ class MappingStepper[@specialized (Double, Int, Long) A, @specialized(Double, In if (undersub == null) null else new MappingStepper(undersub, mapping) } - def spliterator: Spliterator[_] = new MappingSpliterator[A, B](underlying.spliterator.asInstanceOf[Spliterator[A]], mapping) + def spliterator[C >: B]: Spliterator[_] = new MappingSpliterator[A, B](underlying.spliterator.asInstanceOf[Spliterator[A]], mapping) } class MappingSpliterator[A, B](private val underlying: Spliterator[A], mapping: A => B) extends Spliterator[B] { From 29f2b2b010d660e70b5a50ac6ed03a432829e523 Mon Sep 17 00:00:00 2001 From: Lukas Rytz Date: Mon, 20 May 2019 14:46:28 +0200 Subject: [PATCH 21/23] use fully qualified references in doc comments https://github.com/lightbend/genjavadoc/issues/134 --- .../scala/compat/java8/StreamConverters.scala | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/main/scala/scala/compat/java8/StreamConverters.scala b/src/main/scala/scala/compat/java8/StreamConverters.scala index fbdef17..237a853 100644 --- a/src/main/scala/scala/compat/java8/StreamConverters.scala +++ b/src/main/scala/scala/compat/java8/StreamConverters.scala @@ -216,14 +216,14 @@ trait StreamExtensions { /** * Copy the elements of this stream into a Scala collection. * - * Converting a parallel streams to an [[Accumulator]] using `stream.toScalaFactory(Accumulator)` + * Converting a parallel streams to an [[scala.jdk.Accumulator]] using `stream.toScalaFactory(Accumulator)` * builds the result in parallel. * * A `toScalaFactory(Accumulator)` call automatically converts streams of boxed integers, longs or - * doubles are converted to the primitive accumulators ([[IntAccumulator]], etc.). + * doubles are converted to the primitive accumulators ([[scala.jdk.IntAccumulator]], etc.). * * When converting a parallel stream to a different Scala collection, the stream is first - * converted into an [[Accumulator]], which supports parallel building. The accumulator is + * converted into an [[scala.jdk.Accumulator]], which supports parallel building. The accumulator is * then converted to the target collection. Note that the stream is processed eagerly while * building the accumulator, even if the target collection is lazy. * @@ -243,11 +243,11 @@ trait StreamExtensions { /** * Copy the elements of this stream into a Scala collection. * - * For parallel streams, using [[accumulate]] is recommended as it builds the [[Accumulator]] + * For parallel streams, using [[accumulate]] is recommended as it builds the [[scala.jdk.Accumulator]] * in parallel. * * When converting a parallel stream to a different Scala collection, the stream is first - * converted into an [[Accumulator]], which supports parallel building. The accumulator is + * converted into an [[scala.jdk.Accumulator]], which supports parallel building. The accumulator is * then converted to the target collection. Note that the stream is processed eagerly while * building the accumulator, even if the target collection is lazy. * @@ -295,14 +295,14 @@ trait StreamExtensions { /** * Copy the elements of this stream into a Scala collection. * - * Converting a parallel streams to an [[Accumulator]] using `stream.toScalaFactory(Accumulator)` + * Converting a parallel streams to an [[scala.jdk.Accumulator]] using `stream.toScalaFactory(Accumulator)` * builds the result in parallel. * * A `toScalaFactory(Accumulator)` call automatically converts the `IntStream` to a primitive - * [[IntAccumulator]]. + * [[scala.jdk.IntAccumulator]]. * * When converting a parallel stream to a different Scala collection, the stream is first - * converted into an [[Accumulator]], which supports parallel building. The accumulator is + * converted into an [[scala.jdk.Accumulator]], which supports parallel building. The accumulator is * then converted to the target collection. Note that the stream is processed eagerly while * building the accumulator, even if the target collection is lazy. * @@ -320,11 +320,11 @@ trait StreamExtensions { /** * Copy the elements of this stream into a Scala collection. * - * For parallel streams, using [[accumulate]] is recommended as it builds the [[IntAccumulator]] + * For parallel streams, using [[accumulate]] is recommended as it builds the [[scala.jdk.IntAccumulator]] * in parallel. * * When converting a parallel stream to a different Scala collection, the stream is first - * converted into an [[Accumulator]], which supports parallel building. The accumulator is + * converted into an [[scala.jdk.Accumulator]], which supports parallel building. The accumulator is * then converted to the target collection. Note that the stream is processed eagerly while * building the accumulator, even if the target collection is lazy. * @@ -343,14 +343,14 @@ trait StreamExtensions { /** * Copy the elements of this stream into a Scala collection. * - * Converting a parallel streams to an [[Accumulator]] using `stream.toScalaFactory(Accumulator)` + * Converting a parallel streams to an [[scala.jdk.Accumulator]] using `stream.toScalaFactory(Accumulator)` * builds the result in parallel. * * A `toScalaFactory(Accumulator)` call automatically converts the `LongStream` to a primitive - * [[LongAccumulator]]. + * [[scala.jdk.LongAccumulator]]. * * When converting a parallel stream to a different Scala collection, the stream is first - * converted into an [[Accumulator]], which supports parallel building. The accumulator is + * converted into an [[scala.jdk.Accumulator]], which supports parallel building. The accumulator is * then converted to the target collection. Note that the stream is processed eagerly while * building the accumulator, even if the target collection is lazy. * @@ -368,11 +368,11 @@ trait StreamExtensions { /** * Copy the elements of this stream into a Scala collection. * - * For parallel streams, using [[accumulate]] is recommended as it builds the [[LongAccumulator]] + * For parallel streams, using [[accumulate]] is recommended as it builds the [[scala.jdk.LongAccumulator]] * in parallel. * * When converting a parallel stream to a different Scala collection, the stream is first - * converted into an [[Accumulator]], which supports parallel building. The accumulator is + * converted into an [[scala.jdk.Accumulator]], which supports parallel building. The accumulator is * then converted to the target collection. Note that the stream is processed eagerly while * building the accumulator, even if the target collection is lazy. * @@ -391,14 +391,14 @@ trait StreamExtensions { /** * Copy the elements of this stream into a Scala collection. * - * Converting a parallel streams to an [[Accumulator]] using `stream.toScalaFactory(Accumulator)` + * Converting a parallel streams to an [[scala.jdk.Accumulator]] using `stream.toScalaFactory(Accumulator)` * builds the result in parallel. * * A `toScalaFactory(Accumulator)` call automatically converts the `DoubleStream` to a primitive - * [[DoubleAccumulator]]. + * [[scala.jdk.DoubleAccumulator]]. * * When converting a parallel stream to a different Scala collection, the stream is first - * converted into an [[Accumulator]], which supports parallel building. The accumulator is + * converted into an [[scala.jdk.Accumulator]], which supports parallel building. The accumulator is * then converted to the target collection. Note that the stream is processed eagerly while * building the accumulator, even if the target collection is lazy. * @@ -416,11 +416,11 @@ trait StreamExtensions { /** * Copy the elements of this stream into a Scala collection. * - * For parallel streams, using [[accumulate]] is recommended as it builds the [[DoubleAccumulator]] + * For parallel streams, using [[accumulate]] is recommended as it builds the [[scala.jdk.DoubleAccumulator]] * in parallel. * * When converting a parallel stream to a different Scala collection, the stream is first - * converted into an [[Accumulator]], which supports parallel building. The accumulator is + * converted into an [[scala.jdk.Accumulator]], which supports parallel building. The accumulator is * then converted to the target collection. Note that the stream is processed eagerly while * building the accumulator, even if the target collection is lazy. * From 4b8d41ac7818dd7d06a0a496307066a7249ed0ed Mon Sep 17 00:00:00 2001 From: Lukas Rytz Date: Wed, 29 May 2019 08:30:06 +0200 Subject: [PATCH 22/23] Adapt to 2.13.0-RC3 --- .travis.yml | 2 +- build.sbt | 2 +- .../compat/java8/ScalaStreamSupport.java | 2 +- .../scala/compat/java8/StreamConverters.scala | 26 +++++++++---------- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/.travis.yml b/.travis.yml index 24e00c5..a90acc1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,7 @@ jdk: - openjdk11 scala: - - 2.13.0-RC2 + - 2.13.0-RC3 env: global: diff --git a/build.sbt b/build.sbt index 5cb40dd..fa8337f 100644 --- a/build.sbt +++ b/build.sbt @@ -1,6 +1,6 @@ import ScalaModulePlugin._ -crossScalaVersions in ThisBuild := List("2.13.0-RC2") +crossScalaVersions in ThisBuild := List("2.13.0-RC3") val disableDocs = sys.props("nodocs") == "true" || diff --git a/src/main/java/scala/compat/java8/ScalaStreamSupport.java b/src/main/java/scala/compat/java8/ScalaStreamSupport.java index c1ac69b..af78ecd 100644 --- a/src/main/java/scala/compat/java8/ScalaStreamSupport.java +++ b/src/main/java/scala/compat/java8/ScalaStreamSupport.java @@ -71,7 +71,7 @@ public static Stream streamKeys(Map coll) { * @return A Stream view of the collection which, by default, executes sequentially. */ public static Stream streamValues(Map coll) { - return StreamSupport.stream(coll.>valueStepper(StepperShape.anyStepperShape()).spliterator(), false); + return StreamSupport.stream(coll.>valueStepper(StepperShape.anyStepperShape()).spliterator(), false); } /** diff --git a/src/main/scala/scala/compat/java8/StreamConverters.scala b/src/main/scala/scala/compat/java8/StreamConverters.scala index 237a853..7234e7a 100644 --- a/src/main/scala/scala/compat/java8/StreamConverters.scala +++ b/src/main/scala/scala/compat/java8/StreamConverters.scala @@ -41,12 +41,12 @@ trait StreamExtensions { s.fromStepper(cc.stepper, par = false) } - protected type IterableOnceWithEfficientStepper[A] = IterableOnce[A] { - def stepper[B >: A, S <: Stepper[_]](implicit shape : StepperShape[B, S]) : S with EfficientSplit - } - // Not `CC[X] <: IterableOnce[X]`, but `C` with an extra constraint, to support non-parametric classes like IntAccumulator implicit class IterableNonGenericHasParStream[A, C <: IterableOnce[_]](c: C)(implicit ev: C <:< IterableOnce[A]) { + private type IterableOnceWithEfficientStepper = IterableOnce[A] { + def stepper[S <: Stepper[_]](implicit shape : StepperShape[A, S]) : S with EfficientSplit + } + /** Create a parallel [[java.util.stream.Stream Java Stream]] for this collection. If the * collection contains primitive values, a corresponding specialized Stream is returned (e.g., * [[java.util.stream.IntStream `IntStream`]]). @@ -55,13 +55,13 @@ trait StreamExtensions { s: StreamShape[A, S, St], st: StepperShape[A, St], @implicitNotFound("`parStream` can only be called on collections where `stepper` returns a `Stepper with EfficientSplit`") - isEfficient: C <:< IterableOnceWithEfficientStepper[A]): S = + isEfficient: C <:< IterableOnceWithEfficientStepper): S = s.fromStepper(ev(c).stepper, par = true) } // maps - implicit class MapHasSeqKeyValueStream[K, V, CC[X, Y] <: collection.MapOps[X, Y, CC, _]](cc: CC[K, V]) { + implicit class MapHasSeqKeyValueStream[K, V, CC[X, Y] <: collection.MapOps[X, Y, collection.Map, _]](cc: CC[K, V]) { /** Create a sequential [[java.util.stream.Stream Java Stream]] for the keys of this map. If * the keys are primitive values, a corresponding specialized Stream is returned (e.g., * [[java.util.stream.IntStream `IntStream`]]). @@ -85,10 +85,10 @@ trait StreamExtensions { } - implicit class MapHasParKeyValueStream[K, V, CC[X, Y] <: collection.MapOps[X, Y, CC, _]](cc: CC[K, V]) { - private type MapOpsWithEfficientKeyStepper[K, V] = collection.MapOps[K, V, CC, _] { def keyStepper[S <: Stepper[_]](implicit shape : StepperShape[K, S]) : S with EfficientSplit } - private type MapOpsWithEfficientValueStepper[K, V] = collection.MapOps[K, V, CC, _] { def valueStepper[V1 >: V, S <: Stepper[_]](implicit shape : StepperShape[V1, S]) : S with EfficientSplit } - private type MapOpsWithEfficientStepper[K, V] = collection.MapOps[K, V, CC, _] { def stepper[B >: (K, V), S <: Stepper[_]](implicit shape : StepperShape[B, S]) : S with EfficientSplit } + implicit class MapHasParKeyValueStream[K, V, CC[X, Y] <: collection.MapOps[X, Y, collection.Map, _]](cc: CC[K, V]) { + private type MapOpsWithEfficientKeyStepper = collection.MapOps[K, V, collection.Map, _] { def keyStepper[S <: Stepper[_]](implicit shape : StepperShape[K, S]) : S with EfficientSplit } + private type MapOpsWithEfficientValueStepper = collection.MapOps[K, V, collection.Map, _] { def valueStepper[V1 >: V, S <: Stepper[_]](implicit shape : StepperShape[V1, S]) : S with EfficientSplit } + private type MapOpsWithEfficientStepper = collection.MapOps[K, V, collection.Map, _] { def stepper[S <: Stepper[_]](implicit shape : StepperShape[(K, V), S]) : S with EfficientSplit } /** Create a parallel [[java.util.stream.Stream Java Stream]] for the keys of this map. If * the keys are primitive values, a corresponding specialized Stream is returned (e.g., @@ -98,7 +98,7 @@ trait StreamExtensions { s: StreamShape[K, S, St], st: StepperShape[K, St], @implicitNotFound("parKeyStream can only be called on maps where `keyStepper` returns a `Stepper with EfficientSplit`") - isEfficient: CC[K, V] <:< MapOpsWithEfficientKeyStepper[K, V]): S = + isEfficient: CC[K, V] <:< MapOpsWithEfficientKeyStepper): S = s.fromStepper(cc.keyStepper, par = true) /** Create a parallel [[java.util.stream.Stream Java Stream]] for the values of this map. If @@ -109,7 +109,7 @@ trait StreamExtensions { s: StreamShape[V, S, St], st: StepperShape[V, St], @implicitNotFound("parValueStream can only be called on maps where `valueStepper` returns a `Stepper with EfficientSplit`") - isEfficient: CC[K, V] <:< MapOpsWithEfficientValueStepper[K, V]): S = + isEfficient: CC[K, V] <:< MapOpsWithEfficientValueStepper): S = s.fromStepper(cc.valueStepper, par = true) // The parStream extension method for IterableOnce doesn't apply because its `CC` takes a single type parameter, whereas the one here takes two @@ -120,7 +120,7 @@ trait StreamExtensions { s: StreamShape[(K, V), S, St], st: StepperShape[(K, V), St], @implicitNotFound("parStream can only be called on maps where `stepper` returns a `Stepper with EfficientSplit`") - isEfficient: CC[K, V] <:< MapOpsWithEfficientStepper[K, V]): S = + isEfficient: CC[K, V] <:< MapOpsWithEfficientStepper): S = s.fromStepper(cc.stepper, par = true) } From 1f469a119038ce7020925de3db73518cb7652d64 Mon Sep 17 00:00:00 2001 From: Arnout Engelen Date: Sat, 8 Jun 2019 13:01:16 +0200 Subject: [PATCH 23/23] Adapt to 2.13.0 --- .travis.yml | 2 +- build.sbt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index a90acc1..ed906d4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,7 @@ jdk: - openjdk11 scala: - - 2.13.0-RC3 + - 2.13.0 env: global: diff --git a/build.sbt b/build.sbt index fa8337f..6da152e 100644 --- a/build.sbt +++ b/build.sbt @@ -1,6 +1,6 @@ import ScalaModulePlugin._ -crossScalaVersions in ThisBuild := List("2.13.0-RC3") +crossScalaVersions in ThisBuild := List("2.13.0") val disableDocs = sys.props("nodocs") == "true" ||