EnumerableMap.sol 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531
  1. // SPDX-License-Identifier: MIT
  2. // OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableMap.sol)
  3. pragma solidity ^0.8.0;
  4. import "./EnumerableSet.sol";
  5. /**
  6. * @dev Library for managing an enumerable variant of Solidity's
  7. * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]
  8. * type.
  9. *
  10. * Maps have the following properties:
  11. *
  12. * - Entries are added, removed, and checked for existence in constant time
  13. * (O(1)).
  14. * - Entries are enumerated in O(n). No guarantees are made on the ordering.
  15. *
  16. * ```
  17. * contract Example {
  18. * // Add the library methods
  19. * using EnumerableMap for EnumerableMap.UintToAddressMap;
  20. *
  21. * // Declare a set state variable
  22. * EnumerableMap.UintToAddressMap private myMap;
  23. * }
  24. * ```
  25. *
  26. * The following map types are supported:
  27. *
  28. * - `uint256 -> address` (`UintToAddressMap`) since v3.0.0
  29. * - `address -> uint256` (`AddressToUintMap`) since v4.6.0
  30. * - `bytes32 -> bytes32` (`Bytes32ToBytes32`) since v4.6.0
  31. * - `uint256 -> uint256` (`UintToUintMap`) since v4.7.0
  32. * - `bytes32 -> uint256` (`Bytes32ToUintMap`) since v4.7.0
  33. *
  34. * [WARNING]
  35. * ====
  36. * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure
  37. * unusable.
  38. * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.
  39. *
  40. * In order to clean an EnumerableMap, you can either remove all elements one by one or create a fresh instance using an
  41. * array of EnumerableMap.
  42. * ====
  43. */
  44. library EnumerableMap {
  45. using EnumerableSet for EnumerableSet.Bytes32Set;
  46. // To implement this library for multiple types with as little code
  47. // repetition as possible, we write it in terms of a generic Map type with
  48. // bytes32 keys and values.
  49. // The Map implementation uses private functions, and user-facing
  50. // implementations (such as Uint256ToAddressMap) are just wrappers around
  51. // the underlying Map.
  52. // This means that we can only create new EnumerableMaps for types that fit
  53. // in bytes32.
  54. struct Bytes32ToBytes32Map {
  55. // Storage of keys
  56. EnumerableSet.Bytes32Set _keys;
  57. mapping(bytes32 => bytes32) _values;
  58. }
  59. /**
  60. * @dev Adds a key-value pair to a map, or updates the value for an existing
  61. * key. O(1).
  62. *
  63. * Returns true if the key was added to the map, that is if it was not
  64. * already present.
  65. */
  66. function set(
  67. Bytes32ToBytes32Map storage map,
  68. bytes32 key,
  69. bytes32 value
  70. ) internal returns (bool) {
  71. map._values[key] = value;
  72. return map._keys.add(key);
  73. }
  74. /**
  75. * @dev Removes a key-value pair from a map. O(1).
  76. *
  77. * Returns true if the key was removed from the map, that is if it was present.
  78. */
  79. function remove(Bytes32ToBytes32Map storage map, bytes32 key) internal returns (bool) {
  80. delete map._values[key];
  81. return map._keys.remove(key);
  82. }
  83. /**
  84. * @dev Returns true if the key is in the map. O(1).
  85. */
  86. function contains(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bool) {
  87. return map._keys.contains(key);
  88. }
  89. /**
  90. * @dev Returns the number of key-value pairs in the map. O(1).
  91. */
  92. function length(Bytes32ToBytes32Map storage map) internal view returns (uint256) {
  93. return map._keys.length();
  94. }
  95. /**
  96. * @dev Returns the key-value pair stored at position `index` in the map. O(1).
  97. *
  98. * Note that there are no guarantees on the ordering of entries inside the
  99. * array, and it may change when more entries are added or removed.
  100. *
  101. * Requirements:
  102. *
  103. * - `index` must be strictly less than {length}.
  104. */
  105. function at(Bytes32ToBytes32Map storage map, uint256 index) internal view returns (bytes32, bytes32) {
  106. bytes32 key = map._keys.at(index);
  107. return (key, map._values[key]);
  108. }
  109. /**
  110. * @dev Tries to returns the value associated with `key`. O(1).
  111. * Does not revert if `key` is not in the map.
  112. */
  113. function tryGet(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bool, bytes32) {
  114. bytes32 value = map._values[key];
  115. if (value == bytes32(0)) {
  116. return (contains(map, key), bytes32(0));
  117. } else {
  118. return (true, value);
  119. }
  120. }
  121. /**
  122. * @dev Returns the value associated with `key`. O(1).
  123. *
  124. * Requirements:
  125. *
  126. * - `key` must be in the map.
  127. */
  128. function get(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bytes32) {
  129. bytes32 value = map._values[key];
  130. require(value != 0 || contains(map, key), "EnumerableMap: nonexistent key");
  131. return value;
  132. }
  133. /**
  134. * @dev Same as {_get}, with a custom error message when `key` is not in the map.
  135. *
  136. * CAUTION: This function is deprecated because it requires allocating memory for the error
  137. * message unnecessarily. For custom revert reasons use {_tryGet}.
  138. */
  139. function get(
  140. Bytes32ToBytes32Map storage map,
  141. bytes32 key,
  142. string memory errorMessage
  143. ) internal view returns (bytes32) {
  144. bytes32 value = map._values[key];
  145. require(value != 0 || contains(map, key), errorMessage);
  146. return value;
  147. }
  148. // UintToUintMap
  149. struct UintToUintMap {
  150. Bytes32ToBytes32Map _inner;
  151. }
  152. /**
  153. * @dev Adds a key-value pair to a map, or updates the value for an existing
  154. * key. O(1).
  155. *
  156. * Returns true if the key was added to the map, that is if it was not
  157. * already present.
  158. */
  159. function set(
  160. UintToUintMap storage map,
  161. uint256 key,
  162. uint256 value
  163. ) internal returns (bool) {
  164. return set(map._inner, bytes32(key), bytes32(value));
  165. }
  166. /**
  167. * @dev Removes a value from a set. O(1).
  168. *
  169. * Returns true if the key was removed from the map, that is if it was present.
  170. */
  171. function remove(UintToUintMap storage map, uint256 key) internal returns (bool) {
  172. return remove(map._inner, bytes32(key));
  173. }
  174. /**
  175. * @dev Returns true if the key is in the map. O(1).
  176. */
  177. function contains(UintToUintMap storage map, uint256 key) internal view returns (bool) {
  178. return contains(map._inner, bytes32(key));
  179. }
  180. /**
  181. * @dev Returns the number of elements in the map. O(1).
  182. */
  183. function length(UintToUintMap storage map) internal view returns (uint256) {
  184. return length(map._inner);
  185. }
  186. /**
  187. * @dev Returns the element stored at position `index` in the set. O(1).
  188. * Note that there are no guarantees on the ordering of values inside the
  189. * array, and it may change when more values are added or removed.
  190. *
  191. * Requirements:
  192. *
  193. * - `index` must be strictly less than {length}.
  194. */
  195. function at(UintToUintMap storage map, uint256 index) internal view returns (uint256, uint256) {
  196. (bytes32 key, bytes32 value) = at(map._inner, index);
  197. return (uint256(key), uint256(value));
  198. }
  199. /**
  200. * @dev Tries to returns the value associated with `key`. O(1).
  201. * Does not revert if `key` is not in the map.
  202. */
  203. function tryGet(UintToUintMap storage map, uint256 key) internal view returns (bool, uint256) {
  204. (bool success, bytes32 value) = tryGet(map._inner, bytes32(key));
  205. return (success, uint256(value));
  206. }
  207. /**
  208. * @dev Returns the value associated with `key`. O(1).
  209. *
  210. * Requirements:
  211. *
  212. * - `key` must be in the map.
  213. */
  214. function get(UintToUintMap storage map, uint256 key) internal view returns (uint256) {
  215. return uint256(get(map._inner, bytes32(key)));
  216. }
  217. /**
  218. * @dev Same as {get}, with a custom error message when `key` is not in the map.
  219. *
  220. * CAUTION: This function is deprecated because it requires allocating memory for the error
  221. * message unnecessarily. For custom revert reasons use {tryGet}.
  222. */
  223. function get(
  224. UintToUintMap storage map,
  225. uint256 key,
  226. string memory errorMessage
  227. ) internal view returns (uint256) {
  228. return uint256(get(map._inner, bytes32(key), errorMessage));
  229. }
  230. // UintToAddressMap
  231. struct UintToAddressMap {
  232. Bytes32ToBytes32Map _inner;
  233. }
  234. /**
  235. * @dev Adds a key-value pair to a map, or updates the value for an existing
  236. * key. O(1).
  237. *
  238. * Returns true if the key was added to the map, that is if it was not
  239. * already present.
  240. */
  241. function set(
  242. UintToAddressMap storage map,
  243. uint256 key,
  244. address value
  245. ) internal returns (bool) {
  246. return set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));
  247. }
  248. /**
  249. * @dev Removes a value from a set. O(1).
  250. *
  251. * Returns true if the key was removed from the map, that is if it was present.
  252. */
  253. function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {
  254. return remove(map._inner, bytes32(key));
  255. }
  256. /**
  257. * @dev Returns true if the key is in the map. O(1).
  258. */
  259. function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {
  260. return contains(map._inner, bytes32(key));
  261. }
  262. /**
  263. * @dev Returns the number of elements in the map. O(1).
  264. */
  265. function length(UintToAddressMap storage map) internal view returns (uint256) {
  266. return length(map._inner);
  267. }
  268. /**
  269. * @dev Returns the element stored at position `index` in the set. O(1).
  270. * Note that there are no guarantees on the ordering of values inside the
  271. * array, and it may change when more values are added or removed.
  272. *
  273. * Requirements:
  274. *
  275. * - `index` must be strictly less than {length}.
  276. */
  277. function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {
  278. (bytes32 key, bytes32 value) = at(map._inner, index);
  279. return (uint256(key), address(uint160(uint256(value))));
  280. }
  281. /**
  282. * @dev Tries to returns the value associated with `key`. O(1).
  283. * Does not revert if `key` is not in the map.
  284. *
  285. * _Available since v3.4._
  286. */
  287. function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) {
  288. (bool success, bytes32 value) = tryGet(map._inner, bytes32(key));
  289. return (success, address(uint160(uint256(value))));
  290. }
  291. /**
  292. * @dev Returns the value associated with `key`. O(1).
  293. *
  294. * Requirements:
  295. *
  296. * - `key` must be in the map.
  297. */
  298. function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {
  299. return address(uint160(uint256(get(map._inner, bytes32(key)))));
  300. }
  301. /**
  302. * @dev Same as {get}, with a custom error message when `key` is not in the map.
  303. *
  304. * CAUTION: This function is deprecated because it requires allocating memory for the error
  305. * message unnecessarily. For custom revert reasons use {tryGet}.
  306. */
  307. function get(
  308. UintToAddressMap storage map,
  309. uint256 key,
  310. string memory errorMessage
  311. ) internal view returns (address) {
  312. return address(uint160(uint256(get(map._inner, bytes32(key), errorMessage))));
  313. }
  314. // AddressToUintMap
  315. struct AddressToUintMap {
  316. Bytes32ToBytes32Map _inner;
  317. }
  318. /**
  319. * @dev Adds a key-value pair to a map, or updates the value for an existing
  320. * key. O(1).
  321. *
  322. * Returns true if the key was added to the map, that is if it was not
  323. * already present.
  324. */
  325. function set(
  326. AddressToUintMap storage map,
  327. address key,
  328. uint256 value
  329. ) internal returns (bool) {
  330. return set(map._inner, bytes32(uint256(uint160(key))), bytes32(value));
  331. }
  332. /**
  333. * @dev Removes a value from a set. O(1).
  334. *
  335. * Returns true if the key was removed from the map, that is if it was present.
  336. */
  337. function remove(AddressToUintMap storage map, address key) internal returns (bool) {
  338. return remove(map._inner, bytes32(uint256(uint160(key))));
  339. }
  340. /**
  341. * @dev Returns true if the key is in the map. O(1).
  342. */
  343. function contains(AddressToUintMap storage map, address key) internal view returns (bool) {
  344. return contains(map._inner, bytes32(uint256(uint160(key))));
  345. }
  346. /**
  347. * @dev Returns the number of elements in the map. O(1).
  348. */
  349. function length(AddressToUintMap storage map) internal view returns (uint256) {
  350. return length(map._inner);
  351. }
  352. /**
  353. * @dev Returns the element stored at position `index` in the set. O(1).
  354. * Note that there are no guarantees on the ordering of values inside the
  355. * array, and it may change when more values are added or removed.
  356. *
  357. * Requirements:
  358. *
  359. * - `index` must be strictly less than {length}.
  360. */
  361. function at(AddressToUintMap storage map, uint256 index) internal view returns (address, uint256) {
  362. (bytes32 key, bytes32 value) = at(map._inner, index);
  363. return (address(uint160(uint256(key))), uint256(value));
  364. }
  365. /**
  366. * @dev Tries to returns the value associated with `key`. O(1).
  367. * Does not revert if `key` is not in the map.
  368. */
  369. function tryGet(AddressToUintMap storage map, address key) internal view returns (bool, uint256) {
  370. (bool success, bytes32 value) = tryGet(map._inner, bytes32(uint256(uint160(key))));
  371. return (success, uint256(value));
  372. }
  373. /**
  374. * @dev Returns the value associated with `key`. O(1).
  375. *
  376. * Requirements:
  377. *
  378. * - `key` must be in the map.
  379. */
  380. function get(AddressToUintMap storage map, address key) internal view returns (uint256) {
  381. return uint256(get(map._inner, bytes32(uint256(uint160(key)))));
  382. }
  383. /**
  384. * @dev Same as {get}, with a custom error message when `key` is not in the map.
  385. *
  386. * CAUTION: This function is deprecated because it requires allocating memory for the error
  387. * message unnecessarily. For custom revert reasons use {tryGet}.
  388. */
  389. function get(
  390. AddressToUintMap storage map,
  391. address key,
  392. string memory errorMessage
  393. ) internal view returns (uint256) {
  394. return uint256(get(map._inner, bytes32(uint256(uint160(key))), errorMessage));
  395. }
  396. // Bytes32ToUintMap
  397. struct Bytes32ToUintMap {
  398. Bytes32ToBytes32Map _inner;
  399. }
  400. /**
  401. * @dev Adds a key-value pair to a map, or updates the value for an existing
  402. * key. O(1).
  403. *
  404. * Returns true if the key was added to the map, that is if it was not
  405. * already present.
  406. */
  407. function set(
  408. Bytes32ToUintMap storage map,
  409. bytes32 key,
  410. uint256 value
  411. ) internal returns (bool) {
  412. return set(map._inner, key, bytes32(value));
  413. }
  414. /**
  415. * @dev Removes a value from a set. O(1).
  416. *
  417. * Returns true if the key was removed from the map, that is if it was present.
  418. */
  419. function remove(Bytes32ToUintMap storage map, bytes32 key) internal returns (bool) {
  420. return remove(map._inner, key);
  421. }
  422. /**
  423. * @dev Returns true if the key is in the map. O(1).
  424. */
  425. function contains(Bytes32ToUintMap storage map, bytes32 key) internal view returns (bool) {
  426. return contains(map._inner, key);
  427. }
  428. /**
  429. * @dev Returns the number of elements in the map. O(1).
  430. */
  431. function length(Bytes32ToUintMap storage map) internal view returns (uint256) {
  432. return length(map._inner);
  433. }
  434. /**
  435. * @dev Returns the element stored at position `index` in the set. O(1).
  436. * Note that there are no guarantees on the ordering of values inside the
  437. * array, and it may change when more values are added or removed.
  438. *
  439. * Requirements:
  440. *
  441. * - `index` must be strictly less than {length}.
  442. */
  443. function at(Bytes32ToUintMap storage map, uint256 index) internal view returns (bytes32, uint256) {
  444. (bytes32 key, bytes32 value) = at(map._inner, index);
  445. return (key, uint256(value));
  446. }
  447. /**
  448. * @dev Tries to returns the value associated with `key`. O(1).
  449. * Does not revert if `key` is not in the map.
  450. */
  451. function tryGet(Bytes32ToUintMap storage map, bytes32 key) internal view returns (bool, uint256) {
  452. (bool success, bytes32 value) = tryGet(map._inner, key);
  453. return (success, uint256(value));
  454. }
  455. /**
  456. * @dev Returns the value associated with `key`. O(1).
  457. *
  458. * Requirements:
  459. *
  460. * - `key` must be in the map.
  461. */
  462. function get(Bytes32ToUintMap storage map, bytes32 key) internal view returns (uint256) {
  463. return uint256(get(map._inner, key));
  464. }
  465. /**
  466. * @dev Same as {get}, with a custom error message when `key` is not in the map.
  467. *
  468. * CAUTION: This function is deprecated because it requires allocating memory for the error
  469. * message unnecessarily. For custom revert reasons use {tryGet}.
  470. */
  471. function get(
  472. Bytes32ToUintMap storage map,
  473. bytes32 key,
  474. string memory errorMessage
  475. ) internal view returns (uint256) {
  476. return uint256(get(map._inner, key, errorMessage));
  477. }
  478. }