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