123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960 |
- // SPDX-License-Identifier: MIT
- // OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/BitMaps.sol)
- pragma solidity ^0.8.20;
- /**
- * @dev Library for managing uint256 to bool mapping in a compact and efficient way, provided the keys are sequential.
- * Largely inspired by Uniswap's https://github.com/Uniswap/merkle-distributor/blob/master/contracts/MerkleDistributor.sol[merkle-distributor].
- *
- * BitMaps pack 256 booleans across each bit of a single 256-bit slot of `uint256` type.
- * Hence booleans corresponding to 256 _sequential_ indices would only consume a single slot,
- * unlike the regular `bool` which would consume an entire slot for a single value.
- *
- * This results in gas savings in two ways:
- *
- * - Setting a zero value to non-zero only once every 256 times
- * - Accessing the same warm slot for every 256 _sequential_ indices
- */
- library BitMaps {
- struct BitMap {
- mapping(uint256 bucket => uint256) _data;
- }
- /**
- * @dev Returns whether the bit at `index` is set.
- */
- function get(BitMap storage bitmap, uint256 index) internal view returns (bool) {
- uint256 bucket = index >> 8;
- uint256 mask = 1 << (index & 0xff);
- return bitmap._data[bucket] & mask != 0;
- }
- /**
- * @dev Sets the bit at `index` to the boolean `value`.
- */
- function setTo(BitMap storage bitmap, uint256 index, bool value) internal {
- if (value) {
- set(bitmap, index);
- } else {
- unset(bitmap, index);
- }
- }
- /**
- * @dev Sets the bit at `index`.
- */
- function set(BitMap storage bitmap, uint256 index) internal {
- uint256 bucket = index >> 8;
- uint256 mask = 1 << (index & 0xff);
- bitmap._data[bucket] |= mask;
- }
- /**
- * @dev Unsets the bit at `index`.
- */
- function unset(BitMap storage bitmap, uint256 index) internal {
- uint256 bucket = index >> 8;
- uint256 mask = 1 << (index & 0xff);
- bitmap._data[bucket] &= ~mask;
- }
- }
|