Documentation and Changelog

This commit is contained in:
hrkrshnn 2021-08-17 18:08:05 +02:00
parent d67391531e
commit fbb1b884b2
3 changed files with 67 additions and 0 deletions

View File

@ -3,6 +3,7 @@
Language Features: Language Features:
* Inheritance: A function that overrides only a single interface function does not require the ``override`` specifier. * Inheritance: A function that overrides only a single interface function does not require the ``override`` specifier.
* Type System: Support ``type().min`` and ``type().max`` for enums. * Type System: Support ``type().min`` and ``type().max`` for enums.
* User Defined Value Type: allows creating a zero cost abstraction over a value type with stricter type requirements.
Compiler Features: Compiler Features:

View File

@ -113,6 +113,9 @@ them.
+-------------------------------+-----------------------------------------------------------------------------+ +-------------------------------+-----------------------------------------------------------------------------+
|:ref:`enum<enums>` |``uint8`` | |:ref:`enum<enums>` |``uint8`` |
+-------------------------------+-----------------------------------------------------------------------------+ +-------------------------------+-----------------------------------------------------------------------------+
|:ref:`user defined value types |its underlying value type |
|<user-defined-value-types>` | |
+-------------------------------+-----------------------------------------------------------------------------+
|:ref:`struct<structs>` |``tuple`` | |:ref:`struct<structs>` |``tuple`` |
+-------------------------------+-----------------------------------------------------------------------------+ +-------------------------------+-----------------------------------------------------------------------------+

View File

@ -628,6 +628,69 @@ smallest and respectively largest value of the given enum.
.. note:: .. note::
Enums can also be declared on the file level, outside of contract or library definitions. Enums can also be declared on the file level, outside of contract or library definitions.
.. index:: ! user defined value type, custom type
.. _user-defined-value-types:
User Defined Value Types
------------------------
A user defined value type allows creating a zero cost abstraction over an elementary value type.
This is similar to an alias, but with stricter type requirements.
A user defined value type is defined using ``type C is V``, where ``C`` is the name of the newly
introduced type and ``V`` has to be a built-in value type (the "underlying type"). The function
``C.wrap`` is used to convert from the underlying type to the custom type. Similarly, the
function ``C.unwrap`` is used to convert from the custom type to the underlying type.
The type ``C`` does not have any operators or bound member functions. In particular, even the
operator ``==`` is not defined. Explicit and implicit conversions to and from other types are
disallowed.
The data-representation of values of such types are inherited from the underlying type
and the underlying type is also used in the ABI.
The following example illustrates a custom type ``UFixed256x18`` representing a decimal fixed point
type with 18 decimals and a minimal library to do arithmetic operations on the type.
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.8;
// Represent a 18 decimal, 256 bit wide fixed point type using a user defined value type.
type UFixed256x18 is uint256;
/// A minimal library to do fixed point operations on UFixed256x18.
library FixedMath {
uint constant multiplier = 10**18;
/// Adds two UFixed256x18 numbers. Reverts on overflow, relying on checked
/// arithmetic on uint256.
function add(UFixed256x18 a, UFixed256x18 b) internal pure returns (UFixed256x18) {
return UFixed256x18.wrap(UFixed256x18.unwrap(a) + UFixed256x18.unwrap(b));
}
/// Multiplies UFixed256x18 and uint256. Reverts on overflow, relying on checked
/// arithmetic on uint256.
function mul(UFixed256x18 a, uint256 b) internal pure returns (UFixed256x18) {
return UFixed256x18.wrap(UFixed256x18.unwrap(a) * b);
}
/// Truncates UFixed256x18 to the nearest uint256 number.
function truncate(UFixed256x18 a) internal pure returns (uint256) {
return UFixed256x18.unwrap(a) / multiplier;
}
/// Turns a uint256 into a UFixed256x18 of the same value.
/// Reverts if the integer is too large.
function toUFixed256x18(uint256 a) internal pure returns (UFixed256x18) {
return UFixed256x18.wrap(a * multiplier);
}
}
Notice how ``UFixed256x18.wrap`` and ``FixedMath.toUFixed256x18`` have the same signature but
perform two very different operations: The ``UFixed256x18.wrap`` function returns a ``UFixed256x18``
that has the same data representation as the input, whereas ``toUFixed256x18`` returns a
``UFixed256x18`` that has the same numerical value.
.. index:: ! function type, ! type; function .. index:: ! function type, ! type; function