Files
Nim/doc/sets_fragment.txt
Jjp137 93461aee34 Fix many broken links
Note that contrary to what docgen.rst currently says, the ids have
to match exactly or else most web browsers will not jump to the
intended symbol.
2019-10-22 17:59:12 -07:00

87 lines
2.8 KiB
Plaintext

The set type models the mathematical notion of a set. The set's basetype can
only be an ordinal type of a certain size, namely:
* ``int8``-``int16``
* ``uint8``/``byte``-``uint16``
* ``char``
* ``enum``
or equivalent. For signed integers the set's base type is defined to be in the
range ``0 .. MaxSetElements-1`` where ``MaxSetElements`` is currently always
2^16.
The reason is that sets are implemented as high performance bit vectors.
Attempting to declare a set with a larger type will result in an error:
.. code-block:: nim
var s: set[int64] # Error: set is too large
Sets can be constructed via the set constructor: ``{}`` is the empty set. The
empty set is type compatible with any concrete set type. The constructor
can also be used to include elements (and ranges of elements):
.. code-block:: nim
type
CharSet = set[char]
var
x: CharSet
x = {'a'..'z', '0'..'9'} # This constructs a set that contains the
# letters from 'a' to 'z' and the digits
# from '0' to '9'
These operations are supported by sets:
================== ========================================================
operation meaning
================== ========================================================
``A + B`` union of two sets
``A * B`` intersection of two sets
``A - B`` difference of two sets (A without B's elements)
``A == B`` set equality
``A <= B`` subset relation (A is subset of B or equal to B)
``A < B`` strict subset relation (A is a proper subset of B)
``e in A`` set membership (A contains element e)
``e notin A`` A does not contain element e
``contains(A, e)`` A contains element e
``card(A)`` the cardinality of A (number of elements in A)
``incl(A, elem)`` same as ``A = A + {elem}``
``excl(A, elem)`` same as ``A = A - {elem}``
================== ========================================================
Bit fields
~~~~~~~~~~
Sets are often used to define a type for the *flags* of a procedure.
This is a cleaner (and type safe) solution than defining integer
constants that have to be ``or``'ed together.
Enum, sets and casting can be used together as in:
.. code-block:: nim
type
MyFlag* {.size: sizeof(cint).} = enum
A
B
C
D
MyFlags = set[MyFlag]
proc toNum(f: MyFlags): int = cast[cint](f)
proc toFlags(v: int): MyFlags = cast[MyFlags](v)
assert toNum({}) == 0
assert toNum({A}) == 1
assert toNum({D}) == 8
assert toNum({A, C}) == 5
assert toFlags(0) == {}
assert toFlags(7) == {A, B, C}
Note how the set turns enum values into powers of 2.
If using enums and sets with C, use distinct cint.
For interoperability with C see also the
`bitsize pragma <manual.html#implementation-specific-pragmas-bitsize-pragma>`_.