aboutsummaryrefslogtreecommitdiffstats
path: root/docs/contracts
diff options
context:
space:
mode:
authorChris Ward <chris.ward@ethereum.org>2019-01-08 01:08:00 +0800
committerChris Ward <chris.ward@ethereum.org>2019-01-08 01:08:00 +0800
commitee5eac4b3edcb36f092b9140323a6e1f8ffa11be (patch)
tree8fd3862f9c0172fc2d618f4dafa0e627727ab4dd /docs/contracts
parenta2926cd9dcdddf681b87471cef8ed0c83c3aefd3 (diff)
downloaddexon-solidity-ee5eac4b3edcb36f092b9140323a6e1f8ffa11be.tar.gz
dexon-solidity-ee5eac4b3edcb36f092b9140323a6e1f8ffa11be.tar.zst
dexon-solidity-ee5eac4b3edcb36f092b9140323a6e1f8ffa11be.zip
Split using for into new file
Diffstat (limited to 'docs/contracts')
-rw-r--r--docs/contracts/using-for.rst119
1 files changed, 119 insertions, 0 deletions
diff --git a/docs/contracts/using-for.rst b/docs/contracts/using-for.rst
new file mode 100644
index 00000000..ef456ff4
--- /dev/null
+++ b/docs/contracts/using-for.rst
@@ -0,0 +1,119 @@
+.. index:: ! using for, library
+
+.. _using-for:
+
+*********
+Using For
+*********
+
+The directive ``using A for B;`` can be used to attach library
+functions (from the library ``A``) to any type (``B``).
+These functions will receive the object they are called on
+as their first parameter (like the ``self`` variable in Python).
+
+The effect of ``using A for *;`` is that the functions from
+the library ``A`` are attached to *any* type.
+
+In both situations, *all* functions in the library are 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
+resolution is performed.
+
+The ``using A for B;`` directive is active only within the current
+contract, including within all of its functions, and has no effect
+outside of the contract in which it is used. The directive
+may only be used inside a contract, not inside any of its functions.
+
+By including a library, its data types including library functions are
+available without having to add further code.
+
+Let us rewrite the set example from the
+:ref:`libraries` in this way::
+
+ pragma solidity >=0.4.16 <0.6.0;
+
+ // This is the same code as before, just without comments
+ library Set {
+ struct Data { mapping(uint => bool) flags; }
+
+ function insert(Data storage self, uint value)
+ public
+ returns (bool)
+ {
+ if (self.flags[value])
+ return false; // already there
+ self.flags[value] = true;
+ return true;
+ }
+
+ function remove(Data storage self, uint value)
+ public
+ returns (bool)
+ {
+ if (!self.flags[value])
+ return false; // not there
+ self.flags[value] = false;
+ return true;
+ }
+
+ function contains(Data storage self, uint value)
+ public
+ view
+ returns (bool)
+ {
+ return self.flags[value];
+ }
+ }
+
+ contract C {
+ using Set for Set.Data; // this is the crucial change
+ Set.Data knownValues;
+
+ function register(uint value) public {
+ // Here, all variables of type Set.Data have
+ // corresponding member functions.
+ // The following function call is identical to
+ // `Set.insert(knownValues, value)`
+ require(knownValues.insert(value));
+ }
+ }
+
+It is also possible to extend elementary types in that way::
+
+ pragma solidity >=0.4.16 <0.6.0;
+
+ library Search {
+ function indexOf(uint[] storage self, uint value)
+ public
+ view
+ returns (uint)
+ {
+ for (uint i = 0; i < self.length; i++)
+ if (self[i] == value) return i;
+ return uint(-1);
+ }
+ }
+
+ contract C {
+ using Search for uint[];
+ uint[] data;
+
+ function append(uint value) public {
+ data.push(value);
+ }
+
+ function replace(uint _old, uint _new) public {
+ // This performs the library function call
+ uint index = data.indexOf(_old);
+ if (index == uint(-1))
+ data.push(_new);
+ else
+ data[index] = _new;
+ }
+ }
+
+Note that all library calls are actual EVM function calls. This means that
+if you pass memory or value types, a copy will be performed, even of the
+``self`` variable. The only situation where no copy will be performed
+is when storage reference variables are used.