fixup! User-defined operators: Documentation

This commit is contained in:
Kamil Śliwak 2023-01-24 17:59:21 +01:00
parent 2abe345c7f
commit fd6359000e
2 changed files with 36 additions and 17 deletions

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),

View File

@ -653,8 +653,10 @@ private:
* all functions, and this is checked at the point of the using statement. For versions 1 and
* 2, this check is only done when a function is called.
*
* For version 4, T has to be user-defined value type. All parameters and
* return value of all the functions have to be of type T.
* For version 4, T has to be user-defined value type.
* All parameters and return value of all the functions have to be of type T.
* This version can be combined with version 3 - a single directive may attach functions to the
* type and define operators on it at the same time.
*
* Finally, `using {f1, f2, ..., fn} for T global` is also valid at file level, as long as T is
* a user-defined type defined in the same file at file level. In this case, the methods are