tpackedsets.nim 5.8 KB

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