Skip to content

Commit 5f29da7

Browse files
author
Aleksandar Prokopec
committed
Widen types in signatures of Future companion methods, refactor OnceCanBuildFrom.
Removed the implicit modifier on the OnceCanBuildFrom, as we don't support implicit classes with zero arguments. Added an implicit OnceCanBuildFrom method. The idea behind OnceCanBuildFrom is for it to be used by methods which construct collections, but are defined outside of collection classes. OnceCanBuildFrom so far worked only for objects of type TraversableOnce: shuffle(List(1, 2, 3).iterator: TraversableOnce[Int]) but this used to result in an implicit resolution error: shuffle(List(1, 2, 3).iterator) because after the type parameter M for `shuffle` was inferred to Iterator, no implicit of type CanBuildFrom[Iterator[_], A, Iterator[A]] could be found. Introduced another CanBuildFrom to the Iterator companion object. Modified Future tests appropriately.
1 parent ce04a62 commit 5f29da7

File tree

6 files changed

+329
-277
lines changed

6 files changed

+329
-277
lines changed

src/library/scala/collection/Iterator.scala

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,14 @@ import immutable.Stream
2121
*/
2222
object Iterator {
2323

24+
/** With the advent of `TraversableOnce` and `Iterator`, it can be useful to have a builder which
25+
* operates on `Iterator`s so they can be treated uniformly along with the collections.
26+
* See `scala.util.Random.shuffle` for an example.
27+
*/
28+
implicit def IteratorCanBuildFrom[A] = new TraversableOnce.BufferedCanBuildFrom[A, Iterator] {
29+
def toColl[B](coll: ArrayBuffer[B]) = coll.iterator
30+
}
31+
2432
/** The iterator which produces no values. */
2533
val empty: Iterator[Nothing] = new AbstractIterator[Nothing] {
2634
def hasNext: Boolean = false

src/library/scala/collection/TraversableOnce.scala

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
package scala.collection
1010

11-
import mutable.{ Buffer, ListBuffer, ArrayBuffer }
11+
import mutable.{ Buffer, Builder, ListBuffer, ArrayBuffer }
1212
import annotation.unchecked.{ uncheckedVariance => uV }
1313
import language.{implicitConversions, higherKinds}
1414

@@ -357,7 +357,6 @@ trait TraversableOnce[+A] extends Any with GenTraversableOnce[A] {
357357
}
358358

359359

360-
361360
object TraversableOnce {
362361
@deprecated("use OnceCanBuildFrom instead")
363362
def traversableOnceCanBuildFrom[T] = new OnceCanBuildFrom[T]
@@ -367,26 +366,34 @@ object TraversableOnce {
367366
implicit def alternateImplicit[A](trav: TraversableOnce[A]) = new ForceImplicitAmbiguity
368367
implicit def flattenTraversableOnce[A, CC[_]](travs: TraversableOnce[CC[A]])(implicit ev: CC[A] => TraversableOnce[A]) =
369368
new FlattenOps[A](travs map ev)
370-
371-
/** With the advent of TraversableOnce, it can be useful to have a builder which
372-
* operates on Iterators so they can be treated uniformly along with the collections.
373-
* See scala.util.Random.shuffle for an example.
374-
*/
375-
implicit class OnceCanBuildFrom[A] extends generic.CanBuildFrom[TraversableOnce[A], A, TraversableOnce[A]] {
376-
def newIterator = new ArrayBuffer[A] mapResult (_.iterator)
369+
370+
abstract class BufferedCanBuildFrom[A, Coll[X] <: TraversableOnce[X]] extends generic.CanBuildFrom[Coll[_], A, Coll[A]] {
371+
def toColl[B](buff: ArrayBuffer[B]): Coll[B]
372+
373+
def newIterator: Builder[A, Coll[A]] = new ArrayBuffer[A] mapResult toColl
377374

378375
/** Creates a new builder on request of a collection.
379376
* @param from the collection requesting the builder to be created.
380377
* @return the result of invoking the `genericBuilder` method on `from`.
381378
*/
382-
def apply(from: TraversableOnce[A]) = newIterator
379+
def apply(from: Coll[_]): Builder[A, Coll[A]] = newIterator
383380

384381
/** Creates a new builder from scratch
385382
* @return the result of invoking the `newBuilder` method of this factory.
386383
*/
387384
def apply() = newIterator
388385
}
389-
386+
387+
/** With the advent of `TraversableOnce`, it can be useful to have a builder which
388+
* operates on `Iterator`s so they can be treated uniformly along with the collections.
389+
* See `scala.util.Random.shuffle` or `scala.concurrent.Future.sequence` for an example.
390+
*/
391+
class OnceCanBuildFrom[A] extends BufferedCanBuildFrom[A, TraversableOnce] {
392+
def toColl[B](buff: ArrayBuffer[B]) = buff.iterator
393+
}
394+
395+
implicit def OnceCanBuildFrom[A] = new OnceCanBuildFrom[A]
396+
390397
class FlattenOps[A](travs: TraversableOnce[TraversableOnce[A]]) {
391398
def flatten: Iterator[A] = new AbstractIterator[A] {
392399
val its = travs.toIterator

src/library/scala/concurrent/Future.scala

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -426,21 +426,8 @@ trait Future[+T] extends Awaitable[T] {
426426
* that conforms to `S`'s erased type or a `ClassCastException` otherwise.
427427
*/
428428
def mapTo[S](implicit tag: ClassTag[S]): Future[S] = {
429-
import java.{ lang => jl }
430-
val toBoxed = Map[Class[_], Class[_]](
431-
classOf[Boolean] -> classOf[jl.Boolean],
432-
classOf[Byte] -> classOf[jl.Byte],
433-
classOf[Char] -> classOf[jl.Character],
434-
classOf[Short] -> classOf[jl.Short],
435-
classOf[Int] -> classOf[jl.Integer],
436-
classOf[Long] -> classOf[jl.Long],
437-
classOf[Float] -> classOf[jl.Float],
438-
classOf[Double] -> classOf[jl.Double],
439-
classOf[Unit] -> classOf[scala.runtime.BoxedUnit]
440-
)
441-
442429
def boxedType(c: Class[_]): Class[_] = {
443-
if (c.isPrimitive) toBoxed(c) else c
430+
if (c.isPrimitive) Future.toBoxed(c) else c
444431
}
445432

446433
val p = newPromise[S]
@@ -530,7 +517,22 @@ trait Future[+T] extends Awaitable[T] {
530517
* Note: using this method yields nondeterministic dataflow programs.
531518
*/
532519
object Future {
533-
/** Starts an asynchronous computation and returns a `Future` object with the result of that computation.
520+
521+
import java.{ lang => jl }
522+
523+
private[concurrent] val toBoxed = Map[Class[_], Class[_]](
524+
classOf[Boolean] -> classOf[jl.Boolean],
525+
classOf[Byte] -> classOf[jl.Byte],
526+
classOf[Char] -> classOf[jl.Character],
527+
classOf[Short] -> classOf[jl.Short],
528+
classOf[Int] -> classOf[jl.Integer],
529+
classOf[Long] -> classOf[jl.Long],
530+
classOf[Float] -> classOf[jl.Float],
531+
classOf[Double] -> classOf[jl.Double],
532+
classOf[Unit] -> classOf[scala.runtime.BoxedUnit]
533+
)
534+
535+
/** Starts an asynchronous computation and returns a `Future` object with the result of that computation.
534536
*
535537
* The result becomes available once the asynchronous computation is completed.
536538
*
@@ -544,18 +546,18 @@ object Future {
544546
import scala.collection.mutable.Builder
545547
import scala.collection.generic.CanBuildFrom
546548

547-
/** Simple version of `Futures.traverse`. Transforms a `Traversable[Future[A]]` into a `Future[Traversable[A]]`.
549+
/** Simple version of `Futures.traverse`. Transforms a `TraversableOnce[Future[A]]` into a `Future[TraversableOnce[A]]`.
548550
* Useful for reducing many `Future`s into a single `Future`.
549551
*/
550-
def sequence[A, M[_] <: Traversable[_]](in: M[Future[A]])(implicit cbf: CanBuildFrom[M[Future[A]], A, M[A]], executor: ExecutionContext): Future[M[A]] = {
552+
def sequence[A, M[_] <: TraversableOnce[_]](in: M[Future[A]])(implicit cbf: CanBuildFrom[M[Future[A]], A, M[A]], executor: ExecutionContext): Future[M[A]] = {
551553
in.foldLeft(Promise.successful(cbf(in)).future) {
552554
(fr, fa) => for (r <- fr; a <- fa.asInstanceOf[Future[A]]) yield (r += a)
553555
} map (_.result)
554556
}
555557

556558
/** Returns a `Future` to the result of the first future in the list that is completed.
557559
*/
558-
def firstCompletedOf[T](futures: Traversable[Future[T]])(implicit executor: ExecutionContext): Future[T] = {
560+
def firstCompletedOf[T](futures: TraversableOnce[Future[T]])(implicit executor: ExecutionContext): Future[T] = {
559561
val p = Promise[T]()
560562

561563
val completeFirst: Either[Throwable, T] => Unit = p tryComplete _
@@ -566,7 +568,8 @@ object Future {
566568

567569
/** Returns a `Future` that will hold the optional result of the first `Future` with a result that matches the predicate.
568570
*/
569-
def find[T](futures: Traversable[Future[T]])(predicate: T => Boolean)(implicit executor: ExecutionContext): Future[Option[T]] = {
571+
def find[T](futurestravonce: TraversableOnce[Future[T]])(predicate: T => Boolean)(implicit executor: ExecutionContext): Future[Option[T]] = {
572+
val futures = futurestravonce.toBuffer
570573
if (futures.isEmpty) Promise.successful[Option[T]](None).future
571574
else {
572575
val result = Promise[Option[T]]()
@@ -577,8 +580,9 @@ object Future {
577580
case _ =>
578581
}
579582
} finally {
580-
if (ref.decrementAndGet == 0)
583+
if (ref.decrementAndGet == 0) {
581584
result tryComplete Right(None)
585+
}
582586
}
583587

584588
futures.foreach(_ onComplete search)
@@ -597,7 +601,7 @@ object Future {
597601
* val result = Await.result(Future.fold(futures)(0)(_ + _), 5 seconds)
598602
* }}}
599603
*/
600-
def fold[T, R](futures: Traversable[Future[T]])(zero: R)(foldFun: (R, T) => R)(implicit executor: ExecutionContext): Future[R] = {
604+
def fold[T, R](futures: TraversableOnce[Future[T]])(zero: R)(foldFun: (R, T) => R)(implicit executor: ExecutionContext): Future[R] = {
601605
if (futures.isEmpty) Promise.successful(zero).future
602606
else sequence(futures).map(_.foldLeft(zero)(foldFun))
603607
}
@@ -609,20 +613,20 @@ object Future {
609613
* val result = Await.result(Futures.reduce(futures)(_ + _), 5 seconds)
610614
* }}}
611615
*/
612-
def reduce[T, R >: T](futures: Traversable[Future[T]])(op: (R, T) => R)(implicit executor: ExecutionContext): Future[R] = {
616+
def reduce[T, R >: T](futures: TraversableOnce[Future[T]])(op: (R, T) => R)(implicit executor: ExecutionContext): Future[R] = {
613617
if (futures.isEmpty) Promise[R].failure(new NoSuchElementException("reduce attempted on empty collection")).future
614618
else sequence(futures).map(_ reduceLeft op)
615619
}
616620

617-
/** Transforms a `Traversable[A]` into a `Future[Traversable[B]]` using the provided function `A => Future[B]`.
621+
/** Transforms a `TraversableOnce[A]` into a `Future[TraversableOnce[B]]` using the provided function `A => Future[B]`.
618622
* This is useful for performing a parallel map. For example, to apply a function to all items of a list
619623
* in parallel:
620624
*
621625
* {{{
622626
* val myFutureList = Future.traverse(myList)(x => Future(myFunc(x)))
623627
* }}}
624628
*/
625-
def traverse[A, B, M[_] <: Traversable[_]](in: M[A])(fn: A => Future[B])(implicit cbf: CanBuildFrom[M[A], B, M[B]], executor: ExecutionContext): Future[M[B]] =
629+
def traverse[A, B, M[_] <: TraversableOnce[_]](in: M[A])(fn: A => Future[B])(implicit cbf: CanBuildFrom[M[A], B, M[B]], executor: ExecutionContext): Future[M[B]] =
626630
in.foldLeft(Promise.successful(cbf(in)).future) { (fr, a) =>
627631
val fb = fn(a.asInstanceOf[A])
628632
for (r <- fr; b <- fb) yield (r += b)

src/library/scala/concurrent/util/Duration.scala

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
1-
/**
2-
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
3-
*/
1+
/* __ *\
2+
** ________ ___ / / ___ Scala API **
3+
** / __/ __// _ | / / / _ | (c) 2003-2012, LAMP/EPFL **
4+
** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
5+
** /____/\___/_/ |_/____/_/ | | **
6+
** |/ **
7+
\* */
48

59
package scala.concurrent.util
610

711
import java.util.concurrent.TimeUnit
812
import TimeUnit._
9-
import java.lang.{ Double JDouble }
13+
import java.lang.{ Double => JDouble }
1014
import language.implicitConversions
1115

1216
case class Deadline private (time: Duration) {

0 commit comments

Comments
 (0)