setops.nim 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. func incl*[T](x: var set[T], y: T) {.magic: "Incl".} =
  2. ## Includes element `y` in the set `x`.
  3. ##
  4. ## This is the same as `x = x + {y}`, but it might be more efficient.
  5. runnableExamples:
  6. var a = {1, 3, 5}
  7. a.incl(2)
  8. assert a == {1, 2, 3, 5}
  9. a.incl(4)
  10. assert a == {1, 2, 3, 4, 5}
  11. template incl*[T](x: var set[T], y: set[T]) =
  12. ## Includes the set `y` in the set `x`.
  13. runnableExamples:
  14. var a = {1, 3, 5, 7}
  15. var b = {4, 5, 6}
  16. a.incl(b)
  17. assert a == {1, 3, 4, 5, 6, 7}
  18. x = x + y
  19. func excl*[T](x: var set[T], y: T) {.magic: "Excl".} =
  20. ## Excludes element `y` from the set `x`.
  21. ##
  22. ## This is the same as `x = x - {y}`, but it might be more efficient.
  23. runnableExamples:
  24. var b = {2, 3, 5, 6, 12, 545}
  25. b.excl(5)
  26. assert b == {2, 3, 6, 12, 545}
  27. template excl*[T](x: var set[T], y: set[T]) =
  28. ## Excludes the set `y` from the set `x`.
  29. runnableExamples:
  30. var a = {1, 3, 5, 7}
  31. var b = {3, 4, 5}
  32. a.excl(b)
  33. assert a == {1, 7}
  34. x = x - y
  35. func card*[T](x: set[T]): int {.magic: "Card".} =
  36. ## Returns the cardinality of the set `x`, i.e. the number of elements
  37. ## in the set.
  38. runnableExamples:
  39. var a = {1, 3, 5, 7}
  40. assert card(a) == 4
  41. var b = {1, 3, 5, 7, 5}
  42. assert card(b) == 4 # repeated 5 doesn't count
  43. func len*[T](x: set[T]): int {.magic: "Card".}
  44. ## An alias for `card(x)`.
  45. func `*`*[T](x, y: set[T]): set[T] {.magic: "MulSet".} =
  46. ## This operator computes the intersection of two sets.
  47. runnableExamples:
  48. assert {1, 2, 3} * {2, 3, 4} == {2, 3}
  49. func `+`*[T](x, y: set[T]): set[T] {.magic: "PlusSet".} =
  50. ## This operator computes the union of two sets.
  51. runnableExamples:
  52. assert {1, 2, 3} + {2, 3, 4} == {1, 2, 3, 4}
  53. func `-`*[T](x, y: set[T]): set[T] {.magic: "MinusSet".} =
  54. ## This operator computes the difference of two sets.
  55. runnableExamples:
  56. assert {1, 2, 3} - {2, 3, 4} == {1}
  57. func contains*[T](x: set[T], y: T): bool {.magic: "InSet".} =
  58. ## One should overload this proc if one wants to overload the `in` operator.
  59. ##
  60. ## The parameters are in reverse order! `a in b` is a template for
  61. ## `contains(b, a)`.
  62. ## This is because the unification algorithm that Nim uses for overload
  63. ## resolution works from left to right.
  64. ## But for the `in` operator that would be the wrong direction for this
  65. ## piece of code:
  66. runnableExamples:
  67. var s: set[range['a'..'z']] = {'a'..'c'}
  68. assert s.contains('c')
  69. assert 'b' in s
  70. assert 'd' notin s
  71. assert set['a'..'z'] is set[range['a'..'z']]
  72. ## If `in` had been declared as `[T](elem: T, s: set[T])` then `T` would
  73. ## have been bound to `char`. But `s` is not compatible to type
  74. ## `set[char]`! The solution is to bind `T` to `range['a'..'z']`. This
  75. ## is achieved by reversing the parameters for `contains`; `in` then
  76. ## passes its arguments in reverse order.