std/wrapnils (original) (raw)

Source Edit

This module allows evaluating expressions safely against the following conditions:

default(T) is returned in those cases when evaluating an expression of type T. This simplifies code by reducing need for if-else branches.

Note: experimental module, unstable API.

Example:

import std/wrapnils type Foo = ref object x1: string x2: Foo x3: ref int

var f: Foo assert ?.f.x2.x1 == ""

var f2 = Foo(x1: "a") f2.x2 = f2 assert ?.f2.x1 == "a" assert ?.Foo(x1: "a").x1 == "a"

assert ?.(f2.x2.x2).x3[] == 0

assert (?.f2.x2.x2).x3 == nil

Example:

import std/wrapnils

type B = object b0: int case cond: bool of false: discard of true: b1: float

var b = B(cond: false, b0: 3) doAssertRaises(FieldDefect): discard b.b1 doAssert ?.b.b1 == 0.0 b = B(cond: true, b1: 4.5) doAssert ?.b.b1 == 4.5

if (let p = ?.b.b1.addr; p != nil): p[] = 4.7 doAssert b.b1 == 4.7

Macros

macro ?.(a: typed): auto

Transforms a into an expression that can be safely evaluated even in presence of intermediate nil pointers/references, in which case a default value is produced.Source Edit

macro ??.(a: typed): Option

Same as ?. but returns an Option.

Example:

import std/options type Foo = ref object x1: ref int x2: int

var f1 = Foo(x1: int.new, x2: 2) doAssert (??.f1.x1[]).get == 0 doAssert (??.f1.x1[]).isSome doAssert (??.f1.x2).get == 2

var f2: Foo doAssert not (??.f2.x1[]).isSome

doAssertRaises(UnpackDefect): discard (??.f2.x1[]).get doAssert ?.f2.x1[] == 0

Source Edit