EnumerableSet.sol 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791
  1. // SPDX-License-Identifier: MIT
  2. // OpenZeppelin Contracts (last updated v5.3.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: Developers should keep in mind that this function has an unbounded cost and using it may render the
  116. * function uncallable if the set grows to the point where clearing it consumes too much gas to fit in a block.
  117. */
  118. function _clear(Set storage set) private {
  119. uint256 len = _length(set);
  120. for (uint256 i = 0; i < len; ++i) {
  121. delete set._positions[set._values[i]];
  122. }
  123. Arrays.unsafeSetLength(set._values, 0);
  124. }
  125. /**
  126. * @dev Returns true if the value is in the set. O(1).
  127. */
  128. function _contains(Set storage set, bytes32 value) private view returns (bool) {
  129. return set._positions[value] != 0;
  130. }
  131. /**
  132. * @dev Returns the number of values on the set. O(1).
  133. */
  134. function _length(Set storage set) private view returns (uint256) {
  135. return set._values.length;
  136. }
  137. /**
  138. * @dev Returns the value stored at position `index` in the set. O(1).
  139. *
  140. * Note that there are no guarantees on the ordering of values inside the
  141. * array, and it may change when more values are added or removed.
  142. *
  143. * Requirements:
  144. *
  145. * - `index` must be strictly less than {length}.
  146. */
  147. function _at(Set storage set, uint256 index) private view returns (bytes32) {
  148. return set._values[index];
  149. }
  150. /**
  151. * @dev Return the entire set in an array
  152. *
  153. * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
  154. * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
  155. * this function has an unbounded cost, and using it as part of a state-changing function may render the function
  156. * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
  157. */
  158. function _values(Set storage set) private view returns (bytes32[] memory) {
  159. return set._values;
  160. }
  161. /**
  162. * @dev Return a slice of the set in an array
  163. *
  164. * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
  165. * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
  166. * this function has an unbounded cost, and using it as part of a state-changing function may render the function
  167. * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
  168. */
  169. function _values(Set storage set, uint256 start, uint256 end) private view returns (bytes32[] memory) {
  170. unchecked {
  171. end = Math.min(end, _length(set));
  172. start = Math.min(start, end);
  173. uint256 len = end - start;
  174. bytes32[] memory result = new bytes32[](len);
  175. for (uint256 i = 0; i < len; ++i) {
  176. result[i] = Arrays.unsafeAccess(set._values, start + i).value;
  177. }
  178. return result;
  179. }
  180. }
  181. // Bytes32Set
  182. struct Bytes32Set {
  183. Set _inner;
  184. }
  185. /**
  186. * @dev Add a value to a set. O(1).
  187. *
  188. * Returns true if the value was added to the set, that is if it was not
  189. * already present.
  190. */
  191. function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
  192. return _add(set._inner, value);
  193. }
  194. /**
  195. * @dev Removes a value from a set. O(1).
  196. *
  197. * Returns true if the value was removed from the set, that is if it was
  198. * present.
  199. */
  200. function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
  201. return _remove(set._inner, value);
  202. }
  203. /**
  204. * @dev Removes all the values from a set. O(n).
  205. *
  206. * WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the
  207. * function uncallable if the set grows to the point where clearing it consumes too much gas to fit in a block.
  208. */
  209. function clear(Bytes32Set storage set) internal {
  210. _clear(set._inner);
  211. }
  212. /**
  213. * @dev Returns true if the value is in the set. O(1).
  214. */
  215. function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
  216. return _contains(set._inner, value);
  217. }
  218. /**
  219. * @dev Returns the number of values in the set. O(1).
  220. */
  221. function length(Bytes32Set storage set) internal view returns (uint256) {
  222. return _length(set._inner);
  223. }
  224. /**
  225. * @dev Returns the value stored at position `index` in the set. O(1).
  226. *
  227. * Note that there are no guarantees on the ordering of values inside the
  228. * array, and it may change when more values are added or removed.
  229. *
  230. * Requirements:
  231. *
  232. * - `index` must be strictly less than {length}.
  233. */
  234. function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
  235. return _at(set._inner, index);
  236. }
  237. /**
  238. * @dev Return the entire set in an array
  239. *
  240. * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
  241. * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
  242. * this function has an unbounded cost, and using it as part of a state-changing function may render the function
  243. * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
  244. */
  245. function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {
  246. bytes32[] memory store = _values(set._inner);
  247. bytes32[] memory result;
  248. assembly ("memory-safe") {
  249. result := store
  250. }
  251. return result;
  252. }
  253. /**
  254. * @dev Return a slice of the set in an array
  255. *
  256. * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
  257. * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
  258. * this function has an unbounded cost, and using it as part of a state-changing function may render the function
  259. * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
  260. */
  261. function values(Bytes32Set storage set, uint256 start, uint256 end) internal view returns (bytes32[] memory) {
  262. bytes32[] memory store = _values(set._inner, start, end);
  263. bytes32[] memory result;
  264. assembly ("memory-safe") {
  265. result := store
  266. }
  267. return result;
  268. }
  269. // AddressSet
  270. struct AddressSet {
  271. Set _inner;
  272. }
  273. /**
  274. * @dev Add a value to a set. O(1).
  275. *
  276. * Returns true if the value was added to the set, that is if it was not
  277. * already present.
  278. */
  279. function add(AddressSet storage set, address value) internal returns (bool) {
  280. return _add(set._inner, bytes32(uint256(uint160(value))));
  281. }
  282. /**
  283. * @dev Removes a value from a set. O(1).
  284. *
  285. * Returns true if the value was removed from the set, that is if it was
  286. * present.
  287. */
  288. function remove(AddressSet storage set, address value) internal returns (bool) {
  289. return _remove(set._inner, bytes32(uint256(uint160(value))));
  290. }
  291. /**
  292. * @dev Removes all the values from a set. O(n).
  293. *
  294. * WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the
  295. * function uncallable if the set grows to the point where clearing it consumes too much gas to fit in a block.
  296. */
  297. function clear(AddressSet storage set) internal {
  298. _clear(set._inner);
  299. }
  300. /**
  301. * @dev Returns true if the value is in the set. O(1).
  302. */
  303. function contains(AddressSet storage set, address value) internal view returns (bool) {
  304. return _contains(set._inner, bytes32(uint256(uint160(value))));
  305. }
  306. /**
  307. * @dev Returns the number of values in the set. O(1).
  308. */
  309. function length(AddressSet storage set) internal view returns (uint256) {
  310. return _length(set._inner);
  311. }
  312. /**
  313. * @dev Returns the value stored at position `index` in the set. O(1).
  314. *
  315. * Note that there are no guarantees on the ordering of values inside the
  316. * array, and it may change when more values are added or removed.
  317. *
  318. * Requirements:
  319. *
  320. * - `index` must be strictly less than {length}.
  321. */
  322. function at(AddressSet storage set, uint256 index) internal view returns (address) {
  323. return address(uint160(uint256(_at(set._inner, index))));
  324. }
  325. /**
  326. * @dev Return the entire set in an array
  327. *
  328. * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
  329. * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
  330. * this function has an unbounded cost, and using it as part of a state-changing function may render the function
  331. * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
  332. */
  333. function values(AddressSet storage set) internal view returns (address[] memory) {
  334. bytes32[] memory store = _values(set._inner);
  335. address[] memory result;
  336. assembly ("memory-safe") {
  337. result := store
  338. }
  339. return result;
  340. }
  341. /**
  342. * @dev Return a slice of the set in an array
  343. *
  344. * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
  345. * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
  346. * this function has an unbounded cost, and using it as part of a state-changing function may render the function
  347. * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
  348. */
  349. function values(AddressSet storage set, uint256 start, uint256 end) internal view returns (address[] memory) {
  350. bytes32[] memory store = _values(set._inner, start, end);
  351. address[] memory result;
  352. assembly ("memory-safe") {
  353. result := store
  354. }
  355. return result;
  356. }
  357. // UintSet
  358. struct UintSet {
  359. Set _inner;
  360. }
  361. /**
  362. * @dev Add a value to a set. O(1).
  363. *
  364. * Returns true if the value was added to the set, that is if it was not
  365. * already present.
  366. */
  367. function add(UintSet storage set, uint256 value) internal returns (bool) {
  368. return _add(set._inner, bytes32(value));
  369. }
  370. /**
  371. * @dev Removes a value from a set. O(1).
  372. *
  373. * Returns true if the value was removed from the set, that is if it was
  374. * present.
  375. */
  376. function remove(UintSet storage set, uint256 value) internal returns (bool) {
  377. return _remove(set._inner, bytes32(value));
  378. }
  379. /**
  380. * @dev Removes all the values from a set. O(n).
  381. *
  382. * WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the
  383. * function uncallable if the set grows to the point where clearing it consumes too much gas to fit in a block.
  384. */
  385. function clear(UintSet storage set) internal {
  386. _clear(set._inner);
  387. }
  388. /**
  389. * @dev Returns true if the value is in the set. O(1).
  390. */
  391. function contains(UintSet storage set, uint256 value) internal view returns (bool) {
  392. return _contains(set._inner, bytes32(value));
  393. }
  394. /**
  395. * @dev Returns the number of values in the set. O(1).
  396. */
  397. function length(UintSet storage set) internal view returns (uint256) {
  398. return _length(set._inner);
  399. }
  400. /**
  401. * @dev Returns the value stored at position `index` in the set. O(1).
  402. *
  403. * Note that there are no guarantees on the ordering of values inside the
  404. * array, and it may change when more values are added or removed.
  405. *
  406. * Requirements:
  407. *
  408. * - `index` must be strictly less than {length}.
  409. */
  410. function at(UintSet storage set, uint256 index) internal view returns (uint256) {
  411. return uint256(_at(set._inner, index));
  412. }
  413. /**
  414. * @dev Return the entire set in an array
  415. *
  416. * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
  417. * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
  418. * this function has an unbounded cost, and using it as part of a state-changing function may render the function
  419. * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
  420. */
  421. function values(UintSet storage set) internal view returns (uint256[] memory) {
  422. bytes32[] memory store = _values(set._inner);
  423. uint256[] memory result;
  424. assembly ("memory-safe") {
  425. result := store
  426. }
  427. return result;
  428. }
  429. /**
  430. * @dev Return a slice of the set in an array
  431. *
  432. * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
  433. * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
  434. * this function has an unbounded cost, and using it as part of a state-changing function may render the function
  435. * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
  436. */
  437. function values(UintSet storage set, uint256 start, uint256 end) internal view returns (uint256[] memory) {
  438. bytes32[] memory store = _values(set._inner, start, end);
  439. uint256[] memory result;
  440. assembly ("memory-safe") {
  441. result := store
  442. }
  443. return result;
  444. }
  445. struct StringSet {
  446. // Storage of set values
  447. string[] _values;
  448. // Position is the index of the value in the `values` array plus 1.
  449. // Position 0 is used to mean a value is not in the set.
  450. mapping(string value => uint256) _positions;
  451. }
  452. /**
  453. * @dev Add a value to a set. O(1).
  454. *
  455. * Returns true if the value was added to the set, that is if it was not
  456. * already present.
  457. */
  458. function add(StringSet storage self, string memory value) internal returns (bool) {
  459. if (!contains(self, value)) {
  460. self._values.push(value);
  461. // The value is stored at length-1, but we add 1 to all indexes
  462. // and use 0 as a sentinel value
  463. self._positions[value] = self._values.length;
  464. return true;
  465. } else {
  466. return false;
  467. }
  468. }
  469. /**
  470. * @dev Removes a value from a set. O(1).
  471. *
  472. * Returns true if the value was removed from the set, that is if it was
  473. * present.
  474. */
  475. function remove(StringSet storage self, string memory value) internal returns (bool) {
  476. // We cache the value's position to prevent multiple reads from the same storage slot
  477. uint256 position = self._positions[value];
  478. if (position != 0) {
  479. // Equivalent to contains(self, value)
  480. // To delete an element from the _values array in O(1), we swap the element to delete with the last one in
  481. // the array, and then remove the last element (sometimes called as 'swap and pop').
  482. // This modifies the order of the array, as noted in {at}.
  483. uint256 valueIndex = position - 1;
  484. uint256 lastIndex = self._values.length - 1;
  485. if (valueIndex != lastIndex) {
  486. string memory lastValue = self._values[lastIndex];
  487. // Move the lastValue to the index where the value to delete is
  488. self._values[valueIndex] = lastValue;
  489. // Update the tracked position of the lastValue (that was just moved)
  490. self._positions[lastValue] = position;
  491. }
  492. // Delete the slot where the moved value was stored
  493. self._values.pop();
  494. // Delete the tracked position for the deleted slot
  495. delete self._positions[value];
  496. return true;
  497. } else {
  498. return false;
  499. }
  500. }
  501. /**
  502. * @dev Removes all the values from a set. O(n).
  503. *
  504. * WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the
  505. * function uncallable if the set grows to the point where clearing it consumes too much gas to fit in a block.
  506. */
  507. function clear(StringSet storage set) internal {
  508. uint256 len = length(set);
  509. for (uint256 i = 0; i < len; ++i) {
  510. delete set._positions[set._values[i]];
  511. }
  512. Arrays.unsafeSetLength(set._values, 0);
  513. }
  514. /**
  515. * @dev Returns true if the value is in the set. O(1).
  516. */
  517. function contains(StringSet storage self, string memory value) internal view returns (bool) {
  518. return self._positions[value] != 0;
  519. }
  520. /**
  521. * @dev Returns the number of values on the set. O(1).
  522. */
  523. function length(StringSet storage self) internal view returns (uint256) {
  524. return self._values.length;
  525. }
  526. /**
  527. * @dev Returns the value stored at position `index` in the set. O(1).
  528. *
  529. * Note that there are no guarantees on the ordering of values inside the
  530. * array, and it may change when more values are added or removed.
  531. *
  532. * Requirements:
  533. *
  534. * - `index` must be strictly less than {length}.
  535. */
  536. function at(StringSet storage self, uint256 index) internal view returns (string memory) {
  537. return self._values[index];
  538. }
  539. /**
  540. * @dev Return the entire set in an array
  541. *
  542. * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
  543. * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
  544. * this function has an unbounded cost, and using it as part of a state-changing function may render the function
  545. * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
  546. */
  547. function values(StringSet storage self) internal view returns (string[] memory) {
  548. return self._values;
  549. }
  550. /**
  551. * @dev Return a slice of the set in an array
  552. *
  553. * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
  554. * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
  555. * this function has an unbounded cost, and using it as part of a state-changing function may render the function
  556. * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
  557. */
  558. function values(StringSet storage set, uint256 start, uint256 end) internal view returns (string[] memory) {
  559. unchecked {
  560. end = Math.min(end, length(set));
  561. start = Math.min(start, end);
  562. uint256 len = end - start;
  563. string[] memory result = new string[](len);
  564. for (uint256 i = 0; i < len; ++i) {
  565. result[i] = Arrays.unsafeAccess(set._values, start + i).value;
  566. }
  567. return result;
  568. }
  569. }
  570. struct BytesSet {
  571. // Storage of set values
  572. bytes[] _values;
  573. // Position is the index of the value in the `values` array plus 1.
  574. // Position 0 is used to mean a value is not in the set.
  575. mapping(bytes value => uint256) _positions;
  576. }
  577. /**
  578. * @dev Add a value to a set. O(1).
  579. *
  580. * Returns true if the value was added to the set, that is if it was not
  581. * already present.
  582. */
  583. function add(BytesSet storage self, bytes memory value) internal returns (bool) {
  584. if (!contains(self, value)) {
  585. self._values.push(value);
  586. // The value is stored at length-1, but we add 1 to all indexes
  587. // and use 0 as a sentinel value
  588. self._positions[value] = self._values.length;
  589. return true;
  590. } else {
  591. return false;
  592. }
  593. }
  594. /**
  595. * @dev Removes a value from a set. O(1).
  596. *
  597. * Returns true if the value was removed from the set, that is if it was
  598. * present.
  599. */
  600. function remove(BytesSet storage self, bytes memory value) internal returns (bool) {
  601. // We cache the value's position to prevent multiple reads from the same storage slot
  602. uint256 position = self._positions[value];
  603. if (position != 0) {
  604. // Equivalent to contains(self, value)
  605. // To delete an element from the _values array in O(1), we swap the element to delete with the last one in
  606. // the array, and then remove the last element (sometimes called as 'swap and pop').
  607. // This modifies the order of the array, as noted in {at}.
  608. uint256 valueIndex = position - 1;
  609. uint256 lastIndex = self._values.length - 1;
  610. if (valueIndex != lastIndex) {
  611. bytes memory lastValue = self._values[lastIndex];
  612. // Move the lastValue to the index where the value to delete is
  613. self._values[valueIndex] = lastValue;
  614. // Update the tracked position of the lastValue (that was just moved)
  615. self._positions[lastValue] = position;
  616. }
  617. // Delete the slot where the moved value was stored
  618. self._values.pop();
  619. // Delete the tracked position for the deleted slot
  620. delete self._positions[value];
  621. return true;
  622. } else {
  623. return false;
  624. }
  625. }
  626. /**
  627. * @dev Removes all the values from a set. O(n).
  628. *
  629. * WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the
  630. * function uncallable if the set grows to the point where clearing it consumes too much gas to fit in a block.
  631. */
  632. function clear(BytesSet storage set) internal {
  633. uint256 len = length(set);
  634. for (uint256 i = 0; i < len; ++i) {
  635. delete set._positions[set._values[i]];
  636. }
  637. Arrays.unsafeSetLength(set._values, 0);
  638. }
  639. /**
  640. * @dev Returns true if the value is in the set. O(1).
  641. */
  642. function contains(BytesSet storage self, bytes memory value) internal view returns (bool) {
  643. return self._positions[value] != 0;
  644. }
  645. /**
  646. * @dev Returns the number of values on the set. O(1).
  647. */
  648. function length(BytesSet storage self) internal view returns (uint256) {
  649. return self._values.length;
  650. }
  651. /**
  652. * @dev Returns the value stored at position `index` in the set. O(1).
  653. *
  654. * Note that there are no guarantees on the ordering of values inside the
  655. * array, and it may change when more values are added or removed.
  656. *
  657. * Requirements:
  658. *
  659. * - `index` must be strictly less than {length}.
  660. */
  661. function at(BytesSet storage self, uint256 index) internal view returns (bytes memory) {
  662. return self._values[index];
  663. }
  664. /**
  665. * @dev Return the entire set in an array
  666. *
  667. * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
  668. * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
  669. * this function has an unbounded cost, and using it as part of a state-changing function may render the function
  670. * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
  671. */
  672. function values(BytesSet storage self) internal view returns (bytes[] memory) {
  673. return self._values;
  674. }
  675. /**
  676. * @dev Return a slice of the set in an array
  677. *
  678. * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
  679. * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
  680. * this function has an unbounded cost, and using it as part of a state-changing function may render the function
  681. * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
  682. */
  683. function values(BytesSet storage set, uint256 start, uint256 end) internal view returns (bytes[] memory) {
  684. unchecked {
  685. end = Math.min(end, length(set));
  686. start = Math.min(start, end);
  687. uint256 len = end - start;
  688. bytes[] memory result = new bytes[](len);
  689. for (uint256 i = 0; i < len; ++i) {
  690. result[i] = Arrays.unsafeAccess(set._values, start + i).value;
  691. }
  692. return result;
  693. }
  694. }
  695. }