diff --git a/core/src/main/scala/scala/collection/parallel/ParIterableLike.scala b/core/src/main/scala/scala/collection/parallel/ParIterableLike.scala index 5b65c720..31429694 100644 --- a/core/src/main/scala/scala/collection/parallel/ParIterableLike.scala +++ b/core/src/main/scala/scala/collection/parallel/ParIterableLike.scala @@ -698,11 +698,11 @@ self => }) }) else setTaskSupport((companion.newCombiner[U] += z).result(), tasksupport) } -/* - def scanLeft[S, That](z: S)(op: (S, T) => S)(implicit bf: CanBuildFrom[Repr, S, That]) = setTaskSupport(seq.scanLeft(z)(op)(bf2seq(bf)), tasksupport) - def scanRight[S, That](z: S)(op: (T, S) => S)(implicit bf: CanBuildFrom[Repr, S, That]) = setTaskSupport(seq.scanRight(z)(op)(bf2seq(bf)), tasksupport) -*/ + def scanLeft[S](z: S)(op: (S, T) => S): Iterable[S] = seq.scanLeft(z)(op) + + def scanRight[S](z: S)(op: (T, S) => S): Iterable[S] = seq.scanRight(z)(op) + /** Takes the longest prefix of elements that satisfy the predicate. * * $indexsignalling diff --git a/core/src/main/scala/scala/collection/parallel/ParSeqLike.scala b/core/src/main/scala/scala/collection/parallel/ParSeqLike.scala index d10ae5de..b2d0fccc 100644 --- a/core/src/main/scala/scala/collection/parallel/ParSeqLike.scala +++ b/core/src/main/scala/scala/collection/parallel/ParSeqLike.scala @@ -177,16 +177,18 @@ self => * @param offset the starting offset for the search * @return `true` if there is a sequence `that` starting at `offset` in this sequence, `false` otherwise */ - def startsWith[S >: T](that: ParSeq[S], offset: Int): Boolean = { - if (offset < 0 || offset >= length) offset == length && that.length == 0 - else if (that.length == 0) true - else if (that.length > length - offset) false - else { - val ctx = new DefaultSignalling with VolatileAbort - tasksupport.executeAndWaitResult( - new SameElements[S](splitter.psplitWithSignalling(offset, that.length)(1) assign ctx, that.splitter) - ) - } + def startsWith[S >: T](that: IterableOnce[S], offset: Int = 0): Boolean = that match { + case pt: ParSeq[S] => + if (offset < 0 || offset >= length) offset == length && pt.isEmpty + else if (pt.isEmpty) true + else if (pt.length > length - offset) false + else { + val ctx = new DefaultSignalling with VolatileAbort + tasksupport.executeAndWaitResult( + new SameElements[S](splitter.psplitWithSignalling(offset, pt.length)(1) assign ctx, pt.splitter) + ) + } + case _ => seq.startsWith(that, offset) } override def sameElements[U >: T](that: IterableOnce[U]): Boolean = { @@ -216,6 +218,16 @@ self => } } + /** Tests whether this $coll ends with the given collection. + * + * $abortsignalling + * + * @tparam S the type of the elements of `that` sequence + * @param that the sequence to test + * @return `true` if this $coll has `that` as a suffix, `false` otherwise + */ + def endsWith[S >: T](that: Iterable[S]): Boolean = seq.endsWith(that) + def patch[U >: T](from: Int, patch: ParSeq[U], replaced: Int): CC[U] = { val realreplaced = replaced min (length - from) if ((size - realreplaced + patch.size) > MIN_FOR_COPY) { diff --git a/scalacheck/src/test/scala/ParallelSeqCheck.scala b/scalacheck/src/test/scala/ParallelSeqCheck.scala index 39682dd3..ef029c78 100644 --- a/scalacheck/src/test/scala/ParallelSeqCheck.scala +++ b/scalacheck/src/test/scala/ParallelSeqCheck.scala @@ -131,80 +131,80 @@ abstract class ParallelSeqCheck[T](collName: String) extends ParallelIterableChe }).reduceLeft(_ && _) } -// property("sameElements must be equal") = forAllNoShrink(collectionPairsWithModifiedWithLengths) { -// case (s, coll, collmodif, len) => -// val pos = if (len < 0) 0 else len -// val scm = s.sameElements(collmodif) -// val ccm = coll.sameElements(collmodif) -// if (scm != ccm) { -// println("Comparing: " + s) -// println("and: " + coll) -// println("with: " + collmodif) -// println(scm) -// println(ccm) -// } -// ("Nil" |: s.sameElements(Nil) == coll.sameElements(Nil)) && -// ("toList" |: s.sameElements(s.toList) == coll.sameElements(coll.toList)) && -// ("identity" |: s.sameElements(s.map(e => e)) == coll.sameElements(coll.map(e => e))) && -// ("vice-versa" |: s.sameElements(coll) == coll.sameElements(s)) && -// ("equal" |: s.sameElements(coll)) && -// ("modified" |: scm == ccm) && -// (for ((it, ind) <- sameElementsSeqs.zipWithIndex) yield { -// val sres = s.sameElements(it) -// val pres = coll.sameElements(it) -// if (sres != pres) { -// println("Comparing: " + s) -// println("and: " + coll) -// println("with: " + it) -// println(sres) -// println(pres) -// } -// ("collection " + ind) |: sres == pres -// }).reduceLeft(_ && _) -// } + property("sameElements must be equal") = forAllNoShrink(collectionPairsWithModifiedWithLengths) { + case (s, coll, collmodif, len) => + val pos = if (len < 0) 0 else len + val scm = s.sameElements(collmodif) + val ccm = coll.sameElements(collmodif) + if (scm != ccm) { + println("Comparing: " + s) + println("and: " + coll) + println("with: " + collmodif) + println(scm) + println(ccm) + } + ("Nil" |: s.sameElements(Nil) == coll.sameElements(Nil)) && + ("toList" |: s.sameElements(s.toList) == coll.sameElements(coll.toList)) && + ("identity" |: s.sameElements(s.map(e => e)) == coll.sameElements(coll.map(e => e))) && + ("vice-versa" |: s.sameElements(coll) == coll.sameElements(s)) && + ("equal" |: s.sameElements(coll)) && + ("modified" |: scm == ccm) && + (for ((it, ind) <- sameElementsSeqs.zipWithIndex) yield { + val sres = s.sameElements(it) + val pres = coll.sameElements(it) + if (sres != pres) { + println("Comparing: " + s) + println("and: " + coll) + println("with: " + it) + println(sres) + println(pres) + } + ("collection " + ind) |: sres == pres + }).reduceLeft(_ && _) + } -// property("startsWiths must be equal") = forAllNoShrink(collectionPairsWithModifiedWithLengths) { -// case (s, coll, collmodif, len) => -// val pos = if (len < 0) 0 else len -// ("start with self" |: s.startsWith(s) == coll.startsWith(coll)) && -// ("tails correspond" |: (s.length == 0 || s.startsWith(s.tail, 1) == coll.startsWith(coll.tail, 1))) && -// ("with each other" |: coll.startsWith(s)) && -// ("modified" |: s.startsWith(collmodif) == coll.startsWith(collmodif)) && -// ("modified2" |: s.startsWith(collmodif, pos) == coll.startsWith(collmodif, pos)) && -// (for (sq <- startEndSeqs) yield { -// val ss = s.startsWith(sq, pos) -// val cs = coll.startsWith(fromSeq(sq), pos) -// if (ss != cs) { -// println("from: " + s) -// println("and: " + coll) -// println("test seq: " + sq) -// println("from pos: " + pos) -// println(ss) -// println(cs) -// println(coll.iterator.psplit(pos, coll.length - pos)(1).toList) -// } -// ("seq " + sq) |: ss == cs -// }).reduceLeft(_ && _) -// } + property("startsWiths must be equal") = forAllNoShrink(collectionPairsWithModifiedWithLengths) { + case (s, coll, collmodif, len) => + val pos = if (len < 0) 0 else len + ("start with self" |: s.startsWith(s) == coll.startsWith(coll)) && + ("tails correspond" |: (s.length == 0 || s.startsWith(s.tail, 1) == coll.startsWith(coll.tail, 1))) && + ("with each other" |: coll.startsWith(s)) && + ("modified" |: s.startsWith(collmodif) == coll.startsWith(collmodif)) && + ("modified2" |: s.startsWith(collmodif, pos) == coll.startsWith(collmodif, pos)) && + (for (sq <- startEndSeqs) yield { + val ss = s.startsWith(sq, pos) + val cs = coll.startsWith(fromSeq(sq), pos) + if (ss != cs) { + println("from: " + s) + println("and: " + coll) + println("test seq: " + sq) + println("from pos: " + pos) + println(ss) + println(cs) + println(coll.iterator.psplit(pos, coll.length - pos)(1).toList) + } + ("seq " + sq) |: ss == cs + }).reduceLeft(_ && _) + } -// property("endsWiths must be equal") = forAllNoShrink(collectionPairsWithModified) { -// case (s, coll, collmodif) => -// ("ends with self" |: s.endsWith(s) == coll.endsWith(s)) && -// ("ends with tail" |: (s.length == 0 || s.endsWith(s.tail) == coll.endsWith(coll.tail))) && -// ("with each other" |: coll.endsWith(s)) && -// ("modified" |: s.startsWith(collmodif) == coll.endsWith(collmodif)) && -// (for (sq <- startEndSeqs) yield { -// val sew = s.endsWith(sq) -// val cew = coll.endsWith(fromSeq(sq)) -// if (sew != cew) { -// println("from: " + s) -// println("and: " + coll) -// println(sew) -// println(cew) -// } -// ("seq " + sq) |: sew == cew -// }).reduceLeft(_ && _) -// } + property("endsWiths must be equal") = forAllNoShrink(collectionPairsWithModified) { + case (s, coll, collmodif) => + ("ends with self" |: s.endsWith(s) == coll.endsWith(s)) && + ("ends with tail" |: (s.length == 0 || s.endsWith(s.tail) == coll.endsWith(coll.tail))) && + ("with each other" |: coll.endsWith(s)) && + ("modified" |: s.startsWith(collmodif) == coll.endsWith(collmodif)) && + (for (sq <- startEndSeqs if s.nonEmpty /* guard because of https://github.com/scala/bug/issues/11328 */) yield { + val sew = s.endsWith(sq) + val cew = coll.endsWith(fromSeq(sq)) + if (sew != cew) { + println("from: " + s) + println("and: " + coll) + println(sew) + println(cew) + } + ("seq " + sq) |: sew == cew + }).reduceLeft(_ && _) + } // property("unions must be equal") = forAllNoShrink(collectionPairsWithModified) { case (s, coll, collmodif) => // ("modified" |: s.union(collmodif.seq) == coll.union(collmodif)) &&