|
2 | 2 |
|
3 | 3 | pragma solidity ^0.8.20;
|
4 | 4 |
|
| 5 | +import { ArrayUtils } from '../utils/ArrayUtils.sol'; |
| 6 | +import { Math } from '../utils/Math.sol'; |
| 7 | + |
5 | 8 | /**
|
6 | 9 | * @title Set implementation with enumeration functions
|
7 | 10 | * @dev derived from https://github.com/OpenZeppelin/openzeppelin-contracts (MIT license)
|
8 | 11 | */
|
9 | 12 | library EnumerableSet {
|
| 13 | + using ArrayUtils for bytes32[]; |
| 14 | + |
10 | 15 | error EnumerableSet__IndexOutOfBounds();
|
11 | 16 |
|
12 | 17 | struct Set {
|
@@ -144,33 +149,51 @@ library EnumerableSet {
|
144 | 149 | function toArray(
|
145 | 150 | Bytes32Set storage set
|
146 | 151 | ) internal view returns (bytes32[] memory) {
|
147 |
| - return set._inner._values; |
| 152 | + return _toArray(set._inner); |
148 | 153 | }
|
149 | 154 |
|
150 | 155 | function toArray(
|
151 | 156 | AddressSet storage set
|
152 | 157 | ) internal view returns (address[] memory) {
|
153 |
| - bytes32[] storage values = set._inner._values; |
154 |
| - address[] storage array; |
155 |
| - |
156 |
| - assembly { |
157 |
| - array.slot := values.slot |
158 |
| - } |
159 |
| - |
160 |
| - return array; |
| 158 | + return _toArray(set._inner).toAddressArray(); |
161 | 159 | }
|
162 | 160 |
|
163 | 161 | function toArray(
|
164 | 162 | UintSet storage set
|
165 | 163 | ) internal view returns (uint256[] memory) {
|
166 |
| - bytes32[] storage values = set._inner._values; |
167 |
| - uint256[] storage array; |
| 164 | + return _toArray(set._inner).toUint256Array(); |
| 165 | + } |
| 166 | + |
| 167 | + function toArray( |
| 168 | + Bytes32Set storage set, |
| 169 | + uint256 startIndex, |
| 170 | + uint256 count |
| 171 | + ) internal view returns (bytes32[] memory array) { |
| 172 | + array = _toArray(set._inner, startIndex, count); |
| 173 | + } |
| 174 | + |
| 175 | + function toArray( |
| 176 | + AddressSet storage set, |
| 177 | + uint256 startIndex, |
| 178 | + uint256 count |
| 179 | + ) internal view returns (address[] memory array) { |
| 180 | + bytes32[] memory bytes32Array = _toArray(set._inner, startIndex, count); |
168 | 181 |
|
169 | 182 | assembly {
|
170 |
| - array.slot := values.slot |
| 183 | + array := bytes32Array |
171 | 184 | }
|
| 185 | + } |
172 | 186 |
|
173 |
| - return array; |
| 187 | + function toArray( |
| 188 | + UintSet storage set, |
| 189 | + uint256 startIndex, |
| 190 | + uint256 count |
| 191 | + ) internal view returns (uint256[] memory array) { |
| 192 | + bytes32[] memory bytes32Array = _toArray(set._inner, startIndex, count); |
| 193 | + |
| 194 | + assembly { |
| 195 | + array := bytes32Array |
| 196 | + } |
174 | 197 | }
|
175 | 198 |
|
176 | 199 | function _at(
|
@@ -236,4 +259,28 @@ library EnumerableSet {
|
236 | 259 | status = true;
|
237 | 260 | }
|
238 | 261 | }
|
| 262 | + |
| 263 | + function _toArray( |
| 264 | + Set storage set |
| 265 | + ) private view returns (bytes32[] storage array) { |
| 266 | + array = set._values; |
| 267 | + } |
| 268 | + |
| 269 | + function _toArray( |
| 270 | + Set storage set, |
| 271 | + uint256 startIndex, |
| 272 | + uint256 count |
| 273 | + ) private view returns (bytes32[] memory array) { |
| 274 | + unchecked { |
| 275 | + uint256 size = _length(set); |
| 276 | + |
| 277 | + if (startIndex >= size) revert EnumerableSet__IndexOutOfBounds(); |
| 278 | + |
| 279 | + array = new bytes32[](Math.min(count, size - startIndex)); |
| 280 | + |
| 281 | + for (uint256 i; i < count; i++) { |
| 282 | + array[i] = set._values[startIndex + i]; |
| 283 | + } |
| 284 | + } |
| 285 | + } |
239 | 286 | }
|
0 commit comments