setops.nim 3.0 KB

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