From c6ec67a32aa5ce3f85188dae556dc26bcf4970dc Mon Sep 17 00:00:00 2001 From: Rex Kerr Date: Sat, 28 Jul 2018 15:14:41 -0700 Subject: [PATCH 01/13] Fixed NPE in VectorStepper due to dirty display vector. (Could occur with structurally shared vectors.) --- .../java8/runtime/CollectionInternals.java | 7 +++ .../converterImpl/StepsLikeIndexed.scala | 3 + .../java8/converterImpl/StepsVector.scala | 58 +++++++++++++++++-- .../compat/java8/StreamConvertersTest.scala | 28 +++++++++ 4 files changed, 90 insertions(+), 6 deletions(-) diff --git a/src/main/java/scala/compat/java8/runtime/CollectionInternals.java b/src/main/java/scala/compat/java8/runtime/CollectionInternals.java index 6f8da89..901a3d5 100644 --- a/src/main/java/scala/compat/java8/runtime/CollectionInternals.java +++ b/src/main/java/scala/compat/java8/runtime/CollectionInternals.java @@ -5,12 +5,19 @@ public class CollectionInternals { public static Object[] getTable(scala.collection.mutable.FlatHashTable fht) { return fht.hashTableContents().table(); } public static > scala.collection.mutable.HashEntry[] getTable(scala.collection.mutable.HashTable ht) { return ht.hashTableContents().table(); } + public static boolean getDirt(scala.collection.immutable.Vector v) { return v.dirty(); } public static Object[] getDisplay0(scala.collection.immutable.Vector v) { return v.display0(); } + public static Object[] getDisplay0(scala.collection.immutable.VectorIterator p) { return p.display0(); } public static Object[] getDisplay1(scala.collection.immutable.Vector v) { return v.display1(); } + public static Object[] getDisplay1(scala.collection.immutable.VectorIterator p) { return p.display1(); } public static Object[] getDisplay2(scala.collection.immutable.Vector v) { return v.display2(); } + public static Object[] getDisplay2(scala.collection.immutable.VectorIterator p) { return p.display2(); } public static Object[] getDisplay3(scala.collection.immutable.Vector v) { return v.display3(); } + public static Object[] getDisplay3(scala.collection.immutable.VectorIterator p) { return p.display3(); } public static Object[] getDisplay4(scala.collection.immutable.Vector v) { return v.display4(); } + public static Object[] getDisplay4(scala.collection.immutable.VectorIterator p) { return p.display4(); } public static Object[] getDisplay5(scala.collection.immutable.Vector v) { return v.display5(); } + public static Object[] getDisplay5(scala.collection.immutable.VectorIterator p) { return p.display5(); } public static scala.Tuple2< scala.Tuple2< scala.collection.Iterator, Object >, scala.collection.Iterator > trieIteratorSplit(scala.collection.Iterator it) { if (it instanceof scala.collection.immutable.TrieIterator) { scala.collection.immutable.TrieIterator trie = (scala.collection.immutable.TrieIterator)it; diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeIndexed.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeIndexed.scala index ed5abfa..8e3d312 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeIndexed.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeIndexed.scala @@ -32,16 +32,19 @@ private[java8] abstract class StepsLikeIndexed[A, STA >: Null <: StepsLikeIndexe private[java8] abstract class StepsDoubleLikeIndexed[STD >: Null <: StepsDoubleLikeIndexed[_]](_i0: Int, _iN: Int) extends AbstractStepsLikeIndexed[DoubleStepper, STD](_i0, _iN) with DoubleStepper + with java.util.Spliterator.OfDouble // Compiler wants this for mixin forwarder {} /** Abstracts the operation of stepping over an indexable collection of Ints */ private[java8] abstract class StepsIntLikeIndexed[STI >: Null <: StepsIntLikeIndexed[_]](_i0: Int, _iN: Int) extends AbstractStepsLikeIndexed[IntStepper, STI](_i0, _iN) with IntStepper + with java.util.Spliterator.OfInt // Compiler wants this for mixin forwarder {} /** Abstracts the operation of stepping over an indexable collection of Longs */ private[java8] abstract class StepsLongLikeIndexed[STL >: Null <: StepsLongLikeIndexed[_]](_i0: Int, _iN: Int) extends AbstractStepsLikeIndexed[LongStepper, STL](_i0, _iN) with LongStepper + with java.util.Spliterator.OfLong // Compiler wants this for mixin forwarder {} diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsVector.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsVector.scala index b0abe26..11fe5ec 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsVector.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsVector.scala @@ -2,6 +2,8 @@ package scala.compat.java8.converterImpl import scala.annotation.switch +import scala.collection.immutable.VectorIterator + import scala.compat.java8.collectionImpl._ import scala.compat.java8.runtime._ @@ -13,20 +15,27 @@ import Stepper._ private[java8] trait StepsVectorLike[A] { protected def myVector: Vector[A] + protected def myVectorIterator: VectorIterator[A] + protected def myVectorLength: Int protected var index: Int = 32 protected var data: Array[AnyRef] = null protected var index1: Int = 32 protected var data1: Array[AnyRef] = null protected final def advanceData(iX: Int): Unit = { index1 += 1 - if (index >= 32) initTo(iX) + if (index >= 32) { + if (myVector != null) initTo(iX) + else initVpTo(iX) + } else { data = data1(index1).asInstanceOf[Array[AnyRef]] index = 0 } } protected final def initTo(iX: Int): Unit = { - myVector.length match { + // WARNING--initVpTo is an exact copy of this except for the type! If you change one you must change the other! + // (Manually specialized this way for speed.) + myVectorLength match { case x if x <= 0x20 => index = iX data = CollectionInternals.getDisplay0(myVector) @@ -52,12 +61,43 @@ private[java8] trait StepsVectorLike[A] { data = data1(index1).asInstanceOf[Array[AnyRef]] } } + protected final def initVpTo(iX: Int): Unit = { + // WARNING--this is an exact copy of initTo! If you change one you must change the other! + // (Manually specialized this way for speed.) + myVectorLength match { + case x if x <= 0x20 => + index = iX + data = CollectionInternals.getDisplay0(myVectorIterator) + case x if x <= 0x400 => + index1 = iX >>> 5 + data1 = CollectionInternals.getDisplay1(myVectorIterator) + index = iX & 0x1F + data = data1(index1).asInstanceOf[Array[AnyRef]] + case x => + var N = 0 + var dataN: Array[AnyRef] = + if (x <= 0x8000) { N = 2; CollectionInternals.getDisplay2(myVectorIterator) } + else if (x <= 0x100000) { N = 3; CollectionInternals.getDisplay3(myVectorIterator) } + else if (x <= 0x2000000) { N = 4; CollectionInternals.getDisplay4(myVectorIterator) } + else /*x <= 0x40000000*/{ N = 5; CollectionInternals.getDisplay5(myVectorIterator) } + while (N > 2) { + dataN = dataN((iX >>> (5*N))&0x1F).asInstanceOf[Array[AnyRef]] + N -= 1 + } + index1 = (iX >>> 5) & 0x1F + data1 = dataN((iX >>> 10) & 0x1F).asInstanceOf[Array[AnyRef]] + index = iX & 0x1F + data = data1(index1).asInstanceOf[Array[AnyRef]] + } + } } private[java8] class StepsAnyVector[A](underlying: Vector[A], _i0: Int, _iN: Int) extends StepsLikeIndexed[A, StepsAnyVector[A]](_i0, _iN) with StepsVectorLike[A] { - protected def myVector = underlying + protected val myVector = if (CollectionInternals.getDirt(underlying)) null else underlying + protected val myVectorIterator = if (myVector == null) underlying.iterator else null + protected val myVectorLength = underlying.length def next() = if (hasNext()) { index += 1 if (index >= 32) advanceData(i0) @@ -76,7 +116,9 @@ with StepsVectorLike[A] { private[java8] class StepsDoubleVector(underlying: Vector[Double], _i0: Int, _iN: Int) extends StepsDoubleLikeIndexed[StepsDoubleVector](_i0, _iN) with StepsVectorLike[Double] { - protected def myVector = underlying + protected val myVector = if (CollectionInternals.getDirt(underlying)) null else underlying + protected val myVectorIterator = if (myVector == null) underlying.iterator else null + protected val myVectorLength = underlying.length def nextDouble() = if (hasNext()) { index += 1 if (index >= 32) advanceData(i0) @@ -95,7 +137,9 @@ with StepsVectorLike[Double] { private[java8] class StepsIntVector(underlying: Vector[Int], _i0: Int, _iN: Int) extends StepsIntLikeIndexed[StepsIntVector](_i0, _iN) with StepsVectorLike[Int] { - protected def myVector = underlying + protected val myVector = if (CollectionInternals.getDirt(underlying)) null else underlying + protected val myVectorIterator = if (myVector == null) underlying.iterator else null + protected val myVectorLength = underlying.length def nextInt() = if (hasNext()) { index += 1 if (index >= 32) advanceData(i0) @@ -114,7 +158,9 @@ with StepsVectorLike[Int] { private[java8] class StepsLongVector(underlying: Vector[Long], _i0: Int, _iN: Int) extends StepsLongLikeIndexed[StepsLongVector](_i0, _iN) with StepsVectorLike[Long] { - protected def myVector = underlying + protected val myVector = if (CollectionInternals.getDirt(underlying)) null else underlying + protected val myVectorIterator = if (myVector == null) underlying.iterator else null + protected val myVectorLength = underlying.length def nextLong() = if (hasNext()) { index += 1 if (index >= 32) advanceData(i0) diff --git a/src/test/scala/scala/compat/java8/StreamConvertersTest.scala b/src/test/scala/scala/compat/java8/StreamConvertersTest.scala index fbecae5..10a3f08 100644 --- a/src/test/scala/scala/compat/java8/StreamConvertersTest.scala +++ b/src/test/scala/scala/compat/java8/StreamConvertersTest.scala @@ -276,4 +276,32 @@ class StreamConvertersTest { val stepper2 = steppize2(coll2).stepper assertTrue(stepper2.getClass.getName.contains("StepsIntVector")) } + + @Test + def issue_87(): Unit = { + // Vectors that are generated from other vectors tend _not_ to + // have all their display vectors consistent; the cached vectors + // are correct, but the higher-level vector does _not_ contain + // the cached vector in the correct place (for efficiency)! This + // is called being "dirty", and needs to be handled specially. + val dirtyDisplayVector = Vector.fill(120)("a").slice(0, 40) + val shouldNotNPE = + dirtyDisplayVector.seqStream.collect(Collectors.toList()) + assertEq(shouldNotNPE.toArray(new Array[String](0)).toVector, dirtyDisplayVector, "Vector[Any].seqStream (with dirty display)") + + val dirtyDisplayVectorInt = Vector.fill(120)(999).slice(0, 40) + val shouldNotNPEInt = + dirtyDisplayVectorInt.seqStream.sum() + assertEq(shouldNotNPEInt, dirtyDisplayVectorInt.sum, "Vector[Int].seqStream (with dirty display)") + + val dirtyDisplayVectorLong = Vector.fill(120)(99999999999L).slice(0, 40) + val shouldNotNPELong = + dirtyDisplayVectorLong.seqStream.sum() + assertEq(shouldNotNPELong, dirtyDisplayVectorLong.sum, "Vector[Long].seqStream (with dirty display)") + + val dirtyDisplayVectorDouble = Vector.fill(120)(0.1).slice(0, 40) + val shouldNotNPEDouble = + math.rint(dirtyDisplayVectorDouble.seqStream.sum() * 10) + assertEq(shouldNotNPEDouble, math.rint(dirtyDisplayVectorDouble.sum * 10), "Vector[Double].seqStream (with dirty display)") + } } From 52403642a270eb2902d668dea4af4f9fd32f695d Mon Sep 17 00:00:00 2001 From: Philippus Date: Sat, 16 Feb 2019 11:36:00 +0100 Subject: [PATCH 02/13] Relicense under Apache 2, closes #128 --- LICENSE | 229 +++++++++++++++--- benchmark/src/main/scala/bench/CodeGen.scala | 12 + .../main/scala/bench/CollectionSource.scala | 12 + .../src/main/scala/bench/Operations.scala | 12 + .../src/main/scala/bench/ParseJmhLog.scala | 12 + build.sbt | 4 + fnGen/WrapFnGen.scala | 10 +- project/CodeGen.scala | 10 +- .../compat/java8/ScalaStreamSupport.java | 12 + .../java8/runtime/CollectionInternals.java | 12 + .../java8/runtime/LambdaDeserializer.scala | 12 + .../IteratorPrimitiveDoubleWrapper.java | 11 +- .../wrappers/IteratorPrimitiveIntWrapper.java | 11 +- .../IteratorPrimitiveLongWrapper.java | 11 +- .../compat/java8/DurationConverters.scala | 11 +- .../scala/compat/java8/FutureConverters.scala | 11 +- .../scala/compat/java8/OptionConverters.scala | 11 +- .../java8/PrimitiveIteratorConversions.scala | 11 +- .../compat/java8/SpliteratorConverters.scala | 12 + .../scala/compat/java8/StreamConverters.scala | 12 + .../scala/compat/java8/WrapperTraits.scala | 12 + .../java8/collectionImpl/Accumulator.scala | 12 + .../collectionImpl/AccumulatorLike.scala | 12 + .../collectionImpl/DoubleAccumulator.scala | 12 + .../java8/collectionImpl/IntAccumulator.scala | 12 + .../collectionImpl/LongAccumulator.scala | 12 + .../compat/java8/collectionImpl/Stepper.scala | 12 + .../java8/converterImpl/Accumulates.scala | 12 + .../converterImpl/AccumulatorConverters.scala | 12 + .../java8/converterImpl/MakesSteppers.scala | 12 + .../java8/converterImpl/StepConverters.scala | 12 + .../java8/converterImpl/StepsArray.scala | 12 + .../java8/converterImpl/StepsBitSet.scala | 12 + .../converterImpl/StepsFlatHashTable.scala | 12 + .../java8/converterImpl/StepsHashTable.scala | 12 + .../java8/converterImpl/StepsImmHashMap.scala | 12 + .../java8/converterImpl/StepsImmHashSet.scala | 12 + .../java8/converterImpl/StepsIndexedSeq.scala | 12 + .../java8/converterImpl/StepsIterable.scala | 12 + .../java8/converterImpl/StepsIterator.scala | 12 + .../java8/converterImpl/StepsLikeGapped.scala | 12 + .../converterImpl/StepsLikeImmHashMap.scala | 12 + .../converterImpl/StepsLikeIndexed.scala | 12 + .../converterImpl/StepsLikeIterator.scala | 12 + .../java8/converterImpl/StepsLikeSliced.scala | 12 + .../converterImpl/StepsLikeTrieIterator.scala | 12 + .../java8/converterImpl/StepsLinearSeq.scala | 12 + .../compat/java8/converterImpl/StepsMap.scala | 12 + .../java8/converterImpl/StepsRange.scala | 12 + .../java8/converterImpl/StepsString.scala | 12 + .../java8/converterImpl/StepsVector.scala | 12 + .../java8/converterImpl/StepsWithTail.scala | 12 + .../java8/FutureConvertersImpl.scala | 11 +- .../java/scala/compat/java8/BoxingTest.java | 11 +- .../java8/DurationConvertersJavaTest.java | 11 +- .../compat/java8/FutureConvertersTest.java | 11 +- .../java/scala/compat/java8/LambdaTest.java | 11 +- .../compat/java8/OptionConvertersTest.scala | 11 +- .../scala/compat/java8/SpecializedTest.scala | 11 +- .../compat/java8/SpecializedTestSupport.java | 11 +- .../java8/StreamConvertersExampleTest.java | 10 +- .../java8/runtime/LambdaDeserializerTest.java | 12 + .../compat/java8/DurationConvertersTest.scala | 11 +- .../compat/java8/FunctionConvertersTest.scala | 12 + .../compat/java8/StepConvertersTest.scala | 12 + .../scala/compat/java8/StepperTest.scala | 12 + .../compat/java8/StreamConvertersTest.scala | 12 + 67 files changed, 944 insertions(+), 47 deletions(-) diff --git a/LICENSE b/LICENSE index d536dec..f49a4e1 100644 --- a/LICENSE +++ b/LICENSE @@ -1,28 +1,201 @@ -Copyright (c) 2002-2018 EPFL -Copyright (c) 2011-2018 Lightbend, Inc. - -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of the EPFL nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/benchmark/src/main/scala/bench/CodeGen.scala b/benchmark/src/main/scala/bench/CodeGen.scala index 58976f6..53ede95 100644 --- a/benchmark/src/main/scala/bench/CodeGen.scala +++ b/benchmark/src/main/scala/bench/CodeGen.scala @@ -1,3 +1,15 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package bench.codegen import scala.util._ diff --git a/benchmark/src/main/scala/bench/CollectionSource.scala b/benchmark/src/main/scala/bench/CollectionSource.scala index 2713543..07d021d 100644 --- a/benchmark/src/main/scala/bench/CollectionSource.scala +++ b/benchmark/src/main/scala/bench/CollectionSource.scala @@ -1,3 +1,15 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package bench import java.util.stream._ diff --git a/benchmark/src/main/scala/bench/Operations.scala b/benchmark/src/main/scala/bench/Operations.scala index 0b795db..0a13126 100644 --- a/benchmark/src/main/scala/bench/Operations.scala +++ b/benchmark/src/main/scala/bench/Operations.scala @@ -1,3 +1,15 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package bench.operate import java.util.stream._ diff --git a/benchmark/src/main/scala/bench/ParseJmhLog.scala b/benchmark/src/main/scala/bench/ParseJmhLog.scala index 90cc9d3..0263c45 100644 --- a/benchmark/src/main/scala/bench/ParseJmhLog.scala +++ b/benchmark/src/main/scala/bench/ParseJmhLog.scala @@ -1,3 +1,15 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package bench.examine import scala.util._ diff --git a/build.sbt b/build.sbt index 6d3bb3d..10f155c 100644 --- a/build.sbt +++ b/build.sbt @@ -24,6 +24,10 @@ def osgiExport(scalaVersion: String, version: String) = { lazy val commonSettings = Seq( organization := "org.scala-lang.modules", version := "0.9.1-SNAPSHOT", + + // this line could be removed after https://github.com/scala/sbt-scala-module/issues/48 is fixed + licenses := Seq(("Apache-2.0", url("https://www.apache.org/licenses/LICENSE-2.0"))), + scalacOptions ++= Seq("-feature", "-deprecation", "-unchecked") ) diff --git a/fnGen/WrapFnGen.scala b/fnGen/WrapFnGen.scala index f3d959a..b46dcce 100644 --- a/fnGen/WrapFnGen.scala +++ b/fnGen/WrapFnGen.scala @@ -1,5 +1,13 @@ /* - * Copyright (C) 2015-2016 Lightbend Inc. + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. */ object WrapFnGen { diff --git a/project/CodeGen.scala b/project/CodeGen.scala index 250637a..4289973 100644 --- a/project/CodeGen.scala +++ b/project/CodeGen.scala @@ -1,5 +1,13 @@ /* - * Copyright (C) 2012-2016 Lightbend Inc. + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. */ sealed abstract class Type(val code: Char, val prim: String, val ref: String) { diff --git a/src/main/java/scala/compat/java8/ScalaStreamSupport.java b/src/main/java/scala/compat/java8/ScalaStreamSupport.java index b0d3452..bc21ca8 100644 --- a/src/main/java/scala/compat/java8/ScalaStreamSupport.java +++ b/src/main/java/scala/compat/java8/ScalaStreamSupport.java @@ -1,3 +1,15 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.compat.java8; import scala.compat.java8.converterImpl.*; diff --git a/src/main/java/scala/compat/java8/runtime/CollectionInternals.java b/src/main/java/scala/compat/java8/runtime/CollectionInternals.java index 6f8da89..1044ec5 100644 --- a/src/main/java/scala/compat/java8/runtime/CollectionInternals.java +++ b/src/main/java/scala/compat/java8/runtime/CollectionInternals.java @@ -1,3 +1,15 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.compat.java8.runtime; // No imports! All type names are fully qualified to avoid confusion! diff --git a/src/main/java/scala/compat/java8/runtime/LambdaDeserializer.scala b/src/main/java/scala/compat/java8/runtime/LambdaDeserializer.scala index f9609d1..cdda56a 100644 --- a/src/main/java/scala/compat/java8/runtime/LambdaDeserializer.scala +++ b/src/main/java/scala/compat/java8/runtime/LambdaDeserializer.scala @@ -1,3 +1,15 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.compat.java8.runtime import java.lang.invoke._ diff --git a/src/main/java/scala/compat/java8/wrappers/IteratorPrimitiveDoubleWrapper.java b/src/main/java/scala/compat/java8/wrappers/IteratorPrimitiveDoubleWrapper.java index f863b8c..001699c 100644 --- a/src/main/java/scala/compat/java8/wrappers/IteratorPrimitiveDoubleWrapper.java +++ b/src/main/java/scala/compat/java8/wrappers/IteratorPrimitiveDoubleWrapper.java @@ -1,6 +1,15 @@ /* - * Copyright (C) 2012-2015 Lightbend Inc. + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. */ + package scala.compat.java8.wrappers; public class IteratorPrimitiveDoubleWrapper implements java.util.PrimitiveIterator.OfDouble { diff --git a/src/main/java/scala/compat/java8/wrappers/IteratorPrimitiveIntWrapper.java b/src/main/java/scala/compat/java8/wrappers/IteratorPrimitiveIntWrapper.java index 10c5cf0..0e9a6fe 100644 --- a/src/main/java/scala/compat/java8/wrappers/IteratorPrimitiveIntWrapper.java +++ b/src/main/java/scala/compat/java8/wrappers/IteratorPrimitiveIntWrapper.java @@ -1,6 +1,15 @@ /* - * Copyright (C) 2012-2015 Lightbend Inc. + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. */ + package scala.compat.java8.wrappers; public class IteratorPrimitiveIntWrapper implements java.util.PrimitiveIterator.OfInt { diff --git a/src/main/java/scala/compat/java8/wrappers/IteratorPrimitiveLongWrapper.java b/src/main/java/scala/compat/java8/wrappers/IteratorPrimitiveLongWrapper.java index 2cf799d..a78c736 100644 --- a/src/main/java/scala/compat/java8/wrappers/IteratorPrimitiveLongWrapper.java +++ b/src/main/java/scala/compat/java8/wrappers/IteratorPrimitiveLongWrapper.java @@ -1,6 +1,15 @@ /* - * Copyright (C) 2012-2015 Lightbend Inc. + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. */ + package scala.compat.java8.wrappers; public class IteratorPrimitiveLongWrapper implements java.util.PrimitiveIterator.OfLong { diff --git a/src/main/scala/scala/compat/java8/DurationConverters.scala b/src/main/scala/scala/compat/java8/DurationConverters.scala index 27f3c46..854f9dc 100644 --- a/src/main/scala/scala/compat/java8/DurationConverters.scala +++ b/src/main/scala/scala/compat/java8/DurationConverters.scala @@ -1,6 +1,15 @@ /* - * Copyright (C) 2012-2018 Lightbend Inc. + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. */ + package scala.compat.java8 import java.time.temporal.ChronoUnit diff --git a/src/main/scala/scala/compat/java8/FutureConverters.scala b/src/main/scala/scala/compat/java8/FutureConverters.scala index 99f019a..2f95056 100644 --- a/src/main/scala/scala/compat/java8/FutureConverters.scala +++ b/src/main/scala/scala/compat/java8/FutureConverters.scala @@ -1,6 +1,15 @@ /* - * Copyright (C) 2012-2015 Lightbend Inc. + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. */ + package scala.compat.java8 import scala.language.implicitConversions diff --git a/src/main/scala/scala/compat/java8/OptionConverters.scala b/src/main/scala/scala/compat/java8/OptionConverters.scala index 75b7915..49e06c2 100644 --- a/src/main/scala/scala/compat/java8/OptionConverters.scala +++ b/src/main/scala/scala/compat/java8/OptionConverters.scala @@ -1,6 +1,15 @@ /* - * Copyright (C) 2012-2015 Lightbend Inc. + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. */ + package scala.compat.java8 import java.util.{Optional, OptionalDouble, OptionalInt, OptionalLong} diff --git a/src/main/scala/scala/compat/java8/PrimitiveIteratorConversions.scala b/src/main/scala/scala/compat/java8/PrimitiveIteratorConversions.scala index f5a7a44..2d80ba6 100644 --- a/src/main/scala/scala/compat/java8/PrimitiveIteratorConversions.scala +++ b/src/main/scala/scala/compat/java8/PrimitiveIteratorConversions.scala @@ -1,6 +1,15 @@ /* - * Copyright (C) 2012-2015 Lightbend Inc. + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. */ + package scala.compat.java8 import java.util.{ Iterator => JIterator, PrimitiveIterator } diff --git a/src/main/scala/scala/compat/java8/SpliteratorConverters.scala b/src/main/scala/scala/compat/java8/SpliteratorConverters.scala index a635c92..36838f3 100644 --- a/src/main/scala/scala/compat/java8/SpliteratorConverters.scala +++ b/src/main/scala/scala/compat/java8/SpliteratorConverters.scala @@ -1,3 +1,15 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.compat.java8 import language.implicitConversions diff --git a/src/main/scala/scala/compat/java8/StreamConverters.scala b/src/main/scala/scala/compat/java8/StreamConverters.scala index 4f773a9..00a3d24 100644 --- a/src/main/scala/scala/compat/java8/StreamConverters.scala +++ b/src/main/scala/scala/compat/java8/StreamConverters.scala @@ -1,3 +1,15 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.compat.java8 import scala.language.higherKinds diff --git a/src/main/scala/scala/compat/java8/WrapperTraits.scala b/src/main/scala/scala/compat/java8/WrapperTraits.scala index da0125c..9106dfc 100644 --- a/src/main/scala/scala/compat/java8/WrapperTraits.scala +++ b/src/main/scala/scala/compat/java8/WrapperTraits.scala @@ -1,3 +1,15 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.compat.java8 /** A trait that indicates that the class is or can be converted to a Scala version by wrapping a Java class */ diff --git a/src/main/scala/scala/compat/java8/collectionImpl/Accumulator.scala b/src/main/scala/scala/compat/java8/collectionImpl/Accumulator.scala index 39f68ac..7358a1c 100644 --- a/src/main/scala/scala/compat/java8/collectionImpl/Accumulator.scala +++ b/src/main/scala/scala/compat/java8/collectionImpl/Accumulator.scala @@ -1,3 +1,15 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.compat.java8.collectionImpl import scala.language.higherKinds diff --git a/src/main/scala/scala/compat/java8/collectionImpl/AccumulatorLike.scala b/src/main/scala/scala/compat/java8/collectionImpl/AccumulatorLike.scala index 8201ac3..56519d2 100644 --- a/src/main/scala/scala/compat/java8/collectionImpl/AccumulatorLike.scala +++ b/src/main/scala/scala/compat/java8/collectionImpl/AccumulatorLike.scala @@ -1,3 +1,15 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.compat.java8.collectionImpl /** An accumulator that works with Java 8 streams; it accepts elements of type `A`, diff --git a/src/main/scala/scala/compat/java8/collectionImpl/DoubleAccumulator.scala b/src/main/scala/scala/compat/java8/collectionImpl/DoubleAccumulator.scala index d43e40d..b082769 100644 --- a/src/main/scala/scala/compat/java8/collectionImpl/DoubleAccumulator.scala +++ b/src/main/scala/scala/compat/java8/collectionImpl/DoubleAccumulator.scala @@ -1,3 +1,15 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.compat.java8.collectionImpl import scala.language.higherKinds diff --git a/src/main/scala/scala/compat/java8/collectionImpl/IntAccumulator.scala b/src/main/scala/scala/compat/java8/collectionImpl/IntAccumulator.scala index d962d24..5054d26 100644 --- a/src/main/scala/scala/compat/java8/collectionImpl/IntAccumulator.scala +++ b/src/main/scala/scala/compat/java8/collectionImpl/IntAccumulator.scala @@ -1,3 +1,15 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.compat.java8.collectionImpl import scala.language.higherKinds diff --git a/src/main/scala/scala/compat/java8/collectionImpl/LongAccumulator.scala b/src/main/scala/scala/compat/java8/collectionImpl/LongAccumulator.scala index 06faa21..b924a71 100644 --- a/src/main/scala/scala/compat/java8/collectionImpl/LongAccumulator.scala +++ b/src/main/scala/scala/compat/java8/collectionImpl/LongAccumulator.scala @@ -1,3 +1,15 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.compat.java8.collectionImpl import scala.language.higherKinds diff --git a/src/main/scala/scala/compat/java8/collectionImpl/Stepper.scala b/src/main/scala/scala/compat/java8/collectionImpl/Stepper.scala index ffc94cb..8e13ea1 100644 --- a/src/main/scala/scala/compat/java8/collectionImpl/Stepper.scala +++ b/src/main/scala/scala/compat/java8/collectionImpl/Stepper.scala @@ -1,3 +1,15 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.compat.java8.collectionImpl import scala.language.higherKinds diff --git a/src/main/scala/scala/compat/java8/converterImpl/Accumulates.scala b/src/main/scala/scala/compat/java8/converterImpl/Accumulates.scala index cb3c963..ff40e53 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/Accumulates.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/Accumulates.scala @@ -1,3 +1,15 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.compat.java8.converterImpl import scala.compat.java8.collectionImpl._ diff --git a/src/main/scala/scala/compat/java8/converterImpl/AccumulatorConverters.scala b/src/main/scala/scala/compat/java8/converterImpl/AccumulatorConverters.scala index 8a43fd6..5b3e77f 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/AccumulatorConverters.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/AccumulatorConverters.scala @@ -1,3 +1,15 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.compat.java8.converterImpl import language.implicitConversions diff --git a/src/main/scala/scala/compat/java8/converterImpl/MakesSteppers.scala b/src/main/scala/scala/compat/java8/converterImpl/MakesSteppers.scala index e194de9..e73e4d2 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/MakesSteppers.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/MakesSteppers.scala @@ -1,3 +1,15 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.compat.java8.converterImpl import scala.compat.java8.collectionImpl._ diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepConverters.scala b/src/main/scala/scala/compat/java8/converterImpl/StepConverters.scala index 7fbf363..e6752dc 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepConverters.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepConverters.scala @@ -1,3 +1,15 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.compat.java8.converterImpl import language.implicitConversions diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsArray.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsArray.scala index c9d21cf..d77daac 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsArray.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsArray.scala @@ -1,3 +1,15 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.compat.java8.converterImpl import scala.annotation.switch diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsBitSet.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsBitSet.scala index 8b0a49c..279035b 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsBitSet.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsBitSet.scala @@ -1,3 +1,15 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.compat.java8.converterImpl import scala.compat.java8.collectionImpl._ diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsFlatHashTable.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsFlatHashTable.scala index 8661105..3ec1ae2 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsFlatHashTable.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsFlatHashTable.scala @@ -1,3 +1,15 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.compat.java8.converterImpl import scala.annotation.switch diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsHashTable.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsHashTable.scala index f4869d6..f7a9f6c 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsHashTable.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsHashTable.scala @@ -1,3 +1,15 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.compat.java8.converterImpl import scala.annotation.switch diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsImmHashMap.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsImmHashMap.scala index 4875a4a..0b7c329 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsImmHashMap.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsImmHashMap.scala @@ -1,3 +1,15 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.compat.java8.converterImpl import scala.annotation.switch diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsImmHashSet.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsImmHashSet.scala index 84e0aff..864a3c2 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsImmHashSet.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsImmHashSet.scala @@ -1,3 +1,15 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.compat.java8.converterImpl import scala.annotation.switch diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsIndexedSeq.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsIndexedSeq.scala index 1065f0d..b7d2fe7 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsIndexedSeq.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsIndexedSeq.scala @@ -1,3 +1,15 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.compat.java8.converterImpl import scala.annotation.switch diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsIterable.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsIterable.scala index b0d63e9..4343206 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsIterable.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsIterable.scala @@ -1,3 +1,15 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.compat.java8.converterImpl import scala.annotation.switch diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsIterator.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsIterator.scala index d3b244f..62549a1 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsIterator.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsIterator.scala @@ -1,3 +1,15 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.compat.java8.converterImpl import scala.annotation.switch diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeGapped.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeGapped.scala index 6f74880..27c3bff 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeGapped.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeGapped.scala @@ -1,3 +1,15 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.compat.java8.converterImpl import scala.compat.java8.collectionImpl._ diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeImmHashMap.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeImmHashMap.scala index de4cdf1..e7ced1a 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeImmHashMap.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeImmHashMap.scala @@ -1,3 +1,15 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.compat.java8.converterImpl import scala.compat.java8.collectionImpl._ diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeIndexed.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeIndexed.scala index ed5abfa..56082d1 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeIndexed.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeIndexed.scala @@ -1,3 +1,15 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.compat.java8.converterImpl import scala.compat.java8.collectionImpl._ diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeIterator.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeIterator.scala index 02a05c7..518cee3 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeIterator.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeIterator.scala @@ -1,3 +1,15 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.compat.java8.converterImpl import scala.compat.java8.collectionImpl._ diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeSliced.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeSliced.scala index 8de1df0..ed3c695 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeSliced.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeSliced.scala @@ -1,3 +1,15 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.compat.java8.converterImpl import scala.compat.java8.collectionImpl._ diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeTrieIterator.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeTrieIterator.scala index eeda5b9..78abd12 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeTrieIterator.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeTrieIterator.scala @@ -1,3 +1,15 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.compat.java8.converterImpl import scala.compat.java8.collectionImpl._ diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsLinearSeq.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsLinearSeq.scala index 4c18398..d78c893 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsLinearSeq.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsLinearSeq.scala @@ -1,3 +1,15 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.compat.java8.converterImpl import scala.annotation.switch diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsMap.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsMap.scala index 1bf71fa..c6e8862 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsMap.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsMap.scala @@ -1,3 +1,15 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.compat.java8.converterImpl import scala.annotation.switch diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsRange.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsRange.scala index d364ed2..a4c92a3 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsRange.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsRange.scala @@ -1,3 +1,15 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.compat.java8.converterImpl import scala.annotation.switch diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsString.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsString.scala index 66101a1..adc78f7 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsString.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsString.scala @@ -1,3 +1,15 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.compat.java8.converterImpl import scala.compat.java8.collectionImpl._ diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsVector.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsVector.scala index b0abe26..c6cf1b8 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsVector.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsVector.scala @@ -1,3 +1,15 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.compat.java8.converterImpl import scala.annotation.switch diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsWithTail.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsWithTail.scala index f9977d7..04505a9 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsWithTail.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsWithTail.scala @@ -1,3 +1,15 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.compat.java8.converterImpl import scala.compat.java8.collectionImpl._ diff --git a/src/main/scala/scala/concurrent/java8/FutureConvertersImpl.scala b/src/main/scala/scala/concurrent/java8/FutureConvertersImpl.scala index 07265b1..31a6523 100644 --- a/src/main/scala/scala/concurrent/java8/FutureConvertersImpl.scala +++ b/src/main/scala/scala/concurrent/java8/FutureConvertersImpl.scala @@ -1,6 +1,15 @@ /* - * Copyright (C) 2012-2015 Lightbend Inc. + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. */ + package scala.concurrent.java8 // Located in this package to access private[concurrent] members diff --git a/src/test/java/scala/compat/java8/BoxingTest.java b/src/test/java/scala/compat/java8/BoxingTest.java index c093631..e0a2c03 100644 --- a/src/test/java/scala/compat/java8/BoxingTest.java +++ b/src/test/java/scala/compat/java8/BoxingTest.java @@ -1,6 +1,15 @@ /* - * Copyright (C) 2012-2015 Lightbend Inc. + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. */ + package scala.compat.java8; import org.junit.Test; diff --git a/src/test/java/scala/compat/java8/DurationConvertersJavaTest.java b/src/test/java/scala/compat/java8/DurationConvertersJavaTest.java index a032ae9..7d214a9 100644 --- a/src/test/java/scala/compat/java8/DurationConvertersJavaTest.java +++ b/src/test/java/scala/compat/java8/DurationConvertersJavaTest.java @@ -1,6 +1,15 @@ /* - * Copyright (C) 2012-2018 Lightbend Inc. + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. */ + package scala.compat.java8; import org.junit.Test; diff --git a/src/test/java/scala/compat/java8/FutureConvertersTest.java b/src/test/java/scala/compat/java8/FutureConvertersTest.java index 8022499..e3e492d 100644 --- a/src/test/java/scala/compat/java8/FutureConvertersTest.java +++ b/src/test/java/scala/compat/java8/FutureConvertersTest.java @@ -1,6 +1,15 @@ /* - * Copyright (C) 2012-2015 Lightbend Inc. + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. */ + package scala.compat.java8; import org.junit.Test; diff --git a/src/test/java/scala/compat/java8/LambdaTest.java b/src/test/java/scala/compat/java8/LambdaTest.java index 7992f03..5127c18 100644 --- a/src/test/java/scala/compat/java8/LambdaTest.java +++ b/src/test/java/scala/compat/java8/LambdaTest.java @@ -1,6 +1,15 @@ /* - * Copyright (C) 2012-2015 Lightbend Inc. + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. */ + package scala.compat.java8; import org.apache.commons.lang3.SerializationUtils; diff --git a/src/test/java/scala/compat/java8/OptionConvertersTest.scala b/src/test/java/scala/compat/java8/OptionConvertersTest.scala index a93b494..da99587 100644 --- a/src/test/java/scala/compat/java8/OptionConvertersTest.scala +++ b/src/test/java/scala/compat/java8/OptionConvertersTest.scala @@ -1,6 +1,15 @@ /* - * Copyright (C) 2012-2015 Lightbend Inc. + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. */ + package scala.compat.java8 import org.junit.Test diff --git a/src/test/java/scala/compat/java8/SpecializedTest.scala b/src/test/java/scala/compat/java8/SpecializedTest.scala index 7bd4a80..135c81f 100644 --- a/src/test/java/scala/compat/java8/SpecializedTest.scala +++ b/src/test/java/scala/compat/java8/SpecializedTest.scala @@ -1,6 +1,15 @@ /* - * Copyright (C) 2012-2015 Lightbend Inc. + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. */ + package scala.compat.java8 import org.junit.Test diff --git a/src/test/java/scala/compat/java8/SpecializedTestSupport.java b/src/test/java/scala/compat/java8/SpecializedTestSupport.java index 274926f..51f9cd2 100644 --- a/src/test/java/scala/compat/java8/SpecializedTestSupport.java +++ b/src/test/java/scala/compat/java8/SpecializedTestSupport.java @@ -1,6 +1,15 @@ /* - * Copyright (C) 2012-2015 Lightbend Inc. + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. */ + package scala.compat.java8; import java.util.Arrays; diff --git a/src/test/java/scala/compat/java8/StreamConvertersExampleTest.java b/src/test/java/scala/compat/java8/StreamConvertersExampleTest.java index 33b1800..3a95f03 100644 --- a/src/test/java/scala/compat/java8/StreamConvertersExampleTest.java +++ b/src/test/java/scala/compat/java8/StreamConvertersExampleTest.java @@ -1,5 +1,13 @@ /* - * Copyright (C) 2016 Lightbend Inc. + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. */ import org.junit.Test; diff --git a/src/test/java/scala/compat/java8/runtime/LambdaDeserializerTest.java b/src/test/java/scala/compat/java8/runtime/LambdaDeserializerTest.java index 723e56c..6640a44 100644 --- a/src/test/java/scala/compat/java8/runtime/LambdaDeserializerTest.java +++ b/src/test/java/scala/compat/java8/runtime/LambdaDeserializerTest.java @@ -1,3 +1,15 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.compat.java8.runtime; import org.junit.Assert; diff --git a/src/test/scala/scala/compat/java8/DurationConvertersTest.scala b/src/test/scala/scala/compat/java8/DurationConvertersTest.scala index 23c2304..443d40c 100644 --- a/src/test/scala/scala/compat/java8/DurationConvertersTest.scala +++ b/src/test/scala/scala/compat/java8/DurationConvertersTest.scala @@ -1,6 +1,15 @@ /* - * Copyright (C) 2009-2018 Lightbend Inc. + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. */ + package scala.compat.java8 import java.time.{Duration => JavaDuration} diff --git a/src/test/scala/scala/compat/java8/FunctionConvertersTest.scala b/src/test/scala/scala/compat/java8/FunctionConvertersTest.scala index 77881dd..b3da5ac 100644 --- a/src/test/scala/scala/compat/java8/FunctionConvertersTest.scala +++ b/src/test/scala/scala/compat/java8/FunctionConvertersTest.scala @@ -1,3 +1,15 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.compat.java8 import org.junit.Test diff --git a/src/test/scala/scala/compat/java8/StepConvertersTest.scala b/src/test/scala/scala/compat/java8/StepConvertersTest.scala index b7a43e4..d3e118c 100644 --- a/src/test/scala/scala/compat/java8/StepConvertersTest.scala +++ b/src/test/scala/scala/compat/java8/StepConvertersTest.scala @@ -1,3 +1,15 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.compat.java8 import org.junit.Test diff --git a/src/test/scala/scala/compat/java8/StepperTest.scala b/src/test/scala/scala/compat/java8/StepperTest.scala index 48f3a8a..7bbbcd9 100644 --- a/src/test/scala/scala/compat/java8/StepperTest.scala +++ b/src/test/scala/scala/compat/java8/StepperTest.scala @@ -1,3 +1,15 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.compat.java8 import org.junit.Test diff --git a/src/test/scala/scala/compat/java8/StreamConvertersTest.scala b/src/test/scala/scala/compat/java8/StreamConvertersTest.scala index fbecae5..1a63c86 100644 --- a/src/test/scala/scala/compat/java8/StreamConvertersTest.scala +++ b/src/test/scala/scala/compat/java8/StreamConvertersTest.scala @@ -1,3 +1,15 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + package scala.compat.java8 import scala.language.higherKinds From 96b4d6636c553a931d52d652a276777edce8ab40 Mon Sep 17 00:00:00 2001 From: Philippus Date: Sat, 16 Feb 2019 11:37:36 +0100 Subject: [PATCH 03/13] Update copyright header for auto-generated files --- fnGen/WrapFnGen.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fnGen/WrapFnGen.scala b/fnGen/WrapFnGen.scala index b46dcce..26acee7 100644 --- a/fnGen/WrapFnGen.scala +++ b/fnGen/WrapFnGen.scala @@ -14,7 +14,7 @@ object WrapFnGen { val copyright = s""" |/* - | * Copyright (C) 2015-2016, Lightbend Inc. + | * Copyright EPFL and Lightbend, Inc. | * This file auto-generated by WrapFnGen.scala. Do not modify directly. | */ |""".stripMargin From 5a25ea201acf6dec0e6a1426513d9a3f5feab34a Mon Sep 17 00:00:00 2001 From: Philippus Date: Sat, 16 Feb 2019 11:41:34 +0100 Subject: [PATCH 04/13] Add build status icon --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4f89b6d..2c5539f 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -## scala-java8-compat [](http://search.maven.org/#search%7Cga%7C1%7Cg%3Aorg.scala-lang.modules%20a%3Ascala-java8-compat_2.11) [](http://search.maven.org/#search%7Cga%7C1%7Cg%3Aorg.scala-lang.modules%20a%3Ascala-java8-compat_2.12) +# scala-java8-compat [![Build Status](https://travis-ci.org/scala/scala-java8-compat.svg?branch=master)](https://travis-ci.org/scala/scala-java8-compat) [](http://search.maven.org/#search%7Cga%7C1%7Cg%3Aorg.scala-lang.modules%20a%3Ascala-java8-compat_2.11) [](http://search.maven.org/#search%7Cga%7C1%7Cg%3Aorg.scala-lang.modules%20a%3Ascala-java8-compat_2.12) A Java 8 compatibility kit for Scala. From 407df09cbd88310f5fafc52d91ee322b050f10e2 Mon Sep 17 00:00:00 2001 From: Will Sargent Date: Tue, 19 Feb 2019 08:59:05 -0800 Subject: [PATCH 05/13] Fix a typo s/FutureConverter/FutureConverters/ --- src/main/scala/scala/compat/java8/FutureConverters.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/scala/compat/java8/FutureConverters.scala b/src/main/scala/scala/compat/java8/FutureConverters.scala index 2f95056..341f400 100644 --- a/src/main/scala/scala/compat/java8/FutureConverters.scala +++ b/src/main/scala/scala/compat/java8/FutureConverters.scala @@ -38,7 +38,7 @@ import java.util.function.Consumer * {{{ * import java.util.concurrent.CompletionStage; * import scala.concurrent.Future; - * import static scala.concurrent.java8.FutureConverter.*; + * import static scala.concurrent.java8.FutureConverters.*; * * final CompletionStage cs = ... // from an async Java API * final Future f = toScala(cs); From efb60c4e1f828d6dc0a4bf44814fe1b92fd54c65 Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Tue, 19 Feb 2019 20:19:57 -0800 Subject: [PATCH 06/13] upgrade to sbt 1 --- admin/build.sh | 2 +- admin/gpg.sbt | 3 +-- build.sbt | 4 ---- project/build.properties | 2 +- project/plugins.sbt | 2 +- 5 files changed, 4 insertions(+), 9 deletions(-) diff --git a/admin/build.sh b/admin/build.sh index db8692b..929aa55 100755 --- a/admin/build.sh +++ b/admin/build.sh @@ -29,7 +29,7 @@ if [[ "$TRAVIS_TAG" =~ $tagPat ]]; then currentJvmVer=$(java -version 2>&1 | awk -F '"' '/version/ {print $2}' | sed 's/^1\.//' | sed 's/[^0-9].*//') echo "Releasing $tagVer with Scala $TRAVIS_SCALA_VERSION on Java version $currentJvmVer." - publishTask="publish-signed" + publishTask="publishSigned" cat admin/gpg.sbt >> project/plugins.sbt cp admin/publish-settings.sbt . diff --git a/admin/gpg.sbt b/admin/gpg.sbt index d60e366..e6f00f4 100644 --- a/admin/gpg.sbt +++ b/admin/gpg.sbt @@ -1,2 +1 @@ - -addSbtPlugin("com.typesafe.sbt" % "sbt-pgp" % "0.8.3") // only added when publishing: +addSbtPlugin("com.jsuereth" % "sbt-pgp" % "1.1.2-1") // only added when publishing diff --git a/build.sbt b/build.sbt index 10f155c..e853b87 100644 --- a/build.sbt +++ b/build.sbt @@ -25,9 +25,6 @@ lazy val commonSettings = Seq( organization := "org.scala-lang.modules", version := "0.9.1-SNAPSHOT", - // this line could be removed after https://github.com/scala/sbt-scala-module/issues/48 is fixed - licenses := Seq(("Apache-2.0", url("https://www.apache.org/licenses/LICENSE-2.0"))), - scalacOptions ++= Seq("-feature", "-deprecation", "-unchecked") ) @@ -70,7 +67,6 @@ lazy val root = (project in file(".")). val runTarget = (mainClass in Compile in fnGen).value getOrElse "No main class defined for function conversion generator" val classPath = (fullClasspath in Compile in fnGen).value runner.value.run(runTarget, classPath.files, args, streams.value.log) - .foreach(sys.error) (out ** "*.scala").get }.taskValue, diff --git a/project/build.properties b/project/build.properties index 8e682c5..c0bab04 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=0.13.18 +sbt.version=1.2.8 diff --git a/project/plugins.sbt b/project/plugins.sbt index 1e7f7c0..2de9ecd 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -5,4 +5,4 @@ scalacOptions ++= (sys.props("java.specification.version") match { case _ => Seq("-Xfatal-warnings") }) -addSbtPlugin("org.scala-lang.modules" % "sbt-scala-module" % "1.0.14") +addSbtPlugin("org.scala-lang.modules" % "sbt-scala-module" % "2.0.0") From 2a28f25d87c89c997a31218d01f8fcc7c390374c Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Wed, 6 Mar 2019 14:40:42 -0800 Subject: [PATCH 07/13] add OpenJDK 11 to CI matrix fixes #130 --- .travis.yml | 1 + build.sbt | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 713eac5..c8f9482 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,7 @@ sudo: false jdk: - oraclejdk8 + - openjdk11 scala: # no 2.13 for now in cross-build because of diff --git a/build.sbt b/build.sbt index e853b87..cf9c21e 100644 --- a/build.sbt +++ b/build.sbt @@ -4,7 +4,10 @@ import ScalaModulePlugin._ // https://github.com/scala/scala-java8-compat/issues/97 crossScalaVersions in ThisBuild := List("2.12.8", "2.11.12") -val disableDocs = sys.props("nodocs") == "true" +val disableDocs = + sys.props("nodocs") == "true" || + // can't build doc on JDK 11 until sbt/sbt#4350 is fixed + !sys.props("java.version").startsWith("1.") lazy val JavaDoc = config("genjavadoc") extend Compile From b8415dbc6f3775e3224597aeb1751afc6105028c Mon Sep 17 00:00:00 2001 From: Scala steward Date: Wed, 27 Mar 2019 23:12:24 +0100 Subject: [PATCH 08/13] Update genjavadoc-plugin to 0.13 --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index cf9c21e..f9493cc 100644 --- a/build.sbt +++ b/build.sbt @@ -113,7 +113,7 @@ lazy val root = (project in file(".")). }, javacOptions in JavaDoc := Seq(), artifactName in packageDoc in JavaDoc := ((sv, mod, art) => "" + mod.name + "_" + sv.binary + "-" + mod.revision + "-javadoc.jar"), - libraryDependencies += compilerPlugin("com.typesafe.genjavadoc" % "genjavadoc-plugin" % "0.11" cross CrossVersion.full), + libraryDependencies += compilerPlugin("com.typesafe.genjavadoc" % "genjavadoc-plugin" % "0.13" cross CrossVersion.full), scalacOptions in Compile += "-P:genjavadoc:out=" + (target.value / "java") ))): _* ). From d6d99f884751420caaeb4a3a8b6d5754e70ce6f7 Mon Sep 17 00:00:00 2001 From: Lukas Rytz Date: Tue, 27 Nov 2018 18:12:01 +0100 Subject: [PATCH 09/13] Minor cleanups --- .../scala/compat/java8/StreamConverters.scala | 2 +- .../java8/collectionImpl/Accumulator.scala | 7 +++-- .../collectionImpl/AccumulatorLike.scala | 2 +- .../compat/java8/collectionImpl/Stepper.scala | 2 +- .../java8/converterImpl/StepsArray.scala | 18 ++++++------ .../java8/converterImpl/StepsBitSet.scala | 5 ++-- .../converterImpl/StepsFlatHashTable.scala | 8 +++--- .../java8/converterImpl/StepsHashTable.scala | 28 +++++++++---------- .../java8/converterImpl/StepsIndexedSeq.scala | 8 +++--- .../java8/converterImpl/StepsIterator.scala | 8 +++--- .../java8/converterImpl/StepsLikeGapped.scala | 2 +- .../converterImpl/StepsLikeIndexed.scala | 2 +- .../converterImpl/StepsLikeIterator.scala | 2 +- .../java8/converterImpl/StepsLikeSliced.scala | 2 +- .../converterImpl/StepsLikeTrieIterator.scala | 2 +- .../java8/converterImpl/StepsLinearSeq.scala | 8 +++--- .../java8/converterImpl/StepsRange.scala | 8 +++--- .../java8/converterImpl/StepsString.scala | 2 +- .../java8/converterImpl/StepsVector.scala | 8 +++--- .../java8/converterImpl/StepsWithTail.scala | 2 +- 20 files changed, 64 insertions(+), 62 deletions(-) diff --git a/src/main/scala/scala/compat/java8/StreamConverters.scala b/src/main/scala/scala/compat/java8/StreamConverters.scala index 5fd8f33..0975d9e 100644 --- a/src/main/scala/scala/compat/java8/StreamConverters.scala +++ b/src/main/scala/scala/compat/java8/StreamConverters.scala @@ -103,7 +103,7 @@ trait Priority2StreamConverters { trait Priority1StreamConverters extends Priority2StreamConverters { implicit class RichStream[A](stream: Stream[A]) { - def accumulate = stream.collect(Accumulator.supplier[A], Accumulator.adder[A], Accumulator.merger[A]) + def accumulate: Accumulator[A] = stream.collect(Accumulator.supplier[A], Accumulator.adder[A], Accumulator.merger[A]) def toScala[Coll[_]](implicit factory: collection.Factory[A, Coll[A]]): Coll[A] = { if (stream.isParallel) accumulate.to[Coll](factory) diff --git a/src/main/scala/scala/compat/java8/collectionImpl/Accumulator.scala b/src/main/scala/scala/compat/java8/collectionImpl/Accumulator.scala index eb9f61c..b8c6743 100644 --- a/src/main/scala/scala/compat/java8/collectionImpl/Accumulator.scala +++ b/src/main/scala/scala/compat/java8/collectionImpl/Accumulator.scala @@ -19,11 +19,14 @@ import scala.language.higherKinds * Accumulators can contain more than `Int.MaxValue` elements. */ final class Accumulator[A] extends AccumulatorLike[A, Accumulator[A]] { self => + // Elements are added to `current`. Once full, it's added to `history`, and a new `current` is + // created with `nextBlockSize` (which depends on `totalSize`). + // `cumul(i)` is `(0 until i).map(history(_).length)` private[java8] var current: Array[AnyRef] = Accumulator.emptyAnyRefArray private[java8] var history: Array[Array[AnyRef]] = Accumulator.emptyAnyRefArrayArray private[java8] var cumul: Array[Long] = Accumulator.emptyLongArray - - private[java8] def cumulative(i: Int) = cumul(i) + + private[java8] def cumulative(i: Int): Long = cumul(i) private def expand(): Unit = { if (index > 0) { diff --git a/src/main/scala/scala/compat/java8/collectionImpl/AccumulatorLike.scala b/src/main/scala/scala/compat/java8/collectionImpl/AccumulatorLike.scala index 56519d2..f7f3143 100644 --- a/src/main/scala/scala/compat/java8/collectionImpl/AccumulatorLike.scala +++ b/src/main/scala/scala/compat/java8/collectionImpl/AccumulatorLike.scala @@ -31,7 +31,7 @@ trait AccumulatorLike[@specialized(Double, Int, Long) A, AC] { } /** Size of the accumulated collection, as a `Long` */ - final def size = totalSize + final def size: Long = totalSize /** Remove all accumulated elements from this accumulator. */ def clear(): Unit = { diff --git a/src/main/scala/scala/compat/java8/collectionImpl/Stepper.scala b/src/main/scala/scala/compat/java8/collectionImpl/Stepper.scala index 4bf3f98..8760b5c 100644 --- a/src/main/scala/scala/compat/java8/collectionImpl/Stepper.scala +++ b/src/main/scala/scala/compat/java8/collectionImpl/Stepper.scala @@ -44,7 +44,7 @@ import java.util.Spliterator * {{{ * val s = Stepper.of(Vector(1,2,3,4)) * if (s.hasStep) println(s.nextStep) // Prints 1 - * println(s.tryStep(i => println(i*i))) // Prints 4, then true + * println(s.tryStep(i => println(i*i))) // Prints 2, then true * s.substep.foreach(println) // Prints 3 * println(s.count(_ > 3)) // Prints 4 * println(s.hasStep) // Prints `false` diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsArray.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsArray.scala index d77daac..410d0f4 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsArray.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsArray.scala @@ -25,55 +25,55 @@ import Stepper._ private[java8] class StepsObjectArray[A <: Object](underlying: Array[A], _i0: Int, _iN: Int) extends StepsLikeIndexed[A, StepsObjectArray[A]](_i0, _iN) { def next() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE - def semiclone(half: Int) = new StepsObjectArray[A](underlying, i0, half) + protected def semiclone(half: Int) = new StepsObjectArray[A](underlying, i0, half) } private[java8] class StepsBoxedBooleanArray(underlying: Array[Boolean], _i0: Int, _iN: Int) extends StepsLikeIndexed[Boolean, StepsBoxedBooleanArray](_i0, _iN) { def next() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE - def semiclone(half: Int) = new StepsBoxedBooleanArray(underlying, i0, half) + protected def semiclone(half: Int) = new StepsBoxedBooleanArray(underlying, i0, half) } private[java8] class StepsWidenedByteArray(underlying: Array[Byte], _i0: Int, _iN: Int) extends StepsIntLikeIndexed[StepsWidenedByteArray](_i0, _iN) { def nextInt() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE - def semiclone(half: Int) = new StepsWidenedByteArray(underlying, i0, half) + protected def semiclone(half: Int) = new StepsWidenedByteArray(underlying, i0, half) } private[java8] class StepsWidenedCharArray(underlying: Array[Char], _i0: Int, _iN: Int) extends StepsIntLikeIndexed[StepsWidenedCharArray](_i0, _iN) { def nextInt() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE - def semiclone(half: Int) = new StepsWidenedCharArray(underlying, i0, half) + protected def semiclone(half: Int) = new StepsWidenedCharArray(underlying, i0, half) } private[java8] class StepsWidenedShortArray(underlying: Array[Short], _i0: Int, _iN: Int) extends StepsIntLikeIndexed[StepsWidenedShortArray](_i0, _iN) { def nextInt() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE - def semiclone(half: Int) = new StepsWidenedShortArray(underlying, i0, half) + protected def semiclone(half: Int) = new StepsWidenedShortArray(underlying, i0, half) } private[java8] class StepsWidenedFloatArray(underlying: Array[Float], _i0: Int, _iN: Int) extends StepsDoubleLikeIndexed[StepsWidenedFloatArray](_i0, _iN) { def nextDouble() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE - def semiclone(half: Int) = new StepsWidenedFloatArray(underlying, i0, half) + protected def semiclone(half: Int) = new StepsWidenedFloatArray(underlying, i0, half) } private[java8] class StepsDoubleArray(underlying: Array[Double], _i0: Int, _iN: Int) extends StepsDoubleLikeIndexed[StepsDoubleArray](_i0, _iN) { def nextDouble() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE - def semiclone(half: Int) = new StepsDoubleArray(underlying, i0, half) + protected def semiclone(half: Int) = new StepsDoubleArray(underlying, i0, half) } private[java8] class StepsIntArray(underlying: Array[Int], _i0: Int, _iN: Int) extends StepsIntLikeIndexed[StepsIntArray](_i0, _iN) { def nextInt() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE - def semiclone(half: Int) = new StepsIntArray(underlying, i0, half) + protected def semiclone(half: Int) = new StepsIntArray(underlying, i0, half) } private[java8] class StepsLongArray(underlying: Array[Long], _i0: Int, _iN: Int) extends StepsLongLikeIndexed[StepsLongArray](_i0, _iN) { def nextLong() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE - def semiclone(half: Int) = new StepsLongArray(underlying, i0, half) + protected def semiclone(half: Int) = new StepsLongArray(underlying, i0, half) } ////////////////////////// diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsBitSet.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsBitSet.scala index 279035b..d0392f6 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsBitSet.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsBitSet.scala @@ -26,7 +26,7 @@ extends StepsIntLikeSliced[Array[Long], StepsIntBitSet](_underlying, _i0, _iN) { private var mask: Long = (-1L) << (i & 0x3F) private var cache: Long = underlying(i >>> 6) private var found: Boolean = false - def semiclone(half: Int) = { + protected def semiclone(half: Int) = { val ans = new StepsIntBitSet(underlying, i, half) i = half mask = (-1L) << (i & 0x3F) @@ -50,8 +50,7 @@ extends StepsIntLikeSliced[Array[Long], StepsIntBitSet](_underlying, _i0, _iN) { if (i < 0 || i >= iN) { i = iN false - } - else { + } else { found = true true } diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsFlatHashTable.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsFlatHashTable.scala index e254cf0..94174d9 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsFlatHashTable.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsFlatHashTable.scala @@ -26,25 +26,25 @@ import Stepper._ private[java8] class StepsAnyFlatHashTable[A](_underlying: Array[AnyRef], _i0: Int, _iN: Int) extends StepsLikeGapped[A, StepsAnyFlatHashTable[A]](_underlying, _i0, _iN) { def next() = if (currentEntry eq null) throwNSEE else { val ans = currentEntry.asInstanceOf[A]; currentEntry = null; ans } - def semiclone(half: Int) = new StepsAnyFlatHashTable[A](underlying, i0, half) + protected def semiclone(half: Int) = new StepsAnyFlatHashTable[A](underlying, i0, half) } private[java8] class StepsDoubleFlatHashTable(_underlying: Array[AnyRef], _i0: Int, _iN: Int) extends StepsDoubleLikeGapped[StepsDoubleFlatHashTable](_underlying, _i0, _iN) { def nextDouble() = if (currentEntry eq null) throwNSEE else { val ans = currentEntry.asInstanceOf[Double]; currentEntry = null; ans } - def semiclone(half: Int) = new StepsDoubleFlatHashTable(underlying, i0, half) + protected def semiclone(half: Int) = new StepsDoubleFlatHashTable(underlying, i0, half) } private[java8] class StepsIntFlatHashTable(_underlying: Array[AnyRef], _i0: Int, _iN: Int) extends StepsIntLikeGapped[StepsIntFlatHashTable](_underlying, _i0, _iN) { def nextInt() = if (currentEntry eq null) throwNSEE else { val ans = currentEntry.asInstanceOf[Int]; currentEntry = null; ans } - def semiclone(half: Int) = new StepsIntFlatHashTable(underlying, i0, half) + protected def semiclone(half: Int) = new StepsIntFlatHashTable(underlying, i0, half) } private[java8] class StepsLongFlatHashTable(_underlying: Array[AnyRef], _i0: Int, _iN: Int) extends StepsLongLikeGapped[StepsLongFlatHashTable](_underlying, _i0, _iN) { def nextLong() = if (currentEntry eq null) throwNSEE else { val ans = currentEntry.asInstanceOf[Long]; currentEntry = null; ans } - def semiclone(half: Int) = new StepsLongFlatHashTable(underlying, i0, half) + protected def semiclone(half: Int) = new StepsLongFlatHashTable(underlying, i0, half) } ////////////////////////// diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsHashTable.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsHashTable.scala index 7a5ad21..d75b3d8 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsHashTable.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsHashTable.scala @@ -28,25 +28,25 @@ import Stepper._ private[java8] class StepsAnyHashTableKey[K](_underlying: Array[AnyRef], _i0: Int, _iN: Int) extends StepsLikeGapped[K, StepsAnyHashTableKey[K]](_underlying, _i0, _iN) { def next() = if (currentEntry eq null) throwNSEE else { val ans = CollectionInternals.hashEntryKey[K](currentEntry); currentEntry = CollectionInternals.hashEntryNext(currentEntry); ans } - def semiclone(half: Int) = new StepsAnyHashTableKey[K](underlying, i0, half) + protected def semiclone(half: Int) = new StepsAnyHashTableKey[K](underlying, i0, half) } private[java8] class StepsDoubleHashTableKey(_underlying: Array[AnyRef], _i0: Int, _iN: Int) extends StepsDoubleLikeGapped[StepsDoubleHashTableKey](_underlying, _i0, _iN) { def nextDouble() = if (currentEntry eq null) throwNSEE else { val ans = CollectionInternals.hashEntryKey[Double](currentEntry); currentEntry = CollectionInternals.hashEntryNext(currentEntry); ans } - def semiclone(half: Int) = new StepsDoubleHashTableKey(underlying, i0, half) + protected def semiclone(half: Int) = new StepsDoubleHashTableKey(underlying, i0, half) } private[java8] class StepsIntHashTableKey(_underlying: Array[AnyRef], _i0: Int, _iN: Int) extends StepsIntLikeGapped[StepsIntHashTableKey](_underlying, _i0, _iN) { def nextInt() = if (currentEntry eq null) throwNSEE else { val ans = CollectionInternals.hashEntryKey[Int](currentEntry); currentEntry = CollectionInternals.hashEntryNext(currentEntry); ans } - def semiclone(half: Int) = new StepsIntHashTableKey(underlying, i0, half) + protected def semiclone(half: Int) = new StepsIntHashTableKey(underlying, i0, half) } private[java8] class StepsLongHashTableKey(_underlying: Array[AnyRef], _i0: Int, _iN: Int) extends StepsLongLikeGapped[StepsLongHashTableKey](_underlying, _i0, _iN) { def nextLong() = if (currentEntry eq null) throwNSEE else { val ans = CollectionInternals.hashEntryKey[Long](currentEntry); currentEntry = CollectionInternals.hashEntryNext(currentEntry); ans } - def semiclone(half: Int) = new StepsLongHashTableKey(underlying, i0, half) + protected def semiclone(half: Int) = new StepsLongHashTableKey(underlying, i0, half) } // Steppers for entries stored in DefaultEntry HashEntry @@ -57,7 +57,7 @@ extends StepsLikeGapped[(K, V), StepsAnyDefaultHashTable[K, V]](_underlying, _i0 def next() = if (currentEntry eq null) throwNSEE else { val e = currentEntry; currentEntry = CollectionInternals.hashEntryNext(e); (CollectionInternals.hashEntryKey[K](e), CollectionInternals.defaultEntryValue[V](e)) } - def semiclone(half: Int) = + protected def semiclone(half: Int) = new StepsAnyDefaultHashTable[K, V](underlying, i0, half) } @@ -66,7 +66,7 @@ extends StepsLikeGapped[V, StepsAnyDefaultHashTableValue[K, V]](_underlying, _i0 def next() = if (currentEntry eq null) throwNSEE else { val e = currentEntry; currentEntry = CollectionInternals.hashEntryNext(e); CollectionInternals.defaultEntryValue[V](e) } - def semiclone(half: Int) = + protected def semiclone(half: Int) = new StepsAnyDefaultHashTableValue[K, V](underlying, i0, half) } @@ -75,7 +75,7 @@ extends StepsDoubleLikeGapped[StepsDoubleDefaultHashTableValue[K]](_underlying, def nextDouble() = if (currentEntry eq null) throwNSEE else { val e = currentEntry; currentEntry = CollectionInternals.hashEntryNext(e); CollectionInternals.defaultEntryValue[Double](e) } - def semiclone(half: Int) = + protected def semiclone(half: Int) = new StepsDoubleDefaultHashTableValue[K](underlying, i0, half) } @@ -84,7 +84,7 @@ extends StepsIntLikeGapped[StepsIntDefaultHashTableValue[K]](_underlying, _i0, _ def nextInt() = if (currentEntry eq null) throwNSEE else { val e = currentEntry; currentEntry = CollectionInternals.hashEntryNext(e); CollectionInternals.defaultEntryValue[Int](e) } - def semiclone(half: Int) = + protected def semiclone(half: Int) = new StepsIntDefaultHashTableValue[K](underlying, i0, half) } @@ -93,7 +93,7 @@ extends StepsLongLikeGapped[StepsLongDefaultHashTableValue[K]](_underlying, _i0, def nextLong() = if (currentEntry eq null) throwNSEE else { val e = currentEntry; currentEntry = CollectionInternals.hashEntryNext(e); CollectionInternals.defaultEntryValue[Long](e) } - def semiclone(half: Int) = + protected def semiclone(half: Int) = new StepsLongDefaultHashTableValue[K](underlying, i0, half) } @@ -105,7 +105,7 @@ extends StepsLikeGapped[(K, V), StepsAnyLinkedHashTable[K, V]](_underlying, _i0, def next() = if (currentEntry eq null) throwNSEE else { val e = currentEntry; currentEntry = CollectionInternals.hashEntryNext(e); (CollectionInternals.hashEntryKey[K](e), CollectionInternals.linkedEntryValue[V](e)) } - def semiclone(half: Int) = + protected def semiclone(half: Int) = new StepsAnyLinkedHashTable[K, V](underlying, i0, half) } @@ -114,7 +114,7 @@ extends StepsLikeGapped[V, StepsAnyLinkedHashTableValue[K, V]](_underlying, _i0, def next() = if (currentEntry eq null) throwNSEE else { val e = currentEntry; currentEntry = CollectionInternals.hashEntryNext(e); CollectionInternals.linkedEntryValue[V](e) } - def semiclone(half: Int) = + protected def semiclone(half: Int) = new StepsAnyLinkedHashTableValue[K, V](underlying, i0, half) } @@ -123,7 +123,7 @@ extends StepsDoubleLikeGapped[StepsDoubleLinkedHashTableValue[K]](_underlying, _ def nextDouble() = if (currentEntry eq null) throwNSEE else { val e = currentEntry; currentEntry = CollectionInternals.hashEntryNext(e); CollectionInternals.linkedEntryValue[Double](e) } - def semiclone(half: Int) = + protected def semiclone(half: Int) = new StepsDoubleLinkedHashTableValue[K](underlying, i0, half) } @@ -132,7 +132,7 @@ extends StepsIntLikeGapped[StepsIntLinkedHashTableValue[K]](_underlying, _i0, _i def nextInt() = if (currentEntry eq null) throwNSEE else { val e = currentEntry; currentEntry = CollectionInternals.hashEntryNext(e); CollectionInternals.linkedEntryValue[Int](e) } - def semiclone(half: Int) = + protected def semiclone(half: Int) = new StepsIntLinkedHashTableValue[K](underlying, i0, half) } @@ -141,7 +141,7 @@ extends StepsLongLikeGapped[StepsLongLinkedHashTableValue[K]](_underlying, _i0, def nextLong() = if (currentEntry eq null) throwNSEE else { val e = currentEntry; currentEntry = CollectionInternals.hashEntryNext(e); CollectionInternals.linkedEntryValue[Long](e) } - def semiclone(half: Int) = + protected def semiclone(half: Int) = new StepsLongLinkedHashTableValue[K](underlying, i0, half) } diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsIndexedSeq.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsIndexedSeq.scala index 9222c38..3627236 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsIndexedSeq.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsIndexedSeq.scala @@ -23,25 +23,25 @@ import Stepper._ private[java8] class StepsAnyIndexedSeq[A](underlying: collection.IndexedSeqOps[A, Any, _], _i0: Int, _iN: Int) extends StepsLikeIndexed[A, StepsAnyIndexedSeq[A]](_i0, _iN) { def next() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE - def semiclone(half: Int) = new StepsAnyIndexedSeq[A](underlying, i0, half) + protected def semiclone(half: Int) = new StepsAnyIndexedSeq[A](underlying, i0, half) } private[java8] class StepsDoubleIndexedSeq[CC <: collection.IndexedSeqOps[Double, Any, _]](underlying: CC, _i0: Int, _iN: Int) extends StepsDoubleLikeIndexed[StepsDoubleIndexedSeq[CC]](_i0, _iN) { def nextDouble() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE - def semiclone(half: Int) = new StepsDoubleIndexedSeq[CC](underlying, i0, half) + protected def semiclone(half: Int) = new StepsDoubleIndexedSeq[CC](underlying, i0, half) } private[java8] class StepsIntIndexedSeq[CC <: collection.IndexedSeqOps[Int, Any, _]](underlying: CC, _i0: Int, _iN: Int) extends StepsIntLikeIndexed[StepsIntIndexedSeq[CC]](_i0, _iN) { def nextInt() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE - def semiclone(half: Int) = new StepsIntIndexedSeq[CC](underlying, i0, half) + protected def semiclone(half: Int) = new StepsIntIndexedSeq[CC](underlying, i0, half) } private[java8] class StepsLongIndexedSeq[CC <: collection.IndexedSeqOps[Long, Any, _]](underlying: CC, _i0: Int, _iN: Int) extends StepsLongLikeIndexed[StepsLongIndexedSeq[CC]](_i0, _iN) { def nextLong() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE - def semiclone(half: Int) = new StepsLongIndexedSeq[CC](underlying, i0, half) + protected def semiclone(half: Int) = new StepsLongIndexedSeq[CC](underlying, i0, half) } ////////////////////////// diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsIterator.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsIterator.scala index 62549a1..b5d0700 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsIterator.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsIterator.scala @@ -22,25 +22,25 @@ import scala.compat.java8.collectionImpl._ private[java8] class StepsAnyIterator[A](_underlying: Iterator[A]) extends StepsLikeIterator[A, StepsAnyIterator[A]](_underlying) { - def semiclone() = new StepsAnyIterator(null) + protected def semiclone() = new StepsAnyIterator(null) def next() = if (proxied ne null) proxied.nextStep else underlying.next } private[java8] class StepsDoubleIterator(_underlying: Iterator[Double]) extends StepsDoubleLikeIterator[StepsDoubleIterator](_underlying) { - def semiclone() = new StepsDoubleIterator(null) + protected def semiclone() = new StepsDoubleIterator(null) def nextDouble() = if (proxied ne null) proxied.nextStep else underlying.next } private[java8] class StepsIntIterator(_underlying: Iterator[Int]) extends StepsIntLikeIterator[StepsIntIterator](_underlying) { - def semiclone() = new StepsIntIterator(null) + protected def semiclone() = new StepsIntIterator(null) def nextInt() = if (proxied ne null) proxied.nextStep else underlying.next } private[java8] class StepsLongIterator(_underlying: Iterator[Long]) extends StepsLongLikeIterator[StepsLongIterator](_underlying) { - def semiclone() = new StepsLongIterator(null) + protected def semiclone() = new StepsLongIterator(null) def nextLong() = if (proxied ne null) proxied.nextStep else underlying.next } diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeGapped.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeGapped.scala index 27c3bff..6d0fa5b 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeGapped.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeGapped.scala @@ -25,7 +25,7 @@ private[java8] abstract class AbstractStepsLikeGapped[Sub >: Null, Semi <: Sub]( extends EfficientSubstep { protected var currentEntry: AnyRef = null - def semiclone(half: Int): Semi + protected def semiclone(half: Int): Semi def characteristics(): Int = Ordered def estimateSize(): Long = if (!hasNext) 0 else iN - i0 def hasNext(): Boolean = currentEntry != null || (i0 < iN && { diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeIndexed.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeIndexed.scala index 325b064..9a0aae8 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeIndexed.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeIndexed.scala @@ -19,7 +19,7 @@ import Stepper._ private[java8] abstract class AbstractStepsLikeIndexed[Sub >: Null, Semi <: Sub](protected var i0: Int, protected var iN: Int) extends EfficientSubstep { - def semiclone(half: Int): Semi + protected def semiclone(half: Int): Semi def characteristics(): Int = Ordered + Sized + SubSized def estimateSize(): Long = iN - i0 def hasNext(): Boolean = i0 < iN diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeIterator.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeIterator.scala index 518cee3..3f1abe0 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeIterator.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeIterator.scala @@ -19,7 +19,7 @@ import Stepper._ private[java8] abstract class AbstractStepsLikeIterator[A, SP >: Null <: Stepper[A], Semi <: SP](final protected var underlying: Iterator[A]) { final protected var nextChunkSize = 16 final protected var proxied: SP = null - def semiclone(): Semi // Must initialize with null iterator! + protected def semiclone(): Semi // Must initialize with null iterator! def characteristics(): Int = if (proxied ne null) Ordered | Sized | SubSized else Ordered def estimateSize(): Long = if (proxied ne null) proxied.knownSize else Long.MaxValue def hasNext(): Boolean = if (proxied ne null) proxied.hasStep else underlying.hasNext diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeSliced.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeSliced.scala index ed3c695..b26d302 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeSliced.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeSliced.scala @@ -23,7 +23,7 @@ private[java8] abstract class AbstractStepsLikeSliced[Coll, Sub >: Null, Semi <: extends EfficientSubstep { protected var i0: Int = i - def semiclone(halfHint: Int): Semi // Must really do all the work for both this and cloned collection! + protected def semiclone(halfHint: Int): Semi // Must really do all the work for both this and cloned collection! def characteristics(): Int = Ordered def estimateSize(): Long = iN - i def substep(): Sub = if (estimateSize > 0) semiclone((iN + i) >>> 1) else null diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeTrieIterator.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeTrieIterator.scala index 78abd12..1d33216 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeTrieIterator.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeTrieIterator.scala @@ -23,7 +23,7 @@ extends AbstractStepsLikeSliced[Iterator[A], Sub, Semi] { protected def demiclone(it: Iterator[A], N: Int): Semi override def characteristics() = Immutable def hasNext(): Boolean = underlying.hasNext - def semiclone(halfHint: Int): Semi = + protected def semiclone(halfHint: Int): Semi = if (!underlying.hasNext || i > iN-2) null else scala.compat.java8.runtime.CollectionInternals.trieIteratorSplit(underlying) match { case null => null diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsLinearSeq.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsLinearSeq.scala index d78c893..d4c0958 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsLinearSeq.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsLinearSeq.scala @@ -27,7 +27,7 @@ extends StepsWithTail[A, collection.LinearSeq[A], StepsAnyLinearSeq[A]](_underly protected def myIsEmpty(cc: collection.LinearSeq[A]): Boolean = cc.isEmpty protected def myTailOf(cc: collection.LinearSeq[A]) = cc.tail def next() = if (hasNext()) { maxN -= 1; val ans = underlying.head; underlying = underlying.tail; ans } else throwNSEE - def semiclone(half: Int) = new StepsAnyLinearSeq[A](underlying, half) + protected def semiclone(half: Int) = new StepsAnyLinearSeq[A](underlying, half) } private[java8] class StepsDoubleLinearSeq(_underlying: collection.LinearSeq[Double], _maxN: Long) @@ -35,7 +35,7 @@ extends StepsDoubleWithTail[collection.LinearSeq[Double], StepsDoubleLinearSeq]( protected def myIsEmpty(cc: collection.LinearSeq[Double]): Boolean = cc.isEmpty protected def myTailOf(cc: collection.LinearSeq[Double]) = cc.tail def nextDouble() = if (hasNext()) { maxN -= 1; val ans = underlying.head; underlying = underlying.tail; ans } else throwNSEE - def semiclone(half: Int) = new StepsDoubleLinearSeq(underlying, half) + protected def semiclone(half: Int) = new StepsDoubleLinearSeq(underlying, half) } private[java8] class StepsIntLinearSeq(_underlying: collection.LinearSeq[Int], _maxN: Long) @@ -43,7 +43,7 @@ extends StepsIntWithTail[collection.LinearSeq[Int], StepsIntLinearSeq](_underlyi protected def myIsEmpty(cc: collection.LinearSeq[Int]): Boolean = cc.isEmpty protected def myTailOf(cc: collection.LinearSeq[Int]) = cc.tail def nextInt() = if (hasNext()) { maxN -= 1; val ans = underlying.head; underlying = underlying.tail; ans } else throwNSEE - def semiclone(half: Int) = new StepsIntLinearSeq(underlying, half) + protected def semiclone(half: Int) = new StepsIntLinearSeq(underlying, half) } private[java8] class StepsLongLinearSeq(_underlying: collection.LinearSeq[Long], _maxN: Long) @@ -51,7 +51,7 @@ extends StepsLongWithTail[collection.LinearSeq[Long], StepsLongLinearSeq](_under protected def myIsEmpty(cc: collection.LinearSeq[Long]): Boolean = cc.isEmpty protected def myTailOf(cc: collection.LinearSeq[Long]) = cc.tail def nextLong() = if (hasNext()) { maxN -= 1; val ans = underlying.head; underlying = underlying.tail; ans } else throwNSEE - def semiclone(half: Int) = new StepsLongLinearSeq(underlying, half) + protected def semiclone(half: Int) = new StepsLongLinearSeq(underlying, half) } ////////////////////////// diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsRange.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsRange.scala index a4c92a3..4060011 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsRange.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsRange.scala @@ -25,25 +25,25 @@ import Stepper._ private[java8] class StepsIntRange(underlying: Range, _i0: Int, _iN: Int) extends StepsIntLikeIndexed[StepsIntRange](_i0, _iN) { def nextInt() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE - def semiclone(half: Int) = new StepsIntRange(underlying, i0, half) + protected def semiclone(half: Int) = new StepsIntRange(underlying, i0, half) } private[java8] class StepsAnyNumericRange[T](underlying: collection.immutable.NumericRange[T], _i0: Int, _iN: Int) extends StepsLikeIndexed[T, StepsAnyNumericRange[T]](_i0, _iN) { def next() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE - def semiclone(half: Int) = new StepsAnyNumericRange[T](underlying, i0, half) + protected def semiclone(half: Int) = new StepsAnyNumericRange[T](underlying, i0, half) } private[java8] class StepsIntNumericRange(underlying: collection.immutable.NumericRange[Int], _i0: Int, _iN: Int) extends StepsIntLikeIndexed[StepsIntNumericRange](_i0, _iN) { def nextInt() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE - def semiclone(half: Int) = new StepsIntNumericRange(underlying, i0, half) + protected def semiclone(half: Int) = new StepsIntNumericRange(underlying, i0, half) } private[java8] class StepsLongNumericRange(underlying: collection.immutable.NumericRange[Long], _i0: Int, _iN: Int) extends StepsLongLikeIndexed[StepsLongNumericRange](_i0, _iN) { def nextLong() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE - def semiclone(half: Int) = new StepsLongNumericRange(underlying, i0, half) + protected def semiclone(half: Int) = new StepsLongNumericRange(underlying, i0, half) } ////////////////////////// diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsString.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsString.scala index adc78f7..c7a5dff 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsString.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsString.scala @@ -23,7 +23,7 @@ import Stepper._ private[java8] class StepperStringChar(underlying: CharSequence, _i0: Int, _iN: Int) extends StepsIntLikeIndexed[StepperStringChar](_i0, _iN) { def nextInt() = if (hasNext()) { val j = i0; i0 += 1; underlying.charAt(j) } else throwNSEE - def semiclone(half: Int) = new StepperStringChar(underlying, i0, half) + protected def semiclone(half: Int) = new StepperStringChar(underlying, i0, half) } private[java8] class StepperStringCodePoint(underlying: String, var i0: Int, var iN: Int) extends IntStepper with EfficientSubstep { diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsVector.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsVector.scala index 0c9a23e..c4aa7e3 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsVector.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsVector.scala @@ -116,7 +116,7 @@ with StepsVectorLike[A] { i0 += 1 data(index).asInstanceOf[A] } else throwNSEE - def semiclone(half: Int) = { + protected def semiclone(half: Int) = { val ans = new StepsAnyVector(underlying, i0, half) index = 32 index1 = 32 @@ -137,7 +137,7 @@ with StepsVectorLike[Double] { i0 += 1 data(index).asInstanceOf[Double] } else throwNSEE - def semiclone(half: Int) = { + protected def semiclone(half: Int) = { val ans = new StepsDoubleVector(underlying, i0, half) index = 32 index1 = 32 @@ -158,7 +158,7 @@ with StepsVectorLike[Int] { i0 += 1 data(index).asInstanceOf[Int] } else throwNSEE - def semiclone(half: Int) = { + protected def semiclone(half: Int) = { val ans = new StepsIntVector(underlying, i0, half) index = 32 index1 = 32 @@ -179,7 +179,7 @@ with StepsVectorLike[Long] { i0 += 1 data(index).asInstanceOf[Long] } else throwNSEE - def semiclone(half: Int) = { + protected def semiclone(half: Int) = { val ans = new StepsLongVector(underlying, i0, half) index = 32 index1 = 32 diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsWithTail.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsWithTail.scala index 04505a9..c20f997 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsWithTail.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsWithTail.scala @@ -37,7 +37,7 @@ private[java8] abstract class AbstractStepsWithTail[CC >: Null, Sub >: Null, Sem } this } - def semiclone(chunk: Int): Semi + protected def semiclone(chunk: Int): Semi def characteristics(): Int = if (maxN < Int.MaxValue) Ordered | Sized | SubSized else Ordered def estimateSize(): Long = if (maxN < Int.MaxValue) maxN else Long.MaxValue def hasNext(): Boolean = if (maxN < Int.MaxValue) maxN > 0 else if (myIsEmpty(underlying)) { maxN = 0; false } else true From f05a43b571082f712401827b296f207192d69743 Mon Sep 17 00:00:00 2001 From: Lukas Rytz Date: Wed, 28 Nov 2018 08:51:37 +0100 Subject: [PATCH 10/13] Consistently use empty param list for effectful methods --- .../main/scala/bench/CollectionSource.scala | 2 +- fnGen/WrapFnGen.scala | 4 +- .../java8/PrimitiveIteratorConversions.scala | 12 +- .../scala/compat/java8/StreamConverters.scala | 8 +- .../java8/collectionImpl/Accumulator.scala | 6 +- .../collectionImpl/DoubleAccumulator.scala | 4 +- .../java8/collectionImpl/IntAccumulator.scala | 4 +- .../collectionImpl/LongAccumulator.scala | 4 +- .../compat/java8/collectionImpl/Stepper.scala | 110 +++++++++--------- .../converterImpl/AccumulatorConverters.scala | 2 +- .../java8/converterImpl/StepsArray.scala | 18 +-- .../java8/converterImpl/StepsBitSet.scala | 2 +- .../java8/converterImpl/StepsImmHashSet.scala | 8 +- .../java8/converterImpl/StepsIndexedSeq.scala | 8 +- .../java8/converterImpl/StepsIterator.scala | 8 +- .../java8/converterImpl/StepsLikeGapped.scala | 4 +- .../converterImpl/StepsLikeIndexed.scala | 4 +- .../converterImpl/StepsLikeIterator.scala | 28 ++--- .../java8/converterImpl/StepsLikeSliced.scala | 2 +- .../converterImpl/StepsLikeTrieIterator.scala | 4 +- .../java8/converterImpl/StepsLinearSeq.scala | 8 +- .../java8/converterImpl/StepsRange.scala | 8 +- .../java8/converterImpl/StepsString.scala | 6 +- .../java8/converterImpl/StepsVector.scala | 8 +- .../java8/converterImpl/StepsWithTail.scala | 4 +- .../scala/compat/java8/StepperTest.scala | 20 ++-- 26 files changed, 148 insertions(+), 148 deletions(-) diff --git a/benchmark/src/main/scala/bench/CollectionSource.scala b/benchmark/src/main/scala/bench/CollectionSource.scala index 38c1291..5f0bb49 100644 --- a/benchmark/src/main/scala/bench/CollectionSource.scala +++ b/benchmark/src/main/scala/bench/CollectionSource.scala @@ -233,7 +233,7 @@ package object generate { implicit val arrayIntToIterator: (Array[Int] => Iterator[Int]) = (a: Array[Int]) => new Iterator[Int] { private[this] var i = 0 def hasNext = i < a.length - def next = if (hasNext) { var ans = a(i); i += 1; ans } else throw new NoSuchElementException(i.toString) + def next() = if (hasNext) { var ans = a(i); i += 1; ans } else throw new NoSuchElementException(i.toString) } implicit val arrayStringToIterator: (Array[String] => Iterator[String]) = _.iterator } diff --git a/fnGen/WrapFnGen.scala b/fnGen/WrapFnGen.scala index 3d0b560..7045f0b 100644 --- a/fnGen/WrapFnGen.scala +++ b/fnGen/WrapFnGen.scala @@ -247,7 +247,7 @@ object WrapFnGen { numberedA ++= scalaTargs.map(_.toString).collect{ case An(digits) if (digits.length < 10) => digits.toInt } val scalafnTnames = (jfn.pTypes :+ jfn.rType).zipWithIndex.map{ case (pt, i) if (i < jfn.pTypes.length && pt.isFinalType) || (!pt.isFinalType && jfn.pTypes.take(i).exists(_ == pt)) => - val j = Iterator.from(i).dropWhile(numberedA).next + val j = Iterator.from(i).dropWhile(numberedA).next() val genericName = TypeName(s"A$j") numberedA += j evidences += ((genericName, pt.typeSymbol.name.toTypeName)) @@ -312,6 +312,6 @@ object WrapFnGen { def main(args: Array[String]): Unit = { val names = args.iterator.map(x => new java.io.File(x)) - write(names.next, converterContents) + write(names.next(), converterContents) } } diff --git a/src/main/scala/scala/compat/java8/PrimitiveIteratorConversions.scala b/src/main/scala/scala/compat/java8/PrimitiveIteratorConversions.scala index 2d80ba6..d0abb4d 100644 --- a/src/main/scala/scala/compat/java8/PrimitiveIteratorConversions.scala +++ b/src/main/scala/scala/compat/java8/PrimitiveIteratorConversions.scala @@ -53,10 +53,10 @@ object PrimitiveIteratorConverters { def nextDouble() = it.next() override def remove(): Unit = { throw new UnsupportedOperationException("remove on scala.collection.Iterator") } override def forEachRemaining(c: java.util.function.Consumer[_ >: java.lang.Double]): Unit = { - while (it.hasNext) c.accept(it.next) + while (it.hasNext) c.accept(it.next()) } override def forEachRemaining(c: java.util.function.DoubleConsumer): Unit = { - while (it.hasNext) c.accept(it.next) + while (it.hasNext) c.accept(it.next()) } } } @@ -74,10 +74,10 @@ object PrimitiveIteratorConverters { def nextInt() = it.next() override def remove(): Unit = { throw new UnsupportedOperationException("remove on scala.collection.Iterator") } override def forEachRemaining(c: java.util.function.Consumer[_ >: java.lang.Integer]): Unit = { - while (it.hasNext) c.accept(it.next) + while (it.hasNext) c.accept(it.next()) } override def forEachRemaining(c: java.util.function.IntConsumer): Unit = { - while (it.hasNext) c.accept(it.next) + while (it.hasNext) c.accept(it.next()) } } } @@ -95,10 +95,10 @@ object PrimitiveIteratorConverters { def nextLong() = it.next() override def remove(): Unit = { throw new UnsupportedOperationException("remove on scala.collection.Iterator") } override def forEachRemaining(c: java.util.function.Consumer[_ >: java.lang.Long]): Unit = { - while (it.hasNext) c.accept(it.next) + while (it.hasNext) c.accept(it.next()) } override def forEachRemaining(c: java.util.function.LongConsumer): Unit = { - while (it.hasNext) c.accept(it.next) + while (it.hasNext) c.accept(it.next()) } } } diff --git a/src/main/scala/scala/compat/java8/StreamConverters.scala b/src/main/scala/scala/compat/java8/StreamConverters.scala index 0975d9e..e902491 100644 --- a/src/main/scala/scala/compat/java8/StreamConverters.scala +++ b/src/main/scala/scala/compat/java8/StreamConverters.scala @@ -51,7 +51,7 @@ trait StreamShapeLowPriority { final def fromStepper (mk: MakesStepper[T, _], par: Boolean): S = stream(mk.stepper, par) final def fromKeyStepper (mk: MakesKeyValueStepper[T, _, _], par: Boolean): S = stream(mk.keyStepper, par) final def fromValueStepper(mk: MakesKeyValueStepper[_, T, _], par: Boolean): S = stream(mk.valueStepper, par) - @inline private[this] def stream(st: St, par: Boolean): S = mkStream(if(par) st.anticipateParallelism else st, par) + @inline private[this] def stream(st: St, par: Boolean): S = mkStream(if(par) st.anticipateParallelism() else st, par) protected[this] def mkStream(st: St, par: Boolean): S } protected[this] def intStreamShape[T](implicit ss: StepperShape[T, IntStepper]): StreamShape[T, IntStream] = new BaseStreamShape[T, IntStream, IntStepper] { @@ -330,7 +330,7 @@ with converterImpl.Priority1AccumulatorConverters new AccumulatesFromStepper[Double, DoubleAccumulator] { def apply(stepper: Stepper[Double]) = { val a = new DoubleAccumulator - while (stepper.hasStep) a += stepper.nextStep + while (stepper.hasStep) a += stepper.nextStep() a } } @@ -339,7 +339,7 @@ with converterImpl.Priority1AccumulatorConverters new AccumulatesFromStepper[Int, IntAccumulator] { def apply(stepper: Stepper[Int]) = { val a = new IntAccumulator - while (stepper.hasStep) a += stepper.nextStep + while (stepper.hasStep) a += stepper.nextStep() a } } @@ -348,7 +348,7 @@ with converterImpl.Priority1AccumulatorConverters new AccumulatesFromStepper[Long, LongAccumulator] { def apply(stepper: Stepper[Long]) = { val a = new LongAccumulator - while (stepper.hasStep) a += stepper.nextStep + while (stepper.hasStep) a += stepper.nextStep() a } } diff --git a/src/main/scala/scala/compat/java8/collectionImpl/Accumulator.scala b/src/main/scala/scala/compat/java8/collectionImpl/Accumulator.scala index b8c6743..c7642eb 100644 --- a/src/main/scala/scala/compat/java8/collectionImpl/Accumulator.scala +++ b/src/main/scala/scala/compat/java8/collectionImpl/Accumulator.scala @@ -121,7 +121,7 @@ final class Accumulator[A] extends AccumulatorLike[A, Accumulator[A]] { self => history((w >>> 32).toInt)((w & 0xFFFFFFFFL).toInt).asInstanceOf[A] } } - + /** Retrieves the `ix`th element, using an `Int` index. */ final def apply(i: Int): A = apply(i.toLong) @@ -266,13 +266,13 @@ private[java8] class AccumulatorStepper[A](private val acc: Accumulator[A]) exte i = 0 } - def characteristics() = ORDERED | SIZED | SUBSIZED + def characteristics = ORDERED | SIZED | SUBSIZED def estimateSize = N def hasNext = N > 0 - def next: A = + def next(): A = if (N <= 0) throw new NoSuchElementException("Next in empty Stepper") else { if (i >= n) loadMore() diff --git a/src/main/scala/scala/compat/java8/collectionImpl/DoubleAccumulator.scala b/src/main/scala/scala/compat/java8/collectionImpl/DoubleAccumulator.scala index 00487e5..b40b997 100644 --- a/src/main/scala/scala/compat/java8/collectionImpl/DoubleAccumulator.scala +++ b/src/main/scala/scala/compat/java8/collectionImpl/DoubleAccumulator.scala @@ -260,13 +260,13 @@ private[java8] class DoubleAccumulatorStepper(private val acc: DoubleAccumulator i = 0 } - def characteristics() = ORDERED | SIZED | SUBSIZED | NONNULL + def characteristics = ORDERED | SIZED | SUBSIZED | NONNULL def estimateSize = N def hasNext = N > 0 - def nextDouble: Double = + def nextDouble(): Double = if (n <= 0) throw new NoSuchElementException("next on empty Stepper") else { if (i >= n) loadMore() diff --git a/src/main/scala/scala/compat/java8/collectionImpl/IntAccumulator.scala b/src/main/scala/scala/compat/java8/collectionImpl/IntAccumulator.scala index 2ff0ef7..2100bb6 100644 --- a/src/main/scala/scala/compat/java8/collectionImpl/IntAccumulator.scala +++ b/src/main/scala/scala/compat/java8/collectionImpl/IntAccumulator.scala @@ -267,13 +267,13 @@ private[java8] class IntAccumulatorStepper(private val acc: IntAccumulator) exte i = 0 } - def characteristics() = ORDERED | SIZED | SUBSIZED | NONNULL + def characteristics = ORDERED | SIZED | SUBSIZED | NONNULL def estimateSize = N def hasNext = N > 0 - def nextInt: Int = + def nextInt(): Int = if (N <= 0) throw new NoSuchElementException("next on empty Stepper") else { if (i >= n) loadMore() diff --git a/src/main/scala/scala/compat/java8/collectionImpl/LongAccumulator.scala b/src/main/scala/scala/compat/java8/collectionImpl/LongAccumulator.scala index 84c9495..978fba3 100644 --- a/src/main/scala/scala/compat/java8/collectionImpl/LongAccumulator.scala +++ b/src/main/scala/scala/compat/java8/collectionImpl/LongAccumulator.scala @@ -261,13 +261,13 @@ private[java8] class LongAccumulatorStepper(private val acc: LongAccumulator) ex i = 0 } - def characteristics() = ORDERED | SIZED | SUBSIZED | NONNULL + def characteristics = ORDERED | SIZED | SUBSIZED | NONNULL def estimateSize = N def hasNext = N > 0 - def nextLong: Long = + def nextLong(): Long = if (n <= 0) throw new NoSuchElementException("next on empty Stepper") else { if (i >= n) loadMore() diff --git a/src/main/scala/scala/compat/java8/collectionImpl/Stepper.scala b/src/main/scala/scala/compat/java8/collectionImpl/Stepper.scala index 8760b5c..2a35ff5 100644 --- a/src/main/scala/scala/compat/java8/collectionImpl/Stepper.scala +++ b/src/main/scala/scala/compat/java8/collectionImpl/Stepper.scala @@ -43,7 +43,7 @@ import java.util.Spliterator * Example: * {{{ * val s = Stepper.of(Vector(1,2,3,4)) - * if (s.hasStep) println(s.nextStep) // Prints 1 + * if (s.hasStep) println(s.nextStep()) // Prints 1 * println(s.tryStep(i => println(i*i))) // Prints 2, then true * s.substep.foreach(println) // Prints 3 * println(s.count(_ > 3)) // Prints 4 @@ -80,7 +80,7 @@ trait StepperLike[@specialized(Double, Int, Long) A, +CC] { self: CC => * guaranteed to be any safer than modification of any generic mutable collection, and if the underlying collection is ordered by * virtue of sorting, `Stepper` will not keep track of that fact. */ - def characteristics(): Int + def characteristics: Int /** Returns the size of the collection, if known exactly, or `-1` if not. */ def knownSize: Long @@ -105,7 +105,7 @@ trait StepperLike[@specialized(Double, Int, Long) A, +CC] { self: CC => def substep(): CC /** Warns this `Stepper` that it is likely to be used in a parallel context (used for efficiency only) */ - def anticipateParallelism: this.type = this + def anticipateParallelism(): this.type = this //// @@ -117,48 +117,48 @@ trait StepperLike[@specialized(Double, Int, Long) A, +CC] { self: CC => * iterate over the elements. */ def count(): Long = knownSize match { - case x if x < 0 => var n = 0L; while (hasStep) { nextStep; n += 1 }; n + case x if x < 0 => var n = 0L; while (hasStep) { nextStep(); n += 1 }; n case x => x } /** Consumes all remaining elements in this `Stepper` and counts how many satisfy condition `p`. * This is a terminal operation. */ - def count(p: A => Boolean): Long = { var n = 0L; while (hasStep) { if (p(nextStep)) n += 1 }; n } + def count(p: A => Boolean): Long = { var n = 0L; while (hasStep) { if (p(nextStep())) n += 1 }; n } /** Searches for an element that satisfies condition `p`. If none are found, it returns `false`. * This is a terminal operation. */ - def exists(p: A => Boolean): Boolean = { while(hasStep) { if (p(nextStep)) return true }; false } + def exists(p: A => Boolean): Boolean = { while(hasStep) { if (p(nextStep())) return true }; false } /** Searches for an element that satisifes condition `p`, returning it wrapped in `Some` if one is found, or `None` otherwise. * This is a terminal operation. */ - def find(p: A => Boolean): Option[A] = { while (hasStep) { val a = nextStep; if (p(a)) return Some(a) }; None } + def find(p: A => Boolean): Option[A] = { while (hasStep) { val a = nextStep(); if (p(a)) return Some(a) }; None } /** Repeatedly applies `op` to propagate an initial value `zero` through all elements of the collection. * Traversal order is left-to-right. * This is a terminal operation. */ - def fold[@specialized(Double, Int, Long) B](zero: B)(op: (B, A) => B) = { var b = zero; while (hasStep) { b = op(b, nextStep) }; b } + def fold[@specialized(Double, Int, Long) B](zero: B)(op: (B, A) => B) = { var b = zero; while (hasStep) { b = op(b, nextStep()) }; b } /** Repeatedly applies `op` to propagate an initial value `zero` through the collection until a condition `p` is met. * If `p` is never met, the result of the last operation is returned. * This is a terminal operation. */ - def foldTo[@specialized(Double, Int, Long) B](zero: B)(op: (B, A) => B)(p: B => Boolean) = { var b = zero; while (!p(b) && hasStep) { b = op(b, nextStep) }; b } + def foldTo[@specialized(Double, Int, Long) B](zero: B)(op: (B, A) => B)(p: B => Boolean) = { var b = zero; while (!p(b) && hasStep) { b = op(b, nextStep()) }; b } /** Applies `f` to every remaining element in the collection. * This is a terminal operation. */ - def foreach(f: A => Unit): Unit = { while (hasStep) f(nextStep) } + def foreach(f: A => Unit): Unit = { while (hasStep) f(nextStep()) } /** Repeatedly merges elements with `op` until only a single element remains. * Throws an exception if the `Stepper` is empty. * Merging occurs from left to right. * This is a terminal operation. */ - def reduce(op: (A, A) => A): A = { var a = nextStep; while (hasStep) { a = op(a, nextStep) }; a } + def reduce(op: (A, A) => A): A = { var a = nextStep(); while (hasStep) { a = op(a, nextStep()) }; a } //// @@ -175,13 +175,13 @@ trait StepperLike[@specialized(Double, Int, Long) A, +CC] { self: CC => */ def iterator: Iterator[A] = new scala.collection.AbstractIterator[A] { def hasNext = self.hasStep - def next = self.nextStep + def next() = self.nextStep() } /** Returns a Scala collection of the type requested. */ def to[Coll[_]](implicit factory: collection.Factory[A, Coll[A]]): Coll[A] = { val b = factory.newBuilder - while (hasStep) b += nextStep + while (hasStep) b += nextStep() b.result() } } @@ -193,7 +193,7 @@ trait NextStepper[@specialized(Double, Int, Long) A] extends Stepper[A] with Ste def spliterator: Spliterator[A] = new ProxySpliteratorViaNext[A](this) } private[collectionImpl] class ProxySpliteratorViaNext[A](underlying: NextStepper[A]) extends Spliterator[A] { - def characteristics() = underlying.characteristics + def characteristics = underlying.characteristics def estimateSize() = underlying.knownSize def tryAdvance(f: java.util.function.Consumer[_ >: A]): Boolean = if (underlying.hasStep) { f.accept(underlying.nextStep()); true } else false def trySplit() = underlying.substep() match { case null => null; case x => new ProxySpliteratorViaNext[A](x) } @@ -213,7 +213,7 @@ trait TryStepper[@specialized(Double, Int, Long) A] extends Stepper[A] with Step myCacheIsFull } final def hasStep = myCacheIsFull || load() - final def nextStep = { + final def nextStep() = { if (!myCacheIsFull) { load() if (!myCacheIsFull) Stepper.throwNSEE @@ -232,7 +232,7 @@ trait TryStepper[@specialized(Double, Int, Long) A] extends Stepper[A] with Step def spliterator: Spliterator[A] = new ProxySpliteratorViaTry[A](this) } private[collectionImpl] class ProxySpliteratorViaTry[A](underlying: TryStepper[A]) extends Spliterator[A] { - def characteristics() = underlying.characteristics + def characteristics = underlying.characteristics def estimateSize() = underlying.knownSize def tryAdvance(f: java.util.function.Consumer[_ >: A]): Boolean = underlying.tryStep(a => f.accept(a)) override def forEachRemaining(f: java.util.function.Consumer[_ >: A]): Unit = { underlying.foreach(a => f.accept(a)) } @@ -241,13 +241,13 @@ private[collectionImpl] class ProxySpliteratorViaTry[A](underlying: TryStepper[A /** Any `AnyStepper` combines the functionality of a Java `Iterator`, a Java `Spliterator`, and a `Stepper`. */ trait AnyStepper[A] extends Stepper[A] with java.util.Iterator[A] with Spliterator[A] with StepperLike[A, AnyStepper[A]] { - override def forEachRemaining(c: java.util.function.Consumer[_ >: A]): Unit = { while (hasNext) { c.accept(next) } } - def hasStep = hasNext() + override def forEachRemaining(c: java.util.function.Consumer[_ >: A]): Unit = { while (hasNext) { c.accept(next()) } } + def hasStep = hasNext def knownSize = getExactSizeIfKnown - def nextStep = next - def tryAdvance(c: java.util.function.Consumer[_ >: A]): Boolean = if (hasNext) { c.accept(next); true } else false - def tryStep(f: A => Unit): Boolean = if (hasNext) { f(next); true } else false - def trySplit() = substep + def nextStep() = next() + def tryAdvance(c: java.util.function.Consumer[_ >: A]): Boolean = if (hasNext) { c.accept(next()); true } else false + def tryStep(f: A => Unit): Boolean = if (hasNext) { f(next()); true } else false + def trySplit() = substep() override def spliterator: Spliterator[A] = this def seqStream: java.util.stream.Stream[A] = java.util.stream.StreamSupport.stream(this, false) def parStream: java.util.stream.Stream[A] = java.util.stream.StreamSupport.stream(this, true) @@ -255,25 +255,25 @@ trait AnyStepper[A] extends Stepper[A] with java.util.Iterator[A] with Spliterat private[collectionImpl] object AnyStepper { final class BoxedDoubleStepper(st: DoubleStepper) extends AnyStepper[Double] { - def hasNext(): Boolean = st.hasNext() + def hasNext: Boolean = st.hasNext def next(): Double = st.next() - def characteristics(): Int = st.characteristics() + def characteristics: Int = st.characteristics def estimateSize(): Long = st.estimateSize() def substep(): AnyStepper[Double] = new BoxedDoubleStepper(st.substep()) } final class BoxedIntStepper(st: IntStepper) extends AnyStepper[Int] { - def hasNext(): Boolean = st.hasNext() + def hasNext: Boolean = st.hasNext def next(): Int = st.next() - def characteristics(): Int = st.characteristics() + def characteristics: Int = st.characteristics def estimateSize(): Long = st.estimateSize() def substep(): AnyStepper[Int] = new BoxedIntStepper(st.substep()) } final class BoxedLongStepper(st: LongStepper) extends AnyStepper[Long] { - def hasNext(): Boolean = st.hasNext() + def hasNext: Boolean = st.hasNext def next(): Long = st.next() - def characteristics(): Int = st.characteristics() + def characteristics: Int = st.characteristics def estimateSize(): Long = st.estimateSize() def substep(): AnyStepper[Long] = new BoxedLongStepper(st.substep()) } @@ -283,13 +283,13 @@ private[collectionImpl] object AnyStepper { trait DoubleStepper extends Stepper[Double] with java.util.PrimitiveIterator.OfDouble with Spliterator.OfDouble with StepperLike[Double, DoubleStepper] { override def forEachRemaining(c: java.util.function.Consumer[_ >: java.lang.Double]): Unit = { while (hasNext) { c.accept(java.lang.Double.valueOf(nextDouble)) } } override def forEachRemaining(c: java.util.function.DoubleConsumer): Unit = { while (hasNext) { c.accept(nextDouble) } } - def hasStep = hasNext() + def hasStep = hasNext def knownSize = getExactSizeIfKnown - def nextStep = nextDouble + def nextStep() = nextDouble override def tryAdvance(c: java.util.function.Consumer[_ >: java.lang.Double]): Boolean = if (hasNext) { c.accept(java.lang.Double.valueOf(nextDouble)); true } else false def tryAdvance(c: java.util.function.DoubleConsumer): Boolean = if (hasNext) { c.accept(nextDouble); true } else false def tryStep(f: Double => Unit): Boolean = if (hasNext) { f(nextDouble); true } else false - def trySplit() = substep + def trySplit() = substep() override def spliterator: Spliterator[Double] = this.asInstanceOf[Spliterator[Double]] // Scala and Java disagree about whether it's java.lang.Double or double def seqStream: java.util.stream.DoubleStream = java.util.stream.StreamSupport.doubleStream(this, false) def parStream: java.util.stream.DoubleStream = java.util.stream.StreamSupport.doubleStream(this, true) @@ -299,13 +299,13 @@ trait DoubleStepper extends Stepper[Double] with java.util.PrimitiveIterator.OfD trait IntStepper extends Stepper[Int] with java.util.PrimitiveIterator.OfInt with Spliterator.OfInt with StepperLike[Int, IntStepper] { override def forEachRemaining(c: java.util.function.Consumer[_ >: java.lang.Integer]): Unit = { while (hasNext) { c.accept(java.lang.Integer.valueOf(nextInt)) } } override def forEachRemaining(c: java.util.function.IntConsumer): Unit = { while (hasNext) { c.accept(nextInt) } } - def hasStep = hasNext() + def hasStep = hasNext def knownSize = getExactSizeIfKnown - def nextStep = nextInt + def nextStep() = nextInt override def tryAdvance(c: java.util.function.Consumer[_ >: java.lang.Integer]): Boolean = if (hasNext) { c.accept(java.lang.Integer.valueOf(nextInt)); true } else false def tryAdvance(c: java.util.function.IntConsumer): Boolean = if (hasNext) { c.accept(nextInt); true } else false def tryStep(f: Int => Unit): Boolean = if (hasNext) { f(nextInt); true } else false - def trySplit() = substep + def trySplit() = substep() override def spliterator: Spliterator[Int] = this.asInstanceOf[Spliterator[Int]] // Scala and Java disagree about whether it's java.lang.Integer or int def seqStream: java.util.stream.IntStream = java.util.stream.StreamSupport.intStream(this, false) def parStream: java.util.stream.IntStream = java.util.stream.StreamSupport.intStream(this, true) @@ -315,13 +315,13 @@ trait IntStepper extends Stepper[Int] with java.util.PrimitiveIterator.OfInt wit trait LongStepper extends Stepper[Long] with java.util.PrimitiveIterator.OfLong with Spliterator.OfLong with StepperLike[Long, LongStepper] { override def forEachRemaining(c: java.util.function.Consumer[_ >: java.lang.Long]): Unit = { while (hasNext) { c.accept(java.lang.Long.valueOf(nextLong)) } } override def forEachRemaining(c: java.util.function.LongConsumer): Unit = { while (hasNext) { c.accept(nextLong) } } - def hasStep = hasNext() + def hasStep = hasNext def knownSize = getExactSizeIfKnown - def nextStep = nextLong + def nextStep() = nextLong override def tryAdvance(c: java.util.function.Consumer[_ >: java.lang.Long]): Boolean = if (hasNext) { c.accept(java.lang.Long.valueOf(nextLong)); true } else false def tryAdvance(c: java.util.function.LongConsumer): Boolean = if (hasNext) { c.accept(nextLong); true } else false def tryStep(f: Long => Unit): Boolean = if (hasNext) { f(nextLong); true } else false - def trySplit() = substep + def trySplit() = substep() override def spliterator: Spliterator[Long] = this.asInstanceOf[Spliterator[Long]] // Scala and Java disagree about whether it's java.lang.Long or long def seqStream: java.util.stream.LongStream = java.util.stream.StreamSupport.longStream(this, false) def parStream: java.util.stream.LongStream = java.util.stream.StreamSupport.longStream(this, true) @@ -378,7 +378,7 @@ object Stepper { sp.forEachRemaining(c) } def hasNext = cached || loadCache - def next = { + def next() = { if (!hasNext) throwNSEE val ans = cache cache = null.asInstanceOf[A] @@ -429,7 +429,7 @@ object Stepper { sp.forEachRemaining(c) } def hasNext = cached || loadCache - def nextDouble = { + def nextDouble() = { if (!hasNext) throwNSEE val ans = cache cached = false @@ -478,7 +478,7 @@ object Stepper { sp.forEachRemaining(c) } def hasNext = cached || loadCache - def nextInt = { + def nextInt() = { if (!hasNext) throwNSEE val ans = cache cached = false @@ -527,7 +527,7 @@ object Stepper { sp.forEachRemaining(c) } def hasNext = cached || loadCache - def nextLong = { + def nextLong() = { if (!hasNext) throwNSEE val ans = cache cached = false @@ -584,57 +584,57 @@ object Stepper { * (see for example StepsIntArray and StepsWidenedByteArray). */ private[java8] class UnboxingDoubleStepper(st: AnyStepper[Double]) extends DoubleStepper { - def hasNext(): Boolean = st.hasNext() + def hasNext: Boolean = st.hasNext def nextDouble(): Double = st.next() - def characteristics(): Int = st.characteristics() + def characteristics: Int = st.characteristics def estimateSize(): Long = st.estimateSize() def substep(): DoubleStepper = new UnboxingDoubleStepper(st.substep()) } private[java8] class UnboxingIntStepper(st: AnyStepper[Int]) extends IntStepper { - def hasNext(): Boolean = st.hasNext() + def hasNext: Boolean = st.hasNext def nextInt(): Int = st.next() - def characteristics(): Int = st.characteristics() + def characteristics: Int = st.characteristics def estimateSize(): Long = st.estimateSize() def substep(): IntStepper = new UnboxingIntStepper(st.substep()) } private[java8] class UnboxingLongStepper(st: AnyStepper[Long]) extends LongStepper { - def hasNext(): Boolean = st.hasNext() + def hasNext: Boolean = st.hasNext def nextLong(): Long = st.next() - def characteristics(): Int = st.characteristics() + def characteristics: Int = st.characteristics def estimateSize(): Long = st.estimateSize() def substep(): LongStepper = new UnboxingLongStepper(st.substep()) } private[java8] class UnboxingByteStepper(st: AnyStepper[Byte]) extends IntStepper { - def hasNext(): Boolean = st.hasNext() + def hasNext: Boolean = st.hasNext def nextInt(): Int = st.next() - def characteristics(): Int = st.characteristics() | NonNull + def characteristics: Int = st.characteristics | NonNull def estimateSize(): Long = st.estimateSize() def substep(): IntStepper = new UnboxingByteStepper(st.substep()) } private[java8] class UnboxingCharStepper(st: AnyStepper[Char]) extends IntStepper { - def hasNext(): Boolean = st.hasNext() + def hasNext: Boolean = st.hasNext def nextInt(): Int = st.next() - def characteristics(): Int = st.characteristics() | NonNull + def characteristics: Int = st.characteristics | NonNull def estimateSize(): Long = st.estimateSize() def substep(): IntStepper = new UnboxingCharStepper(st.substep()) } private[java8] class UnboxingShortStepper(st: AnyStepper[Short]) extends IntStepper { - def hasNext(): Boolean = st.hasNext() + def hasNext: Boolean = st.hasNext def nextInt(): Int = st.next() - def characteristics(): Int = st.characteristics() | NonNull + def characteristics: Int = st.characteristics | NonNull def estimateSize(): Long = st.estimateSize() def substep(): IntStepper = new UnboxingShortStepper(st.substep()) } private[java8] class UnboxingFloatStepper(st: AnyStepper[Float]) extends DoubleStepper { - def hasNext(): Boolean = st.hasNext() + def hasNext: Boolean = st.hasNext def nextDouble(): Double = st.next() - def characteristics(): Int = st.characteristics() | NonNull + def characteristics: Int = st.characteristics | NonNull def estimateSize(): Long = st.estimateSize() def substep(): DoubleStepper = new UnboxingFloatStepper(st.substep()) } diff --git a/src/main/scala/scala/compat/java8/converterImpl/AccumulatorConverters.scala b/src/main/scala/scala/compat/java8/converterImpl/AccumulatorConverters.scala index beeabf1..8a1c46f 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/AccumulatorConverters.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/AccumulatorConverters.scala @@ -40,7 +40,7 @@ private[java8] object PrivateAccumulatorConverters { val genericAccumulateAnyStepper: AccumulatesFromStepper[Any, Accumulator[Any]] = new AccumulatesFromStepper[Any, Accumulator[Any]] { def apply(stepper: Stepper[Any]) = { val a = new Accumulator[Any] - while (stepper.hasStep) a += stepper.nextStep + while (stepper.hasStep) a += stepper.nextStep() a } } diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsArray.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsArray.scala index 410d0f4..8ebaf34 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsArray.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsArray.scala @@ -24,55 +24,55 @@ import Stepper._ private[java8] class StepsObjectArray[A <: Object](underlying: Array[A], _i0: Int, _iN: Int) extends StepsLikeIndexed[A, StepsObjectArray[A]](_i0, _iN) { - def next() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE + def next() = if (hasNext) { val j = i0; i0 += 1; underlying(j) } else throwNSEE protected def semiclone(half: Int) = new StepsObjectArray[A](underlying, i0, half) } private[java8] class StepsBoxedBooleanArray(underlying: Array[Boolean], _i0: Int, _iN: Int) extends StepsLikeIndexed[Boolean, StepsBoxedBooleanArray](_i0, _iN) { - def next() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE + def next() = if (hasNext) { val j = i0; i0 += 1; underlying(j) } else throwNSEE protected def semiclone(half: Int) = new StepsBoxedBooleanArray(underlying, i0, half) } private[java8] class StepsWidenedByteArray(underlying: Array[Byte], _i0: Int, _iN: Int) extends StepsIntLikeIndexed[StepsWidenedByteArray](_i0, _iN) { - def nextInt() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE + def nextInt() = if (hasNext) { val j = i0; i0 += 1; underlying(j) } else throwNSEE protected def semiclone(half: Int) = new StepsWidenedByteArray(underlying, i0, half) } private[java8] class StepsWidenedCharArray(underlying: Array[Char], _i0: Int, _iN: Int) extends StepsIntLikeIndexed[StepsWidenedCharArray](_i0, _iN) { - def nextInt() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE + def nextInt() = if (hasNext) { val j = i0; i0 += 1; underlying(j) } else throwNSEE protected def semiclone(half: Int) = new StepsWidenedCharArray(underlying, i0, half) } private[java8] class StepsWidenedShortArray(underlying: Array[Short], _i0: Int, _iN: Int) extends StepsIntLikeIndexed[StepsWidenedShortArray](_i0, _iN) { - def nextInt() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE + def nextInt() = if (hasNext) { val j = i0; i0 += 1; underlying(j) } else throwNSEE protected def semiclone(half: Int) = new StepsWidenedShortArray(underlying, i0, half) } private[java8] class StepsWidenedFloatArray(underlying: Array[Float], _i0: Int, _iN: Int) extends StepsDoubleLikeIndexed[StepsWidenedFloatArray](_i0, _iN) { - def nextDouble() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE + def nextDouble() = if (hasNext) { val j = i0; i0 += 1; underlying(j) } else throwNSEE protected def semiclone(half: Int) = new StepsWidenedFloatArray(underlying, i0, half) } private[java8] class StepsDoubleArray(underlying: Array[Double], _i0: Int, _iN: Int) extends StepsDoubleLikeIndexed[StepsDoubleArray](_i0, _iN) { - def nextDouble() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE + def nextDouble() = if (hasNext) { val j = i0; i0 += 1; underlying(j) } else throwNSEE protected def semiclone(half: Int) = new StepsDoubleArray(underlying, i0, half) } private[java8] class StepsIntArray(underlying: Array[Int], _i0: Int, _iN: Int) extends StepsIntLikeIndexed[StepsIntArray](_i0, _iN) { - def nextInt() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE + def nextInt() = if (hasNext) { val j = i0; i0 += 1; underlying(j) } else throwNSEE protected def semiclone(half: Int) = new StepsIntArray(underlying, i0, half) } private[java8] class StepsLongArray(underlying: Array[Long], _i0: Int, _iN: Int) extends StepsLongLikeIndexed[StepsLongArray](_i0, _iN) { - def nextLong() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE + def nextLong() = if (hasNext) { val j = i0; i0 += 1; underlying(j) } else throwNSEE protected def semiclone(half: Int) = new StepsLongArray(underlying, i0, half) } diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsBitSet.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsBitSet.scala index d0392f6..c7c95c3 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsBitSet.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsBitSet.scala @@ -34,7 +34,7 @@ extends StepsIntLikeSliced[Array[Long], StepsIntBitSet](_underlying, _i0, _iN) { found = false ans } - def hasNext(): Boolean = found || ((i < iN) && { + def hasNext: Boolean = found || ((i < iN) && { while ((mask & cache) == 0) { i += java.lang.Long.numberOfLeadingZeros(~mask) if (i < 0 || i >= iN) { i = iN; return false } diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsImmHashSet.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsImmHashSet.scala index 864a3c2..a2a4eeb 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsImmHashSet.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsImmHashSet.scala @@ -23,25 +23,25 @@ import scala.compat.java8.collectionImpl._ private[java8] class StepsAnyImmHashSet[A](_underlying: Iterator[A], _N: Int) extends StepsLikeTrieIterator[A, StepsAnyImmHashSet[A]](_underlying, _N) { protected def demiclone(it: Iterator[A], N: Int) = new StepsAnyImmHashSet(it, N) - def next(): A = { val ans = underlying.next; i += 1; ans } + def next(): A = { val ans = underlying.next(); i += 1; ans } } private[java8] class StepsDoubleImmHashSet(_underlying: Iterator[Double], _N: Int) extends StepsDoubleLikeTrieIterator[StepsDoubleImmHashSet](_underlying, _N) { protected def demiclone(it: Iterator[Double], N: Int) = new StepsDoubleImmHashSet(it, N) - def nextDouble() = { val ans = underlying.next; i += 1; ans } + def nextDouble() = { val ans = underlying.next(); i += 1; ans } } private[java8] class StepsIntImmHashSet(_underlying: Iterator[Int], _N: Int) extends StepsIntLikeTrieIterator[StepsIntImmHashSet](_underlying, _N) { protected def demiclone(it: Iterator[Int], N: Int) = new StepsIntImmHashSet(it, N) - def nextInt() = { val ans = underlying.next; i += 1; ans } + def nextInt() = { val ans = underlying.next(); i += 1; ans } } private[java8] class StepsLongImmHashSet(_underlying: Iterator[Long], _N: Int) extends StepsLongLikeTrieIterator[StepsLongImmHashSet](_underlying, _N) { protected def demiclone(it: Iterator[Long], N: Int) = new StepsLongImmHashSet(it, N) - def nextLong() = { val ans = underlying.next; i += 1; ans } + def nextLong() = { val ans = underlying.next(); i += 1; ans } } ////////////////////////// diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsIndexedSeq.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsIndexedSeq.scala index 3627236..abf9485 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsIndexedSeq.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsIndexedSeq.scala @@ -22,25 +22,25 @@ import Stepper._ private[java8] class StepsAnyIndexedSeq[A](underlying: collection.IndexedSeqOps[A, Any, _], _i0: Int, _iN: Int) extends StepsLikeIndexed[A, StepsAnyIndexedSeq[A]](_i0, _iN) { - def next() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE + def next() = if (hasNext) { val j = i0; i0 += 1; underlying(j) } else throwNSEE protected def semiclone(half: Int) = new StepsAnyIndexedSeq[A](underlying, i0, half) } private[java8] class StepsDoubleIndexedSeq[CC <: collection.IndexedSeqOps[Double, Any, _]](underlying: CC, _i0: Int, _iN: Int) extends StepsDoubleLikeIndexed[StepsDoubleIndexedSeq[CC]](_i0, _iN) { - def nextDouble() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE + def nextDouble() = if (hasNext) { val j = i0; i0 += 1; underlying(j) } else throwNSEE protected def semiclone(half: Int) = new StepsDoubleIndexedSeq[CC](underlying, i0, half) } private[java8] class StepsIntIndexedSeq[CC <: collection.IndexedSeqOps[Int, Any, _]](underlying: CC, _i0: Int, _iN: Int) extends StepsIntLikeIndexed[StepsIntIndexedSeq[CC]](_i0, _iN) { - def nextInt() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE + def nextInt() = if (hasNext) { val j = i0; i0 += 1; underlying(j) } else throwNSEE protected def semiclone(half: Int) = new StepsIntIndexedSeq[CC](underlying, i0, half) } private[java8] class StepsLongIndexedSeq[CC <: collection.IndexedSeqOps[Long, Any, _]](underlying: CC, _i0: Int, _iN: Int) extends StepsLongLikeIndexed[StepsLongIndexedSeq[CC]](_i0, _iN) { - def nextLong() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE + def nextLong() = if (hasNext) { val j = i0; i0 += 1; underlying(j) } else throwNSEE protected def semiclone(half: Int) = new StepsLongIndexedSeq[CC](underlying, i0, half) } diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsIterator.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsIterator.scala index b5d0700..fd2e17b 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsIterator.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsIterator.scala @@ -23,25 +23,25 @@ import scala.compat.java8.collectionImpl._ private[java8] class StepsAnyIterator[A](_underlying: Iterator[A]) extends StepsLikeIterator[A, StepsAnyIterator[A]](_underlying) { protected def semiclone() = new StepsAnyIterator(null) - def next() = if (proxied ne null) proxied.nextStep else underlying.next + def next() = if (proxied ne null) proxied.nextStep() else underlying.next() } private[java8] class StepsDoubleIterator(_underlying: Iterator[Double]) extends StepsDoubleLikeIterator[StepsDoubleIterator](_underlying) { protected def semiclone() = new StepsDoubleIterator(null) - def nextDouble() = if (proxied ne null) proxied.nextStep else underlying.next + def nextDouble() = if (proxied ne null) proxied.nextStep() else underlying.next() } private[java8] class StepsIntIterator(_underlying: Iterator[Int]) extends StepsIntLikeIterator[StepsIntIterator](_underlying) { protected def semiclone() = new StepsIntIterator(null) - def nextInt() = if (proxied ne null) proxied.nextStep else underlying.next + def nextInt() = if (proxied ne null) proxied.nextStep() else underlying.next() } private[java8] class StepsLongIterator(_underlying: Iterator[Long]) extends StepsLongLikeIterator[StepsLongIterator](_underlying) { protected def semiclone() = new StepsLongIterator(null) - def nextLong() = if (proxied ne null) proxied.nextStep else underlying.next + def nextLong() = if (proxied ne null) proxied.nextStep() else underlying.next() } ////////////////////////// diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeGapped.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeGapped.scala index 6d0fa5b..e17ff2a 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeGapped.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeGapped.scala @@ -26,9 +26,9 @@ private[java8] abstract class AbstractStepsLikeGapped[Sub >: Null, Semi <: Sub]( protected var currentEntry: AnyRef = null protected def semiclone(half: Int): Semi - def characteristics(): Int = Ordered + def characteristics: Int = Ordered def estimateSize(): Long = if (!hasNext) 0 else iN - i0 - def hasNext(): Boolean = currentEntry != null || (i0 < iN && { + def hasNext: Boolean = currentEntry != null || (i0 < iN && { do { currentEntry = underlying(i0); i0 += 1 } while (currentEntry == null && i0 < iN) currentEntry != null }) diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeIndexed.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeIndexed.scala index 9a0aae8..dc386e0 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeIndexed.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeIndexed.scala @@ -20,9 +20,9 @@ private[java8] abstract class AbstractStepsLikeIndexed[Sub >: Null, Semi <: Sub] extends EfficientSubstep { protected def semiclone(half: Int): Semi - def characteristics(): Int = Ordered + Sized + SubSized + def characteristics: Int = Ordered + Sized + SubSized def estimateSize(): Long = iN - i0 - def hasNext(): Boolean = i0 < iN + def hasNext: Boolean = i0 < iN def substep(): Sub = { if (iN-1 > i0) { val half = (i0+iN) >>> 1 diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeIterator.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeIterator.scala index 3f1abe0..f5695d2 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeIterator.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeIterator.scala @@ -20,9 +20,9 @@ private[java8] abstract class AbstractStepsLikeIterator[A, SP >: Null <: Stepper final protected var nextChunkSize = 16 final protected var proxied: SP = null protected def semiclone(): Semi // Must initialize with null iterator! - def characteristics(): Int = if (proxied ne null) Ordered | Sized | SubSized else Ordered + def characteristics: Int = if (proxied ne null) Ordered | Sized | SubSized else Ordered def estimateSize(): Long = if (proxied ne null) proxied.knownSize else Long.MaxValue - def hasNext(): Boolean = if (proxied ne null) proxied.hasStep else underlying.hasNext + def hasNext: Boolean = if (proxied ne null) proxied.hasStep else underlying.hasNext } /** Abstracts the operation of stepping over an iterator (that needs to be cached when splitting) */ @@ -30,14 +30,14 @@ private[java8] abstract class StepsLikeIterator[A, SLI >: Null <: StepsLikeItera extends AbstractStepsLikeIterator[A, AnyStepper[A], SLI](_underlying) with AnyStepper[A] { - override def substep(): AnyStepper[A] = if (proxied ne null) proxied.substep else { + override def substep(): AnyStepper[A] = if (proxied ne null) proxied.substep() else { val acc = new Accumulator[A] var i = 0 val n = (nextChunkSize & 0xFFFFFFFC) - while (i < n && underlying.hasNext) { acc += underlying.next; i += 1 } + while (i < n && underlying.hasNext) { acc += underlying.next(); i += 1 } if (i < n || !underlying.hasNext) { proxied = acc.stepper - proxied.substep + proxied.substep() } else { val ans = semiclone() @@ -53,14 +53,14 @@ private[java8] abstract class StepsDoubleLikeIterator[SLI >: Null <: StepsDouble extends AbstractStepsLikeIterator[Double, DoubleStepper, SLI](_underlying) with DoubleStepper { - override def substep(): DoubleStepper = if (proxied ne null) proxied.substep else { + override def substep(): DoubleStepper = if (proxied ne null) proxied.substep() else { val acc = new DoubleAccumulator var i = 0 val n = (nextChunkSize & 0xFFFFFFFC) - while (i < n && underlying.hasNext) { acc += underlying.next; i += 1 } + while (i < n && underlying.hasNext) { acc += underlying.next(); i += 1 } if (i < n || !underlying.hasNext) { proxied = acc.stepper - proxied.substep + proxied.substep() } else { val ans = semiclone() @@ -76,14 +76,14 @@ private[java8] abstract class StepsIntLikeIterator[SLI >: Null <: StepsIntLikeIt extends AbstractStepsLikeIterator[Int, IntStepper, SLI](_underlying) with IntStepper { - override def substep(): IntStepper = if (proxied ne null) proxied.substep else { + override def substep(): IntStepper = if (proxied ne null) proxied.substep() else { val acc = new IntAccumulator var i = 0 val n = (nextChunkSize & 0xFFFFFFFC) - while (i < n && underlying.hasNext) { acc += underlying.next; i += 1 } + while (i < n && underlying.hasNext) { acc += underlying.next(); i += 1 } if (i < n || !underlying.hasNext) { proxied = acc.stepper - proxied.substep + proxied.substep() } else { val ans = semiclone() @@ -99,14 +99,14 @@ private[java8] abstract class StepsLongLikeIterator[SLI >: Null <: StepsLongLike extends AbstractStepsLikeIterator[Long, LongStepper, SLI](_underlying) with LongStepper { - override def substep: LongStepper = if (proxied ne null) proxied.substep else { + override def substep(): LongStepper = if (proxied ne null) proxied.substep() else { val acc = new LongAccumulator var i = 0 val n = (nextChunkSize & 0xFFFFFFFC) - while (i < n && underlying.hasNext) { acc += underlying.next; i += 1 } + while (i < n && underlying.hasNext) { acc += underlying.next(); i += 1 } if (i < n || !underlying.hasNext) { proxied = acc.stepper - proxied.substep + proxied.substep() } else { val ans = semiclone() diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeSliced.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeSliced.scala index b26d302..1044481 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeSliced.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeSliced.scala @@ -24,7 +24,7 @@ private[java8] abstract class AbstractStepsLikeSliced[Coll, Sub >: Null, Semi <: protected var i0: Int = i protected def semiclone(halfHint: Int): Semi // Must really do all the work for both this and cloned collection! - def characteristics(): Int = Ordered + def characteristics: Int = Ordered def estimateSize(): Long = iN - i def substep(): Sub = if (estimateSize > 0) semiclone((iN + i) >>> 1) else null } diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeTrieIterator.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeTrieIterator.scala index 1d33216..1c2334b 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsLikeTrieIterator.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsLikeTrieIterator.scala @@ -21,8 +21,8 @@ import Stepper._ private[java8] trait AbstractStepsLikeTrieIterator[A, Sub >: Null, Semi >: Null <: Sub with AbstractStepsLikeTrieIterator[A, Sub, _]] extends AbstractStepsLikeSliced[Iterator[A], Sub, Semi] { protected def demiclone(it: Iterator[A], N: Int): Semi - override def characteristics() = Immutable - def hasNext(): Boolean = underlying.hasNext + override def characteristics = Immutable + def hasNext: Boolean = underlying.hasNext protected def semiclone(halfHint: Int): Semi = if (!underlying.hasNext || i > iN-2) null else scala.compat.java8.runtime.CollectionInternals.trieIteratorSplit(underlying) match { diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsLinearSeq.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsLinearSeq.scala index d4c0958..52b0d0e 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsLinearSeq.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsLinearSeq.scala @@ -26,7 +26,7 @@ private[java8] class StepsAnyLinearSeq[A](_underlying: collection.LinearSeq[A], extends StepsWithTail[A, collection.LinearSeq[A], StepsAnyLinearSeq[A]](_underlying, _maxN) { protected def myIsEmpty(cc: collection.LinearSeq[A]): Boolean = cc.isEmpty protected def myTailOf(cc: collection.LinearSeq[A]) = cc.tail - def next() = if (hasNext()) { maxN -= 1; val ans = underlying.head; underlying = underlying.tail; ans } else throwNSEE + def next() = if (hasNext) { maxN -= 1; val ans = underlying.head; underlying = underlying.tail; ans } else throwNSEE protected def semiclone(half: Int) = new StepsAnyLinearSeq[A](underlying, half) } @@ -34,7 +34,7 @@ private[java8] class StepsDoubleLinearSeq(_underlying: collection.LinearSeq[Doub extends StepsDoubleWithTail[collection.LinearSeq[Double], StepsDoubleLinearSeq](_underlying, _maxN) { protected def myIsEmpty(cc: collection.LinearSeq[Double]): Boolean = cc.isEmpty protected def myTailOf(cc: collection.LinearSeq[Double]) = cc.tail - def nextDouble() = if (hasNext()) { maxN -= 1; val ans = underlying.head; underlying = underlying.tail; ans } else throwNSEE + def nextDouble() = if (hasNext) { maxN -= 1; val ans = underlying.head; underlying = underlying.tail; ans } else throwNSEE protected def semiclone(half: Int) = new StepsDoubleLinearSeq(underlying, half) } @@ -42,7 +42,7 @@ private[java8] class StepsIntLinearSeq(_underlying: collection.LinearSeq[Int], _ extends StepsIntWithTail[collection.LinearSeq[Int], StepsIntLinearSeq](_underlying, _maxN) { protected def myIsEmpty(cc: collection.LinearSeq[Int]): Boolean = cc.isEmpty protected def myTailOf(cc: collection.LinearSeq[Int]) = cc.tail - def nextInt() = if (hasNext()) { maxN -= 1; val ans = underlying.head; underlying = underlying.tail; ans } else throwNSEE + def nextInt() = if (hasNext) { maxN -= 1; val ans = underlying.head; underlying = underlying.tail; ans } else throwNSEE protected def semiclone(half: Int) = new StepsIntLinearSeq(underlying, half) } @@ -50,7 +50,7 @@ private[java8] class StepsLongLinearSeq(_underlying: collection.LinearSeq[Long], extends StepsLongWithTail[collection.LinearSeq[Long], StepsLongLinearSeq](_underlying, _maxN) { protected def myIsEmpty(cc: collection.LinearSeq[Long]): Boolean = cc.isEmpty protected def myTailOf(cc: collection.LinearSeq[Long]) = cc.tail - def nextLong() = if (hasNext()) { maxN -= 1; val ans = underlying.head; underlying = underlying.tail; ans } else throwNSEE + def nextLong() = if (hasNext) { maxN -= 1; val ans = underlying.head; underlying = underlying.tail; ans } else throwNSEE protected def semiclone(half: Int) = new StepsLongLinearSeq(underlying, half) } diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsRange.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsRange.scala index 4060011..fdeaaf8 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsRange.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsRange.scala @@ -24,25 +24,25 @@ import Stepper._ private[java8] class StepsIntRange(underlying: Range, _i0: Int, _iN: Int) extends StepsIntLikeIndexed[StepsIntRange](_i0, _iN) { - def nextInt() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE + def nextInt() = if (hasNext) { val j = i0; i0 += 1; underlying(j) } else throwNSEE protected def semiclone(half: Int) = new StepsIntRange(underlying, i0, half) } private[java8] class StepsAnyNumericRange[T](underlying: collection.immutable.NumericRange[T], _i0: Int, _iN: Int) extends StepsLikeIndexed[T, StepsAnyNumericRange[T]](_i0, _iN) { - def next() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE + def next() = if (hasNext) { val j = i0; i0 += 1; underlying(j) } else throwNSEE protected def semiclone(half: Int) = new StepsAnyNumericRange[T](underlying, i0, half) } private[java8] class StepsIntNumericRange(underlying: collection.immutable.NumericRange[Int], _i0: Int, _iN: Int) extends StepsIntLikeIndexed[StepsIntNumericRange](_i0, _iN) { - def nextInt() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE + def nextInt() = if (hasNext) { val j = i0; i0 += 1; underlying(j) } else throwNSEE protected def semiclone(half: Int) = new StepsIntNumericRange(underlying, i0, half) } private[java8] class StepsLongNumericRange(underlying: collection.immutable.NumericRange[Long], _i0: Int, _iN: Int) extends StepsLongLikeIndexed[StepsLongNumericRange](_i0, _iN) { - def nextLong() = if (hasNext()) { val j = i0; i0 += 1; underlying(j) } else throwNSEE + def nextLong() = if (hasNext) { val j = i0; i0 += 1; underlying(j) } else throwNSEE protected def semiclone(half: Int) = new StepsLongNumericRange(underlying, i0, half) } diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsString.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsString.scala index c7a5dff..0f15fc9 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsString.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsString.scala @@ -22,16 +22,16 @@ import Stepper._ private[java8] class StepperStringChar(underlying: CharSequence, _i0: Int, _iN: Int) extends StepsIntLikeIndexed[StepperStringChar](_i0, _iN) { - def nextInt() = if (hasNext()) { val j = i0; i0 += 1; underlying.charAt(j) } else throwNSEE + def nextInt() = if (hasNext) { val j = i0; i0 += 1; underlying.charAt(j) } else throwNSEE protected def semiclone(half: Int) = new StepperStringChar(underlying, i0, half) } private[java8] class StepperStringCodePoint(underlying: String, var i0: Int, var iN: Int) extends IntStepper with EfficientSubstep { - def characteristics() = NonNull + def characteristics = NonNull def estimateSize = iN - i0 def hasNext = i0 < iN def nextInt() = { - if (hasNext()) { + if (hasNext) { val cp = underlying.codePointAt(i0) i0 += java.lang.Character.charCount(cp) cp diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsVector.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsVector.scala index c4aa7e3..5cefaef 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsVector.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsVector.scala @@ -110,7 +110,7 @@ with StepsVectorLike[A] { protected val myVector = if (CollectionInternals.getDirt(underlying)) null else underlying protected val myVectorIterator = if (myVector == null) underlying.iterator else null protected val myVectorLength = underlying.length - def next() = if (hasNext()) { + def next() = if (hasNext) { index += 1 if (index >= 32) advanceData(i0) i0 += 1 @@ -131,7 +131,7 @@ with StepsVectorLike[Double] { protected val myVector = if (CollectionInternals.getDirt(underlying)) null else underlying protected val myVectorIterator = if (myVector == null) underlying.iterator else null protected val myVectorLength = underlying.length - def nextDouble() = if (hasNext()) { + def nextDouble() = if (hasNext) { index += 1 if (index >= 32) advanceData(i0) i0 += 1 @@ -152,7 +152,7 @@ with StepsVectorLike[Int] { protected val myVector = if (CollectionInternals.getDirt(underlying)) null else underlying protected val myVectorIterator = if (myVector == null) underlying.iterator else null protected val myVectorLength = underlying.length - def nextInt() = if (hasNext()) { + def nextInt() = if (hasNext) { index += 1 if (index >= 32) advanceData(i0) i0 += 1 @@ -173,7 +173,7 @@ with StepsVectorLike[Long] { protected val myVector = if (CollectionInternals.getDirt(underlying)) null else underlying protected val myVectorIterator = if (myVector == null) underlying.iterator else null protected val myVectorLength = underlying.length - def nextLong() = if (hasNext()) { + def nextLong() = if (hasNext) { index += 1 if (index >= 32) advanceData(i0) i0 += 1 diff --git a/src/main/scala/scala/compat/java8/converterImpl/StepsWithTail.scala b/src/main/scala/scala/compat/java8/converterImpl/StepsWithTail.scala index c20f997..8a66033 100644 --- a/src/main/scala/scala/compat/java8/converterImpl/StepsWithTail.scala +++ b/src/main/scala/scala/compat/java8/converterImpl/StepsWithTail.scala @@ -38,9 +38,9 @@ private[java8] abstract class AbstractStepsWithTail[CC >: Null, Sub >: Null, Sem this } protected def semiclone(chunk: Int): Semi - def characteristics(): Int = if (maxN < Int.MaxValue) Ordered | Sized | SubSized else Ordered + def characteristics: Int = if (maxN < Int.MaxValue) Ordered | Sized | SubSized else Ordered def estimateSize(): Long = if (maxN < Int.MaxValue) maxN else Long.MaxValue - def hasNext(): Boolean = if (maxN < Int.MaxValue) maxN > 0 else if (myIsEmpty(underlying)) { maxN = 0; false } else true + def hasNext: Boolean = if (maxN < Int.MaxValue) maxN > 0 else if (myIsEmpty(underlying)) { maxN = 0; false } else true def substep(): Sub = { prepareParallelOperation() maxN match { diff --git a/src/test/scala/scala/compat/java8/StepperTest.scala b/src/test/scala/scala/compat/java8/StepperTest.scala index 7bbbcd9..704d9c7 100644 --- a/src/test/scala/scala/compat/java8/StepperTest.scala +++ b/src/test/scala/scala/compat/java8/StepperTest.scala @@ -53,7 +53,7 @@ class IncStepperB(private val size0: Long) extends TryStepper[Int] { class IncSpliterator(private val size0: Long) extends Spliterator.OfInt { if (size0 < 0) throw new IllegalArgumentException("Size must be >= 0L") private var i = 0L - def characteristics() = Stepper.Sized | Stepper.SubSized | Stepper.Ordered + def characteristics = Stepper.Sized | Stepper.SubSized | Stepper.Ordered def estimateSize() = math.max(0L, size0 - i) def tryAdvance(f: java.util.function.IntConsumer): Boolean = if (i >= size0) false else { f.accept(i.toInt); i += 1; true } def trySplit(): Spliterator.OfInt = if (i+1 >= size0) null else { @@ -157,12 +157,12 @@ class StepperTest { @Test def stepping(): Unit = { - sources.foreach{ case (i, s) => assert((0 until i).forall{ j => s.hasStep && s.nextStep == j } && !s.hasStep) } + sources.foreach{ case (i, s) => assert((0 until i).forall{ j => s.hasStep && s.nextStep() == j } && !s.hasStep) } sources.foreach{ case (i, s) => val set = collection.mutable.BitSet.empty subs(0)(s)( { x => - while (x.hasStep) { val y = x.nextStep; assert(!(set contains y)); set += y } + while (x.hasStep) { val y = x.nextStep(); assert(!(set contains y)); set += y } 0 }, _ + _ @@ -194,16 +194,16 @@ class StepperTest { @Test def substepping(): Unit = { sources.foreach{ case (i,s) => - val ss = s.substep + val ss = s.substep() assertEquals(ss == null, i < 2) if (ss != null) { assertTrue(s.hasStep) assertTrue(ss.hasStep) - val c1 = s.count - val c2 = ss.count + val c1 = s.count() + val c2 = ss.count() assertEquals(s"$i != $c1 + $c2 from ${s.getClass.getName}", i, c1 + c2) } - else assertEquals(i, s.count) + else assertEquals(i, s.count()) } } @@ -222,8 +222,8 @@ class StepperTest { @Test def count_only(): Unit = { - sources.foreach{ case (i, s) => assertEquals(i, s.count) } - sources.foreach{ case (i, s) => assertEquals(i, subs(0)(s)(_.count.toInt, _ + _)) } + sources.foreach{ case (i, s) => assertEquals(i, s.count()) } + sources.foreach{ case (i, s) => assertEquals(i, subs(0)(s)(_.count().toInt, _ + _)) } } @Test @@ -267,7 +267,7 @@ class StepperTest { sources.foreach{ case (i,s) => assertEquals(expected(i), s.foldTo(0)(_ + _)(_ >= 6*i)) } sources.foreach{ case (_,s) => assertEquals(-1, s.foldTo(-1)(_ * _)(_ => true)) } sources.foreach{ case (i,s) => - val ss = s.substep + val ss = s.substep() val x = s.foldTo( if (ss == null) 0 else ss.foldTo(0)(_ + _)(_ >= 6*i) )(_ + _)(_ >= 6*i) assertEquals(expected(i), x) } From a80061ce17c53c1a077f7839961769f660903b32 Mon Sep 17 00:00:00 2001 From: Lukas Rytz Date: Tue, 9 Apr 2019 12:22:00 +0200 Subject: [PATCH 11/13] 2.13.0-RC1 version bump only --- .travis.yml | 2 +- build.sbt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0b1403b..af0c85a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,7 @@ jdk: - openjdk11 scala: - - 2.13.0-M5 + - 2.13.0-RC1 env: global: diff --git a/build.sbt b/build.sbt index 71f6728..d570920 100644 --- a/build.sbt +++ b/build.sbt @@ -1,6 +1,6 @@ import ScalaModulePlugin._ -crossScalaVersions in ThisBuild := List("2.13.0-M5") +crossScalaVersions in ThisBuild := List("2.13.0-RC1") val disableDocs = sys.props("nodocs") == "true" || From 5d9bd5de56c2ae1aab2f1d1629c1f2649be80688 Mon Sep 17 00:00:00 2001 From: Lukas Rytz Date: Tue, 9 Apr 2019 16:38:16 +0200 Subject: [PATCH 12/13] Fix FutureConverters for RC1 --- src/main/scala/scala/compat/java8/FutureConverters.scala | 2 +- .../scala/scala/concurrent/java8/FutureConvertersImpl.scala | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/scala/scala/compat/java8/FutureConverters.scala b/src/main/scala/scala/compat/java8/FutureConverters.scala index 341f400..a0a9c6c 100644 --- a/src/main/scala/scala/compat/java8/FutureConverters.scala +++ b/src/main/scala/scala/compat/java8/FutureConverters.scala @@ -68,7 +68,7 @@ object FutureConverters { case p: P[T] => p.wrapped case _ => val cf = new CF[T](f) - implicit val ec = InternalCallbackExecutor + implicit val ec = ExecutionContext.parasitic f onComplete cf cf } diff --git a/src/main/scala/scala/concurrent/java8/FutureConvertersImpl.scala b/src/main/scala/scala/concurrent/java8/FutureConvertersImpl.scala index d4ab402..9d06fc8 100644 --- a/src/main/scala/scala/concurrent/java8/FutureConvertersImpl.scala +++ b/src/main/scala/scala/concurrent/java8/FutureConvertersImpl.scala @@ -22,8 +22,6 @@ import java.util.function.{ BiConsumer, Function ⇒ JF, Consumer, BiFunction } // TODO: make this private[scala] when genjavadoc allows for that. object FuturesConvertersImpl { - def InternalCallbackExecutor = Future.InternalCallbackExecutor - class CF[T](val wrapped: Future[T]) extends CompletableFuture[T] with (Try[T] => Unit) { override def apply(t: Try[T]): Unit = t match { case Success(v) ⇒ complete(v) From 186e8cc6418cb09baad3fb3408a5a55c3b2da93e Mon Sep 17 00:00:00 2001 From: Lukas Rytz Date: Tue, 9 Apr 2019 16:38:21 +0200 Subject: [PATCH 13/13] Change StreamConverters to use the implementation from 2.13.0-RC1 This drops the Stepper and Accumulator implementations from this repository. It introduces new extension methods that use the implementations from 2.13.0-RC1, but with the names from 2.12 java8-compat. For example, `stream.accumulate` continues works when using java8-compat for 2.13. When using `scala.jdk.StreamConverters`, the user would have to write `stream.toScala(Accumulator)`. The core use cases should continue to work, see the changes to test files --- project/CodeGen.scala | 4 +- .../compat/java8/ScalaStreamSupport.java | 720 ++++-------------- .../java8/runtime/CollectionInternals.java | 52 -- .../compat/java8/SpliteratorConverters.scala | 41 - .../scala/compat/java8/StreamConverters.scala | 573 ++++++++------ .../java8/collectionImpl/Accumulator.scala | 361 --------- .../collectionImpl/AccumulatorLike.scala | 53 -- .../collectionImpl/DoubleAccumulator.scala | 353 --------- .../java8/collectionImpl/IntAccumulator.scala | 360 --------- .../collectionImpl/LongAccumulator.scala | 354 --------- .../compat/java8/collectionImpl/Stepper.scala | 641 ---------------- .../compat/java8/collectionImpl/package.scala | 30 + .../java8/converterImpl/Accumulates.scala | 56 +- .../converterImpl/AccumulatorConverters.scala | 17 +- .../java8/converterImpl/MakesSteppers.scala | 102 --- .../java8/converterImpl/StepConverters.scala | 58 -- .../converterImpl/StepperExtensions.scala | 77 ++ .../java8/converterImpl/StepsArray.scala | 97 --- .../java8/converterImpl/StepsBitSet.scala | 80 -- .../converterImpl/StepsFlatHashTable.scala | 64 -- .../java8/converterImpl/StepsHashTable.scala | 209 ----- .../java8/converterImpl/StepsImmHashSet.scala | 58 -- .../java8/converterImpl/StepsIndexedSeq.scala | 58 -- .../java8/converterImpl/StepsIterable.scala | 29 - .../java8/converterImpl/StepsIterator.scala | 58 -- .../java8/converterImpl/StepsLikeGapped.scala | 79 -- .../converterImpl/StepsLikeIndexed.scala | 62 -- .../converterImpl/StepsLikeIterator.scala | 118 --- .../java8/converterImpl/StepsLikeSliced.scala | 54 -- .../converterImpl/StepsLikeTrieIterator.scala | 59 -- .../java8/converterImpl/StepsLinearSeq.scala | 68 -- .../compat/java8/converterImpl/StepsMap.scala | 38 - .../java8/converterImpl/StepsRange.scala | 64 -- .../java8/converterImpl/StepsString.scala | 61 -- .../java8/converterImpl/StepsVector.scala | 202 ----- .../java8/converterImpl/StepsWithTail.scala | 98 --- .../java/scala/compat/java8/BoxingTest.java | 6 +- .../compat/java8/StepConvertersTest.scala | 16 +- .../scala/compat/java8/StepperTest.scala | 108 +-- .../compat/java8/StreamConvertersTest.scala | 176 ++--- 40 files changed, 721 insertions(+), 4993 deletions(-) delete mode 100644 src/main/java/scala/compat/java8/runtime/CollectionInternals.java delete mode 100644 src/main/scala/scala/compat/java8/SpliteratorConverters.scala delete mode 100644 src/main/scala/scala/compat/java8/collectionImpl/Accumulator.scala delete mode 100644 src/main/scala/scala/compat/java8/collectionImpl/AccumulatorLike.scala delete mode 100644 src/main/scala/scala/compat/java8/collectionImpl/DoubleAccumulator.scala delete mode 100644 src/main/scala/scala/compat/java8/collectionImpl/IntAccumulator.scala delete mode 100644 src/main/scala/scala/compat/java8/collectionImpl/LongAccumulator.scala delete mode 100644 src/main/scala/scala/compat/java8/collectionImpl/Stepper.scala create mode 100644 src/main/scala/scala/compat/java8/collectionImpl/package.scala delete mode 100644 src/main/scala/scala/compat/java8/converterImpl/MakesSteppers.scala delete mode 100644 src/main/scala/scala/compat/java8/converterImpl/StepConverters.scala create mode 100644 src/main/scala/scala/compat/java8/converterImpl/StepperExtensions.scala delete mode 100644 src/main/scala/scala/compat/java8/converterImpl/StepsArray.scala delete mode 100644 src/main/scala/scala/compat/java8/converterImpl/StepsBitSet.scala delete mode 100644 src/main/scala/scala/compat/java8/converterImpl/StepsFlatHashTable.scala delete mode 100644 src/main/scala/scala/compat/java8/converterImpl/StepsHashTable.scala delete mode 100644 src/main/scala/scala/compat/java8/converterImpl/StepsImmHashSet.scala delete mode 100644 src/main/scala/scala/compat/java8/converterImpl/StepsIndexedSeq.scala delete mode 100644 src/main/scala/scala/compat/java8/converterImpl/StepsIterable.scala delete mode 100644 src/main/scala/scala/compat/java8/converterImpl/StepsIterator.scala delete mode 100644 src/main/scala/scala/compat/java8/converterImpl/StepsLikeGapped.scala delete mode 100644 src/main/scala/scala/compat/java8/converterImpl/StepsLikeIndexed.scala delete mode 100644 src/main/scala/scala/compat/java8/converterImpl/StepsLikeIterator.scala delete mode 100644 src/main/scala/scala/compat/java8/converterImpl/StepsLikeSliced.scala delete mode 100644 src/main/scala/scala/compat/java8/converterImpl/StepsLikeTrieIterator.scala delete mode 100644 src/main/scala/scala/compat/java8/converterImpl/StepsLinearSeq.scala delete mode 100644 src/main/scala/scala/compat/java8/converterImpl/StepsMap.scala delete mode 100644 src/main/scala/scala/compat/java8/converterImpl/StepsRange.scala delete mode 100644 src/main/scala/scala/compat/java8/converterImpl/StepsString.scala delete mode 100644 src/main/scala/scala/compat/java8/converterImpl/StepsVector.scala delete mode 100644 src/main/scala/scala/compat/java8/converterImpl/StepsWithTail.scala diff --git a/project/CodeGen.scala b/project/CodeGen.scala index 4289973..b3f3f11 100644 --- a/project/CodeGen.scala +++ b/project/CodeGen.scala @@ -519,9 +519,9 @@ object CodeGen { val specialized = List("V", "V,IJFD", "V,IJD,IJD").flatMap(specialize).map { case (i, a, sp) => - s" public static scala.Function$i<$a> procSpecialized(JFunction$i$sp f) { return f; }" } ++ + s" public static scala.Function$i<$a> procSpecialized(JFunction$i$sp f) { return (scala.Function$i<$a>)(Object)f; }" } ++ List("BSIJCFDZ", "ZIFJD,IJFD", "ZIFJD,IJD,IJD").flatMap(specialize).map { case (i, a, sp) => - s" public static scala.Function$i<$a> funcSpecialized(JFunction$i$sp f) { return f; }" } + s" public static scala.Function$i<$a> funcSpecialized(JFunction$i$sp f) { return (scala.Function$i<$a>)(Object)f; }" } (blocks.map(_._1) ++ blocks.map(_._2)) :+ ( "JFunction", diff --git a/src/main/java/scala/compat/java8/ScalaStreamSupport.java b/src/main/java/scala/compat/java8/ScalaStreamSupport.java index 6a8499c..112833e 100644 --- a/src/main/java/scala/compat/java8/ScalaStreamSupport.java +++ b/src/main/java/scala/compat/java8/ScalaStreamSupport.java @@ -12,10 +12,10 @@ package scala.compat.java8; -import scala.compat.java8.converterImpl.*; -import scala.compat.java8.collectionImpl.*; import java.util.stream.*; -import scala.compat.java8.runtime.CollectionInternals; + +import scala.collection.*; +import scala.jdk.StreamConverters; /** * This class contains static utility methods for creating Java Streams from Scala Collections, similar @@ -33,166 +33,62 @@ public class ScalaStreamSupport { ///////////////////// /** - * Generates a Stream that traverses an IndexedSeq. - *

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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