Skip to content

Commit

Permalink
Fix scala-native#3307, scala-native#3315: javalib *Stream.iterate cha…
Browse files Browse the repository at this point in the history
…racteristics now match JVM (scala-native#3317)

* Fix scala-native#3307, scala-native#3315: javalib *Stream.iterate characteristics now match JVM

* Provide build-breaker & quality fixes to StreamTest*.scala

(cherry picked from commit 54a7fb8)
  • Loading branch information
LeeTibbert authored and WojciechMazur committed Sep 1, 2023
1 parent 6193eec commit 9ea95e2
Show file tree
Hide file tree
Showing 10 changed files with 318 additions and 99 deletions.
14 changes: 8 additions & 6 deletions javalib/src/main/scala/java/util/PrimitiveIterator.scala
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package java.util

import java.{lang => jl}

import java.util.function._

import Spliterator._

object PrimitiveIterator {
trait OfDouble extends PrimitiveIterator[Double, DoubleConsumer] {
override def forEachRemaining(action: Consumer[_ >: Double]): Unit = {
trait OfDouble extends PrimitiveIterator[jl.Double, DoubleConsumer] {
override def forEachRemaining(action: Consumer[_ >: jl.Double]): Unit = {
Objects.requireNonNull(action)

if (action.isInstanceOf[DoubleConsumer]) {
Expand Down Expand Up @@ -38,8 +40,8 @@ object PrimitiveIterator {
def nextDouble(): scala.Double // Abstract
}

trait OfInt extends PrimitiveIterator[Int, IntConsumer] {
override def forEachRemaining(action: Consumer[_ >: Int]): Unit = {
trait OfInt extends PrimitiveIterator[jl.Integer, IntConsumer] {
override def forEachRemaining(action: Consumer[_ >: jl.Integer]): Unit = {
Objects.requireNonNull(action)

if (action.isInstanceOf[IntConsumer]) {
Expand All @@ -64,8 +66,8 @@ object PrimitiveIterator {
def nextInt(): Int // Abstract
}

trait OfLong extends PrimitiveIterator[Long, LongConsumer] {
override def forEachRemaining(action: Consumer[_ >: Long]): Unit = {
trait OfLong extends PrimitiveIterator[jl.Long, LongConsumer] {
override def forEachRemaining(action: Consumer[_ >: jl.Long]): Unit = {
Objects.requireNonNull(action)
if (action.isInstanceOf[LongConsumer]) {
forEachRemaining(action.asInstanceOf[LongConsumer])
Expand Down
67 changes: 44 additions & 23 deletions javalib/src/main/scala/java/util/stream/DoubleStream.scala
Original file line number Diff line number Diff line change
@@ -1,17 +1,33 @@
package java.util.stream

import java.{lang => jl}

import java.util._
import java.util.function._

trait DoubleStream extends BaseStream[Double, DoubleStream] {
/* Design Note:
*
* DoubleStream extends BaseStream[jl.Double, DoubleStream]
* in correspondence to the documentation & usage of Spliterator.Of*
* and PrimitiveIterator.Of*. That is, the first type is a Java container.
*
* In this file "Double" types should be qualified to ease tracing the code
* and prevent confusion & defects.
* * jl.Double indicates an Java Object qua Scala AnyRef is desired.
* * scala.Double indicates a Java "double" primitive is desired.
* Someday, the generated code should be examined to ensure that
* unboxed primitives are actually being used.
*/

trait DoubleStream extends BaseStream[jl.Double, DoubleStream] {

def allMatch(pred: DoublePredicate): Boolean

def anyMatch(pred: DoublePredicate): Boolean

def average(): OptionalDouble

def boxed(): Stream[Double]
def boxed(): Stream[jl.Double]

def collect[R](
supplier: Supplier[R],
Expand Down Expand Up @@ -46,12 +62,12 @@ trait DoubleStream extends BaseStream[Double, DoubleStream] {

def tryAdvance(action: DoubleConsumer): Boolean = {
if (doneDropping) {
spliter.tryAdvance((e) => action.accept(e))
spliter.tryAdvance(e => action.accept(e))
} else {
var doneLooping = false
while (!doneLooping) {
val advanced =
spliter.tryAdvance((e) => {
spliter.tryAdvance(e => {
if (!pred.test(e)) {
action.accept(e)
doneDropping = true
Expand Down Expand Up @@ -108,7 +124,7 @@ trait DoubleStream extends BaseStream[Double, DoubleStream] {

val spliter = this.spliterator() // also marks this stream "operated upon"

val buffer = new ArrayDeque[Double]()
val buffer = new ArrayDeque[scala.Double]()

// Can not predict replacements, so Spliterator can not be SIZED.
// May need to adjust other characteristics.
Expand All @@ -125,9 +141,7 @@ trait DoubleStream extends BaseStream[Double, DoubleStream] {
while (!done) {
if (buffer.size() == 0) {
val stepped =
spliter.tryAdvance((e: Double) =>
mapper.accept(e, r => buffer.add(r))
)
spliter.tryAdvance(e => mapper.accept(e, r => buffer.add(r)))
done = !stepped
} else {
action.accept(buffer.removeFirst())
Expand Down Expand Up @@ -161,15 +175,15 @@ trait DoubleStream extends BaseStream[Double, DoubleStream] {

def peek(action: DoubleConsumer): DoubleStream

def reduce(identity: Double, op: DoubleBinaryOperator): Double
def reduce(identity: scala.Double, op: DoubleBinaryOperator): Double

def reduce(op: DoubleBinaryOperator): OptionalDouble

def skip(n: Long): DoubleStream

def sorted(): DoubleStream

def sum(): Double
def sum(): scala.Double

def summaryStatistics(): DoubleSummaryStatistics

Expand All @@ -196,7 +210,7 @@ trait DoubleStream extends BaseStream[Double, DoubleStream] {
def tryAdvance(action: DoubleConsumer): Boolean = {
if (done) false
else
spliter.tryAdvance((e) =>
spliter.tryAdvance(e =>
if (!pred.test(e)) done = true
else action.accept(e)
)
Expand All @@ -206,7 +220,7 @@ trait DoubleStream extends BaseStream[Double, DoubleStream] {
new DoubleStreamImpl(spl, parallel = false, parent = this)
}

def toArray(): Array[Double]
def toArray(): Array[scala.Double]

}

Expand All @@ -223,7 +237,7 @@ object DoubleStream {

@FunctionalInterface
trait DoubleMapMultiConsumer {
def accept(value: Double, dc: DoubleConsumer): Unit
def accept(value: scala.Double, dc: DoubleConsumer): Unit
}

def builder(): DoubleStream.Builder =
Expand Down Expand Up @@ -252,16 +266,19 @@ object DoubleStream {

// Since: Java 9
def iterate(
seed: Double,
seed: scala.Double,
hasNext: DoublePredicate,
next: DoubleUnaryOperator
): DoubleStream = {
// "seed" on RHS here is to keep compiler happy with local var init
// "seed" on RHS here is to keep compiler happy with local var initialize.
var previous = seed
var seedUsed = false

val spliter =
new Spliterators.AbstractDoubleSpliterator(Long.MaxValue, 0) {
new Spliterators.AbstractDoubleSpliterator(
Long.MaxValue,
Spliterator.ORDERED | Spliterator.IMMUTABLE | Spliterator.NONNULL
) {
def tryAdvance(action: DoubleConsumer): Boolean = {
val current =
if (seedUsed) next.applyAsDouble(previous)
Expand All @@ -283,14 +300,18 @@ object DoubleStream {
}

def iterate(
seed: Double,
seed: scala.Double,
f: DoubleUnaryOperator
): DoubleStream = {
var previous = seed // "seed" here is just to keep compiler happy.
// "seed" on RHS here is to keep compiler happy with local var initialize.
var previous = seed
var seedUsed = false

val spliter =
new Spliterators.AbstractDoubleSpliterator(Long.MaxValue, 0) {
new Spliterators.AbstractDoubleSpliterator(
Long.MaxValue,
Spliterator.ORDERED | Spliterator.IMMUTABLE | Spliterator.NONNULL
) {
def tryAdvance(action: DoubleConsumer): Boolean = {
val current =
if (seedUsed) f.applyAsDouble(previous)
Expand All @@ -308,7 +329,10 @@ object DoubleStream {
new DoubleStreamImpl(spliter, parallel = false)
}

def of(values: Array[Double]): DoubleStream = {
def of(t: scala.Double): DoubleStream =
DoubleStream.builder().add(t).build()

def of(values: Array[scala.Double]): DoubleStream = {
/* One would expect variables arguments to be declared as
* "values: Objects*" here.
* However, that causes "symbol not found" errors at OS link time.
Expand All @@ -322,7 +346,4 @@ object DoubleStream {
bldr.build()
}

def of(t: Double): DoubleStream =
DoubleStream.builder().add(t).build()

}

0 comments on commit 9ea95e2

Please sign in to comment.