ttables.nim 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435
  1. discard """
  2. output: '''
  3. done tableadds
  4. And we get here
  5. 1
  6. 2
  7. 3
  8. '''
  9. joinable: false
  10. """
  11. import hashes, sequtils, tables, algorithm
  12. proc sortedPairs[T](t: T): auto = toSeq(t.pairs).sorted
  13. template sortedItems(t: untyped): untyped = sorted(toSeq(t))
  14. block tableDollar:
  15. # other tests should use `sortedPairs` to be robust to future table/hash
  16. # implementation changes
  17. doAssert ${1: 'a', 2: 'b'}.toTable in ["{1: 'a', 2: 'b'}", "{2: 'b', 1: 'a'}"]
  18. # test should not be joined because it takes too long.
  19. block tableadds:
  20. proc main =
  21. var tab = newTable[string, string]()
  22. for i in 0..1000:
  23. tab.add "key", "value " & $i
  24. main()
  25. echo "done tableadds"
  26. block tcounttable:
  27. # bug #2625
  28. const s_len = 32
  29. var substr_counts: CountTable[string] = initCountTable[string]()
  30. var my_string = "Hello, this is sadly broken for strings over 64 characters. Note that it *does* appear to work for short strings."
  31. for i in 0..(my_string.len - s_len):
  32. let s = my_string[i..i+s_len-1]
  33. substr_counts[s] = 1
  34. # substr_counts[s] = substr_counts[s] + 1 # Also breaks, + 2 as well, etc.
  35. # substr_counts.inc(s) # This works
  36. #echo "Iteration ", i
  37. echo "And we get here"
  38. block thashes:
  39. # Test with int
  40. block:
  41. var t = initTable[int,int]()
  42. t[0] = 42
  43. t[1] = t[0] + 1
  44. assert(t[0] == 42)
  45. assert(t[1] == 43)
  46. let t2 = {1: 1, 2: 2}.toTable
  47. assert(t2[2] == 2)
  48. # Test with char
  49. block:
  50. var t = initTable[char,int]()
  51. t['0'] = 42
  52. t['1'] = t['0'] + 1
  53. assert(t['0'] == 42)
  54. assert(t['1'] == 43)
  55. let t2 = {'1': 1, '2': 2}.toTable
  56. assert(t2['2'] == 2)
  57. # Test with enum
  58. block:
  59. type
  60. E = enum eA, eB, eC
  61. var t = initTable[E,int]()
  62. t[eA] = 42
  63. t[eB] = t[eA] + 1
  64. assert(t[eA] == 42)
  65. assert(t[eB] == 43)
  66. let t2 = {eA: 1, eB: 2}.toTable
  67. assert(t2[eB] == 2)
  68. # Test with range
  69. block:
  70. type
  71. R = range[0..9]
  72. var t = initTable[R,int]() # causes warning, why?
  73. t[1] = 42 # causes warning, why?
  74. t[2] = t[1] + 1
  75. assert(t[1] == 42)
  76. assert(t[2] == 43)
  77. let t2 = {1.R: 1, 2.R: 2}.toTable
  78. assert(t2[2.R] == 2)
  79. # Test which combines the generics for tuples + ordinals
  80. block:
  81. type
  82. E = enum eA, eB, eC
  83. var t = initTable[(string, E, int, char), int]()
  84. t[("a", eA, 0, '0')] = 42
  85. t[("b", eB, 1, '1')] = t[("a", eA, 0, '0')] + 1
  86. assert(t[("a", eA, 0, '0')] == 42)
  87. assert(t[("b", eB, 1, '1')] == 43)
  88. let t2 = {("a", eA, 0, '0'): 1, ("b", eB, 1, '1'): 2}.toTable
  89. assert(t2[("b", eB, 1, '1')] == 2)
  90. # Test to check if overloading is possible
  91. # Unfortunately, this does not seem to work for int
  92. # The same test with a custom hash(s: string) does
  93. # work though.
  94. block:
  95. proc hash(x: int): Hash {.inline.} =
  96. echo "overloaded hash"
  97. result = x
  98. var t = initTable[int, int]()
  99. t[0] = 0
  100. # Check hashability of all integer types (issue #5429)
  101. block:
  102. let intTables = (
  103. newTable[int, string](),
  104. newTable[int8, string](),
  105. newTable[int16, string](),
  106. newTable[int32, string](),
  107. newTable[int64, string](),
  108. newTable[uint, string](),
  109. newTable[uint8, string](),
  110. newTable[uint16, string](),
  111. newTable[uint32, string](),
  112. newTable[uint64, string](),
  113. )
  114. echo "1"
  115. block tindexby:
  116. doAssert indexBy(newSeq[int](), proc(x: int):int = x) == initTable[int, int](), "empty int table"
  117. var tbl1 = initTable[int, int]()
  118. tbl1.add(1,1)
  119. tbl1.add(2,2)
  120. doAssert indexBy(@[1,2], proc(x: int):int = x) == tbl1, "int table"
  121. type
  122. TElem = object
  123. foo: int
  124. bar: string
  125. let
  126. elem1 = TElem(foo: 1, bar: "bar")
  127. elem2 = TElem(foo: 2, bar: "baz")
  128. var tbl2 = initTable[string, TElem]()
  129. tbl2.add("bar", elem1)
  130. tbl2.add("baz", elem2)
  131. doAssert indexBy(@[elem1,elem2], proc(x: TElem): string = x.bar) == tbl2, "element table"
  132. block tableconstr:
  133. # Test if the new table constructor syntax works:
  134. template ignoreExpr(e) =
  135. discard
  136. # test first class '..' syntactical citizen:
  137. ignoreExpr x <> 2..4
  138. # test table constructor:
  139. ignoreExpr({:})
  140. ignoreExpr({2: 3, "key": "value"})
  141. # NEW:
  142. assert 56 in 50..100
  143. assert 56 in ..60
  144. block ttables2:
  145. proc TestHashIntInt() =
  146. var tab = initTable[int,int]()
  147. let n = 100_000
  148. for i in 1..n:
  149. tab[i] = i
  150. for i in 1..n:
  151. var x = tab[i]
  152. if x != i : echo "not found ", i
  153. proc run1() =
  154. for i in 1 .. 50:
  155. TestHashIntInt()
  156. # bug #2107
  157. var delTab = initTable[int,int](4)
  158. for i in 1..4:
  159. delTab[i] = i
  160. delTab.del(i)
  161. delTab[5] = 5
  162. run1()
  163. echo "2"
  164. block allValues:
  165. var t: Table[int, string]
  166. var key = 0
  167. let n = 1000
  168. for i in 0..<n: t.add(i, $i)
  169. const keys = [0, -1, 12]
  170. for i in 0..1:
  171. for key in keys:
  172. t.add(key, $key & ":" & $i)
  173. for i in 0..<n:
  174. if i notin keys:
  175. t.del(i)
  176. doAssert t.sortedPairs == @[(-1, "-1:0"), (-1, "-1:1"), (0, "0"), (0, "0:0"), (0, "0:1"), (12, "12"), (12, "12:0"), (12, "12:1")]
  177. doAssert sortedItems(t.allValues(0)) == @["0", "0:0", "0:1"]
  178. doAssert sortedItems(t.allValues(-1)) == @["-1:0", "-1:1"]
  179. doAssert sortedItems(t.allValues(12)) == @["12", "12:0", "12:1"]
  180. doAssert sortedItems(t.allValues(1)) == @[]
  181. block tablesref:
  182. const
  183. data = {
  184. "34": 123456, "12": 789,
  185. "90": 343, "0": 34404,
  186. "1": 344004, "2": 344774,
  187. "3": 342244, "4": 3412344,
  188. "5": 341232144, "6": 34214544,
  189. "7": 3434544, "8": 344544,
  190. "9": 34435644, "---00": 346677844,
  191. "10": 34484, "11": 34474, "19": 34464,
  192. "20": 34454, "30": 34141244, "40": 344114,
  193. "50": 344490, "60": 344491, "70": 344492,
  194. "80": 344497}
  195. sorteddata = {
  196. "---00": 346677844,
  197. "0": 34404,
  198. "1": 344004,
  199. "10": 34484,
  200. "11": 34474,
  201. "12": 789,
  202. "19": 34464,
  203. "2": 344774, "20": 34454,
  204. "3": 342244, "30": 34141244,
  205. "34": 123456,
  206. "4": 3412344, "40": 344114,
  207. "5": 341232144, "50": 344490,
  208. "6": 34214544, "60": 344491,
  209. "7": 3434544, "70": 344492,
  210. "8": 344544, "80": 344497,
  211. "9": 34435644,
  212. "90": 343}
  213. block tableTest1:
  214. var t = newTable[tuple[x, y: int], string]()
  215. t[(0,0)] = "00"
  216. t[(1,0)] = "10"
  217. t[(0,1)] = "01"
  218. t[(1,1)] = "11"
  219. for x in 0..1:
  220. for y in 0..1:
  221. assert t[(x,y)] == $x & $y
  222. assert t.sortedPairs ==
  223. @[((x: 0, y: 0), "00"), ((x: 0, y: 1), "01"), ((x: 1, y: 0), "10"), ((x: 1, y: 1), "11")]
  224. block tableTest2:
  225. var t = newTable[string, float]()
  226. t["test"] = 1.2345
  227. t["111"] = 1.000043
  228. t["123"] = 1.23
  229. t.del("111")
  230. t["012"] = 67.9
  231. t["123"] = 1.5 # test overwriting
  232. assert t["123"] == 1.5
  233. try:
  234. echo t["111"] # deleted
  235. except KeyError:
  236. discard
  237. assert(not hasKey(t, "111"))
  238. assert "111" notin t
  239. for key, val in items(data): t[key] = val.toFloat
  240. for key, val in items(data): assert t[key] == val.toFloat
  241. block orderedTableTest1:
  242. var t = newOrderedTable[string, int](2)
  243. for key, val in items(data): t[key] = val
  244. for key, val in items(data): assert t[key] == val
  245. var i = 0
  246. # `pairs` needs to yield in insertion order:
  247. for key, val in pairs(t):
  248. assert key == data[i][0]
  249. assert val == data[i][1]
  250. inc(i)
  251. for key, val in mpairs(t): val = 99
  252. for val in mvalues(t): assert val == 99
  253. block countTableTest1:
  254. var s = data.toTable
  255. var t = newCountTable[string]()
  256. var r = newCountTable[string]()
  257. for x in [t, r]:
  258. for k in s.keys:
  259. x.inc(k)
  260. assert x[k] == 1
  261. x.inc("90", 3)
  262. x.inc("12", 2)
  263. x.inc("34", 1)
  264. assert t.largest()[0] == "90"
  265. t.sort()
  266. r.sort(SortOrder.Ascending)
  267. var ps1 = toSeq t.pairs
  268. var ps2 = toSeq r.pairs
  269. ps2.reverse()
  270. for ps in [ps1, ps2]:
  271. var i = 0
  272. for (k, v) in ps:
  273. case i
  274. of 0: assert k == "90" and v == 4
  275. of 1: assert k == "12" and v == 3
  276. of 2: assert k == "34" and v == 2
  277. else: break
  278. inc i
  279. block SyntaxTest:
  280. var x = newTable[int, string]({:})
  281. discard x
  282. block nilTest:
  283. var i, j: TableRef[int, int] = nil
  284. assert i == j
  285. j = newTable[int, int]()
  286. assert i != j
  287. assert j != i
  288. i = newTable[int, int]()
  289. assert i == j
  290. proc orderedTableSortTest() =
  291. var t = newOrderedTable[string, int](2)
  292. for key, val in items(data): t[key] = val
  293. for key, val in items(data): assert t[key] == val
  294. proc cmper(x, y: tuple[key: string, val: int]): int = cmp(x.key, y.key)
  295. t.sort(cmper)
  296. var i = 0
  297. # `pairs` needs to yield in sorted order:
  298. for key, val in pairs(t):
  299. doAssert key == sorteddata[i][0]
  300. doAssert val == sorteddata[i][1]
  301. inc(i)
  302. t.sort(cmper, order=SortOrder.Descending)
  303. i = 0
  304. for key, val in pairs(t):
  305. doAssert key == sorteddata[high(data)-i][0]
  306. doAssert val == sorteddata[high(data)-i][1]
  307. inc(i)
  308. # check that lookup still works:
  309. for key, val in pairs(t):
  310. doAssert val == t[key]
  311. # check that insert still works:
  312. t["newKeyHere"] = 80
  313. block anonZipTest:
  314. let keys = @['a','b','c']
  315. let values = @[1, 2, 3]
  316. doAssert zip(keys, values).toTable.sortedPairs == @[('a', 1), ('b', 2), ('c', 3)]
  317. block clearTableTest:
  318. var t = newTable[string, float]()
  319. t["test"] = 1.2345
  320. t["111"] = 1.000043
  321. t["123"] = 1.23
  322. assert t.len() != 0
  323. t.clear()
  324. assert t.len() == 0
  325. block clearOrderedTableTest:
  326. var t = newOrderedTable[string, int](2)
  327. for key, val in items(data): t[key] = val
  328. assert t.len() != 0
  329. t.clear()
  330. assert t.len() == 0
  331. block clearCountTableTest:
  332. var t = newCountTable[string]()
  333. t.inc("90", 3)
  334. t.inc("12", 2)
  335. t.inc("34", 1)
  336. assert t.len() != 0
  337. t.clear()
  338. assert t.len() == 0
  339. orderedTableSortTest()
  340. echo "3"
  341. block: # https://github.com/nim-lang/Nim/issues/13496
  342. template testDel(body) =
  343. block:
  344. body
  345. when t is CountTable|CountTableRef:
  346. t.inc(15, 1)
  347. t.inc(19, 2)
  348. t.inc(17, 3)
  349. t.inc(150, 4)
  350. t.del(150)
  351. else:
  352. t[15] = 1
  353. t[19] = 2
  354. t[17] = 3
  355. t[150] = 4
  356. t.del(150)
  357. doAssert t.len == 3
  358. doAssert sortedItems(t.values) == @[1, 2, 3]
  359. doAssert sortedItems(t.keys) == @[15, 17, 19]
  360. doAssert sortedPairs(t) == @[(15, 1), (17, 3), (19, 2)]
  361. var s = newSeq[int]()
  362. for v in t.values: s.add(v)
  363. assert s.len == 3
  364. doAssert sortedItems(s) == @[1, 2, 3]
  365. when t is OrderedTable|OrderedTableRef:
  366. doAssert toSeq(t.keys) == @[15, 19, 17]
  367. doAssert toSeq(t.values) == @[1,2,3]
  368. doAssert toSeq(t.pairs) == @[(15, 1), (19, 2), (17, 3)]
  369. testDel(): (var t: Table[int, int])
  370. testDel(): (let t = newTable[int, int]())
  371. testDel(): (var t: OrderedTable[int, int])
  372. testDel(): (let t = newOrderedTable[int, int]())
  373. testDel(): (var t: CountTable[int])
  374. testDel(): (let t = newCountTable[int]())