ttables.nim 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. discard """
  2. matrix: "--mm:refc; --mm:orc"
  3. """
  4. import tables, hashes
  5. import std/assertions
  6. type
  7. Person = object
  8. firstName, lastName: string
  9. proc hash(x: Person): Hash =
  10. ## Piggyback on the already available string hash proc.
  11. ##
  12. ## Without this proc nothing works!
  13. result = x.firstName.hash !& x.lastName.hash
  14. result = !$result
  15. var
  16. salaries = initTable[Person, int]()
  17. p1, p2: Person
  18. p1.firstName = "Jon"
  19. p1.lastName = "Ross"
  20. salaries[p1] = 30_000
  21. p2.firstName = "소진"
  22. p2.lastName = "박"
  23. salaries[p2] = 45_000
  24. var
  25. s2 = initOrderedTable[Person, int]()
  26. s3 = initCountTable[Person]()
  27. s2[p1] = 30_000
  28. s2[p2] = 45_000
  29. s3[p1] = 30_000
  30. s3[p2] = 45_000
  31. block: # Ordered table should preserve order after deletion
  32. var
  33. s4 = initOrderedTable[int, int]()
  34. s4[1] = 1
  35. s4[2] = 2
  36. s4[3] = 3
  37. var prev = 0
  38. for i in s4.values:
  39. doAssert(prev < i)
  40. prev = i
  41. s4.del(2)
  42. doAssert(2 notin s4)
  43. doAssert(s4.len == 2)
  44. prev = 0
  45. for i in s4.values:
  46. doAssert(prev < i)
  47. prev = i
  48. block: # Deletion from OrderedTable should account for collision groups. See issue #5057.
  49. # The bug is reproducible only with exact keys
  50. const key1 = "boy_jackpot.inGamma"
  51. const key2 = "boy_jackpot.outBlack"
  52. var t = {
  53. key1: 0,
  54. key2: 0
  55. }.toOrderedTable()
  56. t.del(key1)
  57. doAssert(t.len == 1)
  58. doAssert(key2 in t)
  59. var
  60. t1 = initCountTable[string]()
  61. t2 = initCountTable[string]()
  62. t1.inc("foo")
  63. t1.inc("bar", 2)
  64. t1.inc("baz", 3)
  65. t2.inc("foo", 4)
  66. t2.inc("bar")
  67. t2.inc("baz", 11)
  68. merge(t1, t2)
  69. doAssert(t1["foo"] == 5)
  70. doAssert(t1["bar"] == 3)
  71. doAssert(t1["baz"] == 14)
  72. let
  73. t1r = newCountTable[string]()
  74. t2r = newCountTable[string]()
  75. t1r.inc("foo")
  76. t1r.inc("bar", 2)
  77. t1r.inc("baz", 3)
  78. t2r.inc("foo", 4)
  79. t2r.inc("bar")
  80. t2r.inc("baz", 11)
  81. merge(t1r, t2r)
  82. doAssert(t1r["foo"] == 5)
  83. doAssert(t1r["bar"] == 3)
  84. doAssert(t1r["baz"] == 14)
  85. var
  86. t1l = initCountTable[string]()
  87. t2l = initCountTable[string]()
  88. t1l.inc("foo")
  89. t1l.inc("bar", 2)
  90. t1l.inc("baz", 3)
  91. t2l.inc("foo", 4)
  92. t2l.inc("bar")
  93. t2l.inc("baz", 11)
  94. block:
  95. const testKey = "TESTKEY"
  96. let t: CountTableRef[string] = newCountTable[string]()
  97. # Before, does not compile with error message:
  98. #test_counttable.nim(7, 43) template/generic instantiation from here
  99. #lib/pure/collections/tables.nim(117, 21) template/generic instantiation from here
  100. #lib/pure/collections/tableimpl.nim(32, 27) Error: undeclared field: 'hcode
  101. doAssert 0 == t[testKey]
  102. t.inc(testKey, 3)
  103. doAssert 3 == t[testKey]
  104. block:
  105. # Clear tests
  106. var clearTable = newTable[int, string]()
  107. clearTable[42] = "asd"
  108. clearTable[123123] = "piuyqwb "
  109. doAssert clearTable[42] == "asd"
  110. clearTable.clear()
  111. doAssert(not clearTable.hasKey(123123))
  112. doAssert clearTable.getOrDefault(42) == ""
  113. block: #5482
  114. var a = [("wrong?", "foo"), ("wrong?", "foo2")].newOrderedTable()
  115. var b = newOrderedTable[string, string](initialSize = 2)
  116. b["wrong?"] = "foo"
  117. b["wrong?"] = "foo2"
  118. doAssert a == b
  119. block: #5482
  120. var a = {"wrong?": "foo", "wrong?": "foo2"}.newOrderedTable()
  121. var b = newOrderedTable[string, string](initialSize = 2)
  122. b["wrong?"] = "foo"
  123. b["wrong?"] = "foo2"
  124. doAssert a == b
  125. block: #5487
  126. var a = {"wrong?": "foo", "wrong?": "foo2"}.newOrderedTable()
  127. var b = newOrderedTable[string, string]() # notice, default size!
  128. b["wrong?"] = "foo"
  129. b["wrong?"] = "foo2"
  130. doAssert a == b
  131. block: #5487
  132. var a = [("wrong?", "foo"), ("wrong?", "foo2")].newOrderedTable()
  133. var b = newOrderedTable[string, string]() # notice, default size!
  134. b["wrong?"] = "foo"
  135. b["wrong?"] = "foo2"
  136. doAssert a == b
  137. block:
  138. var a = {"wrong?": "foo", "wrong?": "foo2"}.newOrderedTable()
  139. var b = [("wrong?", "foo"), ("wrong?", "foo2")].newOrderedTable()
  140. var c = newOrderedTable[string, string]() # notice, default size!
  141. c["wrong?"] = "foo"
  142. c["wrong?"] = "foo2"
  143. doAssert a == b
  144. doAssert a == c
  145. block: #6250
  146. let
  147. a = {3: 1}.toOrderedTable
  148. b = {3: 2}.toOrderedTable
  149. doAssert((a == b) == false)
  150. doAssert((b == a) == false)
  151. block: #6250
  152. let
  153. a = {3: 2}.toOrderedTable
  154. b = {3: 2}.toOrderedTable
  155. doAssert((a == b) == true)
  156. doAssert((b == a) == true)
  157. block: # CountTable.smallest
  158. let t = toCountTable([0, 0, 5, 5, 5])
  159. doAssert t.smallest == (0, 2)
  160. block: #10065
  161. let t = toCountTable("abracadabra")
  162. doAssert t['z'] == 0
  163. var t_mut = toCountTable("abracadabra")
  164. doAssert t_mut['z'] == 0
  165. # the previous read may not have modified the table.
  166. doAssert t_mut.hasKey('z') == false
  167. t_mut['z'] = 1
  168. doAssert t_mut['z'] == 1
  169. doAssert t_mut.hasKey('z') == true
  170. block: #12813 #13079
  171. var t = toCountTable("abracadabra")
  172. doAssert len(t) == 5
  173. t['a'] = 0 # remove a key
  174. doAssert len(t) == 4
  175. block:
  176. var tp: Table[string, string] = initTable[string, string]()
  177. doAssert "test1" == tp.getOrDefault("test1", "test1")
  178. tp["test2"] = "test2"
  179. doAssert "test2" == tp.getOrDefault("test2", "test1")
  180. var tr: TableRef[string, string] = newTable[string, string]()
  181. doAssert "test1" == tr.getOrDefault("test1", "test1")
  182. tr["test2"] = "test2"
  183. doAssert "test2" == tr.getOrDefault("test2", "test1")
  184. var op: OrderedTable[string, string] = initOrderedTable[string, string]()
  185. doAssert "test1" == op.getOrDefault("test1", "test1")
  186. op["test2"] = "test2"
  187. doAssert "test2" == op.getOrDefault("test2", "test1")
  188. var orf: OrderedTableRef[string, string] = newOrderedTable[string, string]()
  189. doAssert "test1" == orf.getOrDefault("test1", "test1")
  190. orf["test2"] = "test2"
  191. doAssert "test2" == orf.getOrDefault("test2", "test1")
  192. block tableWithoutInit:
  193. var
  194. a: Table[string, int]
  195. b: Table[string, int]
  196. c: Table[string, int]
  197. d: Table[string, int]
  198. e: Table[string, int]
  199. a["a"] = 7
  200. doAssert a.hasKey("a")
  201. doAssert a.len == 1
  202. doAssert a["a"] == 7
  203. a["a"] = 9
  204. doAssert a.len == 1
  205. doAssert a["a"] == 9
  206. doAssert b.hasKeyOrPut("b", 5) == false
  207. doAssert b.hasKey("b")
  208. doAssert b.hasKeyOrPut("b", 8)
  209. doAssert b["b"] == 5
  210. doAssert c.getOrDefault("a") == 0
  211. doAssert c.getOrDefault("a", 3) == 3
  212. c["a"] = 6
  213. doAssert c.getOrDefault("a", 3) == 6
  214. doAssert d.mgetOrPut("a", 3) == 3
  215. doAssert d.mgetOrPut("a", 6) == 3
  216. var x = 99
  217. doAssert e.pop("a", x) == false
  218. doAssert x == 99
  219. e["a"] = 77
  220. doAssert e.pop("a", x)
  221. doAssert x == 77
  222. block orderedTableWithoutInit:
  223. var
  224. a: OrderedTable[string, int]
  225. b: OrderedTable[string, int]
  226. c: OrderedTable[string, int]
  227. d: OrderedTable[string, int]
  228. a["a"] = 7
  229. doAssert a.hasKey("a")
  230. doAssert a.len == 1
  231. doAssert a["a"] == 7
  232. a["a"] = 9
  233. doAssert a.len == 1
  234. doAssert a["a"] == 9
  235. doAssert b.hasKeyOrPut("b", 5) == false
  236. doAssert b.hasKey("b")
  237. doAssert b.hasKeyOrPut("b", 8)
  238. doAssert b["b"] == 5
  239. doAssert c.getOrDefault("a") == 0
  240. doAssert c.getOrDefault("a", 3) == 3
  241. c["a"] = 6
  242. doAssert c.getOrDefault("a", 3) == 6
  243. doAssert d.mgetOrPut("a", 3) == 3
  244. doAssert d.mgetOrPut("a", 6) == 3
  245. block countTableWithoutInit:
  246. var
  247. a: CountTable[string]
  248. b: CountTable[string]
  249. c: CountTable[string]
  250. d: CountTable[string]
  251. e: CountTable[string]
  252. a["a"] = 7
  253. doAssert a.hasKey("a")
  254. doAssert a.len == 1
  255. doAssert a["a"] == 7
  256. a["a"] = 9
  257. doAssert a.len == 1
  258. doAssert a["a"] == 9
  259. doAssert b["b"] == 0
  260. b.inc("b")
  261. doAssert b["b"] == 1
  262. doAssert c.getOrDefault("a") == 0
  263. doAssert c.getOrDefault("a", 3) == 3
  264. c["a"] = 6
  265. doAssert c.getOrDefault("a", 3) == 6
  266. e["f"] = 3
  267. merge(d, e)
  268. doAssert d.hasKey("f")
  269. d.inc("f")
  270. merge(d, e)
  271. doAssert d["f"] == 7
  272. block: # issue #23587
  273. type
  274. A = proc ()
  275. proc main =
  276. let repo = initTable[uint32, A]()
  277. let c1 = repo.getOrDefault(uint32(1), nil)
  278. doAssert c1.isNil
  279. let c2 = repo.getOrDefault(uint32(1), A(nil))
  280. doAssert c2.isNil
  281. main()