futures: lentify (#413)
sometimes avoid copies when reading from `Future`
This commit is contained in:
parent
6c2ea67512
commit
a7f708bea8
|
@ -451,19 +451,25 @@ proc internalCheckComplete*(fut: FutureBase) {.raises: [CatchableError].} =
|
|||
injectStacktrace(fut.internalError)
|
||||
raise fut.internalError
|
||||
|
||||
proc internalRead*[T](fut: Future[T]): T {.inline.} =
|
||||
# For internal use only. Used in asyncmacro
|
||||
when T isnot void:
|
||||
return fut.internalValue
|
||||
proc read*[T: not void](future: Future[T] ): lent T {.raises: [CatchableError].} =
|
||||
## Retrieves the value of ``future``. Future must be finished otherwise
|
||||
## this function will fail with a ``ValueError`` exception.
|
||||
##
|
||||
## If the result of the future is an error then that error will be raised.
|
||||
if not future.finished():
|
||||
# TODO: Make a custom exception type for this?
|
||||
raise newException(ValueError, "Future still in progress.")
|
||||
|
||||
proc read*[T](future: Future[T] ): T {.raises: [CatchableError].} =
|
||||
internalCheckComplete(future)
|
||||
future.internalValue
|
||||
|
||||
proc read*(future: Future[void] ) {.raises: [CatchableError].} =
|
||||
## Retrieves the value of ``future``. Future must be finished otherwise
|
||||
## this function will fail with a ``ValueError`` exception.
|
||||
##
|
||||
## If the result of the future is an error then that error will be raised.
|
||||
if future.finished():
|
||||
internalCheckComplete(future)
|
||||
internalRead(future)
|
||||
else:
|
||||
# TODO: Make a custom exception type for this?
|
||||
raise newException(ValueError, "Future still in progress.")
|
||||
|
|
|
@ -309,7 +309,7 @@ template await*[T](f: Future[T]): untyped =
|
|||
# `child` released by `futureContinue`
|
||||
chronosInternalRetFuture.internalChild.internalCheckComplete()
|
||||
when T isnot void:
|
||||
cast[type(f)](chronosInternalRetFuture.internalChild).internalRead()
|
||||
cast[type(f)](chronosInternalRetFuture.internalChild).value()
|
||||
else:
|
||||
unsupported "await is only available within {.async.}"
|
||||
|
||||
|
|
|
@ -184,7 +184,7 @@ func completed*(future: FutureBase): bool {.inline.} =
|
|||
func location*(future: FutureBase): array[LocationKind, ptr SrcLoc] =
|
||||
future.internalLocation
|
||||
|
||||
func value*[T](future: Future[T]): T =
|
||||
func value*[T: not void](future: Future[T]): lent T =
|
||||
## Return the value in a completed future - raises Defect when
|
||||
## `fut.completed()` is `false`.
|
||||
##
|
||||
|
@ -196,8 +196,19 @@ func value*[T](future: Future[T]): T =
|
|||
msg: "Future not completed while accessing value",
|
||||
cause: future)
|
||||
|
||||
when T isnot void:
|
||||
future.internalValue
|
||||
future.internalValue
|
||||
|
||||
func value*(future: Future[void]) =
|
||||
## Return the value in a completed future - raises Defect when
|
||||
## `fut.completed()` is `false`.
|
||||
##
|
||||
## See `read` for a version that raises an catchable error when future
|
||||
## has not completed.
|
||||
when chronosStrictFutureAccess:
|
||||
if not future.completed():
|
||||
raise (ref FutureDefect)(
|
||||
msg: "Future not completed while accessing value",
|
||||
cause: future)
|
||||
|
||||
func error*(future: FutureBase): ref CatchableError =
|
||||
## Return the error of `future`, or `nil` if future did not fail.
|
||||
|
|
|
@ -1237,12 +1237,14 @@ suite "Future[T] behavior test suite":
|
|||
fut2.complete() # LINE POSITION 4
|
||||
fut3.complete() # LINE POSITION 6
|
||||
|
||||
{.push warning[Deprecated]: off.} # testing backwards compatibility interface
|
||||
let loc10 = fut1.location[0]
|
||||
let loc11 = fut1.location[1]
|
||||
let loc20 = fut2.location[0]
|
||||
let loc21 = fut2.location[1]
|
||||
let loc30 = fut3.location[0]
|
||||
let loc31 = fut3.location[1]
|
||||
{.pop.}
|
||||
|
||||
proc chk(loc: ptr SrcLoc, file: string, line: int,
|
||||
procedure: string): bool =
|
||||
|
|
Loading…
Reference in New Issue