tgenerics_various.nim 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. discard """
  2. output: '''
  3. we
  4. direct
  5. generic
  6. generic
  7. '''
  8. """
  9. import algorithm, sugar, sequtils, typetraits, asyncdispatch
  10. block tconfusing_arrow:
  11. type Deck = object
  12. value: int
  13. proc sort(h: var seq[Deck]) =
  14. # works:
  15. h.sort(proc (x, y: Deck): auto =
  16. cmp(x.value, y.value))
  17. # fails:
  18. h.sort((x, y: Deck) => cmp(ord(x.value), ord(y.value)))
  19. var player: seq[Deck] = @[]
  20. player.sort()
  21. block tdictdestruct:
  22. type
  23. TDict[TK, TV] = object
  24. k: TK
  25. v: TV
  26. PDict[TK, TV] = ref TDict[TK, TV]
  27. proc fakeNew[T](x: var ref T, destroy: proc (a: ref T) {.nimcall.}) =
  28. discard
  29. proc destroyDict[TK, TV](a: PDict[TK, TV]) =
  30. return
  31. proc newDict[TK, TV](a: TK, b: TV): PDict[TK, TV] =
  32. fakeNew(result, destroyDict[TK, TV])
  33. # Problem: destroyDict is not instantiated when newDict is instantiated!
  34. discard newDict("a", "b")
  35. block tgenericdefaults:
  36. type
  37. TFoo[T, U, R = int] = object
  38. x: T
  39. y: U
  40. z: R
  41. TBar[T] = TFoo[T, array[4, T], T]
  42. var x1: TFoo[int, float]
  43. static:
  44. assert type(x1.x) is int
  45. assert type(x1.y) is float
  46. assert type(x1.z) is int
  47. var x2: TFoo[string, R = float, U = seq[int]]
  48. static:
  49. assert type(x2.x) is string
  50. assert type(x2.y) is seq[int]
  51. assert type(x2.z) is float
  52. var x3: TBar[float]
  53. static:
  54. assert type(x3.x) is float
  55. assert type(x3.y) is array[4, float]
  56. assert type(x3.z) is float
  57. block tprop:
  58. type
  59. TProperty[T] = object of RootObj
  60. getProc: proc(property: TProperty[T]): T {.nimcall.}
  61. setProc: proc(property: TProperty[T], value: T) {.nimcall.}
  62. value: T
  63. proc newProperty[T](value: RootObj): TProperty[T] =
  64. result.getProc = proc (property: TProperty[T]) =
  65. return property.value
  66. block trefs:
  67. type
  68. PA[T] = ref TA[T]
  69. TA[T] = object
  70. field: T
  71. var a: PA[string]
  72. new(a)
  73. a.field = "some string"
  74. proc someOther[T](len: string): seq[T] = discard
  75. proc someOther[T](len: int): seq[T] = echo "we"
  76. proc foo[T](x: T) =
  77. var s = someOther[T](34)
  78. #newSeq[T](34)
  79. foo 23
  80. when false:
  81. # Compiles unless you use var a: PA[string]
  82. type
  83. PA = ref TA
  84. TA[T] = object
  85. # Cannot instantiate:
  86. type
  87. TA[T] = object
  88. a: PA[T]
  89. PA[T] = ref TA[T]
  90. type
  91. PA[T] = ref TA[T]
  92. TA[T] = object
  93. block tsharedcases:
  94. proc typeNameLen(x: typedesc): int {.compileTime.} =
  95. result = x.name.len
  96. macro selectType(a, b: typedesc): typedesc =
  97. result = a
  98. type
  99. Foo[T] = object
  100. data1: array[T.high, int]
  101. data2: array[typeNameLen(T), float]
  102. data3: array[0..T.typeNameLen, selectType(float, int)]
  103. MyEnum = enum A, B, C, D
  104. var f1: Foo[MyEnum]
  105. var f2: Foo[int8]
  106. doAssert high(f1.data1) == 2 # (D = 3) - 1 == 2
  107. doAssert high(f1.data2) == 5 # (MyEnum.len = 6) - 1 == 5
  108. doAssert high(f2.data1) == 126 # 127 - 1 == 126
  109. doAssert high(f2.data2) == 3 # int8.len - 1 == 3
  110. static:
  111. assert high(f1.data1) == ord(C)
  112. assert high(f1.data2) == 5 # length of MyEnum minus one, because we used T.high
  113. assert high(f2.data1) == 126
  114. assert high(f2.data2) == 3
  115. assert high(f1.data3) == 6 # length of MyEnum
  116. assert high(f2.data3) == 4 # length of int8
  117. assert f2.data3[0] is float
  118. block tmap_auto:
  119. let x = map(@[1, 2, 3], x => x+10)
  120. assert x == @[11, 12, 13]
  121. let y = map(@[(1,"a"), (2,"b"), (3,"c")], x => $x[0] & x[1])
  122. assert y == @["1a", "2b", "3c"]
  123. proc eatsTwoArgProc[T,S,U](a: T, b: S, f: proc(t: T, s: S): U): U =
  124. f(a,b)
  125. let z = eatsTwoArgProc(1, "a", (t,s) => $t & s)
  126. assert z == "1a"
  127. block tproctypecache_falsepositive:
  128. type
  129. Callback = proc() {.closure, gcsafe.}
  130. GameState = ref object
  131. playerChangeHandlers: seq[Callback]
  132. proc newGameState(): GameState =
  133. result = GameState(
  134. playerChangeHandlers: newSeq[Callback]() # this fails
  135. )
  136. block tptrinheritance:
  137. type NSPasteboardItem = ptr object
  138. type NSPasteboard = ptr object
  139. type NSArrayAbstract = ptr object {.inheritable.}
  140. type NSMutableArrayAbstract = ptr object of NSArrayAbstract
  141. type NSArray[T] = ptr object of NSArrayAbstract
  142. type NSMutableArray[T] = ptr object of NSArray[T]
  143. proc newMutableArrayAbstract(): NSMutableArrayAbstract = discard
  144. template newMutableArray(T: typedesc): NSMutableArray[T] =
  145. cast[NSMutableArray[T]](newMutableArrayAbstract())
  146. proc writeObjects(p: NSPasteboard, o: NSArray[NSPasteboardItem]) = discard
  147. let a = newMutableArray NSPasteboardItem
  148. var x: NSMutableArray[NSPasteboardItem]
  149. var y: NSArray[NSPasteboardItem] = x
  150. writeObjects(nil, a)
  151. block tsigtypeop:
  152. type Vec3[T] = array[3, T]
  153. proc foo(x: Vec3, y: Vec3.T, z: x.T): x.type.T =
  154. return 10
  155. var y: Vec3[int] = [1, 2, 3]
  156. var z: int = foo(y, 3, 4)
  157. block tvarargs_vs_generics:
  158. proc withDirectType(args: string) =
  159. echo "direct"
  160. proc withDirectType[T](arg: T) =
  161. echo "generic"
  162. proc withOpenArray(args: openarray[string]) =
  163. echo "openarray"
  164. proc withOpenArray[T](arg: T) =
  165. echo "generic"
  166. proc withVarargs(args: varargs[string]) =
  167. echo "varargs"
  168. proc withVarargs[T](arg: T) =
  169. echo "generic"
  170. withDirectType "string"
  171. withOpenArray "string"
  172. withVarargs "string"