.. 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.7.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.7.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.