Add keys() accessor to EnumerableMaps (#3920)

Co-authored-by: Francisco Giordano <frangio.1@gmail.com>
This commit is contained in:
Hadrien Croubois
2023-01-03 22:25:37 +01:00
committed by GitHub
parent 2fc24fc8d4
commit 88754d0b36
5 changed files with 147 additions and 10 deletions

View File

@ -168,6 +168,18 @@ function get(
require(value != 0 || contains(map, key), errorMessage);
return value;
}
/**
* @dev Return the an array containing all the keys
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function keys(Bytes32ToBytes32Map storage map) internal view returns (bytes32[] memory) {
return map._keys.values();
}
`;
const customMap = ({ name, keyType, valueType }) => `\
@ -193,7 +205,7 @@ function set(
}
/**
* @dev Removes a value from a set. O(1).
* @dev Removes a value from a map. O(1).
*
* Returns true if the key was removed from the map, that is if it was present.
*/
@ -216,7 +228,7 @@ function length(${name} storage map) internal view returns (uint256) {
}
/**
* @dev Returns the element stored at position \`index\` in the set. O(1).
* @dev Returns the element stored at position \`index\` in the map. O(1).
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
@ -262,6 +274,26 @@ function get(
) internal view returns (${valueType}) {
return ${fromBytes32(valueType, `get(map._inner, ${toBytes32(keyType, 'key')}, errorMessage)`)};
}
/**
* @dev Return the an array containing all the keys
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function keys(${name} storage map) internal view returns (${keyType}[] memory) {
bytes32[] memory store = keys(map._inner);
${keyType}[] memory result;
/// @solidity memory-safe-assembly
assembly {
result := store
}
return result;
}
`;
// GENERATE