Skip to content

Commit

Permalink
✨ DynamicArrayLib add copy and slice (#1310)
Browse files Browse the repository at this point in the history
  • Loading branch information
Vectorized authored Jan 17, 2025
1 parent 45d8b3f commit 6d3e510
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 1 deletion.
30 changes: 30 additions & 0 deletions src/utils/DynamicArrayLib.sol
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,31 @@ library DynamicArrayLib {
}
}

/// @dev Returns a copy of `a` sliced from `start` to the end of the array.
function slice(uint256[] memory a, uint256 start)
internal
pure
returns (uint256[] memory result)
{
result = slice(a, start, type(uint256).max);
}

/// @dev Returns a copy of the array.
function copy(uint256[] memory a) internal pure returns (uint256[] memory result) {
/// @solidity memory-safe-assembly
assembly {
result := mload(0x40)
let end := add(add(result, 0x20), shl(5, mload(a)))
let o := result
for { let d := sub(a, result) } 1 {} {
mstore(o, mload(add(o, d)))
o := add(0x20, o)
if eq(o, end) { break }
}
mstore(0x40, o)
}
}

/// @dev Returns if `needle` is in `a`.
function contains(uint256[] memory a, uint256 needle) internal pure returns (bool) {
return ~indexOf(a, needle, 0) != 0;
Expand Down Expand Up @@ -837,6 +862,11 @@ library DynamicArrayLib {
result.data = slice(a.data, start, type(uint256).max);
}

/// @dev Returns a copy of `a`.
function copy(DynamicArray memory a) internal pure returns (DynamicArray memory result) {
result.data = copy(a.data);
}

/// @dev Returns if `needle` is in `a`.
function contains(DynamicArray memory a, uint256 needle) internal pure returns (bool) {
return ~indexOf(a.data, needle, 0) != 0;
Expand Down
30 changes: 30 additions & 0 deletions src/utils/g/DynamicArrayLib.sol
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,31 @@ library DynamicArrayLib {
}
}

/// @dev Returns a copy of `a` sliced from `start` to the end of the array.
function slice(uint256[] memory a, uint256 start)
internal
pure
returns (uint256[] memory result)
{
result = slice(a, start, type(uint256).max);
}

/// @dev Returns a copy of the array.
function copy(uint256[] memory a) internal pure returns (uint256[] memory result) {
/// @solidity memory-safe-assembly
assembly {
result := mload(0x40)
let end := add(add(result, 0x20), shl(5, mload(a)))
let o := result
for { let d := sub(a, result) } 1 {} {
mstore(o, mload(add(o, d)))
o := add(0x20, o)
if eq(o, end) { break }
}
mstore(0x40, o)
}
}

/// @dev Returns if `needle` is in `a`.
function contains(uint256[] memory a, uint256 needle) internal pure returns (bool) {
return ~indexOf(a, needle, 0) != 0;
Expand Down Expand Up @@ -841,6 +866,11 @@ library DynamicArrayLib {
result.data = slice(a.data, start, type(uint256).max);
}

/// @dev Returns a copy of `a`.
function copy(DynamicArray memory a) internal pure returns (DynamicArray memory result) {
result.data = copy(a.data);
}

/// @dev Returns if `needle` is in `a`.
function contains(DynamicArray memory a, uint256 needle) internal pure returns (bool) {
return ~indexOf(a.data, needle, 0) != 0;
Expand Down
18 changes: 17 additions & 1 deletion test/DynamicArrayLib.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -228,12 +228,28 @@ contract DynamicArrayLibTest is SoladyTest {
unchecked {
start = _bound(start, 0, a.data.length + 2);
end = _bound(end, 0, a.data.length + 2);
DynamicArrayLib.DynamicArray memory slice = a.slice(start, end);
DynamicArrayLib.DynamicArray memory slice;
if (_randomChance(2) && end > a.data.length) {
slice = a.slice(start);
} else {
slice = a.slice(start, end);
}
_checkMemory(slice.data);
assertEq(slice.data, _sliceOriginal(data, start, end));
}
}

function testDynamicArrayCopy(uint256[] memory data) public {
DynamicArrayLib.DynamicArray memory a;
a.data = data;
DynamicArrayLib.DynamicArray memory b = a.copy();
assertEq(a.data, b.data);
a.p(1);
assertNotEq(a.data, b.data);
b.p(1);
assertEq(a.data, b.data);
}

function testUint256Contains() public {
uint256 n = 50;
uint256[] memory a;
Expand Down

0 comments on commit 6d3e510

Please sign in to comment.