Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/fine-frogs-bake.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'openzeppelin-solidity': minor
---

`EnumerableMap`: Add `keys(uint256,uint256)` that returns a subset (slice) of the keys in the map.
5 changes: 5 additions & 0 deletions .changeset/hot-grapes-lie.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'openzeppelin-solidity': minor
---

`EnumerableSet`: Add `values(uint256,uint256)` that returns a subset (slice) of the values in the set.
196 changes: 194 additions & 2 deletions contracts/utils/structs/EnumerableMap.sol
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ library EnumerableMap {
}

/**
* @dev Return the an array containing all the keys
* @dev Returns 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
Expand All @@ -175,6 +175,22 @@ library EnumerableMap {
return map._keys.values();
}

/**
* @dev Returns an array containing a slice of 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,
uint256 start,
uint256 end
) internal view returns (bytes32[] memory) {
return map._keys.values(start, end);
}

// UintToUintMap

struct UintToUintMap {
Expand Down Expand Up @@ -278,6 +294,25 @@ library EnumerableMap {
return result;
}

/**
* @dev Return the an array containing a slice of 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(UintToUintMap storage map, uint256 start, uint256 end) internal view returns (uint256[] memory) {
bytes32[] memory store = keys(map._inner, start, end);
uint256[] memory result;

assembly ("memory-safe") {
result := store
}

return result;
}

// UintToAddressMap

struct UintToAddressMap {
Expand Down Expand Up @@ -381,6 +416,25 @@ library EnumerableMap {
return result;
}

/**
* @dev Return the an array containing a slice of 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(UintToAddressMap storage map, uint256 start, uint256 end) internal view returns (uint256[] memory) {
bytes32[] memory store = keys(map._inner, start, end);
uint256[] memory result;

assembly ("memory-safe") {
result := store
}

return result;
}

// UintToBytes32Map

struct UintToBytes32Map {
Expand Down Expand Up @@ -484,6 +538,25 @@ library EnumerableMap {
return result;
}

/**
* @dev Return the an array containing a slice of 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(UintToBytes32Map storage map, uint256 start, uint256 end) internal view returns (uint256[] memory) {
bytes32[] memory store = keys(map._inner, start, end);
uint256[] memory result;

assembly ("memory-safe") {
result := store
}

return result;
}

// AddressToUintMap

struct AddressToUintMap {
Expand Down Expand Up @@ -587,6 +660,25 @@ library EnumerableMap {
return result;
}

/**
* @dev Return the an array containing a slice of 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(AddressToUintMap storage map, uint256 start, uint256 end) internal view returns (address[] memory) {
bytes32[] memory store = keys(map._inner, start, end);
address[] memory result;

assembly ("memory-safe") {
result := store
}

return result;
}

// AddressToAddressMap

struct AddressToAddressMap {
Expand Down Expand Up @@ -690,6 +782,29 @@ library EnumerableMap {
return result;
}

/**
* @dev Return the an array containing a slice of 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(
AddressToAddressMap storage map,
uint256 start,
uint256 end
) internal view returns (address[] memory) {
bytes32[] memory store = keys(map._inner, start, end);
address[] memory result;

assembly ("memory-safe") {
result := store
}

return result;
}

// AddressToBytes32Map

struct AddressToBytes32Map {
Expand Down Expand Up @@ -793,6 +908,29 @@ library EnumerableMap {
return result;
}

/**
* @dev Return the an array containing a slice of 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(
AddressToBytes32Map storage map,
uint256 start,
uint256 end
) internal view returns (address[] memory) {
bytes32[] memory store = keys(map._inner, start, end);
address[] memory result;

assembly ("memory-safe") {
result := store
}

return result;
}

// Bytes32ToUintMap

struct Bytes32ToUintMap {
Expand Down Expand Up @@ -896,6 +1034,25 @@ library EnumerableMap {
return result;
}

/**
* @dev Return the an array containing a slice of 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(Bytes32ToUintMap storage map, uint256 start, uint256 end) internal view returns (bytes32[] memory) {
bytes32[] memory store = keys(map._inner, start, end);
bytes32[] memory result;

assembly ("memory-safe") {
result := store
}

return result;
}

// Bytes32ToAddressMap

struct Bytes32ToAddressMap {
Expand Down Expand Up @@ -999,6 +1156,29 @@ library EnumerableMap {
return result;
}

/**
* @dev Return the an array containing a slice of 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(
Bytes32ToAddressMap storage map,
uint256 start,
uint256 end
) internal view returns (bytes32[] memory) {
bytes32[] memory store = keys(map._inner, start, end);
bytes32[] memory result;

assembly ("memory-safe") {
result := store
}

return result;
}

/**
* @dev Query for a nonexistent map key.
*/
Expand Down Expand Up @@ -1106,7 +1286,7 @@ library EnumerableMap {
}

/**
* @dev Return the an array containing all the keys
* @dev Returns 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
Expand All @@ -1116,4 +1296,16 @@ library EnumerableMap {
function keys(BytesToBytesMap storage map) internal view returns (bytes[] memory) {
return map._keys.values();
}

/**
* @dev Returns an array containing a slice of 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(BytesToBytesMap storage map, uint256 start, uint256 end) internal view returns (bytes[] memory) {
return map._keys.values(start, end);
}
}
Loading