mirror of
https://github.com/logos-storage/questionable.git
synced 2026-01-09 09:13:07 +00:00
Operator .?[] evaluates openArray expression only once
This commit is contained in:
parent
b4d8327329
commit
48e8fe845f
@ -1,23 +1,29 @@
|
|||||||
import std/macros
|
import std/macros
|
||||||
|
|
||||||
macro `.?`*(expression: seq | string | openArray, brackets: untyped{nkBracket}): untyped =
|
macro `.?`*(expression: seq | string, brackets: untyped{nkBracket}): untyped =
|
||||||
# chain is of shape: (seq or string).?[index]
|
# chain is of shape: (seq or string).?[index]
|
||||||
let index = brackets[0]
|
let index = brackets[0]
|
||||||
quote do:
|
quote do:
|
||||||
block:
|
block:
|
||||||
type T = typeof(`expression`[`index`])
|
type T = typeof(`expression`[`index`])
|
||||||
|
let evaluated = `expression`
|
||||||
when typeof(`expression`) is openArray:
|
if `index` >= evaluated.low and `index` <= evaluated.high:
|
||||||
if `index` >= `expression`.low and `index` <= `expression`.high:
|
evaluated[`index`].some
|
||||||
`expression`[`index`].some
|
|
||||||
else:
|
|
||||||
T.none
|
|
||||||
else:
|
else:
|
||||||
let evaluated = `expression`
|
T.none
|
||||||
if `index` >= evaluated.low and `index` <= evaluated.high:
|
|
||||||
evaluated[`index`].some
|
macro `.?`*(expression: openArray, brackets: untyped{nkBracket}): untyped =
|
||||||
|
# chain is of shape: openArray.?[index]
|
||||||
|
let index = brackets[0]
|
||||||
|
quote do:
|
||||||
|
block:
|
||||||
|
type T = typeof(`expression`[`index`])
|
||||||
|
proc safeGet(arr: openArray[T], i: int): ?T {.gensym.} =
|
||||||
|
if i >= arr.low and i <= arr.high:
|
||||||
|
arr[i].some
|
||||||
else:
|
else:
|
||||||
T.none
|
T.none
|
||||||
|
safeGet(`expression`, `index`)
|
||||||
|
|
||||||
macro `.?`*(expression: typed, brackets: untyped{nkBracket}): untyped =
|
macro `.?`*(expression: typed, brackets: untyped{nkBracket}): untyped =
|
||||||
# chain is of shape: expression.?[index]
|
# chain is of shape: expression.?[index]
|
||||||
|
|||||||
@ -355,6 +355,11 @@ suite "optionals":
|
|||||||
|
|
||||||
checkOpenArray(@[1])
|
checkOpenArray(@[1])
|
||||||
|
|
||||||
|
test ".?[] evaluates openArray expression only once":
|
||||||
|
var count = 0
|
||||||
|
discard (inc count; @[1].toOpenArray(0, 0)).?[0]
|
||||||
|
check count == 1
|
||||||
|
|
||||||
test ".?[] can be followed by calls, operators and indexing":
|
test ".?[] can be followed by calls, operators and indexing":
|
||||||
let table = @{"a": @[41, 42]}.toTable
|
let table = @{"a": @[41, 42]}.toTable
|
||||||
check table.?["a"].isSome
|
check table.?["a"].isSome
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user