tpackedsets.nim 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. import std/packedsets
  2. import std/sets
  3. import sequtils
  4. import algorithm
  5. import std/assertions
  6. block basicIntSetTests:
  7. var y = initPackedSet[int]()
  8. y.incl(1)
  9. y.incl(2)
  10. y.incl(7)
  11. y.incl(1056)
  12. y.incl(1044)
  13. y.excl(1044)
  14. doAssert y == [1, 2, 7, 1056].toPackedSet
  15. doAssert toSeq(y.items) == [1, 2, 7, 1056]
  16. doAssert y.containsOrIncl(888) == false
  17. doAssert 888 in y
  18. doAssert y.containsOrIncl(888) == true
  19. doAssert y.missingOrExcl(888) == false
  20. doAssert 888 notin y
  21. doAssert y.missingOrExcl(888) == true
  22. proc sortedPairs[T](t: T): auto = toSeq(t.pairs).sorted
  23. template sortedItems(t: untyped): untyped = sorted(toSeq(t))
  24. type Id = distinct int
  25. proc `$`(x: Id): string {.borrow.}
  26. proc cmp(a: Id, b: Id): int {.borrow.}
  27. proc `==`(a: Id, b: Id): bool {.borrow.}
  28. proc `<`(a: Id, b: Id): bool {.borrow.}
  29. block genericTests:
  30. # we use HashSet as groundtruth, it's well tested elsewhere
  31. template testDel(A: typedesc, t: typed, t0: typed) =
  32. block:
  33. template checkEquals() =
  34. doAssert t.len == t0.len
  35. for k in t0:
  36. doAssert k in t
  37. for k in t:
  38. doAssert k in t0
  39. doAssert sortedItems(t) == sortedItems(t0)
  40. template incl2(i) =
  41. t.incl i
  42. t0.incl i
  43. template excl2(i) =
  44. t.excl i
  45. t0.excl i
  46. var expected: seq[A]
  47. let n = 100
  48. let n2 = n*2
  49. for i in 0..<n:
  50. incl2(A(i))
  51. checkEquals()
  52. for i in 0..<n:
  53. if i mod 3 == 0:
  54. if i < n div 2:
  55. excl2(A(i))
  56. else:
  57. t0.excl A(i)
  58. doAssert A(i) in t
  59. doAssert not t.missingOrExcl A(i)
  60. checkEquals()
  61. for i in n..<n2:
  62. incl2(A(i))
  63. checkEquals()
  64. for i in 0..<n2:
  65. if i mod 7 == 0:
  66. excl2(A(i))
  67. checkEquals()
  68. # notin check
  69. for i in 0..<t.len:
  70. if i mod 7 == 0:
  71. doAssert A(i) notin t0
  72. doAssert A(i) notin t
  73. # issue #13505
  74. doAssert t.missingOrExcl(A(i))
  75. var t: PackedSet[int]
  76. var t0: HashSet[int]
  77. testDel(int, t, t0)
  78. var distT: PackedSet[Id]
  79. var distT0: HashSet[Id]
  80. testDel(Id, distT, distT0)
  81. doAssert union(distT, initPackedSet[Id]()) == distT
  82. var charT: PackedSet[char]
  83. var charT0: HashSet[char]
  84. testDel(char, charT, charT0)
  85. block typeSafetyTest:
  86. # mixing sets of different types shouldn't compile
  87. doAssert not compiles( union(initPackedSet[Id](), initPackedSet[int]()) )
  88. doAssert compiles( union(initPackedSet[Id](), initPackedSet[Id]()))
  89. var ids: PackedSet[Id]
  90. doAssert not compiles( ids.incl(3) )
  91. doAssert compiles( ids.incl(Id(3)) )
  92. type NonOrdinal = string
  93. doAssert not compiles( initPackedSet[NonOrdinal]() )
  94. type EnumABCD = enum A, B, C, D
  95. block enumTest:
  96. var letterSet = initPackedSet[EnumABCD]()
  97. for x in [A, C]:
  98. letterSet.incl(x)
  99. doAssert A in letterSet
  100. doAssert B notin letterSet
  101. doAssert C in letterSet
  102. doAssert D notin letterSet
  103. type Foo = distinct int16
  104. proc `$`(a: Foo): string {.borrow.} # `echo a` below won't work without `$` defined, as expected
  105. block printTest:
  106. var a = initPackedSet[EnumABCD]()
  107. a.incl A
  108. a.incl C
  109. doAssert $a == "{A, C}"
  110. import intsets
  111. block legacyMainModuleTests:
  112. template genericTests(A: typedesc[Ordinal], x: typed) =
  113. block:
  114. proc typSeq(s: seq[int]): seq[A] = s.map(proc (i: int): A = A(i))
  115. x.incl(A(1))
  116. x.incl(A(2))
  117. x.incl(A(7))
  118. x.incl(A(1056))
  119. x.incl(A(1044))
  120. x.excl(A(1044))
  121. doAssert x == typSeq(@[1, 2, 7, 1056]).toPackedSet
  122. doAssert x.containsOrIncl(A(888)) == false
  123. doAssert A(888) in x
  124. doAssert x.containsOrIncl(A(888)) == true
  125. doAssert x.missingOrExcl(A(888)) == false
  126. doAssert A(888) notin x
  127. doAssert x.missingOrExcl(A(888)) == true
  128. var xs = toSeq(items(x))
  129. xs.sort(cmp[A])
  130. doAssert xs == typSeq(@[1, 2, 7, 1056])
  131. var y: PackedSet[A]
  132. assign(y, x)
  133. var ys = toSeq(items(y))
  134. ys.sort(cmp[A])
  135. doAssert ys == typSeq(@[1, 2, 7, 1056])
  136. doAssert x == y
  137. var z: PackedSet[A]
  138. for i in 0..1000:
  139. incl z, A(i)
  140. doAssert z.len() == i+1
  141. for i in 0..1000:
  142. doAssert z.contains(A(i))
  143. var w = initPackedSet[A]()
  144. w.incl(A(1))
  145. w.incl(A(4))
  146. w.incl(A(50))
  147. w.incl(A(1001))
  148. w.incl(A(1056))
  149. var xuw = x.union(w)
  150. var xuws = toSeq(items(xuw))
  151. xuws.sort(cmp)
  152. doAssert xuws == typSeq(@[1, 2, 4, 7, 50, 1001, 1056])
  153. var xiw = x.intersection(w)
  154. var xiws = toSeq(items(xiw))
  155. xiws.sort(cmp)
  156. doAssert xiws == @[A(1), A(1056)]
  157. var xdw = x.difference(w)
  158. var xdws = toSeq(items(xdw))
  159. xdws.sort(cmp[A])
  160. doAssert xdws == @[A(2), A(7)]
  161. var xsw = x.symmetricDifference(w)
  162. var xsws = toSeq(items(xsw))
  163. xsws.sort(cmp[A])
  164. doAssert xsws == typSeq(@[2, 4, 7, 50, 1001])
  165. x.incl(w)
  166. xs = toSeq(items(x))
  167. xs.sort(cmp[A])
  168. doAssert xs == typSeq(@[1, 2, 4, 7, 50, 1001, 1056])
  169. doAssert w <= x
  170. doAssert w < x
  171. doAssert(not disjoint(w, x))
  172. var u = initPackedSet[A]()
  173. u.incl(A(3))
  174. u.incl(A(5))
  175. u.incl(A(500))
  176. doAssert disjoint(u, x)
  177. var v = initPackedSet[A]()
  178. v.incl(A(2))
  179. v.incl(A(50))
  180. x.excl(v)
  181. xs = toSeq(items(x))
  182. xs.sort(cmp[A])
  183. doAssert xs == typSeq(@[1, 4, 7, 1001, 1056])
  184. proc bug12366 =
  185. var
  186. x = initPackedSet[A]()
  187. y = initPackedSet[A]()
  188. n = 3584
  189. for i in 0..n:
  190. x.incl(A(i))
  191. y.incl(A(i))
  192. let z = symmetricDifference(x, y)
  193. doAssert z.len == 0
  194. doAssert $z == "{}"
  195. bug12366()
  196. var legacyInit = initIntSet()
  197. genericTests(int, legacyInit)
  198. var intGenericInit = initPackedSet[int]()
  199. genericTests(int, intGenericInit)
  200. var intDistinct = initPackedSet[Id]()
  201. genericTests(Id, intDistinct)