From fa0bf405e64b1c2c3693110aaff1881a535e5fab Mon Sep 17 00:00:00 2001 From: Jacek Sieka Date: Mon, 20 Nov 2023 11:04:28 +0100 Subject: [PATCH] varargs overloads (#477) * varargs overloads for convenience and compatibility * no parameterless varargs calls with generic overloads --- chronos/internal/asyncfutures.nim | 38 +++++++++++++++++++++++++++---- tests/testfut.nim | 13 +++++++---- 2 files changed, 43 insertions(+), 8 deletions(-) diff --git a/chronos/internal/asyncfutures.nim b/chronos/internal/asyncfutures.nim index 6a6dbb2..ba7eaf0 100644 --- a/chronos/internal/asyncfutures.nim +++ b/chronos/internal/asyncfutures.nim @@ -1094,10 +1094,18 @@ proc allFutures*[T](futs: varargs[Future[T]]): Future[void] {. ## ## On cancel all the awaited futures ``futs`` WILL NOT BE cancelled. # Because we can't capture varargs[T] in closures we need to create copy. - var nfuts: seq[FutureBase] - for future in futs: - nfuts.add(future) - allFutures(nfuts) + allFutures(futs.mapIt(FutureBase(it))) + +proc allFutures*[T, E](futs: varargs[InternalRaisesFuture[T, E]]): Future[void] {. + async: (raw: true, raises: [CancelledError]).} = + ## Returns a future which will complete only when all futures in ``futs`` + ## will be completed, failed or canceled. + ## + ## If the argument is empty, the returned future COMPLETES immediately. + ## + ## On cancel all the awaited futures ``futs`` WILL NOT BE cancelled. + # Because we can't capture varargs[T] in closures we need to create copy. + allFutures(futs.mapIt(FutureBase(it))) proc allFinished*[F: SomeFuture](futs: varargs[F]): Future[seq[F]] {. async: (raw: true, raises: [CancelledError]).} = @@ -1239,6 +1247,28 @@ proc race*(futs: varargs[FutureBase]): Future[FutureBase] {. return retFuture +proc race*[T](futs: varargs[Future[T]]): Future[FutureBase] {. + async: (raw: true, raises: [ValueError, CancelledError]).} = + ## Returns a future which will complete only when all futures in ``futs`` + ## will be completed, failed or canceled. + ## + ## If the argument is empty, the returned future COMPLETES immediately. + ## + ## On cancel all the awaited futures ``futs`` WILL NOT BE cancelled. + # Because we can't capture varargs[T] in closures we need to create copy. + race(futs.mapIt(FutureBase(it))) + +proc race*[T, E](futs: varargs[InternalRaisesFuture[T, E]]): Future[FutureBase] {. + async: (raw: true, raises: [ValueError, CancelledError]).} = + ## Returns a future which will complete only when all futures in ``futs`` + ## will be completed, failed or canceled. + ## + ## If the argument is empty, the returned future COMPLETES immediately. + ## + ## On cancel all the awaited futures ``futs`` WILL NOT BE cancelled. + # Because we can't capture varargs[T] in closures we need to create copy. + race(futs.mapIt(FutureBase(it))) + when (chronosEventEngine in ["epoll", "kqueue"]) or defined(windows): import std/os diff --git a/tests/testfut.nim b/tests/testfut.nim index 367b5d0..fc2401d 100644 --- a/tests/testfut.nim +++ b/tests/testfut.nim @@ -1314,12 +1314,17 @@ suite "Future[T] behavior test suite": test "race(zero) test": var tseq = newSeq[FutureBase]() var fut1 = race(tseq) - var fut2 = race() - var fut3 = race([]) + check: + # https://github.com/nim-lang/Nim/issues/22964 + not compiles(block: + var fut2 = race()) + not compiles(block: + var fut3 = race([])) + check: fut1.failed() - fut2.failed() - fut3.failed() + # fut2.failed() + # fut3.failed() asyncTest "race(varargs) test": proc vlient1() {.async.} =