Skip to content

Commit

Permalink
add deref that wraps original `system.[]
Browse files Browse the repository at this point in the history
  • Loading branch information
timotheecour committed Jan 6, 2020
1 parent 889a770 commit ce296cb
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 2 deletions.
18 changes: 16 additions & 2 deletions lib/std/wrapnils.nim
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,18 @@ proc wrapnil*[T](a: T): Wrapnil[T] =
template `.`*(a: Wrapnil, b): untyped =
let a1 = a # to avoid double evaluations
let a2 = a1.valueImpl
type T = Wrapnil[type(a2.b)]
if a1.validImpl:
when type(a2) is ref|ptr:
if a2 == nil:
default(Wrapnil[type(a2.b)])
default(T)
else:
wrapnil(a2.b)
else:
wrapnil(a2.b)
else:
# nil is "sticky"; this is needed, see tests
default(Wrapnil[type(a2.b)])
default(T)

{.pop.}

Expand All @@ -51,3 +52,16 @@ template `[]`*[I](a: Wrapnil, i: I): untyped =
wrapnil(a1.valueImpl[i])
else:
default(Wrapnil[type(a1.valueImpl[i])])

template deref*(a: Wrapnil): untyped =
## Since `[]` is hijacked, we can use `deref` that wraps original `system.[]`
let a1 = a # to avoid double evaluations
let a2 = a1.valueImpl
type T = Wrapnil[type(a2[])]
if a1.validImpl:
if a2 == nil:
default(T)
else:
wrapnil(a2[])
else:
default(T)
9 changes: 9 additions & 0 deletions tests/stdlib/twrapnils.nim
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ var witness = 0
proc main() =
type Bar = object
b1: int
b2: ptr string

type Foo = ref object
x1: float
x2: Foo
Expand All @@ -19,6 +21,9 @@ proc main() =
x6: ptr Bar
x7: array[2, string]
x8: seq[int]
x9: ref Bar

proc fun(a: Bar): auto = a.b2

var a: Foo
var x6 = create(Bar)
Expand Down Expand Up @@ -57,4 +62,8 @@ proc main() =
doAssert initFoo(1.3).wrapnil.x1[] == 1.3
doAssert witness == 1

# since `[]` is hijacked, we can use `deref` that wraps original `system.[]`
# here, it's used twice, to deref `ref Bar` and then `ptr string`
doAssert a.wrapnil.x9.deref.fun.deref[] == ""

main()

0 comments on commit ce296cb

Please sign in to comment.