fixup! User-defined operators: Documentation

This commit is contained in:
Kamil Śliwak
2023-01-25 00:29:10 +01:00
parent 2abe345c7f
commit fd6359000e
2 changed files with 36 additions and 17 deletions
+32 -15
View File
@@ -18,26 +18,20 @@ at contract level.
The first part, ``A``, can be one of:
- A list of file-level or library functions (e.g. ``using {f, g, h, L.t} for uint;``) -
only those functions will be attached to the type as member functions.
Note that private library functions can only be specified when ``using for`` is inside the library.
- A list of file-level or library functions, optionally with an operator name assigned (e.g.
``using {f, g as +, h, L.t as -} for uint;``).
If no operator is specified, the function is attached to the type as a member function, otherwise
it becomes the definition of that operator on the type.
- The name of a library (e.g. ``using L for uint;``) -
all non-private functions of the library are attached to the type
as member functions
- a list of assignments of file-level or public/internal/private library functions to operators
(e.g. ``using {f as +, g as -} for T;``) - the functions will be attached to the type (``T``)
as operators. The following binary operators are allowed to be used on the list: ``|``,
``^``, ``&``, ``+``, ``-``, ``*``, ``/``, ``%``, ``==``, ``!=``, ``<``, ``>``, ``<=``,
``>=``, ``<<``, ``>>``, ``**``. Allowed unary operators are: ``~``, ``!``, ``-``.
If an operator can be both binary and unary, it is allowed to have each variant specified
on the list (e.g. ``using {sub as -, unsub as -} for T``).
At file level, the second part, ``B``, has to be an explicit type (without data location specifier).
Inside contracts, you can also use ``*`` in place of the type (e.g. ``using L for *;``),
which has the effect that all functions of the library ``L``
are attached to *all* types.
If you specify a library, *all* functions in the library get attached,
If you specify a library, *all* non-private functions in the library get attached,
even those where the type of the first parameter does not
match the type of the object. The type is checked at the
point the function is called and function overload
@@ -47,11 +41,34 @@ If you use a list of functions (e.g. ``using {f, g, h, L.t} for uint;``),
then the type (``uint``) has to be implicitly convertible to the
first parameter of each of these functions. This check is
performed even if none of these functions are called.
Note that private library functions can only be specified when ``using for`` is inside a library.
If you define an operator for a user-defined type (``using {f as +} for T``), then
the type (``T``), types of function parameters and the type of the function return value
have to be the same. One exception from this is the result type of comparison operators
for which it is always ``bool``.
If you define an operator (e.g. ``using {f as +} for T``), then the type (``T``) must be a
:ref:`user-defined value type <user-defined-value-types>`.
The definition of an operator must be a function with the types of all parameters and
the return value matching ``T``, except for comparison operators, where the return value must
be of type ``bool``.
The following operators can be defined this way:
+------------+---------+----------------------------------------------+
| Category | Arity | Operators |
+============+=========+==============================================+
| Bitwise | binary | ``&``, ``|``, ``^``, ``<<``, ``>>`` |
| +---------+----------------------------------------------+
| | unary | ``~`` |
+------------+---------+----------------------------------------------+
| Arithmetic | binary | ``+``, ``-``, ``*``, ``/``, ``%``, ``**`` |
| +---------+----------------------------------------------+
| | unary | ``-`` |
+------------+---------+----------------------------------------------+
| Comparison | binary | ``==``, ``!=``, ``<``, ``<=``, ``>``, ``>=`` |
+------------+---------+----------------------------------------------+
| Boolean | unary | ``!`` |
+------------+---------+----------------------------------------------+
Note that ``-`` is both binary and unary.
Whether the definition implements one or the other depends on the number of its arguments.
The ``using A for B;`` directive is active only within the current
scope (either the contract or the current module/source unit),