diff options
author | Aleksandar Prokopec <axel22@gmail.com> | 2012-05-01 15:00:27 +0200 |
---|---|---|
committer | Aleksandar Prokopec <axel22@gmail.com> | 2012-05-01 15:00:27 +0200 |
commit | 5f29da78e954d93e5bc8b878565de8c2a2abe561 (patch) | |
tree | 0ef8d37ad1a12cc5d84ca635eff696f2500a0010 /src/library/scala/concurrent/Future.scala | |
parent | ce04a62391bdc879db0eca015a420711e1a07212 (diff) | |
download | scala-5f29da78e954d93e5bc8b878565de8c2a2abe561.tar.gz scala-5f29da78e954d93e5bc8b878565de8c2a2abe561.tar.bz2 scala-5f29da78e954d93e5bc8b878565de8c2a2abe561.zip |
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.
Diffstat (limited to 'src/library/scala/concurrent/Future.scala')
-rw-r--r-- | src/library/scala/concurrent/Future.scala | 52 |
1 files changed, 28 insertions, 24 deletions
diff --git a/src/library/scala/concurrent/Future.scala b/src/library/scala/concurrent/Future.scala index 55c91619fa..11505e4146 100644 --- a/src/library/scala/concurrent/Future.scala +++ b/src/library/scala/concurrent/Future.scala @@ -426,21 +426,8 @@ trait Future[+T] extends Awaitable[T] { * that conforms to `S`'s erased type or a `ClassCastException` otherwise. */ def mapTo[S](implicit tag: ClassTag[S]): Future[S] = { - import java.{ lang => jl } - val toBoxed = Map[Class[_], Class[_]]( - classOf[Boolean] -> classOf[jl.Boolean], - classOf[Byte] -> classOf[jl.Byte], - classOf[Char] -> classOf[jl.Character], - classOf[Short] -> classOf[jl.Short], - classOf[Int] -> classOf[jl.Integer], - classOf[Long] -> classOf[jl.Long], - classOf[Float] -> classOf[jl.Float], - classOf[Double] -> classOf[jl.Double], - classOf[Unit] -> classOf[scala.runtime.BoxedUnit] - ) - def boxedType(c: Class[_]): Class[_] = { - if (c.isPrimitive) toBoxed(c) else c + if (c.isPrimitive) Future.toBoxed(c) else c } val p = newPromise[S] @@ -530,7 +517,22 @@ trait Future[+T] extends Awaitable[T] { * Note: using this method yields nondeterministic dataflow programs. */ object Future { - /** Starts an asynchronous computation and returns a `Future` object with the result of that computation. + + import java.{ lang => jl } + + private[concurrent] val toBoxed = Map[Class[_], Class[_]]( + classOf[Boolean] -> classOf[jl.Boolean], + classOf[Byte] -> classOf[jl.Byte], + classOf[Char] -> classOf[jl.Character], + classOf[Short] -> classOf[jl.Short], + classOf[Int] -> classOf[jl.Integer], + classOf[Long] -> classOf[jl.Long], + classOf[Float] -> classOf[jl.Float], + classOf[Double] -> classOf[jl.Double], + classOf[Unit] -> classOf[scala.runtime.BoxedUnit] + ) + + /** Starts an asynchronous computation and returns a `Future` object with the result of that computation. * * The result becomes available once the asynchronous computation is completed. * @@ -544,10 +546,10 @@ object Future { import scala.collection.mutable.Builder import scala.collection.generic.CanBuildFrom - /** Simple version of `Futures.traverse`. Transforms a `Traversable[Future[A]]` into a `Future[Traversable[A]]`. + /** Simple version of `Futures.traverse`. Transforms a `TraversableOnce[Future[A]]` into a `Future[TraversableOnce[A]]`. * Useful for reducing many `Future`s into a single `Future`. */ - def sequence[A, M[_] <: Traversable[_]](in: M[Future[A]])(implicit cbf: CanBuildFrom[M[Future[A]], A, M[A]], executor: ExecutionContext): Future[M[A]] = { + def sequence[A, M[_] <: TraversableOnce[_]](in: M[Future[A]])(implicit cbf: CanBuildFrom[M[Future[A]], A, M[A]], executor: ExecutionContext): Future[M[A]] = { in.foldLeft(Promise.successful(cbf(in)).future) { (fr, fa) => for (r <- fr; a <- fa.asInstanceOf[Future[A]]) yield (r += a) } map (_.result) @@ -555,7 +557,7 @@ object Future { /** Returns a `Future` to the result of the first future in the list that is completed. */ - def firstCompletedOf[T](futures: Traversable[Future[T]])(implicit executor: ExecutionContext): Future[T] = { + def firstCompletedOf[T](futures: TraversableOnce[Future[T]])(implicit executor: ExecutionContext): Future[T] = { val p = Promise[T]() val completeFirst: Either[Throwable, T] => Unit = p tryComplete _ @@ -566,7 +568,8 @@ object Future { /** Returns a `Future` that will hold the optional result of the first `Future` with a result that matches the predicate. */ - def find[T](futures: Traversable[Future[T]])(predicate: T => Boolean)(implicit executor: ExecutionContext): Future[Option[T]] = { + def find[T](futurestravonce: TraversableOnce[Future[T]])(predicate: T => Boolean)(implicit executor: ExecutionContext): Future[Option[T]] = { + val futures = futurestravonce.toBuffer if (futures.isEmpty) Promise.successful[Option[T]](None).future else { val result = Promise[Option[T]]() @@ -577,8 +580,9 @@ object Future { case _ => } } finally { - if (ref.decrementAndGet == 0) + if (ref.decrementAndGet == 0) { result tryComplete Right(None) + } } futures.foreach(_ onComplete search) @@ -597,7 +601,7 @@ object Future { * val result = Await.result(Future.fold(futures)(0)(_ + _), 5 seconds) * }}} */ - def fold[T, R](futures: Traversable[Future[T]])(zero: R)(foldFun: (R, T) => R)(implicit executor: ExecutionContext): Future[R] = { + def fold[T, R](futures: TraversableOnce[Future[T]])(zero: R)(foldFun: (R, T) => R)(implicit executor: ExecutionContext): Future[R] = { if (futures.isEmpty) Promise.successful(zero).future else sequence(futures).map(_.foldLeft(zero)(foldFun)) } @@ -609,12 +613,12 @@ object Future { * val result = Await.result(Futures.reduce(futures)(_ + _), 5 seconds) * }}} */ - def reduce[T, R >: T](futures: Traversable[Future[T]])(op: (R, T) => R)(implicit executor: ExecutionContext): Future[R] = { + def reduce[T, R >: T](futures: TraversableOnce[Future[T]])(op: (R, T) => R)(implicit executor: ExecutionContext): Future[R] = { if (futures.isEmpty) Promise[R].failure(new NoSuchElementException("reduce attempted on empty collection")).future else sequence(futures).map(_ reduceLeft op) } - /** Transforms a `Traversable[A]` into a `Future[Traversable[B]]` using the provided function `A => Future[B]`. + /** Transforms a `TraversableOnce[A]` into a `Future[TraversableOnce[B]]` using the provided function `A => Future[B]`. * This is useful for performing a parallel map. For example, to apply a function to all items of a list * in parallel: * @@ -622,7 +626,7 @@ object Future { * val myFutureList = Future.traverse(myList)(x => Future(myFunc(x))) * }}} */ - 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]] = + 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]] = in.foldLeft(Promise.successful(cbf(in)).future) { (fr, a) => val fb = fn(a.asInstanceOf[A]) for (r <- fr; b <- fb) yield (r += b) |