forked from nim-lang/Nim
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* js module also uses runnableExamples * better setops docs * Update lib/system/setops.nim * better * Update lib/system/setops.nim * Update lib/system/setops.nim * better * better
- Loading branch information
Showing
1 changed file
with
62 additions
and
70 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,94 +1,86 @@ | ||
proc incl*[T](x: var set[T], y: T) {.magic: "Incl", noSideEffect.} | ||
## Includes element ``y`` in the set ``x``. | ||
func incl*[T](x: var set[T], y: T) {.magic: "Incl".} = | ||
## Includes element `y` in the set `x`. | ||
## | ||
## This is the same as ``x = x + {y}``, but it might be more efficient. | ||
## | ||
## .. code-block:: Nim | ||
## var a = {1, 3, 5} | ||
## a.incl(2) # a <- {1, 2, 3, 5} | ||
## a.incl(4) # a <- {1, 2, 3, 4, 5} | ||
## This is the same as `x = x + {y}`, but it might be more efficient. | ||
runnableExamples: | ||
var a = {1, 3, 5} | ||
a.incl(2) | ||
assert a == {1, 2, 3, 5} | ||
a.incl(4) | ||
assert a == {1, 2, 3, 4, 5} | ||
|
||
template incl*[T](x: var set[T], y: set[T]) = | ||
## Includes the set ``y`` in the set ``x``. | ||
## | ||
## .. code-block:: Nim | ||
## var a = {1, 3, 5, 7} | ||
## var b = {4, 5, 6} | ||
## a.incl(b) # a <- {1, 3, 4, 5, 6, 7} | ||
## Includes the set `y` in the set `x`. | ||
runnableExamples: | ||
var a = {1, 3, 5, 7} | ||
var b = {4, 5, 6} | ||
a.incl(b) | ||
assert a == {1, 3, 4, 5, 6, 7} | ||
x = x + y | ||
|
||
proc excl*[T](x: var set[T], y: T) {.magic: "Excl", noSideEffect.} | ||
## Excludes element ``y`` from the set ``x``. | ||
## | ||
## This is the same as ``x = x - {y}``, but it might be more efficient. | ||
func excl*[T](x: var set[T], y: T) {.magic: "Excl".} = | ||
## Excludes element `y` from the set `x`. | ||
## | ||
## .. code-block:: Nim | ||
## var b = {2, 3, 5, 6, 12, 545} | ||
## b.excl(5) # b <- {2, 3, 6, 12, 545} | ||
## This is the same as `x = x - {y}`, but it might be more efficient. | ||
runnableExamples: | ||
var b = {2, 3, 5, 6, 12, 545} | ||
b.excl(5) | ||
assert b == {2, 3, 6, 12, 545} | ||
|
||
template excl*[T](x: var set[T], y: set[T]) = | ||
## Excludes the set ``y`` from the set ``x``. | ||
## | ||
## .. code-block:: Nim | ||
## var a = {1, 3, 5, 7} | ||
## var b = {3, 4, 5} | ||
## a.excl(b) # a <- {1, 7} | ||
## Excludes the set `y` from the set `x`. | ||
runnableExamples: | ||
var a = {1, 3, 5, 7} | ||
var b = {3, 4, 5} | ||
a.excl(b) | ||
assert a == {1, 7} | ||
x = x - y | ||
|
||
proc card*[T](x: set[T]): int {.magic: "Card", noSideEffect.} | ||
## Returns the cardinality of the set ``x``, i.e. the number of elements | ||
func card*[T](x: set[T]): int {.magic: "Card".} = | ||
## Returns the cardinality of the set `x`, i.e. the number of elements | ||
## in the set. | ||
## | ||
## .. code-block:: Nim | ||
## var a = {1, 3, 5, 7} | ||
## echo card(a) # => 4 | ||
runnableExamples: | ||
var a = {1, 3, 5, 7} | ||
assert card(a) == 4 | ||
var b = {1, 3, 5, 7, 5} | ||
assert card(b) == 4 # repeated 5 doesn't count | ||
|
||
proc len*[T](x: set[T]): int {.magic: "Card", noSideEffect.} | ||
func len*[T](x: set[T]): int {.magic: "Card".} | ||
## An alias for `card(x)`. | ||
|
||
|
||
proc `*`*[T](x, y: set[T]): set[T] {.magic: "MulSet", noSideEffect.} | ||
func `*`*[T](x, y: set[T]): set[T] {.magic: "MulSet".} = | ||
## This operator computes the intersection of two sets. | ||
## | ||
## .. code-block:: Nim | ||
## let | ||
## a = {1, 2, 3} | ||
## b = {2, 3, 4} | ||
## echo a * b # => {2, 3} | ||
proc `+`*[T](x, y: set[T]): set[T] {.magic: "PlusSet", noSideEffect.} | ||
runnableExamples: | ||
assert {1, 2, 3} * {2, 3, 4} == {2, 3} | ||
|
||
func `+`*[T](x, y: set[T]): set[T] {.magic: "PlusSet".} = | ||
## This operator computes the union of two sets. | ||
## | ||
## .. code-block:: Nim | ||
## let | ||
## a = {1, 2, 3} | ||
## b = {2, 3, 4} | ||
## echo a + b # => {1, 2, 3, 4} | ||
proc `-`*[T](x, y: set[T]): set[T] {.magic: "MinusSet", noSideEffect.} | ||
runnableExamples: | ||
assert {1, 2, 3} + {2, 3, 4} == {1, 2, 3, 4} | ||
|
||
func `-`*[T](x, y: set[T]): set[T] {.magic: "MinusSet".} = | ||
## This operator computes the difference of two sets. | ||
## | ||
## .. code-block:: Nim | ||
## let | ||
## a = {1, 2, 3} | ||
## b = {2, 3, 4} | ||
## echo a - b # => {1} | ||
runnableExamples: | ||
assert {1, 2, 3} - {2, 3, 4} == {1} | ||
|
||
proc contains*[T](x: set[T], y: T): bool {.magic: "InSet", noSideEffect.} | ||
## One should overload this proc if one wants to overload the ``in`` operator. | ||
func contains*[T](x: set[T], y: T): bool {.magic: "InSet".} = | ||
## One should overload this proc if one wants to overload the `in` operator. | ||
## | ||
## The parameters are in reverse order! ``a in b`` is a template for | ||
## ``contains(b, a)``. | ||
## The parameters are in reverse order! `a in b` is a template for | ||
## `contains(b, a)`. | ||
## This is because the unification algorithm that Nim uses for overload | ||
## resolution works from left to right. | ||
## But for the ``in`` operator that would be the wrong direction for this | ||
## But for the `in` operator that would be the wrong direction for this | ||
## piece of code: | ||
## | ||
## .. code-block:: Nim | ||
## var s: set[range['a'..'z']] = {'a'..'c'} | ||
## assert s.contains('c') | ||
## assert 'b' in s | ||
## | ||
## If ``in`` had been declared as ``[T](elem: T, s: set[T])`` then ``T`` would | ||
## have been bound to ``char``. But ``s`` is not compatible to type | ||
## ``set[char]``! The solution is to bind ``T`` to ``range['a'..'z']``. This | ||
## is achieved by reversing the parameters for ``contains``; ``in`` then | ||
runnableExamples: | ||
var s: set[range['a'..'z']] = {'a'..'c'} | ||
assert s.contains('c') | ||
assert 'b' in s | ||
assert 'd' notin s | ||
assert set['a'..'z'] is set[range['a'..'z']] | ||
## If `in` had been declared as `[T](elem: T, s: set[T])` then `T` would | ||
## have been bound to `char`. But `s` is not compatible to type | ||
## `set[char]`! The solution is to bind `T` to `range['a'..'z']`. This | ||
## is achieved by reversing the parameters for `contains`; `in` then | ||
## passes its arguments in reverse order. |