Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions library/src/scala/jdk/Accumulator.scala
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ import scala.language.implicitConversions
* [[DoubleAccumulator]].
*
* @tparam CC the covariant higher-kinded type constructor for the specific accumulator collection, constrained to `mutable.Seq`
*
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we do not need the extra line here.

* @tparam C the concrete result type of this accumulator's builder, constrained to `mutable.Seq[A]`
*/
abstract class Accumulator[@specialized(Double, Int, Long) A, +CC[X] <: mutable.Seq[X], +C <: mutable.Seq[A]]
extends mutable.Seq[A]
Expand Down Expand Up @@ -98,6 +100,7 @@ abstract class Accumulator[@specialized(Double, Int, Long) A, +CC[X] <: mutable.
* allocated with 1 extra slot. So `history(0)` has 17 slots of which the first 15 store elements.
*
* @param i the index into the `history` array, where `0 <= i < `hIndex``
* @return the total number of elements stored in `history(0)` through `history(i)`, inclusive
*/
private[jdk] def cumulative(i: Int): Long

Expand Down Expand Up @@ -185,6 +188,7 @@ object Accumulator {
* @tparam A the type of the ${coll}'s elements
* @tparam C the (inferred) specific type of the $coll
* @param canAccumulate the implicit factory shape that determines the specific accumulator type to build
* @return an empty $coll of the type selected by `canAccumulate`
*/
def empty[A, C](implicit canAccumulate: AccumulatorFactoryShape[A, C]): C =
canAccumulate.empty
Expand Down Expand Up @@ -222,6 +226,7 @@ object Accumulator {
* @param init State initial value
* @param f Computes the next element (or returns `None` to signal
* the end of the collection)
* @param canAccumulate the implicit factory shape that determines the specific accumulator type to build
* @return an $coll that produces elements using `f` until `f` returns `None`
*/
def unfold[A, S, C](init: S)(f: S => Option[(A, S)])(implicit canAccumulate: AccumulatorFactoryShape[A, C]): C =
Expand Down Expand Up @@ -350,6 +355,7 @@ object Accumulator {
* @param n1 the number of elements in the 1st dimension
* @param n2 the number of elements in the 2nd dimension
* @param f The function computing element values
* @param canAccumulate the implicit factory shape that determines the specific accumulator type to build
* @return An $coll consisting of elements `f(i1, i2)`
* for `0 <= i1 < n1` and `0 <= i2 < n2`.
*/
Expand All @@ -364,6 +370,7 @@ object Accumulator {
* @param n2 the number of elements in the 2nd dimension
* @param n3 the number of elements in the 3rd dimension
* @param f The function computing element values
* @param canAccumulate the implicit factory shape that determines the specific accumulator type to build
* @return An $coll consisting of elements `f(i1, i2, i3)`
* for `0 <= i1 < n1`, `0 <= i2 < n2`, and `0 <= i3 < n3`.
*/
Expand All @@ -379,6 +386,7 @@ object Accumulator {
* @param n3 the number of elements in the 3rd dimension
* @param n4 the number of elements in the 4th dimension
* @param f The function computing element values
* @param canAccumulate the implicit factory shape that determines the specific accumulator type to build
* @return An $coll consisting of elements `f(i1, i2, i3, i4)`
* for `0 <= i1 < n1`, `0 <= i2 < n2`, `0 <= i3 < n3`, and `0 <= i4 < n4`.
*/
Expand All @@ -395,6 +403,7 @@ object Accumulator {
* @param n4 the number of elements in the 4th dimension
* @param n5 the number of elements in the 5th dimension
* @param f The function computing element values
* @param canAccumulate the implicit factory shape that determines the specific accumulator type to build
* @return An $coll consisting of elements `f(i1, i2, i3, i4, i5)`
* for `0 <= i1 < n1`, `0 <= i2 < n2`, `0 <= i3 < n3`, `0 <= i4 < n4`, and `0 <= i5 < n5`.
*/
Expand Down
12 changes: 11 additions & 1 deletion library/src/scala/jdk/AnyAccumulator.scala
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ final class AnyAccumulator[A]
/** Appends an element to this `AnyAccumulator`.
*
* @param a the element to append
* @return this `AnyAccumulator`, to allow chaining of `addOne` calls
*/
def addOne(a: A): this.type = {
totalSize += 1
Expand Down Expand Up @@ -139,7 +140,8 @@ final class AnyAccumulator[A]

/** Retrieves the `ix`th element.
*
* @param ix the zero-based index of the element to retrieve, as a `Long`
* @param ix the zero-based index of the element to retrieve
* @return the element at position `ix`
*/
def apply(ix: Long): A = {
if (totalSize - ix <= index || hIndex == 0) current((ix - (totalSize - index)).toInt).asInstanceOf[A]
Expand All @@ -152,6 +154,7 @@ final class AnyAccumulator[A]
/** Retrieves the `ix`th element, using an `Int` index.
*
* @param i the zero-based index of the element to retrieve
* @return the element at position `i`
*/
def apply(i: Int): A = apply(i.toLong)

Expand Down Expand Up @@ -179,6 +182,8 @@ final class AnyAccumulator[A]
/** Copies the elements in this `AnyAccumulator` into an `Array`.
*
* @tparam B the element type of the resulting array, must be a supertype of `A`
* @return a new array containing all elements of this `AnyAccumulator` in order
* @throws IllegalArgumentException if the total size exceeds `Int.MaxValue`
*/
override def toArray[B >: A : ClassTag]: Array[B] = {
if (totalSize > Int.MaxValue) throw new IllegalArgumentException("Too many elements accumulated for an array: "+totalSize.toString)
Expand Down Expand Up @@ -233,6 +238,8 @@ final class AnyAccumulator[A]
*
* @tparam C1 the type of the resulting collection
* @param factory the factory used to build the target collection
* @return a collection of type `C1` containing all elements of this `AnyAccumulator`
* @throws IllegalArgumentException if the total size exceeds `Int.MaxValue`
*/
override def to[C1](factory: Factory[A, C1]): C1 = {
if (totalSize > Int.MaxValue) throw new IllegalArgumentException("Too many elements accumulated for a Scala collection: "+totalSize.toString)
Expand All @@ -254,12 +261,14 @@ object AnyAccumulator extends collection.SeqFactory[AnyAccumulator] {
/** A `Supplier` of `AnyAccumulator`s, suitable for use with `java.util.stream.Stream`'s `collect` method.
*
* @tparam A the element type of the accumulator to supply
* @return a `Supplier` that creates a new empty `AnyAccumulator[A]` on each invocation
*/
def supplier[A]: jf.Supplier[AnyAccumulator[A]] = () => new AnyAccumulator[A]

/** A `BiConsumer` that adds an element to an `AnyAccumulator`, suitable for use with `java.util.stream.Stream`'s `collect` method.
*
* @tparam A the element type to add to the accumulator
* @return a `BiConsumer` that appends its second argument to the `AnyAccumulator` given as its first argument
*/
def adder[A]: jf.BiConsumer[AnyAccumulator[A], A] = (ac: AnyAccumulator[A], a: A) => ac addOne a

Expand All @@ -275,6 +284,7 @@ object AnyAccumulator extends collection.SeqFactory[AnyAccumulator] {
/** A `BiConsumer` that merges `AnyAccumulator`s, suitable for use with `java.util.stream.Stream`'s `collect` method.
*
* @tparam A the element type of the accumulators to merge
* @return a `BiConsumer` that drains the elements of the second `AnyAccumulator` into the first, leaving the second empty
*/
def merger[A]: jf.BiConsumer[AnyAccumulator[A], AnyAccumulator[A]] = (a1: AnyAccumulator[A], a2: AnyAccumulator[A]) => a1 drain a2

Expand Down
4 changes: 4 additions & 0 deletions library/src/scala/jdk/DoubleAccumulator.scala
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ final class DoubleAccumulator
/** Appends an element to this `DoubleAccumulator`.
*
* @param a the `Double` value to append
* @return this `DoubleAccumulator` (to allow chaining of operations)
*/
def addOne(a: Double): this.type = {
totalSize += 1
Expand Down Expand Up @@ -146,6 +147,7 @@ final class DoubleAccumulator
/** Retrieves the `ix`th element.
*
* @param ix the zero-based index of the element to retrieve
* @return the `Double` value stored at position `ix`
*/
def apply(ix: Long): Double = {
if (totalSize - ix <= index || hIndex == 0) current((ix - (totalSize - index)).toInt)
Expand All @@ -158,6 +160,7 @@ final class DoubleAccumulator
/** Retrieves the `ix`th element, using an `Int` index.
*
* @param i the zero-based index of the element to retrieve (converted to `Long` internally)
* @return the `Double` value stored at position `i`
*/
def apply(i: Int): Double = apply(i.toLong)

Expand Down Expand Up @@ -298,6 +301,7 @@ final class DoubleAccumulator
*
* @tparam C1 the result type of the target collection (e.g., `Vector[Double]`)
* @param factory the factory for creating the target collection from elements
* @return a new collection of type `C1` containing all elements of this `DoubleAccumulator`
*/
override def to[C1](factory: Factory[Double, C1]): C1 = {
if (totalSize > Int.MaxValue) throw new IllegalArgumentException("Too many elements accumulated for a Scala collection: "+totalSize.toString)
Expand Down
4 changes: 4 additions & 0 deletions library/src/scala/jdk/IntAccumulator.scala
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ final class IntAccumulator
/** Appends an element to this `IntAccumulator`.
*
* @param a the `Int` value to append
* @return this `IntAccumulator` with the element appended
*/
def addOne(a: Int): this.type = {
totalSize += 1
Expand Down Expand Up @@ -152,6 +153,7 @@ final class IntAccumulator
/** Retrieves the `ix`th element.
*
* @param ix the zero-based index of the element to retrieve, as a `Long`
* @return the `Int` element at index `ix`
*/
def apply(ix: Long): Int = {
if (totalSize - ix <= index || hIndex == 0) current((ix - (totalSize - index)).toInt)
Expand All @@ -164,6 +166,7 @@ final class IntAccumulator
/** Retrieves the `ix`th element, using an `Int` index.
*
* @param i the zero-based index of the element to retrieve
* @return the `Int` element at index `i`
*/
def apply(i: Int): Int = apply(i.toLong)

Expand Down Expand Up @@ -304,6 +307,7 @@ final class IntAccumulator
*
* @tparam C1 the type of the target collection
* @param factory the factory for building the target collection from `Int` elements
* @return a collection of type `C1` containing all elements of this `IntAccumulator`
*/
override def to[C1](factory: Factory[Int, C1]): C1 = {
if (totalSize > Int.MaxValue) throw new IllegalArgumentException("Too many elements accumulated for a Scala collection: "+totalSize.toString)
Expand Down
4 changes: 4 additions & 0 deletions library/src/scala/jdk/LongAccumulator.scala
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ final class LongAccumulator
/** Appends an element to this `LongAccumulator`.
*
* @param a the `Long` value to append
* @return this `LongAccumulator` with the element appended
*/
def addOne(a: Long): this.type = {
totalSize += 1
Expand Down Expand Up @@ -147,6 +148,7 @@ final class LongAccumulator
/** Retrieves the `ix`th element.
*
* @param ix the zero-based index of the element to retrieve
* @return the `Long` element stored at position `ix`
*/
def apply(ix: Long): Long = {
if (totalSize - ix <= index || hIndex == 0) current((ix - (totalSize - index)).toInt)
Expand All @@ -159,6 +161,7 @@ final class LongAccumulator
/** Retrieves the `ix`th element, using an `Int` index.
*
* @param i the zero-based index of the element to retrieve
* @return the `Long` element stored at position `i`
*/
def apply(i: Int): Long = apply(i.toLong)

Expand Down Expand Up @@ -299,6 +302,7 @@ final class LongAccumulator
*
* @tparam C1 the result type of the target collection
* @param factory the factory for the target collection type
* @return a collection of type `C1` containing all elements of this `LongAccumulator`
*/
override def to[C1](factory: Factory[Long, C1]): C1 = {
if (totalSize > Int.MaxValue) throw new IllegalArgumentException("Too many elements accumulated for a Scala collection: "+totalSize.toString)
Expand Down
2 changes: 2 additions & 0 deletions library/src/scala/jdk/OptionConverters.scala
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ object OptionConverters {
*
* @tparam O the target specialized Java `Optional` type, inferred from the available `OptionShape` instance (e.g., `OptionalInt`, `OptionalDouble`, `OptionalLong`)
* @param shape implicit evidence that defines how to convert between `Optional[A]` and the specialized type `O`
* @return the specialized Java `Optional` variant containing the same value as `o`, or an empty variant if `o` is empty
*/
def toJavaPrimitive[O](implicit shape: OptionShape[A, O]): O = shape.fromJava(o)
}
Expand All @@ -83,6 +84,7 @@ object OptionConverters {
*
* @tparam O the specialized Java `Optional` type (e.g., `OptionalInt`, `OptionalDouble`, `OptionalLong`)
* @param shape implicit evidence that defines how to convert between `Option[A]` and the specialized type `O`
* @return the specialized Java `Optional` variant containing the value of `o`, or an empty variant if `o` is `None`
*/
def toJavaPrimitive[O](implicit shape: OptionShape[A, O]): O = shape.fromScala(o)
}
Expand Down
2 changes: 2 additions & 0 deletions library/src/scala/jdk/OptionShape.scala
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,13 @@ sealed abstract class OptionShape[A, O] {
/** Converts from `Optional` to the specialized variant `O`.
*
* @param o the generic `Optional` to convert to the specialized variant
* @return the specialized `Optional` containing the value of `o` if present, otherwise an empty specialized `Optional`
*/
def fromJava(o: Optional[A]): O
/** Converts from `Option` to the specialized variant `O`.
*
* @param o the Scala `Option` to convert to the specialized Java variant
* @return the specialized `Optional` containing the value of `o` if defined, otherwise an empty specialized `Optional`
*/
def fromScala(o: Option[A]): O
}
Expand Down
Loading
Loading