Files
openzeppelin-contracts/contracts/utils/EnumerableSet.sol
2020-01-23 21:17:49 +00:00

100 lines
2.8 KiB
Solidity

pragma solidity ^0.5.0;
/**
* @title EnumerableSet
* @dev Data structure - https://en.wikipedia.org/wiki/Set_(abstract_data_type)
*
* An EnumerableSet.AddressSet is a data structure containing a number of unique addresses.
*
* - It is possible to add and remove addresses in O(1).
* - It is also possible to query if the AddressSet contains an address in O(1).
* - It is possible to retrieve an array with all the addresses in the AddressSet using enumerate.
* This operation is O(N) where N is the number of addresses in the AddressSet. The order in
* which the addresses are retrieved is not guaranteed.
*
* Initialization of a set must include an empty array:
* `EnumerableSet.AddressSet set = EnumerableSet.AddressSet({values: new address[](0)});`
*
* @author Alberto Cuesta Cañada
*/
library EnumerableSet {
struct AddressSet {
// Position of the value in the `values` array, plus 1 because index 0
// means a value is not in the set.
mapping (address => uint256) index;
address[] values;
}
/**
* @dev Add a value. O(1).
*/
function newAddressSet()
internal
pure
returns (AddressSet memory)
{
return AddressSet({values: new address[](0)});
}
/**
* @dev Add a value. O(1). Returns false if the value was already in the set.
*/
function add(AddressSet storage set, address value)
internal
returns (bool)
{
if (!contains(set, value)){
set.index[value] = set.values.push(value);
return true;
} else {
return false;
}
}
/**
* @dev Remove a value. O(1). Returns false if the calue was not present in the set.
*/
function remove(AddressSet storage set, address value)
internal
returns (bool)
{
if (contains(set, value)){
// Replaced the value to remove with the last one in the array. O(1)
set.values[set.index[value] - 1] = set.values[set.values.length - 1];
set.values.pop();
delete set.index[value];
return true;
} else {
return false;
}
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(AddressSet storage set, address value)
internal
view
returns (bool)
{
return set.index[value] != 0;
}
/**
* @dev Return an array with all values in the set. O(N).
*/
function enumerate(AddressSet storage set)
internal
view
returns (address[] memory)
{
address[] memory output = new address[](set.values.length);
for (uint256 i; i < set.values.length; i++){
output[i] = set.values[i];
}
return output;
}
}