Support for .?[] operator on openArrays

This commit is contained in:
Tomasz Bekas 2023-11-20 12:34:45 +01:00
parent 2dd6b6b220
commit b4d8327329
No known key found for this signature in database
GPG Key ID: 4854E04C98824959
2 changed files with 23 additions and 6 deletions

View File

@ -1,13 +1,20 @@
import std/macros import std/macros
macro `.?`*(expression: seq | string, brackets: untyped{nkBracket}): untyped = macro `.?`*(expression: seq | string | openArray, 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`])
when typeof(`expression`) is openArray:
if `index` >= `expression`.low and `index` <= `expression`.high:
`expression`[`index`].some
else:
T.none
else:
let evaluated = `expression` let evaluated = `expression`
if `index` < evaluated.len: if `index` >= evaluated.low and `index` <= evaluated.high:
evaluated[`index`].some evaluated[`index`].some
else: else:
T.none T.none

View File

@ -339,11 +339,21 @@ suite "optionals":
let str = "a" let str = "a"
check str.?[0] == 'a'.some check str.?[0] == 'a'.some
check str.?[1] == char.none check str.?[1] == char.none
check str.?[-1] == char.none
test ".?[] can be used for indexing sequences without raising IndexDefect": test ".?[] can be used for indexing sequences without raising IndexDefect":
let sequence = @[1] let sequence = @[1]
check sequence.?[0] == 1.some check sequence.?[0] == 1.some
check sequence.?[1] == int.none check sequence.?[1] == int.none
check sequence.?[-1] == int.none
test ".?[] can be used for indexing openArrays without raising IndexDefect":
proc checkOpenArray(oa: openArray[int]): void =
check oa.?[0] == 1.some
check oa.?[1] == int.none
check oa.?[-1] == int.none
checkOpenArray(@[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