From 9dd46f387a5ef39ec7fc861d29c5c89fbcbcaf4d Mon Sep 17 00:00:00 2001 From: Stefan Zeiger Date: Wed, 13 Apr 2016 20:15:53 +0200 Subject: [PATCH 1/4] Unboxed Steppers for `WrappedArray` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - `WrappedArray` now produces the same primitive, non-boxing `Stepper` that the underlying `Array` would. - Plus some improvements to the unit tests and benchmarks. An interesting observation from the benchmarks: `IntStream.sum` is horribly slow when used on a seqStream built from an `IntStepper`. It is still slow when used on a seqStream built directly from an `Array` with Java’s own stream support. Using a `while` loop on an `IntIterator` produced by the stream beats both hands down and has the same performance independent of the stream source. --- benchmark/README.md | 14 ++--- benchmark/build.sbt | 4 +- .../src/main/scala/bench/Operations.scala | 8 ++- .../src/main/scala/bench/ParseJmhLog.scala | 2 + .../java8/converterImpl/StepConverters.scala | 13 ++++- .../compat/java8/StepConvertersTest.scala | 56 ++++++++++--------- .../compat/java8/StreamConvertersTest.scala | 18 +++++- 7 files changed, 75 insertions(+), 40 deletions(-) diff --git a/benchmark/README.md b/benchmark/README.md index c7d3491..2d6e4e9 100644 --- a/benchmark/README.md +++ b/benchmark/README.md @@ -14,18 +14,14 @@ Because the benchmarking is **very computationally expensive** it should be done 1. Make sure your terminal has plenty of lines of scrollback. (A couple thousand should do.) -2. Run `sbt` +2. Run `sbt "jmh:run -i 5 -wi 3 -f 5"`. Wait overnight. -3. Enter `jmh:run -i 5 -wi 3 -f5`. Wait overnight. +3. Clip off the last set of lines from the terminal window starting before the line that contains `[info] # Run complete. Total time:` and including that line until the end. -4. Clip off the last set of lines from the terminal window starting before the line that contains `[info] # Run complete. Total time:` and including that line until the end. - -5. Save that in the file `results/jmhbench.log` +4. Save that in the file `results/jmhbench.log` ## Comparison step -1. Run `sbt console` - -2. Enter `bench.examine.SpeedReports()` +1. Run `sbt parseJmh` -3. Look at the ASCII art results showing speed comparisons. +2. Look at the ASCII art results showing speed comparisons. diff --git a/benchmark/build.sbt b/benchmark/build.sbt index 5a7420f..8aa4d2b 100644 --- a/benchmark/build.sbt +++ b/benchmark/build.sbt @@ -1,6 +1,7 @@ enablePlugins(JmhPlugin) val generateJmh = TaskKey[Unit]("generateJmh", "Generates JMH benchmark sources.") +val parseJmh = TaskKey[Unit]("parseJmh", "Parses JMH benchmark logs in results/jmhbench.log.") lazy val root = (project in file(".")).settings( name := "java8-compat-bench", @@ -11,5 +12,6 @@ lazy val root = (project in file(".")).settings( unmanagedJars in Compile ++= Seq(baseDirectory.value / "../target/scala-2.11/scala-java8-compat_2.11-0.8.0-SNAPSHOT.jar"), // This would be nicer but sbt-jmh doesn't like it: //unmanagedClasspath in Compile += Attributed.blank(baseDirectory.value / "../target/scala-2.11/classes"), - generateJmh := (runMain in Compile).toTask(" bench.codegen.GenJmhBench").value + generateJmh := (runMain in Compile).toTask(" bench.codegen.GenJmhBench").value, + parseJmh := (runMain in Compile).toTask(" bench.examine.ParseJmhLog").value ) diff --git a/benchmark/src/main/scala/bench/Operations.scala b/benchmark/src/main/scala/bench/Operations.scala index 6208ac4..0b795db 100644 --- a/benchmark/src/main/scala/bench/Operations.scala +++ b/benchmark/src/main/scala/bench/Operations.scala @@ -27,7 +27,13 @@ object OnInt { def sum(t: Traversable[Int]): Int = t.sum def sum(i: Iterator[Int]): Int = i.sum def sum(s: IntStepper): Int = s.fold(0)(_ + _) - def sum(s: IntStream): Int = s.sum + def sum(s: IntStream): Int = { + s.sum + /*var r = 0 + val it = s.iterator() + while(it.hasNext) r += it.nextInt() + r*/ + } def psum(i: ParIterable[Int]): Int = i.sum def psum(s: IntStream): Int = s.sum diff --git a/benchmark/src/main/scala/bench/ParseJmhLog.scala b/benchmark/src/main/scala/bench/ParseJmhLog.scala index df45ee9..32d110a 100644 --- a/benchmark/src/main/scala/bench/ParseJmhLog.scala +++ b/benchmark/src/main/scala/bench/ParseJmhLog.scala @@ -143,4 +143,6 @@ object ParseJmhLog { println("-"*79) println } + + def main(args: Array[String]): Unit = apply() } diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepConverters.scala b/src/main/scala/scala/compat/java8/converterImpl/StepConverters.scala index 1269f94..f27900f 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepConverters.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepConverters.scala @@ -84,6 +84,13 @@ trait Priority2StepConverters extends Priority3StepConverters { implicit def richArrayCharCanStep(underlying: Array[Char]) = new RichArrayCharCanStep(underlying) implicit def richArrayShortCanStep(underlying: Array[Short]) = new RichArrayShortCanStep(underlying) implicit def richArrayFloatCanStep(underlying: Array[Float]) = new RichArrayFloatCanStep(underlying) + + // No special cases for AnyStepper-producing WrappedArrays; they are treated as IndexedSeqs + implicit def richWrappedArrayByteCanStep(underlying: collection.mutable.WrappedArray[Byte]) = new RichArrayByteCanStep(underlying.array) + implicit def richWrappedArrayCharCanStep(underlying: collection.mutable.WrappedArray[Char]) = new RichArrayCharCanStep(underlying.array) + implicit def richWrappedArrayShortCanStep(underlying: collection.mutable.WrappedArray[Short]) = new RichArrayShortCanStep(underlying.array) + implicit def richWrappedArrayFloatCanStep(underlying: collection.mutable.WrappedArray[Float]) = new RichArrayFloatCanStep(underlying.array) + implicit def richDoubleIndexedSeqCanStep[CC <: collection.IndexedSeqLike[Double, _]](underlying: CC) = new RichDoubleIndexedSeqCanStep[CC](underlying) implicit def richIntIndexedSeqCanStep[CC <: collection.IndexedSeqLike[Int, _]](underlying: CC) = @@ -113,7 +120,11 @@ trait Priority1StepConverters extends Priority2StepConverters { implicit def richArrayDoubleCanStep(underlying: Array[Double]) = new RichArrayDoubleCanStep(underlying) implicit def richArrayIntCanStep(underlying: Array[Int]) = new RichArrayIntCanStep(underlying) implicit def richArrayLongCanStep(underlying: Array[Long]) = new RichArrayLongCanStep(underlying) - + + implicit def richWrappedArrayDoubleCanStep(underlying: collection.mutable.WrappedArray[Double]) = new RichArrayDoubleCanStep(underlying.array) + implicit def richWrappedArrayIntCanStep(underlying: collection.mutable.WrappedArray[Int]) = new RichArrayIntCanStep(underlying.array) + implicit def richWrappedArrayLongCanStep(underlying: collection.mutable.WrappedArray[Long]) = new RichArrayLongCanStep(underlying.array) + implicit def richIntNumericRangeCanStep(underlying: collection.immutable.NumericRange[Int]) = new RichIntNumericRangeCanStep(underlying) implicit def richLongNumericRangeCanStep(underlying: collection.immutable.NumericRange[Long]) = new RichLongNumericRangeCanStep(underlying) implicit def richRangeCanStep(underlying: Range) = new RichRangeCanStep(underlying) diff --git a/src/test/scala/scala/compat/java8/StepConvertersTest.scala b/src/test/scala/scala/compat/java8/StepConvertersTest.scala index c4597d5..d7efe82 100644 --- a/src/test/scala/scala/compat/java8/StepConvertersTest.scala +++ b/src/test/scala/scala/compat/java8/StepConvertersTest.scala @@ -25,46 +25,54 @@ class StepConvertersTest { case _ => false } - trait SpecCheck { def apply[X](x: X): Boolean } + trait SpecCheck { + def check[X](x: X): Boolean + def msg[X](x: X): String + def assert(x: Any): Unit = + if(!check(x)) assertTrue(msg(x), false) + } object SpecCheck { - def apply(f: Any => Boolean) = new SpecCheck { def apply[X](x: X): Boolean = f(x) } + def apply(f: Any => Boolean, err: Any => String = (_ => "SpecCheck failed")) = new SpecCheck { + def check[X](x: X): Boolean = f(x) + def msg[X](x: X): String = err(x) + } } def _eh_[X](x: => X)(implicit correctSpec: SpecCheck) { - assert(x.isInstanceOf[Stepper[_]]) - assert(correctSpec(x)) + assertTrue(x.isInstanceOf[Stepper[_]]) + correctSpec.assert(x) } def IFFY[X](x: => X)(implicit correctSpec: SpecCheck) { - assert(x.isInstanceOf[Stepper[_]]) - assert(correctSpec(x)) - assert(isAcc(x)) + assertTrue(x.isInstanceOf[Stepper[_]]) + correctSpec.assert(x) + assertTrue(isAcc(x)) } def Okay[X](x: => X)(implicit correctSpec: SpecCheck) { - assert(x.isInstanceOf[Stepper[_]]) - assert(correctSpec(x)) - assert(!isAcc(x)) - assert(isLin(x)) + assertTrue(x.isInstanceOf[Stepper[_]]) + correctSpec.assert(x) + assertTrue(!isAcc(x)) + assertTrue(isLin(x)) } def Fine[X](x: => X)(implicit correctSpec: SpecCheck) { - assert(x.isInstanceOf[Stepper[_]]) - assert(correctSpec(x)) - assert(!isAcc(x)) + assertTrue(x.isInstanceOf[Stepper[_]]) + correctSpec.assert(x) + assertTrue(!isAcc(x)) } def good[X](x: => X)(implicit correctSpec: SpecCheck) { - assert(x.isInstanceOf[Stepper[_]]) - assert(correctSpec(x)) - assert(!isAcc(x)) - assert(!isLin(x)) + assertTrue(x.isInstanceOf[Stepper[_]]) + correctSpec.assert(x) + assertTrue(!isAcc(x)) + assertTrue(!isLin(x)) } def Tell[X](x: => X)(implicit correctSpec: SpecCheck) { println(x.getClass.getName + " -> " + isAcc(x)) - assert(x.isInstanceOf[Stepper[_]]) - assert(correctSpec(x)) + assertTrue(x.isInstanceOf[Stepper[_]]) + correctSpec.assert(x) } @Test @@ -439,19 +447,17 @@ class StepConvertersTest { @Test def shortWidening() { - implicit val spec = SpecCheck(_.isInstanceOf[IntStepper]) + 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 ) - //TODO: None of these currently work because there are no native Stepper implementations. This does not only - // affect widening conversions though. While you can get, for example, an IntStepper for a WrappedArray[Int], - // all values have to go through a boxing/unboxing step! + //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.ArrayOps[Short]).stepper ) //good( cm.ResizableArray[Short](654321.toShort).stepper ) - //good( (Array[Short](654321.toShort): cm.WrappedArray[Short]).stepper ) } @Test diff --git a/src/test/scala/scala/compat/java8/StreamConvertersTest.scala b/src/test/scala/scala/compat/java8/StreamConvertersTest.scala index 7ce1340..44ca113 100644 --- a/src/test/scala/scala/compat/java8/StreamConvertersTest.scala +++ b/src/test/scala/scala/compat/java8/StreamConvertersTest.scala @@ -3,10 +3,13 @@ package scala.compat.java8 import org.junit.Test import org.junit.Assert._ +import java.util.stream._ +import StreamConverters._ +import scala.compat.java8.collectionImpl.IntStepper +import scala.compat.java8.converterImpl.{MakesStepper, MakesSequentialStream} + class StreamConvertersTest { - import java.util.stream._ - import StreamConverters._ - + def assertEq[A](a1: A, a2: A, s: String) { assertEquals(s, a1, a2) } // Weird order normally! def assertEq[A](a1: A, a2: A) { assertEq(a1, a2, "not equal") } @@ -247,4 +250,13 @@ class StreamConvertersTest { 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.WrappedArray.make[Int](Array(1,2,3)) + val streamize = implicitly[collection.mutable.WrappedArray[Int] => MakesSequentialStream[java.lang.Integer, IntStream]] + assertTrue(streamize(coll).getClass.getName.contains("EnrichScalaCollectionWithSeqIntStream")) + val steppize = implicitly[collection.mutable.WrappedArray[Int] => MakesStepper[IntStepper]] + assertTrue(steppize(coll).getClass.getName.contains("RichArrayIntCanStep")) + } } From c0221902ec7d321f6dbb66ee197f057fc974287c Mon Sep 17 00:00:00 2001 From: Stefan Zeiger Date: Thu, 14 Apr 2016 14:34:16 +0200 Subject: [PATCH 2/4] Special-case primitive `WrappedArray` types when creating Streams This was already done for `Array` in the same way. Streams produced by `Arrays.stream` can be faster than going through a `Stepper`. --- .../scala/compat/java8/StreamConverters.scala | 18 ++++++++++++++++++ .../compat/java8/StreamConvertersTest.scala | 2 +- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/main/scala/scala/compat/java8/StreamConverters.scala b/src/main/scala/scala/compat/java8/StreamConverters.scala index badb07b..394fc4c 100644 --- a/src/main/scala/scala/compat/java8/StreamConverters.scala +++ b/src/main/scala/scala/compat/java8/StreamConverters.scala @@ -292,6 +292,24 @@ with converterImpl.Priority1AccumulatorConverters def parStream: LongStream = seqStream.parallel } + implicit final class EnrichDoubleWrappedArrayWithStream(private val a: collection.mutable.WrappedArray[Double]) + extends AnyVal with MakesSequentialStream[java.lang.Double, DoubleStream] with MakesParallelStream[java.lang.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]) + extends AnyVal with MakesSequentialStream[java.lang.Integer, IntStream] with MakesParallelStream[java.lang.Integer, 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]) + extends AnyVal with MakesSequentialStream[java.lang.Long, LongStream] with MakesParallelStream[java.lang.Long, LongStream] { + def seqStream: LongStream = java.util.Arrays.stream(a.array) + 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) diff --git a/src/test/scala/scala/compat/java8/StreamConvertersTest.scala b/src/test/scala/scala/compat/java8/StreamConvertersTest.scala index 44ca113..66997bf 100644 --- a/src/test/scala/scala/compat/java8/StreamConvertersTest.scala +++ b/src/test/scala/scala/compat/java8/StreamConvertersTest.scala @@ -255,7 +255,7 @@ class StreamConvertersTest { def streamMaterialization(): Unit = { val coll = collection.mutable.WrappedArray.make[Int](Array(1,2,3)) val streamize = implicitly[collection.mutable.WrappedArray[Int] => MakesSequentialStream[java.lang.Integer, IntStream]] - assertTrue(streamize(coll).getClass.getName.contains("EnrichScalaCollectionWithSeqIntStream")) + assertTrue(streamize(coll).getClass.getName.contains("EnrichIntWrappedArrayWithStream")) val steppize = implicitly[collection.mutable.WrappedArray[Int] => MakesStepper[IntStepper]] assertTrue(steppize(coll).getClass.getName.contains("RichArrayIntCanStep")) } From 56e66b952b10965a0fcd87e4ac4e9372d682c65d Mon Sep 17 00:00:00 2001 From: Stefan Zeiger Date: Mon, 18 Apr 2016 18:26:43 +0200 Subject: [PATCH 3/4] A new approach to Stepper and Stream materialization Getting the most efficient Stepper implementation requires knowledge of the static type of a collection. This problem could be solved in the most elegant way by integrating Steppers into the collections framework as a replacement for Iterators (i.e. every collection gets a `stepper` method and `iterator` delegates to `stepper` by default). But this is at odds with the handling of specialized primitive Steppers in the current implementation. If we want `stepper` to be an instance methods instead of an extension method, there needs to be a single such method for all specialized Steppers. The fundamental change in this new implementation is to encode the translation from element type to Stepper type (including widening conversions) as a functional dependency via the new `StepperShape` trait. This greatly reduces the number of implicit methods and classes and keeps all specialized versions of `MakesStepper` together. The default base classes support all unboxing and widening conversions so that a simple `MakesStepper` for a collection of boxed elements only needs to handle the `AnyStepper` case. `keyStepper` and `valueStepper` are handled in the same way. `StreamConverters` use a separate `StreamShape` for the translation from element type to `BaseStream` subtype which is compatible with `StepConverters` and supports the same primitive types and widening conversions. --- .../main/scala/bench/CollectionSource.scala | 57 ++--- .../compat/java8/ScalaStreamSupport.java | 4 +- .../scala/compat/java8/StreamConverters.scala | 231 +++++------------- .../compat/java8/collectionImpl/Stepper.scala | 49 +++- .../java8/converterImpl/MakesSteppers.scala | 120 +++++++-- .../java8/converterImpl/StepConverters.scala | 126 +--------- .../java8/converterImpl/StepsArray.scala | 69 ++---- .../java8/converterImpl/StepsBitSet.scala | 7 +- .../converterImpl/StepsFlatHashTable.scala | 33 +-- .../java8/converterImpl/StepsHashTable.scala | 170 +++++-------- .../java8/converterImpl/StepsImmHashMap.scala | 49 ++-- .../java8/converterImpl/StepsImmHashSet.scala | 22 +- .../java8/converterImpl/StepsIndexedSeq.scala | 22 +- .../java8/converterImpl/StepsIterable.scala | 22 +- .../java8/converterImpl/StepsIterator.scala | 23 +- .../java8/converterImpl/StepsLinearSeq.scala | 62 +++-- .../compat/java8/converterImpl/StepsMap.scala | 42 ++-- .../java8/converterImpl/StepsRange.scala | 22 +- .../java8/converterImpl/StepsString.scala | 6 +- .../java8/converterImpl/StepsVector.scala | 22 +- .../compat/java8/StepConvertersTest.scala | 4 +- .../compat/java8/StreamConvertersTest.scala | 43 ++-- 22 files changed, 479 insertions(+), 726 deletions(-) diff --git a/benchmark/src/main/scala/bench/CollectionSource.scala b/benchmark/src/main/scala/bench/CollectionSource.scala index 5f40a33..2713543 100644 --- a/benchmark/src/main/scala/bench/CollectionSource.scala +++ b/benchmark/src/main/scala/bench/CollectionSource.scala @@ -6,6 +6,7 @@ import scala.collection.generic.CanBuildFrom import scala.compat.java8.StreamConverters._ import scala.compat.java8.collectionImpl._ import scala.compat.java8.converterImpl._ +import scala.compat.java8.{MakesSequentialStream, MakesParallelStream} package object generate { private def myInty(n: Int) = 0 until n @@ -25,42 +26,42 @@ package object generate { } object Pstep { - def i[CC](cc: CC)(implicit steppize: CC => MakesStepper[IntStepper with EfficientSubstep]): IntStepper = + def i[CC](cc: CC)(implicit steppize: CC => MakesStepper[Int, EfficientSubstep]): IntStepper = steppize(cc).stepper - def s[CC](cc: CC)(implicit steppize: CC => MakesStepper[AnyStepper[String] with EfficientSubstep]): AnyStepper[String] = + def s[CC](cc: CC)(implicit steppize: CC => MakesStepper[String, EfficientSubstep]): AnyStepper[String] = steppize(cc).stepper } object Sstep { - def i[CC](cc: CC)(implicit steppize: CC => MakesStepper[IntStepper]): IntStepper = + def i[CC](cc: CC)(implicit steppize: CC => MakesStepper[Int, Any]): IntStepper = steppize(cc).stepper - def s[CC](cc: CC)(implicit steppize: CC => MakesStepper[AnyStepper[String]]): AnyStepper[String] = + def s[CC](cc: CC)(implicit steppize: CC => MakesStepper[String, Any]): AnyStepper[String] = steppize(cc).stepper } object PsStream { - def i[CC](cc: CC)(implicit steppize: CC => MakesStepper[IntStepper with EfficientSubstep]): IntStream = + def i[CC](cc: CC)(implicit steppize: CC => MakesStepper[Int, EfficientSubstep]): IntStream = steppize(cc).stepper.parStream - def s[CC](cc: CC)(implicit steppize: CC => MakesStepper[AnyStepper[String] with EfficientSubstep]): Stream[String] = + def s[CC](cc: CC)(implicit steppize: CC => MakesStepper[String, EfficientSubstep]): Stream[String] = steppize(cc).stepper.parStream } object SsStream { - def i[CC](cc: CC)(implicit steppize: CC => MakesStepper[IntStepper]): IntStream = + def i[CC](cc: CC)(implicit steppize: CC => MakesStepper[Int, Any]): IntStream = steppize(cc).stepper.seqStream - def s[CC](cc: CC)(implicit steppize: CC => MakesStepper[AnyStepper[String]]): Stream[String] = + def s[CC](cc: CC)(implicit steppize: CC => MakesStepper[String, Any]): Stream[String] = steppize(cc).stepper.seqStream } object Sstream { - def i[CC](cc: CC)(implicit streamize: CC => MakesSequentialStream[java.lang.Integer, IntStream]) = + def i[CC](cc: CC)(implicit streamize: CC => MakesSequentialStream[Int, IntStream]) = streamize(cc).seqStream def s[CC](cc: CC)(implicit streamize: CC => MakesSequentialStream[String, Stream[String]]) = streamize(cc).seqStream } object Pstream { - def i[CC](cc: CC)(implicit streamize: CC => MakesParallelStream[java.lang.Integer, IntStream]) = + def i[CC](cc: CC)(implicit streamize: CC => MakesParallelStream[Int, IntStream]) = streamize(cc).parStream def s[CC](cc: CC)(implicit streamize: CC => MakesParallelStream[String, Stream[String]]) = streamize(cc).parStream @@ -78,14 +79,14 @@ package object generate { // Iterator def iI(j: Int)(implicit x: CC[Int] => Iterator[Int]) = x(cI(j)) // Steppers (second letter--s = sequential, p = parallel) - def tsI(j: Int)(implicit x: CC[Int] => MakesStepper[IntStepper]) = Sstep i cI(j) - def tpI(j: Int)(implicit x: CC[Int] => MakesStepper[IntStepper with EfficientSubstep]) = Pstep i cI(j) + def tsI(j: Int)(implicit x: CC[Int] => MakesStepper[Int, Any]) = Sstep i cI(j) + def tpI(j: Int)(implicit x: CC[Int] => MakesStepper[Int, EfficientSubstep]) = Pstep i cI(j) // Streams - def ssI(j: Int)(implicit x: CC[Int] => MakesSequentialStream[java.lang.Integer, IntStream]) = Sstream i cI(j) - def spI(j: Int)(implicit x: CC[Int] => MakesParallelStream[java.lang.Integer, IntStream]) = Pstream i cI(j) + def ssI(j: Int)(implicit x: CC[Int] => MakesSequentialStream[Int, IntStream]) = Sstream i cI(j) + def spI(j: Int)(implicit x: CC[Int] => MakesParallelStream[Int, IntStream]) = Pstream i cI(j) // Streams via steppers - def zsI(j: Int)(implicit x: CC[Int] => MakesStepper[IntStepper]) = SsStream i cI(j) - def zpI(j: Int)(implicit x: CC[Int] => MakesStepper[IntStepper with EfficientSubstep]) = PsStream i cI(j) + def zsI(j: Int)(implicit x: CC[Int] => MakesStepper[Int, Any]) = SsStream i cI(j) + def zpI(j: Int)(implicit x: CC[Int] => MakesStepper[Int, EfficientSubstep]) = PsStream i cI(j) } trait StringThingsOf[CC[_]] extends GenThingsOf[CC] { @@ -95,14 +96,14 @@ package object generate { // Iterator def iS(j: Int)(implicit x: CC[String] => Iterator[String]) = x(cS(j)) // Steppers (second letter--s = sequential, p = parallel) - def tsS(j: Int)(implicit x: CC[String] => MakesStepper[AnyStepper[String]]) = Sstep s cS(j) - def tpS(j: Int)(implicit x: CC[String] => MakesStepper[AnyStepper[String] with EfficientSubstep]) = Pstep s cS(j) + def tsS(j: Int)(implicit x: CC[String] => MakesStepper[String, Any]) = Sstep s cS(j) + def tpS(j: Int)(implicit x: CC[String] => MakesStepper[String, EfficientSubstep]) = Pstep s cS(j) // Streams def ssS(j: Int)(implicit x: CC[String] => MakesSequentialStream[String, Stream[String]]) = Sstream s cS(j) def spS(j: Int)(implicit x: CC[String] => MakesParallelStream[String, Stream[String]]) = Pstream s cS(j) // Streams via steppers - def zsS(j: Int)(implicit x: CC[String] => MakesStepper[AnyStepper[String]]) = SsStream s cS(j) - def zpS(j: Int)(implicit x: CC[String] => MakesStepper[AnyStepper[String] with EfficientSubstep]) = PsStream s cS(j) + def zsS(j: Int)(implicit x: CC[String] => MakesStepper[String, Any]) = SsStream s cS(j) + def zpS(j: Int)(implicit x: CC[String] => MakesStepper[String, EfficientSubstep]) = PsStream s cS(j) } trait ThingsOf[CC[_]] extends IntThingsOf[CC] with StringThingsOf[CC] {} @@ -158,16 +159,16 @@ package object generate { // Streams from ArrayList (Java) - implicit val getsParStreamFromArrayListInt: (java.util.ArrayList[Int] => MakesParallelStream[java.lang.Integer, IntStream]) = ali => { - new MakesParallelStream[java.lang.Integer, IntStream] { + implicit val getsParStreamFromArrayListInt: (java.util.ArrayList[Int] => MakesParallelStream[Int, IntStream]) = ali => { + new MakesParallelStream[Int, IntStream] { def parStream: IntStream = ali. asInstanceOf[java.util.ArrayList[java.lang.Integer]]. parallelStream.parallel. mapToInt(new java.util.function.ToIntFunction[java.lang.Integer]{ def applyAsInt(i: java.lang.Integer) = i.intValue }) } } - implicit val getsSeqStreamFromArrayListInt: (java.util.ArrayList[Int] => MakesSequentialStream[java.lang.Integer, IntStream]) = ali => { - new MakesSequentialStream[java.lang.Integer, IntStream] { + implicit val getsSeqStreamFromArrayListInt: (java.util.ArrayList[Int] => MakesSequentialStream[Int, IntStream]) = ali => { + new MakesSequentialStream[Int, IntStream] { def seqStream: IntStream = ali. asInstanceOf[java.util.ArrayList[java.lang.Integer]]. stream(). @@ -187,16 +188,16 @@ package object generate { // Streams from LinkedList (Java) - implicit val getsParStreamFromLinkedListInt: (java.util.LinkedList[Int] => MakesParallelStream[java.lang.Integer, IntStream]) = ali => { - new MakesParallelStream[java.lang.Integer, IntStream] { + implicit val getsParStreamFromLinkedListInt: (java.util.LinkedList[Int] => MakesParallelStream[Int, IntStream]) = ali => { + new MakesParallelStream[Int, IntStream] { def parStream: IntStream = ali. asInstanceOf[java.util.LinkedList[java.lang.Integer]]. parallelStream.parallel. mapToInt(new java.util.function.ToIntFunction[java.lang.Integer]{ def applyAsInt(i: java.lang.Integer) = i.intValue }) } } - implicit val getsSeqStreamFromLinkedListInt: (java.util.LinkedList[Int] => MakesSequentialStream[java.lang.Integer, IntStream]) = ali => { - new MakesSequentialStream[java.lang.Integer, IntStream] { + implicit val getsSeqStreamFromLinkedListInt: (java.util.LinkedList[Int] => MakesSequentialStream[Int, IntStream]) = ali => { + new MakesSequentialStream[Int, IntStream] { def seqStream: IntStream = ali. asInstanceOf[java.util.LinkedList[java.lang.Integer]]. stream(). diff --git a/src/main/java/scala/compat/java8/ScalaStreamSupport.java b/src/main/java/scala/compat/java8/ScalaStreamSupport.java index 21af821..5afbde7 100644 --- a/src/main/java/scala/compat/java8/ScalaStreamSupport.java +++ b/src/main/java/scala/compat/java8/ScalaStreamSupport.java @@ -482,9 +482,9 @@ public static DoubleStream doubleStreamAccumulatedValues(scala.collection.Map MakesStepper[AnyStepper[A] with EfficientSubstep]) - extends MakesParallelStream[A, Stream[A]] { - def parStream: Stream[A] = StreamSupport.stream(steppize(cc).stepper.anticipateParallelism, true) - } - implicit class EnrichAnyKeySteppableWithParKeyStream[K, CC](cc: CC)(implicit steppize: CC => MakesKeyStepper[AnyStepper[K] with EfficientSubstep]) { - def parKeyStream: Stream[K] = StreamSupport.stream(steppize(cc).keyStepper.anticipateParallelism, true) - } - implicit class EnrichAnyValueSteppableWithParValueStream[V, CC](cc: CC)(implicit steppize: CC => MakesValueStepper[AnyStepper[V] with EfficientSubstep]) { - def parValueStream: Stream[V] = StreamSupport.stream(steppize(cc).valueStepper.anticipateParallelism, true) - } - implicit class EnrichScalaCollectionWithSeqStream[A, CC](cc: CC)(implicit steppize: CC => MakesStepper[AnyStepper[A]]) - extends MakesSequentialStream[A, Stream[A]] { - def seqStream: Stream[A] = StreamSupport.stream(steppize(cc).stepper, false) - } - implicit class EnrichScalaCollectionWithKeySeqStream[K, CC](cc: CC)(implicit steppize: CC => MakesKeyStepper[AnyStepper[K]]) { - def seqKeyStream: Stream[K] = StreamSupport.stream(steppize(cc).keyStepper, false) - } - implicit class EnrichScalaCollectionWithValueSeqStream[V, CC](cc: CC)(implicit steppize: CC => MakesValueStepper[AnyStepper[V]]) { - def seqValueStream: Stream[V] = StreamSupport.stream(steppize(cc).valueStepper, 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 StreamShapeLowPrio { + // primitive + implicit val IntValue = intStreamShape[Int] + implicit val LongValue = longStreamShape[Long] + implicit val DoubleValue = doubleStreamShape[Double] -trait Priority3StreamConverters extends Priority4StreamConverters { - // Prefer to unbox and widen small primitive types over keeping them boxed - implicit class EnrichBoxedFloatSteppableWithParStream[CC](cc: CC)(implicit steppize: CC => MakesStepper[AnyStepper[Float] with EfficientSubstep]) - extends MakesParallelStream[java.lang.Double, DoubleStream] { - def parStream: DoubleStream = StreamSupport.doubleStream(new Stepper.WideningFloatStepper(steppize(cc).stepper.anticipateParallelism), true) - } - implicit class EnrichBoxedFloatKeySteppableWithParKeyStream[CC](cc: CC)(implicit steppize: CC => MakesKeyStepper[AnyStepper[Float] with EfficientSubstep]) { - def parKeyStream: DoubleStream = StreamSupport.doubleStream(new Stepper.WideningFloatStepper(steppize(cc).keyStepper.anticipateParallelism), true) - } - implicit class EnrichBoxedFloatValueSteppableWithParValueStream[CC](cc: CC)(implicit steppize: CC => MakesValueStepper[AnyStepper[Float] with EfficientSubstep]) { - def parValueStream: DoubleStream = StreamSupport.doubleStream(new Stepper.WideningFloatStepper(steppize(cc).valueStepper.anticipateParallelism), true) - } - implicit class EnrichBoxedByteSteppableWithParStream[CC](cc: CC)(implicit steppize: CC => MakesStepper[AnyStepper[Byte] with EfficientSubstep]) - extends MakesParallelStream[java.lang.Integer, IntStream] { - def parStream: IntStream = StreamSupport.intStream(new Stepper.WideningByteStepper(steppize(cc).stepper.anticipateParallelism), true) - } - implicit class EnrichBoxedByteKeySteppableWithParKeyStream[CC](cc: CC)(implicit steppize: CC => MakesKeyStepper[AnyStepper[Byte] with EfficientSubstep]) { - def parKeyStream: IntStream = StreamSupport.intStream(new Stepper.WideningByteStepper(steppize(cc).keyStepper.anticipateParallelism), true) - } - implicit class EnrichBoxedByteValueSteppableWithParValueStream[CC](cc: CC)(implicit steppize: CC => MakesValueStepper[AnyStepper[Byte] with EfficientSubstep]) { - def parValueStream: IntStream = StreamSupport.intStream(new Stepper.WideningByteStepper(steppize(cc).valueStepper.anticipateParallelism), true) - } - implicit class EnrichBoxedShortSteppableWithParStream[CC](cc: CC)(implicit steppize: CC => MakesStepper[AnyStepper[Short] with EfficientSubstep]) - extends MakesParallelStream[java.lang.Integer, IntStream] { - def parStream: IntStream = StreamSupport.intStream(new Stepper.WideningShortStepper(steppize(cc).stepper.anticipateParallelism), true) - } - implicit class EnrichBoxedShortKeySteppableWithParKeyStream[CC](cc: CC)(implicit steppize: CC => MakesKeyStepper[AnyStepper[Short] with EfficientSubstep]) { - def parKeyStream: IntStream = StreamSupport.intStream(new Stepper.WideningShortStepper(steppize(cc).keyStepper.anticipateParallelism), true) - } - implicit class EnrichBoxedShortValueSteppableWithParValueStream[CC](cc: CC)(implicit steppize: CC => MakesValueStepper[AnyStepper[Short] with EfficientSubstep]) { - def parValueStream: IntStream = StreamSupport.intStream(new Stepper.WideningShortStepper(steppize(cc).valueStepper.anticipateParallelism), true) - } - implicit class EnrichBoxedCharSteppableWithParStream[CC](cc: CC)(implicit steppize: CC => MakesStepper[AnyStepper[Char] with EfficientSubstep]) - extends MakesParallelStream[java.lang.Integer, IntStream] { - def parStream: IntStream = StreamSupport.intStream(new Stepper.WideningCharStepper(steppize(cc).stepper.anticipateParallelism), true) - } - implicit class EnrichBoxedCharKeySteppableWithParKeyStream[CC](cc: CC)(implicit steppize: CC => MakesKeyStepper[AnyStepper[Char] with EfficientSubstep]) { - def parKeyStream: IntStream = StreamSupport.intStream(new Stepper.WideningCharStepper(steppize(cc).keyStepper.anticipateParallelism), true) - } - implicit class EnrichBoxedCharValueSteppableWithParValueStream[CC](cc: CC)(implicit steppize: CC => MakesValueStepper[AnyStepper[Char] with EfficientSubstep]) { - def parValueStream: IntStream = StreamSupport.intStream(new Stepper.WideningCharStepper(steppize(cc).valueStepper.anticipateParallelism), true) - } - implicit class EnrichBoxedFloatSteppableWithSeqStream[CC](cc: CC)(implicit steppize: CC => MakesStepper[AnyStepper[Float]]) - extends MakesSequentialStream[java.lang.Double, DoubleStream] { - def seqStream: DoubleStream = StreamSupport.doubleStream(new Stepper.WideningFloatStepper(steppize(cc).stepper), false) - } - implicit class EnrichBoxedFloatKeySteppableWithSeqKeyStream[CC](cc: CC)(implicit steppize: CC => MakesKeyStepper[AnyStepper[Float]]) { - def seqKeyStream: DoubleStream = StreamSupport.doubleStream(new Stepper.WideningFloatStepper(steppize(cc).keyStepper), false) - } - implicit class EnrichBoxedFloatValueSteppableWithSeqValueStream[CC](cc: CC)(implicit steppize: CC => MakesValueStepper[AnyStepper[Float]]) { - def seqValueStream: DoubleStream = StreamSupport.doubleStream(new Stepper.WideningFloatStepper(steppize(cc).valueStepper), false) - } - implicit class EnrichBoxedByteSteppableWithSeqStream[CC](cc: CC)(implicit steppize: CC => MakesStepper[AnyStepper[Byte]]) - extends MakesSequentialStream[java.lang.Integer, IntStream] { - def seqStream: IntStream = StreamSupport.intStream(new Stepper.WideningByteStepper(steppize(cc).stepper), false) - } - implicit class EnrichBoxedByteKeySteppableWithSeqKeyStream[CC](cc: CC)(implicit steppize: CC => MakesKeyStepper[AnyStepper[Byte]]) { - def seqKeyStream: IntStream = StreamSupport.intStream(new Stepper.WideningByteStepper(steppize(cc).keyStepper), false) - } - implicit class EnrichBoxedByteValueSteppableWithSeqValueStream[CC](cc: CC)(implicit steppize: CC => MakesValueStepper[AnyStepper[Byte]]) { - def seqValueStream: IntStream = StreamSupport.intStream(new Stepper.WideningByteStepper(steppize(cc).valueStepper), false) - } - implicit class EnrichBoxedShortSteppableWithSeqStream[CC](cc: CC)(implicit steppize: CC => MakesStepper[AnyStepper[Short]]) - extends MakesSequentialStream[java.lang.Integer, IntStream] { - def seqStream: IntStream = StreamSupport.intStream(new Stepper.WideningShortStepper(steppize(cc).stepper), false) - } - implicit class EnrichBoxedShortKeySteppableWithSeqKeyStream[CC](cc: CC)(implicit steppize: CC => MakesKeyStepper[AnyStepper[Short]]) { - def seqKeyStream: IntStream = StreamSupport.intStream(new Stepper.WideningShortStepper(steppize(cc).keyStepper), false) + // widening + implicit val ByteValue = intStreamShape[Byte] + implicit val ShortValue = intStreamShape[Short] + implicit val CharValue = intStreamShape[Char] + implicit val FloatValue = doubleStreamShape[Float] +} +trait StreamShapeLowPrio { + 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 } - implicit class EnrichBoxedShortValueSteppableWithSeqValueStream[CC](cc: CC)(implicit steppize: CC => MakesValueStepper[AnyStepper[Short]]) { - def seqValueStream: IntStream = StreamSupport.intStream(new Stepper.WideningShortStepper(steppize(cc).valueStepper), false) + 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) } - implicit class EnrichBoxedCharSteppableWithSeqStream[CC](cc: CC)(implicit steppize: CC => MakesStepper[AnyStepper[Char]]) - extends MakesSequentialStream[java.lang.Integer, IntStream] { - def seqStream: IntStream = StreamSupport.intStream(new Stepper.WideningCharStepper(steppize(cc).stepper), false) + 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) } - implicit class EnrichBoxedCharKeySteppableWithSeqKeyStream[CC](cc: CC)(implicit steppize: CC => MakesKeyStepper[AnyStepper[Char]]) { - def seqKeyStream: IntStream = StreamSupport.intStream(new Stepper.WideningCharStepper(steppize(cc).keyStepper), 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 EnrichBoxedCharValueSteppableWithSeqValueStream[CC](cc: CC)(implicit steppize: CC => MakesValueStepper[AnyStepper[Char]]) { - def seqValueStream: IntStream = StreamSupport.intStream(new Stepper.WideningCharStepper(steppize(cc).valueStepper), false) + + // 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) } } -trait Priority2StreamConverters extends Priority3StreamConverters { - implicit class EnrichDoubleSteppableWithParStream[CC](cc: CC)(implicit steppize: CC => MakesStepper[DoubleStepper with EfficientSubstep]) - extends MakesParallelStream[java.lang.Double, DoubleStream] { - def parStream: DoubleStream = StreamSupport.doubleStream(steppize(cc).stepper.anticipateParallelism, true) - } - implicit class EnrichDoubleKeySteppableWithParKeyStream[CC](cc: CC)(implicit steppize: CC => MakesKeyStepper[DoubleStepper with EfficientSubstep]) { - def parKeyStream: DoubleStream = StreamSupport.doubleStream(steppize(cc).keyStepper.anticipateParallelism, true) - } - implicit class EnrichDoubleValueSteppableWithParValueStream[CC](cc: CC)(implicit steppize: CC => MakesValueStepper[DoubleStepper with EfficientSubstep]) { - def parValueStream: DoubleStream = StreamSupport.doubleStream(steppize(cc).valueStepper.anticipateParallelism, true) - } - implicit class EnrichIntSteppableWithParStream[CC](cc: CC)(implicit steppize: CC => MakesStepper[IntStepper with EfficientSubstep]) - extends MakesParallelStream[java.lang.Integer, IntStream] { - def parStream: IntStream = StreamSupport.intStream(steppize(cc).stepper.anticipateParallelism, true) - } - implicit class EnrichIntKeySteppableWithParKeyStream[CC](cc: CC)(implicit steppize: CC => MakesKeyStepper[IntStepper with EfficientSubstep]) { - def parKeyStream: IntStream = StreamSupport.intStream(steppize(cc).keyStepper.anticipateParallelism, true) - } - implicit class EnrichIntValueSteppableWithParValueStream[CC](cc: CC)(implicit steppize: CC => MakesValueStepper[IntStepper with EfficientSubstep]) { - def parValueStream: IntStream = StreamSupport.intStream(steppize(cc).valueStepper.anticipateParallelism, true) - } - implicit class EnrichLongSteppableWithParStream[CC](cc: CC)(implicit steppize: CC => MakesStepper[LongStepper with EfficientSubstep]) - extends MakesParallelStream[java.lang.Long, LongStream] { - def parStream: LongStream = StreamSupport.longStream(steppize(cc).stepper.anticipateParallelism, true) - } - implicit class EnrichLongKeySteppableWithParKeyStream[CC](cc: CC)(implicit steppize: CC => MakesKeyStepper[LongStepper with EfficientSubstep]) { - def parKeyStream: LongStream = StreamSupport.longStream(steppize(cc).keyStepper.anticipateParallelism, true) - } - implicit class EnrichLongValueSteppableWithParValueStream[CC](cc: CC)(implicit steppize: CC => MakesValueStepper[LongStepper with EfficientSubstep]) { - def parValueStream: LongStream = StreamSupport.longStream(steppize(cc).valueStepper.anticipateParallelism, true) - } - implicit class EnrichScalaCollectionWithSeqDoubleStream[CC](cc: CC)(implicit steppize: CC => MakesStepper[DoubleStepper]) - extends MakesSequentialStream[java.lang.Double, DoubleStream] { - def seqStream: DoubleStream = StreamSupport.doubleStream(steppize(cc).stepper, false) - } - implicit class EnrichScalaCollectionWithSeqIntStream[CC](cc: CC)(implicit steppize: CC => MakesStepper[IntStepper]) - extends MakesSequentialStream[java.lang.Integer, IntStream] { - def seqStream: IntStream = StreamSupport.intStream(steppize(cc).stepper, false) - } - implicit class EnrichScalaCollectionWithSeqLongStream[CC](cc: CC)(implicit steppize: CC => MakesStepper[LongStepper]) - extends MakesSequentialStream[java.lang.Long, LongStream] { - def seqStream: LongStream = StreamSupport.longStream(steppize(cc).stepper, false) - } - implicit class EnrichScalaCollectionWithSeqDoubleKeyStream[CC](cc: CC)(implicit steppize: CC => MakesKeyStepper[DoubleStepper]) { - def seqKeyStream: DoubleStream = StreamSupport.doubleStream(steppize(cc).keyStepper, false) +trait PrimitiveStreamAccumulator[S, AA] { + def streamAccumulate(stream: S): AA +} + +trait PrimitiveStreamUnboxer[A, S] { + def apply(boxed: Stream[A]): S +} + +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 EnrichScalaCollectionWithSeqIntKeyStream[CC](cc: CC)(implicit steppize: CC => MakesKeyStepper[IntStepper]) { - def seqKeyStream: IntStream = StreamSupport.intStream(steppize(cc).keyStepper, false) + 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 EnrichScalaCollectionWithSeqLongKeyStream[CC](cc: CC)(implicit steppize: CC => MakesKeyStepper[LongStepper]) { - def seqKeyStream: LongStream = StreamSupport.longStream(steppize(cc).keyStepper, false) + 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 EnrichScalaCollectionWithSeqDoubleValueStream[CC](cc: CC)(implicit steppize: CC => MakesValueStepper[DoubleStepper]) { - def seqValueStream: DoubleStream = StreamSupport.doubleStream(steppize(cc).valueStepper, false) + 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 EnrichScalaCollectionWithSeqIntValueStream[CC](cc: CC)(implicit steppize: CC => MakesValueStepper[IntStepper]) { - def seqValueStream: IntStream = StreamSupport.intStream(steppize(cc).valueStepper, false) + 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 EnrichScalaCollectionWithSeqLongValueStream[CC](cc: CC)(implicit steppize: CC => MakesValueStepper[LongStepper]) { - def seqValueStream: LongStream = StreamSupport.longStream(steppize(cc).valueStepper, false) + 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) } } @@ -275,37 +178,37 @@ with converterImpl.Priority1StepConverters with converterImpl.Priority1AccumulatorConverters { implicit final class EnrichDoubleArrayWithStream(private val a: Array[Double]) - extends AnyVal with MakesSequentialStream[java.lang.Double, DoubleStream] with MakesParallelStream[java.lang.Double, DoubleStream] { + 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[java.lang.Integer, IntStream] with MakesParallelStream[java.lang.Integer, IntStream] { + 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[java.lang.Long, LongStream] with MakesParallelStream[java.lang.Long, LongStream] { + 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 EnrichDoubleWrappedArrayWithStream(private val a: collection.mutable.WrappedArray[Double]) - extends AnyVal with MakesSequentialStream[java.lang.Double, DoubleStream] with MakesParallelStream[java.lang.Double, DoubleStream] { + 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]) - extends AnyVal with MakesSequentialStream[java.lang.Integer, IntStream] with MakesParallelStream[java.lang.Integer, IntStream] { + 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]) - extends AnyVal with MakesSequentialStream[java.lang.Long, LongStream] with MakesParallelStream[java.lang.Long, LongStream] { + 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/collectionImpl/Stepper.scala b/src/main/scala/scala/compat/java8/collectionImpl/Stepper.scala index e315024..1ca95dd 100644 --- a/src/main/scala/scala/compat/java8/collectionImpl/Stepper.scala +++ b/src/main/scala/scala/compat/java8/collectionImpl/Stepper.scala @@ -564,41 +564,64 @@ object Stepper { case _ => new OfLongSpliterator(sp) } - /* These adapter classes can wrap an AnyStepper of a small numeric type into the appropriately 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 already boxed. In other cases the widening conversion - * should always be performed directly on the original unboxed values in a custom Stepper implementation - * (see for example StepsWidenedByteArray). */ + /* 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 WideningByteStepper(st: AnyStepper[Byte]) extends IntStepper { + 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 WideningByteStepper(st.substep()) + def substep(): IntStepper = new UnboxingByteStepper(st.substep()) } - private[java8] class WideningCharStepper(st: AnyStepper[Char]) extends IntStepper { + 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 WideningCharStepper(st.substep()) + def substep(): IntStepper = new UnboxingCharStepper(st.substep()) } - private[java8] class WideningShortStepper(st: AnyStepper[Short]) extends IntStepper { + 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 WideningShortStepper(st.substep()) + def substep(): IntStepper = new UnboxingShortStepper(st.substep()) } - private[java8] class WideningFloatStepper(st: AnyStepper[Float]) extends DoubleStepper { + 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 WideningFloatStepper(st.substep()) + def substep(): DoubleStepper = new UnboxingFloatStepper(st.substep()) } } diff --git a/src/main/scala/scala/compat/java8/converterImpl/MakesSteppers.scala b/src/main/scala/scala/compat/java8/converterImpl/MakesSteppers.scala index 55c31f5..1079d24 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/MakesSteppers.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/MakesSteppers.scala @@ -5,27 +5,117 @@ import language.implicitConversions import scala.compat.java8.collectionImpl._ import scala.compat.java8.runtime._ -/** Classes or objects implementing this trait create streams suitable for sequential use */ -trait MakesSequentialStream[A, SS <: java.util.stream.BaseStream[A, SS]] extends Any { - def seqStream: SS +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 } -/** Classes or objects implementing this trait create streams suitable for parallel use */ -trait MakesParallelStream[A, SS <: java.util.stream.BaseStream[A, SS]] extends Any { - def parStream: SS +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 +} + +sealed trait StepperShape[T, S <: Stepper[_]] { def ref: Boolean } +object StepperShape extends StepperShapeLowPrio { + private[this] def valueShape[T, S <: Stepper[_]]: StepperShape[T, S] = new StepperShape[T, S] { def ref = false } + + // primitive + implicit val IntValue = valueShape[Int, IntStepper] + implicit val LongValue = valueShape[Long, LongStepper] + implicit val DoubleValue = valueShape[Double, DoubleStepper] + + // widening + implicit val ByteValue = valueShape[Byte, IntStepper] + implicit val ShortValue = valueShape[Short, IntStepper] + implicit val CharValue = valueShape[Char, IntStepper] + implicit val FloatValue = valueShape[Float, DoubleStepper] +} +trait StepperShapeLowPrio { + // reference + implicit def anyStepperShape[T]: StepperShape[T, AnyStepper[T]] = new StepperShape[T, AnyStepper[T]] { def ref = true } } -trait MakesStepper[+T <: Stepper[_]] extends Any { - /** Generates a fresh stepper of type `T` */ - def stepper: T +/** Superclass for `MakesStepper` implementations which support parallelization. At least the `AnyStepper` case must be + * implemented, all others default to building an `AnyStepper` and putting an unboxing conversion on top. */ +trait MakesParStepper[T] extends Any with MakesStepper[T, EfficientSubstep] { + def stepper[S <: Stepper[_]](implicit ss: StepperShape[T, S]) = (ss match { + case StepperShape.IntValue => new Stepper.UnboxingIntStepper (stepper(StepperShape.anyStepperShape[T]).asInstanceOf[AnyStepper[Int ]]) with EfficientSubstep + case StepperShape.LongValue => new Stepper.UnboxingLongStepper (stepper(StepperShape.anyStepperShape[T]).asInstanceOf[AnyStepper[Long ]]) with EfficientSubstep + case StepperShape.DoubleValue => new Stepper.UnboxingDoubleStepper(stepper(StepperShape.anyStepperShape[T]).asInstanceOf[AnyStepper[Double]]) with EfficientSubstep + case StepperShape.ByteValue => new Stepper.UnboxingByteStepper (stepper(StepperShape.anyStepperShape[T]).asInstanceOf[AnyStepper[Byte ]]) with EfficientSubstep + case StepperShape.ShortValue => new Stepper.UnboxingShortStepper (stepper(StepperShape.anyStepperShape[T]).asInstanceOf[AnyStepper[Short ]]) with EfficientSubstep + case StepperShape.CharValue => new Stepper.UnboxingCharStepper (stepper(StepperShape.anyStepperShape[T]).asInstanceOf[AnyStepper[Char ]]) with EfficientSubstep + case StepperShape.FloatValue => new Stepper.UnboxingFloatStepper (stepper(StepperShape.anyStepperShape[T]).asInstanceOf[AnyStepper[Float ]]) with EfficientSubstep + case _ => throw new NotImplementedError("AnyStepper must be handled in `stepper` implementations") + }).asInstanceOf[S with EfficientSubstep] } -trait MakesKeyStepper[+T <: Stepper[_]] extends Any { - /** Generates a fresh stepper of type `T` over map keys */ - def keyStepper: T +/** Superclass for `MakesStepper` implementations which do not support parallelization. At least the `AnyStepper` case must be + * implemented, all others default to building an `AnyStepper` and putting an unboxing conversion on top. */ +trait MakesSeqStepper[T] extends Any with MakesStepper[T, Any] { + def stepper[S <: Stepper[_]](implicit ss: StepperShape[T, S]) = (ss match { + case StepperShape.IntValue => new Stepper.UnboxingIntStepper (stepper(StepperShape.anyStepperShape[T]).asInstanceOf[AnyStepper[Int ]]) + case StepperShape.LongValue => new Stepper.UnboxingLongStepper (stepper(StepperShape.anyStepperShape[T]).asInstanceOf[AnyStepper[Long ]]) + case StepperShape.DoubleValue => new Stepper.UnboxingDoubleStepper(stepper(StepperShape.anyStepperShape[T]).asInstanceOf[AnyStepper[Double]]) + case StepperShape.ByteValue => new Stepper.UnboxingByteStepper (stepper(StepperShape.anyStepperShape[T]).asInstanceOf[AnyStepper[Byte ]]) + case StepperShape.ShortValue => new Stepper.UnboxingShortStepper (stepper(StepperShape.anyStepperShape[T]).asInstanceOf[AnyStepper[Short ]]) + case StepperShape.CharValue => new Stepper.UnboxingCharStepper (stepper(StepperShape.anyStepperShape[T]).asInstanceOf[AnyStepper[Char ]]) + case StepperShape.FloatValue => new Stepper.UnboxingFloatStepper (stepper(StepperShape.anyStepperShape[T]).asInstanceOf[AnyStepper[Float ]]) + case _ => throw new NotImplementedError("AnyStepper must be handled in `stepper` implementations") + }).asInstanceOf[S] } -trait MakesValueStepper[+T <: Stepper[_]] extends Any { - /** Generates a fresh stepper of type `T` over map values */ - def valueStepper: T +/** Superclass for `MakesKeyalueStepper` implementations which support parallelization. At least the `AnyStepper` case must be + * implemented, all others default to building an `AnyStepper` and putting an unboxing conversion on top. */ +trait MakesKeyValueParStepper[K, V] extends Any with MakesKeyValueStepper[K, V, EfficientSubstep] { + def keyStepper[S <: Stepper[_]](implicit ss: StepperShape[K, S]) = (ss match { + case StepperShape.IntValue => new Stepper.UnboxingIntStepper (keyStepper(StepperShape.anyStepperShape[K]).asInstanceOf[AnyStepper[Int ]]) with EfficientSubstep + case StepperShape.LongValue => new Stepper.UnboxingLongStepper (keyStepper(StepperShape.anyStepperShape[K]).asInstanceOf[AnyStepper[Long ]]) with EfficientSubstep + case StepperShape.DoubleValue => new Stepper.UnboxingDoubleStepper(keyStepper(StepperShape.anyStepperShape[K]).asInstanceOf[AnyStepper[Double]]) with EfficientSubstep + case StepperShape.ByteValue => new Stepper.UnboxingByteStepper (keyStepper(StepperShape.anyStepperShape[K]).asInstanceOf[AnyStepper[Byte ]]) with EfficientSubstep + case StepperShape.ShortValue => new Stepper.UnboxingShortStepper (keyStepper(StepperShape.anyStepperShape[K]).asInstanceOf[AnyStepper[Short ]]) with EfficientSubstep + case StepperShape.CharValue => new Stepper.UnboxingCharStepper (keyStepper(StepperShape.anyStepperShape[K]).asInstanceOf[AnyStepper[Char ]]) with EfficientSubstep + case StepperShape.FloatValue => new Stepper.UnboxingFloatStepper (keyStepper(StepperShape.anyStepperShape[K]).asInstanceOf[AnyStepper[Float ]]) with EfficientSubstep + case _ => throw new NotImplementedError("AnyStepper case must be handled in `keyStepper` implementations") + }).asInstanceOf[S with EfficientSubstep] + + def valueStepper[S <: Stepper[_]](implicit ss: StepperShape[V, S]) = (ss match { + case StepperShape.IntValue => new Stepper.UnboxingIntStepper (valueStepper(StepperShape.anyStepperShape[V]).asInstanceOf[AnyStepper[Int ]]) with EfficientSubstep + case StepperShape.LongValue => new Stepper.UnboxingLongStepper (valueStepper(StepperShape.anyStepperShape[V]).asInstanceOf[AnyStepper[Long ]]) with EfficientSubstep + case StepperShape.DoubleValue => new Stepper.UnboxingDoubleStepper(valueStepper(StepperShape.anyStepperShape[V]).asInstanceOf[AnyStepper[Double]]) with EfficientSubstep + case StepperShape.ByteValue => new Stepper.UnboxingByteStepper (valueStepper(StepperShape.anyStepperShape[V]).asInstanceOf[AnyStepper[Byte ]]) with EfficientSubstep + case StepperShape.ShortValue => new Stepper.UnboxingShortStepper (valueStepper(StepperShape.anyStepperShape[V]).asInstanceOf[AnyStepper[Short ]]) with EfficientSubstep + case StepperShape.CharValue => new Stepper.UnboxingCharStepper (valueStepper(StepperShape.anyStepperShape[V]).asInstanceOf[AnyStepper[Char ]]) with EfficientSubstep + case StepperShape.FloatValue => new Stepper.UnboxingFloatStepper (valueStepper(StepperShape.anyStepperShape[V]).asInstanceOf[AnyStepper[Float ]]) with EfficientSubstep + case _ => throw new NotImplementedError("AnyStepper case must be handled in `valueStepper` implementations") + }).asInstanceOf[S with EfficientSubstep] +} + +/** Superclass for `MakesKeyalueStepper` implementations which do not support parallelization. At least the `AnyStepper` case must be + * implemented, all others default to building an `AnyStepper` and putting an unboxing conversion on top. */ +trait MakesKeyValueSeqStepper[K, V] extends Any with MakesKeyValueStepper[K, V, Any] { + def keyStepper[S <: Stepper[_]](implicit ss: StepperShape[K, S]) = (ss match { + case StepperShape.IntValue => new Stepper.UnboxingIntStepper (keyStepper(StepperShape.anyStepperShape[K]).asInstanceOf[AnyStepper[Int ]]) + case StepperShape.LongValue => new Stepper.UnboxingLongStepper (keyStepper(StepperShape.anyStepperShape[K]).asInstanceOf[AnyStepper[Long ]]) + case StepperShape.DoubleValue => new Stepper.UnboxingDoubleStepper(keyStepper(StepperShape.anyStepperShape[K]).asInstanceOf[AnyStepper[Double]]) + case StepperShape.ByteValue => new Stepper.UnboxingByteStepper (keyStepper(StepperShape.anyStepperShape[K]).asInstanceOf[AnyStepper[Byte ]]) + case StepperShape.ShortValue => new Stepper.UnboxingShortStepper (keyStepper(StepperShape.anyStepperShape[K]).asInstanceOf[AnyStepper[Short ]]) + case StepperShape.CharValue => new Stepper.UnboxingCharStepper (keyStepper(StepperShape.anyStepperShape[K]).asInstanceOf[AnyStepper[Char ]]) + case StepperShape.FloatValue => new Stepper.UnboxingFloatStepper (keyStepper(StepperShape.anyStepperShape[K]).asInstanceOf[AnyStepper[Float ]]) + case _ => throw new NotImplementedError("AnyStepper case must be handled in `keyStepper` implementations") + }).asInstanceOf[S] + + def valueStepper[S <: Stepper[_]](implicit ss: StepperShape[V, S]) = (ss match { + case StepperShape.IntValue => new Stepper.UnboxingIntStepper (valueStepper(StepperShape.anyStepperShape[V]).asInstanceOf[AnyStepper[Int ]]) + case StepperShape.LongValue => new Stepper.UnboxingLongStepper (valueStepper(StepperShape.anyStepperShape[V]).asInstanceOf[AnyStepper[Long ]]) + case StepperShape.DoubleValue => new Stepper.UnboxingDoubleStepper(valueStepper(StepperShape.anyStepperShape[V]).asInstanceOf[AnyStepper[Double]]) + case StepperShape.ByteValue => new Stepper.UnboxingByteStepper (valueStepper(StepperShape.anyStepperShape[V]).asInstanceOf[AnyStepper[Byte ]]) + case StepperShape.ShortValue => new Stepper.UnboxingShortStepper (valueStepper(StepperShape.anyStepperShape[V]).asInstanceOf[AnyStepper[Short ]]) + case StepperShape.CharValue => new Stepper.UnboxingCharStepper (valueStepper(StepperShape.anyStepperShape[V]).asInstanceOf[AnyStepper[Char ]]) + case StepperShape.FloatValue => new Stepper.UnboxingFloatStepper (valueStepper(StepperShape.anyStepperShape[V]).asInstanceOf[AnyStepper[Float ]]) + case _ => throw new NotImplementedError("AnyStepper case must be handled in `valueStepper` implementations") + }).asInstanceOf[S] } diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepConverters.scala b/src/main/scala/scala/compat/java8/converterImpl/StepConverters.scala index f27900f..566c17c 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepConverters.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepConverters.scala @@ -7,136 +7,28 @@ import scala.compat.java8.runtime._ import Stepper._ -trait Priority7StepConverters { +trait Priority3StepConverters { implicit def richIterableCanStep[A](underlying: Iterable[A]) = new RichIterableCanStep(underlying) -} - -trait Priority6StepConverters extends Priority7StepConverters { - implicit def richDoubleIterableCanStep(underlying: Iterable[Double]) = new RichDoubleIterableCanStep(underlying) - implicit def richIntIterableCanStep(underlying: Iterable[Int]) = new RichIntIterableCanStep(underlying) - implicit def richLongIterableCanStep(underlying: Iterable[Long]) = new RichLongIterableCanStep(underlying) implicit def richMapCanStep[K, V](underlying: collection.Map[K, V]) = new RichMapCanStep[K, V](underlying) } -trait Priority5StepConverters extends Priority6StepConverters { - implicit def richDoubleKeyMapCanStep[V](underlying: collection.Map[Double, V]) = new RichDoubleKeyMapCanStep(underlying) - implicit def richDoubleValueMapCanStep[K](underlying: collection.Map[K, Double]) = new RichDoubleValueMapCanStep(underlying) - implicit def richIntKeyMapCanStep[V](underlying: collection.Map[Int, V]) = new RichIntKeyMapCanStep(underlying) - implicit def richIntValueMapCanStep[K](underlying: collection.Map[K, Int]) = new RichIntValueMapCanStep(underlying) - implicit def richLongKeyMapCanStep[V](underlying: collection.Map[Long, V]) = new RichLongKeyMapCanStep(underlying) - implicit def richLongValueMapCanStep[K](underlying: collection.Map[K, Long]) = new RichLongValueMapCanStep(underlying) -} - -trait Priority4StepConverters extends Priority5StepConverters { - implicit def richLinearSeqCanStep[A, CC[A] >: Null <: collection.LinearSeqLike[A, CC[A]]](underlying: CC[A]) = new RichLinearSeqCanStep[A, CC[A]](underlying) - implicit def richHashTableKeyCanStep[K, HE >: Null <: collection.mutable.HashEntry[K, HE]](underlying: collection.mutable.HashTable[K, HE]) = - new RichHashTableKeyCanStep[K, HE](underlying) - implicit def richDefaultHashTableCanStep[K, V](underlying: collection.mutable.HashTable[K, collection.mutable.DefaultEntry[K, V]]) = - new RichDefaultHashTableCanStep[K, V](underlying) - implicit def richDefaultHashTableValueCanStep[K, V](underlying: collection.mutable.HashTable[K, collection.mutable.DefaultEntry[K, V]]) = - new RichDefaultHashTableValueCanStep[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 richLinkedHashTableValueCanStep[K, V](underlying: collection.mutable.HashTable[K, collection.mutable.LinkedEntry[K, V]]) = - new RichLinkedHashTableValueCanStep[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.IndexedSeqLike[A, _]) = new RichIndexedSeqCanStep[A](underlying) } -trait Priority3StepConverters extends Priority4StepConverters { - implicit def richArrayAnyCanStep[A](underlying: Array[A]) = new RichArrayAnyCanStep[A](underlying) - implicit def richIndexedSeqCanStep[A](underlying: collection.IndexedSeqLike[A, _]) = - 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 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 richDoubleLinearSeqCanStep[CC >: Null <: collection.LinearSeqLike[Double, CC]](underlying: CC) = - new RichDoubleLinearSeqCanStep[CC](underlying) - implicit def richIntLinearSeqCanStep[CC >: Null <: collection.LinearSeqLike[Int, CC]](underlying: CC) = - new RichIntLinearSeqCanStep[CC](underlying) - implicit def richLongLinearSeqCanStep[CC >: Null <: collection.LinearSeqLike[Long, CC]](underlying: CC) = - new RichLongLinearSeqCanStep[CC](underlying) implicit def richIteratorCanStep[A](underlying: Iterator[A]) = new RichIteratorCanStep(underlying) - implicit def richHashTableDoubleKeyCanStep[HE >: Null <: collection.mutable.HashEntry[Double, HE]](underlying: collection.mutable.HashTable[Double, HE]) = - new RichHashTableDoubleKeyCanStep[HE](underlying) - implicit def richHashTableIntKeyCanStep[HE >: Null <: collection.mutable.HashEntry[Int, HE]](underlying: collection.mutable.HashTable[Int, HE]) = - new RichHashTableIntKeyCanStep[HE](underlying) - implicit def richHashTableLongKeyCanStep[HE >: Null <: collection.mutable.HashEntry[Long, HE]](underlying: collection.mutable.HashTable[Long, HE]) = - new RichHashTableLongKeyCanStep[HE](underlying) - implicit def richDefaultHashTableDoubleValueCanStep[K](underlying: collection.mutable.HashTable[K, collection.mutable.DefaultEntry[K, Double]]) = - new RichDefaultHashTableDoubleValueCanStep[K](underlying) - implicit def richDefaultHashTableIntValueCanStep[K](underlying: collection.mutable.HashTable[K, collection.mutable.DefaultEntry[K, Int]]) = - new RichDefaultHashTableIntValueCanStep[K](underlying) - implicit def richDefaultHashTableLongValueCanStep[K](underlying: collection.mutable.HashTable[K, collection.mutable.DefaultEntry[K, Long]]) = - new RichDefaultHashTableLongValueCanStep[K](underlying) - implicit def richLinkedHashTableDoubleValueCanStep[K](underlying: collection.mutable.HashTable[K, collection.mutable.LinkedEntry[K, Double]]) = - new RichLinkedHashTableDoubleValueCanStep[K](underlying) - implicit def richLinkedHashTableIntValueCanStep[K](underlying: collection.mutable.HashTable[K, collection.mutable.LinkedEntry[K, Int]]) = - new RichLinkedHashTableIntValueCanStep[K](underlying) - implicit def richLinkedHashTableLongValueCanStep[K](underlying: collection.mutable.HashTable[K, collection.mutable.LinkedEntry[K, Long]]) = - new RichLinkedHashTableLongValueCanStep[K](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) -} - -trait Priority2StepConverters extends Priority3StepConverters { - implicit def richArrayObjectCanStep[A <: Object](underlying: Array[A]) = new RichArrayObjectCanStep[A](underlying) - implicit def richArrayUnitCanStep(underlying: Array[Unit]) = new RichArrayUnitCanStep(underlying) - implicit def richArrayBooleanCanStep(underlying: Array[Boolean]) = new RichArrayBooleanCanStep(underlying) - implicit def richArrayByteCanStep(underlying: Array[Byte]) = new RichArrayByteCanStep(underlying) - implicit def richArrayCharCanStep(underlying: Array[Char]) = new RichArrayCharCanStep(underlying) - implicit def richArrayShortCanStep(underlying: Array[Short]) = new RichArrayShortCanStep(underlying) - implicit def richArrayFloatCanStep(underlying: Array[Float]) = new RichArrayFloatCanStep(underlying) - - // No special cases for AnyStepper-producing WrappedArrays; they are treated as IndexedSeqs - implicit def richWrappedArrayByteCanStep(underlying: collection.mutable.WrappedArray[Byte]) = new RichArrayByteCanStep(underlying.array) - implicit def richWrappedArrayCharCanStep(underlying: collection.mutable.WrappedArray[Char]) = new RichArrayCharCanStep(underlying.array) - implicit def richWrappedArrayShortCanStep(underlying: collection.mutable.WrappedArray[Short]) = new RichArrayShortCanStep(underlying.array) - implicit def richWrappedArrayFloatCanStep(underlying: collection.mutable.WrappedArray[Float]) = new RichArrayFloatCanStep(underlying.array) - - implicit def richDoubleIndexedSeqCanStep[CC <: collection.IndexedSeqLike[Double, _]](underlying: CC) = - new RichDoubleIndexedSeqCanStep[CC](underlying) - implicit def richIntIndexedSeqCanStep[CC <: collection.IndexedSeqLike[Int, _]](underlying: CC) = - new RichIntIndexedSeqCanStep[CC](underlying) - implicit def richLongIndexedSeqCanStep[CC <: collection.IndexedSeqLike[Long, _]](underlying: CC) = - new RichLongIndexedSeqCanStep[CC](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 richDoubleFlatHashTableCanStep(underlying: collection.mutable.FlatHashTable[Double]) = new RichDoubleFlatHashTableCanStep(underlying) - implicit def richIntFlatHashTableCanStep(underlying: collection.mutable.FlatHashTable[Int]) = new RichIntFlatHashTableCanStep(underlying) - implicit def richLongFlatHashTableCanStep(underlying: collection.mutable.FlatHashTable[Long]) = new RichLongFlatHashTableCanStep(underlying) - implicit def richDoubleIteratorCanStep(underlying: Iterator[Double]) = new RichDoubleIteratorCanStep(underlying) - implicit def richIntIteratorCanStep(underlying: Iterator[Int]) = new RichIntIteratorCanStep(underlying) - implicit def richLongIteratorCanStep(underlying: Iterator[Long]) = new RichLongIteratorCanStep(underlying) - - implicit def richImmHashMapDoubleKeyCanStep[V](underlying: collection.immutable.HashMap[Double, V]) = new RichImmHashMapDoubleKeyCanStep(underlying) - implicit def richImmHashMapDoubleValueCanStep[K](underlying: collection.immutable.HashMap[K, Double]) = new RichImmHashMapDoubleValueCanStep(underlying) - implicit def richImmHashMapIntKeyCanStep[V](underlying: collection.immutable.HashMap[Int, V]) = new RichImmHashMapIntKeyCanStep(underlying) - implicit def richImmHashMapIntValueCanStep[K](underlying: collection.immutable.HashMap[K, Int]) = new RichImmHashMapIntValueCanStep(underlying) - implicit def richImmHashMapLongKeyCanStep[V](underlying: collection.immutable.HashMap[Long, V]) = new RichImmHashMapLongKeyCanStep(underlying) - implicit def richImmHashMapLongValueCanStep[K](underlying: collection.immutable.HashMap[K, Long]) = new RichImmHashMapLongValueCanStep(underlying) - implicit def richBitSetCanStep(underlying: collection.BitSet) = new RichBitSetCanStep(underlying) -} - -trait Priority1StepConverters extends Priority2StepConverters { - implicit def richArrayDoubleCanStep(underlying: Array[Double]) = new RichArrayDoubleCanStep(underlying) - implicit def richArrayIntCanStep(underlying: Array[Int]) = new RichArrayIntCanStep(underlying) - implicit def richArrayLongCanStep(underlying: Array[Long]) = new RichArrayLongCanStep(underlying) - - implicit def richWrappedArrayDoubleCanStep(underlying: collection.mutable.WrappedArray[Double]) = new RichArrayDoubleCanStep(underlying.array) - implicit def richWrappedArrayIntCanStep(underlying: collection.mutable.WrappedArray[Int]) = new RichArrayIntCanStep(underlying.array) - implicit def richWrappedArrayLongCanStep(underlying: collection.mutable.WrappedArray[Long]) = new RichArrayLongCanStep(underlying.array) - - implicit def richIntNumericRangeCanStep(underlying: collection.immutable.NumericRange[Int]) = new RichIntNumericRangeCanStep(underlying) - implicit def richLongNumericRangeCanStep(underlying: collection.immutable.NumericRange[Long]) = new RichLongNumericRangeCanStep(underlying) implicit def richRangeCanStep(underlying: Range) = new RichRangeCanStep(underlying) - - implicit def richDoubleVectorCanStep[A](underlying: Vector[Double]) = new RichDoubleVectorCanStep(underlying) - implicit def richIntVectorCanStep[A](underlying: Vector[Int]) = new RichIntVectorCanStep(underlying) - implicit def richLongVectorCanStep[A](underlying: Vector[Long]) = new RichLongVectorCanStep(underlying) - - implicit def richDoubleHashSetCanStep(underlying: collection.immutable.HashSet[Double]) = new RichDoubleHashSetCanStep(underlying) - implicit def richIntHashSetCanStep(underlying: collection.immutable.HashSet[Int]) = new RichIntHashSetCanStep(underlying) - implicit def richLongHashSetCanStep(underlying: collection.immutable.HashSet[Long]) = new RichLongHashSetCanStep(underlying) - implicit def richStringCanStep(underlying: String) = new RichStringCanStep(underlying) } - diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsArray.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsArray.scala index 8a960d0..0da150e 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsArray.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsArray.scala @@ -17,18 +17,6 @@ extends StepsLikeIndexed[A, StepsObjectArray[A]](_i0, _iN) { def semiclone(half: Int) = new StepsObjectArray[A](underlying, i0, half) } -private[java8] class StepsAnyArray[A](underlying: Array[A], _i0: Int, _iN: Int) -extends StepsLikeIndexed[A, StepsAnyArray[A]](_i0, _iN) { - def next() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE - def semiclone(half: Int) = new StepsAnyArray[A](underlying, i0, half) -} - -private[java8] class StepsUnitArray(underlying: Array[Unit], _i0: Int, _iN: Int) -extends StepsLikeIndexed[Unit, StepsUnitArray](_i0, _iN) { - def next() = if (hasNext()) { val j = i0; i0 += 1; () } else throwNSEE - def semiclone(half: Int) = new StepsUnitArray(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 @@ -81,46 +69,19 @@ extends StepsLongLikeIndexed[StepsLongArray](_i0, _iN) { // Value class adapters // ////////////////////////// -final class RichArrayAnyCanStep[A](private val underlying: Array[A]) extends AnyVal with MakesStepper[AnyStepper[A] with EfficientSubstep] { - @inline def stepper: AnyStepper[A] with EfficientSubstep = new StepsAnyArray[A](underlying, 0, underlying.length) -} - -final class RichArrayObjectCanStep[A <: Object](private val underlying: Array[A]) extends AnyVal with MakesStepper[AnyStepper[A] with EfficientSubstep] { - @inline def stepper: AnyStepper[A] with EfficientSubstep = new StepsObjectArray[A](underlying, 0, underlying.length) -} - -final class RichArrayUnitCanStep(private val underlying: Array[Unit]) extends AnyVal with MakesStepper[AnyStepper[Unit] with EfficientSubstep] { - @inline def stepper: AnyStepper[Unit] with EfficientSubstep = new StepsUnitArray(underlying, 0, underlying.length) -} - -final class RichArrayBooleanCanStep(private val underlying: Array[Boolean]) extends AnyVal with MakesStepper[AnyStepper[Boolean] with EfficientSubstep] { - @inline def stepper: AnyStepper[Boolean] with EfficientSubstep = new StepsBoxedBooleanArray(underlying, 0, underlying.length) -} - -final class RichArrayByteCanStep(private val underlying: Array[Byte]) extends AnyVal with MakesStepper[IntStepper with EfficientSubstep] { - @inline def stepper: IntStepper with EfficientSubstep = new StepsWidenedByteArray(underlying, 0, underlying.length) -} - -final class RichArrayCharCanStep(private val underlying: Array[Char]) extends AnyVal with MakesStepper[IntStepper with EfficientSubstep] { - @inline def stepper: IntStepper with EfficientSubstep = new StepsWidenedCharArray(underlying, 0, underlying.length) -} - -final class RichArrayShortCanStep(private val underlying: Array[Short]) extends AnyVal with MakesStepper[IntStepper with EfficientSubstep] { - @inline def stepper: IntStepper with EfficientSubstep = new StepsWidenedShortArray(underlying, 0, underlying.length) -} - -final class RichArrayFloatCanStep(private val underlying: Array[Float]) extends AnyVal with MakesStepper[DoubleStepper with EfficientSubstep] { - @inline def stepper: DoubleStepper with EfficientSubstep = new StepsWidenedFloatArray(underlying, 0, underlying.length) -} - -final class RichArrayDoubleCanStep(private val underlying: Array[Double]) extends AnyVal with MakesStepper[DoubleStepper with EfficientSubstep] { - @inline def stepper: DoubleStepper with EfficientSubstep = new StepsDoubleArray(underlying, 0, underlying.length) -} - -final class RichArrayIntCanStep(private val underlying: Array[Int]) extends AnyVal with MakesStepper[IntStepper with EfficientSubstep] { - @inline def stepper: IntStepper with EfficientSubstep = new StepsIntArray(underlying, 0, underlying.length) -} - -final class RichArrayLongCanStep(private val underlying: Array[Long]) extends AnyVal with MakesStepper[LongStepper with EfficientSubstep] { - @inline def stepper: LongStepper with EfficientSubstep = new StepsLongArray(underlying, 0, underlying.length) +final class RichArrayCanStep[T](private val underlying: Array[T]) extends AnyVal with MakesParStepper[T] { + override def stepper[S <: Stepper[_]](implicit ss: StepperShape[T, S]) = (ss match { + case ss if ss.ref => + 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) + case ss => super.stepper(ss) + }).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 index 4c9436c..55bae9f 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsBitSet.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsBitSet.scala @@ -53,16 +53,17 @@ extends StepsIntLikeSliced[Array[Long], StepsIntBitSet](_underlying, _i0, _iN) { // Value class adapter // ///////////////////////// -final class RichBitSetCanStep(private val underlying: collection.BitSet) extends AnyVal with MakesStepper[IntStepper with EfficientSubstep] { - def stepper: IntStepper with EfficientSubstep = { +final class RichBitSetCanStep(private val underlying: collection.BitSet) extends AnyVal with MakesParStepper[Int] { + 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) + 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 index fb28870..70dbc76 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsFlatHashTable.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsFlatHashTable.scala @@ -39,30 +39,15 @@ extends StepsLongLikeGapped[StepsLongFlatHashTable](_underlying, _i0, _iN) { // Value class adapters // ////////////////////////// -final class RichFlatHashTableCanStep[A](private val underlying: collection.mutable.FlatHashTable[A]) extends AnyVal with MakesStepper[AnyStepper[A] with EfficientSubstep] { - @inline def stepper: AnyStepper[A] with EfficientSubstep = { +final class RichFlatHashTableCanStep[T](private val underlying: collection.mutable.FlatHashTable[T]) extends AnyVal with MakesParStepper[T] { + override def stepper[S <: Stepper[_]](implicit ss: StepperShape[T, S]) = { val tbl = CollectionInternals.getTable(underlying) - new StepsAnyFlatHashTable(tbl, 0, tbl.length) - } -} - -final class RichDoubleFlatHashTableCanStep(private val underlying: collection.mutable.FlatHashTable[Double]) extends AnyVal with MakesStepper[DoubleStepper with EfficientSubstep] { - @inline def stepper: DoubleStepper with EfficientSubstep = { - val tbl = CollectionInternals.getTable(underlying) - new StepsDoubleFlatHashTable(tbl, 0, tbl.length) - } -} - -final class RichIntFlatHashTableCanStep(private val underlying: collection.mutable.FlatHashTable[Int]) extends AnyVal with MakesStepper[IntStepper with EfficientSubstep] { - @inline def stepper: IntStepper with EfficientSubstep = { - val tbl = CollectionInternals.getTable(underlying) - new StepsIntFlatHashTable(tbl, 0, tbl.length) - } -} - -final class RichLongFlatHashTableCanStep(private val underlying: collection.mutable.FlatHashTable[Long]) extends AnyVal with MakesStepper[LongStepper with EfficientSubstep] { - @inline def stepper: LongStepper with EfficientSubstep = { - val tbl = CollectionInternals.getTable(underlying) - new StepsLongFlatHashTable(tbl, 0, tbl.length) + (ss match { + case ss if ss.ref => new StepsAnyFlatHashTable[T](tbl, 0, tbl.length) + 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 => super.stepper(ss) + }).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 index db68bb7..4a328d1 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsHashTable.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsHashTable.scala @@ -13,28 +13,28 @@ import Stepper._ // Steppers for keys (type of HashEntry doesn't matter) -private[java8] class StepsAnyHashTableKey[K, HE <: collection.mutable.HashEntry[K, HE]](_underlying: Array[collection.mutable.HashEntry[K, HE]], _i0: Int, _iN: Int) -extends StepsLikeGapped[K, StepsAnyHashTableKey[K, HE]](_underlying.asInstanceOf[Array[AnyRef]], _i0, _iN) { - def next() = if (currentEntry eq null) throwNSEE else { val ans = currentEntry.asInstanceOf[HE].key; currentEntry = currentEntry.asInstanceOf[HE].next; ans } - def semiclone(half: Int) = new StepsAnyHashTableKey[K, HE](underlying.asInstanceOf[Array[collection.mutable.HashEntry[K, HE]]], i0, half) +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 StepsDoubleHashTableKey[HE <: collection.mutable.HashEntry[Double, HE]](_underlying: Array[collection.mutable.HashEntry[Double, HE]], _i0: Int, _iN: Int) -extends StepsDoubleLikeGapped[StepsDoubleHashTableKey[HE]](_underlying.asInstanceOf[Array[AnyRef]], _i0, _iN) { - def nextDouble() = if (currentEntry eq null) throwNSEE else { val ans = currentEntry.asInstanceOf[HE].key; currentEntry = currentEntry.asInstanceOf[HE].next; ans } - def semiclone(half: Int) = new StepsDoubleHashTableKey[HE](underlying.asInstanceOf[Array[collection.mutable.HashEntry[Double, HE]]], 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 StepsIntHashTableKey[HE <: collection.mutable.HashEntry[Int, HE]](_underlying: Array[collection.mutable.HashEntry[Int, HE]], _i0: Int, _iN: Int) -extends StepsIntLikeGapped[StepsIntHashTableKey[HE]](_underlying.asInstanceOf[Array[AnyRef]], _i0, _iN) { - def nextInt() = if (currentEntry eq null) throwNSEE else { val ans = currentEntry.asInstanceOf[HE].key; currentEntry = currentEntry.asInstanceOf[HE].next; ans } - def semiclone(half: Int) = new StepsIntHashTableKey[HE](underlying.asInstanceOf[Array[collection.mutable.HashEntry[Int, HE]]], 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 StepsLongHashTableKey[HE <: collection.mutable.HashEntry[Long, HE]](_underlying: Array[collection.mutable.HashEntry[Long, HE]], _i0: Int, _iN: Int) -extends StepsLongLikeGapped[StepsLongHashTableKey[HE]](_underlying.asInstanceOf[Array[AnyRef]], _i0, _iN) { - def nextLong() = if (currentEntry eq null) throwNSEE else { val ans = currentEntry.asInstanceOf[HE].key; currentEntry = currentEntry.asInstanceOf[HE].next; ans } - def semiclone(half: Int) = new StepsLongHashTableKey[HE](underlying.asInstanceOf[Array[collection.mutable.HashEntry[Long, HE]]], 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) } // Steppers for entries stored in DefaultEntry HashEntry @@ -138,122 +138,64 @@ extends StepsLongLikeGapped[StepsLongLinkedHashTableValue[K]](_underlying.asInst // Value class adapters // ////////////////////////// -// Steppers for keys (type of HashEntry doesn't matter) - -final class RichHashTableKeyCanStep[K, HE >: Null <: collection.mutable.HashEntry[K, HE]](private val underlying: collection.mutable.HashTable[K, HE]) -extends AnyVal with MakesKeyStepper[AnyStepper[K] with EfficientSubstep] { - @inline def keyStepper: AnyStepper[K] with EfficientSubstep = { - val tbl = CollectionInternals.getTable[K, HE](underlying) - new StepsAnyHashTableKey(tbl, 0, tbl.length) - } -} - -final class RichHashTableDoubleKeyCanStep[HE >: Null <: collection.mutable.HashEntry[Double, HE]](private val underlying: collection.mutable.HashTable[Double, HE]) -extends AnyVal with MakesKeyStepper[DoubleStepper with EfficientSubstep] { - @inline def keyStepper: DoubleStepper with EfficientSubstep = { - val tbl = CollectionInternals.getTable[Double, HE](underlying) - new StepsDoubleHashTableKey(tbl, 0, tbl.length) - } -} - -final class RichHashTableIntKeyCanStep[HE >: Null <: collection.mutable.HashEntry[Int, HE]](private val underlying: collection.mutable.HashTable[Int, HE]) -extends AnyVal with MakesKeyStepper[IntStepper with EfficientSubstep] { - @inline def keyStepper: IntStepper with EfficientSubstep = { - val tbl = CollectionInternals.getTable[Int, HE](underlying) - new StepsIntHashTableKey(tbl, 0, tbl.length) - } -} - -final class RichHashTableLongKeyCanStep[HE >: Null <: collection.mutable.HashEntry[Long, HE]](private val underlying: collection.mutable.HashTable[Long, HE]) -extends AnyVal with MakesKeyStepper[LongStepper with EfficientSubstep] { - @inline def keyStepper: LongStepper with EfficientSubstep = { - val tbl = CollectionInternals.getTable[Long, HE](underlying) - new StepsLongHashTableKey(tbl, 0, tbl.length) - } -} - // Steppers for entries stored in DefaultEntry HashEntry -// (both for key-value pair and for values alone) -final class RichDefaultHashTableCanStep[K, V](private val underlying: collection.mutable.HashTable[K, collection.mutable.DefaultEntry[K, V]]) -extends AnyVal with MakesStepper[AnyStepper[(K,V)] with EfficientSubstep] { - @inline def stepper: AnyStepper[(K,V)] with EfficientSubstep = { +final class RichDefaultHashTableCanStep[K, V](private val underlying: collection.mutable.HashTable[K, collection.mutable.DefaultEntry[K, V]]) extends AnyVal with MakesKeyValueParStepper[K, V] with MakesParStepper[(K, V)] { + override def stepper[S <: Stepper[_]](implicit ss: StepperShape[(K, V), S]) = { val tbl = CollectionInternals.getTable[K, collection.mutable.DefaultEntry[K, V]](underlying) - new StepsAnyDefaultHashTable(tbl, 0, tbl.length) + new StepsAnyDefaultHashTable(tbl, 0, tbl.length).asInstanceOf[S with EfficientSubstep] } -} -final class RichDefaultHashTableValueCanStep[K, V](private val underlying: collection.mutable.HashTable[K, collection.mutable.DefaultEntry[K, V]]) -extends AnyVal with MakesValueStepper[AnyStepper[V] with EfficientSubstep] { - @inline def valueStepper: AnyStepper[V] with EfficientSubstep = { + override def keyStepper[S <: Stepper[_]](implicit ss: StepperShape[K, S]) = { val tbl = CollectionInternals.getTable[K, collection.mutable.DefaultEntry[K, V]](underlying) - new StepsAnyDefaultHashTableValue(tbl, 0, tbl.length) + (ss match { + case ss if ss.ref => new StepsAnyHashTableKey (tbl.asInstanceOf[Array[collection.mutable.HashEntry[K, _]]], 0, tbl.length) + 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 => super.keyStepper(ss) + }).asInstanceOf[S with EfficientSubstep] } -} -final class RichDefaultHashTableDoubleValueCanStep[K](private val underlying: collection.mutable.HashTable[K, collection.mutable.DefaultEntry[K, Double]]) -extends AnyVal with MakesValueStepper[DoubleStepper with EfficientSubstep] { - @inline def valueStepper: DoubleStepper with EfficientSubstep = { - val tbl = CollectionInternals.getTable[K, collection.mutable.DefaultEntry[K, Double]](underlying) - new StepsDoubleDefaultHashTableValue(tbl, 0, tbl.length) - } -} - -final class RichDefaultHashTableIntValueCanStep[K](private val underlying: collection.mutable.HashTable[K, collection.mutable.DefaultEntry[K, Int]]) -extends AnyVal with MakesValueStepper[IntStepper with EfficientSubstep] { - @inline def valueStepper: IntStepper with EfficientSubstep = { - val tbl = CollectionInternals.getTable[K, collection.mutable.DefaultEntry[K, Int]](underlying) - new StepsIntDefaultHashTableValue(tbl, 0, tbl.length) + override def valueStepper[S <: Stepper[_]](implicit ss: StepperShape[V, S]) = { + val tbl = CollectionInternals.getTable[K, collection.mutable.DefaultEntry[K, V]](underlying) + (ss match { + case ss if ss.ref => new StepsAnyDefaultHashTableValue (tbl, 0, tbl.length) + 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 => super.valueStepper(ss) + }).asInstanceOf[S with EfficientSubstep] } } -final class RichDefaultHashTableLongValueCanStep[K](private val underlying: collection.mutable.HashTable[K, collection.mutable.DefaultEntry[K, Long]]) -extends AnyVal with MakesValueStepper[LongStepper with EfficientSubstep] { - @inline def valueStepper: LongStepper with EfficientSubstep = { - val tbl = CollectionInternals.getTable[K, collection.mutable.DefaultEntry[K, Long]](underlying) - new StepsLongDefaultHashTableValue(tbl, 0, tbl.length) - } -} - // Steppers for entries stored in LinkedEntry HashEntry -// (both for key-value pair and for values alone) -final class RichLinkedHashTableCanStep[K, V](private val underlying: collection.mutable.HashTable[K, collection.mutable.LinkedEntry[K, V]]) -extends AnyVal with MakesStepper[AnyStepper[(K,V)] with EfficientSubstep] { - @inline def stepper: AnyStepper[(K,V)] with EfficientSubstep = { +final class RichLinkedHashTableCanStep[K, V](private val underlying: collection.mutable.HashTable[K, collection.mutable.LinkedEntry[K, V]]) extends AnyVal with MakesKeyValueParStepper[K, V] with MakesParStepper[(K, V)] { + override def stepper[S <: Stepper[_]](implicit ss: StepperShape[(K, V), S]) = { val tbl = CollectionInternals.getTable[K, collection.mutable.LinkedEntry[K, V]](underlying) - new StepsAnyLinkedHashTable(tbl, 0, tbl.length) + new StepsAnyLinkedHashTable(tbl, 0, tbl.length).asInstanceOf[S with EfficientSubstep] } -} -final class RichLinkedHashTableValueCanStep[K, V](private val underlying: collection.mutable.HashTable[K, collection.mutable.LinkedEntry[K, V]]) -extends AnyVal with MakesValueStepper[AnyStepper[V] with EfficientSubstep] { - @inline def valueStepper: AnyStepper[V] with EfficientSubstep = { + override def keyStepper[S <: Stepper[_]](implicit ss: StepperShape[K, S]) = { val tbl = CollectionInternals.getTable[K, collection.mutable.LinkedEntry[K, V]](underlying) - new StepsAnyLinkedHashTableValue(tbl, 0, tbl.length) + (ss match { + case ss if ss.ref => new StepsAnyHashTableKey (tbl.asInstanceOf[Array[collection.mutable.HashEntry[K, _]]], 0, tbl.length) + 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 => super.keyStepper(ss) + }).asInstanceOf[S with EfficientSubstep] } -} - -final class RichLinkedHashTableDoubleValueCanStep[K](private val underlying: collection.mutable.HashTable[K, collection.mutable.LinkedEntry[K, Double]]) -extends AnyVal with MakesValueStepper[DoubleStepper with EfficientSubstep] { - @inline def valueStepper: DoubleStepper with EfficientSubstep = { - val tbl = CollectionInternals.getTable[K, collection.mutable.LinkedEntry[K, Double]](underlying) - new StepsDoubleLinkedHashTableValue(tbl, 0, tbl.length) - } -} -final class RichLinkedHashTableIntValueCanStep[K](private val underlying: collection.mutable.HashTable[K, collection.mutable.LinkedEntry[K, Int]]) -extends AnyVal with MakesValueStepper[IntStepper with EfficientSubstep] { - @inline def valueStepper: IntStepper with EfficientSubstep = { - val tbl = CollectionInternals.getTable[K, collection.mutable.LinkedEntry[K, Int]](underlying) - new StepsIntLinkedHashTableValue(tbl, 0, tbl.length) - } -} - -final class RichLinkedHashTableLongValueCanStep[K](private val underlying: collection.mutable.HashTable[K, collection.mutable.LinkedEntry[K, Long]]) -extends AnyVal with MakesValueStepper[LongStepper with EfficientSubstep] { - @inline def valueStepper: LongStepper with EfficientSubstep = { - val tbl = CollectionInternals.getTable[K, collection.mutable.LinkedEntry[K, Long]](underlying) - new StepsLongLinkedHashTableValue(tbl, 0, tbl.length) + override def valueStepper[S <: Stepper[_]](implicit ss: StepperShape[V, S]) = { + val tbl = CollectionInternals.getTable[K, collection.mutable.LinkedEntry[K, V]](underlying) + (ss match { + case ss if ss.ref => new StepsAnyLinkedHashTableValue (tbl, 0, tbl.length) + 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 => super.valueStepper(ss) + }).asInstanceOf[S with EfficientSubstep] } } diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsImmHashMap.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsImmHashMap.scala index d10b9a8..888c1d4 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsImmHashMap.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsImmHashMap.scala @@ -125,34 +125,23 @@ extends StepsLongLikeImmHashMap[K, Long, StepsLongImmHashMapValue[K]](_underlyin // Value class adapters // ////////////////////////// -final class RichImmHashMapCanStep[K, V](private val underlying: collection.immutable.HashMap[K, V]) -extends AnyVal with MakesStepper[AnyStepper[(K, V)] with EfficientSubstep] with MakesKeyStepper[AnyStepper[K] with EfficientSubstep] with MakesValueStepper[AnyStepper[V] with EfficientSubstep] { - @inline def stepper: AnyStepper[(K, V)] with EfficientSubstep = new StepsAnyImmHashMap[K, V](underlying, 0, underlying.size) - @inline def keyStepper: AnyStepper[K] with EfficientSubstep = new StepsAnyImmHashMapKey[K, V](underlying, 0, underlying.size) - @inline def valueStepper: AnyStepper[V] with EfficientSubstep = new StepsAnyImmHashMapValue[K, V](underlying, 0, underlying.size) +final class RichImmHashMapCanStep[K, V](private val underlying: collection.immutable.HashMap[K, V]) extends AnyVal with MakesKeyValueParStepper[K, V] with MakesParStepper[(K, V)] { + override def stepper[S <: Stepper[_]](implicit ss: StepperShape[(K, V), S]) = + new StepsAnyImmHashMap[K, V](underlying, 0, underlying.size).asInstanceOf[S with EfficientSubstep] + + override def keyStepper[S <: Stepper[_]](implicit ss: StepperShape[K, S]) = (ss match { + case ss if ss.ref => new StepsAnyImmHashMapKey[K, V](underlying, 0, underlying.size) + 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 => super.keyStepper(ss) + }).asInstanceOf[S with EfficientSubstep] + + override def valueStepper[S <: Stepper[_]](implicit ss: StepperShape[V, S]) = (ss match { + case ss if ss.ref => new StepsAnyImmHashMapValue[K, V](underlying, 0, underlying.size) + 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 => super.valueStepper(ss) + }).asInstanceOf[S with EfficientSubstep] } - -final class RichImmHashMapDoubleKeyCanStep[V](private val underlying: collection.immutable.HashMap[Double, V]) extends AnyVal with MakesKeyStepper[DoubleStepper with EfficientSubstep] { - @inline def keyStepper: DoubleStepper with EfficientSubstep = new StepsDoubleImmHashMapKey[V](underlying, 0, underlying.size) -} - -final class RichImmHashMapDoubleValueCanStep[K](private val underlying: collection.immutable.HashMap[K, Double]) extends AnyVal with MakesValueStepper[DoubleStepper with EfficientSubstep] { - @inline def valueStepper: DoubleStepper with EfficientSubstep = new StepsDoubleImmHashMapValue[K](underlying, 0, underlying.size) -} - -final class RichImmHashMapIntKeyCanStep[V](private val underlying: collection.immutable.HashMap[Int, V]) extends AnyVal with MakesKeyStepper[IntStepper with EfficientSubstep] { - @inline def keyStepper: IntStepper with EfficientSubstep = new StepsIntImmHashMapKey[V](underlying, 0, underlying.size) -} - -final class RichImmHashMapIntValueCanStep[K](private val underlying: collection.immutable.HashMap[K, Int]) extends AnyVal with MakesValueStepper[IntStepper with EfficientSubstep] { - @inline def valueStepper: IntStepper with EfficientSubstep = new StepsIntImmHashMapValue[K](underlying, 0, underlying.size) -} - -final class RichImmHashMapLongKeyCanStep[V](private val underlying: collection.immutable.HashMap[Long, V]) extends AnyVal with MakesKeyStepper[LongStepper with EfficientSubstep] { - @inline def keyStepper: LongStepper with EfficientSubstep = new StepsLongImmHashMapKey[V](underlying, 0, underlying.size) -} - -final class RichImmHashMapLongValueCanStep[K](private val underlying: collection.immutable.HashMap[K, Long]) extends AnyVal with MakesValueStepper[LongStepper with EfficientSubstep] { - @inline def valueStepper: LongStepper with EfficientSubstep = new StepsLongImmHashMapValue[K](underlying, 0, underlying.size) -} - diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsImmHashSet.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsImmHashSet.scala index 75e0c7a..56e0560 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsImmHashSet.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsImmHashSet.scala @@ -39,18 +39,12 @@ extends StepsLongLikeTrieIterator[StepsLongImmHashSet](_underlying, _N) { // Value class adapters // ////////////////////////// -final class RichImmHashSetCanStep[A](private val underlying: collection.immutable.HashSet[A]) extends AnyVal with MakesStepper[AnyStepper[A] with EfficientSubstep] { - @inline def stepper: AnyStepper[A] with EfficientSubstep = new StepsAnyImmHashSet(underlying.iterator, underlying.size) -} - -final class RichDoubleHashSetCanStep(private val underlying: collection.immutable.HashSet[Double]) extends AnyVal with MakesStepper[DoubleStepper with EfficientSubstep] { - @inline def stepper: DoubleStepper with EfficientSubstep = new StepsDoubleImmHashSet(underlying.iterator, underlying.size) -} - -final class RichIntHashSetCanStep(private val underlying: collection.immutable.HashSet[Int]) extends AnyVal with MakesStepper[IntStepper with EfficientSubstep] { - @inline def stepper: IntStepper with EfficientSubstep = new StepsIntImmHashSet(underlying.iterator, underlying.size) -} - -final class RichLongHashSetCanStep(private val underlying: collection.immutable.HashSet[Long]) extends AnyVal with MakesStepper[LongStepper with EfficientSubstep] { - @inline def stepper: LongStepper with EfficientSubstep = new StepsLongImmHashSet(underlying.iterator, underlying.size) +final class RichImmHashSetCanStep[T](private val underlying: collection.immutable.HashSet[T]) extends AnyVal with MakesParStepper[T] { + override def stepper[S <: Stepper[_]](implicit ss: StepperShape[T, S]) = (ss match { + case ss if ss.ref => new StepsAnyImmHashSet[T](underlying.iterator, underlying.size) + 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 => super.stepper(ss) + }).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 bf00f35..69d3260 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsIndexedSeq.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsIndexedSeq.scala @@ -39,18 +39,12 @@ extends StepsLongLikeIndexed[StepsLongIndexedSeq[CC]](_i0, _iN) { // Value class adapters // ////////////////////////// -final class RichIndexedSeqCanStep[A](private val underlying: collection.IndexedSeqLike[A, _]) extends AnyVal with MakesStepper[AnyStepper[A] with EfficientSubstep] { - @inline def stepper: AnyStepper[A] with EfficientSubstep = new StepsAnyIndexedSeq[A](underlying, 0, underlying.length) -} - -final class RichDoubleIndexedSeqCanStep[CC <: collection.IndexedSeqLike[Double, _]](private val underlying: CC) extends AnyVal with MakesStepper[DoubleStepper with EfficientSubstep] { - @inline def stepper: DoubleStepper with EfficientSubstep = new StepsDoubleIndexedSeq[CC](underlying, 0, underlying.length) -} - -final class RichIntIndexedSeqCanStep[CC <: collection.IndexedSeqLike[Int, _]](private val underlying: CC) extends AnyVal with MakesStepper[IntStepper with EfficientSubstep] { - @inline def stepper: IntStepper with EfficientSubstep = new StepsIntIndexedSeq[CC](underlying, 0, underlying.length) -} - -final class RichLongIndexedSeqCanStep[CC <: collection.IndexedSeqLike[Long, _]](private val underlying: CC) extends AnyVal with MakesStepper[LongStepper with EfficientSubstep] { - @inline def stepper: LongStepper with EfficientSubstep = new StepsLongIndexedSeq[CC](underlying, 0, underlying.length) +final class RichIndexedSeqCanStep[T](private val underlying: collection.IndexedSeqLike[T, _]) extends AnyVal with MakesParStepper[T] { + override def stepper[S <: Stepper[_]](implicit ss: StepperShape[T, S]) = (ss match { + case ss if ss.ref => new StepsAnyIndexedSeq[T](underlying, 0, underlying.length) + 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 => super.stepper(ss) + }).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 index 0623119..256d121 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsIterable.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsIterable.scala @@ -10,18 +10,12 @@ import Stepper._ // Iterables just defer to iterator unless they can pattern match something better. // TODO: implement pattern matching! -final class RichIterableCanStep[A](private val underlying: Iterable[A]) extends AnyVal with MakesStepper[AnyStepper[A]] { - @inline def stepper: AnyStepper[A] = new StepsAnyIterator[A](underlying.iterator) -} - -final class RichDoubleIterableCanStep(private val underlying: Iterable[Double]) extends AnyVal with MakesStepper[DoubleStepper] { - @inline def stepper: DoubleStepper = new StepsDoubleIterator(underlying.iterator) -} - -final class RichIntIterableCanStep(private val underlying: Iterable[Int]) extends AnyVal with MakesStepper[IntStepper] { - @inline def stepper: IntStepper = new StepsIntIterator(underlying.iterator) -} - -final class RichLongIterableCanStep(private val underlying: Iterable[Long]) extends AnyVal with MakesStepper[LongStepper] { - @inline def stepper: LongStepper = new StepsLongIterator(underlying.iterator) +final class RichIterableCanStep[T](private val underlying: Iterable[T]) extends AnyVal with MakesSeqStepper[T] { + override def stepper[S <: Stepper[_]](implicit ss: StepperShape[T, S]) = (ss match { + case ss if ss.ref => new StepsAnyIterator[T](underlying.iterator) + 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 => super.stepper(ss) + }).asInstanceOf[S] } diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsIterator.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsIterator.scala index 89fa367..5058303 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsIterator.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsIterator.scala @@ -39,19 +39,12 @@ extends StepsLongLikeIterator[StepsLongIterator](_underlying) { // Value class adapters // ////////////////////////// -final class RichIteratorCanStep[A](private val underlying: Iterator[A]) extends AnyVal with MakesStepper[AnyStepper[A]] { - @inline def stepper: AnyStepper[A] = new StepsAnyIterator[A](underlying) +final class RichIteratorCanStep[T](private val underlying: Iterator[T]) extends AnyVal with MakesSeqStepper[T] { + override def stepper[S <: Stepper[_]](implicit ss: StepperShape[T, S]) = (ss match { + case ss if ss.ref => new StepsAnyIterator[T](underlying) + 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 => super.stepper(ss) + }).asInstanceOf[S] } - -final class RichDoubleIteratorCanStep(private val underlying: Iterator[Double]) extends AnyVal with MakesStepper[DoubleStepper] { - @inline def stepper: DoubleStepper = new StepsDoubleIterator(underlying) -} - -final class RichIntIteratorCanStep(private val underlying: Iterator[Int]) extends AnyVal with MakesStepper[IntStepper] { - @inline def stepper: IntStepper = new StepsIntIterator(underlying) -} - -final class RichLongIteratorCanStep(private val underlying: Iterator[Long]) extends AnyVal with MakesStepper[LongStepper] { - @inline def stepper: LongStepper = new StepsLongIterator(underlying) -} - diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsLinearSeq.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsLinearSeq.scala index 978bc33..c111915 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsLinearSeq.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsLinearSeq.scala @@ -11,54 +11,48 @@ import Stepper._ // Stepper implementations // ///////////////////////////// -private[java8] class StepsAnyLinearSeq[A, CC >: Null <: collection.LinearSeqLike[A, CC]](_underlying: CC, _maxN: Long) -extends StepsWithTail[A, CC, StepsAnyLinearSeq[A, CC]](_underlying, _maxN) { - protected def myIsEmpty(cc: CC): Boolean = cc.isEmpty - protected def myTailOf(cc: CC): CC = cc.tail +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 - def semiclone(half: Int) = new StepsAnyLinearSeq[A, CC](underlying, half) + def semiclone(half: Int) = new StepsAnyLinearSeq[A](underlying, half) } -private[java8] class StepsDoubleLinearSeq[CC >: Null <: collection.LinearSeqLike[Double, CC]](_underlying: CC, _maxN: Long) -extends StepsDoubleWithTail[CC, StepsDoubleLinearSeq[CC]](_underlying, _maxN) { - protected def myIsEmpty(cc: CC): Boolean = cc.isEmpty - protected def myTailOf(cc: CC): CC = cc.tail +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 - def semiclone(half: Int) = new StepsDoubleLinearSeq[CC](underlying, half) + def semiclone(half: Int) = new StepsDoubleLinearSeq(underlying, half) } -private[java8] class StepsIntLinearSeq[CC >: Null <: collection.LinearSeqLike[Int, CC]](_underlying: CC, _maxN: Long) -extends StepsIntWithTail[CC, StepsIntLinearSeq[CC]](_underlying, _maxN) { - protected def myIsEmpty(cc: CC): Boolean = cc.isEmpty - protected def myTailOf(cc: CC): CC = cc.tail +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 - def semiclone(half: Int) = new StepsIntLinearSeq[CC](underlying, half) + def semiclone(half: Int) = new StepsIntLinearSeq(underlying, half) } -private[java8] class StepsLongLinearSeq[CC >: Null <: collection.LinearSeqLike[Long, CC]](_underlying: CC, _maxN: Long) -extends StepsLongWithTail[CC, StepsLongLinearSeq[CC]](_underlying, _maxN) { - protected def myIsEmpty(cc: CC): Boolean = cc.isEmpty - protected def myTailOf(cc: CC): CC = cc.tail +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 - def semiclone(half: Int) = new StepsLongLinearSeq[CC](underlying, half) + def semiclone(half: Int) = new StepsLongLinearSeq(underlying, half) } ////////////////////////// // Value class adapters // ////////////////////////// -final class RichLinearSeqCanStep[A, CC >: Null <: collection.LinearSeqLike[A, CC]](private val underlying: CC) extends AnyVal with MakesStepper[AnyStepper[A]] { - @inline def stepper: AnyStepper[A] = new StepsAnyLinearSeq[A, CC](underlying, Long.MaxValue) -} - -final class RichDoubleLinearSeqCanStep[CC >: Null <: collection.LinearSeqLike[Double, CC]](private val underlying: CC) extends AnyVal with MakesStepper[DoubleStepper] { - @inline def stepper: DoubleStepper = new StepsDoubleLinearSeq[CC](underlying, Long.MaxValue) -} - -final class RichIntLinearSeqCanStep[CC >: Null <: collection.LinearSeqLike[Int, CC]](private val underlying: CC) extends AnyVal with MakesStepper[IntStepper] { - @inline def stepper: IntStepper = new StepsIntLinearSeq[CC](underlying, Long.MaxValue) -} - -final class RichLongLinearSeqCanStep[CC >: Null <: collection.LinearSeqLike[Long, CC]](private val underlying: CC) extends AnyVal with MakesStepper[LongStepper] { - @inline def stepper: LongStepper = new StepsLongLinearSeq[CC](underlying, Long.MaxValue) +final class RichLinearSeqCanStep[T](private val underlying: collection.LinearSeq[T]) extends AnyVal with MakesSeqStepper[T] { + override def stepper[S <: Stepper[_]](implicit ss: StepperShape[T, S]) = (ss match { + case ss if ss.ref => new StepsAnyLinearSeq[T](underlying, Long.MaxValue) + 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 => super.stepper(ss) + }).asInstanceOf[S] } diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsMap.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsMap.scala index 684892c..d5ae3bb 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsMap.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsMap.scala @@ -10,32 +10,22 @@ import Stepper._ // 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 MakesKeyStepper[AnyStepper[K]] with MakesValueStepper[AnyStepper[V]] { +final class RichMapCanStep[K, V](private val underlying: collection.Map[K, V]) extends AnyVal with MakesKeyValueSeqStepper[K, V] { // No generic stepper because RichIterableCanStep will get that anyway, and we don't pattern match here - def keyStepper: AnyStepper[K] = new StepsAnyIterator[K](underlying.keysIterator) - def valueStepper: AnyStepper[V] = new StepsAnyIterator[V](underlying.valuesIterator) -} - -final class RichDoubleKeyMapCanStep[V](private val underlying: collection.Map[Double, V]) extends AnyVal with MakesKeyStepper[DoubleStepper] { - def keyStepper: DoubleStepper = new StepsDoubleIterator(underlying.keysIterator) -} - -final class RichDoubleValueMapCanStep[K](private val underlying: collection.Map[K, Double]) extends AnyVal with MakesValueStepper[DoubleStepper] { - def valueStepper: DoubleStepper = new StepsDoubleIterator(underlying.valuesIterator) -} - -final class RichIntKeyMapCanStep[V](private val underlying: collection.Map[Int, V]) extends AnyVal with MakesKeyStepper[IntStepper] { - def keyStepper: IntStepper = new StepsIntIterator(underlying.keysIterator) -} - -final class RichIntValueMapCanStep[K](private val underlying: collection.Map[K, Int]) extends AnyVal with MakesValueStepper[IntStepper] { - def valueStepper: IntStepper = new StepsIntIterator(underlying.valuesIterator) -} - -final class RichLongKeyMapCanStep[V](private val underlying: collection.Map[Long, V]) extends AnyVal with MakesKeyStepper[LongStepper] { - def keyStepper: LongStepper = new StepsLongIterator(underlying.keysIterator) -} -final class RichLongValueMapCanStep[K](private val underlying: collection.Map[K, Long]) extends AnyVal with MakesValueStepper[LongStepper] { - def valueStepper: LongStepper = new StepsLongIterator(underlying.valuesIterator) + override def keyStepper[S <: Stepper[_]](implicit ss: StepperShape[K, S]) = (ss match { + case ss if ss.ref => new StepsAnyIterator (underlying.keysIterator) + 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 => super.keyStepper(ss) + }).asInstanceOf[S] + + override def valueStepper[S <: Stepper[_]](implicit ss: StepperShape[V, S]) = (ss match { + case ss if ss.ref => new StepsAnyIterator (underlying.valuesIterator) + 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 => super.valueStepper(ss) + }).asInstanceOf[S] } diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsRange.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsRange.scala index e60acee..4dc0eec 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsRange.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsRange.scala @@ -39,18 +39,16 @@ extends StepsLongLikeIndexed[StepsLongNumericRange](_i0, _iN) { // Value class adapters // ////////////////////////// -final class RichRangeCanStep(private val underlying: Range) extends AnyVal with MakesStepper[IntStepper with EfficientSubstep] { - @inline def stepper: IntStepper with EfficientSubstep = new StepsIntRange(underlying, 0, underlying.length) -} - -final class RichNumericRangeCanStep[T](private val underlying: collection.immutable.NumericRange[T]) extends AnyVal with MakesStepper[AnyStepper[T] with EfficientSubstep] { - @inline def stepper: AnyStepper[T] with EfficientSubstep = new StepsAnyNumericRange[T](underlying, 0, underlying.length) -} - -final class RichIntNumericRangeCanStep(private val underlying: collection.immutable.NumericRange[Int]) extends AnyVal with MakesStepper[IntStepper with EfficientSubstep] { - @inline def stepper: IntStepper with EfficientSubstep = new StepsIntNumericRange(underlying, 0, underlying.length) +final class RichRangeCanStep[T](private val underlying: Range) extends AnyVal with MakesParStepper[Int] { + override def stepper[S <: Stepper[_]](implicit ss: StepperShape[Int, S]) = + new StepsIntRange(underlying, 0, underlying.length).asInstanceOf[S with EfficientSubstep] } -final class RichLongNumericRangeCanStep(private val underlying: collection.immutable.NumericRange[Long]) extends AnyVal with MakesStepper[LongStepper with EfficientSubstep] { - @inline def stepper: LongStepper with EfficientSubstep = new StepsLongNumericRange(underlying, 0, underlying.length) +final class RichNumericRangeCanStep[T](private val underlying: collection.immutable.NumericRange[T]) extends AnyVal with MakesParStepper[T] { + override def stepper[S <: Stepper[_]](implicit ss: StepperShape[T, S]) = (ss match { + case ss if ss.ref => new StepsAnyNumericRange[T](underlying, 0, underlying.length) + 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 => super.stepper(ss) + }).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 index de937b8..85e4706 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsString.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsString.scala @@ -11,7 +11,7 @@ import Stepper._ // Stepper implementation // //////////////////////////// -private[java8] class StepperStringChar(underlying: String, _i0: Int, _iN: Int) +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) @@ -45,8 +45,8 @@ private[java8] class StepperStringCodePoint(underlying: String, var i0: Int, var // Value class adapter // ///////////////////////// -final class RichStringCanStep(private val underlying: String) extends AnyVal with MakesStepper[IntStepper with EfficientSubstep] { - @inline def stepper: IntStepper with EfficientSubstep = charStepper +final class RichStringCanStep(private val underlying: String) extends AnyVal with MakesParStepper[Char] { + override 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 index 132f89b..046a587 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsVector.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsVector.scala @@ -134,18 +134,12 @@ with StepsVectorLike[Long] { // Value class adapters // ////////////////////////// -final class RichVectorCanStep[A](private val underlying: Vector[A]) extends AnyVal with MakesStepper[AnyStepper[A] with EfficientSubstep] { - @inline def stepper: AnyStepper[A] with EfficientSubstep = new StepsAnyVector[A](underlying, 0, underlying.length) -} - -final class RichDoubleVectorCanStep[A](private val underlying: Vector[Double]) extends AnyVal with MakesStepper[DoubleStepper with EfficientSubstep] { - @inline def stepper: DoubleStepper with EfficientSubstep = new StepsDoubleVector(underlying, 0, underlying.length) -} - -final class RichIntVectorCanStep[A](private val underlying: Vector[Int]) extends AnyVal with MakesStepper[IntStepper with EfficientSubstep] { - @inline def stepper: IntStepper with EfficientSubstep = new StepsIntVector(underlying, 0, underlying.length) -} - -final class RichLongVectorCanStep[A](private val underlying: Vector[Long]) extends AnyVal with MakesStepper[LongStepper with EfficientSubstep] { - @inline def stepper: LongStepper with EfficientSubstep = new StepsLongVector(underlying, 0, underlying.length) +final class RichVectorCanStep[T](private val underlying: Vector[T]) extends AnyVal with MakesParStepper[T] { + override def stepper[S <: Stepper[_]](implicit ss: StepperShape[T, S]) = (ss match { + case ss if ss.ref => new StepsAnyVector[T](underlying, 0, underlying.length) + 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 => super.stepper(ss) + }).asInstanceOf[S with EfficientSubstep] } diff --git a/src/test/scala/scala/compat/java8/StepConvertersTest.scala b/src/test/scala/scala/compat/java8/StepConvertersTest.scala index d7efe82..d061913 100644 --- a/src/test/scala/scala/compat/java8/StepConvertersTest.scala +++ b/src/test/scala/scala/compat/java8/StepConvertersTest.scala @@ -324,7 +324,7 @@ class StepConvertersTest { @Test def comprehensivelyInt() { - implicit val spec = SpecCheck(_.isInstanceOf[IntStepper]) + implicit val spec = SpecCheck(_.isInstanceOf[IntStepper], x => s"$x should be an IntStepper") // Int-specific tests good( co.BitSet(42).stepper ) @@ -585,7 +585,7 @@ class StepConvertersTest { @Test def comprehensivelySpecific() { - implicit val spec = SpecCheck(_.isInstanceOf[AnyStepper[_]]) + implicit val spec = SpecCheck(_.isInstanceOf[IntStepper], x => s"$x should be an IntStepper") good( ci.NumericRange(277: Short, 279: Short, 1: Short).stepper ) _eh_( ci.PagedSeq.fromLines(Array("salmon").iterator).stepper ) diff --git a/src/test/scala/scala/compat/java8/StreamConvertersTest.scala b/src/test/scala/scala/compat/java8/StreamConvertersTest.scala index 66997bf..26ca38c 100644 --- a/src/test/scala/scala/compat/java8/StreamConvertersTest.scala +++ b/src/test/scala/scala/compat/java8/StreamConvertersTest.scala @@ -6,13 +6,15 @@ import org.junit.Assert._ import java.util.stream._ import StreamConverters._ import scala.compat.java8.collectionImpl.IntStepper -import scala.compat.java8.converterImpl.{MakesStepper, MakesSequentialStream} +import scala.compat.java8.converterImpl.MakesStepper class StreamConvertersTest { def assertEq[A](a1: A, a2: A, s: String) { assertEquals(s, a1, a2) } // Weird order normally! def assertEq[A](a1: A, a2: A) { assertEq(a1, a2, "not equal") } - + def assert(b: Boolean) { assertTrue(b) } + def assert(b: Boolean, s: String) { assertTrue(s, b) } + def arrayO(n: Int) = (1 to n).map(_.toString).toArray def arrayD(n: Int) = (1 to n).map(_.toDouble).toArray def arrayI(n: Int) = (1 to n).toArray @@ -37,7 +39,7 @@ class StreamConvertersTest { assertEq(vecO, accO.toList.toVector, s"stream $n to vector via list in parallel") assert((0 until accO.size.toInt).forall(i => vecO(i) == accO(i)), s"stream $n indexed via accumulator") assert(accO.isInstanceOf[scala.compat.java8.collectionImpl.Accumulator[_]], s"stream $n to generic accumulator") - + for (boxless <- Seq(false, true)) { val sbox = (if (boxless) "" else "(boxed)") val vecD = arrayD(n).toVector @@ -78,28 +80,28 @@ class StreamConvertersTest { } } } - + @Test def streamToScala() { for (n <- ns) { val vecO = arrayO(n).toVector 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]) - + val vecI = arrayI(n).toVector 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]) } } - + @Test def streamUnbox() { assert(newDoubleStream(1).boxed.unboxed.isInstanceOf[DoubleStream]) @@ -148,7 +150,7 @@ class StreamConvertersTest { 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 val abD = abufD(n) @@ -177,7 +179,7 @@ class StreamConvertersTest { 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 val abI = abufI(n) @@ -206,7 +208,7 @@ class StreamConvertersTest { 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 val abL = abufL(n) @@ -254,9 +256,22 @@ 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[java.lang.Integer, IntStream]] + 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[IntStepper]] - assertTrue(steppize(coll).getClass.getName.contains("RichArrayIntCanStep")) + val steppize = implicitly[collection.mutable.WrappedArray[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")) } } From 159000486415855fdccac7fd9fc8c96f86f2a2fc Mon Sep 17 00:00:00 2001 From: Stefan Zeiger Date: Wed, 20 Apr 2016 19:24:44 +0200 Subject: [PATCH 4/4] Improved StepperShape This does away with the default implementations of `MakesStepper` et. al. and moves the unboxing logic into `StepperShape` for simpler implementations with faster dispatch. --- .../compat/java8/ScalaStreamSupport.java | 2 +- .../scala/compat/java8/StreamConverters.scala | 4 +- .../java8/converterImpl/MakesSteppers.scala | 154 +++++++----------- .../java8/converterImpl/StepsArray.scala | 8 +- .../java8/converterImpl/StepsBitSet.scala | 2 +- .../converterImpl/StepsFlatHashTable.scala | 8 +- .../java8/converterImpl/StepsHashTable.scala | 37 ++--- .../java8/converterImpl/StepsImmHashMap.scala | 15 +- .../java8/converterImpl/StepsImmHashSet.scala | 8 +- .../java8/converterImpl/StepsIndexedSeq.scala | 8 +- .../java8/converterImpl/StepsIterable.scala | 8 +- .../java8/converterImpl/StepsIterator.scala | 8 +- .../java8/converterImpl/StepsLinearSeq.scala | 8 +- .../compat/java8/converterImpl/StepsMap.scala | 13 +- .../java8/converterImpl/StepsRange.scala | 12 +- .../java8/converterImpl/StepsString.scala | 4 +- .../java8/converterImpl/StepsVector.scala | 8 +- 17 files changed, 137 insertions(+), 170 deletions(-) diff --git a/src/main/java/scala/compat/java8/ScalaStreamSupport.java b/src/main/java/scala/compat/java8/ScalaStreamSupport.java index 5afbde7..b0d3452 100644 --- a/src/main/java/scala/compat/java8/ScalaStreamSupport.java +++ b/src/main/java/scala/compat/java8/ScalaStreamSupport.java @@ -484,7 +484,7 @@ 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$.IntValue()), false); + return StreamSupport.intStream(rbscs.stepper(StepperShape$.MODULE$.intStepperShape()), false); } /** diff --git a/src/main/scala/scala/compat/java8/StreamConverters.scala b/src/main/scala/scala/compat/java8/StreamConverters.scala index e47852d..bbb5fbd 100644 --- a/src/main/scala/scala/compat/java8/StreamConverters.scala +++ b/src/main/scala/scala/compat/java8/StreamConverters.scala @@ -21,7 +21,7 @@ sealed trait StreamShape[T, S <: BaseStream[_, S]] { def fromKeyStepper (mk: MakesKeyValueStepper[T, _, _], par: Boolean): S def fromValueStepper(mk: MakesKeyValueStepper[_, T, _], par: Boolean): S } -object StreamShape extends StreamShapeLowPrio { +object StreamShape extends StreamShapeLowPriority { // primitive implicit val IntValue = intStreamShape[Int] implicit val LongValue = longStreamShape[Long] @@ -33,7 +33,7 @@ object StreamShape extends StreamShapeLowPrio { implicit val CharValue = intStreamShape[Char] implicit val FloatValue = doubleStreamShape[Float] } -trait StreamShapeLowPrio { +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) diff --git a/src/main/scala/scala/compat/java8/converterImpl/MakesSteppers.scala b/src/main/scala/scala/compat/java8/converterImpl/MakesSteppers.scala index 1079d24..017f2cd 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/MakesSteppers.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/MakesSteppers.scala @@ -18,104 +18,76 @@ trait MakesKeyValueStepper[K, V, +Extra] extends Any { def valueStepper[S <: Stepper[_]](implicit ss: StepperShape[V, S]): S with Extra } -sealed trait StepperShape[T, S <: Stepper[_]] { def ref: Boolean } -object StepperShape extends StepperShapeLowPrio { - private[this] def valueShape[T, S <: Stepper[_]]: StepperShape[T, S] = new StepperShape[T, S] { def ref = false } +/** 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 - // primitive - implicit val IntValue = valueShape[Int, IntStepper] - implicit val LongValue = valueShape[Long, LongStepper] - implicit val DoubleValue = valueShape[Double, DoubleStepper] + /** Create an unboxing primitive sequential Stepper from a boxed `AnyStepper`. + * This is an identity operation for reference shapes. */ + def seqUnbox(st: AnyStepper[T]): S - // widening - implicit val ByteValue = valueShape[Byte, IntStepper] - implicit val ShortValue = valueShape[Short, IntStepper] - implicit val CharValue = valueShape[Char, IntStepper] - implicit val FloatValue = valueShape[Float, DoubleStepper] + /** 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 } -trait StepperShapeLowPrio { +object StepperShape extends StepperShapeLowPriority { // reference - implicit def anyStepperShape[T]: StepperShape[T, AnyStepper[T]] = new StepperShape[T, AnyStepper[T]] { def ref = true } -} - -/** Superclass for `MakesStepper` implementations which support parallelization. At least the `AnyStepper` case must be - * implemented, all others default to building an `AnyStepper` and putting an unboxing conversion on top. */ -trait MakesParStepper[T] extends Any with MakesStepper[T, EfficientSubstep] { - def stepper[S <: Stepper[_]](implicit ss: StepperShape[T, S]) = (ss match { - case StepperShape.IntValue => new Stepper.UnboxingIntStepper (stepper(StepperShape.anyStepperShape[T]).asInstanceOf[AnyStepper[Int ]]) with EfficientSubstep - case StepperShape.LongValue => new Stepper.UnboxingLongStepper (stepper(StepperShape.anyStepperShape[T]).asInstanceOf[AnyStepper[Long ]]) with EfficientSubstep - case StepperShape.DoubleValue => new Stepper.UnboxingDoubleStepper(stepper(StepperShape.anyStepperShape[T]).asInstanceOf[AnyStepper[Double]]) with EfficientSubstep - case StepperShape.ByteValue => new Stepper.UnboxingByteStepper (stepper(StepperShape.anyStepperShape[T]).asInstanceOf[AnyStepper[Byte ]]) with EfficientSubstep - case StepperShape.ShortValue => new Stepper.UnboxingShortStepper (stepper(StepperShape.anyStepperShape[T]).asInstanceOf[AnyStepper[Short ]]) with EfficientSubstep - case StepperShape.CharValue => new Stepper.UnboxingCharStepper (stepper(StepperShape.anyStepperShape[T]).asInstanceOf[AnyStepper[Char ]]) with EfficientSubstep - case StepperShape.FloatValue => new Stepper.UnboxingFloatStepper (stepper(StepperShape.anyStepperShape[T]).asInstanceOf[AnyStepper[Float ]]) with EfficientSubstep - case _ => throw new NotImplementedError("AnyStepper must be handled in `stepper` implementations") - }).asInstanceOf[S with EfficientSubstep] -} + final val Reference = 0 -/** Superclass for `MakesStepper` implementations which do not support parallelization. At least the `AnyStepper` case must be - * implemented, all others default to building an `AnyStepper` and putting an unboxing conversion on top. */ -trait MakesSeqStepper[T] extends Any with MakesStepper[T, Any] { - def stepper[S <: Stepper[_]](implicit ss: StepperShape[T, S]) = (ss match { - case StepperShape.IntValue => new Stepper.UnboxingIntStepper (stepper(StepperShape.anyStepperShape[T]).asInstanceOf[AnyStepper[Int ]]) - case StepperShape.LongValue => new Stepper.UnboxingLongStepper (stepper(StepperShape.anyStepperShape[T]).asInstanceOf[AnyStepper[Long ]]) - case StepperShape.DoubleValue => new Stepper.UnboxingDoubleStepper(stepper(StepperShape.anyStepperShape[T]).asInstanceOf[AnyStepper[Double]]) - case StepperShape.ByteValue => new Stepper.UnboxingByteStepper (stepper(StepperShape.anyStepperShape[T]).asInstanceOf[AnyStepper[Byte ]]) - case StepperShape.ShortValue => new Stepper.UnboxingShortStepper (stepper(StepperShape.anyStepperShape[T]).asInstanceOf[AnyStepper[Short ]]) - case StepperShape.CharValue => new Stepper.UnboxingCharStepper (stepper(StepperShape.anyStepperShape[T]).asInstanceOf[AnyStepper[Char ]]) - case StepperShape.FloatValue => new Stepper.UnboxingFloatStepper (stepper(StepperShape.anyStepperShape[T]).asInstanceOf[AnyStepper[Float ]]) - case _ => throw new NotImplementedError("AnyStepper must be handled in `stepper` implementations") - }).asInstanceOf[S] -} + // primitive + final val IntValue = 1 + final val LongValue = 2 + final val DoubleValue = 3 -/** Superclass for `MakesKeyalueStepper` implementations which support parallelization. At least the `AnyStepper` case must be - * implemented, all others default to building an `AnyStepper` and putting an unboxing conversion on top. */ -trait MakesKeyValueParStepper[K, V] extends Any with MakesKeyValueStepper[K, V, EfficientSubstep] { - def keyStepper[S <: Stepper[_]](implicit ss: StepperShape[K, S]) = (ss match { - case StepperShape.IntValue => new Stepper.UnboxingIntStepper (keyStepper(StepperShape.anyStepperShape[K]).asInstanceOf[AnyStepper[Int ]]) with EfficientSubstep - case StepperShape.LongValue => new Stepper.UnboxingLongStepper (keyStepper(StepperShape.anyStepperShape[K]).asInstanceOf[AnyStepper[Long ]]) with EfficientSubstep - case StepperShape.DoubleValue => new Stepper.UnboxingDoubleStepper(keyStepper(StepperShape.anyStepperShape[K]).asInstanceOf[AnyStepper[Double]]) with EfficientSubstep - case StepperShape.ByteValue => new Stepper.UnboxingByteStepper (keyStepper(StepperShape.anyStepperShape[K]).asInstanceOf[AnyStepper[Byte ]]) with EfficientSubstep - case StepperShape.ShortValue => new Stepper.UnboxingShortStepper (keyStepper(StepperShape.anyStepperShape[K]).asInstanceOf[AnyStepper[Short ]]) with EfficientSubstep - case StepperShape.CharValue => new Stepper.UnboxingCharStepper (keyStepper(StepperShape.anyStepperShape[K]).asInstanceOf[AnyStepper[Char ]]) with EfficientSubstep - case StepperShape.FloatValue => new Stepper.UnboxingFloatStepper (keyStepper(StepperShape.anyStepperShape[K]).asInstanceOf[AnyStepper[Float ]]) with EfficientSubstep - case _ => throw new NotImplementedError("AnyStepper case must be handled in `keyStepper` implementations") - }).asInstanceOf[S with EfficientSubstep] + // widening + final val ByteValue = 4 + final val ShortValue = 5 + final val CharValue = 6 + final val FloatValue = 7 - def valueStepper[S <: Stepper[_]](implicit ss: StepperShape[V, S]) = (ss match { - case StepperShape.IntValue => new Stepper.UnboxingIntStepper (valueStepper(StepperShape.anyStepperShape[V]).asInstanceOf[AnyStepper[Int ]]) with EfficientSubstep - case StepperShape.LongValue => new Stepper.UnboxingLongStepper (valueStepper(StepperShape.anyStepperShape[V]).asInstanceOf[AnyStepper[Long ]]) with EfficientSubstep - case StepperShape.DoubleValue => new Stepper.UnboxingDoubleStepper(valueStepper(StepperShape.anyStepperShape[V]).asInstanceOf[AnyStepper[Double]]) with EfficientSubstep - case StepperShape.ByteValue => new Stepper.UnboxingByteStepper (valueStepper(StepperShape.anyStepperShape[V]).asInstanceOf[AnyStepper[Byte ]]) with EfficientSubstep - case StepperShape.ShortValue => new Stepper.UnboxingShortStepper (valueStepper(StepperShape.anyStepperShape[V]).asInstanceOf[AnyStepper[Short ]]) with EfficientSubstep - case StepperShape.CharValue => new Stepper.UnboxingCharStepper (valueStepper(StepperShape.anyStepperShape[V]).asInstanceOf[AnyStepper[Char ]]) with EfficientSubstep - case StepperShape.FloatValue => new Stepper.UnboxingFloatStepper (valueStepper(StepperShape.anyStepperShape[V]).asInstanceOf[AnyStepper[Float ]]) with EfficientSubstep - case _ => throw new NotImplementedError("AnyStepper case must be handled in `valueStepper` implementations") - }).asInstanceOf[S with EfficientSubstep] + 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]]] -/** Superclass for `MakesKeyalueStepper` implementations which do not support parallelization. At least the `AnyStepper` case must be - * implemented, all others default to building an `AnyStepper` and putting an unboxing conversion on top. */ -trait MakesKeyValueSeqStepper[K, V] extends Any with MakesKeyValueStepper[K, V, Any] { - def keyStepper[S <: Stepper[_]](implicit ss: StepperShape[K, S]) = (ss match { - case StepperShape.IntValue => new Stepper.UnboxingIntStepper (keyStepper(StepperShape.anyStepperShape[K]).asInstanceOf[AnyStepper[Int ]]) - case StepperShape.LongValue => new Stepper.UnboxingLongStepper (keyStepper(StepperShape.anyStepperShape[K]).asInstanceOf[AnyStepper[Long ]]) - case StepperShape.DoubleValue => new Stepper.UnboxingDoubleStepper(keyStepper(StepperShape.anyStepperShape[K]).asInstanceOf[AnyStepper[Double]]) - case StepperShape.ByteValue => new Stepper.UnboxingByteStepper (keyStepper(StepperShape.anyStepperShape[K]).asInstanceOf[AnyStepper[Byte ]]) - case StepperShape.ShortValue => new Stepper.UnboxingShortStepper (keyStepper(StepperShape.anyStepperShape[K]).asInstanceOf[AnyStepper[Short ]]) - case StepperShape.CharValue => new Stepper.UnboxingCharStepper (keyStepper(StepperShape.anyStepperShape[K]).asInstanceOf[AnyStepper[Char ]]) - case StepperShape.FloatValue => new Stepper.UnboxingFloatStepper (keyStepper(StepperShape.anyStepperShape[K]).asInstanceOf[AnyStepper[Float ]]) - case _ => throw new NotImplementedError("AnyStepper case must be handled in `keyStepper` implementations") - }).asInstanceOf[S] - - def valueStepper[S <: Stepper[_]](implicit ss: StepperShape[V, S]) = (ss match { - case StepperShape.IntValue => new Stepper.UnboxingIntStepper (valueStepper(StepperShape.anyStepperShape[V]).asInstanceOf[AnyStepper[Int ]]) - case StepperShape.LongValue => new Stepper.UnboxingLongStepper (valueStepper(StepperShape.anyStepperShape[V]).asInstanceOf[AnyStepper[Long ]]) - case StepperShape.DoubleValue => new Stepper.UnboxingDoubleStepper(valueStepper(StepperShape.anyStepperShape[V]).asInstanceOf[AnyStepper[Double]]) - case StepperShape.ByteValue => new Stepper.UnboxingByteStepper (valueStepper(StepperShape.anyStepperShape[V]).asInstanceOf[AnyStepper[Byte ]]) - case StepperShape.ShortValue => new Stepper.UnboxingShortStepper (valueStepper(StepperShape.anyStepperShape[V]).asInstanceOf[AnyStepper[Short ]]) - case StepperShape.CharValue => new Stepper.UnboxingCharStepper (valueStepper(StepperShape.anyStepperShape[V]).asInstanceOf[AnyStepper[Char ]]) - case StepperShape.FloatValue => new Stepper.UnboxingFloatStepper (valueStepper(StepperShape.anyStepperShape[V]).asInstanceOf[AnyStepper[Float ]]) - case _ => throw new NotImplementedError("AnyStepper case must be handled in `valueStepper` implementations") - }).asInstanceOf[S] + 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/StepsArray.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsArray.scala index 0da150e..ef75eb6 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsArray.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsArray.scala @@ -1,6 +1,7 @@ package scala.compat.java8.converterImpl import language.implicitConversions +import scala.annotation.switch import scala.compat.java8.collectionImpl._ import scala.compat.java8.runtime._ @@ -69,9 +70,9 @@ extends StepsLongLikeIndexed[StepsLongArray](_i0, _iN) { // Value class adapters // ////////////////////////// -final class RichArrayCanStep[T](private val underlying: Array[T]) extends AnyVal with MakesParStepper[T] { - override def stepper[S <: Stepper[_]](implicit ss: StepperShape[T, S]) = (ss match { - case ss if ss.ref => +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) @@ -82,6 +83,5 @@ final class RichArrayCanStep[T](private val underlying: Array[T]) extends AnyVal 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) - case ss => super.stepper(ss) }).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 index 55bae9f..b6f698a 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsBitSet.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsBitSet.scala @@ -53,7 +53,7 @@ extends StepsIntLikeSliced[Array[Long], StepsIntBitSet](_underlying, _i0, _iN) { // Value class adapter // ///////////////////////// -final class RichBitSetCanStep(private val underlying: collection.BitSet) extends AnyVal with MakesParStepper[Int] { +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) diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsFlatHashTable.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsFlatHashTable.scala index 70dbc76..ec30008 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsFlatHashTable.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsFlatHashTable.scala @@ -1,6 +1,7 @@ package scala.compat.java8.converterImpl import language.implicitConversions +import scala.annotation.switch import scala.compat.java8.collectionImpl._ import scala.compat.java8.runtime._ @@ -39,15 +40,14 @@ extends StepsLongLikeGapped[StepsLongFlatHashTable](_underlying, _i0, _iN) { // Value class adapters // ////////////////////////// -final class RichFlatHashTableCanStep[T](private val underlying: collection.mutable.FlatHashTable[T]) extends AnyVal with MakesParStepper[T] { +final class RichFlatHashTableCanStep[T](private val underlying: collection.mutable.FlatHashTable[T]) extends AnyVal with MakesStepper[T, EfficientSubstep] { override def stepper[S <: Stepper[_]](implicit ss: StepperShape[T, S]) = { val tbl = CollectionInternals.getTable(underlying) - (ss match { - case ss if ss.ref => new StepsAnyFlatHashTable[T](tbl, 0, tbl.length) + ((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 => super.stepper(ss) + 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 index 4a328d1..dde431e 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsHashTable.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsHashTable.scala @@ -1,6 +1,7 @@ package scala.compat.java8.converterImpl import language.implicitConversions +import scala.annotation.switch import scala.compat.java8.collectionImpl._ import scala.compat.java8.runtime._ @@ -140,62 +141,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 MakesKeyValueParStepper[K, V] with MakesParStepper[(K, V)] { - override def stepper[S <: Stepper[_]](implicit ss: StepperShape[(K, V), S]) = { +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] { + def stepper[S <: Stepper[_]](implicit ss: StepperShape[(K, V), S]) = { val tbl = CollectionInternals.getTable[K, collection.mutable.DefaultEntry[K, V]](underlying) new StepsAnyDefaultHashTable(tbl, 0, tbl.length).asInstanceOf[S with EfficientSubstep] } - override def keyStepper[S <: Stepper[_]](implicit ss: StepperShape[K, S]) = { + def keyStepper[S <: Stepper[_]](implicit ss: StepperShape[K, S]) = { val tbl = CollectionInternals.getTable[K, collection.mutable.DefaultEntry[K, V]](underlying) - (ss match { - case ss if ss.ref => new StepsAnyHashTableKey (tbl.asInstanceOf[Array[collection.mutable.HashEntry[K, _]]], 0, tbl.length) + ((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 => super.keyStepper(ss) + case _ => ss.parUnbox(new StepsAnyHashTableKey (tbl.asInstanceOf[Array[collection.mutable.HashEntry[K, _]]], 0, tbl.length)) }).asInstanceOf[S with EfficientSubstep] } - override def valueStepper[S <: Stepper[_]](implicit ss: StepperShape[V, S]) = { + def valueStepper[S <: Stepper[_]](implicit ss: StepperShape[V, S]) = { val tbl = CollectionInternals.getTable[K, collection.mutable.DefaultEntry[K, V]](underlying) - (ss match { - case ss if ss.ref => new StepsAnyDefaultHashTableValue (tbl, 0, tbl.length) + ((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 => super.valueStepper(ss) + 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 MakesKeyValueParStepper[K, V] with MakesParStepper[(K, V)] { - override def stepper[S <: Stepper[_]](implicit ss: StepperShape[(K, V), S]) = { +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] { + def stepper[S <: Stepper[_]](implicit ss: StepperShape[(K, V), S]) = { val tbl = CollectionInternals.getTable[K, collection.mutable.LinkedEntry[K, V]](underlying) new StepsAnyLinkedHashTable(tbl, 0, tbl.length).asInstanceOf[S with EfficientSubstep] } - override def keyStepper[S <: Stepper[_]](implicit ss: StepperShape[K, S]) = { + def keyStepper[S <: Stepper[_]](implicit ss: StepperShape[K, S]) = { val tbl = CollectionInternals.getTable[K, collection.mutable.LinkedEntry[K, V]](underlying) - (ss match { - case ss if ss.ref => new StepsAnyHashTableKey (tbl.asInstanceOf[Array[collection.mutable.HashEntry[K, _]]], 0, tbl.length) + ((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 => super.keyStepper(ss) + case _ => ss.parUnbox(new StepsAnyHashTableKey (tbl.asInstanceOf[Array[collection.mutable.HashEntry[K, _]]], 0, tbl.length)) }).asInstanceOf[S with EfficientSubstep] } - override def valueStepper[S <: Stepper[_]](implicit ss: StepperShape[V, S]) = { + def valueStepper[S <: Stepper[_]](implicit ss: StepperShape[V, S]) = { val tbl = CollectionInternals.getTable[K, collection.mutable.LinkedEntry[K, V]](underlying) - (ss match { - case ss if ss.ref => new StepsAnyLinkedHashTableValue (tbl, 0, tbl.length) + ((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 => super.valueStepper(ss) + case _ => ss.parUnbox(new StepsAnyLinkedHashTableValue (tbl, 0, tbl.length)) }).asInstanceOf[S with EfficientSubstep] } } diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsImmHashMap.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsImmHashMap.scala index 888c1d4..d6a5b0e 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsImmHashMap.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsImmHashMap.scala @@ -1,6 +1,7 @@ package scala.compat.java8.converterImpl import language.implicitConversions +import scala.annotation.switch import scala.compat.java8.collectionImpl._ import scala.compat.java8.runtime._ @@ -125,23 +126,21 @@ extends StepsLongLikeImmHashMap[K, Long, StepsLongImmHashMapValue[K]](_underlyin // Value class adapters // ////////////////////////// -final class RichImmHashMapCanStep[K, V](private val underlying: collection.immutable.HashMap[K, V]) extends AnyVal with MakesKeyValueParStepper[K, V] with MakesParStepper[(K, V)] { - override def stepper[S <: Stepper[_]](implicit ss: StepperShape[(K, V), S]) = +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] - override def keyStepper[S <: Stepper[_]](implicit ss: StepperShape[K, S]) = (ss match { - case ss if ss.ref => new StepsAnyImmHashMapKey[K, V](underlying, 0, underlying.size) + 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 => super.keyStepper(ss) + case _ => ss.parUnbox(new StepsAnyImmHashMapKey[K, V](underlying, 0, underlying.size)) }).asInstanceOf[S with EfficientSubstep] - override def valueStepper[S <: Stepper[_]](implicit ss: StepperShape[V, S]) = (ss match { - case ss if ss.ref => new StepsAnyImmHashMapValue[K, V](underlying, 0, underlying.size) + 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 => super.valueStepper(ss) + 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/StepsImmHashSet.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsImmHashSet.scala index 56e0560..abde687 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsImmHashSet.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsImmHashSet.scala @@ -1,6 +1,7 @@ package scala.compat.java8.converterImpl import language.implicitConversions +import scala.annotation.switch import scala.compat.java8.collectionImpl._ import scala.compat.java8.runtime._ @@ -39,12 +40,11 @@ extends StepsLongLikeTrieIterator[StepsLongImmHashSet](_underlying, _N) { // Value class adapters // ////////////////////////// -final class RichImmHashSetCanStep[T](private val underlying: collection.immutable.HashSet[T]) extends AnyVal with MakesParStepper[T] { - override def stepper[S <: Stepper[_]](implicit ss: StepperShape[T, S]) = (ss match { - case ss if ss.ref => new StepsAnyImmHashSet[T](underlying.iterator, underlying.size) +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 => super.stepper(ss) + 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 index 69d3260..e36fab0 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsIndexedSeq.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsIndexedSeq.scala @@ -1,6 +1,7 @@ package scala.compat.java8.converterImpl import language.implicitConversions +import scala.annotation.switch import scala.compat.java8.collectionImpl._ import scala.compat.java8.runtime._ @@ -39,12 +40,11 @@ extends StepsLongLikeIndexed[StepsLongIndexedSeq[CC]](_i0, _iN) { // Value class adapters // ////////////////////////// -final class RichIndexedSeqCanStep[T](private val underlying: collection.IndexedSeqLike[T, _]) extends AnyVal with MakesParStepper[T] { - override def stepper[S <: Stepper[_]](implicit ss: StepperShape[T, S]) = (ss match { - case ss if ss.ref => new StepsAnyIndexedSeq[T](underlying, 0, underlying.length) +final class RichIndexedSeqCanStep[T](private val underlying: collection.IndexedSeqLike[T, _]) 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 => super.stepper(ss) + 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 index 256d121..dd8d6a3 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsIterable.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsIterable.scala @@ -1,6 +1,7 @@ package scala.compat.java8.converterImpl import language.implicitConversions +import scala.annotation.switch import scala.compat.java8.collectionImpl._ import scala.compat.java8.runtime._ @@ -10,12 +11,11 @@ import Stepper._ // 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 MakesSeqStepper[T] { - override def stepper[S <: Stepper[_]](implicit ss: StepperShape[T, S]) = (ss match { - case ss if ss.ref => new StepsAnyIterator[T](underlying.iterator) +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 => super.stepper(ss) + 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 index 5058303..02f58cd 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsIterator.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsIterator.scala @@ -1,6 +1,7 @@ package scala.compat.java8.converterImpl import language.implicitConversions +import scala.annotation.switch import scala.compat.java8.collectionImpl._ import scala.compat.java8.runtime._ @@ -39,12 +40,11 @@ extends StepsLongLikeIterator[StepsLongIterator](_underlying) { // Value class adapters // ////////////////////////// -final class RichIteratorCanStep[T](private val underlying: Iterator[T]) extends AnyVal with MakesSeqStepper[T] { - override def stepper[S <: Stepper[_]](implicit ss: StepperShape[T, S]) = (ss match { - case ss if ss.ref => new StepsAnyIterator[T](underlying) +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 => super.stepper(ss) + case _ => ss.seqUnbox(new StepsAnyIterator[T](underlying)) }).asInstanceOf[S] } diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsLinearSeq.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsLinearSeq.scala index c111915..892bed5 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsLinearSeq.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsLinearSeq.scala @@ -1,6 +1,7 @@ package scala.compat.java8.converterImpl import language.implicitConversions +import scala.annotation.switch import scala.compat.java8.collectionImpl._ import scala.compat.java8.runtime._ @@ -47,12 +48,11 @@ extends StepsLongWithTail[collection.LinearSeq[Long], StepsLongLinearSeq](_under // Value class adapters // ////////////////////////// -final class RichLinearSeqCanStep[T](private val underlying: collection.LinearSeq[T]) extends AnyVal with MakesSeqStepper[T] { - override def stepper[S <: Stepper[_]](implicit ss: StepperShape[T, S]) = (ss match { - case ss if ss.ref => new StepsAnyLinearSeq[T](underlying, Long.MaxValue) +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 => super.stepper(ss) + 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 index d5ae3bb..3a1f49c 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsMap.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsMap.scala @@ -1,6 +1,7 @@ package scala.compat.java8.converterImpl import language.implicitConversions +import scala.annotation.switch import scala.compat.java8.collectionImpl._ import scala.compat.java8.runtime._ @@ -10,22 +11,20 @@ import Stepper._ // 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 MakesKeyValueSeqStepper[K, V] { +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 - override def keyStepper[S <: Stepper[_]](implicit ss: StepperShape[K, S]) = (ss match { - case ss if ss.ref => new StepsAnyIterator (underlying.keysIterator) + 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 => super.keyStepper(ss) + case _ => ss.seqUnbox(new StepsAnyIterator (underlying.keysIterator)) }).asInstanceOf[S] - override def valueStepper[S <: Stepper[_]](implicit ss: StepperShape[V, S]) = (ss match { - case ss if ss.ref => new StepsAnyIterator (underlying.valuesIterator) + 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 => super.valueStepper(ss) + 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 index 4dc0eec..63505c8 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsRange.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsRange.scala @@ -1,6 +1,7 @@ package scala.compat.java8.converterImpl import language.implicitConversions +import scala.annotation.switch import scala.compat.java8.collectionImpl._ import scala.compat.java8.runtime._ @@ -39,16 +40,15 @@ extends StepsLongLikeIndexed[StepsLongNumericRange](_i0, _iN) { // Value class adapters // ////////////////////////// -final class RichRangeCanStep[T](private val underlying: Range) extends AnyVal with MakesParStepper[Int] { - override def stepper[S <: Stepper[_]](implicit ss: StepperShape[Int, S]) = +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 MakesParStepper[T] { - override def stepper[S <: Stepper[_]](implicit ss: StepperShape[T, S]) = (ss match { - case ss if ss.ref => new StepsAnyNumericRange[T](underlying, 0, underlying.length) +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 => super.stepper(ss) + 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 index 85e4706..c8c7ad6 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsString.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsString.scala @@ -45,8 +45,8 @@ private[java8] class StepperStringCodePoint(underlying: String, var i0: Int, var // Value class adapter // ///////////////////////// -final class RichStringCanStep(private val underlying: String) extends AnyVal with MakesParStepper[Char] { - override def stepper[S <: Stepper[_]](implicit ss: StepperShape[Char, S]) = charStepper.asInstanceOf[S with EfficientSubstep] +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 index 046a587..ad54503 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsVector.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsVector.scala @@ -1,6 +1,7 @@ package scala.compat.java8.converterImpl import language.implicitConversions +import scala.annotation.switch import scala.compat.java8.collectionImpl._ import scala.compat.java8.runtime._ @@ -134,12 +135,11 @@ with StepsVectorLike[Long] { // Value class adapters // ////////////////////////// -final class RichVectorCanStep[T](private val underlying: Vector[T]) extends AnyVal with MakesParStepper[T] { - override def stepper[S <: Stepper[_]](implicit ss: StepperShape[T, S]) = (ss match { - case ss if ss.ref => new StepsAnyVector[T](underlying, 0, underlying.length) +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 => super.stepper(ss) + case _ => ss.parUnbox(new StepsAnyVector[T](underlying, 0, underlying.length)) }).asInstanceOf[S with EfficientSubstep] }