tgenerics_various.nim 5.3 KB

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