openzeppelin-contracts icon indicating copy to clipboard operation
openzeppelin-contracts copied to clipboard

Consider adding `slice` and `splice` function to `Arrays` and `Bytes`

Open ernestognw opened this issue 7 months ago • 1 comments

🧐 Motivation

Currently, the Bytes library includes a function to slice a chunk of data. I think this is useful, but for cases when the original array can be discarded, I think developers would benefit from implementing an splice function.

We could consider these functions for the Arrays library too, so we can offer a generalized library for doing this with any native solidity type.

📝 Details

Here's a reference implementation for the Arrays library for bytes32[] memory arrays:

/**
 * @dev Splices a slice of a bytes32 array. Avoids expanding memory.
 *
 * Replicates https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice[Javascript's `Array.splice`]
 *
 * NOTE: Clears the array if `start` is greater than `end`.
 */
function _splice(bytes32[] memory data, uint256 start, uint256 end) private pure returns (bytes32[] memory) {
    // sanitize
    uint256 length = data.length;
    end = Math.min(end, length);
    start = Math.min(start, end);

    if (start != 0) {
        // allocate and copy
        for (uint256 i = start; i < end; i++) {
            data[i - start] = data[i];
        }
    }

    assembly ("memory-safe") {
        mstore(data, sub(end, start)) // Reset the length of the array. Can't overflow because `end` is less than `data.length`.
    }

    return data;
}

ernestognw avatar Jun 07 '25 18:06 ernestognw

Definitelly yes for Bytes.sol!

For arrays, I'm not sure if we should have that only for bytes32[] ? For all value type (uint256[], address[], ...) ? For string[] and bytes[] ? (I'd tend to say no to that last one)

Note: We should be able to avoid the loop using a mcopy.

Amxx avatar Jun 10 '25 12:06 Amxx