summary refs log tree commit diff stats
path: root/tests/compile/tgensymgeneric.nim
blob: 54390a4efbaabed002d4e262757ca64795df103a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# We need to open the gensym'ed symbol again so that the instantiation
# creates a fresh copy; but this is wrong the very first reason for gensym
# is that scope rules cannot be used! So simply removing 'sfGenSym' does
# not work. Copying the symbol does not work either because we're already
# the owner of the symbol! What we need to do is to copy the symbol
# in the generic instantiation process...

type
  TA = object
    x: int
  TB = object
    x: string

template genImpl() =
  var gensymed: T
  when T is TB:
    gensymed.x = "abc"
  else:
    gensymed.x = 123
  shallowCopy(result, gensymed)

proc gen[T](x: T): T =
  genImpl()

var
  a: TA
  b: TB
let x = gen(a)
let y = gen(b)

echo x.x, " ", y.x
high: yield a[i] var arr = ["a", "b", "c", "d", "e"] for a in modItems(arr): a = "X" for a in items(arr): stdout.write(a) for i, a in modPairs(arr): a = $i for a in items(arr): stdout.write(a) echo "" #-------------------------------------------------------------------- # Lent iterators #-------------------------------------------------------------------- type NonCopyable = object x: int proc `=destroy`(o: var NonCopyable) = discard proc `=copy`(dst: var NonCopyable, src: NonCopyable) {.error.} proc `=sink`(dst: var NonCopyable, src: NonCopyable) = dst.x = src.x iterator lentItems[T](a: openarray[T]): lent T = for i in 0..a.high: yield a[i] iterator lentPairs[T](a: array[0..1, T]): tuple[key: int, val: lent T] = for i in 0..a.high: yield (i, a[i]) let arr1 = [1, 2, 3] let arr2 = @["a", "b", "c"] let arr3 = [NonCopyable(x: 1), NonCopyable(x: 2)] let arr4 = @[(1, "a"), (2, "b"), (3, "c")] var accum: string for x in lentItems(arr1): accum &= $x doAssert(accum == "123") accum = "" for x in lentItems(arr2): accum &= $x doAssert(accum == "abc") accum = "" for val in lentItems(arr3): accum &= $val.x doAssert(accum == "12") accum = "" for i, val in lentPairs(arr3): accum &= $i & "-" & $val.x & " " doAssert(accum == "0-1 1-2 ") accum = "" for i, val in lentItems(arr4): accum &= $i & "-" & $val & " " doAssert(accum == "1-a 2-b 3-c ") accum = "" for (i, val) in lentItems(arr4): accum &= $i & "-" & $val & " " doAssert(accum == "1-a 2-b 3-c ")