EnumerableSet.sol 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792
  1. // SPDX-License-Identifier: MIT
  2. // OpenZeppelin Contracts (last updated v5.4.0-rc.0) (utils/structs/EnumerableSet.sol)
  3. // This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.
  4. pragma solidity ^0.8.20;
  5. import {Arrays} from "../Arrays.sol";
  6. import {Math} from "../math/Math.sol";
  7. /**
  8. * @dev Library for managing
  9. * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
  10. * types.
  11. *
  12. * Sets have the following properties:
  13. *
  14. * - Elements are added, removed, and checked for existence in constant time
  15. * (O(1)).
  16. * - Elements are enumerated in O(n). No guarantees are made on the ordering.
  17. * - Set can be cleared (all elements removed) in O(n).
  18. *
  19. * ```solidity
  20. * contract Example {
  21. * // Add the library methods
  22. * using EnumerableSet for EnumerableSet.AddressSet;
  23. *
  24. * // Declare a set state variable
  25. * EnumerableSet.AddressSet private mySet;
  26. * }
  27. * ```
  28. *
  29. * The following types are supported:
  30. *
  31. * - `bytes32` (`Bytes32Set`) since v3.3.0
  32. * - `address` (`AddressSet`) since v3.3.0
  33. * - `uint256` (`UintSet`) since v3.3.0
  34. * - `string` (`StringSet`) since v5.4.0
  35. * - `bytes` (`BytesSet`) since v5.4.0
  36. *
  37. * [WARNING]
  38. * ====
  39. * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure
  40. * unusable.
  41. * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.
  42. *
  43. * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an
  44. * array of EnumerableSet.
  45. * ====
  46. */
  47. library EnumerableSet {
  48. // To implement this library for multiple types with as little code
  49. // repetition as possible, we write it in terms of a generic Set type with
  50. // bytes32 values.
  51. // The Set implementation uses private functions, and user-facing
  52. // implementations (such as AddressSet) are just wrappers around the
  53. // underlying Set.
  54. // This means that we can only create new EnumerableSets for types that fit
  55. // in bytes32.
  56. struct Set {
  57. // Storage of set values
  58. bytes32[] _values;
  59. // Position is the index of the value in the `values` array plus 1.
  60. // Position 0 is used to mean a value is not in the set.
  61. mapping(bytes32 value => uint256) _positions;
  62. }
  63. /**
  64. * @dev Add a value to a set. O(1).
  65. *
  66. * Returns true if the value was added to the set, that is if it was not
  67. * already present.
  68. */
  69. function _add(Set storage set, bytes32 value) private returns (bool) {
  70. if (!_contains(set, value)) {
  71. set._values.push(value);
  72. // The value is stored at length-1, but we add 1 to all indexes
  73. // and use 0 as a sentinel value
  74. set._positions[value] = set._values.length;
  75. return true;
  76. } else {
  77. return false;
  78. }
  79. }
  80. /**
  81. * @dev Removes a value from a set. O(1).
  82. *
  83. * Returns true if the value was removed from the set, that is if it was
  84. * present.
  85. */
  86. function _remove(Set storage set, bytes32 value) private returns (bool) {
  87. // We cache the value's position to prevent multiple reads from the same storage slot
  88. uint256 position = set._positions[value];
  89. if (position != 0) {
  90. // Equivalent to contains(set, value)
  91. // To delete an element from the _values array in O(1), we swap the element to delete with the last one in
  92. // the array, and then remove the last element (sometimes called as 'swap and pop').
  93. // This modifies the order of the array, as noted in {at}.
  94. uint256 valueIndex = position - 1;
  95. uint256 lastIndex = set._values.length - 1;
  96. if (valueIndex != lastIndex) {
  97. bytes32 lastValue = set._values[lastIndex];
  98. // Move the lastValue to the index where the value to delete is
  99. set._values[valueIndex] = lastValue;
  100. // Update the tracked position of the lastValue (that was just moved)
  101. set._positions[lastValue] = position;
  102. }
  103. // Delete the slot where the moved value was stored
  104. set._values.pop();
  105. // Delete the tracked position for the deleted slot
  106. delete set._positions[value];
  107. return true;
  108. } else {
  109. return false;
  110. }
  111. }
  112. /**
  113. * @dev Removes all the values from a set. O(n).
  114. *
  115. * WARNING: This function has an unbounded cost that scales with set size. Developers should keep in mind that
  116. * using it may render the function uncallable if the set grows to the point where clearing it consumes too much
  117. * gas to fit in a block.
  118. */
  119. function _clear(Set storage set) private {
  120. uint256 len = _length(set);
  121. for (uint256 i = 0; i < len; ++i) {
  122. delete set._positions[set._values[i]];
  123. }
  124. Arrays.unsafeSetLength(set._values, 0);
  125. }
  126. /**
  127. * @dev Returns true if the value is in the set. O(1).
  128. */
  129. function _contains(Set storage set, bytes32 value) private view returns (bool) {
  130. return set._positions[value] != 0;
  131. }
  132. /**
  133. * @dev Returns the number of values on the set. O(1).
  134. */
  135. function _length(Set storage set) private view returns (uint256) {
  136. return set._values.length;
  137. }
  138. /**
  139. * @dev Returns the value stored at position `index` in the set. O(1).
  140. *
  141. * Note that there are no guarantees on the ordering of values inside the
  142. * array, and it may change when more values are added or removed.
  143. *
  144. * Requirements:
  145. *
  146. * - `index` must be strictly less than {length}.
  147. */
  148. function _at(Set storage set, uint256 index) private view returns (bytes32) {
  149. return set._values[index];
  150. }
  151. /**
  152. * @dev Return the entire set in an array
  153. *
  154. * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
  155. * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
  156. * this function has an unbounded cost, and using it as part of a state-changing function may render the function
  157. * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
  158. */
  159. function _values(Set storage set) private view returns (bytes32[] memory) {
  160. return set._values;
  161. }
  162. /**
  163. * @dev Return a slice of the set in an array
  164. *
  165. * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
  166. * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
  167. * this function has an unbounded cost, and using it as part of a state-changing function may render the function
  168. * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
  169. */
  170. function _values(Set storage set, uint256 start, uint256 end) private view returns (bytes32[] memory) {
  171. unchecked {
  172. end = Math.min(end, _length(set));
  173. start = Math.min(start, end);
  174. uint256 len = end - start;
  175. bytes32[] memory result = new bytes32[](len);
  176. for (uint256 i = 0; i < len; ++i) {
  177. result[i] = Arrays.unsafeAccess(set._values, start + i).value;
  178. }
  179. return result;
  180. }
  181. }
  182. // Bytes32Set
  183. struct Bytes32Set {
  184. Set _inner;
  185. }
  186. /**
  187. * @dev Add a value to a set. O(1).
  188. *
  189. * Returns true if the value was added to the set, that is if it was not
  190. * already present.
  191. */
  192. function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
  193. return _add(set._inner, value);
  194. }
  195. /**
  196. * @dev Removes a value from a set. O(1).
  197. *
  198. * Returns true if the value was removed from the set, that is if it was
  199. * present.
  200. */
  201. function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
  202. return _remove(set._inner, value);
  203. }
  204. /**
  205. * @dev Removes all the values from a set. O(n).
  206. *
  207. * WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the
  208. * function uncallable if the set grows to the point where clearing it consumes too much gas to fit in a block.
  209. */
  210. function clear(Bytes32Set storage set) internal {
  211. _clear(set._inner);
  212. }
  213. /**
  214. * @dev Returns true if the value is in the set. O(1).
  215. */
  216. function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
  217. return _contains(set._inner, value);
  218. }
  219. /**
  220. * @dev Returns the number of values in the set. O(1).
  221. */
  222. function length(Bytes32Set storage set) internal view returns (uint256) {
  223. return _length(set._inner);
  224. }
  225. /**
  226. * @dev Returns the value stored at position `index` in the set. O(1).
  227. *
  228. * Note that there are no guarantees on the ordering of values inside the
  229. * array, and it may change when more values are added or removed.
  230. *
  231. * Requirements:
  232. *
  233. * - `index` must be strictly less than {length}.
  234. */
  235. function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
  236. return _at(set._inner, index);
  237. }
  238. /**
  239. * @dev Return the entire set in an array
  240. *
  241. * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
  242. * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
  243. * this function has an unbounded cost, and using it as part of a state-changing function may render the function
  244. * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
  245. */
  246. function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {
  247. bytes32[] memory store = _values(set._inner);
  248. bytes32[] memory result;
  249. assembly ("memory-safe") {
  250. result := store
  251. }
  252. return result;
  253. }
  254. /**
  255. * @dev Return a slice of the set in an array
  256. *
  257. * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
  258. * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
  259. * this function has an unbounded cost, and using it as part of a state-changing function may render the function
  260. * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
  261. */
  262. function values(Bytes32Set storage set, uint256 start, uint256 end) internal view returns (bytes32[] memory) {
  263. bytes32[] memory store = _values(set._inner, start, end);
  264. bytes32[] memory result;
  265. assembly ("memory-safe") {
  266. result := store
  267. }
  268. return result;
  269. }
  270. // AddressSet
  271. struct AddressSet {
  272. Set _inner;
  273. }
  274. /**
  275. * @dev Add a value to a set. O(1).
  276. *
  277. * Returns true if the value was added to the set, that is if it was not
  278. * already present.
  279. */
  280. function add(AddressSet storage set, address value) internal returns (bool) {
  281. return _add(set._inner, bytes32(uint256(uint160(value))));
  282. }
  283. /**
  284. * @dev Removes a value from a set. O(1).
  285. *
  286. * Returns true if the value was removed from the set, that is if it was
  287. * present.
  288. */
  289. function remove(AddressSet storage set, address value) internal returns (bool) {
  290. return _remove(set._inner, bytes32(uint256(uint160(value))));
  291. }
  292. /**
  293. * @dev Removes all the values from a set. O(n).
  294. *
  295. * WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the
  296. * function uncallable if the set grows to the point where clearing it consumes too much gas to fit in a block.
  297. */
  298. function clear(AddressSet storage set) internal {
  299. _clear(set._inner);
  300. }
  301. /**
  302. * @dev Returns true if the value is in the set. O(1).
  303. */
  304. function contains(AddressSet storage set, address value) internal view returns (bool) {
  305. return _contains(set._inner, bytes32(uint256(uint160(value))));
  306. }
  307. /**
  308. * @dev Returns the number of values in the set. O(1).
  309. */
  310. function length(AddressSet storage set) internal view returns (uint256) {
  311. return _length(set._inner);
  312. }
  313. /**
  314. * @dev Returns the value stored at position `index` in the set. O(1).
  315. *
  316. * Note that there are no guarantees on the ordering of values inside the
  317. * array, and it may change when more values are added or removed.
  318. *
  319. * Requirements:
  320. *
  321. * - `index` must be strictly less than {length}.
  322. */
  323. function at(AddressSet storage set, uint256 index) internal view returns (address) {
  324. return address(uint160(uint256(_at(set._inner, index))));
  325. }
  326. /**
  327. * @dev Return the entire set in an array
  328. *
  329. * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
  330. * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
  331. * this function has an unbounded cost, and using it as part of a state-changing function may render the function
  332. * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
  333. */
  334. function values(AddressSet storage set) internal view returns (address[] memory) {
  335. bytes32[] memory store = _values(set._inner);
  336. address[] memory result;
  337. assembly ("memory-safe") {
  338. result := store
  339. }
  340. return result;
  341. }
  342. /**
  343. * @dev Return a slice of the set in an array
  344. *
  345. * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
  346. * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
  347. * this function has an unbounded cost, and using it as part of a state-changing function may render the function
  348. * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
  349. */
  350. function values(AddressSet storage set, uint256 start, uint256 end) internal view returns (address[] memory) {
  351. bytes32[] memory store = _values(set._inner, start, end);
  352. address[] memory result;
  353. assembly ("memory-safe") {
  354. result := store
  355. }
  356. return result;
  357. }
  358. // UintSet
  359. struct UintSet {
  360. Set _inner;
  361. }
  362. /**
  363. * @dev Add a value to a set. O(1).
  364. *
  365. * Returns true if the value was added to the set, that is if it was not
  366. * already present.
  367. */
  368. function add(UintSet storage set, uint256 value) internal returns (bool) {
  369. return _add(set._inner, bytes32(value));
  370. }
  371. /**
  372. * @dev Removes a value from a set. O(1).
  373. *
  374. * Returns true if the value was removed from the set, that is if it was
  375. * present.
  376. */
  377. function remove(UintSet storage set, uint256 value) internal returns (bool) {
  378. return _remove(set._inner, bytes32(value));
  379. }
  380. /**
  381. * @dev Removes all the values from a set. O(n).
  382. *
  383. * WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the
  384. * function uncallable if the set grows to the point where clearing it consumes too much gas to fit in a block.
  385. */
  386. function clear(UintSet storage set) internal {
  387. _clear(set._inner);
  388. }
  389. /**
  390. * @dev Returns true if the value is in the set. O(1).
  391. */
  392. function contains(UintSet storage set, uint256 value) internal view returns (bool) {
  393. return _contains(set._inner, bytes32(value));
  394. }
  395. /**
  396. * @dev Returns the number of values in the set. O(1).
  397. */
  398. function length(UintSet storage set) internal view returns (uint256) {
  399. return _length(set._inner);
  400. }
  401. /**
  402. * @dev Returns the value stored at position `index` in the set. O(1).
  403. *
  404. * Note that there are no guarantees on the ordering of values inside the
  405. * array, and it may change when more values are added or removed.
  406. *
  407. * Requirements:
  408. *
  409. * - `index` must be strictly less than {length}.
  410. */
  411. function at(UintSet storage set, uint256 index) internal view returns (uint256) {
  412. return uint256(_at(set._inner, index));
  413. }
  414. /**
  415. * @dev Return the entire set in an array
  416. *
  417. * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
  418. * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
  419. * this function has an unbounded cost, and using it as part of a state-changing function may render the function
  420. * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
  421. */
  422. function values(UintSet storage set) internal view returns (uint256[] memory) {
  423. bytes32[] memory store = _values(set._inner);
  424. uint256[] memory result;
  425. assembly ("memory-safe") {
  426. result := store
  427. }
  428. return result;
  429. }
  430. /**
  431. * @dev Return a slice of the set in an array
  432. *
  433. * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
  434. * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
  435. * this function has an unbounded cost, and using it as part of a state-changing function may render the function
  436. * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
  437. */
  438. function values(UintSet storage set, uint256 start, uint256 end) internal view returns (uint256[] memory) {
  439. bytes32[] memory store = _values(set._inner, start, end);
  440. uint256[] memory result;
  441. assembly ("memory-safe") {
  442. result := store
  443. }
  444. return result;
  445. }
  446. struct StringSet {
  447. // Storage of set values
  448. string[] _values;
  449. // Position is the index of the value in the `values` array plus 1.
  450. // Position 0 is used to mean a value is not in the set.
  451. mapping(string value => uint256) _positions;
  452. }
  453. /**
  454. * @dev Add a value to a set. O(1).
  455. *
  456. * Returns true if the value was added to the set, that is if it was not
  457. * already present.
  458. */
  459. function add(StringSet storage set, string memory value) internal returns (bool) {
  460. if (!contains(set, value)) {
  461. set._values.push(value);
  462. // The value is stored at length-1, but we add 1 to all indexes
  463. // and use 0 as a sentinel value
  464. set._positions[value] = set._values.length;
  465. return true;
  466. } else {
  467. return false;
  468. }
  469. }
  470. /**
  471. * @dev Removes a value from a set. O(1).
  472. *
  473. * Returns true if the value was removed from the set, that is if it was
  474. * present.
  475. */
  476. function remove(StringSet storage set, string memory value) internal returns (bool) {
  477. // We cache the value's position to prevent multiple reads from the same storage slot
  478. uint256 position = set._positions[value];
  479. if (position != 0) {
  480. // Equivalent to contains(set, value)
  481. // To delete an element from the _values array in O(1), we swap the element to delete with the last one in
  482. // the array, and then remove the last element (sometimes called as 'swap and pop').
  483. // This modifies the order of the array, as noted in {at}.
  484. uint256 valueIndex = position - 1;
  485. uint256 lastIndex = set._values.length - 1;
  486. if (valueIndex != lastIndex) {
  487. string memory lastValue = set._values[lastIndex];
  488. // Move the lastValue to the index where the value to delete is
  489. set._values[valueIndex] = lastValue;
  490. // Update the tracked position of the lastValue (that was just moved)
  491. set._positions[lastValue] = position;
  492. }
  493. // Delete the slot where the moved value was stored
  494. set._values.pop();
  495. // Delete the tracked position for the deleted slot
  496. delete set._positions[value];
  497. return true;
  498. } else {
  499. return false;
  500. }
  501. }
  502. /**
  503. * @dev Removes all the values from a set. O(n).
  504. *
  505. * WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the
  506. * function uncallable if the set grows to the point where clearing it consumes too much gas to fit in a block.
  507. */
  508. function clear(StringSet storage set) internal {
  509. uint256 len = length(set);
  510. for (uint256 i = 0; i < len; ++i) {
  511. delete set._positions[set._values[i]];
  512. }
  513. Arrays.unsafeSetLength(set._values, 0);
  514. }
  515. /**
  516. * @dev Returns true if the value is in the set. O(1).
  517. */
  518. function contains(StringSet storage set, string memory value) internal view returns (bool) {
  519. return set._positions[value] != 0;
  520. }
  521. /**
  522. * @dev Returns the number of values on the set. O(1).
  523. */
  524. function length(StringSet storage set) internal view returns (uint256) {
  525. return set._values.length;
  526. }
  527. /**
  528. * @dev Returns the value stored at position `index` in the set. O(1).
  529. *
  530. * Note that there are no guarantees on the ordering of values inside the
  531. * array, and it may change when more values are added or removed.
  532. *
  533. * Requirements:
  534. *
  535. * - `index` must be strictly less than {length}.
  536. */
  537. function at(StringSet storage set, uint256 index) internal view returns (string memory) {
  538. return set._values[index];
  539. }
  540. /**
  541. * @dev Return the entire set in an array
  542. *
  543. * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
  544. * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
  545. * this function has an unbounded cost, and using it as part of a state-changing function may render the function
  546. * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
  547. */
  548. function values(StringSet storage set) internal view returns (string[] memory) {
  549. return set._values;
  550. }
  551. /**
  552. * @dev Return a slice of the set in an array
  553. *
  554. * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
  555. * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
  556. * this function has an unbounded cost, and using it as part of a state-changing function may render the function
  557. * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
  558. */
  559. function values(StringSet storage set, uint256 start, uint256 end) internal view returns (string[] memory) {
  560. unchecked {
  561. end = Math.min(end, length(set));
  562. start = Math.min(start, end);
  563. uint256 len = end - start;
  564. string[] memory result = new string[](len);
  565. for (uint256 i = 0; i < len; ++i) {
  566. result[i] = Arrays.unsafeAccess(set._values, start + i).value;
  567. }
  568. return result;
  569. }
  570. }
  571. struct BytesSet {
  572. // Storage of set values
  573. bytes[] _values;
  574. // Position is the index of the value in the `values` array plus 1.
  575. // Position 0 is used to mean a value is not in the set.
  576. mapping(bytes value => uint256) _positions;
  577. }
  578. /**
  579. * @dev Add a value to a set. O(1).
  580. *
  581. * Returns true if the value was added to the set, that is if it was not
  582. * already present.
  583. */
  584. function add(BytesSet storage set, bytes memory value) internal returns (bool) {
  585. if (!contains(set, value)) {
  586. set._values.push(value);
  587. // The value is stored at length-1, but we add 1 to all indexes
  588. // and use 0 as a sentinel value
  589. set._positions[value] = set._values.length;
  590. return true;
  591. } else {
  592. return false;
  593. }
  594. }
  595. /**
  596. * @dev Removes a value from a set. O(1).
  597. *
  598. * Returns true if the value was removed from the set, that is if it was
  599. * present.
  600. */
  601. function remove(BytesSet storage set, bytes memory value) internal returns (bool) {
  602. // We cache the value's position to prevent multiple reads from the same storage slot
  603. uint256 position = set._positions[value];
  604. if (position != 0) {
  605. // Equivalent to contains(set, value)
  606. // To delete an element from the _values array in O(1), we swap the element to delete with the last one in
  607. // the array, and then remove the last element (sometimes called as 'swap and pop').
  608. // This modifies the order of the array, as noted in {at}.
  609. uint256 valueIndex = position - 1;
  610. uint256 lastIndex = set._values.length - 1;
  611. if (valueIndex != lastIndex) {
  612. bytes memory lastValue = set._values[lastIndex];
  613. // Move the lastValue to the index where the value to delete is
  614. set._values[valueIndex] = lastValue;
  615. // Update the tracked position of the lastValue (that was just moved)
  616. set._positions[lastValue] = position;
  617. }
  618. // Delete the slot where the moved value was stored
  619. set._values.pop();
  620. // Delete the tracked position for the deleted slot
  621. delete set._positions[value];
  622. return true;
  623. } else {
  624. return false;
  625. }
  626. }
  627. /**
  628. * @dev Removes all the values from a set. O(n).
  629. *
  630. * WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the
  631. * function uncallable if the set grows to the point where clearing it consumes too much gas to fit in a block.
  632. */
  633. function clear(BytesSet storage set) internal {
  634. uint256 len = length(set);
  635. for (uint256 i = 0; i < len; ++i) {
  636. delete set._positions[set._values[i]];
  637. }
  638. Arrays.unsafeSetLength(set._values, 0);
  639. }
  640. /**
  641. * @dev Returns true if the value is in the set. O(1).
  642. */
  643. function contains(BytesSet storage set, bytes memory value) internal view returns (bool) {
  644. return set._positions[value] != 0;
  645. }
  646. /**
  647. * @dev Returns the number of values on the set. O(1).
  648. */
  649. function length(BytesSet storage set) internal view returns (uint256) {
  650. return set._values.length;
  651. }
  652. /**
  653. * @dev Returns the value stored at position `index` in the set. O(1).
  654. *
  655. * Note that there are no guarantees on the ordering of values inside the
  656. * array, and it may change when more values are added or removed.
  657. *
  658. * Requirements:
  659. *
  660. * - `index` must be strictly less than {length}.
  661. */
  662. function at(BytesSet storage set, uint256 index) internal view returns (bytes memory) {
  663. return set._values[index];
  664. }
  665. /**
  666. * @dev Return the entire set in an array
  667. *
  668. * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
  669. * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
  670. * this function has an unbounded cost, and using it as part of a state-changing function may render the function
  671. * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
  672. */
  673. function values(BytesSet storage set) internal view returns (bytes[] memory) {
  674. return set._values;
  675. }
  676. /**
  677. * @dev Return a slice of the set in an array
  678. *
  679. * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
  680. * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
  681. * this function has an unbounded cost, and using it as part of a state-changing function may render the function
  682. * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
  683. */
  684. function values(BytesSet storage set, uint256 start, uint256 end) internal view returns (bytes[] memory) {
  685. unchecked {
  686. end = Math.min(end, length(set));
  687. start = Math.min(start, end);
  688. uint256 len = end - start;
  689. bytes[] memory result = new bytes[](len);
  690. for (uint256 i = 0; i < len; ++i) {
  691. result[i] = Arrays.unsafeAccess(set._values, start + i).value;
  692. }
  693. return result;
  694. }
  695. }
  696. }