Merge branch 'master' into refactor/DoubleEndedQueue
This commit is contained in:
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// OpenZeppelin Contracts (last updated v4.8.0) (utils/structs/BitMaps.sol)
|
||||
pragma solidity ^0.8.0;
|
||||
// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/BitMaps.sol)
|
||||
pragma solidity ^0.8.19;
|
||||
|
||||
/**
|
||||
* @dev Library for managing uint256 to bool mapping in a compact and efficient way, providing the keys are sequential.
|
||||
|
||||
394
contracts/utils/structs/Checkpoints.sol
Normal file
394
contracts/utils/structs/Checkpoints.sol
Normal file
@ -0,0 +1,394 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/Checkpoints.sol)
|
||||
// This file was procedurally generated from scripts/generate/templates/Checkpoints.js.
|
||||
|
||||
pragma solidity ^0.8.19;
|
||||
|
||||
import "../math/Math.sol";
|
||||
import "../math/SafeCast.sol";
|
||||
|
||||
/**
|
||||
* @dev This library defines the `History` struct, for checkpointing values as they change at different points in
|
||||
* time, and later looking up past values by block number. See {Votes} as an example.
|
||||
*
|
||||
* To create a history of checkpoints define a variable type `Checkpoints.History` in your contract, and store a new
|
||||
* checkpoint for the current transaction block using the {push} function.
|
||||
*
|
||||
* _Available since v4.5._
|
||||
*/
|
||||
library Checkpoints {
|
||||
/**
|
||||
* @dev A value was attempted to be inserted on a past checkpoint.
|
||||
*/
|
||||
error CheckpointUnorderedInsertion();
|
||||
|
||||
struct Trace224 {
|
||||
Checkpoint224[] _checkpoints;
|
||||
}
|
||||
|
||||
struct Checkpoint224 {
|
||||
uint32 _key;
|
||||
uint224 _value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Pushes a (`key`, `value`) pair into a Trace224 so that it is stored as the checkpoint.
|
||||
*
|
||||
* Returns previous value and new value.
|
||||
*/
|
||||
function push(Trace224 storage self, uint32 key, uint224 value) internal returns (uint224, uint224) {
|
||||
return _insert(self._checkpoints, key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the value in the first (oldest) checkpoint with key greater or equal than the search key, or zero if there is none.
|
||||
*/
|
||||
function lowerLookup(Trace224 storage self, uint32 key) internal view returns (uint224) {
|
||||
uint256 len = self._checkpoints.length;
|
||||
uint256 pos = _lowerBinaryLookup(self._checkpoints, key, 0, len);
|
||||
return pos == len ? 0 : _unsafeAccess(self._checkpoints, pos)._value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero if there is none.
|
||||
*/
|
||||
function upperLookup(Trace224 storage self, uint32 key) internal view returns (uint224) {
|
||||
uint256 len = self._checkpoints.length;
|
||||
uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len);
|
||||
return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero if there is none.
|
||||
*
|
||||
* NOTE: This is a variant of {upperLookup} that is optimised to find "recent" checkpoint (checkpoints with high keys).
|
||||
*/
|
||||
function upperLookupRecent(Trace224 storage self, uint32 key) internal view returns (uint224) {
|
||||
uint256 len = self._checkpoints.length;
|
||||
|
||||
uint256 low = 0;
|
||||
uint256 high = len;
|
||||
|
||||
if (len > 5) {
|
||||
uint256 mid = len - Math.sqrt(len);
|
||||
if (key < _unsafeAccess(self._checkpoints, mid)._key) {
|
||||
high = mid;
|
||||
} else {
|
||||
low = mid + 1;
|
||||
}
|
||||
}
|
||||
|
||||
uint256 pos = _upperBinaryLookup(self._checkpoints, key, low, high);
|
||||
|
||||
return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints.
|
||||
*/
|
||||
function latest(Trace224 storage self) internal view returns (uint224) {
|
||||
uint256 pos = self._checkpoints.length;
|
||||
return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value
|
||||
* in the most recent checkpoint.
|
||||
*/
|
||||
function latestCheckpoint(Trace224 storage self) internal view returns (bool exists, uint32 _key, uint224 _value) {
|
||||
uint256 pos = self._checkpoints.length;
|
||||
if (pos == 0) {
|
||||
return (false, 0, 0);
|
||||
} else {
|
||||
Checkpoint224 memory ckpt = _unsafeAccess(self._checkpoints, pos - 1);
|
||||
return (true, ckpt._key, ckpt._value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the number of checkpoint.
|
||||
*/
|
||||
function length(Trace224 storage self) internal view returns (uint256) {
|
||||
return self._checkpoints.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns checkpoint at given position.
|
||||
*/
|
||||
function at(Trace224 storage self, uint32 pos) internal view returns (Checkpoint224 memory) {
|
||||
return self._checkpoints[pos];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint,
|
||||
* or by updating the last one.
|
||||
*/
|
||||
function _insert(Checkpoint224[] storage self, uint32 key, uint224 value) private returns (uint224, uint224) {
|
||||
uint256 pos = self.length;
|
||||
|
||||
if (pos > 0) {
|
||||
// Copying to memory is important here.
|
||||
Checkpoint224 memory last = _unsafeAccess(self, pos - 1);
|
||||
|
||||
// Checkpoint keys must be non-decreasing.
|
||||
if (last._key > key) {
|
||||
revert CheckpointUnorderedInsertion();
|
||||
}
|
||||
|
||||
// Update or push new checkpoint
|
||||
if (last._key == key) {
|
||||
_unsafeAccess(self, pos - 1)._value = value;
|
||||
} else {
|
||||
self.push(Checkpoint224({_key: key, _value: value}));
|
||||
}
|
||||
return (last._value, value);
|
||||
} else {
|
||||
self.push(Checkpoint224({_key: key, _value: value}));
|
||||
return (0, value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Return the index of the last (most recent) checkpoint with key lower or equal than the search key, or `high` if there is none.
|
||||
* `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`.
|
||||
*
|
||||
* WARNING: `high` should not be greater than the array's length.
|
||||
*/
|
||||
function _upperBinaryLookup(
|
||||
Checkpoint224[] storage self,
|
||||
uint32 key,
|
||||
uint256 low,
|
||||
uint256 high
|
||||
) private view returns (uint256) {
|
||||
while (low < high) {
|
||||
uint256 mid = Math.average(low, high);
|
||||
if (_unsafeAccess(self, mid)._key > key) {
|
||||
high = mid;
|
||||
} else {
|
||||
low = mid + 1;
|
||||
}
|
||||
}
|
||||
return high;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Return the index of the first (oldest) checkpoint with key is greater or equal than the search key, or `high` if there is none.
|
||||
* `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`.
|
||||
*
|
||||
* WARNING: `high` should not be greater than the array's length.
|
||||
*/
|
||||
function _lowerBinaryLookup(
|
||||
Checkpoint224[] storage self,
|
||||
uint32 key,
|
||||
uint256 low,
|
||||
uint256 high
|
||||
) private view returns (uint256) {
|
||||
while (low < high) {
|
||||
uint256 mid = Math.average(low, high);
|
||||
if (_unsafeAccess(self, mid)._key < key) {
|
||||
low = mid + 1;
|
||||
} else {
|
||||
high = mid;
|
||||
}
|
||||
}
|
||||
return high;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds.
|
||||
*/
|
||||
function _unsafeAccess(
|
||||
Checkpoint224[] storage self,
|
||||
uint256 pos
|
||||
) private pure returns (Checkpoint224 storage result) {
|
||||
assembly {
|
||||
mstore(0, self.slot)
|
||||
result.slot := add(keccak256(0, 0x20), pos)
|
||||
}
|
||||
}
|
||||
|
||||
struct Trace160 {
|
||||
Checkpoint160[] _checkpoints;
|
||||
}
|
||||
|
||||
struct Checkpoint160 {
|
||||
uint96 _key;
|
||||
uint160 _value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Pushes a (`key`, `value`) pair into a Trace160 so that it is stored as the checkpoint.
|
||||
*
|
||||
* Returns previous value and new value.
|
||||
*/
|
||||
function push(Trace160 storage self, uint96 key, uint160 value) internal returns (uint160, uint160) {
|
||||
return _insert(self._checkpoints, key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the value in the first (oldest) checkpoint with key greater or equal than the search key, or zero if there is none.
|
||||
*/
|
||||
function lowerLookup(Trace160 storage self, uint96 key) internal view returns (uint160) {
|
||||
uint256 len = self._checkpoints.length;
|
||||
uint256 pos = _lowerBinaryLookup(self._checkpoints, key, 0, len);
|
||||
return pos == len ? 0 : _unsafeAccess(self._checkpoints, pos)._value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero if there is none.
|
||||
*/
|
||||
function upperLookup(Trace160 storage self, uint96 key) internal view returns (uint160) {
|
||||
uint256 len = self._checkpoints.length;
|
||||
uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len);
|
||||
return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero if there is none.
|
||||
*
|
||||
* NOTE: This is a variant of {upperLookup} that is optimised to find "recent" checkpoint (checkpoints with high keys).
|
||||
*/
|
||||
function upperLookupRecent(Trace160 storage self, uint96 key) internal view returns (uint160) {
|
||||
uint256 len = self._checkpoints.length;
|
||||
|
||||
uint256 low = 0;
|
||||
uint256 high = len;
|
||||
|
||||
if (len > 5) {
|
||||
uint256 mid = len - Math.sqrt(len);
|
||||
if (key < _unsafeAccess(self._checkpoints, mid)._key) {
|
||||
high = mid;
|
||||
} else {
|
||||
low = mid + 1;
|
||||
}
|
||||
}
|
||||
|
||||
uint256 pos = _upperBinaryLookup(self._checkpoints, key, low, high);
|
||||
|
||||
return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints.
|
||||
*/
|
||||
function latest(Trace160 storage self) internal view returns (uint160) {
|
||||
uint256 pos = self._checkpoints.length;
|
||||
return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value
|
||||
* in the most recent checkpoint.
|
||||
*/
|
||||
function latestCheckpoint(Trace160 storage self) internal view returns (bool exists, uint96 _key, uint160 _value) {
|
||||
uint256 pos = self._checkpoints.length;
|
||||
if (pos == 0) {
|
||||
return (false, 0, 0);
|
||||
} else {
|
||||
Checkpoint160 memory ckpt = _unsafeAccess(self._checkpoints, pos - 1);
|
||||
return (true, ckpt._key, ckpt._value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the number of checkpoint.
|
||||
*/
|
||||
function length(Trace160 storage self) internal view returns (uint256) {
|
||||
return self._checkpoints.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns checkpoint at given position.
|
||||
*/
|
||||
function at(Trace160 storage self, uint32 pos) internal view returns (Checkpoint160 memory) {
|
||||
return self._checkpoints[pos];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint,
|
||||
* or by updating the last one.
|
||||
*/
|
||||
function _insert(Checkpoint160[] storage self, uint96 key, uint160 value) private returns (uint160, uint160) {
|
||||
uint256 pos = self.length;
|
||||
|
||||
if (pos > 0) {
|
||||
// Copying to memory is important here.
|
||||
Checkpoint160 memory last = _unsafeAccess(self, pos - 1);
|
||||
|
||||
// Checkpoint keys must be non-decreasing.
|
||||
if (last._key > key) {
|
||||
revert CheckpointUnorderedInsertion();
|
||||
}
|
||||
|
||||
// Update or push new checkpoint
|
||||
if (last._key == key) {
|
||||
_unsafeAccess(self, pos - 1)._value = value;
|
||||
} else {
|
||||
self.push(Checkpoint160({_key: key, _value: value}));
|
||||
}
|
||||
return (last._value, value);
|
||||
} else {
|
||||
self.push(Checkpoint160({_key: key, _value: value}));
|
||||
return (0, value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Return the index of the last (most recent) checkpoint with key lower or equal than the search key, or `high` if there is none.
|
||||
* `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`.
|
||||
*
|
||||
* WARNING: `high` should not be greater than the array's length.
|
||||
*/
|
||||
function _upperBinaryLookup(
|
||||
Checkpoint160[] storage self,
|
||||
uint96 key,
|
||||
uint256 low,
|
||||
uint256 high
|
||||
) private view returns (uint256) {
|
||||
while (low < high) {
|
||||
uint256 mid = Math.average(low, high);
|
||||
if (_unsafeAccess(self, mid)._key > key) {
|
||||
high = mid;
|
||||
} else {
|
||||
low = mid + 1;
|
||||
}
|
||||
}
|
||||
return high;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Return the index of the first (oldest) checkpoint with key is greater or equal than the search key, or `high` if there is none.
|
||||
* `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`.
|
||||
*
|
||||
* WARNING: `high` should not be greater than the array's length.
|
||||
*/
|
||||
function _lowerBinaryLookup(
|
||||
Checkpoint160[] storage self,
|
||||
uint96 key,
|
||||
uint256 low,
|
||||
uint256 high
|
||||
) private view returns (uint256) {
|
||||
while (low < high) {
|
||||
uint256 mid = Math.average(low, high);
|
||||
if (_unsafeAccess(self, mid)._key < key) {
|
||||
low = mid + 1;
|
||||
} else {
|
||||
high = mid;
|
||||
}
|
||||
}
|
||||
return high;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds.
|
||||
*/
|
||||
function _unsafeAccess(
|
||||
Checkpoint160[] storage self,
|
||||
uint256 pos
|
||||
) private pure returns (Checkpoint160 storage result) {
|
||||
assembly {
|
||||
mstore(0, self.slot)
|
||||
result.slot := add(keccak256(0, 0x20), pos)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// OpenZeppelin Contracts (last updated v4.6.0) (utils/structs/DoubleEndedQueue.sol)
|
||||
pragma solidity ^0.8.4;
|
||||
// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/DoubleEndedQueue.sol)
|
||||
pragma solidity ^0.8.19;
|
||||
|
||||
import "../math/SafeCast.sol";
|
||||
|
||||
@ -12,7 +12,7 @@ import "../math/SafeCast.sol";
|
||||
*
|
||||
* The struct is called `Bytes32Deque`. Other types can be cast to and from `bytes32`. This data structure can only be
|
||||
* used in storage, and not in memory.
|
||||
* ```
|
||||
* ```solidity
|
||||
* DoubleEndedQueue.Bytes32Deque queue;
|
||||
* ```
|
||||
*
|
||||
@ -22,7 +22,7 @@ library DoubleEndedQueue {
|
||||
/**
|
||||
* @dev An operation (e.g. {front}) couldn't be completed due to the queue being empty.
|
||||
*/
|
||||
error Empty();
|
||||
error QueueEmpty();
|
||||
|
||||
/**
|
||||
* @dev A push operation couldn't be completed due to the queue being full.
|
||||
@ -32,7 +32,7 @@ library DoubleEndedQueue {
|
||||
/**
|
||||
* @dev An operation (e.g. {at}) couldn't be completed due to an index being out of bounds.
|
||||
*/
|
||||
error OutOfBounds();
|
||||
error QueueOutOfBounds();
|
||||
|
||||
/**
|
||||
* @dev Indices are signed integers because the queue can grow in any direction. They are 128 bits so begin and end
|
||||
@ -67,12 +67,12 @@ library DoubleEndedQueue {
|
||||
/**
|
||||
* @dev Removes the item at the end of the queue and returns it.
|
||||
*
|
||||
* Reverts with `Empty` if the queue is empty.
|
||||
* Reverts with `QueueEmpty` if the queue is empty.
|
||||
*/
|
||||
function popBack(Bytes32Deque storage deque) internal returns (bytes32 value) {
|
||||
unchecked {
|
||||
uint128 backIndex = deque._end;
|
||||
if (backIndex == deque._begin) revert Empty();
|
||||
if (backIndex == deque._begin) revert QueueEmpty();
|
||||
--backIndex;
|
||||
value = deque._data[backIndex];
|
||||
delete deque._data[backIndex];
|
||||
@ -95,12 +95,12 @@ library DoubleEndedQueue {
|
||||
/**
|
||||
* @dev Removes the item at the beginning of the queue and returns it.
|
||||
*
|
||||
* Reverts with `Empty` if the queue is empty.
|
||||
* Reverts with `QueueEmpty` if the queue is empty.
|
||||
*/
|
||||
function popFront(Bytes32Deque storage deque) internal returns (bytes32 value) {
|
||||
unchecked {
|
||||
uint128 frontIndex = deque._begin;
|
||||
if (frontIndex == deque._end) revert Empty();
|
||||
if (frontIndex == deque._end) revert QueueEmpty();
|
||||
value = deque._data[frontIndex];
|
||||
delete deque._data[frontIndex];
|
||||
deque._begin = frontIndex + 1;
|
||||
@ -110,20 +110,20 @@ library DoubleEndedQueue {
|
||||
/**
|
||||
* @dev Returns the item at the beginning of the queue.
|
||||
*
|
||||
* Reverts with `Empty` if the queue is empty.
|
||||
* Reverts with `QueueEmpty` if the queue is empty.
|
||||
*/
|
||||
function front(Bytes32Deque storage deque) internal view returns (bytes32 value) {
|
||||
if (empty(deque)) revert Empty();
|
||||
if (empty(deque)) revert QueueEmpty();
|
||||
return deque._data[deque._begin];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the item at the end of the queue.
|
||||
*
|
||||
* Reverts with `Empty` if the queue is empty.
|
||||
* Reverts with `QueueEmpty` if the queue is empty.
|
||||
*/
|
||||
function back(Bytes32Deque storage deque) internal view returns (bytes32 value) {
|
||||
if (empty(deque)) revert Empty();
|
||||
if (empty(deque)) revert QueueEmpty();
|
||||
unchecked {
|
||||
return deque._data[deque._end - 1];
|
||||
}
|
||||
@ -133,10 +133,10 @@ library DoubleEndedQueue {
|
||||
* @dev Return the item at a position in the queue given by `index`, with the first item at 0 and last item at
|
||||
* `length(deque) - 1`.
|
||||
*
|
||||
* Reverts with `OutOfBounds` if the index is out of bounds.
|
||||
* Reverts with `QueueOutOfBounds` if the index is out of bounds.
|
||||
*/
|
||||
function at(Bytes32Deque storage deque, uint256 index) internal view returns (bytes32 value) {
|
||||
if (index >= length(deque)) revert OutOfBounds();
|
||||
if (index >= length(deque)) revert QueueOutOfBounds();
|
||||
unchecked {
|
||||
return deque._data[deque._begin + SafeCast.toUint128(index)];
|
||||
}
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// OpenZeppelin Contracts (last updated v4.8.0) (utils/structs/EnumerableMap.sol)
|
||||
// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableMap.sol)
|
||||
// This file was procedurally generated from scripts/generate/templates/EnumerableMap.js.
|
||||
|
||||
pragma solidity ^0.8.0;
|
||||
pragma solidity ^0.8.19;
|
||||
|
||||
import "./EnumerableSet.sol";
|
||||
|
||||
@ -17,7 +17,7 @@ import "./EnumerableSet.sol";
|
||||
* (O(1)).
|
||||
* - Entries are enumerated in O(n). No guarantees are made on the ordering.
|
||||
*
|
||||
* ```
|
||||
* ```solidity
|
||||
* contract Example {
|
||||
* // Add the library methods
|
||||
* using EnumerableMap for EnumerableMap.UintToAddressMap;
|
||||
@ -57,6 +57,11 @@ library EnumerableMap {
|
||||
// This means that we can only create new EnumerableMaps for types that fit
|
||||
// in bytes32.
|
||||
|
||||
/**
|
||||
* @dev Query for a nonexistent map key.
|
||||
*/
|
||||
error EnumerableMapNonexistentKey(bytes32 key);
|
||||
|
||||
struct Bytes32ToBytes32Map {
|
||||
// Storage of keys
|
||||
EnumerableSet.Bytes32Set _keys;
|
||||
@ -136,23 +141,9 @@ library EnumerableMap {
|
||||
*/
|
||||
function get(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bytes32) {
|
||||
bytes32 value = map._values[key];
|
||||
require(value != 0 || contains(map, key), "EnumerableMap: nonexistent key");
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Same as {get}, with a custom error message when `key` is not in the map.
|
||||
*
|
||||
* CAUTION: This function is deprecated because it requires allocating memory for the error
|
||||
* message unnecessarily. For custom revert reasons use {tryGet}.
|
||||
*/
|
||||
function get(
|
||||
Bytes32ToBytes32Map storage map,
|
||||
bytes32 key,
|
||||
string memory errorMessage
|
||||
) internal view returns (bytes32) {
|
||||
bytes32 value = map._values[key];
|
||||
require(value != 0 || contains(map, key), errorMessage);
|
||||
if (value == 0 && !contains(map, key)) {
|
||||
revert EnumerableMapNonexistentKey(key);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@ -242,16 +233,6 @@ library EnumerableMap {
|
||||
return uint256(get(map._inner, bytes32(key)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Same as {get}, with a custom error message when `key` is not in the map.
|
||||
*
|
||||
* CAUTION: This function is deprecated because it requires allocating memory for the error
|
||||
* message unnecessarily. For custom revert reasons use {tryGet}.
|
||||
*/
|
||||
function get(UintToUintMap storage map, uint256 key, string memory errorMessage) internal view returns (uint256) {
|
||||
return uint256(get(map._inner, bytes32(key), errorMessage));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Return the an array containing all the keys
|
||||
*
|
||||
@ -346,20 +327,6 @@ library EnumerableMap {
|
||||
return address(uint160(uint256(get(map._inner, bytes32(key)))));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Same as {get}, with a custom error message when `key` is not in the map.
|
||||
*
|
||||
* CAUTION: This function is deprecated because it requires allocating memory for the error
|
||||
* message unnecessarily. For custom revert reasons use {tryGet}.
|
||||
*/
|
||||
function get(
|
||||
UintToAddressMap storage map,
|
||||
uint256 key,
|
||||
string memory errorMessage
|
||||
) internal view returns (address) {
|
||||
return address(uint160(uint256(get(map._inner, bytes32(key), errorMessage))));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Return the an array containing all the keys
|
||||
*
|
||||
@ -454,20 +421,6 @@ library EnumerableMap {
|
||||
return uint256(get(map._inner, bytes32(uint256(uint160(key)))));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Same as {get}, with a custom error message when `key` is not in the map.
|
||||
*
|
||||
* CAUTION: This function is deprecated because it requires allocating memory for the error
|
||||
* message unnecessarily. For custom revert reasons use {tryGet}.
|
||||
*/
|
||||
function get(
|
||||
AddressToUintMap storage map,
|
||||
address key,
|
||||
string memory errorMessage
|
||||
) internal view returns (uint256) {
|
||||
return uint256(get(map._inner, bytes32(uint256(uint160(key))), errorMessage));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Return the an array containing all the keys
|
||||
*
|
||||
@ -562,20 +515,6 @@ library EnumerableMap {
|
||||
return uint256(get(map._inner, key));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Same as {get}, with a custom error message when `key` is not in the map.
|
||||
*
|
||||
* CAUTION: This function is deprecated because it requires allocating memory for the error
|
||||
* message unnecessarily. For custom revert reasons use {tryGet}.
|
||||
*/
|
||||
function get(
|
||||
Bytes32ToUintMap storage map,
|
||||
bytes32 key,
|
||||
string memory errorMessage
|
||||
) internal view returns (uint256) {
|
||||
return uint256(get(map._inner, key, errorMessage));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Return the an array containing all the keys
|
||||
*
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// OpenZeppelin Contracts (last updated v4.8.0) (utils/structs/EnumerableSet.sol)
|
||||
// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol)
|
||||
// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.
|
||||
|
||||
pragma solidity ^0.8.0;
|
||||
pragma solidity ^0.8.19;
|
||||
|
||||
/**
|
||||
* @dev Library for managing
|
||||
@ -15,7 +15,7 @@ pragma solidity ^0.8.0;
|
||||
* (O(1)).
|
||||
* - Elements are enumerated in O(n). No guarantees are made on the ordering.
|
||||
*
|
||||
* ```
|
||||
* ```solidity
|
||||
* contract Example {
|
||||
* // Add the library methods
|
||||
* using EnumerableSet for EnumerableSet.AddressSet;
|
||||
|
||||
Reference in New Issue
Block a user